Mercurial > octave-nkf
comparison scripts/miscellaneous/fullfile.m @ 19598:c304687571c8
fullfile.m: properly process file separators and drive letters on Windows systems (bug #43926)
author | Philip Nienhuis <prnienhuis@users.sf.net> |
---|---|
date | Sun, 11 Jan 2015 20:11:43 +0100 |
parents | 8cc4a9bb253b |
children | db92e7e28e1f |
comparison
equal
deleted
inserted
replaced
19595:0d3e67f27d57 | 19598:c304687571c8 |
---|---|
21 ## @deftypefnx {Function File} {@var{filenames} =} fullfile (@dots{}, @var{files}) | 21 ## @deftypefnx {Function File} {@var{filenames} =} fullfile (@dots{}, @var{files}) |
22 ## Build complete filename from separate parts. | 22 ## Build complete filename from separate parts. |
23 ## | 23 ## |
24 ## Joins any number of path components intelligently. The return value | 24 ## Joins any number of path components intelligently. The return value |
25 ## is the concatenation of each component with exactly one file separator | 25 ## is the concatenation of each component with exactly one file separator |
26 ## between each non empty part. | 26 ## between each non empty part and at most one leading and/or trailing file |
27 ## separator. | |
27 ## | 28 ## |
28 ## If the last component part is a cell array, returns a cell array of | 29 ## If the last component part is a cell array, returns a cell array of |
29 ## filepaths, one for each element in the last component, e.g.: | 30 ## filepaths, one for each element in the last component, e.g.: |
30 ## | 31 ## |
31 ## @example | 32 ## @example |
35 ## /home/username/data/f2.csv | 36 ## /home/username/data/f2.csv |
36 ## /home/username/data/f3.csv | 37 ## /home/username/data/f3.csv |
37 ## @end group | 38 ## @end group |
38 ## @end example | 39 ## @end example |
39 ## | 40 ## |
41 ## On Windows systems, while forward slash file separators do work, they | |
42 ## are replaced by backslashes; in addition drive letters are stripped of | |
43 ## leading file separators to obtain a valid file path. | |
44 ## | |
40 ## @seealso{fileparts, filesep} | 45 ## @seealso{fileparts, filesep} |
41 ## @end deftypefn | 46 ## @end deftypefn |
42 | 47 |
43 ## Author: Carnë Draug <carandraug@octave.org> | 48 ## Author: Carnë Draug <carandraug@octave.org> |
44 | 49 |
47 if (nargin && iscell (varargin{end})) | 52 if (nargin && iscell (varargin{end})) |
48 filename = cellfun (@(x) fullfile (varargin{1:end-1}, x), varargin{end}, | 53 filename = cellfun (@(x) fullfile (varargin{1:end-1}, x), varargin{end}, |
49 "UniformOutput", false); | 54 "UniformOutput", false); |
50 else | 55 else |
51 non_empty = cellfun ("isempty", varargin); | 56 non_empty = cellfun ("isempty", varargin); |
57 if (ispc && ! isempty (varargin)) | |
58 varargin = strrep (varargin, "/", filesep); | |
59 varargin(1) = regexprep (varargin{1}, '[\\/]*([a-zA-Z]:[\\/]*)', "$1"); | |
60 endif | |
52 filename = strjoin (varargin(! non_empty), filesep); | 61 filename = strjoin (varargin(! non_empty), filesep); |
53 filename(strfind (filename, [filesep filesep])) = ""; | 62 filename(strfind (filename, [filesep filesep])) = ""; |
54 endif | 63 endif |
55 | 64 |
56 endfunction | 65 endfunction |
57 | 66 |
58 | 67 |
59 %!shared fs, fsx, xfs, fsxfs, xfsy | 68 %!shared fs, fsx, xfs, fsxfs, xfsy, xfsyfs |
60 %! fs = filesep (); | 69 %! fs = filesep (); |
61 %! fsx = [fs "x"]; | 70 %! fsx = [fs "x"]; |
62 %! xfs = ["x" fs]; | 71 %! xfs = ["x" fs]; |
63 %! fsxfs = [fs "x" fs]; | 72 %! fsxfs = [fs "x" fs]; |
64 %! xfsy = ["x" fs "y"]; | 73 %! xfsy = ["x" fs "y"]; |
74 %! xfsyfs = ["x" fs "y" fs]; | |
75 | |
65 %!assert (fullfile (""), "") | 76 %!assert (fullfile (""), "") |
66 %!assert (fullfile (fs), fs) | 77 %!assert (fullfile (fs), fs) |
67 %!assert (fullfile ("", fs), fs) | 78 %!assert (fullfile ("", fs), fs) |
68 %!assert (fullfile (fs, ""), fs) | 79 %!assert (fullfile (fs, ""), fs) |
69 %!assert (fullfile ("", fs), fs) | 80 %!assert (fullfile ("", fs), fs) |
80 %!assert (fullfile (fs, "x"), fsx) | 91 %!assert (fullfile (fs, "x"), fsx) |
81 %!assert (fullfile (fs, xfs), fsxfs) | 92 %!assert (fullfile (fs, xfs), fsxfs) |
82 %!assert (fullfile (fsx, fs), fsxfs) | 93 %!assert (fullfile (fsx, fs), fsxfs) |
83 %!assert (fullfile (fs, "x", fs), fsxfs) | 94 %!assert (fullfile (fs, "x", fs), fsxfs) |
84 | 95 |
85 %!assert (fullfile ("a/", "/", "/", "b", "/", "/"), "a/b/") | 96 %!assert (fullfile ("x/", "/", "/", "y", "/", "/"), xfsyfs) |
86 %!assert (fullfile ("/", "a/", "/", "/", "b", "/", "/"), "/a/b/") | 97 %!assert (fullfile ("/", "x/", "/", "/", "y", "/", "/"), [fs xfsyfs]) |
87 %!assert (fullfile ("/a/", "/", "/", "b", "/", "/"), "/a/b/") | 98 %!assert (fullfile ("/x/", "/", "/", "y", "/", "/"), [fs xfsyfs]) |
88 | 99 |
89 ## different on purpose so that "fullfile (c{:})" works for empty c | 100 ## different on purpose so that "fullfile (c{:})" works for empty c |
90 %!assert (fullfile (), "") | 101 %!assert (fullfile (), "") |
91 | 102 |
92 %!assert (fullfile ("a", "b", {"c", "d"}), {"a/b/c", "a/b/d"}) | 103 %!assert (fullfile ("x", "y", {"c", "d"}), {[xfsyfs "c"], [xfsyfs "d"]}) |
93 | 104 |
105 %% Windows specific - drive letters and file sep type | |
106 %!test | |
107 %! if (ispc) | |
108 %! assert (fullfile ('\/\/\//A:/\/\', "x/", "/", "/", "y", "/", "/"), ... | |
109 %! ['A:\' xfsyfs]); | |
110 %! endif | |
111 | |
112 %% Windows specific - drive letters and file sep type, cell array | |
113 %!test | |
114 %! if (ispc) | |
115 %! tmp = fullfile ({"\\\/B:\//", "A://c", "\\\C:/g/h/i/j\/"}); | |
116 %! assert (tmp{1}, 'B:\'); | |
117 %! assert (tmp{2}, 'A:\c'); | |
118 %! assert (tmp{3}, 'C:\g\h\i\j\'); | |
119 %! endif |