mux/src/wild.cpp File Reference

#include "copyright.h"
#include "autoconf.h"
#include "config.h"
#include "externs.h"

Include dependency graph for wild.cpp:

Go to the source code of this file.

Defines

#define EQUAL(a, b)   (mux_tolower(a) == mux_tolower(b))
#define NOTEQUAL(a, b)   (mux_tolower(a) != mux_tolower(b))

Functions

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

Variables

static char ** arglist
static int numargs


Define Documentation

#define EQUAL ( a,
 )     (mux_tolower(a) == mux_tolower(b))

Definition at line 21 of file wild.cpp.

Referenced by quick_wild().

#define NOTEQUAL ( a,
 )     (mux_tolower(a) != mux_tolower(b))

Definition at line 22 of file wild.cpp.

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


Function Documentation

bool quick_wild ( const char *  tstr,
const char *  dstr 
)

Definition at line 35 of file wild.cpp.

References EQUAL, mudconf, mudstate, NOTEQUAL, quick_wild(), statedata::wild_invk_ctr, and confdata::wild_invk_lim.

Referenced by badname_check(), check_filter(), do_chanlist(), do_comlist(), find_wild_attrs(), FUNCTION(), list_vattrs(), quick_wild(), ReportMatchedTopics(), wild(), wild1(), and wild_match().

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

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

Definition at line 364 of file wild.cpp.

References alloc_lbuf, arglist, free_lbuf, mudstate, NOTEQUAL, numargs, quick_wild(), wild1(), and statedata::wild_invk_ctr.

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

00365 {
00366     mudstate.wild_invk_ctr = 0;
00367 
00368     int i;
00369     char *scan;
00370 
00371     // Initialize the return array.
00372     //
00373     for (i = 0; i < nargs; i++)
00374     {
00375         args[i] = NULL;
00376     }
00377 
00378     // Do fast match.
00379     //
00380     while (  *tstr != '*'
00381           && *tstr != '?')
00382     {
00383         if (*tstr == '\\')
00384         {
00385             tstr++;
00386         }
00387         if (NOTEQUAL(*dstr, *tstr))
00388         {
00389             return false;
00390         }
00391         if (!*dstr)
00392         {
00393             return true;
00394         }
00395         tstr++;
00396         dstr++;
00397     }
00398 
00399     // Allocate space for the return args.
00400     //
00401     i = 0;
00402     scan = tstr;
00403     while (  *scan
00404           && i < nargs)
00405     {
00406         switch (*scan)
00407         {
00408         case '?':
00409 
00410             args[i] = alloc_lbuf("wild.?");
00411             i++;
00412             break;
00413 
00414         case '*':
00415 
00416             args[i] = alloc_lbuf("wild.*");
00417             i++;
00418         }
00419         scan++;
00420     }
00421 
00422     // Put stuff in globals for quick recursion.
00423     //
00424     arglist = args;
00425     numargs = nargs;
00426 
00427     // Do the match.
00428     //
00429     bool value = nargs ? wild1(tstr, dstr, 0) : quick_wild(tstr, dstr);
00430 
00431     // Clean out any fake match data left by wild1.
00432     //
00433     for (i = 0; i < nargs; i++)
00434     {
00435         if (  args[i] != NULL
00436            && (  !*args[i]
00437               || !value))
00438         {
00439             free_lbuf(args[i]);
00440             args[i] = NULL;
00441         }
00442     }
00443     return value;
00444 }

static bool wild1 ( char *  tstr,
char *  dstr,
int  arg 
) [static]

Definition at line 147 of file wild.cpp.

References arglist, LBUF_SIZE, mudconf, mudstate, NOTEQUAL, numargs, quick_wild(), statedata::wild_invk_ctr, and confdata::wild_invk_lim.

Referenced by wild().

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

bool wild_match ( char *  tstr,
const char *  dstr 
)

Definition at line 452 of file wild.cpp.

References mudstate, mux_atol(), mux_isdigit, quick_wild(), and statedata::wild_invk_ctr.

Referenced by check_attr(), do_switch(), and switch_handler().

00453 {
00454     switch (*tstr)
00455     {
00456     case '>':
00457 
00458         tstr++;
00459         if (  mux_isdigit(*tstr)
00460            || *tstr == '-')
00461         {
00462             long lt = mux_atol(tstr);
00463             long ld = mux_atol(dstr);
00464             return (lt < ld);
00465         }
00466         else
00467         {
00468             return (strcmp(tstr, dstr) < 0);
00469         }
00470 
00471     case '<':
00472 
00473         tstr++;
00474         if (  mux_isdigit(*tstr)
00475            || *tstr == '-')
00476         {
00477             long lt = mux_atol(tstr);
00478             long ld = mux_atol(dstr);
00479             return (lt > ld);
00480         }
00481         else
00482         {
00483             return (strcmp(tstr, dstr) > 0);
00484         }
00485     }
00486     mudstate.wild_invk_ctr = 0;
00487     return quick_wild(tstr, dstr);
00488 }


Variable Documentation

char** arglist [static]

Definition at line 26 of file wild.cpp.

Referenced by wild(), and wild1().

int numargs [static]

Definition at line 27 of file wild.cpp.

Referenced by wild(), and wild1().


Generated on Mon May 28 04:40:23 2007 for MUX by  doxygen 1.4.7