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 else
01297 {
01298 feval = eval & ~EV_TOP;
01299 }
01300
01301 char **fargs = PushPointers(MAX_ARG);
01302 pdstr = parse_arglist_lite(executor, caller, enactor,
01303 pdstr + 1, ')', feval, fargs, nfargs, cargs, ncargs,
01304 &nfargs);
01305
01306
01307
01308
01309 if (!pdstr)
01310 {
01311 pdstr = tstr;
01312 if (nBufferAvailable)
01313 {
01314 *(*bufc)++ = *pdstr;
01315 nBufferAvailable--;
01316 }
01317 }
01318 else
01319 {
01320 pdstr--;
01321
01322
01323
01324 mudstate.func_nest_lev++;
01325 mudstate.func_invk_ctr++;
01326 if (mudconf.func_nest_lim <= mudstate.func_nest_lev)
01327 {
01328 safe_str("#-1 FUNCTION RECURSION LIMIT EXCEEDED", buff, &oldp);
01329 }
01330 else if (mudconf.func_invk_lim <= mudstate.func_invk_ctr)
01331 {
01332 safe_str("#-1 FUNCTION INVOCATION LIMIT EXCEEDED", buff, &oldp);
01333 }
01334 else if (Going(executor))
01335 {
01336 safe_str("#-1 BAD EXECUTOR", buff, &oldp);
01337 }
01338 else if (!check_access(executor, ufp ? ufp->perms : fp->perms))
01339 {
01340 safe_noperm(buff, &oldp);
01341 }
01342 else if (MuxAlarm.bAlarmed)
01343 {
01344 safe_str("#-1 CPU LIMITED", buff, &oldp);
01345 }
01346 else if (ufp)
01347 {
01348 tstr = atr_get(ufp->obj, ufp->atr, &aowner, &aflags);
01349 if (ufp->flags & FN_PRIV)
01350 {
01351 i = ufp->obj;
01352 }
01353 else
01354 {
01355 i = executor;
01356 }
01357 TempPtr = tstr;
01358
01359 char **preserve = NULL;
01360 int *preserve_len = NULL;
01361
01362 if (ufp->flags & FN_PRES)
01363 {
01364 preserve = PushPointers(MAX_GLOBAL_REGS);
01365 preserve_len = PushIntegers(MAX_GLOBAL_REGS);
01366 save_global_regs("eval_save", preserve, preserve_len);
01367 }
01368
01369 mux_exec(buff, &oldp, i, executor, enactor, feval,
01370 &TempPtr, fargs, nfargs);
01371
01372 if (ufp->flags & FN_PRES)
01373 {
01374 restore_global_regs("eval_restore", preserve, preserve_len);
01375 PopIntegers(preserve_len, MAX_GLOBAL_REGS);
01376 PopPointers(preserve, MAX_GLOBAL_REGS);
01377 preserve = NULL;
01378 preserve_len = NULL;
01379 }
01380 free_lbuf(tstr);
01381 }
01382 else
01383 {
01384
01385
01386
01387 if ( fp->minArgs <= nfargs
01388 && nfargs <= fp->maxArgs
01389 && !MuxAlarm.bAlarmed)
01390 {
01391 fp->fun(buff, &oldp, executor, caller, enactor,
01392 fargs, nfargs, cargs, ncargs);
01393 }
01394 else
01395 {
01396 if (fp->minArgs == fp->maxArgs)
01397 {
01398 sprintf(mux_scratch,
01399 "#-1 FUNCTION (%s) EXPECTS %d ARGUMENTS",
01400 fp->name, fp->minArgs);
01401 }
01402 else if (fp->minArgs + 1 == fp->maxArgs)
01403 {
01404 sprintf(mux_scratch,
01405 "#-1 FUNCTION (%s) EXPECTS %d OR %d ARGUMENTS",
01406 fp->name, fp->minArgs, fp->maxArgs);
01407 }
01408 else if (MuxAlarm.bAlarmed)
01409 {
01410 sprintf(mux_scratch, "#-1 CPU LIMITED");
01411 }
01412 else
01413 {
01414 sprintf(mux_scratch,
01415 "#-1 FUNCTION (%s) EXPECTS BETWEEN %d AND %d ARGUMENTS",
01416 fp->name, fp->minArgs, fp->maxArgs);
01417 }
01418 safe_str(mux_scratch, buff, &oldp);
01419 }
01420 }
01421 *bufc = oldp;
01422 nBufferAvailable = LBUF_SIZE - (*bufc - buff) - 1;
01423 mudstate.func_nest_lev--;
01424 }
01425
01426
01427
01428 for (i = 0; i < nfargs; i++)
01429 {
01430 free_lbuf(fargs[i]);
01431 }
01432 PopPointers(fargs, MAX_ARG);
01433 fargs = NULL;
01434 }
01435 eval &= ~EV_FCHECK;
01436 isSpecial(L1, '(') = false;
01437 }
01438 else if (*pdstr == '%')
01439 {
01440
01441
01442
01443 at_space = 0;
01444 if (!(eval & EV_EVAL))
01445 {
01446 if (nBufferAvailable)
01447 {
01448 *(*bufc)++ = '%';
01449 nBufferAvailable--;
01450 }
01451 pdstr++;
01452 if (nBufferAvailable)
01453 {
01454 *(*bufc)++ = *pdstr;
01455 nBufferAvailable--;
01456 }
01457 }
01458 else
01459 {
01460 pdstr++;
01461 ch = *pdstr;
01462 unsigned char cType_L2 = isSpecial(L2, ch);
01463 TempPtr = *bufc;
01464 int iCode = cType_L2 & 0x7F;
01465 if (iCode == 1)
01466 {
01467
01468
01469
01470
01471
01472 i = ch - '0';
01473 if ( i < ncargs
01474 && cargs[i])
01475 {
01476 safe_str(cargs[i], buff, bufc);
01477 nBufferAvailable = LBUF_SIZE - (*bufc - buff) - 1;
01478 }
01479 }
01480 else if (iCode == 2)
01481 {
01482
01483
01484
01485 pdstr++;
01486 i = mux_RegisterSet[(unsigned char)*pdstr];
01487 if ( 0 <= i
01488 && i < MAX_GLOBAL_REGS)
01489 {
01490 if ( mudstate.glob_reg_len[i] > 0
01491 && mudstate.global_regs[i])
01492 {
01493 safe_copy_buf(mudstate.global_regs[i],
01494 mudstate.glob_reg_len[i], buff, bufc);
01495 nBufferAvailable = LBUF_SIZE - (*bufc - buff) - 1;
01496 }
01497 }
01498 else if (*pdstr == '\0')
01499 {
01500 pdstr--;
01501 }
01502 }
01503 else if (iCode <= 4)
01504 {
01505 if (iCode == 3)
01506 {
01507
01508
01509
01510
01511
01512 mux_scratch[0] = '#';
01513 i = mux_ltoa(enactor, mux_scratch+1);
01514 safe_copy_buf(mux_scratch, i+1, buff, bufc);
01515 nBufferAvailable = LBUF_SIZE - (*bufc - buff) - 1;
01516 }
01517 else if (iCode == 4)
01518 {
01519
01520
01521
01522
01523
01524
01525 mux_scratch[0] = '#';
01526 i = mux_ltoa(executor, mux_scratch+1);
01527 safe_copy_buf(mux_scratch, i+1, buff, bufc);
01528 nBufferAvailable = LBUF_SIZE - (*bufc - buff) - 1;
01529 }
01530 else
01531 {
01532
01533
01534
01535
01536 if (nBufferAvailable)
01537 {
01538 *(*bufc)++ = ch;
01539 nBufferAvailable--;
01540 }
01541 }
01542 }
01543 else if (iCode <= 6)
01544 {
01545 if (iCode == 6)
01546 {
01547
01548
01549
01550
01551
01552 const char *pColor = ColorTable[(unsigned char)pdstr[1]];
01553 if (pColor)
01554 {
01555 pdstr++;
01556 ansi = true;
01557 safe_str(pColor, buff, bufc);
01558 nBufferAvailable = LBUF_SIZE - (*bufc - buff) - 1;
01559 }
01560 else if (pdstr[1] && nBufferAvailable)
01561 {
01562 *(*bufc)++ = *pdstr;
01563 nBufferAvailable--;
01564 }
01565 }
01566 else
01567 {
01568
01569
01570
01571
01572
01573 safe_copy_buf("\r\n", 2, buff, bufc);
01574 nBufferAvailable = LBUF_SIZE - (*bufc - buff) - 1;
01575 }
01576 }
01577 else if (iCode <= 8)
01578 {
01579 if (iCode == 7)
01580 {
01581
01582
01583
01584
01585
01586 if (nBufferAvailable)
01587 {
01588 *(*bufc)++ = ' ';
01589 nBufferAvailable--;
01590 }
01591 }
01592 else
01593 {
01594
01595
01596
01597
01598
01599 if (nBufferAvailable)
01600 {
01601 *(*bufc)++ = '\t';
01602 nBufferAvailable--;
01603 }
01604 }
01605 }
01606 else if (iCode <= 10)
01607 {
01608 if (iCode == 9)
01609 {
01610
01611
01612
01613
01614
01615 if (!(eval & EV_NO_LOCATION))
01616 {
01617 mux_scratch[0] = '#';
01618 i = mux_ltoa(where_is(enactor), mux_scratch+1);
01619 safe_copy_buf(mux_scratch, i+1, buff, bufc);
01620 nBufferAvailable = LBUF_SIZE - (*bufc - buff) - 1;
01621 }
01622 }
01623 else
01624 {
01625
01626
01627
01628
01629
01630 pdstr++;
01631 if (mux_isazAZ(*pdstr))
01632 {
01633 i = A_VA + mux_toupper(*pdstr) - 'A';
01634 size_t nAttrGotten;
01635 atr_pget_str_LEN(mux_scratch, executor, i,
01636 &aowner, &aflags, &nAttrGotten);
01637 if (0 < nAttrGotten)
01638 {
01639 if (nAttrGotten > nBufferAvailable)
01640 {
01641 nAttrGotten = nBufferAvailable;
01642 }
01643 memcpy(*bufc, mux_scratch, nAttrGotten);
01644 *bufc += nAttrGotten;
01645 nBufferAvailable -= nAttrGotten;
01646 }
01647 }
01648 else if (*pdstr == '\0')
01649 {
01650 pdstr--;
01651 }
01652 }
01653 }
01654 else if (iCode <= 14)
01655 {
01656 if (iCode <= 12)
01657 {
01658 if (iCode == 11)
01659 {
01660
01661
01662
01663
01664
01665 if (nBufferAvailable)
01666 {
01667 *(*bufc)++ = '%';
01668 nBufferAvailable--;
01669 }
01670 }
01671 else
01672 {
01673
01674
01675
01676
01677
01678 safe_str(Name(enactor), buff, bufc);
01679 nBufferAvailable = LBUF_SIZE - (*bufc - buff) - 1;
01680 }
01681 }
01682 else
01683 {
01684 if (iCode == 13)
01685 {
01686
01687
01688
01689
01690
01691 safe_str(mudstate.pout, buff, bufc);
01692 nBufferAvailable = LBUF_SIZE - (*bufc - buff) - 1;
01693 }
01694 else
01695 {
01696
01697
01698
01699
01700
01701 if (gender < 0)
01702 {
01703 gender = get_gender(enactor);
01704 }
01705 if (!gender)
01706 {
01707 constbuf = Name(enactor);
01708 }
01709 else
01710 {
01711 constbuf = subj[gender];
01712 }
01713 safe_str(constbuf, buff, bufc);
01714 nBufferAvailable = LBUF_SIZE - (*bufc - buff) - 1;
01715 }
01716 }
01717 }
01718 else
01719 {
01720 if (iCode <= 16)
01721 {
01722 if (iCode == 15)
01723 {
01724
01725
01726
01727
01728
01729 if (gender < 0)
01730 {
01731 gender = get_gender(enactor);
01732 }
01733
01734 if (!gender)
01735 {
01736 safe_str(Name(enactor), buff, bufc);
01737 nBufferAvailable = LBUF_SIZE - (*bufc - buff) - 1;
01738 if (nBufferAvailable)
01739 {
01740 *(*bufc)++ = 's';
01741 nBufferAvailable--;
01742 }
01743 }
01744 else
01745 {
01746 safe_str((char *)poss[gender], buff, bufc);
01747 nBufferAvailable = LBUF_SIZE - (*bufc - buff) - 1;
01748 }
01749 }
01750 else
01751 {
01752
01753
01754
01755
01756
01757 if (gender < 0)
01758 {
01759 gender = get_gender(enactor);
01760 }
01761 if (!gender)
01762 {
01763 constbuf = Name(enactor);
01764 }
01765 else
01766 {
01767 constbuf = obj[gender];
01768 }
01769 safe_str(constbuf, buff, bufc);
01770 nBufferAvailable = LBUF_SIZE - (*bufc - buff) - 1;
01771 }
01772 }
01773 else
01774 {
01775 if (iCode == 17)
01776 {
01777
01778
01779
01780
01781
01782
01783 if (gender < 0)
01784 {
01785 gender = get_gender(enactor);
01786 }
01787
01788 if (!gender)
01789 {
01790 safe_str(Name(enactor), buff, bufc);
01791 nBufferAvailable = LBUF_SIZE - (*bufc - buff) - 1;
01792 if (nBufferAvailable)
01793 {
01794 *(*bufc)++ = 's';
01795 nBufferAvailable--;
01796 }
01797 }
01798 else
01799 {
01800 safe_str(absp[gender], buff, bufc);
01801 nBufferAvailable = LBUF_SIZE - (*bufc - buff) - 1;
01802 }
01803 }
01804 else if (iCode == 18)
01805 {
01806
01807
01808
01809
01810
01811 pdstr--;
01812 }
01813 else if (iCode == 19)
01814 {
01815
01816
01817
01818
01819
01820 safe_str(mudstate.curr_cmd, buff, bufc);
01821 nBufferAvailable = LBUF_SIZE - (*bufc - buff) - 1;
01822 }
01823 else
01824 {
01825
01826
01827
01828
01829
01830
01831 mux_scratch[0] = '#';
01832 i = mux_ltoa(caller, mux_scratch+1);
01833 safe_copy_buf(mux_scratch, i+1, buff, bufc);
01834 nBufferAvailable = LBUF_SIZE - (*bufc - buff) - 1;
01835 }
01836 }
01837 }
01838
01839
01840
01841
01842
01843 if (cType_L2 & 0x80)
01844 {
01845 *TempPtr = mux_toupper(*TempPtr);
01846 }
01847 }
01848 }
01849 else if (*pdstr == '[')
01850 {
01851
01852
01853
01854
01855 tstr = pdstr++;
01856 mudstate.nStackNest++;
01857 tbuf = parse_to_lite(&pdstr, ']', '\0', &at_space, &at_space);
01858 at_space = 0;
01859 if (pdstr == NULL)
01860 {
01861 if (nBufferAvailable)
01862 {
01863 *(*bufc)++ = '[';
01864 nBufferAvailable--;
01865 }
01866 pdstr = tstr;
01867 }
01868 else
01869 {
01870 mudstate.nStackNest--;
01871 TempPtr = tbuf;
01872 mux_exec(buff, bufc, executor, caller, enactor,
01873 (eval | EV_FCHECK | EV_FMAND) & ~EV_TOP, &TempPtr, cargs,
01874 ncargs);
01875 nBufferAvailable = LBUF_SIZE - (*bufc - buff) - 1;
01876 pdstr--;
01877 }
01878 }
01879
01880
01881
01882
01883
01884
01885 else if (*pdstr == ' ')
01886 {
01887
01888
01889
01890 if (bSpaceIsSpecial && !at_space)
01891 {
01892 if (nBufferAvailable)
01893 {
01894 *(*bufc)++ = ' ';
01895 nBufferAvailable--;
01896 }
01897 at_space = 1;
01898 }
01899 }
01900 else if (*pdstr == '{')
01901 {
01902
01903
01904
01905
01906
01907
01908 tstr = pdstr++;
01909 mudstate.nStackNest++;
01910 tbuf = parse_to_lite(&pdstr, '}', '\0', &at_space, &at_space);
01911 at_space = 0;
01912 if (pdstr == NULL)
01913 {
01914 if (nBufferAvailable)
01915 {
01916 *(*bufc)++ = '{';
01917 nBufferAvailable--;
01918 }
01919 pdstr = tstr;
01920 }
01921 else
01922 {
01923 mudstate.nStackNest--;
01924 if (!(eval & EV_STRIP_CURLY))
01925 {
01926 if (nBufferAvailable)
01927 {
01928 *(*bufc)++ = '{';
01929 nBufferAvailable--;
01930 }
01931 }
01932
01933 if (eval & EV_EVAL)
01934 {
01935
01936
01937 if (*tbuf == ' ')
01938 {
01939 if (nBufferAvailable)
01940 {
01941 *(*bufc)++ = ' ';
01942 nBufferAvailable--;
01943 }
01944 tbuf++;
01945 }
01946
01947 TempPtr = tbuf;
01948 mux_exec(buff, bufc, executor, caller, enactor,
01949 (eval & ~(EV_STRIP_CURLY | EV_FCHECK | EV_TOP)),
01950 &TempPtr, cargs, ncargs);
01951 }
01952 else
01953 {
01954 TempPtr = tbuf;
01955 mux_exec(buff, bufc, executor, caller, enactor,
01956 eval & ~EV_TOP, &TempPtr, cargs, ncargs);
01957 }
01958 nBufferAvailable = LBUF_SIZE - (*bufc - buff) - 1;
01959
01960 if (!(eval & EV_STRIP_CURLY))
01961 {
01962 if (nBufferAvailable)
01963 {
01964 *(*bufc)++ = '}';
01965 nBufferAvailable--;
01966 }
01967 }
01968 pdstr--;
01969 }
01970 }
01971 else if (*pdstr == '\\')
01972 {
01973
01974
01975
01976
01977
01978 at_space = 0;
01979 pdstr++;
01980 if (*pdstr)
01981 {
01982 if (nBufferAvailable)
01983 {
01984 *(*bufc)++ = *pdstr;
01985 nBufferAvailable--;
01986 }
01987 }
01988 else
01989 {
01990 pdstr--;
01991 }
01992 }
01993 else
01994 {
01995
01996
01997 at_space = 0;
01998 if (nBufferAvailable)
01999 {
02000 *(*bufc)++ = *pdstr;
02001 nBufferAvailable--;
02002 }
02003 pdstr++;
02004 if (*pdstr)
02005 {
02006 if (nBufferAvailable)
02007 {
02008 *(*bufc)++ = *pdstr;
02009 nBufferAvailable--;
02010 }
02011 }
02012 else
02013 {
02014 pdstr--;
02015 }
02016 }
02017 pdstr++;
02018 }
02019
02020
02021
02022
02023
02024 if ( bSpaceIsSpecial
02025 && at_space
02026 && start != *bufc)
02027 {
02028 (*bufc)--;
02029 }
02030
02031 **bufc = '\0';
02032
02033
02034
02035 if (is_trace)
02036 {
02037 tcache_add(executor, savestr, start);
02038 if ( is_top
02039 || !mudconf.trace_topdown)
02040 {
02041 tcache_finish();
02042 }
02043 if ( is_top
02044 && 0 < tcache_count - mudconf.trace_limit)
02045 {
02046 tbuf = alloc_mbuf("exec.trace_diag");
02047 sprintf(tbuf, "%d lines of trace output discarded.", tcache_count
02048 - mudconf.trace_limit);
02049 notify(executor, tbuf);
02050 free_mbuf(tbuf);
02051 }
02052 }
02053
02054 if ( realbuff
02055 || ansi
02056 || (eval & EV_TOP))
02057 {
02058
02059
02060 static struct ANSI_In_Context aic;
02061 static struct ANSI_Out_Context aoc;
02062
02063 ANSI_String_Out_Init(&aoc, mux_scratch, sizeof(mux_scratch),
02064 sizeof(mux_scratch), ANSI_ENDGOAL_NORMAL);
02065 if (realbuff)
02066 {
02067 *realbp = '\0';
02068 ANSI_String_In_Init(&aic, realbuff, ANSI_ENDGOAL_NORMAL);
02069 ANSI_String_Copy(&aoc, &aic, sizeof(mux_scratch));
02070 }
02071 ANSI_String_In_Init(&aic, buff, ANSI_ENDGOAL_NORMAL);
02072 ANSI_String_Copy(&aoc, &aic, sizeof(mux_scratch));
02073 if (realbuff)
02074 {
02075 MEMFREE(buff);
02076 buff = realbuff;
02077 }
02078
02079 int nVisualWidth;
02080 int nLen = ANSI_String_Finalize(&aoc, &nVisualWidth);
02081 memcpy(buff, mux_scratch, nLen+1);
02082 *bufc = buff + nLen;
02083 }
02084
02085 *dstr = pdstr;
02086
02087
02088
02089 isSpecial(L1, ' ') = bSpaceIsSpecialSave;
02090 isSpecial(L1, '(') = bParenthesisIsSpecialSave;
02091 isSpecial(L1, '[') = bBracketIsSpecialSave;
02092 }
02093
02094
02095
02096
02097
02098
02099 void save_global_regs
02100 (
02101 const char *funcname,
02102 char *preserve[],
02103 int preserve_len[]
02104 )
02105 {
02106 int i;
02107
02108 for (i = 0; i < MAX_GLOBAL_REGS; i++)
02109 {
02110 if (mudstate.global_regs[i])
02111 {
02112 preserve[i] = alloc_lbuf(funcname);
02113 int n = mudstate.glob_reg_len[i];
02114 memcpy(preserve[i], mudstate.global_regs[i], n);
02115 preserve[i][n] = '\0';
02116 preserve_len[i] = n;
02117 }
02118 else
02119 {
02120 preserve[i] = NULL;
02121 preserve_len[i] = 0;
02122 }
02123 }
02124 }
02125
02126 void save_and_clear_global_regs
02127 (
02128 const char *funcname,
02129 char *preserve[],
02130 int preserve_len[]
02131 )
02132 {
02133 UNUSED_PARAMETER(funcname);
02134
02135 int i;
02136
02137 for (i = 0; i < MAX_GLOBAL_REGS; i++)
02138 {
02139 preserve[i] = mudstate.global_regs[i];
02140 preserve_len[i] = mudstate.glob_reg_len[i];
02141
02142 mudstate.global_regs[i] = NULL;
02143 mudstate.glob_reg_len[i] = 0;
02144 }
02145 }
02146
02147 void restore_global_regs
02148 (
02149 const char *funcname,
02150 char *preserve[],
02151 int preserve_len[]
02152 )
02153 {
02154 UNUSED_PARAMETER(funcname);
02155
02156 int i;
02157
02158 for (i = 0; i < MAX_GLOBAL_REGS; i++)
02159 {
02160 if (preserve[i])
02161 {
02162 if (mudstate.global_regs[i])
02163 {
02164 free_lbuf(mudstate.global_regs[i]);
02165 }
02166 mudstate.global_regs[i] = preserve[i];
02167 mudstate.glob_reg_len[i] = preserve_len[i];
02168 }
02169 else
02170 {
02171 if (mudstate.global_regs[i])
02172 {
02173 mudstate.global_regs[i][0] = '\0';
02174 }
02175 mudstate.glob_reg_len[i] = 0;
02176 }
02177 }
02178 }