changeset 21696:b8c05cc524ef

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.
author Lachlan Andrew <lachlanbis@gmail.com>
date Sun, 01 May 2016 22:11:14 +1000
parents 3e495750cf62
children e7f641616581
files libinterp/corefcn/dirfns.cc scripts/miscellaneous/mkdir.m scripts/miscellaneous/module.mk
diffstat 3 files changed, 105 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- 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;
 
--- /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 <http://www.gnu.org/licenses/>.
+
+## -*- 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")
+
--- 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 \