changeset 12499:a3019189ac51

Improve file archiving functions (gzip, bzip2, zip, unpack)
author Rik <octave@nomad.inbox5.com>
date Thu, 03 Mar 2011 11:59:05 -0800
parents 294c0927c762
children 8f2056646dba
files scripts/ChangeLog scripts/miscellaneous/gzip.m scripts/miscellaneous/private/__xzip__.m scripts/miscellaneous/unpack.m
diffstat 4 files changed, 142 insertions(+), 124 deletions(-) [+]
line wrap: on
line diff
--- a/scripts/ChangeLog
+++ b/scripts/ChangeLog
@@ -1,3 +1,13 @@
+2010-03-03  Rik  <octave@nomad.inbox5.com>
+
+	* miscellaneous/gzip.m: Use same functional form as bzip, zip, etc.
+	* miscellaneous/private/__xzip__.m: Allow use of character arrays of
+	filenames.
+	* miscellaneous/unpack.m: Allow use of character arrays of filenames.
+	Add capability for gunzip to work recursively on a directory.
+	Fix bug where unzip returned the archive name in addition to the list
+	of files unzipped.
+
 2010-03-03  Rik  <octave@nomad.inbox5.com>
 
 	* deprecated/module.mk, general/module.mk: Deprecate is_duplicate_entry.
--- a/scripts/miscellaneous/gzip.m
+++ b/scripts/miscellaneous/gzip.m
@@ -28,21 +28,22 @@
 ## @end deftypefn
 
 function entries = gzip (varargin)
-  if (nargin == 1 || nargin == 2) && (nargout <= 1)
-    if nargout == 0
-      __xzip__ ("gzip", "gz", "gzip -r %s", varargin{:});
-    else
-      entries = __xzip__ ("gzip", "gz", "gzip -r %s", varargin{:});
-    endif
-  else
+  if (nargin != 1 && nargin != 2) || (nargout > 1)
     print_usage ();
   endif
+     
+  if (nargout == 0)
+    __xzip__ ("gzip", "gz", "gzip -r %s", varargin{:});
+  else
+    entries = __xzip__ ("gzip", "gz", "gzip -r %s", varargin{:});
+  endif
+
 endfunction
 
 %!error <Invalid call to gzip.  Correct usage is> gzip("1", "2", "3");
 %!error <Invalid call to gzip.  Correct usage is> gzip();
 %!error <output directory does not exist> gzip("1", tmpnam);
-%!error <expecting FILES to be a character array> gzip(1);
+%!error <FILES must be a character array or cellstr> gzip(1);
 %!xtest
 %!  # test gzip together with gunzip
 %!  unwind_protect
--- a/scripts/miscellaneous/private/__xzip__.m
+++ b/scripts/miscellaneous/private/__xzip__.m
@@ -33,81 +33,79 @@
 function entries = __xzip__ (commandname, extension,
                              commandtemplate, files, outdir)
 
-  if (nargin == 4 || nargin == 5)
-    if (! ischar (extension) || length (extension) == 0)
-      error ("__xzip__: EXTENSION has to be a string with finite length");
-    endif
+  if (nargin != 4 && nargin != 5)
+    print_usage ();
+  endif
+  
+  if (! ischar (extension) || length (extension) == 0)
+    error ("__xzip__: EXTENSION must be a string with finite length");
+  endif
 
-    if (nargin == 5 && ! exist (outdir, "dir"))
-      error ("__xzip__: output directory does not exist");
-    endif
+  if (nargin == 5 && ! exist (outdir, "dir"))
+    error ("__xzip__: OUTDIR output directory does not exist");
+  endif
+
+  if (ischar (files))
+    files = cellstr (files);
+  endif
+  if (! iscellstr (files))
+    error ("__xzip__: FILES must be a character array or cellstr");
+  endif
 
-    if (ischar (files))
-      files = cellstr (files);
-    else
-      error ("__xzip__: expecting FILES to be a character array");
-    endif
+  if (nargin == 4)
+    outdir = tmpnam ();
+    mkdir (outdir);
+  endif
+
+  cwd = pwd ();
+  unwind_protect
+    files = glob (files);
 
-    if (nargin == 4)
-      outdir = tmpnam ();
-      mkdir (outdir);
+    ## Ignore any file with the compress extension
+    files(cellfun (@(x) length(x) > length(extension)
+      && strcmp (x((end - length(extension) + 1):end), extension),
+      files)) = [];
+
+    copyfile (files, outdir);
+
+    [d, f] = myfileparts(files);
+
+    cd (outdir);
+
+    cmd = sprintf (commandtemplate, sprintf (" %s", f{:}));
+
+    [status, output] = system (cmd);
+    if (status)
+      error ("__xzip__: %s command failed with exit status = %d",
+             commandname, status);
     endif
 
-    cwd = pwd();
-    unwind_protect
-      files = glob (files);
-
-      ## Ignore any file with the compress extension
-      files (cellfun (@(x) length(x) > length(extension)
-        && strcmp (x((end - length(extension) + 1):end), extension),
-        files)) = [];
-
-      copyfile (files, outdir);
-
-      [d, f] = myfileparts(files);
-
-      cd (outdir);
-
-      cmd = sprintf (commandtemplate, sprintf (" %s", f{:}));
-
-      [status, output] = system (cmd);
-      if (status == 0)
+    if (nargout > 0)
+      if (nargin == 5)
+        entries = cellfun(
+            @(x) fullfile (outdir, sprintf ("%s.%s", x, extension)),
+            f, "uniformoutput", false);
+      else
+        movefile (cellfun(@(x) sprintf ("%s.%s", x, extension), f,
+                          "uniformoutput", false), cwd);
+        ## FIXME this does not work when you try to compress directories
+        entries  = cellfun(@(x) sprintf ("%s.%s", x, extension),
+                           files, "uniformoutput", false);
+      endif
+    endif
 
-        if (nargin == 5)
-          compressed_files = cellfun(
-              @(x) fullfile (outdir, sprintf ("%s.%s", x, extension)),
-              f, "uniformoutput", false);
-        else
-          movefile (cellfun(@(x) sprintf ("%s.%s", x, extension), f,
-                            "uniformoutput", false), cwd);
-          ## FIXME this does not work when you try to compress directories
-
-          compressed_files  = cellfun(@(x) sprintf ("%s.%s", x, extension),
-                                      files, "uniformoutput", false);
-        endif
-
-        if (nargout > 0)
-          entries = compressed_files;
-        endif
-      else
-        error ("__xzip__: %s command failed with exit status = %d",
-               commandname, status);
-      endif
-    unwind_protect_cleanup
-      cd(cwd);
-      if (nargin == 4)
-        crr = confirm_recursive_rmdir ();
-        unwind_protect
-          confirm_recursive_rmdir (false);
-          rmdir (outdir, "s");
-        unwind_protect_cleanup
-          confirm_recursive_rmdir (crr);
-        end_unwind_protect
-      endif
-    end_unwind_protect
-  else
-    print_usage ();
-  endif
+  unwind_protect_cleanup
+    cd (cwd);
+    if (nargin == 4)
+      crr = confirm_recursive_rmdir ();
+      unwind_protect
+        confirm_recursive_rmdir (false);
+        rmdir (outdir, "s");
+      unwind_protect_cleanup
+        confirm_recursive_rmdir (crr);
+      end_unwind_protect
+    endif
+  end_unwind_protect
 
 endfunction
 
--- a/scripts/miscellaneous/unpack.m
+++ b/scripts/miscellaneous/unpack.m
@@ -39,52 +39,17 @@
     print_usage ();
   endif
 
-  if (ischar (file))
-    if (isdir (file))
-      if (isempty (filetype))
-        error ("unpack: FILETYPE must be given for a directory");
-      elseif (! any (strcmpi (filetype, "gunzip")))
-        error ("unpack: FILETYPE must be gunzip for a directory");
-      endif
-    else
-      [pathstr, name, ext] = fileparts (file);
-
-      ## Check to see if it's .tar.gz, .tar.Z, etc.
-      if (any (strcmpi ({".gz" ".Z" ".bz2" ".bz"}, ext)))
-        [tmppathstr, tmpname, tmpext] = fileparts (name);
-        if (strcmpi (tmpext, ".tar"))
-          name = tmpname;
-          ext = cstrcat (tmpext, ext);
-        endif
-      endif
+  if (! ischar (file) && ! iscellstr (file)) 
+    error ("unpack: invalid input file class, %s", class(file));
+  endif
 
-      ## If the file is a URL, download it and then work with that
-      ## file.
-      if (! isempty (strfind (file, "://")))
-        ## FIXME -- the above is not a perfect test for a URL
-        urlfile = file;
-        ## FIXME -- should we name the file that we download with the
-        ## same file name as the URL requests?
-        tmpfile = cstrcat (tmpnam (), ext);
-        [file, success, msg] = urlwrite (urlfile, tmpfile);
-        if (! success)
-          error ("unpack: could not get \"%s\": %s", urlfile, msg);
-        endif
-      endif
+  ## character arrays of more than one string must be treated as cell strings
+  if (ischar (file) && ! isvector (file)) 
+    file = cellstr (file);
+  endif
 
-    endif
-
-    ## canonicalize_file_name returns empty if the file isn't found, so
-    ## use that to check for existence.
-    cfile = canonicalize_file_name (file);
-
-    if (isempty (cfile))
-      error ("unpack: file \"%s\" not found", file);
-    else
-      file = cfile;
-    endif
-
-  elseif (iscellstr (file))
+  ## Recursively unpack cellstr arrays one file at a time
+  if (iscellstr (file))
     files = {};
     for i = 1:numel (file)
       tmpfiles = unpack (file{i}, dir);
@@ -96,9 +61,51 @@
       filelist = files;
     endif
 
-    return
+    return;
+  endif
+
+  if (isdir (file))
+    if (isempty (filetype))
+      error ("unpack: FILETYPE must be given for a directory");
+    elseif (! any (strcmpi (filetype, "gunzip")))
+      error ("unpack: FILETYPE must be gunzip for a directory");
+    endif
+    ext = ".gz";
   else
-    error ("unpack: invalid input file class, %s", class(file));
+    [pathstr, name, ext] = fileparts (file);
+
+    ## Check to see if it's .tar.gz, .tar.Z, etc.
+    if (any (strcmpi ({".gz" ".Z" ".bz2" ".bz"}, ext)))
+      [tmppathstr, tmpname, tmpext] = fileparts (name);
+      if (strcmpi (tmpext, ".tar"))
+        name = tmpname;
+        ext = cstrcat (tmpext, ext);
+      endif
+    endif
+
+    ## If the file is a URL, download it and then work with that file.
+    if (! isempty (strfind (file, "://")))
+      ## FIXME -- the above is not a perfect test for a URL
+      urlfile = file;
+      ## FIXME -- should we name the file that we download with the
+      ## same file name as the URL requests?
+      tmpfile = cstrcat (tmpnam (), ext);
+      [file, success, msg] = urlwrite (urlfile, tmpfile);
+      if (! success)
+        error ("unpack: could not get \"%s\": %s", urlfile, msg);
+      endif
+    endif
+
+  endif
+
+  ## canonicalize_file_name returns empty if the file isn't found, so
+  ## use that to check for existence.
+  cfile = canonicalize_file_name (file);
+
+  if (isempty (cfile))
+    error ("unpack: file \"%s\" not found", file);
+  else
+    file = cfile;
   endif
 
   ## Instructions on what to do for any extension.
@@ -154,7 +161,7 @@
       command = commandq;
     endif
   else
-    warning ("unpack:filetype", "unrecognised file type, %s", ext);
+    warning ("unpack:filetype", "unrecognized file type, %s", ext);
     files = file;
     return;
   endif
@@ -215,6 +222,8 @@
 function files = __parse_zip__ (output)
   ## Parse the output from zip and unzip.
 
+  ## Skip first line which is Archive header
+  output(1) = []; 
   for i = 1:length (output)
     files{i} = output{i}(14:length(output{i}));
   endfor