NAME
Mpp::Glob -- Subroutines for reading directories easily.
USAGE
my @file_info_structs = Mpp::Glob::zglob_fileinfo('pattern'[, default dir]);
my @filenames = Mpp::Glob::zglob('pattern'[, default dir]);
$Mpp::Glob::allow_dot_files = 1; # Enable returning files beginning with '.'.
wildcard_action @wildcards, sub { my $finfo = $_[0]; ... };
DESCRIPTION
Mpp::Glob::zglob
This subroutine performs globbing without forking off to the csh, so in principle it may be faster than using the builtin perl glob. It also supports some limited extended wildcards (ideas stolen from zsh).
* Matches any text
? Matches one character
[range] Matches a range just like the unix wildcards.
** Matches an arbitrary list of directories. This
is a shortcut to running "find" on the directory
tree. For example, 'x/**/a.o' matches 'x/a.o',
'x/y/a.o', 'x/y/z/a.o', etc. Like find, it does
not search through directories specified by
symbolic links.
If the argument to zglob does not have any wildcard characters in it, the file name is returned if the file exists; an empty list is returned if it does not exist. (This is different from the shell's usual globbing behaviour.) If wildcard characters are present, then a list of files matching the wildcard is returned. If no files match, an empty list is returned.
If you want a subroutine which returns something even if no files matched, then call zglob_fileinfo_atleastone. This has the same behavior as the Bourne shell, which returns the wildcard or filename verbatim even if nothing matches.
The second argument to zglob
is the default directory, which is used if you specify a relative file name. If not specified, uses the current default directory. zglob
doesn't repeatedly call Cwd::cwd to get the directory; instead, it uses the Mpp::File package to track the current directory. (This means that it overrides chdir
in your module to be something that stores the current directory.)
By default, zglob
does not return file names beginning with '.'. You can force it to return these files by setting $Mpp::Glob::allow_dot_files=1, or (as with the shell) by specifing a leading . in the wildcard pattern (e.g., '.*').
zglob
only returns files that exists and are readable, or can be built.
zglob
returns a list of file names. It uses an internal subroutine, zglob_fileinfo
, which returns a list of Mpp::File structures. See the Mpp::File package for more details.
Mpp::Glob::find_all_subdirs
my @subdirs = Mpp::Glob::find_all_subdirs($dirinfo)
Returns Mpp::File structures for all the subdirectories immediately under the given directory. These subdirectories might not exist yet; we return Mpp::File structures for any Mpp::File for which has been treated as a directory in calls to Mpp::File::file_info.
We do not follow symbolic links. This is necessary to avoid infinite recursion and a lot of other bad things.
Mpp::Glob::find_all_subdirs_recursively
my @subdirs = Mpp::Glob::find_all_subdirs_recursively($dirinfo);
Returns Mpp::File structures for all the subdirectories of the given directory, or subdirectories of subdirectories of that directory, or....
The subdirectories are returned in a breadth-first manner. The directory specified as an argument is not included in the list.
Subdirectories beginning with '.' are not returned unless $Mpp::Glob::allow_dot_files is true.
Mpp::Glob::wildcard_action
You generally should not call this subroutine directly; it's intended to be called from the chain of responsibility handled by ::wildcard_action.
This subroutine is the key to handling wildcards in pattern rules and dependencies. Usage:
wildcard_action @wildcards, sub {
my ($finfo, $was_wildcard_flag) = @_;
...
};
The subroutine is called once for each file that matches the wildcards. If at some later time, files which match the wildcard are created (or we find rules to build them), then the subroutine is called again. (Internally, this is done by Mpp::File::publish, which is called automatically whenever a file which didn't used to exist now exists, or whenever a build rule is specified for a file which does not currently exist.)
You can specify non-wildcards as arguments to wildcard_action. In this case, the subroutine is called once for each of the files explicitly listed, even if they don't exist and there is no build command for them yet. Use the second argument to the subroutine to determine whether there was actually a wildcard or not, if you need to know.
As with Mpp::Glob::zglob, wildcard_action will match files in directories which don't yet exist, as long as the appropriate Mpp::File structures have been put in by calls to file_info().
Of course, there are ways of creating new files which will not be detected by wildcard_action(), since it only looks at things that it expects to be modified. For example, directories are not automatically reread (but when they are reread, new files are noticed). Also, creation of new symbolic links to directories may deceive the system.
There are two restrictions on wildcards handled by this routine. First, it will not soft-linked directories correctly after the first wildcard. For example, if you do this:
**/xyz/*.cxx
in order to match all .cxx files somewhere in a subdirectory called "xyz", and "xyz" is actually a soft link to some other part of the file system, then your .cxx files will not be found. This is only true if the soft link occurs after the first wildcard; something like 'xyz/*.cxx' will work fine even if xyz is a soft link.
Similarly, after the first wildcard specification, '..' will not work as expected. (It works fine if it's present before all wildcards.) For example, consider something like this:
**/xyz/../*.cxx
In theory, this should find all .cxx files in directories that have a subdirectory called xyz. This won't work with wildcard_action (it'll work fine with zglob_fileinfo above, however). wildcard_action emits a warning message in this case.