function varargout = amt_subdir(varargin)
%AMT_SUBDIR Performs a recursive file search
%
% Usage:
% amt_subdir
% amt_subdir(name)
% files = amt_subdir(...)
%
% This function performs a recursive file search. The input and output
% format is identical to the dir function.
%
% Input parameters:
% name: pathname or filename for search, can be absolute or relative
% and wildcards (*) are allowed. If ommitted, the files in the
% current working directory and its child folders are returned
%
% Output parameters:
% files: m x 1 structure with the following fields:
%
% '.name' full filename
%
% '.date' modification date timestamp
%
% '.bytes' number of bytes allocated to the file
%
% '.isdir' 1 if name is a directory; 0 if no
%
% Example:
% a = subdir(fullfile(matlabroot, 'toolbox', 'matlab', '.mat'))
%
%
% Copyright 2006 Kelly Kearney
% Kelly Kearney (2021). subdir: a recursive file search https://github.com/kakearney/subdir-pkg
%
% Url: http://amtoolbox.sourceforge.net/amt-0.10.0/doc/core/amt_subdir.php
% Copyright (C) 2009-2020 Piotr Majdak and the AMT team.
% This file is part of Auditory Modeling Toolbox (AMT) version 1.0.0
%
% 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/>.
% #License: mit
% #Author: Kelly Kearney
% #Author: Clara Hollomey (for AMT)
%---------------------------
% Get folder and filter
%---------------------------
narginchk(0,1);
nargoutchk(0,1);
if nargin == 0
folder = pwd;
filter = '*';
else
[folder, name, ext] = fileparts(varargin{1});
if isempty(folder)
folder = pwd;
end
if isempty(ext)
if isdir(fullfile(folder, name))
folder = fullfile(folder, name);
filter = '*';
else
filter = [name ext];
end
else
filter = [name ext];
end
if ~isdir(folder)
error('Folder (%s) not found', folder);
end
end
%---------------------------
% Search all folders
%---------------------------
pathstr = genpath_local(folder);
pathfolders = regexp(pathstr, pathsep, 'split'); % Same as strsplit without the error checking
pathfolders = pathfolders(~cellfun('isempty', pathfolders)); % Remove any empty cells
Files = [];
%pathandfilt = fullfile(pathfolders, filter);
%for ifolder = 1:length(pathandfilt)
for ifolder = 1:length(pathfolders)
pathandfilt = fullfile(char(pathfolders(ifolder)), filter);
% NewFiles = dir(pathandfilt{ifolder});
NewFiles = dir(pathandfilt);
if ~isempty(NewFiles)
fullnames = cellfun(@(a) fullfile(pathfolders{ifolder}, a), {NewFiles.name}, 'UniformOutput', false);
[NewFiles.name] = deal(fullnames{:});
Files = [Files; NewFiles];
end
end
%---------------------------
% Prune . and ..
%---------------------------
if ~isempty(Files)
[~, ~, tail] = cellfun(@fileparts, {Files(:).name}, 'UniformOutput', false);
dottest = cellfun(@(x) isempty(regexp(x, '\.+(\w+$)', 'once')), tail);
Files(dottest & [Files(:).isdir]) = [];
end
%---------------------------
% Output
%---------------------------
if nargout == 0
if ~isempty(Files)
amt_disp(' ');
amt_disp(Files.name);
amt_disp(' ');
end
elseif nargout == 1
varargout{1} = Files;
end
function [p] = genpath_local(d)
% Modified genpath that doesn't ignore:
% - Folders named 'private'
% - MATLAB class folders (folder name starts with '@')
% - MATLAB package folders (folder name starts with '+')
files = dir(d);
if isempty(files)
return
end
p = ''; % Initialize output
% Add d to the path even if it is empty.
p = [p d pathsep];
% Set logical vector for subdirectory entries in d
isdir = logical(cat(1,files.isdir));
dirs = files(isdir); % Select only directory entries from the current listing
for i=1:length(dirs)
dirname = dirs(i).name;
if i > 1
p = [p pathsep];
end
if ~strcmp( dirname,'.') && ~strcmp( dirname,'..')
p = [p genpath(fullfile(d,dirname))]; % Recursive calling of this function.
end
end
%===============================================================================
%The MIT License (MIT)
%Copyright (c) 2015 Kelly Kearney
%Permission is hereby granted, free of charge, to any person obtaining a copy of
%this software and associated documentation files (the "Software"), to deal in
%the Software without restriction, including without limitation the rights to
%use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
%the Software, and to permit persons to whom the Software is furnished to do so,
%subject to the following conditions:
%The above copyright notice and this permission notice shall be included in all
%copies or substantial portions of the Software.
%THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
%IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
%FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
%COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
%IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
%CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.