######################################################################## ## ## Copyright (C) 2004-2022 The Octave Project Developers ## ## See the file COPYRIGHT.md in the top-level directory of this ## distribution or . ## ## This file is part of Octave. ## ## Octave 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. ## ## Octave 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 Octave; see the file COPYING. If not, see ## . ## ######################################################################## ## -*- texinfo -*- ## @deftypefn {} {} dir ## @deftypefnx {} {} dir (@var{directory}) ## @deftypefnx {} {[@var{list}] =} dir (@var{directory}) ## Display file listing for directory @var{directory}. ## ## If @var{directory} is not specified then list the present working directory. ## ## If a return value is requested, return a structure array with the fields ## ## @table @asis ## @item name ## File or directory name. ## ## @item folder ## Location of file or directory ## ## @item date ## Timestamp of file modification (string value). ## ## @item bytes ## File size in bytes. ## ## @item isdir ## True if name is a directory. ## ## @item datenum ## Timestamp of file modification as serial date number (double). ## ## @item statinfo ## Information structure returned from @code{stat}. ## @end table ## ## If @var{directory} is a filename, rather than a directory, then return ## information about the named file. @var{directory} may also be a list rather ## than a single directory or file. ## ## @var{directory} is subject to shell expansion if it contains any wildcard ## characters @samp{*}, @samp{?}, @samp{[]}. If these wildcard characters are ## escaped with a backslash @samp{\} (e.g., @samp{\*}) on a POSIX platform, ## then they are not treated as wildcards, but as the corresponding literal ## character. On Windows, it is not possible to escape wildcard characters ## because backslash @samp{\} is treated as a file separator. On Windows, use ## @code{ls} for file or folder names that contain characters that would be ## treated as wildcards by @code{dir}. ## ## Note that for symbolic links, @code{dir} returns information about the ## file that the symbolic link points to rather than the link itself. However, ## if the link points to a nonexistent file, @code{dir} returns information ## about the link. ## @seealso{ls, readdir, glob, what, stat, lstat} ## @end deftypefn function u = dir(d='', w='', recursive=0) if (!ischar (d)) print_usage (); endif if ~isempty(d) f = filesep; ## file seperator if (f == '\') lineEnding = '\r\n'; else lineEnding = '\n'; endif if (recursive == 0) ## check if recursive listing is desired and remove recursive tag from path recursive=!isempty (strfind (d, '**')); recursiveProcessingActive=recursive; ## remember recursive processing if (recursive) d = strrep (d, '**', ''); ## remove recursive tag in d endif ## change "wrong" slashes to fit the actual system plattform if (f == '\') d(d == '/') = f; else d(d == '\') = f; endif d = [d(1),strrep(d(2:end),[f,f],f)]; ## //->/, preserve // at the beginning for net drives d = d(1:end - (d(end) == f)); ## cut last char if its a slash if ( sum (d == f) > 0) ## check if d is a complex path i = max (find (d == f)); ## last slash in string w = d( (i + 1):end); ## ending could be wildcard else w = d; ## if it is without slash than take all endif if (isempty (strfind (w, '*'))) ## check if the ending is a w = '*'; ## complete directory or a else d = d(1:end - length (w) -1 ); ## wildcard endif endif else f = ''; w = '*'; endif ## read actual directory files u = __wglob__ ([d, f, w]); ## add '.' and '..* directory entries if all files are searched if (w=='*') u = [[d,f,'.'];[d,f,'..'];u]; endif ## recurse one level deeper if there are directories present if (recursive > 0) v = __wglob__ ([d, f, '*', f]); ## list ONLY directories for i = 1:numel (v) u = [u;dir(v{i}(1:end - 1),w,recursive + 1)]; ## cut slash at the end of v{i} endfor recursive = recursive - 1; endif if ( (recursive == 0) && (!isempty (u)) ) if (nargout > 0) ## return the directory as a variable ## mtime is unix time = seconds since 1.1.1970 ## datenum is days since 1.1.0000 ## there is just a constant time difference, only a + is needed dt = datenum (1970, 1, 1, 1, 0, 0); ## time difference n = numel (u); st = cellfun (@(x) stat (x), u); ## in former dir.m lstat was used => check with linux b = struct (... 'name', cellfun (@(x) x(max (find (x == f)) + 1:end), u, 'UniformOutput', false),... 'folder', cellfun (@(x) x(1:max (find (x == f)) - 1), u, 'UniformOutput', false),... 'date', mat2cell (datestr ([st.mtime]'./(24 .* 3600) + dt), ones (n, 1)),... 'bytes', {st.size}',... 'isdir', cellfun (@(x) S_ISDIR (x), {st.mode}', 'UniformOutput', false),... 'datenum', num2cell ([st.mtime]'./(24 .* 3600) + dt),... 'statinfo', mat2cell (st, ones (n, 1))... ); u = b; else ## print the output if recursiveProcessingActive ## ... in case of recursive processing at the end of the processing v=cellfun (@(x) x(1:max (find (x == f)) - 1), u, 'UniformOutput', false); ## get folder list [v, k] = unique (v); ## eliminate duplicates v(:, 2) = num2cell (k); ## sort in correct order, like it occured v = sortrows (v, 2); ## ... k = cell2mat (v(:, 2)); ## read the indices of the directory jumps into k k(end + 1) = numel (u) + 1; ## add length of u+1 for i=1:numel(k) - 1 ## print the directories after each other printf ([lineEnding,'Files Found in: %s',lineEnding,lineEnding], v{i, 1}); % directory header printf ("%s", list_in_columns ( cellfun (@(x) x(max (find (x == f)) + 1:end), u( k(i):(k(i + 1) - 1) ), 'UniformOutput', false) ) ); endfor else # ... in case if linear processing... print just the file list without a header printf ("%s", list_in_columns ( cellfun (@(x) x(max (find (x == f)) + 1:end), u, 'UniformOutput', false) ) ); endif clear u ## no u can be given back :) => nargout==0 endif endif end