/* wild.c - wildcard routines */ #include "copyright.h" #include "config.h" #include "db.h" #include "mudconf.h" #include "externs.h" int wild1(char *tstr, char *dstr, int arg, char *args[], int nargs) { char *copy; int startarg, i; copy = NULL; startarg = arg; while (*tstr) { switch (*tstr) { case '\\': /* Escape character: Treat the next character as * a literal char to match, not a potential * wildcard. */ tstr++; if (*tstr) { if (ToLower(*dstr) != ToLower(*tstr)) { for (i=startarg; i<nargs; i++) { if (args[i] != NULL) free_lbuf(args[i]); args[i] = NULL; } return 0; } dstr++; tstr++; } break; case '?': /* Single character match. * If at end of data, return FALSE. * Otherwise, match the character. */ if (!*dstr) { for (i=startarg; i<nargs; i++) { if (args[i] != NULL) free_lbuf(args[i]); args[i] = NULL; } return 0; } if (arg < nargs) { if (args[arg] == NULL) args[arg] = alloc_lbuf("wild1.?"); args[arg][0] = *dstr; args[arg][1] = '\0'; arg++; } tstr++; dstr++; break; case '*': /* Multi-character match * If what follows matches, return success * If we are at the end of the data string, * return failure * Otherwise, move a character and retry */ if (wild1(tstr+1, dstr, arg+1, args, nargs)) { if (copy != NULL) *copy = '\0'; return 1; } if (!*dstr) { for (i=startarg; i<nargs; i++) { if (args[i] != NULL) free_lbuf(args[i]); args[i] = NULL; } return 0; } if ((copy == NULL) && (arg < nargs)) { if (args[arg] == NULL) args[arg] = alloc_lbuf("wild1.*"); copy = args[arg]; } if (copy != NULL) *copy++ = *dstr; dstr++; break; default: if (ToLower(*dstr) != ToLower(*tstr)) { for (i=startarg; i<nargs; i++) { if (args[i] != NULL) free_lbuf(args[i]); args[i] = NULL; } return 0; } dstr++; tstr++; } } if (*dstr) { for (i=startarg; i<nargs; i++) { if (args[i] != NULL) free_lbuf(args[i]); args[i] = NULL; } return 0; } return 1; } int wild(char *tstr, char *dstr, char *args[], int nargs) { int i; for (i=0; i<nargs; i++) args[i] = NULL; return wild1(tstr, dstr, 0, args, nargs); } int quick_wild(char *s, char *d) { while (*s) { switch(*s) { case '?': if (!*d) return 0; s++; d++; break; case '*': if (quick_wild(s+1,d)) return 1; if (!*d) return 0; d++; break; default: if (ToLower(*s) != ToLower(*d)) return 0; s++; d++; } } if (*d) return 0; return 1; } int wild_match(char *tstr, char *dstr, char *args[], int nargs) { int i; switch (*tstr) { case '>': for (i=0; i<nargs; i++) args[i] = NULL; tstr++; if (isdigit(*tstr) || (*tstr == '-')) return (atoi(tstr) < atoi(dstr)); else return (strcmp(tstr, dstr) < 0); case '<': for (i=0; i<nargs; i++) args[i] = NULL; tstr++; if (isdigit(*tstr) || (*tstr == '-')) return (atoi(tstr) > atoi(dstr)); else return (strcmp(tstr, dstr) > 0); default: if (nargs == 0) return quick_wild(tstr, dstr); else return wild(tstr, dstr, args, nargs); } }