src/wild.c File Reference

#include "copyright.h"
#include "config.h"
#include "db.h"
#include "mudconf.h"
#include "externs.h"
#include "alloc.h"

Include dependency graph for wild.c:

Go to the source code of this file.

Defines

#define FIXCASE(a)   (ToLower(a))
#define EQUAL(a, b)   ((a == b) || (FIXCASE(a) == FIXCASE(b)))
#define NOTEQUAL(a, b)   ((a != b) && (FIXCASE(a) != FIXCASE(b)))

Functions

int quick_wild (char *tstr, char *dstr)
int wild1 (char *tstr, char *dstr, int arg)
int wild (char *tstr, char *dstr, char *args[], int nargs)
int wild_match (char *tstr, char *dstr)

Variables

static char ** arglist
static int numargs


Define Documentation

#define EQUAL ( a,
 )     ((a == b) || (FIXCASE(a) == FIXCASE(b)))

Definition at line 26 of file wild.c.

Referenced by quick_wild().

#define FIXCASE (  )     (ToLower(a))

Definition at line 25 of file wild.c.

#define NOTEQUAL ( a,
 )     ((a != b) && (FIXCASE(a) != FIXCASE(b)))

Definition at line 27 of file wild.c.

Referenced by quick_wild(), wild(), and wild1().


Function Documentation

int quick_wild ( char *  tstr,
char *  dstr 
)

Do a wildcard match, without remembering the wild data. This routine will cause crashes if fed NULLs instead of strings.

Definition at line 36 of file wild.c.

References EQUAL, NOTEQUAL, and quick_wild().

Referenced by badname_check(), check_filter(), find_wild_attrs(), fun_grab(), fun_graball(), fun_match(), fun_matchall(), fun_strmatch(), fun_switch(), help_write(), quick_wild(), wild(), wild1(), and wild_match().

00037 {
00038         while (*tstr != '*') {
00039                 switch (*tstr) {
00040                 case '?':
00041                         /*
00042                          * Single character match.  Return false if at * end
00043                          * * * * of data. 
00044                          */
00045                         if(!*dstr)
00046                                 return 0;
00047                         break;
00048                 case '\\':
00049                         /*
00050                          * Escape character.  Move up, and force literal * *
00051                          * * * match of next character. 
00052                          */
00053                         tstr++;
00054                         /*
00055                          * FALL THROUGH 
00056                          */
00057                 default:
00058                         /*
00059                          * Literal character.  Check for a match. * If * * *
00060                          * matching end of data, return true. 
00061                          */
00062                         if(NOTEQUAL(*dstr, *tstr))
00063                                 return 0;
00064                         if(!*dstr)
00065                                 return 1;
00066                 }
00067                 tstr++;
00068                 dstr++;
00069         }
00070 
00071         /*
00072          * Skip over '*'. 
00073          */
00074 
00075         tstr++;
00076 
00077         /*
00078          * Return true on trailing '*'. 
00079          */
00080 
00081         if(!*tstr)
00082                 return 1;
00083 
00084         /*
00085          * Skip over wildcards. 
00086          */
00087 
00088         while ((*tstr == '?') || (*tstr == '*')) {
00089                 if(*tstr == '?') {
00090                         if(!*dstr)
00091                                 return 0;
00092                         dstr++;
00093                 }
00094                 tstr++;
00095         }
00096 
00097         /*
00098          * Skip over a backslash in the pattern string if it is there. 
00099          */
00100 
00101         if(*tstr == '\\')
00102                 tstr++;
00103 
00104         /*
00105          * Return true on trailing '*'. 
00106          */
00107 
00108         if(!*tstr)
00109                 return 1;
00110 
00111         /*
00112          * Scan for possible matches. 
00113          */
00114 
00115         while (*dstr) {
00116                 if(EQUAL(*dstr, *tstr) && quick_wild(tstr + 1, dstr + 1))
00117                         return 1;
00118                 dstr++;
00119         }
00120         return 0;
00121 }

int wild ( char *  tstr,
char *  dstr,
char *  args[],
int  nargs 
)

wild: do a wildcard match, remembering the wild data.

This routine will cause crashes if fed NULLs instead of strings.

This function may crash if alloc_lbuf() fails.

Side Effect: this routine modifies the 'arglist' and 'numargs' static global variables.

Definition at line 337 of file wild.c.

References alloc_lbuf, arglist, free_lbuf, LBUF_SIZE, NOTEQUAL, numargs, quick_wild(), and wild1().

Referenced by atr_match1(), notify_checked(), and process_cmdent().

00338 {
00339         int i, value;
00340         char *scan;
00341 
00342         /*
00343          * Initialize the return array. 
00344          */
00345 
00346         for(i = 0; i < nargs; i++)
00347                 args[i] = NULL;
00348 
00349         /*
00350          * Do fast match. 
00351          */
00352 
00353         while ((*tstr != '*') && (*tstr != '?')) {
00354                 if(*tstr == '\\')
00355                         tstr++;
00356                 if(NOTEQUAL(*dstr, *tstr))
00357                         return 0;
00358                 if(!*dstr)
00359                         return 1;
00360                 tstr++;
00361                 dstr++;
00362         }
00363 
00364         /*
00365          * Allocate space for the return args. 
00366          */
00367 
00368         i = 0;
00369         scan = tstr;
00370         while (*scan && (i < nargs)) {
00371                 switch (*scan) {
00372                 case '?':
00373                         args[i] = alloc_lbuf("wild.?");
00374             memset(args[i], 0, LBUF_SIZE);
00375                         i++;
00376                         break;
00377                 case '*':
00378                         args[i] = alloc_lbuf("wild.*");
00379             memset(args[i], 0, LBUF_SIZE);
00380                         i++;
00381                 }
00382                 scan++;
00383         }
00384 
00385         /*
00386          * Put stuff in globals for quick recursion. 
00387          */
00388 
00389         arglist = args;
00390         numargs = nargs;
00391 
00392         /*
00393          * Do the match. 
00394          */
00395 
00396         value = nargs ? wild1(tstr, dstr, 0) : quick_wild(tstr, dstr);
00397 
00398         /*
00399          * Clean out any fake match data left by wild1. 
00400          */
00401 
00402         for(i = 0; i < nargs; i++)
00403                 if((args[i] != NULL) && (!*args[i] || !value)) {
00404                         free_lbuf(args[i]);
00405                         args[i] = NULL;
00406                 }
00407         return value;
00408 }

int wild1 ( char *  tstr,
char *  dstr,
int  arg 
)

wild1: INTERNAL: do a wildcard match, remembering the wild data.

DO NOT CALL THIS FUNCTION DIRECTLY - DOING SO MAY RESULT IN SERVER CRASHES AND IMPROPER ARGUMENT RETURN.

Side Effect: this routine modifies the 'arglist' static global variable.

Definition at line 132 of file wild.c.

References arglist, LBUF_SIZE, NOTEQUAL, numargs, quick_wild(), and StringCopyTrunc.

Referenced by wild().

00133 {
00134         char *datapos;
00135         int argpos, numextra;
00136 
00137         while (*tstr != '*') {
00138                 switch (*tstr) {
00139                 case '?':
00140                         /*
00141                          * Single character match.  Return false if at * end
00142                          * * * * of data. 
00143                          */
00144                         if(!*dstr)
00145                                 return 0;
00146                         arglist[arg][0] = *dstr;
00147                         arglist[arg][1] = '\0';
00148                         arg++;
00149 
00150                         /*
00151                          * Jump to the fast routine if we can. 
00152                          */
00153 
00154                         if(arg >= numargs)
00155                                 return quick_wild(tstr + 1, dstr + 1);
00156                         break;
00157                 case '\\':
00158                         /*
00159                          * Escape character.  Move up, and force literal * *
00160                          * * * match of next character. 
00161                          */
00162                         tstr++;
00163                         /*
00164                          * FALL THROUGH 
00165                          */
00166                 default:
00167                         /*
00168                          * Literal character.  Check for a match. * If * * *
00169                          * matching end of data, return true. 
00170                          */
00171                         if(NOTEQUAL(*dstr, *tstr))
00172                                 return 0;
00173                         if(!*dstr)
00174                                 return 1;
00175                 }
00176                 tstr++;
00177                 dstr++;
00178         }
00179 
00180         /*
00181          * If at end of pattern, slurp the rest, and leave. 
00182          */
00183 
00184         if(!tstr[1]) {
00185                 StringCopyTrunc(arglist[arg], dstr, LBUF_SIZE - 1);
00186                 arglist[arg][LBUF_SIZE - 1] = '\0';
00187                 return 1;
00188         }
00189         /*
00190          * Remember current position for filling in the '*' return. 
00191          */
00192 
00193         datapos = dstr;
00194         argpos = arg;
00195 
00196         /*
00197          * Scan forward until we find a non-wildcard. 
00198          */
00199 
00200         do {
00201                 if(argpos < arg) {
00202                         /*
00203                          * Fill in arguments if someone put another '*' * * * 
00204                          * 
00205                          * * before a fixed string. 
00206                          */
00207                         arglist[argpos][0] = '\0';
00208                         argpos++;
00209 
00210                         /*
00211                          * Jump to the fast routine if we can. 
00212                          */
00213 
00214                         if(argpos >= numargs)
00215                                 return quick_wild(tstr, dstr);
00216 
00217                         /*
00218                          * Fill in any intervening '?'s 
00219                          */
00220 
00221                         while (argpos < arg) {
00222                                 arglist[argpos][0] = *datapos;
00223                                 arglist[argpos][1] = '\0';
00224                                 datapos++;
00225                                 argpos++;
00226 
00227                                 /*
00228                                  * Jump to the fast routine if we can. 
00229                                  */
00230 
00231                                 if(argpos >= numargs)
00232                                         return quick_wild(tstr, dstr);
00233                         }
00234                 }
00235                 /*
00236                  * Skip over the '*' for now... 
00237                  */
00238 
00239                 tstr++;
00240                 arg++;
00241 
00242                 /*
00243                  * Skip over '?'s for now... 
00244                  */
00245 
00246                 numextra = 0;
00247                 while (*tstr == '?') {
00248                         if(!*dstr)
00249                                 return 0;
00250                         tstr++;
00251                         dstr++;
00252                         arg++;
00253                         numextra++;
00254                 }
00255         } while (*tstr == '*');
00256 
00257         /*
00258          * Skip over a backslash in the pattern string if it is there. 
00259          */
00260 
00261         if(*tstr == '\\')
00262                 tstr++;
00263 
00264         /*
00265          * Check for possible matches.  This loop terminates either at * end
00266          * * * * of data (resulting in failure), or at a successful match. 
00267          */
00268         while (1) {
00269 
00270                 /*
00271                  * Scan forward until first character matches. 
00272                  */
00273 
00274                 if(*tstr)
00275                         while (NOTEQUAL(*dstr, *tstr)) {
00276                                 if(!*dstr)
00277                                         return 0;
00278                                 dstr++;
00279                 } else
00280                         while (*dstr)
00281                                 dstr++;
00282 
00283                 /*
00284                  * The first character matches, now.  Check if the rest * * * 
00285                  * 
00286                  * * does, using the fastest method, as usual. 
00287                  */
00288                 if(!*dstr || ((arg < numargs) ? wild1(tstr + 1, dstr + 1, arg)
00289                                           : quick_wild(tstr + 1, dstr + 1))) {
00290 
00291                         /*
00292                          * Found a match!  Fill in all remaining arguments. * 
00293                          * 
00294                          * *  * *  * * First do the '*'... 
00295                          */
00296                         StringCopyTrunc(arglist[argpos], datapos,
00297                                                         (dstr - datapos) - numextra);
00298                         arglist[argpos][(dstr - datapos) - numextra] = '\0';
00299                         datapos = dstr - numextra;
00300                         argpos++;
00301 
00302                         /*
00303                          * Fill in any trailing '?'s that are left. 
00304                          */
00305 
00306                         while (numextra) {
00307                                 if(argpos >= numargs)
00308                                         return 1;
00309                                 arglist[argpos][0] = *datapos;
00310                                 arglist[argpos][1] = '\0';
00311                                 datapos++;
00312                                 argpos++;
00313                                 numextra--;
00314                         }
00315 
00316                         /*
00317                          * It's done! 
00318                          */
00319 
00320                         return 1;
00321                 } else {
00322                         dstr++;
00323                 }
00324         }
00325 }

int wild_match ( char *  tstr,
char *  dstr 
)

wild_match: do either an order comparison or a wildcard match, remembering the wild data, if wildcard match is done.

This routine will cause crashes if fed NULLs instead of strings.

Definition at line 416 of file wild.c.

References quick_wild().

Referenced by check_attr(), and do_switch().

00417 {
00418         switch (*tstr) {
00419         case '>':
00420                 tstr++;
00421                 if(isdigit(*tstr) || (*tstr == '-'))
00422                         return (atoi(tstr) < atoi(dstr));
00423                 else
00424                         return (strcmp(tstr, dstr) < 0);
00425         case '<':
00426                 tstr++;
00427                 if(isdigit(*tstr) || (*tstr == '-'))
00428                         return (atoi(tstr) > atoi(dstr));
00429                 else
00430                         return (strcmp(tstr, dstr) > 0);
00431         }
00432 
00433         return quick_wild(tstr, dstr);
00434 }


Variable Documentation

char** arglist [static]

Definition at line 29 of file wild.c.

Referenced by wild(), and wild1().

int numargs [static]

Definition at line 30 of file wild.c.

Referenced by mech_report(), mech_scan(), wild(), and wild1().


Generated on Mon May 28 04:25:48 2007 for BattletechMUX by  doxygen 1.4.7