#include "copyright.h"
#include "config.h"
#include "db.h"
#include "match.h"
#include "mudconf.h"
#include "externs.h"
#include "interface.h"
#include "attrs.h"
#include "flags.h"
#include "powers.h"
#include "alloc.h"
Include dependency graph for boolexp.c:
Go to the source code of this file.
Functions | |
static int | check_attr (dbref player, dbref lockobj, ATTR *attr, char *key) |
int | eval_boolexp (dbref player, dbref thing, dbref from, BOOLEXP *b) |
int | eval_boolexp_atr (dbref player, dbref thing, dbref from, char *key) |
static void | skip_whitespace (void) |
static BOOLEXP * | parse_boolexp_E (void) |
static BOOLEXP * | test_atr (char *s) |
static BOOLEXP * | parse_boolexp_L (void) |
static BOOLEXP * | parse_boolexp_F (void) |
static BOOLEXP * | parse_boolexp_T (void) |
BOOLEXP * | parse_boolexp (dbref player, const char *buf, int internal) |
Variables | |
static int | parsing_internal = 0 |
static const char * | parsebuf |
static char | parsestore [LBUF_SIZE] |
static dbref | parse_player |
Indicate if attribute ATTR on player passes key when checked by the object lockobj
Definition at line 24 of file boolexp.c.
References A_LENTER, A_NAME, atr_pget(), attr, free_lbuf, attr::number, See_attr, and wild_match().
Referenced by eval_boolexp().
00025 { 00026 char *buff; 00027 dbref aowner; 00028 int aflags, checkit; 00029 00030 buff = atr_pget(player, attr->number, &aowner, &aflags); 00031 checkit = 0; 00032 00033 if(attr->number == A_LENTER) { 00034 /* We can see enterlocks... else we'd break zones */ 00035 checkit = 1; 00036 } else if(See_attr(lockobj, player, attr, aowner, aflags)) { 00037 checkit = 1; 00038 } else if(attr->number == A_NAME) { 00039 checkit = 1; 00040 } 00041 if(checkit && (!wild_match(key, buff))) { 00042 checkit = 0; 00043 } 00044 free_lbuf(buff); 00045 return checkit; 00046 } /* end check_attr() */
Definition at line 48 of file boolexp.c.
References A_LENTER, A_LOCK, A_NAME, alloc_lbuf, alloc_mbuf, atr_get(), atr_num(), atr_pget(), BOOLEXP_AND, BOOLEXP_ATR, BOOLEXP_CARRY, BOOLEXP_CONST, BOOLEXP_EVAL, BOOLEXP_INDIR, BOOLEXP_IS, BOOLEXP_NOT, BOOLEXP_OR, BOOLEXP_OWNER, c, check_attr(), Contents, DOLIST, ENDLOG, EV_EVAL, EV_FIGNORE, EV_TOP, eval_boolexp(), eval_boolexp_atr(), exec(), free_lbuf, free_mbuf, INDIR_TOKEN, statedata::lock_nest_lev, confdata::lock_nest_lim, LOG_BUGS, log_name_and_loc(), log_text(), member(), mudconf, mudstate, notify, attr::number, Owner, Read_attr, STARTLOG, string_compare(), boolexp::sub1, boolexp::sub2, boolexp::thing, TRUE_BOOLEXP, and boolexp::type.
Referenced by eval_boolexp(), eval_boolexp_atr(), and fun_elock().
00049 { 00050 dbref aowner, obj, source; 00051 int aflags, c, checkit; 00052 char *key, *buff, *buff2, *bp, *str; 00053 ATTR *a; 00054 00055 if(b == TRUE_BOOLEXP) 00056 return 1; 00057 00058 switch (b->type) { 00059 case BOOLEXP_AND: 00060 return (eval_boolexp(player, thing, from, b->sub1) && 00061 eval_boolexp(player, thing, from, b->sub2)); 00062 case BOOLEXP_OR: 00063 return (eval_boolexp(player, thing, from, b->sub1) || 00064 eval_boolexp(player, thing, from, b->sub2)); 00065 case BOOLEXP_NOT: 00066 return !eval_boolexp(player, thing, from, b->sub1); 00067 case BOOLEXP_INDIR: 00068 /* 00069 * BOOLEXP_INDIR (i.e. @) is a unary operation which is replaced at 00070 * evaluation time by the lock of the object whose number is the 00071 * argument of the operation. 00072 */ 00073 00074 mudstate.lock_nest_lev++; 00075 if(mudstate.lock_nest_lev >= mudconf.lock_nest_lim) { 00076 // log_error(LOG_BUGS, "BUG", "LOCK", " 00077 STARTLOG(LOG_BUGS, "BUG", "LOCK") { 00078 log_name_and_loc(player); 00079 log_text((char *) ": Lock exceeded recursion limit."); 00080 ENDLOG; 00081 } notify(player, "Sorry, broken lock!"); 00082 mudstate.lock_nest_lev--; 00083 return (0); 00084 } 00085 if((b->sub1->type != BOOLEXP_CONST) || (b->sub1->thing < 0)) { 00086 STARTLOG(LOG_BUGS, "BUG", "LOCK") { 00087 log_name_and_loc(player); 00088 buff = alloc_mbuf("eval_boolexp.LOG.indir"); 00089 sprintf(buff, ": Lock had bad indirection (%c, type %d)", 00090 INDIR_TOKEN, b->sub1->type); 00091 log_text(buff); 00092 free_mbuf(buff); 00093 ENDLOG; 00094 } 00095 notify(player, "Sorry, broken lock!"); 00096 mudstate.lock_nest_lev--; 00097 return (0); 00098 } 00099 key = atr_get(b->sub1->thing, A_LOCK, &aowner, &aflags); 00100 c = eval_boolexp_atr(player, b->sub1->thing, from, key); 00101 free_lbuf(key); 00102 mudstate.lock_nest_lev--; 00103 return (c); 00104 case BOOLEXP_CONST: 00105 return (b->thing == player || member(b->thing, Contents(player))); 00106 case BOOLEXP_ATR: 00107 a = atr_num(b->thing); 00108 if(!a) 00109 return 0; /* 00110 * no such attribute 00111 */ 00112 00113 /* 00114 * First check the object itself, then its contents 00115 */ 00116 00117 if(check_attr(player, from, a, (char *) b->sub1)) 00118 return 1; 00119 DOLIST(obj, Contents(player)) { 00120 if(check_attr(obj, from, a, (char *) b->sub1)) 00121 return 1; 00122 } 00123 return 0; 00124 case BOOLEXP_EVAL: 00125 a = atr_num(b->thing); 00126 if(!a) 00127 return 0; /* 00128 * no such attribute 00129 */ 00130 source = from; 00131 buff = atr_pget(from, a->number, &aowner, &aflags); 00132 if(!buff || !*buff) { 00133 free_lbuf(buff); 00134 buff = atr_pget(thing, a->number, &aowner, &aflags); 00135 source = thing; 00136 } 00137 checkit = 0; 00138 00139 if((a->number == A_NAME) || (a->number == A_LENTER)) { 00140 checkit = 1; 00141 } else if(Read_attr(source, source, a, aowner, aflags)) { 00142 checkit = 1; 00143 } 00144 if(checkit) { 00145 buff2 = bp = alloc_lbuf("eval_boolexp"); 00146 str = buff; 00147 exec(buff2, &bp, 0, source, player, 00148 EV_FIGNORE | EV_EVAL | EV_TOP, &str, (char **) NULL, 0); 00149 *bp = '\0'; 00150 checkit = !string_compare(buff2, (char *) b->sub1); 00151 free_lbuf(buff2); 00152 } 00153 free_lbuf(buff); 00154 return checkit; 00155 case BOOLEXP_IS: 00156 00157 /* 00158 * If an object check, do that 00159 */ 00160 00161 if(b->sub1->type == BOOLEXP_CONST) 00162 return (b->sub1->thing == player); 00163 00164 /* 00165 * Nope, do an attribute check 00166 */ 00167 00168 a = atr_num(b->sub1->thing); 00169 if(!a) 00170 return 0; 00171 return (check_attr(player, from, a, (char *) (b->sub1)->sub1)); 00172 case BOOLEXP_CARRY: 00173 00174 /* 00175 * If an object check, do that 00176 */ 00177 00178 if(b->sub1->type == BOOLEXP_CONST) 00179 return (member(b->sub1->thing, Contents(player))); 00180 00181 /* 00182 * Nope, do an attribute check 00183 */ 00184 00185 a = atr_num(b->sub1->thing); 00186 if(!a) 00187 return 0; 00188 DOLIST(obj, Contents(player)) { 00189 if(check_attr(obj, from, a, (char *) (b->sub1)->sub1)) 00190 return 1; 00191 } 00192 return 0; 00193 case BOOLEXP_OWNER: 00194 return (Owner(b->sub1->thing) == Owner(player)); 00195 default: 00196 abort(); /* 00197 * bad type 00198 */ 00199 return 0; 00200 } 00201 } /* end eval_boolexp() */
Definition at line 203 of file boolexp.c.
References eval_boolexp(), free_boolexp(), and parse_boolexp().
Referenced by could_doit(), and eval_boolexp().
00204 { 00205 BOOLEXP *b; 00206 int ret_value; 00207 00208 b = parse_boolexp(player, key, 1); 00209 if(b == NULL) { 00210 ret_value = 1; 00211 } else { 00212 ret_value = eval_boolexp(player, thing, from, b); 00213 free_boolexp(b); 00214 } 00215 return (ret_value); 00216 } /* end eval_boolexp_atr() */
Definition at line 552 of file boolexp.c.
References parse_boolexp_E(), parse_player, parsebuf, parsestore, parsing_internal, StringCopy, and TRUE_BOOLEXP.
Referenced by db_write_object(), debug_examine(), do_decomp(), do_examine(), do_lock(), eval_boolexp_atr(), fun_colorpairs(), fun_elock(), fun_eval(), fun_get(), fun_get_eval(), fun_lock(), fun_pairs(), fun_setlock(), fun_xget(), and view_atr().
00553 { 00554 StringCopy(parsestore, buf); 00555 parsebuf = parsestore; 00556 parse_player = player; 00557 if((buf == NULL) || (*buf == '\0')) 00558 return (TRUE_BOOLEXP); 00559 parsing_internal = internal; 00560 return parse_boolexp_E(); 00561 } /* end parse_boolexp() */
static BOOLEXP * parse_boolexp_E | ( | void | ) | [static] |
Definition at line 530 of file boolexp.c.
References alloc_bool, BOOLEXP_OR, free_boolexp(), OR_TOKEN, parse_boolexp_T(), parsebuf, skip_whitespace(), boolexp::sub1, boolexp::sub2, TRUE_BOOLEXP, and boolexp::type.
Referenced by parse_boolexp(), and parse_boolexp_L().
00531 { 00532 BOOLEXP *b, *b2; 00533 00534 if((b = parse_boolexp_T()) != TRUE_BOOLEXP) { 00535 skip_whitespace(); 00536 if(*parsebuf == OR_TOKEN) { 00537 parsebuf++; 00538 00539 b2 = alloc_bool("parse_boolexp_E"); 00540 b2->type = BOOLEXP_OR; 00541 b2->sub1 = b; 00542 if((b2->sub2 = parse_boolexp_E()) == TRUE_BOOLEXP) { 00543 free_boolexp(b2); 00544 return TRUE_BOOLEXP; 00545 } 00546 b = b2; 00547 } 00548 } 00549 return b; 00550 } /* parse_boolexp_E */
static BOOLEXP* parse_boolexp_F | ( | void | ) | [static] |
Definition at line 407 of file boolexp.c.
References alloc_bool, BOOLEXP_ATR, BOOLEXP_CARRY, BOOLEXP_CONST, BOOLEXP_INDIR, BOOLEXP_IS, BOOLEXP_NOT, BOOLEXP_OWNER, CARRY_TOKEN, free_boolexp(), INDIR_TOKEN, IS_TOKEN, NOT_TOKEN, OWNER_TOKEN, parse_boolexp_L(), parsebuf, skip_whitespace(), boolexp::sub1, TRUE_BOOLEXP, and boolexp::type.
Referenced by parse_boolexp_T().
00408 { 00409 BOOLEXP *b2; 00410 00411 skip_whitespace(); 00412 switch (*parsebuf) { 00413 case NOT_TOKEN: 00414 parsebuf++; 00415 b2 = alloc_bool("parse_boolexp_F.not"); 00416 b2->type = BOOLEXP_NOT; 00417 if((b2->sub1 = parse_boolexp_F()) == TRUE_BOOLEXP) { 00418 free_boolexp(b2); 00419 return (TRUE_BOOLEXP); 00420 } else 00421 return (b2); 00422 /* 00423 * NOTREACHED 00424 */ 00425 break; 00426 case INDIR_TOKEN: 00427 parsebuf++; 00428 b2 = alloc_bool("parse_boolexp_F.indir"); 00429 b2->type = BOOLEXP_INDIR; 00430 b2->sub1 = parse_boolexp_L(); 00431 if((b2->sub1) == TRUE_BOOLEXP) { 00432 free_boolexp(b2); 00433 return (TRUE_BOOLEXP); 00434 } else if((b2->sub1->type) != BOOLEXP_CONST) { 00435 free_boolexp(b2); 00436 return (TRUE_BOOLEXP); 00437 } else 00438 return (b2); 00439 /* 00440 * NOTREACHED 00441 */ 00442 break; 00443 case IS_TOKEN: 00444 parsebuf++; 00445 b2 = alloc_bool("parse_boolexp_F.is"); 00446 b2->type = BOOLEXP_IS; 00447 b2->sub1 = parse_boolexp_L(); 00448 if((b2->sub1) == TRUE_BOOLEXP) { 00449 free_boolexp(b2); 00450 return (TRUE_BOOLEXP); 00451 } else if(((b2->sub1->type) != BOOLEXP_CONST) && 00452 ((b2->sub1->type) != BOOLEXP_ATR)) { 00453 free_boolexp(b2); 00454 return (TRUE_BOOLEXP); 00455 } else 00456 return (b2); 00457 /* 00458 * NOTREACHED 00459 */ 00460 break; 00461 case CARRY_TOKEN: 00462 parsebuf++; 00463 b2 = alloc_bool("parse_boolexp_F.carry"); 00464 b2->type = BOOLEXP_CARRY; 00465 b2->sub1 = parse_boolexp_L(); 00466 if((b2->sub1) == TRUE_BOOLEXP) { 00467 free_boolexp(b2); 00468 return (TRUE_BOOLEXP); 00469 } else if(((b2->sub1->type) != BOOLEXP_CONST) && 00470 ((b2->sub1->type) != BOOLEXP_ATR)) { 00471 free_boolexp(b2); 00472 return (TRUE_BOOLEXP); 00473 } else 00474 return (b2); 00475 /* 00476 * NOTREACHED 00477 */ 00478 break; 00479 case OWNER_TOKEN: 00480 parsebuf++; 00481 b2 = alloc_bool("parse_boolexp_F.owner"); 00482 b2->type = BOOLEXP_OWNER; 00483 b2->sub1 = parse_boolexp_L(); 00484 if((b2->sub1) == TRUE_BOOLEXP) { 00485 free_boolexp(b2); 00486 return (TRUE_BOOLEXP); 00487 } else if((b2->sub1->type) != BOOLEXP_CONST) { 00488 free_boolexp(b2); 00489 return (TRUE_BOOLEXP); 00490 } else 00491 return (b2); 00492 /* 00493 * NOTREACHED 00494 */ 00495 break; 00496 default: 00497 return (parse_boolexp_L()); 00498 } 00499 } /* end parse_boolexp_F() */
static BOOLEXP* parse_boolexp_L | ( | void | ) | [static] |
Definition at line 299 of file boolexp.c.
References alloc_bool, alloc_lbuf, AMBIGUOUS, AND_TOKEN, BOOLEXP_CONST, free_bool, free_boolexp(), free_lbuf, Good_obj, init_match(), MAT_EXIT_PARENTS, match_everything(), match_result(), NOTHING, notify_printf(), OR_TOKEN, parse_boolexp_E(), parse_player, parsebuf, parsing_internal, restore_match_state(), save_match_state(), skip_whitespace(), test_atr(), boolexp::thing, TRUE_BOOLEXP, boolexp::type, and TYPE_THING.
Referenced by parse_boolexp_F().
00300 { 00301 BOOLEXP *b; 00302 char *p, *buf; 00303 MSTATE mstate; 00304 00305 buf = NULL; 00306 skip_whitespace(); 00307 00308 switch (*parsebuf) { 00309 case '(': 00310 parsebuf++; 00311 b = parse_boolexp_E(); 00312 skip_whitespace(); 00313 if(b == TRUE_BOOLEXP || *parsebuf++ != ')') { 00314 free_boolexp(b); 00315 return TRUE_BOOLEXP; 00316 } 00317 break; 00318 default: 00319 00320 /* 00321 * Must have hit an object ref. Load the name into our 00322 * buffer 00323 */ 00324 00325 buf = alloc_lbuf("parse_boolexp_L"); 00326 p = buf; 00327 while (*parsebuf && (*parsebuf != AND_TOKEN) && 00328 (*parsebuf != OR_TOKEN) && (*parsebuf != ')')) { 00329 *p++ = *parsebuf++; 00330 } 00331 00332 /* 00333 * strip trailing whitespace 00334 */ 00335 00336 *p-- = '\0'; 00337 while (isspace(*p)) 00338 *p-- = '\0'; 00339 00340 /* 00341 * check for an attribute 00342 */ 00343 00344 if((b = test_atr(buf)) != NULL) { 00345 free_lbuf(buf); 00346 return (b); 00347 } 00348 b = alloc_bool("parse_boolexp_L"); 00349 b->type = BOOLEXP_CONST; 00350 00351 /* 00352 * do the match 00353 */ 00354 00355 /* 00356 * If we are parsing a boolexp that was a stored lock then 00357 * we know that object refs are all dbrefs, so we 00358 * skip the expensive match code. 00359 */ 00360 00361 if(parsing_internal) { 00362 if(buf[0] != '#') { 00363 free_lbuf(buf); 00364 free_bool(b); 00365 return TRUE_BOOLEXP; 00366 } 00367 b->thing = atoi(&buf[1]); 00368 if(!Good_obj(b->thing)) { 00369 free_lbuf(buf); 00370 free_bool(b); 00371 return TRUE_BOOLEXP; 00372 } 00373 } else { 00374 save_match_state(&mstate); 00375 init_match(parse_player, buf, TYPE_THING); 00376 match_everything(MAT_EXIT_PARENTS); 00377 b->thing = match_result(); 00378 restore_match_state(&mstate); 00379 } 00380 00381 if(b->thing == NOTHING) { 00382 notify_printf(parse_player, "I don't see %s here.", buf); 00383 free_lbuf(buf); 00384 free_bool(b); 00385 return TRUE_BOOLEXP; 00386 } 00387 if(b->thing == AMBIGUOUS) { 00388 notify_printf(parse_player, "I don't know which %s you mean!", 00389 buf); 00390 free_lbuf(buf); 00391 free_bool(b); 00392 return TRUE_BOOLEXP; 00393 } 00394 free_lbuf(buf); 00395 } 00396 return b; 00397 } /* end parse_boolexp_L() */
static BOOLEXP* parse_boolexp_T | ( | void | ) | [static] |
Definition at line 505 of file boolexp.c.
References alloc_bool, AND_TOKEN, BOOLEXP_AND, free_boolexp(), parse_boolexp_F(), parsebuf, skip_whitespace(), boolexp::sub1, boolexp::sub2, TRUE_BOOLEXP, and boolexp::type.
Referenced by parse_boolexp_E().
00506 { 00507 BOOLEXP *b, *b2; 00508 00509 if((b = parse_boolexp_F()) != TRUE_BOOLEXP) { 00510 skip_whitespace(); 00511 if(*parsebuf == AND_TOKEN) { 00512 parsebuf++; 00513 00514 b2 = alloc_bool("parse_boolexp_T"); 00515 b2->type = BOOLEXP_AND; 00516 b2->sub1 = b; 00517 if((b2->sub2 = parse_boolexp_T()) == TRUE_BOOLEXP) { 00518 free_boolexp(b2); 00519 return TRUE_BOOLEXP; 00520 } 00521 b = b2; 00522 } 00523 } 00524 return b; 00525 } /* end parse_boolexp_T() */
static void skip_whitespace | ( | void | ) | [static] |
Definition at line 230 of file boolexp.c.
References parsebuf.
Referenced by parse_boolexp_E(), parse_boolexp_F(), parse_boolexp_L(), and parse_boolexp_T().
static BOOLEXP* test_atr | ( | char * | s | ) | [static] |
Definition at line 238 of file boolexp.c.
References alloc_bool, alloc_lbuf, atr_str(), BOOLEXP_ATR, BOOLEXP_EVAL, free_lbuf, God, attr::number, parse_player, StringCopy, strsave(), boolexp::sub1, boolexp::thing, and boolexp::type.
Referenced by parse_boolexp_L().
00239 { 00240 ATTR *attrib; 00241 BOOLEXP *b; 00242 char *buff, *s1; 00243 int anum, locktype; 00244 00245 buff = alloc_lbuf("test_atr"); 00246 StringCopy(buff, s); 00247 for(s = buff; *s && (*s != ':') && (*s != '/'); s++); 00248 if(!*s) { 00249 free_lbuf(buff); 00250 return ((BOOLEXP *) NULL); 00251 } 00252 if(*s == '/') 00253 locktype = BOOLEXP_EVAL; 00254 else 00255 locktype = BOOLEXP_ATR; 00256 00257 *s++ = '\0'; 00258 /* 00259 * see if left side is valid attribute. Access to attr is checked on 00260 * 00261 * * * * * * * * * * eval * Also allow numeric references to * 00262 * attributes. * It * can't * hurt * us, and * lets us import stuff 00263 * * that stores * attr * locks by * number * instead of by * name. 00264 */ 00265 if(!(attrib = atr_str(buff))) { 00266 00267 /* 00268 * Only #1 can lock on numbers 00269 */ 00270 if(!God(parse_player)) { 00271 free_lbuf(buff); 00272 return ((BOOLEXP *) NULL); 00273 } 00274 s1 = buff; 00275 for(s1 = buff; isdigit(*s1); s1++); 00276 if(*s1) { 00277 free_lbuf(buff); 00278 return ((BOOLEXP *) NULL); 00279 } 00280 anum = atoi(buff); 00281 } else { 00282 anum = attrib->number; 00283 } 00284 00285 /* 00286 * made it now make the parse tree node 00287 */ 00288 b = alloc_bool("test_str"); 00289 b->type = locktype; 00290 b->thing = (dbref) anum; 00291 b->sub1 = (BOOLEXP *) strsave(s); 00292 free_lbuf(buff); 00293 return (b); 00294 } /* end test_atr() */
dbref parse_player [static] |
Definition at line 228 of file boolexp.c.
Referenced by parse_boolexp(), parse_boolexp_L(), and test_atr().
const char* parsebuf [static] |
Definition at line 226 of file boolexp.c.
Referenced by parse_boolexp(), parse_boolexp_E(), parse_boolexp_F(), parse_boolexp_L(), parse_boolexp_T(), and skip_whitespace().
char parsestore[LBUF_SIZE] [static] |
int parsing_internal = 0 [static] |