#include "patprep.h" #include #include #include // This is a copy of the patprep() function from the original 1983 version of // locate.c. I have annotated it heavily in order to document, in my own mind at // any rate, exactly what it does, step by step. // Globfree is limited to 100 characters. static char globfree[100]; char *patprep(name) char *name; { register char *endmark, *p, *subp; subp = globfree; *subp++ = '\0'; // Go to the very end of the string passed in. p = name + strlen(name) - 1; /* starting from the END of the string, skip trailing metacharacters (and [] ranges) */ for (; p >= name; p--) // Index is mis-named; it returns a pointer to the first // instance of the character '*p' in the content of the // static string here. In this case, it's saying that // if there is no metacharacter, break out? if (index("*?", *p) == 0) break; if (p < name) p = name; // Skip past a range operator. if (*p == ']') for (p--; p >= name; p--) if (*p == '[') { p--; break; } if (p < name) p = name; /* * if pattern has only metacharacters, check every path (force '/' * search) */ // We got to the start of the string. At least give it an anchoring '/', // so the matcher has something it can makes sense of. if ((p == name) && index("?*[]", *p) != 0) *subp++ = '/'; else { // Okay, from where we were, scan backwards until we find another // metacharacter or the root of the search string, in which case we have // a literal substring. for (endmark = p; p >= name; p--) if (index("]*?", *p) != 0) break; // From the first non-metacharacter found to the first metacharacter (or // EOL), copy that substring into the 100-byte reserve. for (++p; (p <= endmark) && subp < (globfree + sizeof(globfree));) *subp++ = *p++; } // Give a null ending. *subp = '\0'; // Return a pointer to the last byte of the pattern reserve. return (--subp); }