rlocate/crates/squozen/docs/patprep/patprep.c

75 lines
2.0 KiB
C

#include "patprep.h"
#include <stdio.h>
#include <string.h>
#include <strings.h>
// 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);
}