00001
00002
00003
00004
00005 #include "copyright.h"
00006 #include "config.h"
00007
00008 #include "db.h"
00009 #include "externs.h"
00010 #include "attrs.h"
00011 #include "functions.h"
00012 #include "alloc.h"
00013 #include "ansi.h"
00014
00024 static char *parse_to_cleanup(int eval, int first, char *cstr, char *rstr,
00025 char *zstr)
00026 {
00027 if((mudconf.space_compress || (eval & EV_STRIP_TS)) &&
00028 !(eval & EV_NO_COMPRESS) && !first && (cstr[-1] == ' '))
00029 zstr--;
00030 if((eval & EV_STRIP_AROUND) && (*rstr == '{') && (zstr[-1] == '}')) {
00031 rstr++;
00032 if(mudconf.space_compress && (!(eval & EV_NO_COMPRESS) ||
00033 (eval & EV_STRIP_LS)))
00034 while (*rstr && isspace(*rstr))
00035 rstr++;
00036 rstr[-1] = '\0';
00037 zstr--;
00038 if(mudconf.space_compress && (!(eval & EV_NO_COMPRESS) ||
00039 (eval & EV_STRIP_TS)))
00040 while (zstr[-1] && isspace(zstr[-1]))
00041 zstr--;
00042 *zstr = '\0';
00043 }
00044 *zstr = '\0';
00045 return rstr;
00046 }
00047
00048
00049
00050
00051 #define NEXTCHAR \
00052 do {if (cstr == zstr) { \
00053 cstr++; \
00054 zstr++; \
00055 } else \
00056 *zstr++ = *cstr++;} while (0)
00057
00058 char *parse_to(char **dstr, char delim, int eval)
00059 {
00060 #define stacklim 32
00061 char stack[stacklim];
00062 char *rstr, *cstr, *zstr;
00063 int sp, tp, first, bracketlev;
00064
00065 if((dstr == NULL) || (*dstr == NULL))
00066 return NULL;
00067 if(**dstr == '\0') {
00068 rstr = *dstr;
00069 *dstr = NULL;
00070 return rstr;
00071 }
00072 sp = 0;
00073 first = 1;
00074 rstr = *dstr;
00075 if((mudconf.space_compress || (eval & EV_STRIP_LS)) &&
00076 !(eval & EV_NO_COMPRESS)) {
00077 while (*rstr && isspace(*rstr))
00078 rstr++;
00079 *dstr = rstr;
00080 }
00081 zstr = cstr = rstr;
00082 while (*cstr) {
00083 switch (*cstr) {
00084 case '\\':
00085
00086
00087 case '%':
00088
00089
00090 if((*cstr == '\\') && (eval & EV_STRIP_ESC))
00091 cstr++;
00092 else
00093 NEXTCHAR;
00094 if(*cstr)
00095 NEXTCHAR;
00096 first = 0;
00097 break;
00098 case ']':
00099 case ')':
00100 for(tp = sp - 1; (tp >= 0) && (stack[tp] != *cstr); tp--);
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111 if(tp >= 0)
00112 sp = tp;
00113 else if(*cstr == delim) {
00114 rstr = parse_to_cleanup(eval, first, cstr, rstr, zstr);
00115 *dstr = ++cstr;
00116 return rstr;
00117 }
00118 first = 0;
00119 NEXTCHAR;
00120 break;
00121 case '{':
00122 bracketlev = 1;
00123 if(eval & EV_STRIP) {
00124 cstr++;
00125 } else {
00126 NEXTCHAR;
00127 }
00128 while (*cstr && (bracketlev > 0)) {
00129 switch (*cstr) {
00130 case '\\':
00131 case '%':
00132 if(cstr[1]) {
00133 if((*cstr == '\\') && (eval & EV_STRIP_ESC))
00134 cstr++;
00135 else
00136 NEXTCHAR;
00137 }
00138 break;
00139 case '{':
00140 bracketlev++;
00141 break;
00142 case '}':
00143 bracketlev--;
00144 break;
00145 }
00146 if(bracketlev > 0) {
00147 NEXTCHAR;
00148 }
00149 }
00150 if((eval & EV_STRIP) && (bracketlev == 0)) {
00151 cstr++;
00152 } else if(bracketlev == 0) {
00153 NEXTCHAR;
00154 }
00155 first = 0;
00156 break;
00157 default:
00158 if((*cstr == delim) && (sp == 0)) {
00159 rstr = parse_to_cleanup(eval, first, cstr, rstr, zstr);
00160 *dstr = ++cstr;
00161 return rstr;
00162 }
00163 switch (*cstr) {
00164 case ' ':
00165
00166
00167 if(mudconf.space_compress && !(eval & EV_NO_COMPRESS)) {
00168 if(first)
00169 rstr++;
00170 else if(cstr[-1] == ' ')
00171 zstr--;
00172 }
00173 break;
00174 case '[':
00175 if(cstr != rstr && cstr[-1] == ESC_CHAR) {
00176 first = 0;
00177 break;
00178 }
00179 if(sp < stacklim)
00180 stack[sp++] = ']';
00181 first = 0;
00182 break;
00183 case '(':
00184 if(sp < stacklim)
00185 stack[sp++] = ')';
00186 first = 0;
00187 break;
00188 default:
00189 first = 0;
00190 }
00191 NEXTCHAR;
00192 }
00193 }
00194 rstr = parse_to_cleanup(eval, first, cstr, rstr, zstr);
00195 *dstr = NULL;
00196 return rstr;
00197 }
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207 char *parse_arglist(dbref player, dbref cause, char *dstr, char delim,
00208 dbref eval, char *fargs[], dbref nfargs, char *cargs[],
00209 dbref ncargs)
00210 {
00211 char *rstr, *tstr, *bp, *str;
00212 int arg, peval;
00213
00214 for(arg = 0; arg < nfargs; arg++)
00215 fargs[arg] = NULL;
00216 if(dstr == NULL)
00217 return NULL;
00218 rstr = parse_to(&dstr, delim, 0);
00219 arg = 0;
00220
00221 peval = (eval & ~EV_EVAL);
00222
00223 while ((arg < nfargs) && rstr) {
00224 if(arg < (nfargs - 1))
00225 tstr = parse_to(&rstr, ',', peval);
00226 else
00227 tstr = parse_to(&rstr, '\0', peval);
00228 if(eval & EV_EVAL) {
00229 bp = fargs[arg] = alloc_lbuf("parse_arglist");
00230 str = tstr;
00231 exec(fargs[arg], &bp, 0, player, cause, eval | EV_FCHECK, &str,
00232 cargs, ncargs);
00233 *bp = '\0';
00234 } else {
00235 fargs[arg] = alloc_lbuf("parse_arglist");
00236 StringCopy(fargs[arg], tstr);
00237 }
00238 arg++;
00239 }
00240 return dstr;
00241 }
00242
00243
00244
00245
00246
00247
00248 int get_gender(dbref player)
00249 {
00250 char first, *atr_gotten;
00251 dbref aowner;
00252 int aflags;
00253
00254 atr_gotten = atr_pget(player, A_SEX, &aowner, &aflags);
00255 first = *atr_gotten;
00256 free_lbuf(atr_gotten);
00257 switch (first) {
00258 case 'P':
00259 case 'p':
00260 return 4;
00261 case 'M':
00262 case 'm':
00263 return 3;
00264 case 'F':
00265 case 'f':
00266 case 'W':
00267 case 'w':
00268 return 2;
00269 default:
00270 return 1;
00271 }
00272 }
00273
00274
00275
00276
00277
00278
00279 typedef struct tcache_ent TCENT;
00280 struct tcache_ent {
00281 char *orig;
00282 char *result;
00283 struct tcache_ent *next;
00284 } *tcache_head;
00285 int tcache_top, tcache_count;
00286
00287 void tcache_init(void)
00288 {
00289 tcache_head = NULL;
00290 tcache_top = 1;
00291 tcache_count = 0;
00292 }
00293
00294 int tcache_empty(void)
00295 {
00296 if(tcache_top) {
00297 tcache_top = 0;
00298 tcache_count = 0;
00299 return 1;
00300 }
00301 return 0;
00302 }
00303
00304 static void tcache_add(char *orig, char *result)
00305 {
00306 char *tp;
00307 TCENT *xp;
00308
00309 if(strcmp(orig, result)) {
00310 tcache_count++;
00311 if(tcache_count <= mudconf.trace_limit) {
00312 xp = (TCENT *) alloc_sbuf("tcache_add.sbuf");
00313 tp = alloc_lbuf("tcache_add.lbuf");
00314 StringCopy(tp, result);
00315 xp->orig = orig;
00316 xp->result = tp;
00317 xp->next = tcache_head;
00318 tcache_head = xp;
00319 } else {
00320 free_lbuf(orig);
00321 }
00322 } else {
00323 free_lbuf(orig);
00324 }
00325 }
00326
00327 static void tcache_finish(dbref player)
00328 {
00329 TCENT *xp;
00330
00331 while (tcache_head != NULL) {
00332 xp = tcache_head;
00333 tcache_head = xp->next;
00334 notify_printf(Owner(player), "%s(#%d)} '%s' -> '%s'",
00335 Name(player), player, xp->orig, xp->result);
00336 free_lbuf(xp->orig);
00337 free_lbuf(xp->result);
00338 free_sbuf(xp);
00339 }
00340 tcache_top = 1;
00341 tcache_count = 0;
00342 }
00343
00344 void exec(char *buff, char **bufc, int tflags, dbref player, dbref cause,
00345 int eval, char **dstr, char *cargs[], int ncargs)
00346 {
00347 #define NFARGS 30
00348 char *fargs[NFARGS];
00349 char *preserve[MAX_GLOBAL_REGS];
00350 char *tstr, *tbuf, *tbufc, *savepos, *atr_gotten, *start, *oldp, *savestr;
00351 char savec, ch, *str;
00352 char *realbuff = NULL, *realbp = NULL;
00353 dbref aowner;
00354 int at_space, nfargs, gender, i, j, alldone, aflags, feval;
00355 int is_trace, is_top, save_count;
00356 int ansi;
00357 FUN *fp;
00358 UFUN *ufp;
00359
00360 static const char *subj[5] = { "", "it", "she", "he", "they" };
00361 static const char *poss[5] = { "", "its", "her", "his", "their" };
00362 static const char *obj[5] = { "", "it", "her", "him", "them" };
00363 static const char *absp[5] = { "", "its", "hers", "his", "theirs" };
00364
00365 if(*dstr == NULL)
00366 return;
00367
00368
00369
00370 at_space = 1;
00371 gender = -1;
00372 alldone = 0;
00373 ansi = 0;
00374
00375 is_trace = Trace(player) && !(eval & EV_NOTRACE);
00376 is_top = 0;
00377
00378
00379
00380 if(((*bufc) - buff) > (LBUF_SIZE - SBUF_SIZE)) {
00381 realbuff = buff;
00382 realbp = *bufc;
00383 buff = (char *) malloc(LBUF_SIZE);
00384 *bufc = buff;
00385 }
00386
00387 oldp = start = *bufc;
00388
00389
00390
00391
00392
00393 savestr = NULL;
00394 if(is_trace) {
00395 is_top = tcache_empty();
00396 savestr = alloc_lbuf("exec.save");
00397 StringCopy(savestr, *dstr);
00398 }
00399 while (**dstr && !alldone) {
00400 switch (**dstr) {
00401 case ' ':
00402
00403
00404
00405
00406
00407
00408 if(!(mudconf.space_compress && at_space) ||
00409 (eval & EV_NO_COMPRESS)) {
00410 safe_chr(' ', buff, bufc);
00411 at_space = 1;
00412 }
00413 break;
00414 case '\\':
00415
00416
00417
00418
00419
00420 at_space = 0;
00421 (*dstr)++;
00422 if(**dstr)
00423 safe_chr(**dstr, buff, bufc);
00424 else
00425 (*dstr)--;
00426 break;
00427 case '[':
00428
00429
00430
00431
00432
00433
00434 at_space = 0;
00435 tstr = (*dstr)++;
00436 if(eval & EV_NOFCHECK) {
00437 safe_chr('[', buff, bufc);
00438 *dstr = tstr;
00439 break;
00440 }
00441 tbuf = parse_to(dstr, ']', 0);
00442 if(*dstr == NULL) {
00443 safe_chr('[', buff, bufc);
00444 *dstr = tstr;
00445 } else {
00446 str = tbuf;
00447 exec(buff, bufc, 0, player, cause,
00448 (eval | EV_FCHECK | EV_FMAND), &str, cargs, ncargs);
00449 (*dstr)--;
00450 }
00451 break;
00452 case '{':
00453
00454
00455
00456
00457
00458
00459 at_space = 0;
00460 tstr = (*dstr)++;
00461 tbuf = parse_to(dstr, '}', 0);
00462 if(*dstr == NULL) {
00463 safe_chr('{', buff, bufc);
00464 *dstr = tstr;
00465 } else {
00466 if(!(eval & EV_STRIP)) {
00467 safe_chr('{', buff, bufc);
00468 }
00469
00470
00471
00472
00473 if(*tbuf == ' ') {
00474 safe_chr(' ', buff, bufc);
00475 tbuf++;
00476 }
00477 str = tbuf;
00478 exec(buff, bufc, 0, player, cause,
00479 (eval & ~(EV_STRIP | EV_FCHECK)), &str, cargs, ncargs);
00480 if(!(eval & EV_STRIP)) {
00481 safe_chr('}', buff, bufc);
00482 }
00483 (*dstr)--;
00484 }
00485 break;
00486 case '%':
00487
00488
00489
00490
00491
00492
00493 at_space = 0;
00494 (*dstr)++;
00495 savec = **dstr;
00496 savepos = *bufc;
00497 switch (savec) {
00498 case '\0':
00499
00500
00501 (*dstr)--;
00502 break;
00503 case '|':
00504 safe_str(mudstate.pout, buff, bufc);
00505 break;
00506 case '%':
00507
00508
00509 safe_chr('%', buff, bufc);
00510 break;
00511 case 'c':
00512 case 'C':
00513 (*dstr)++;
00514 if(!**dstr)
00515 (*dstr)--;
00516 ansi = 1;
00517 switch (**dstr) {
00518 case 'h':
00519
00520
00521 safe_str(ANSI_HILITE, buff, bufc);
00522 break;
00523 case 'i':
00524
00525
00526 safe_str(ANSI_INVERSE, buff, bufc);
00527 break;
00528 case 'f':
00529
00530
00531 safe_str(ANSI_BLINK, buff, bufc);
00532 break;
00533 case 'u':
00534 safe_str(ANSI_UNDER, buff, bufc);
00535 break;
00536 case 'n':
00537
00538
00539 safe_str(ANSI_NORMAL, buff, bufc);
00540 ansi = 0;
00541 break;
00542 case 'x':
00543
00544
00545 safe_str(ANSI_BLACK, buff, bufc);
00546 break;
00547 case 'r':
00548
00549
00550 safe_str(ANSI_RED, buff, bufc);
00551 break;
00552 case 'g':
00553
00554
00555 safe_str(ANSI_GREEN, buff, bufc);
00556 break;
00557 case 'y':
00558
00559
00560 safe_str(ANSI_YELLOW, buff, bufc);
00561 break;
00562 case 'b':
00563
00564
00565 safe_str(ANSI_BLUE, buff, bufc);
00566 break;
00567 case 'm':
00568
00569
00570 safe_str(ANSI_MAGENTA, buff, bufc);
00571 break;
00572 case 'c':
00573
00574
00575 safe_str(ANSI_CYAN, buff, bufc);
00576 break;
00577 case 'w':
00578
00579
00580 safe_str(ANSI_WHITE, buff, bufc);
00581 break;
00582 case 'X':
00583
00584
00585 safe_str(ANSI_BBLACK, buff, bufc);
00586 break;
00587 case 'R':
00588
00589
00590 safe_str(ANSI_BRED, buff, bufc);
00591 break;
00592 case 'G':
00593
00594
00595 safe_str(ANSI_BGREEN, buff, bufc);
00596 break;
00597 case 'Y':
00598
00599
00600 safe_str(ANSI_BYELLOW, buff, bufc);
00601 break;
00602 case 'B':
00603
00604
00605 safe_str(ANSI_BBLUE, buff, bufc);
00606 break;
00607 case 'M':
00608
00609
00610 safe_str(ANSI_BMAGENTA, buff, bufc);
00611 break;
00612 case 'C':
00613
00614
00615 safe_str(ANSI_BCYAN, buff, bufc);
00616 break;
00617 case 'W':
00618
00619
00620 safe_str(ANSI_BWHITE, buff, bufc);
00621 break;
00622 default:
00623 safe_chr(**dstr, buff, bufc);
00624 }
00625 break;
00626 case 'r':
00627
00628
00629 case 'R':
00630 safe_str((char *) "\r\n", buff, bufc);
00631 break;
00632 case 't':
00633
00634
00635 case 'T':
00636 safe_chr('\t', buff, bufc);
00637 break;
00638 case 'B':
00639
00640
00641 case 'b':
00642 safe_chr(' ', buff, bufc);
00643 break;
00644 case '0':
00645
00646
00647 case '1':
00648 case '2':
00649 case '3':
00650 case '4':
00651 case '5':
00652 case '6':
00653 case '7':
00654 case '8':
00655 case '9':
00656 i = (**dstr - '0');
00657 if((i < ncargs) && (cargs[i] != NULL))
00658 safe_str(cargs[i], buff, bufc);
00659 break;
00660 case 'V':
00661
00662
00663 case 'v':
00664 (*dstr)++;
00665 ch = ToUpper(**dstr);
00666 if(!**dstr)
00667 (*dstr)--;
00668 if((ch < 'A') || (ch > 'Z'))
00669 break;
00670 i = 100 + ch - 'A';
00671 atr_gotten = atr_pget(player, i, &aowner, &aflags);
00672 safe_str(atr_gotten, buff, bufc);
00673 free_lbuf(atr_gotten);
00674 break;
00675 case 'Q':
00676 case 'q':
00677 (*dstr)++;
00678 i = (**dstr - '0');
00679 if((i >= 0) && (i <= 9) && mudstate.global_regs[i]) {
00680 safe_str(mudstate.global_regs[i], buff, bufc);
00681 }
00682 if(!**dstr)
00683 (*dstr)--;
00684 break;
00685 case 'O':
00686
00687
00688 case 'o':
00689 if(gender < 0)
00690 gender = get_gender(cause);
00691 if(!gender)
00692 tbuf = Name(cause);
00693 else
00694 tbuf = (char *) obj[gender];
00695 safe_str(tbuf, buff, bufc);
00696 break;
00697 case 'P':
00698
00699
00700 case 'p':
00701 if(gender < 0)
00702 gender = get_gender(cause);
00703 if(!gender) {
00704 safe_str(Name(cause), buff, bufc);
00705 safe_chr('s', buff, bufc);
00706 } else {
00707 safe_str((char *) poss[gender], buff, bufc);
00708 }
00709 break;
00710 case 'S':
00711
00712
00713 case 's':
00714 if(gender < 0)
00715 gender = get_gender(cause);
00716 if(!gender)
00717 tbuf = Name(cause);
00718 else
00719 tbuf = (char *) subj[gender];
00720 safe_str(tbuf, buff, bufc);
00721 break;
00722 case 'A':
00723
00724
00725 case 'a':
00726
00727
00728 if(gender < 0)
00729 gender = get_gender(cause);
00730 if(!gender) {
00731 safe_str(Name(cause), buff, bufc);
00732 safe_chr('s', buff, bufc);
00733 } else {
00734 safe_str((char *) absp[gender], buff, bufc);
00735 }
00736 break;
00737 case '#':
00738
00739
00740 tbuf = alloc_sbuf("exec.invoker");
00741 sprintf(tbuf, "#%d", cause);
00742 safe_str(tbuf, buff, bufc);
00743 free_sbuf(tbuf);
00744 break;
00745 case '!':
00746
00747
00748 tbuf = alloc_sbuf("exec.executor");
00749 sprintf(tbuf, "#%d", player);
00750 safe_str(tbuf, buff, bufc);
00751 free_sbuf(tbuf);
00752 break;
00753 case 'N':
00754
00755
00756 case 'n':
00757 safe_str(Name(cause), buff, bufc);
00758 break;
00759 case 'L':
00760
00761
00762 case 'l':
00763 if(!(eval & EV_NO_LOCATION)) {
00764 tbuf = alloc_sbuf("exec.exloc");
00765 sprintf(tbuf, "#%d", where_is(cause));
00766 safe_str(tbuf, buff, bufc);
00767 free_sbuf(tbuf);
00768 }
00769
00770 break;
00771 default:
00772
00773
00774 safe_chr(**dstr, buff, bufc);
00775 }
00776 if(isupper(savec))
00777 *savepos = ToUpper(*savepos);
00778 break;
00779 case '(':
00780
00781
00782
00783
00784
00785 at_space = 0;
00786 if(!(eval & EV_FCHECK)) {
00787 safe_chr('(', buff, bufc);
00788 break;
00789 }
00790
00791
00792
00793
00794
00795
00796 **bufc = '\0';
00797 tbufc = tbuf = alloc_sbuf("exec.tbuf");
00798 safe_sb_str(oldp, tbuf, &tbufc);
00799 *tbufc = '\0';
00800 if(mudconf.space_compress) {
00801 while ((--tbufc >= tbuf) && isspace(*tbufc));
00802 tbufc++;
00803 *tbufc = '\0';
00804 }
00805 for(tbufc = tbuf; *tbufc; tbufc++)
00806 *tbufc = ToLower(*tbufc);
00807 fp = (FUN *) hashfind(tbuf, &mudstate.func_htab);
00808
00809
00810
00811
00812
00813 ufp = NULL;
00814 if(fp == NULL) {
00815 ufp = (UFUN *) hashfind(tbuf, &mudstate.ufunc_htab);
00816 }
00817
00818
00819
00820
00821 if(!fp && !ufp) {
00822 if(eval & EV_FMAND) {
00823 *bufc = oldp;
00824 safe_str((char *) "#-1 FUNCTION (", buff, bufc);
00825 safe_str(tbuf, buff, bufc);
00826 safe_str((char *) ") NOT FOUND", buff, bufc);
00827 alldone = 1;
00828 } else {
00829 safe_chr('(', buff, bufc);
00830 }
00831 free_sbuf(tbuf);
00832 eval &= ~EV_FCHECK;
00833 break;
00834 }
00835 free_sbuf(tbuf);
00836
00837
00838
00839
00840
00841
00842
00843
00844 if(ufp)
00845 nfargs = NFARGS;
00846 else if(fp->nargs < 0)
00847 nfargs = -fp->nargs;
00848 else
00849 nfargs = NFARGS;
00850 tstr = *dstr;
00851 if(fp && (fp->flags & FN_NO_EVAL))
00852 feval = (eval & ~EV_EVAL) | EV_STRIP_ESC;
00853 else
00854 feval = eval;
00855 *dstr =
00856 parse_arglist(player, cause, *dstr + 1, ')', feval, fargs,
00857 nfargs, cargs, ncargs);
00858
00859
00860
00861
00862
00863
00864
00865 if(!*dstr) {
00866 *dstr = tstr;
00867 safe_chr(**dstr, buff, bufc);
00868 for(i = 0; i < nfargs; i++)
00869 if(fargs[i] != NULL)
00870 free_lbuf(fargs[i]);
00871 eval &= ~EV_FCHECK;
00872 break;
00873 }
00874
00875
00876
00877
00878 (*dstr)--;
00879 j = 0;
00880 for(i = 0; i < nfargs; i++)
00881 if(fargs[i] != NULL)
00882 j = i + 1;
00883 nfargs = j;
00884
00885
00886
00887
00888
00889 if(ufp) {
00890 mudstate.func_nest_lev++;
00891 if(!check_access(player, ufp->perms)) {
00892 safe_str("#-1 PERMISSION DENIED", buff, &oldp);
00893 *bufc = oldp;
00894 } else {
00895 tstr = atr_get(ufp->obj, ufp->atr, &aowner, &aflags);
00896 if(ufp->flags & FN_PRIV)
00897 i = ufp->obj;
00898 else
00899 i = player;
00900 str = tstr;
00901
00902 if(ufp->flags & FN_PRES) {
00903 for(j = 0; j < MAX_GLOBAL_REGS; j++) {
00904 if(!mudstate.global_regs[j])
00905 preserve[j] = NULL;
00906 else {
00907 preserve[j] = alloc_lbuf("eval_regs");
00908 StringCopy(preserve[j],
00909 mudstate.global_regs[j]);
00910 }
00911 }
00912 }
00913
00914 exec(buff, &oldp, 0, i, cause, feval, &str, fargs,
00915 nfargs);
00916 *bufc = oldp;
00917
00918 if(ufp->flags & FN_PRES) {
00919 for(j = 0; j < MAX_GLOBAL_REGS; j++) {
00920 if(preserve[j]) {
00921 if(!mudstate.global_regs[j])
00922 mudstate.global_regs[j] =
00923 alloc_lbuf("eval_regs");
00924 StringCopy(mudstate.global_regs[j],
00925 preserve[j]);
00926 free_lbuf(preserve[j]);
00927 } else {
00928 if(mudstate.global_regs[j])
00929 *(mudstate.global_regs[i]) = '\0';
00930 }
00931 }
00932 }
00933
00934 free_lbuf(tstr);
00935 }
00936
00937
00938
00939
00940
00941 mudstate.func_nest_lev--;
00942 for(i = 0; i < nfargs; i++)
00943 if(fargs[i] != NULL)
00944 free_lbuf(fargs[i]);
00945 eval &= ~EV_FCHECK;
00946 break;
00947 }
00948
00949
00950
00951
00952
00953
00954
00955
00956 if((fp->nargs == 0) && (nfargs == 1)) {
00957 if(!*fargs[0]) {
00958 free_lbuf(fargs[0]);
00959 fargs[0] = NULL;
00960 nfargs = 0;
00961 }
00962 }
00963 if((nfargs == fp->nargs) || (nfargs == -fp->nargs) ||
00964 (fp->flags & FN_VARARGS)) {
00965
00966
00967
00968
00969
00970 mudstate.func_nest_lev++;
00971 mudstate.func_invk_ctr++;
00972 if(mudstate.func_nest_lev >= mudconf.func_nest_lim) {
00973 safe_str("#-1 FUNCTION RECURSION LIMIT EXCEEDED", buff,
00974 bufc);
00975 } else if(mudstate.func_invk_ctr == mudconf.func_invk_lim) {
00976 safe_str("#-1 FUNCTION INVOCATION LIMIT EXCEEDED",
00977 buff, bufc);
00978 } else if(!check_access(player, fp->perms)) {
00979 safe_str("#-1 PERMISSION DENIED", buff, &oldp);
00980 *bufc = oldp;
00981 } else if(mudstate.func_invk_ctr < mudconf.func_invk_lim) {
00982 fp->fun(buff, &oldp, player, cause, fargs, nfargs,
00983 cargs, ncargs);
00984 *bufc = oldp;
00985 } else {
00986 **bufc = '\0';
00987 }
00988 mudstate.func_nest_lev--;
00989 } else {
00990 *bufc = oldp;
00991 tstr = alloc_sbuf("exec.funcargs");
00992 sprintf(tstr, "%d", fp->nargs);
00993 safe_str((char *) "#-1 FUNCTION (", buff, bufc);
00994 safe_str((char *) fp->name, buff, bufc);
00995 safe_str((char *) ") EXPECTS ", buff, bufc);
00996 safe_str(tstr, buff, bufc);
00997 safe_str((char *) " ARGUMENTS", buff, bufc);
00998 free_sbuf(tstr);
00999 }
01000
01001
01002
01003
01004
01005 for(i = 0; i < nfargs; i++)
01006 if(fargs[i] != NULL)
01007 free_lbuf(fargs[i]);
01008 eval &= ~EV_FCHECK;
01009 break;
01010 default:
01011
01012
01013
01014
01015 at_space = 0;
01016 safe_chr(**dstr, buff, bufc);
01017 }
01018 (*dstr)++;
01019 }
01020
01021
01022
01023
01024
01025
01026
01027
01028 if(mudconf.space_compress && at_space && !(eval & EV_NO_COMPRESS)
01029 && (start != *bufc))
01030 (*bufc)--;
01031
01032
01033
01034
01035
01036
01037
01038
01039 if(ansi == 1)
01040 safe_str(ANSI_NORMAL, buff, bufc);
01041
01042 **bufc = '\0';
01043
01044
01045
01046
01047
01048 if(realbuff) {
01049 **bufc = '\0';
01050 *bufc = realbp;
01051 safe_str(buff, realbuff, bufc);
01052 free(buff);
01053 buff = realbuff;
01054 }
01055
01056 if(is_trace) {
01057 tcache_add(savestr, start);
01058 save_count = tcache_count - mudconf.trace_limit;;
01059 if(is_top || !mudconf.trace_topdown)
01060 tcache_finish(player);
01061 if(is_top && (save_count > 0)) {
01062 tbuf = alloc_mbuf("exec.trace_diag");
01063 sprintf(tbuf, "%d lines of trace output discarded.", save_count);
01064 notify(player, tbuf);
01065 free_mbuf(tbuf);
01066 }
01067 }
01068 }