/* Do not remove the headers from this file! see /USAGE for more info. */
#define CARET_AS_NOT
nosave private mapping cache = ([]);
int has_magic( string s ){
return sizeof( regexp( ({ s }), "[\\[\\*\\]\\?]"));
}
// The flag toggles whether or not ^ and $ are valid.
// 1 means valid.
varargs string translate( string pat, int flag )
{
int i, j, n;
string res, stuff;
n = strlen(pat);
res = "";
for( i = 0; i < n; i++ )
{
if( pat[i] == '\\' && i+1 != n ){
res += pat[i..++i];
continue;
}
switch( pat[i] ){
case '^':
case '$':
if(flag)
{
res += pat[i..i];
continue;
}
case '.':
res += "\\" + pat[i..i];
continue;
case '*':
res += ".*";
continue;
case '?':
res += ".";
continue;
case '[':
j=i;
if( j<n && pat[j] == '!' ) j++;
#ifdef CARET_AS_NOT
if( j<n && pat[j] == '^' ) j++;
#endif
if( j<n && pat[j] == ']' ) j++;
while( j < n && pat[j] != ']' ) j++;
if( j >= n )
res += "\\[";
else{
stuff = pat[i+1..j];
#ifndef CARET_AS_NOT
if( member_array('^', stuff) != -1 )
stuff = replace_string(stuff,"^","\\^");
#endif
i = j;
if( strlen(stuff) > 2 && stuff[0] == '!' ) stuff = "[^"+stuff[1..];
else stuff = "[" + stuff;
res += stuff;
}
continue;
default:
res+= pat[i..i];
continue;
}
}
return res;
}
int fnmatch( string name, string pattern )
{
string result;
if( undefinedp(cache[pattern]) ){
result = "^"+translate(pattern)+"$";
cache[pattern] = result;
}
return sizeof( regexp( ({ name }), cache[pattern] ) );
}
private string* glob1( string dirname, string pattern){
mixed* names, result;
string name;
int i,j;
names = get_dir(dirname+"/*");
result = ({});
j = sizeof(names);
for(i=0;i<j;i++){
name = names[i];
if(name != "." && name != ".."){
if (fnmatch(name, pattern)){
result += ({ name });
}
}
}
return result;
}
string* glob( mixed pathname ){
string dirname, basename, name;
mixed* list, result, sublist;
int i;
if( !stringp(pathname) ) return ({});
if( !has_magic(pathname) ){
if( path_exists( pathname ) ){
return ({ pathname });
}
else{
return ({});
}
}
pathname = split_path( pathname );
dirname = pathname[0];
basename = pathname[1];
if( has_magic(dirname) ){
list = glob(dirname);
}
else{
list = ({ dirname });
}
if( !has_magic(basename) ){
result = ({});
i = sizeof(list);
while(i--){
dirname = list[i];
if( basename || is_directory(dirname) ){
name = dirname+"/"+basename;
if( path_exists(name) )
{
result += ({ name });
}
}
}
}
else{
result = ({});
i = sizeof(list);
while(i--){
dirname = list[i];
if(!strlen(dirname)) continue;
if( dirname[<1] == '/' )
{
if( strlen(dirname) == 1 )
dirname = "";
else
dirname = dirname[0..<2];
}
sublist = glob1( dirname, basename );
sublist = map_array( sublist, (: $(dirname) + "/" + $1 :) );
result += sublist;
}
}
return result;
}