# HG changeset patch # User Lachlan Andrew # Date 1462104674 -36000 # Node ID b8c05cc524ef97ed66cc03eec986b02681c46322 # Parent 3e495750cf620bc67e6e9ab0947d4b6c5eaa6c4c mkdir.m: new script to implement recursive mkdir (bug #30650). * scripts/miscellaneous/mkdir.m: New file. * dirfns.cc (F__mkdir__) : Rename Fmkdir to F__mkdir__. Redirect help string to mkdir.m. * scripts/miscellaneous/modules.mk: add mkdir.m to build system. diff -r 3e495750cf62 -r b8c05cc524ef libinterp/corefcn/dirfns.cc --- a/libinterp/corefcn/dirfns.cc Fri May 13 17:28:54 2016 -0700 +++ b/libinterp/corefcn/dirfns.cc Sun May 01 22:11:14 2016 +1000 @@ -199,30 +199,17 @@ // FIXME: should maybe also allow second arg to specify mode? // OTOH, that might cause trouble with compatibility later... -DEFUNX ("mkdir", Fmkdir, args, , +DEFUN (__mkdir__, args, , "-*- texinfo -*-\n\ -@deftypefn {} {} mkdir @var{dir}\n\ -@deftypefnx {} {} mkdir (@var{parent}, @var{dir})\n\ -@deftypefnx {} {[@var{status}, @var{msg}, @var{msgid}] =} mkdir (@dots{})\n\ -Create a directory named @var{dir} in the directory @var{parent}.\n\ -\n\ -If no @var{parent} directory is specified the present working directory is\n\ -used.\n\ -\n\ -If successful, @var{status} is 1, and @var{msg}, @var{msgid} are empty\n\ -character strings (""). Otherwise, @var{status} is 0, @var{msg} contains a\n\ -system-dependent error message, and @var{msgid} contains a unique message\n\ -identifier.\n\ -\n\ -When creating a directory permissions will be set to\n\ -@code{0777 - @var{umask}}.\n\ -@seealso{rmdir, pwd, cd, umask}\n\ +@deftypefn {} {} __mkdir__ (@var{parent}, @var{dir})\n\ +Internal function called by mkdir.m.\n\ +@seealso{mkdir, rmdir, pwd, cd, umask}\n\ @end deftypefn") { int nargin = args.length (); if (nargin < 1 || nargin > 2) - print_usage (); + print_usage ("mkdir"); std::string dirname; diff -r 3e495750cf62 -r b8c05cc524ef scripts/miscellaneous/mkdir.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/miscellaneous/mkdir.m Sun May 01 22:11:14 2016 +1000 @@ -0,0 +1,99 @@ +## Copyright (C) 2016 Lachlan Andrew +## Copyright (C) 2012 Carnë Draug +## +## This program is free software; you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 3 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program. If not, see . + +## -*- texinfo -*- +## @deftypefn {} {} mkdir @var{dir} +## @deftypefnx {} {} mkdir (@var{parent}, @var{dir}) +## @deftypefnx {} {[@var{status}, @var{msg}, @var{msgid}] =} mkdir (...) +## Create a directory named @var{dir} in the directory @var{parent}, +## creating any intermediate directories if necessary. +## +## If @var{dir} is a relative path and no @var{parent} directory is specified +## then the present working directory is used. +## +## If successful, @var{status} is 1, and @var{msg} and @var{msgid} are empty +## strings (""). Otherwise, @var{status} is 0, @var{msg} contains a +## system-dependent error message, and @var{msgid} contains a unique message +## identifier. +## +## When creating a directory permissions will be set to @code{0777 - UMASK}. +## +## @seealso{rmdir, pwd, cd, umask} +## @end deftypefn + +## There is/was a bug in gnulib's mkdir-p module under Windows. +## This file is a workaround until that is fixed and the fix incorporated +## into Octave. + +function [status, msg, msgid] = mkdir (parent, dirname) + + if (nargin < 1 || nargin > 2) + print_usage (); + endif + + if (nargin == 1) + dirname = parent; + + if (is_absolute_filename (dirname)) + parent = ""; + else + parent = [pwd(), filesep]; + endif + else + parent = [parent, filesep]; + endif + + ## Move leading directory names from dirname to parent + [parent, dirname, ext] = fileparts ([parent, dirname]); + + [status, msg, msgid] = mkdir_recur (parent, [dirname, ext]); + +endfunction + +## Recursively make directories until parent/dirname can be created. +function [status, msg, msgid] = mkdir_recur (parent, dirname) + + status = 1; + + if (! isdir (parent)) + [grandparent, name, ext] = fileparts (parent); + [status, msg, msgid] = mkdir_recur (grandparent, [name, ext]); + endif + + if (status) + [status, msg, msgid] = __mkdir__ (parent, dirname); + endif + +endfunction + + +%!test +%! dir1 = tempname (); +%! dir2 = "%_unlikely_name_%"; +%! dir = fullfile (dir1, dir2); +%! unwind_protect +%! status = mkdir (dir); +%! assert (status); +%! assert (isdir (dir)); +%! unwind_protect_cleanup +%! confirm_recursive_rmdir (false, "local"); +%! rmdir (dir1, "s"); +%! end_unwind_protect + +## Test input validation +%!error mkdir () +%!error mkdir ("a", "b", "c") + diff -r 3e495750cf62 -r b8c05cc524ef scripts/miscellaneous/module.mk --- a/scripts/miscellaneous/module.mk Fri May 13 17:28:54 2016 -0700 +++ b/scripts/miscellaneous/module.mk Sun May 01 22:11:14 2016 +1000 @@ -45,6 +45,7 @@ scripts/miscellaneous/menu.m \ scripts/miscellaneous/mex.m \ scripts/miscellaneous/mexext.m \ + scripts/miscellaneous/mkdir.m \ scripts/miscellaneous/mkoctfile.m \ scripts/miscellaneous/movefile.m \ scripts/miscellaneous/namelengthmax.m \