00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "copyright.h"
00010 #include "autoconf.h"
00011 #include "config.h"
00012 #include "externs.h"
00013
00014 #include "ansi.h"
00015 #include "attrs.h"
00016 #include "functions.h"
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 static char *parse_to_cleanup( int eval, int first, char *cstr, char *rstr,
00027 char *zstr, char *strFirewall)
00028 {
00029 if ( ( mudconf.space_compress
00030 || (eval & EV_STRIP_TS))
00031 && !(eval & EV_NO_COMPRESS)
00032 && !first
00033 && strFirewall < cstr
00034 && cstr[-1] == ' ')
00035 {
00036 zstr--;
00037 }
00038
00039 if ( (eval & EV_STRIP_AROUND)
00040 && *rstr == '{'
00041 && strFirewall < zstr
00042 && zstr[-1] == '}')
00043 {
00044 rstr++;
00045 if ( ( mudconf.space_compress
00046 && !(eval & EV_NO_COMPRESS))
00047 || (eval & EV_STRIP_LS))
00048 {
00049 while (mux_isspace(*rstr))
00050 {
00051 rstr++;
00052 }
00053 }
00054 rstr[-1] = '\0';
00055 zstr--;
00056 if ( ( mudconf.space_compress
00057 && !(eval & EV_NO_COMPRESS))
00058 || (eval & EV_STRIP_TS))
00059 {
00060 while ( strFirewall < zstr
00061 && mux_isspace(zstr[-1]))
00062 {
00063 zstr--;
00064 }
00065 }
00066 *zstr = '\0';
00067 }
00068 *zstr = '\0';
00069 return rstr;
00070 }
00071
00078 #define isSpecial(table, c) isSpecial_##table[(unsigned char)(c)]
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096 static char isSpecial_L3[256] =
00097 {
00098 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00099 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0,
00100 0, 0, 0, 0, 0, 4, 0, 0, 3, 5, 0, 0, 0, 0, 0, 0,
00101 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00102 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00103 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 5, 0, 0,
00104 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00105 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0,
00106 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00107 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00108 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00109 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00110 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00111 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00112 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00113 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00114 };
00115
00116 static const char isSpecial_L4[256] =
00117 {
00118 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00119 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
00120 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00121 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00122 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00123 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
00124 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00125 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 3, 0, 0,
00126 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00127 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00128 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00129 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00130 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00131 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00132 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00133 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00134 };
00135
00136
00137
00138
00139 const signed char mux_RegisterSet[256] =
00140 {
00141 -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
00142 -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
00143 -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
00144 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1,
00145 -1,10,11,12,13,14,15,16, 17,18,19,20,21,22,23,24,
00146 25,26,27,28,29,30,31,32, 33,34,35,-1,-1,-1,-1,-1,
00147 -1,10,11,12,13,14,15,16, 17,18,19,20,21,22,23,24,
00148 25,26,27,28,29,30,31,32, 33,34,35,-1,-1,-1,-1,-1,
00149 -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
00150 -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
00151 -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
00152 -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
00153 -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
00154 -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
00155 -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
00156 -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1
00157 };
00158
00159
00160
00161
00162
00163 #if 1
00164 #define NEXTCHAR *zstr++ = *cstr++;
00165 #else
00166 #define NEXTCHAR \
00167 if (cstr == zstr) \
00168 { \
00169 cstr++; \
00170 zstr++; \
00171 } \
00172 else \
00173 { \
00174 *zstr++ = *cstr++; \
00175 }
00176 #endif
00177
00178
00179 char *parse_to(char **dstr, char delim, int eval)
00180 {
00181 #define stacklim 32
00182 char stack[stacklim];
00183 char *rstr, *cstr, *zstr, *strFirewall;
00184 int sp, tp, bracketlev;
00185
00186 if ( dstr == NULL
00187 || *dstr == NULL)
00188 {
00189 return NULL;
00190 }
00191
00192 if (**dstr == '\0')
00193 {
00194 rstr = *dstr;
00195 *dstr = NULL;
00196 return rstr;
00197 }
00198 sp = 0;
00199 bool first = true;
00200 strFirewall = rstr = *dstr;
00201 if ( ( mudconf.space_compress
00202 || (eval & EV_STRIP_LS))
00203 && !(eval & EV_NO_COMPRESS))
00204 {
00205 while (mux_isspace(*rstr))
00206 {
00207 rstr++;
00208 }
00209 *dstr = rstr;
00210 }
00211 zstr = cstr = rstr;
00212 int iOriginalCode = isSpecial(L3, delim);
00213 isSpecial(L3, ' ') = 1;
00214 if (iOriginalCode <= 3)
00215 {
00216
00217
00218 isSpecial(L3, delim) = 8;
00219 }
00220
00221 for (;;)
00222 {
00223 int iCode = isSpecial(L3, *cstr);
00224
00225 TryAgain:
00226 if (iCode == 0)
00227 {
00228
00229
00230 first = false;
00231 do
00232 {
00233 NEXTCHAR
00234 iCode = isSpecial(L3, *cstr);
00235 } while (iCode == 0);
00236 }
00237
00238 if (iCode <= 4)
00239 {
00240
00241
00242
00243
00244
00245 if (iCode <= 2)
00246 {
00247
00248
00249
00250 if (iCode == 1)
00251 {
00252
00253
00254 if ( mudconf.space_compress
00255 && !(eval & EV_NO_COMPRESS))
00256 {
00257 if (first)
00258 {
00259 rstr++;
00260 }
00261 else if ( strFirewall < cstr
00262 && cstr[-1] == ' ')
00263 {
00264 zstr--;
00265 }
00266 }
00267 NEXTCHAR
00268 }
00269 else
00270 {
00271
00272
00273 first = false;
00274 if (sp < stacklim)
00275 {
00276 stack[sp++] = ']';
00277 }
00278 NEXTCHAR
00279 }
00280 }
00281 else
00282 {
00283
00284
00285
00286 if (iCode == 3)
00287 {
00288 first = false;
00289 if (sp < stacklim)
00290 {
00291 stack[sp++] = ')';
00292 }
00293 NEXTCHAR
00294 }
00295 else
00296 {
00297
00298
00299 first = false;
00300 NEXTCHAR
00301 if (*cstr)
00302 {
00303 NEXTCHAR
00304 }
00305 }
00306 }
00307 }
00308 else
00309 {
00310
00311
00312
00313
00314
00315 if (iCode <= 6)
00316 {
00317
00318
00319
00320 if (iCode == 5)
00321 {
00322
00323
00324 for (tp = sp - 1; tp >= 0 && stack[tp] != *cstr; tp--)
00325 {
00326 ;
00327 }
00328
00329
00330
00331
00332
00333
00334 if (tp >= 0)
00335 {
00336 sp = tp;
00337 }
00338 else if (*cstr == delim)
00339 {
00340 rstr = parse_to_cleanup(eval, first, cstr, rstr, zstr, strFirewall);
00341 *dstr = ++cstr;
00342 isSpecial(L3, delim) = iOriginalCode;
00343 isSpecial(L3, ' ') = 0;
00344 return rstr;
00345 }
00346 first = false;
00347 NEXTCHAR
00348 }
00349 else
00350 {
00351
00352
00353 bracketlev = 1;
00354 if (eval & EV_STRIP_CURLY)
00355 {
00356 cstr++;
00357 }
00358 else
00359 {
00360 NEXTCHAR;
00361 }
00362 for (;;)
00363 {
00364 int iCodeL4 = isSpecial(L4, *cstr);
00365 if (iCodeL4 == 0)
00366 {
00367
00368
00369 do
00370 {
00371 NEXTCHAR
00372 iCodeL4 = isSpecial(L4, *cstr);
00373 } while (iCodeL4 == 0);
00374 }
00375
00376
00377 if (iCodeL4 == 1)
00378 {
00379
00380
00381 if (cstr[1])
00382 {
00383 NEXTCHAR
00384 }
00385 }
00386 else if (iCodeL4 == 2)
00387 {
00388
00389
00390 bracketlev++;
00391 }
00392 else if (iCodeL4 == 3)
00393 {
00394
00395
00396 bracketlev--;
00397 if (bracketlev <= 0)
00398 {
00399 break;
00400 }
00401 }
00402 else
00403 {
00404
00405
00406 break;
00407 }
00408 NEXTCHAR
00409 }
00410
00411 if (bracketlev == 0)
00412 {
00413 if (eval & EV_STRIP_CURLY)
00414 {
00415 cstr++;
00416 }
00417 else
00418 {
00419 NEXTCHAR
00420 }
00421 }
00422 first = false;
00423 }
00424 }
00425 else
00426 {
00427
00428
00429
00430 if (iCode == 7)
00431 {
00432
00433
00434 isSpecial(L3, delim) = iOriginalCode;
00435 isSpecial(L3, ' ') = 0;
00436 break;
00437 }
00438 else
00439 {
00440
00441
00442 if (sp == 0)
00443 {
00444 rstr = parse_to_cleanup(eval, first, cstr, rstr, zstr, strFirewall);
00445 *dstr = ++cstr;
00446 isSpecial(L3, delim) = iOriginalCode;
00447 isSpecial(L3, ' ') = 0;
00448 return rstr;
00449 }
00450
00451
00452
00453 iCode = iOriginalCode;
00454 goto TryAgain;
00455 }
00456 }
00457 }
00458 }
00459 rstr = parse_to_cleanup(eval, first, cstr, rstr, zstr, strFirewall);
00460 *dstr = NULL;
00461 return rstr;
00462 }
00463
00464
00465
00466
00467
00468
00469 static char *parse_to_lite(char **dstr, char delim1, char delim2, int *nLen, int *iWhichDelim)
00470 {
00471 #define stacklim 32
00472 char stack[stacklim];
00473 char *rstr, *cstr;
00474 int sp, tp, bracketlev;
00475
00476 if ( dstr == NULL
00477 || *dstr == NULL)
00478 {
00479 *nLen = 0;
00480 return NULL;
00481 }
00482
00483 if (**dstr == '\0')
00484 {
00485 rstr = *dstr;
00486 *dstr = NULL;
00487 *nLen = 0;
00488 return rstr;
00489 }
00490 sp = 0;
00491 cstr = rstr = *dstr;
00492 int iOriginalCode1 = isSpecial(L3, delim1);
00493 int iOriginalCode2 = isSpecial(L3, delim2);
00494 if (iOriginalCode1 <= 3)
00495 {
00496
00497
00498 isSpecial(L3, delim1) = 8;
00499 }
00500 if (iOriginalCode2 <= 3)
00501 {
00502
00503
00504 isSpecial(L3, delim2) = 8;
00505 }
00506
00507 for (;;)
00508 {
00509 int iCode = isSpecial(L3, *cstr);
00510
00511 TryAgain:
00512 if (iCode == 0)
00513 {
00514
00515
00516 do
00517 {
00518 cstr++;
00519 iCode = isSpecial(L3, *cstr);
00520 } while (iCode == 0);
00521 }
00522
00523 if (iCode <= 4)
00524 {
00525
00526
00527
00528
00529 if (iCode <= 3)
00530 {
00531
00532
00533
00534 if (sp < stacklim)
00535 {
00536 static char matcher[2] = { ']', ')'};
00537 stack[sp++] = matcher[iCode-2];
00538 }
00539 cstr++;
00540 }
00541 else
00542 {
00543
00544
00545 cstr++;
00546 if (*cstr)
00547 {
00548 cstr++;
00549 }
00550 }
00551 }
00552 else
00553 {
00554
00555
00556
00557
00558
00559 if (iCode <= 6)
00560 {
00561
00562
00563
00564 if (iCode == 5)
00565 {
00566
00567
00568 for (tp = sp - 1; tp >= 0 && stack[tp] != *cstr; tp--)
00569 {
00570 ;
00571 }
00572
00573
00574
00575
00576
00577
00578 if (0 <= tp)
00579 {
00580 sp = tp;
00581 }
00582 else if ( *cstr == delim1
00583 || *cstr == delim2)
00584 {
00585 if (*cstr == delim1)
00586 {
00587 *iWhichDelim = 1;
00588 }
00589 else
00590 {
00591 *iWhichDelim = 2;
00592 }
00593 *cstr = '\0';
00594 *nLen = (cstr - rstr);
00595 *dstr = ++cstr;
00596 isSpecial(L3, delim1) = iOriginalCode1;
00597 isSpecial(L3, delim2) = iOriginalCode2;
00598 return rstr;
00599 }
00600 cstr++;
00601 }
00602 else
00603 {
00604
00605
00606 bracketlev = 1;
00607 cstr++;
00608 for (;;)
00609 {
00610 int iCodeL4 = isSpecial(L4, *cstr);
00611 if (iCodeL4 == 0)
00612 {
00613
00614
00615 do
00616 {
00617 cstr++;
00618 iCodeL4 = isSpecial(L4, *cstr);
00619 } while (iCodeL4 == 0);
00620 }
00621
00622
00623 if (iCodeL4 == 1)
00624 {
00625
00626
00627 if (cstr[1])
00628 {
00629 cstr++;
00630 }
00631 }
00632 else if (iCodeL4 == 2)
00633 {
00634
00635
00636 bracketlev++;
00637 }
00638 else if (iCodeL4 == 3)
00639 {
00640
00641
00642 bracketlev--;
00643 if (bracketlev <= 0)
00644 {
00645 break;
00646 }
00647 }
00648 else
00649 {
00650
00651
00652 break;
00653 }
00654 cstr++;
00655 }
00656
00657 if (bracketlev == 0)
00658 {
00659 cstr++;
00660 }
00661 }
00662 }
00663 else
00664 {
00665
00666
00667
00668 if (iCode == 7)
00669 {
00670
00671
00672 isSpecial(L3, delim1) = iOriginalCode1;
00673 isSpecial(L3, delim2) = iOriginalCode2;
00674 break;
00675 }
00676 else
00677 {
00678
00679
00680 if (sp == 0)
00681 {
00682 if (*cstr == delim1)
00683 {
00684 *iWhichDelim = 1;
00685 }
00686 else
00687 {
00688 *iWhichDelim = 2;
00689 }
00690 *cstr = '\0';
00691 *nLen = (cstr - rstr);
00692 *dstr = ++cstr;
00693 isSpecial(L3, delim1) = iOriginalCode1;
00694 isSpecial(L3, delim2) = iOriginalCode2;
00695 return rstr;
00696 }
00697
00698
00699
00700 if (*cstr == delim1)
00701 {
00702 iCode = iOriginalCode1;
00703 }
00704 else
00705 {
00706 iCode = iOriginalCode2;
00707 }
00708 goto TryAgain;
00709 }
00710 }
00711 }
00712 }
00713 *iWhichDelim = 0;
00714 *cstr = '\0';
00715 *nLen = (cstr - rstr);
00716 *dstr = NULL;
00717 return rstr;
00718 }
00719
00720
00721
00722
00723
00724
00725
00726 char *parse_arglist( dbref executor, dbref caller, dbref enactor, char *dstr,
00727 char delim, dbref eval, char *fargs[], dbref nfargs,
00728 char *cargs[], dbref ncargs, int *nArgsParsed )
00729 {
00730 char *rstr, *tstr, *bp, *str;
00731 int arg, peval;
00732
00733 if (dstr == NULL)
00734 {
00735 *nArgsParsed = 0;
00736 return NULL;
00737 }
00738
00739 int nLen;
00740 int iWhichDelim;
00741 rstr = parse_to_lite(&dstr, delim, '\0', &nLen, &iWhichDelim);
00742 arg = 0;
00743
00744 peval = (eval & ~EV_EVAL);
00745
00746 while ( arg < nfargs
00747 && rstr)
00748 {
00749 if (arg < nfargs - 1)
00750 {
00751 tstr = parse_to(&rstr, ',', peval);
00752 }
00753 else
00754 {
00755 tstr = parse_to(&rstr, '\0', peval);
00756 }
00757
00758 bp = fargs[arg] = alloc_lbuf("parse_arglist");
00759 if (eval & EV_EVAL)
00760 {
00761 str = tstr;
00762 mux_exec(fargs[arg], &bp, executor, caller, enactor,
00763 eval | EV_FCHECK, &str, cargs, ncargs);
00764 *bp = '\0';
00765 }
00766 else
00767 {
00768 strcpy(fargs[arg], tstr);
00769 }
00770 arg++;
00771 }
00772 *nArgsParsed = arg;
00773 return dstr;
00774 }
00775
00776 static char *parse_arglist_lite( dbref executor, dbref caller, dbref enactor,
00777 char *dstr, char delim, int eval, char *fargs[],
00778 dbref nfargs, char *cargs[], dbref ncargs,
00779 int *nArgsParsed)
00780 {
00781 UNUSED_PARAMETER(delim);
00782
00783 char *tstr, *bp, *str;
00784
00785 if (dstr == NULL)
00786 {
00787 *nArgsParsed = 0;
00788 return NULL;
00789 }
00790
00791 int nLen;
00792 int peval = eval;
00793 if (eval & EV_EVAL)
00794 {
00795 peval = eval | EV_FCHECK;
00796 }
00797 else
00798 {
00799 peval = ((eval & ~EV_FCHECK)|EV_NOFCHECK);
00800 }
00801 int arg = 0;
00802 int iWhichDelim = 0;
00803 while ( arg < nfargs
00804 && dstr
00805 && iWhichDelim != 2)
00806 {
00807 if (arg < nfargs - 1)
00808 {
00809 tstr = parse_to_lite(&dstr, ',', ')', &nLen, &iWhichDelim);
00810 }
00811 else
00812 {
00813 tstr = parse_to_lite(&dstr, '\0', ')', &nLen, &iWhichDelim);
00814 }
00815
00816 if ( iWhichDelim == 2
00817 && arg == 0
00818 && tstr[0] == '\0')
00819 {
00820 break;
00821 }
00822
00823 bp = fargs[arg] = alloc_lbuf("parse_arglist");
00824 str = tstr;
00825 mux_exec(fargs[arg], &bp, executor, caller, enactor, peval, &str,
00826 cargs, ncargs);
00827 *bp = '\0';
00828 arg++;
00829 }
00830 *nArgsParsed = arg;
00831 return dstr;
00832 }
00833
00834
00835
00836
00837 int get_gender(dbref player)
00838 {
00839 dbref aowner;
00840 int aflags;
00841 char *atr_gotten = atr_pget(player, A_SEX, &aowner, &aflags);
00842 char first = atr_gotten[0];
00843 free_lbuf(atr_gotten);
00844 switch (mux_tolower(first))
00845 {
00846 case 'p':
00847 return 4;
00848
00849 case 'm':
00850 return 3;
00851
00852 case 'f':
00853 case 'w':
00854 return 2;
00855 }
00856 return 1;
00857 }
00858
00859
00860
00861
00862 typedef struct tcache_ent TCENT;
00863 static struct tcache_ent
00864 {
00865 dbref player;
00866 char *orig;
00867 char *result;
00868 struct tcache_ent *next;
00869 } *tcache_head;
00870
00871 static bool tcache_top;
00872 static int tcache_count;
00873
00874 void tcache_init(void)
00875 {
00876 tcache_head = NULL;
00877 tcache_top = true;
00878 tcache_count = 0;
00879 }
00880
00881 static bool tcache_empty(void)
00882 {
00883 if (tcache_top)
00884 {
00885 tcache_top = false;
00886 tcache_count = 0;
00887 return true;
00888 }
00889 return false;
00890 }
00891
00892 static void tcache_add(dbref player, char *orig, char *result)
00893 {
00894 if (strcmp(orig, result))
00895 {
00896 tcache_count++;
00897 if (tcache_count <= mudconf.trace_limit)
00898 {
00899 TCENT *xp = (TCENT *) alloc_sbuf("tcache_add.sbuf");
00900 char *tp = alloc_lbuf("tcache_add.lbuf");
00901
00902 int nvw;
00903 ANSI_TruncateToField(result, LBUF_SIZE, tp, LBUF_SIZE,
00904 &nvw, ANSI_ENDGOAL_NORMAL);
00905 xp->result = tp;
00906
00907 xp->player = player;
00908 xp->orig = orig;
00909 xp->next = tcache_head;
00910 tcache_head = xp;
00911 }
00912 else
00913 {
00914 free_lbuf(orig);
00915 }
00916 }
00917 else
00918 {
00919 free_lbuf(orig);
00920 }
00921 }
00922
00923 static void tcache_finish(void)
00924 {
00925 while (tcache_head != NULL)
00926 {
00927 TCENT *xp = tcache_head;
00928 tcache_head = xp->next;
00929 notify(Owner(xp->player), tprintf("%s(#%d)} '%s' -> '%s'", Name(xp->player),
00930 xp->player, xp->orig, xp->result));
00931 free_lbuf(xp->orig);
00932 free_lbuf(xp->result);
00933 free_sbuf(xp);
00934 }
00935 tcache_top = true;
00936 tcache_count = 0;
00937 }
00938
00939 const char *ColorTable[256] =
00940 {
00941 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00942 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00943 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00944 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00945 0, 0, ANSI_BBLUE, ANSI_BCYAN,
00946 0, 0, 0, ANSI_BGREEN,
00947 0, 0, 0, 0,
00948 0, ANSI_BMAGENTA, 0, 0,
00949 0, 0, ANSI_BRED, 0,
00950 0, 0, 0, ANSI_BWHITE,
00951 ANSI_BBLACK, ANSI_BYELLOW, 0, 0,
00952 0, 0, 0, 0,
00953 0, 0, ANSI_BLUE, ANSI_CYAN,
00954 0, 0, ANSI_BLINK, ANSI_GREEN,
00955 ANSI_HILITE, ANSI_INVERSE, 0, 0,
00956 0, ANSI_MAGENTA, ANSI_NORMAL, 0,
00957 0, 0, ANSI_RED, 0,
00958 0, ANSI_UNDER, 0, ANSI_WHITE,
00959 ANSI_BLACK, ANSI_YELLOW, 0, 0,
00960 0, 0, 0, 0,
00961 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00962 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00963 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00964 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00965 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00966 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00967 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00968 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00969 };
00970
00971 static bool isSpecial_L1[256] =
00972 {
00973 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00974 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
00975 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
00976 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00977 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00978 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0,
00979 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00980 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
00981 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00982 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00983 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00984 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00985 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00986 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00987 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00988 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00989 };
00990
00991 static const unsigned char isSpecial_L2[256] =
00992 {
00993 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00994 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00995 0, 4, 0, 3, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00996 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
00997 20,145, 7, 6, 0, 0, 0, 0, 0, 0, 0, 0, 9,147,140,144,
00998 143,130, 5,142, 8, 0,138, 0, 6, 0, 0, 0, 0, 0, 0, 0,
00999 20, 17, 7, 6, 0, 0, 0, 0, 0, 0, 0, 0, 9, 19, 12, 16,
01000 15, 2, 5, 14, 8, 0, 10, 0, 6, 0, 0, 0, 13, 0, 0, 0,
01001 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
01002 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
01003 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
01004 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
01005 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
01006 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
01007 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
01008 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
01009 };
01010
01011 #define PTRS_PER_FRAME ((LBUF_SIZE - sizeof(char *) - sizeof(int))/sizeof(char *))
01012 typedef struct tag_ptrsframe
01013 {
01014 int nptrs;
01015 char *ptrs[PTRS_PER_FRAME];
01016 struct tag_ptrsframe *next;
01017 } PtrsFrame;
01018
01019 static PtrsFrame *pPtrsFrame = NULL;
01020
01021 char **PushPointers(int nNeeded)
01022 {
01023 if ( !pPtrsFrame
01024 || pPtrsFrame->nptrs < nNeeded)
01025 {
01026 PtrsFrame *p = (PtrsFrame *)alloc_lbuf("PushPointers");
01027 p->next = pPtrsFrame;
01028 p->nptrs = PTRS_PER_FRAME;
01029 pPtrsFrame = p;
01030 }
01031 pPtrsFrame->nptrs -= nNeeded;
01032 return pPtrsFrame->ptrs + pPtrsFrame->nptrs;
01033 }
01034
01035 void PopPointers(char **p, int nNeeded)
01036 {
01037 UNUSED_PARAMETER(p);
01038
01039 if (pPtrsFrame->nptrs == PTRS_PER_FRAME)
01040 {
01041 PtrsFrame *q = pPtrsFrame->next;
01042 free_lbuf((char *)pPtrsFrame);
01043 pPtrsFrame = q;
01044 }
01045
01046 pPtrsFrame->nptrs += nNeeded;
01047 }
01048
01049 #define INTS_PER_FRAME ((LBUF_SIZE - sizeof(char *) - sizeof(int))/sizeof(int))
01050 typedef struct tag_intsframe
01051 {
01052 int nints;
01053 int ints[INTS_PER_FRAME];
01054 struct tag_intsframe *next;
01055 } IntsFrame;
01056
01057 static IntsFrame *pIntsFrame = NULL;
01058
01059 int *PushIntegers(int nNeeded)
01060 {
01061 if ( !pIntsFrame
01062 || pIntsFrame->nints < nNeeded)
01063 {
01064 IntsFrame *p = (IntsFrame *)alloc_lbuf("PushIntegers");
01065 p->next = pIntsFrame;
01066 p->nints = INTS_PER_FRAME;
01067 pIntsFrame = p;
01068 }
01069 pIntsFrame->nints -= nNeeded;
01070 return pIntsFrame->ints + pIntsFrame->nints;
01071 }
01072
01073 void PopIntegers(int *pi, int nNeeded)
01074 {
01075 UNUSED_PARAMETER(pi);
01076
01077 if (pIntsFrame->nints == INTS_PER_FRAME)
01078 {
01079 IntsFrame *p = pIntsFrame->next;
01080 free_lbuf((char *)pIntsFrame);
01081 pIntsFrame = p;
01082 }
01083
01084 pIntsFrame->nints += nNeeded;
01085 }
01086
01087 void mux_exec( char *buff, char **bufc, dbref executor, dbref caller,
01088 dbref enactor, int eval, char **dstr, char *cargs[], int ncargs)
01089 {
01090 if ( *dstr == NULL
01091 || **dstr == '\0'
01092 || MuxAlarm.bAlarmed)
01093 {
01094 return;
01095 }
01096
01097
01098
01099 if (mudconf.nStackLimit < mudstate.nStackNest)
01100 {
01101 mudstate.bStackLimitReached = true;
01102 return;
01103 }
01104
01105 char *TempPtr;
01106 char *tstr, *tbuf, *start, *oldp, *savestr;
01107 const char *constbuf;
01108 int ch;
01109 char *realbuff = NULL, *realbp = NULL;
01110 dbref aowner;
01111 int nfargs, aflags, feval, i;
01112 bool ansi = false;
01113 FUN *fp;
01114 UFUN *ufp;
01115
01116 static const char *subj[5] = {"", "it", "she", "he", "they"};
01117 static const char *poss[5] = {"", "its", "her", "his", "their"};
01118 static const char *obj[5] = {"", "it", "her", "him", "them"};
01119 static const char *absp[5] = {"", "its", "hers", "his", "theirs"};
01120
01121
01122
01123
01124
01125 static char mux_scratch[LBUF_SIZE];
01126
01127 char *pdstr = *dstr;
01128
01129 int at_space = 1;
01130 int gender = -1;
01131
01132 bool is_trace = Trace(executor) && !(eval & EV_NOTRACE);
01133 bool is_top = false;
01134
01135
01136
01137 if (LBUF_SIZE - SBUF_SIZE < (*bufc) - buff)
01138 {
01139 realbuff = buff;
01140 realbp = *bufc;
01141 buff = (char *)MEMALLOC(LBUF_SIZE);
01142 ISOUTOFMEMORY(buff);
01143 *bufc = buff;
01144 }
01145
01146 oldp = start = *bufc;
01147
01148
01149
01150 savestr = NULL;
01151 if (is_trace)
01152 {
01153 is_top = tcache_empty();
01154 savestr = alloc_lbuf("exec.save");
01155 strcpy(savestr, pdstr);
01156 }
01157
01158
01159
01160 bool bSpaceIsSpecialSave = isSpecial(L1, ' ');
01161 bool bParenthesisIsSpecialSave = isSpecial(L1, '(');
01162 bool bBracketIsSpecialSave = isSpecial(L1, '[');
01163
01164
01165
01166 bool bSpaceIsSpecial = mudconf.space_compress && !(eval & EV_NO_COMPRESS);
01167 isSpecial(L1, ' ') = bSpaceIsSpecial;
01168 isSpecial(L1, '(') = (eval & EV_FCHECK) != 0;
01169 isSpecial(L1, '[') = (eval & EV_NOFCHECK) == 0;
01170
01171 size_t nBufferAvailable = LBUF_SIZE - (*bufc - buff) - 1;
01172 for (;;)
01173 {
01174
01175
01176
01177 if (!isSpecial(L1, *pdstr))
01178 {
01179 char *p = pdstr + 1;
01180 while (!isSpecial(L1, *p++))
01181 {
01182 ;
01183 }
01184 size_t n = p - pdstr - 1;
01185 if (nBufferAvailable < n)
01186 {
01187 n = nBufferAvailable;
01188 }
01189 memcpy(*bufc, pdstr, n);
01190 nBufferAvailable -= n;
01191 *bufc += n;
01192 at_space = 0;
01193 pdstr = p - 1;
01194 }
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210 if (*pdstr == '\0')
01211 {
01212 break;
01213 }
01214 else if (*pdstr == '(')
01215 {
01216
01217
01218
01219
01220
01221 at_space = 0;
01222
01223
01224
01225
01226
01227 char *pEnd = *bufc - 1;
01228 if (mudconf.space_compress && (eval & EV_FMAND))
01229 {
01230 while ( oldp <= pEnd
01231 && mux_isspace(*pEnd))
01232 {
01233 pEnd--;
01234 }
01235 }
01236
01237
01238
01239 char *p2 = mux_scratch;
01240 for (char *p = oldp; p <= pEnd; p++)
01241 {
01242 *p2++ = mux_tolower(*p);
01243 }
01244 *p2 = '\0';
01245
01246 int ntbuf = p2 - mux_scratch;
01247 fp = (FUN *)hashfindLEN(mux_scratch, ntbuf, &mudstate.func_htab);
01248
01249
01250
01251 ufp = NULL;
01252 if (fp == NULL)
01253 {
01254 ufp = (UFUN *)hashfindLEN(mux_scratch, ntbuf, &mudstate.ufunc_htab);
01255 }
01256
01257
01258
01259 if (!fp && !ufp)
01260 {
01261 if (eval & EV_FMAND)
01262 {
01263 *bufc = oldp;
01264 safe_str("#-1 FUNCTION (", buff, bufc);
01265 safe_str(mux_scratch, buff, bufc);
01266 safe_str(") NOT FOUND", buff, bufc);
01267 nBufferAvailable = LBUF_SIZE - (*bufc - buff) - 1;
01268 break;
01269 }
01270 else if (nBufferAvailable)
01271 {
01272 *(*bufc)++ = '(';
01273 nBufferAvailable--;
01274 }
01275 }
01276 else
01277 {
01278
01279
01280
01281 if (ufp)
01282 {
01283 nfargs = MAX_ARG;
01284 }
01285 else
01286 {
01287 nfargs = fp->maxArgsParsed;
01288 }
01289
01290 tstr = pdstr;
01291 if ( fp
01292 && (fp->flags & FN_NOEVAL))
01293 {
01294 feval = eval & ~(EV_EVAL|EV_TOP|EV_STRIP_CURLY);
01295 }
01296