#!mkcmd # $Id: samepath.m,v 1.2 2005/10/30 03:12:36 ksb Exp $ # %hi #if !defined(SamePath) #define SamePath(Mglob, Mfile) _SamePath(Mglob, Mfile, 1) extern int _SamePath(char *pcGlob, char *pcFile, int fDot); #endif %% %c /* _SamePath() -- from install.d/special.c * We want /bin/* to match every file in /bin OK. (ksb) * return non-zero for a glob match, 0 for not a match. */ int _SamePath(pcGlob, pcFile, fDot) char *pcGlob; /* the pattern to match */ char *pcFile; /* the file to match with */ int fDot; /* are we at the start of pcFile, or post '/' */ { register char *pc; register int iLenGlob, iLenFile; auto int bFound, cStop; auto int fStarStar; for (;;) { switch (*pcGlob) { case '*': /* match any string */ fStarStar = '*' == pcGlob[1]; if (fStarStar) { ++pcGlob; } pc = ++pcGlob; iLenGlob = 0; while ('\\' != *pc && '?' != *pc && '[' != *pc && '*' != *pc && '\000' != *pc && '/' != *pc) { ++pc, ++iLenGlob; } if (fStarStar) { iLenFile = strlen(pcFile); } else { iLenFile = 0; while ('/' != pcFile[iLenFile] && '\000' != pcFile[iLenFile] && (!fDot || '.' != pcFile[iLenFile])) { ++iLenFile; fDot = 0; } } bFound = 0; do { if (iLenGlob == 0 || 0 == strncmp(pcGlob, pcFile, iLenGlob)) { if (_SamePath(pc, pcFile+iLenGlob, fDot)) { bFound = 1; break; } } --iLenFile, ++pcFile; } while (iLenFile >= iLenGlob); return bFound; case '[': /* any of */ ++pcGlob; cStop = *pcFile++; if (cStop == '/') /* range never match '/' */ break; bFound = 0; if ('-' == *pcGlob) { bFound = '-' == cStop; ++pcGlob; } while (']' != *pcGlob) { if ('-' == pcGlob[1]) { if (pcGlob[0] <= cStop && cStop <= pcGlob[2]) bFound = 1; pcGlob += 2; } else { if (pcGlob[0] == cStop) bFound = 1; } ++pcGlob; } ++pcGlob; if (!bFound) break; continue; case '?': /* any single char but '/' */ if ('/' == *pcFile || (fDot && '.' == *pcFile) || '\000' == *pcFile) break; ++pcGlob, ++pcFile; fDot = 0; continue; case '\\': /* next char not special */ ++pcGlob; /*fall through*/ case '/': /* delimiter */ fDot = 1; if (*pcGlob != *pcFile) break; ++pcGlob; do { ++pcFile; } while ('/' == *pcFile); continue; default: /* or any other character */ fDot = 0; if (*pcGlob != *pcFile) break; ++pcGlob, ++pcFile; continue; case '\000': /* end of pattern, end of file name */ return '\000' == *pcFile; } break; } return 0; } %%