Skip to content

Commit

Permalink
Merge pull request #109 from Remi-Gau/remi_refactor_lint
Browse files Browse the repository at this point in the history
refactoring and linting
  • Loading branch information
Remi-Gau authored Jan 20, 2021
2 parents 7de42bf + d53bdf5 commit 6c1dac6
Show file tree
Hide file tree
Showing 11 changed files with 1,058 additions and 737 deletions.
192 changes: 129 additions & 63 deletions +bids/+internal/file_utils.m
Original file line number Diff line number Diff line change
@@ -1,15 +1,39 @@
function varargout = file_utils(str, varargin)
%
% Character array (or cell array of strings) handling facility
% FORMAT str = bids.internal.file_utils(str,option)
%
%
% To list files or directories (with fullpath if necessary)
%
% FORMAT [files, dirs] = bids.internal.file_utils('List', directory, regexp)
% FORMAT [files, dirs] = bids.internal.file_utils('FPList', directory, regexp)
% FORMAT [dirs] = bids.internal.file_utils('List', directory, 'dir', regexp)
% FORMAT [dirs] = bids.internal.file_utils('FPList', directory, 'dir', regexp)
%
%
%
% To get a certain piece of information from a file.
%
% FORMAT str = bids.internal.file_utils(str, option)
%
% str - character array, or cell array of strings
%
% option - string of requested item - one among:
% {'path', 'basename', 'ext', 'filename', 'cpath', 'fpath'}
%
% FORMAT str = bids.internal.file_utils(str,opt_key,opt_val,...)
%
%
% To set a certain piece of information from a file.
%
% FORMAT str = bids.internal.file_utils(str, opt_key, opt_val,...)
%
% str - character array, or cell array of strings
%
% opt_key - string of targeted item - one among:
% {'path', 'basename', 'ext', 'filename', 'prefix', 'suffix'}
%
% opt_val - string of new value for feature
%
% __________________________________________________________________________
%
% Based on spm_file.m and spm_select.m from SPM12.
Expand Down Expand Up @@ -44,9 +68,9 @@
case 'filename'
str{n} = [nam ext];
case 'cpath'
str(n) = cpath(str(n));
str(n) = canonicalise_path(str(n));
case 'fpath'
str{n} = fileparts(char(cpath(str(n))));
str{n} = fileparts(char(canonicalise_path(str(n))));
otherwise
error('Unknown option: ''%s''', options{1});
end
Expand Down Expand Up @@ -89,76 +113,99 @@
end
varargout = {str};

end

function t = canonicalise_path(t, d)
% ==========================================================================
% -Canonicalise paths to full path names
% ==========================================================================
function t = cpath(t, d)
%
% canonicalise paths to full path names, removing xxx/./yyy and xxx/../yyy
% constructs
% t must be a cell array of (relative or absolute) paths, d must be a
% single cell containing the base path of relative paths in t
%
% - t must be a cell array of (relative or absolute) paths
%
% - d must be a single cell containing the base path of relative paths in t
%

mch = '^/';
if ispc % valid absolute paths
% Allow drive letter or UNC path
mch = '^([a-zA-Z]:)|(\\\\[^\\]*)';
else
mch = '^/';
end

if (nargin < 2) || isempty(d)
d = {pwd};
end

% Find partial paths, prepend them with d
ppsel = cellfun(@isempty, regexp(t, mch, 'once'));
t(ppsel) = cellfun(@(t1)fullfile(d{1}, t1), t(ppsel), 'UniformOutput', false);

% Break paths into cell lists of folder names
pt = pathparts(t);

% Remove single '.' folder names
sd = cellfun(@(pt1)strcmp(pt1, '.'), pt, 'UniformOutput', false);
for cp = 1:numel(pt)
pt{cp} = pt{cp}(~sd{cp});
end
% Go up one level for '..' folders, don't remove drive letter/server name
% from PC path

% Go up one level for '..' folders, don't remove drive letter/server name from PC path
ptstart = 1;
if ispc
ptstart = 2;
else
ptstart = 1;
end

for cp = 1:numel(pt)

tmppt = {};

for cdir = ptstart:numel(pt{cp})
if strcmp(pt{cp}{cdir}, '..')
tmppt = tmppt(1:end - 1);
else
tmppt{end + 1} = pt{cp}{cdir};
end
end

pt{cp} = tmppt;
if ispc
pt{cp} = [pt{cp}(1) tmppt];
else
pt{cp} = tmppt;
end

end

% Assemble paths
t = cellfun(@(pt1)fullfile(filesep, pt1{:}), pt, 'UniformOutput', false);
if ispc
t = cellfun(@(pt1)fullfile(pt1{:}), pt, 'UniformOutput', false);
else
t = cellfun(@(pt1)fullfile(filesep, pt1{:}), pt, 'UniformOutput', false);
end

end

function pp = pathparts(p)
% ==========================================================================
% -Parse paths
% ==========================================================================
function pp = pathparts(p)
%
% parse paths in cellstr p
%
% returns cell array of path component cellstr arrays
%
% For PC (WIN) targets, both '\' and '/' are accepted as filesep, similar
% to MATLAB fileparts
%

file_separator = filesep;
if ispc
fs = '\\/';
else
fs = filesep;
file_separator = '\\/';
end
pp = cellfun(@(p1)textscan(p1, '%s', 'delimiter', fs, 'MultipleDelimsAsOne', 1), p);

pp = cellfun(@(p1)textscan(p1, '%s', ...
'delimiter', file_separator, ...
'MultipleDelimsAsOne', 1), p);

if ispc
for k = 1:numel(pp)
if ~isempty(regexp(pp{k}{1}, '^[a-zA-Z]:$', 'once'))
Expand All @@ -169,17 +216,22 @@
end
end

end

function [files, dirs] = listfiles(action, directory, varargin)
% ==========================================================================
% -List files and directories
% ==========================================================================
function [fi, di] = listfiles(action, d, varargin)
% FORMAT [files, dirs] = listfiles('List',dir,regexp)
% FORMAT [files, dirs] = listfiles('FPList',dir,regexp)
% FORMAT [dirs] = listfiles('List',dir,'dir',regexp)
% FORMAT [dirs] = listfiles('FPList',dir,'dir',regexp)

fi = '';
di = '';
%
% FORMAT [files, dirs] = listfiles('List', directory, regexp)
% FORMAT [files, dirs] = listfiles('FPList', directory, regexp)
% FORMAT [dirs] = listfiles('List', directory, 'dir', regexp)
% FORMAT [dirs] = listfiles('FPList', directory, 'dir', regexp)
%

files = '';
dirs = '';

switch lower(action)
case 'list'
fp = false;
Expand All @@ -188,50 +240,64 @@
otherwise
error('Invalid action: ''%s''.', action);
end

directory = bids.internal.file_utils(directory, 'cpath');
if nargin < 2
d = pwd;
else
d = bids.internal.file_utils(d, 'cpath');
directory = pwd;
end
dirmode = false;
if nargin < 3
expr = '.*';
else
if strcmpi(varargin{1}, 'dir')
dirmode = true;
if nargin < 4
expr = '.*';
else
expr = varargin{2};
end
else
expr = varargin{1};
end
end
dd = dir(d);

dd = dir(directory);
if isempty(dd)
return
end
fi = sort({dd(~[dd.isdir]).name})';
di = sort({dd([dd.isdir]).name})';
di = setdiff(di, {'.', '..'});

% set if we work on directory or files
% set regular expression to use
dirmode = false;
expr = '.*';

if nargin >= 3
expr = varargin{1};
end
if nargin == 3 && strcmpi(varargin{1}, 'dir')
dirmode = true;
end
if nargin >= 3 && strcmpi(varargin{1}, 'dir')
dirmode = true;
expr = varargin{2};
end

files = sort({dd(~[dd.isdir]).name})';
dirs = sort({dd([dd.isdir]).name})';
dirs = setdiff(dirs, {'.', '..'});

if dirmode
t = regexp(di, expr);
if numel(di) == 1 && ~iscell(t)

t = regexp(dirs, expr);

if numel(dirs) == 1 && ~iscell(t)
t = {t};
end
di = di(~cellfun(@isempty, t));
fi = di;
dirs = dirs(~cellfun(@isempty, t));
files = dirs;

else
t = regexp(fi, expr);
if numel(fi) == 1 && ~iscell(t)

t = regexp(files, expr);

if numel(files) == 1 && ~iscell(t)
t = {t};
end
fi = fi(~cellfun(@isempty, t));
files = files(~cellfun(@isempty, t));

end

if fp
fi = cellfun(@(x) fullfile(d, x), fi, 'UniformOutput', false);
di = cellfun(@(x) fullfile(d, x), di, 'UniformOutput', false);
files = cellfun(@(x) fullfile(directory, x), files, 'UniformOutput', false);
dirs = cellfun(@(x) fullfile(directory, x), dirs, 'UniformOutput', false);
end
fi = char(fi);
di = char(di);

files = char(files);
dirs = char(dirs);

end
Loading

0 comments on commit 6c1dac6

Please sign in to comment.