/* * csh a shell by PJAC * glob.c - glob pattern matching */ #include "csh.h" #ifdef MSDOS #include "ndir.h" #else #include #include #endif /* * explode match into buf */ explode(match, buf) char *match, *buf; { static DIR *dirp; static char stem[128]; static char tail[MAX_CWD]; static int stemp; struct direct *d; int state; char *p, *q; if(match != 0){ /* if match is non zero then start a new match */ if(dirp != 0){ closedir(dirp); dirp = 0; } q = rindex(match, '/'); p = rindex(match, '\\'); if(p || q){ if(!p) p = q; if(p > q) q = p; for(p = stem ; match < q ; *p++ = *match++); *p = '\0'; dirp = opendir(stem); *p++ = *match++; *p = '\0'; } else { *stem = '\0'; dirp = opendir("."); if(dirp == 0) dirp = opendir(""); } if(dirp == 0) /* cannot glob it */ return(0); strcpy(tail, match); stemp = strlen(stem); } if(dirp == 0) /* this should never occur */ return(0); while((d = readdir(dirp)) ){ if(d->d_name[0] == '.' && *tail != '.') continue; state = g_match(d->d_name, tail); if(state < 0) syn_err(); if(state > 0){ strcpy(buf, stem); strcpy(buf + stemp, d->d_name); return(1); } } closedir(dirp); dirp = 0; return(0); } /* * match string, given pat */ g_match(str, pat) char *str, *pat; { int found; for(;*pat;) switch(*pat){ case '*': pat++; do { if(g_match(str, pat)) return(1); } while(*str++); return(0); case '?': if(!*str++) return(0); pat++; continue; default: if(*str++ != *pat++) return(0); continue; case '[': for(found = 0, pat++ ; *pat && *pat != ']'; pat++){ if(found) continue; if(*(pat+1) == '-'){ if(pat[2] && pat[2] != ']'){ if(*str>= *pat && *str<= pat[2]) found = 1; pat += 2; continue; } } if(*pat == *str) found = 1; } if(*pat++ != ']') return(-1); if(!found) return(0); str++; continue; case ']': /* syntax error */ return(-1); } return(*str == '\0'); }