static void debug_printvar(dbref player, struct frame *fr, const char *arg) { int i; int lflag = 0; if (!arg || !*arg) { anotify_nolisten(player, CINFO "I don't know which variable you mean.", 1); return; } if (*arg == 'L' || *arg == 'l') arg++, lflag = 1; if (*arg == 'V' || *arg == 'v') arg++; if (!number(arg)) { anotify_nolisten(player, CINFO "I don't know which variable you mean.", 1); return; } i = atoi(arg); if (i >= MAX_VAR || i < 0) { anotify_nolisten(player, CINFO "Variable number out of range.", 1); return; } if (lflag) { notify_nolisten(player, insttotext(&(CurrVar[i]), 4000, -1), 1); } else { notify_nolisten(player, insttotext(&(fr->variables[i]), 4000, -1), 1); } }
void muf_backtrace(dbref player, dbref program, int count, struct frame *fr) { char buf[BUFFER_LEN]; char *ptr; dbref ref; int i, j, cnt, flag; struct inst *pinst, *lastinst; anotify_nolisten(player, CINFO "System stack backtrace:", 1); i = count; if (!i) i = STACK_SIZE; ref = program; pinst = NULL; j = fr->system.top+1; while (j>1 && i-->0) { cnt = 0; do { lastinst = pinst; if (--j == fr->system.top) { pinst = fr->pc+1; } else { ref = fr->system.st[j].progref; pinst = fr->system.st[j].offset; } ptr = unparse_sysreturn(&ref, pinst); cnt++; } while (pinst == lastinst && j>1); if (cnt > 1) { sprintf(buf, " [repeats %d times]", cnt); notify_nolisten(player, buf, 1); } if (pinst != lastinst) { sprintf(buf, "%3d) %s(#%d) %s:", j, NAME(ref), ref, ptr); notify_nolisten(player, buf, 1); flag = ((FLAGS(player) & INTERNAL)? 1 : 0); FLAGS(player) &= ~INTERNAL; list_proglines(player, ref, fr, (pinst-1)->line, 0); if (flag) { FLAGS(player) |= INTERNAL; } } } anotify_nolisten(player, CINFO "Done.", 1); }
void list_program_functions(dbref player, dbref program, char *arg) { struct inst *ptr; int count; ptr = DBFETCH(program)->sp.program.code; count = DBFETCH(program)->sp.program.siz; anotify_nolisten(player, CINFO "*function words*", 1); while (count-- > 0) { if (ptr->type == PROG_FUNCTION) { if (ptr->data.string) { if (!*arg || equalstr(arg, ptr->data.string->data)) { notify_nolisten(player, ptr->data.string->data, 1); } } } ptr++; } anotify_nolisten(player, CINFO "Done.", 1); }
int ansi_notify_listeners(int descr, dbref who, dbref xprog, dbref obj, dbref room, const char *msg, int isprivate) { char buf[BUFFER_LEN], buf2[BUFFER_LEN], *noabuf; dbref ref; if (obj == NOTHING) return 0; noabuf = unparse_ansi(buf2, msg); if (tp_listeners && (tp_listeners_obj || Typeof(obj) == TYPE_ROOM)) { listenqueue(descr, who, room, obj, obj, xprog, "_listen", noabuf, tp_listen_mlev, 1, 0); listenqueue(descr, who, room, obj, obj, xprog, "_olisten", noabuf, tp_listen_mlev, 0, 0); listenqueue(descr, who, room, obj, obj, xprog, "~listen", noabuf, tp_listen_mlev, 1, 1); listenqueue(descr, who, room, obj, obj, xprog, "~olisten", noabuf, tp_listen_mlev, 0, 1); listenqueue(descr, who, room, obj, obj, xprog, "@listen", noabuf, tp_listen_mlev, 1, 1); listenqueue(descr, who, room, obj, obj, xprog, "@olisten", noabuf, tp_listen_mlev, 0, 1); listenqueue(descr, who, room, obj, obj, xprog, "_alisten", msg, tp_listen_mlev, 1, 0); listenqueue(descr, who, room, obj, obj, xprog, "_aolisten", msg, tp_listen_mlev, 0, 0); listenqueue(descr, who, room, obj, obj, xprog, "~alisten", msg, tp_listen_mlev, 1, 1); listenqueue(descr, who, room, obj, obj, xprog, "~aolisten", msg, tp_listen_mlev, 0, 1); listenqueue(descr, who, room, obj, obj, xprog, "@alisten", msg, tp_listen_mlev, 1, 1); listenqueue(descr, who, room, obj, obj, xprog, "@aolisten", msg, tp_listen_mlev, 0, 1); /* Loop up the environment only if tp_listeners_env is set and obj * is a room. Runs once otherwise. -brevantes */ if (tp_listeners_env && (Typeof(obj) == TYPE_ROOM) ) { obj = DBFETCH(obj)->location; for (;obj != NOTHING;obj = DBFETCH(obj)->location) { listenqueue(descr, who, room, obj, obj, xprog, "_listen", noabuf, tp_listen_mlev, 1, 0); listenqueue(descr, who, room, obj, obj, xprog, "_olisten", noabuf, tp_listen_mlev, 0, 0); listenqueue(descr, who, room, obj, obj, xprog, "~listen", noabuf, tp_listen_mlev, 1, 1); listenqueue(descr, who, room, obj, obj, xprog, "~olisten", noabuf, tp_listen_mlev, 0, 1); listenqueue(descr, who, room, obj, obj, xprog, "@listen", noabuf, tp_listen_mlev, 1, 1); listenqueue(descr, who, room, obj, obj, xprog, "@olisten", noabuf, tp_listen_mlev, 0, 1); listenqueue(descr, who, room, obj, obj, xprog, "_alisten", msg, tp_listen_mlev, 1, 0); listenqueue(descr, who, room, obj, obj, xprog, "_aolisten", msg, tp_listen_mlev, 0, 0); listenqueue(descr, who, room, obj, obj, xprog, "~alisten", msg, tp_listen_mlev, 1, 1); listenqueue(descr, who, room, obj, obj, xprog, "~aolisten", msg, tp_listen_mlev, 0, 1); listenqueue(descr, who, room, obj, obj, xprog, "@alisten", msg, tp_listen_mlev, 1, 1); listenqueue(descr, who, room, obj, obj, xprog, "@aolisten", msg, tp_listen_mlev, 0, 1); } return 0; } } if (tp_zombies && (Typeof(obj) == TYPE_THING) && !isprivate && !(FLAGS(obj) & QUELL)) { if (FLAGS(obj) & VEHICLE) { if (getloc(who) == getloc(obj)) { char pbuf[BUFFER_LEN]; const char *prefix; prefix = GETOECHO(obj); if (prefix && *prefix) { prefix = do_parse_mesg(-1, who, obj, prefix, "(@Oecho)", pbuf, MPI_ISPRIVATE); } if (!prefix || !*prefix) prefix = "Outside>"; sprintf(buf, "%s %.*s", prefix, (int) (BUFFER_LEN - 2 - strlen(prefix)), msg); ref = DBFETCH(obj)->contents; while (ref != NOTHING) { #ifdef IGNORE_SUPPORT if (!ignorance(who, ref)) #endif /* IGNORE_SUPPORT */ anotify_nolisten(ref, msg, isprivate); ref = DBFETCH(ref)->next; } } } } if (Typeof(obj) == TYPE_PLAYER || Typeof(obj) == TYPE_THING) { #ifdef IGNORE_SUPPORT if (ignorance(who, obj)) return 0; #endif /* IGNORE_SUPPORT */ if ( !isprivate && Typeof(obj) == TYPE_THING && FLAGS(obj) & ZOMBIE && LOCATION(obj) == LOCATION(OWNER(obj)) ) return 0; return anotify_nolisten(obj, msg, isprivate); } else { return 0; } }
int muf_debugger(dbref player, dbref program, const char *text, struct frame *fr) { char cmd[BUFFER_LEN]; char buf[BUFFER_LEN]; char *ptr, *ptr2, *arg; struct inst *pinst; int i, j, cnt; while (isspace(*text)) text++; strcpy(cmd, text); ptr = cmd + strlen(cmd); if (ptr > cmd) ptr--; while (ptr >= cmd && isspace(*ptr)) *ptr-- = '\0'; for (arg = cmd; *arg && !isspace(*arg); arg++); if (*arg) *arg++ = '\0'; if (!*cmd && fr->brkpt.lastcmd) { strcpy(cmd, fr->brkpt.lastcmd); } else { if (fr->brkpt.lastcmd) free(fr->brkpt.lastcmd); if (*cmd) fr->brkpt.lastcmd = string_dup(cmd); } /* delete triggering breakpoint, if it's only temp. */ j = fr->brkpt.breaknum; if (j >= 0 && fr->brkpt.temp[j]) { for (j++; j < fr->brkpt.count; j++) { fr->brkpt.temp[j-1] = fr->brkpt.temp[j]; fr->brkpt.level[j-1] = fr->brkpt.level[j]; fr->brkpt.line[j-1] = fr->brkpt.line[j]; fr->brkpt.linecount[j-1] = fr->brkpt.linecount[j]; fr->brkpt.pc[j-1] = fr->brkpt.pc[j]; fr->brkpt.pccount[j-1] = fr->brkpt.pccount[j]; fr->brkpt.prog[j-1] = fr->brkpt.prog[j]; } fr->brkpt.count--; } fr->brkpt.breaknum = -1; if (!string_compare(cmd, "cont")) { } else if (!string_compare(cmd, "finish")) { if (fr->brkpt.count >= MAX_BREAKS) { anotify_nolisten(player, CFAIL "Cannot finish because there are too many breakpoints set.", 1); add_muf_read_event(player, program, fr); return 0; } j = fr->brkpt.count++; fr->brkpt.temp[j] = 1; fr->brkpt.level[j] = fr->system.top - 1; fr->brkpt.line[j] = -1; fr->brkpt.linecount[j] = -2; fr->brkpt.pc[j] = NULL; fr->brkpt.pccount[j] = -2; fr->brkpt.prog[j] = program; fr->brkpt.bypass = 1; return 0; } else if (!string_compare(cmd, "stepi")) { i = atoi(arg); if (!i) i = 1; if (fr->brkpt.count >= MAX_BREAKS) { anotify_nolisten(player, CFAIL "Cannot stepi because there are too many breakpoints set.", 1); add_muf_read_event(player, program, fr); return 0; } j = fr->brkpt.count++; fr->brkpt.temp[j] = 1; fr->brkpt.level[j] = -1; fr->brkpt.line[j] = -1; fr->brkpt.linecount[j] = -2; fr->brkpt.pc[j] = NULL; fr->brkpt.pccount[j] = i; fr->brkpt.prog[j] = NOTHING; fr->brkpt.bypass = 1; return 0; } else if (!string_compare(cmd, "step")) { i = atoi(arg); if (!i) i = 1; if (fr->brkpt.count >= MAX_BREAKS) { anotify_nolisten(player, CFAIL "Cannot step because there are too many breakpoints set.", 1); add_muf_read_event(player, program, fr); return 0; } j = fr->brkpt.count++; fr->brkpt.temp[j] = 1; fr->brkpt.level[j] = -1; fr->brkpt.line[j] = -1; fr->brkpt.linecount[j] = i; fr->brkpt.pc[j] = NULL; fr->brkpt.pccount[j] = -2; fr->brkpt.prog[j] = NOTHING; fr->brkpt.bypass = 1; return 0; } else if (!string_compare(cmd, "nexti")) { i = atoi(arg); if (!i) i = 1; if (fr->brkpt.count >= MAX_BREAKS) { anotify_nolisten(player, CFAIL "Cannot nexti because there are too many breakpoints set.", 1); add_muf_read_event(player, program, fr); return 0; } j = fr->brkpt.count++; fr->brkpt.temp[j] = 1; fr->brkpt.level[j] = fr->system.top; fr->brkpt.line[j] = -1; fr->brkpt.linecount[j] = -2; fr->brkpt.pc[j] = NULL; fr->brkpt.pccount[j] = i; fr->brkpt.prog[j] = program; fr->brkpt.bypass = 1; return 0; } else if (!string_compare(cmd, "next")) { i = atoi(arg); if (!i) i = 1; if (fr->brkpt.count >= MAX_BREAKS) { anotify_nolisten(player, CFAIL "Cannot next because there are too many breakpoints set.", 1); add_muf_read_event(player, program, fr); return 0; } j = fr->brkpt.count++; fr->brkpt.temp[j] = 1; fr->brkpt.level[j] = fr->system.top; fr->brkpt.line[j] = -1; fr->brkpt.linecount[j] = i; fr->brkpt.pc[j] = NULL; fr->brkpt.pccount[j] = -2; fr->brkpt.prog[j] = program; fr->brkpt.bypass = 1; return 0; } else if (!string_compare(cmd, "exec")) { if (fr->brkpt.count >= MAX_BREAKS) { anotify_nolisten(player, CFAIL "Cannot finish because there are too many breakpoints set.", 1); add_muf_read_event(player, program, fr); return 0; } if (!(pinst = funcname_to_pc(program, arg))) { anotify_nolisten(player, CINFO "I don't know a function by that name.", 1); add_muf_read_event(player, program, fr); return 0; } if (fr->system.top >= STACK_SIZE) { anotify_nolisten(player, CFAIL "That would exceed the system stack size for this program.", 1); add_muf_read_event(player, program, fr); return 0; } fr->system.st[fr->system.top].progref = program; fr->system.st[fr->system.top++].offset = fr->pc; fr->pc = pinst; j = fr->brkpt.count++; fr->brkpt.temp[j] = 1; fr->brkpt.level[j] = fr->system.top - 1; fr->brkpt.line[j] = -1; fr->brkpt.linecount[j] = -2; fr->brkpt.pc[j] = NULL; fr->brkpt.pccount[j] = -2; fr->brkpt.prog[j] = program; fr->brkpt.bypass = 1; return 0; } else if (!string_compare(cmd, "prim")) { if (fr->brkpt.count >= MAX_BREAKS) { anotify_nolisten(player, CFAIL "Cannot finish because there are too many breakpoints set.", 1); add_muf_read_event(player, program, fr); return 0; } if (!(i = primitive(arg))) { anotify_nolisten(player, CINFO "I don't recognize that primitive.", 1); add_muf_read_event(player, program, fr); return 0; } if (fr->system.top >= STACK_SIZE) { anotify_nolisten(player, CFAIL "That would exceed the system stack size for this program.", 1); add_muf_read_event(player, program, fr); return 0; } shstr.data[0] = '\0'; shstr.links = 1; shstr.length= strlen(shstr.data); primset[0].type = PROG_FUNCTION; primset[0].line = 0; primset[0].data.string = &shstr; primset[1].type = PROG_PRIMITIVE; primset[1].line = 0; primset[1].data.number = i; primset[2].type = PROG_PRIMITIVE; primset[2].line = 0; primset[2].data.number = primitive("EXIT"); fr->system.st[fr->system.top].progref = program; fr->system.st[fr->system.top++].offset = fr->pc; fr->pc = primset; j = fr->brkpt.count++; fr->brkpt.temp[j] = 1; fr->brkpt.level[j] = fr->system.top - 1; fr->brkpt.line[j] = -1; fr->brkpt.linecount[j] = -2; fr->brkpt.pc[j] = NULL; fr->brkpt.pccount[j] = -2; fr->brkpt.prog[j] = program; fr->brkpt.bypass = 1; return 0; } else if (!string_compare(cmd, "break")) { add_muf_read_event(player, program, fr); if (fr->brkpt.count >= MAX_BREAKS) { anotify_nolisten(player, CFAIL "Too many breakpoints set.", 1); return 0; } if (number(arg)) { i = atoi(arg); } else { if (!(pinst = funcname_to_pc(program, arg))) { anotify_nolisten(player, CINFO "I don't know a function by that name.", 1); return 0; } else { i = pinst->line; } } if (!i) i = fr->pc->line; j = fr->brkpt.count++; fr->brkpt.temp[j] = 0; fr->brkpt.level[j] = -1; fr->brkpt.line[j] = i; fr->brkpt.linecount[j] = -2; fr->brkpt.pc[j] = NULL; fr->brkpt.pccount[j] = -2; fr->brkpt.prog[j] = program; anotify_nolisten(player, CSUCC "Breakpoint set.", 1); return 0; } else if (!string_compare(cmd, "delete")) { add_muf_read_event(player, program, fr); i = atoi(arg); if (!i) { anotify_nolisten(player, CINFO "Which breakpoint did you want to delete?", 1); return 0; } if (i < 1 || i > fr->brkpt.count) { anotify_nolisten(player, CFAIL "No such breakpoint.", 1); return 0; } j = i - 1; for (j++; j < fr->brkpt.count; j++) { fr->brkpt.temp[j-1] = fr->brkpt.temp[j]; fr->brkpt.level[j-1] = fr->brkpt.level[j]; fr->brkpt.line[j-1] = fr->brkpt.line[j]; fr->brkpt.linecount[j-1] = fr->brkpt.linecount[j]; fr->brkpt.pc[j-1] = fr->brkpt.pc[j]; fr->brkpt.pccount[j-1] = fr->brkpt.pccount[j]; fr->brkpt.prog[j-1] = fr->brkpt.prog[j]; } fr->brkpt.count--; anotify_nolisten(player, CSUCC "Breakpoint deleted.", 1); return 0; } else if (!string_compare(cmd, "breaks")) { anotify_nolisten(player, CINFO "Breakpoints:", 1); for (i = 0; i < fr->brkpt.count; i++) { ptr = unparse_breakpoint(fr, i); notify_nolisten(player, ptr, 1); } anotify_nolisten(player, CINFO "Done.", 1); add_muf_read_event(player, program, fr); return 0; } else if (!string_compare(cmd, "where")) { i = atoi(arg); muf_backtrace(player, program, i, fr); add_muf_read_event(player, program, fr); return 0; } else if (!string_compare(cmd, "stack")) { anotify_nolisten(player, CINFO "*Argument stack top*", 1); i = atoi(arg); if (!i) i = STACK_SIZE; ptr = ""; for (j = fr->argument.top; j>0 && i-->0;) { cnt = 0; do { strcpy(buf, ptr); ptr = insttotext(&fr->argument.st[--j], 4000, program); cnt++; } while (!string_compare(ptr, buf) && j>0); if (cnt > 1) notify_fmt(player, " [repeats %d times]", cnt); if (string_compare(ptr, buf)) notify_fmt(player, "%3d) %s", j+1, ptr); } anotify_nolisten(player, CINFO "Done.", 1); add_muf_read_event(player, program, fr); return 0; } else if (!string_compare(cmd, "list") || !string_compare(cmd, "listi")) { int startline, endline; startline = endline = 0; add_muf_read_event(player, program, fr); if ((ptr2 = (char *)index(arg, ','))) { *ptr2++ = '\0'; } else { ptr2 = ""; } if (!*arg) { if (fr->brkpt.lastlisted) { startline = fr->brkpt.lastlisted + 1; } else { startline = fr->pc->line; } endline = startline + 15; } else { if (!number(arg)) { if (!(pinst = funcname_to_pc(program, arg))) { anotify_nolisten(player, CINFO "I don't know a function by that name. (starting arg, 1)", 1); return 0; } else { startline = pinst->line; endline = startline + 15; } } else { if (*ptr2) { endline = startline = atoi(arg); } else { startline = atoi(arg) - 7; endline = startline + 15; } } } if (*ptr2) { if (!number(ptr2)) { if (!(pinst = funcname_to_pc(program, ptr2))) { anotify_nolisten(player, CINFO "I don't know a function by that name. (ending arg, 1)", 1); return 0; } else { endline = pinst->line; } } else { endline = atoi(ptr2); } } i = (DBFETCH(program)->sp.program.code + DBFETCH(program)->sp.program.siz - 1)->line; if (startline > i) { anotify_nolisten(player, CFAIL "Starting line is beyond end of program.", 1); return 0; } if (startline < 1) startline = 1; if (endline > i) endline = i; if (endline < startline) endline = startline; anotify_nolisten(player, CINFO "Listing:", 1); if (!string_compare(cmd, "listi")) { for (i = startline; i <= endline; i++) { pinst = linenum_to_pc(program, i); if (pinst) { sprintf(buf, "line %d: %s", i, (i == fr->pc->line) ? show_line_prims(program, fr->pc, STACK_SIZE, 1) : show_line_prims(program, pinst, STACK_SIZE, 0)); notify_nolisten(player, buf, 1); } } } else { list_proglines(player, program, fr, startline, endline); } fr->brkpt.lastlisted = endline; anotify_nolisten(player, CINFO "Done.", 1); return 0; } else if (!string_compare(cmd, "quit")) { anotify_nolisten(player, CINFO "Halting execution.", 1); return 1; } else if (!string_compare(cmd, "trace")) { add_muf_read_event(player, program, fr); if (!string_compare(arg, "on")) { fr->brkpt.showstack = 1; anotify_nolisten(player, CSUCC "Trace turned on.", 1); } else if (!string_compare(arg, "off")) { fr->brkpt.showstack = 0; anotify_nolisten(player, CSUCC "Trace turned off.", 1); } else { sprintf(buf, CINFO "Trace is currently %s.", fr->brkpt.showstack? "on" : "off"); anotify_nolisten(player, buf, 1); } return 0; } else if (!string_compare(cmd, "words")) { list_program_functions(player, program, arg); add_muf_read_event(player, program, fr); return 0; } else if (!string_compare(cmd, "print")) { debug_printvar(player, fr, arg); add_muf_read_event(player, program, fr); return 0; } else if (!string_compare(cmd, "push")) { push_arg(player, fr, arg); add_muf_read_event(player, program, fr); return 0; } else if (!string_compare(cmd, "pop")) { add_muf_read_event(player, program, fr); if (fr->argument.top < 1) { anotify_nolisten(player, CFAIL "Nothing to pop.", 1); return 0; } fr->argument.top--; CLEAR(fr->argument.st + fr->argument.top); anotify_nolisten(player, CSUCC "Stack item popped.", 1); return 0; } else if (!string_compare(cmd, "help")) { notify_nolisten(player, "cont continues execution until a breakpoint is hit.", 1); notify_nolisten(player, "finish completes execution of current function.", 1); notify_nolisten(player, "step [NUM] executes one (or NUM, 1) lines of muf.", 1); notify_nolisten(player, "stepi [NUM] executes one (or NUM, 1) muf instructions.", 1); notify_nolisten(player, "next [NUM] like step, except skips CALL and EXECUTE.", 1); notify_nolisten(player, "nexti [NUM] like stepi, except skips CALL and EXECUTE.", 1); notify_nolisten(player, "break LINE# sets breakpoint at given LINE number.", 1); notify_nolisten(player, "break FUNCNAME sets breakpoint at start of given function.", 1); notify_nolisten(player, "breaks lists all currently set breakpoints.", 1); notify_nolisten(player, "delete NUM deletes breakpoint by NUM, as listed by 'breaks'", 1); notify_nolisten(player, "where [LEVS] displays function call backtrace of up to num levels deep.", 1); notify_nolisten(player, "stack [NUM] shows the top num items on the stack.", 1); notify_nolisten(player, "print v# displays the value of given global variable #.", 1); notify_nolisten(player, "print lv# displays the value of given local variable #.", 1); notify_nolisten(player, "trace [on|off] turns on/off debug stack tracing.", 1); notify_nolisten(player, "list [L1,[L2]] lists source code of given line range.", 1); notify_nolisten(player, "list FUNCNAME lists source code of given function.", 1); notify_nolisten(player, "listi [L1,[L2]] lists instructions in given line range.", 1); notify_nolisten(player, "listi FUNCNAME lists instructions in given function.", 1); notify_nolisten(player, "words lists all function word names in program.", 1); notify_nolisten(player, "words PATTERN lists all function word names that match PATTERN.", 1); notify_nolisten(player, "exec FUNCNAME calls given function with the current stack data.", 1); notify_nolisten(player, "prim PRIMITIVE executes given primitive with current stack data.", 1); notify_nolisten(player, "push DATA pushes an int, dbref, var, or string onto the stack.", 1); notify_nolisten(player, "pop pops top data item off the stack.", 1); notify_nolisten(player, "help displays this help screen.", 1); notify_nolisten(player, "quit stop execution here.", 1); add_muf_read_event(player, program, fr); return 0; } else { anotify_nolisten(player, CINFO "I don't understand that debugger command. Type 'help' for help.", 1); add_muf_read_event(player, program, fr); return 0; } return 0; }
static void push_arg(dbref player, struct frame *fr, const char *arg) { int num, lflag = 0; double nflt = 0.0; if (fr->argument.top >= STACK_SIZE) { anotify_nolisten(player, CFAIL "That would overflow the stack.", 1); return; } if (number(arg)) { /* push a number */ num = atoi(arg); push(fr->argument.st, &fr->argument.top, PROG_INTEGER, MIPSCAST &num); anotify_nolisten(player, CSUCC "Integer pushed.", 1); } else if (isfloat(arg)) { /* push a float */ nflt = atof(arg); push(fr->argument.st, &fr->argument.top, PROG_FLOAT, MIPSCAST &nflt); anotify_nolisten(player, CSUCC "Floating point number pushed.", 1); } else if (*arg == '#') { /* push a dbref */ if (!number(arg+1)) { anotify_nolisten(player, CINFO "I don't understand that dbref.", 1); return; } num = atoi(arg+1); push(fr->argument.st, &fr->argument.top, PROG_OBJECT, MIPSCAST &num); anotify_nolisten(player, CSUCC "Dbref pushed.", 1); } else if (*arg == 'L' || *arg == 'V' || *arg == 'l' || *arg == 'v') { if (*arg == 'L' || *arg == 'l') arg++, lflag = 1; if (*arg == 'V' || *arg == 'v') arg++; if (!number(arg)) { anotify_nolisten(player, CINFO "I don't understand which variable you mean.", 1); return; } num = atoi(arg); if (lflag) { push(fr->argument.st, &fr->argument.top, PROG_LVAR, MIPSCAST &num); anotify_nolisten(player, CSUCC "Local variable pushed.", 1); } else { push(fr->argument.st, &fr->argument.top, PROG_VAR, MIPSCAST &num); anotify_nolisten(player, CSUCC "Global variable pushed.", 1); } } else if (*arg == '"') { /* push a string */ char buf[BUFFER_LEN]; char *ptr; const char *ptr2; for (ptr = buf, ptr2 = arg+1; *ptr2; ptr2++) { if (*ptr2 == '\\') { if (!*(++ptr2)) break; *ptr++ = *ptr2; } else if (*ptr2 == '"') { break; } else { *ptr++ = *ptr2; } } *ptr = '\0'; push(fr->argument.st, &fr->argument.top, PROG_STRING, MIPSCAST alloc_prog_string(buf)); anotify_nolisten(player, CSUCC "String pushed.", 1); } else { anotify_nolisten(player, CINFO "I don't know that data type.", 1); } }
bool could_doit2(int descr, dbref player, dbref thing, char *prop, bool tryprog) { dbref source, dest, owner; if (Typeof(thing) == TYPE_EXIT) { if (DBFETCH(thing)->sp.exit.ndest == 0) { return 0; } owner = OWNER(thing); source = DBFETCH(player)->location; dest = *(DBFETCH(thing)->sp.exit.dest); if (dest == NIL) /* unless its locked, anyone can use #-4 */ return (eval_boolexp(descr, player, GETLOCK(thing), thing)); if (Typeof(dest) == TYPE_PLAYER) { dbref destplayer = dest; dest = DBFETCH(dest)->location; if (!(FLAGS(destplayer) & JUMP_OK) || (FLAGS(dest) & BUILDER)) { return 0; } } /* if (OkObj(thing)) if ( ((FLAG2(player) & F2IMMOBILE) && !(FLAG2(thing) & F2IMMOBILE)) && (!(Typeof(dest) == TYPE_PROGRAM) && !(dest == NIL)) ) { envpropqueue(descr, player, OkObj(player) ? getloc(player) : -1, thing, thing, NOTHING, "@immobile", "Immobile", 1, 1); return 0; } */ if ((dest != HOME) && (Typeof(dest) == TYPE_ROOM) && Guest(player) && (tp_guest_needflag ? !(FLAG2(dest) & F2GUEST) : (FLAG2(dest) & F2GUEST))) { anotify_nolisten(player, CFAIL "Guests aren't allowed there.", 1); return 0; } /* for actions */ if ((DBFETCH(thing)->location != NOTHING) && (Typeof(DBFETCH(thing)->location) != TYPE_ROOM)) { if ((Typeof(dest) == TYPE_ROOM || Typeof(dest) == TYPE_PLAYER) && (FLAGS(source) & BUILDER)) return 0; if (tp_secure_teleport && Typeof(dest) == TYPE_ROOM) { if ((dest != HOME) && (!controls(owner, dest)) && ((FLAGS(dest) & JUMP_OK) == 0)) { return 0; } } } } if (tryprog) return (eval_boolexp(descr, player, get_property_lock(thing, prop), thing)); else return (eval_boolexp2(descr, player, get_property_lock(thing, prop), thing)); }
static void push_arg(dbref player, struct frame *fr, const char *arg) { int num = 0, lflag = 0, sflag = 0; double inum = 0.0; if (fr->argument.top >= STACK_SIZE) { anotify_nolisten(player, CFAIL "That would overflow the stack.", 1); return; } if (number(arg)) { /* push a number */ num = atoi(arg); push(fr->argument.st, &fr->argument.top, PROG_INTEGER, MIPSCAST & num); anotify_nolisten(player, CSUCC "Integer pushed.", 1); } else if (ifloat(arg)) { /* push a float */ inum = atof(arg); push(fr->argument.st, &fr->argument.top, PROG_FLOAT, MIPSCAST & inum); notify_nolisten(player, "Float pushed.", 1); } else if (*arg == NUMBER_TOKEN) { /* push a dbref */ if (!number(arg + 1)) { anotify_nolisten(player, CINFO "I don't understand that dbref.", 1); return; } num = atoi(arg + 1); push(fr->argument.st, &fr->argument.top, PROG_OBJECT, MIPSCAST & num); anotify_nolisten(player, CSUCC "Dbref pushed.", 1); } else if (*arg == '"') { /* push a string */ char buf[BUFFER_LEN]; char *ptr; const char *ptr2; for (ptr = buf, ptr2 = arg + 1; *ptr2; ptr2++) { if (*ptr2 == '\\') { if (!*(++ptr2)) break; *ptr++ = *ptr2; } else if (*ptr2 == '"') { break; } else { *ptr++ = *ptr2; } } *ptr = '\0'; push(fr->argument.st, &fr->argument.top, PROG_STRING, MIPSCAST alloc_prog_string(buf)); anotify_nolisten(player, CSUCC "String pushed.", 1); } else { int varnum = scopedvar_getnum(fr, 0, arg); if (varnum != -1) { sflag = 1; } else { if (*arg == 'S' || *arg == 's') { ++arg; if (*arg == 'V' || *arg == 'v') { arg++; } sflag = 1; varnum = scopedvar_getnum(fr, 0, arg); } else if (*arg == 'L' || *arg == 'l') { ++arg; if (*arg == 'V' || *arg == 'v') { ++arg; } lflag = 1; } else if (*arg == 'V' || *arg == 'v') { ++arg; } } if (varnum > -1) { num = varnum; } else if (number(arg)) { num = atoi(arg); } else { anotify_nolisten(player, CINFO "I don't understand what you want to push.", 1); return; } if (lflag) { push(fr->argument.st, &fr->argument.top, PROG_LVAR, MIPSCAST & num); anotify_nolisten(player, CSUCC "Local variable pushed.", 1); } else if (sflag) { push(fr->argument.st, &fr->argument.top, PROG_SVAR, MIPSCAST & num); anotify_nolisten(player, CSUCC "Scoped variable pushed.", 1); } else { push(fr->argument.st, &fr->argument.top, PROG_VAR, MIPSCAST & num); anotify_nolisten(player, CSUCC "Global variable pushed.", 1); } } }
static void debug_printvar(dbref player, dbref program, struct frame *fr, const char *arg) { int i; int lflag = 0; int sflag = 0; int varnum = -1; char buf[BUFFER_LEN]; if (!arg || !*arg) { anotify_nolisten(player, CINFO "I don't know which variable you mean.", 1); return; } varnum = scopedvar_getnum(fr, 0, arg); if (varnum != -1) { sflag = 1; } else if (*arg == 'L' || *arg == 'l') { arg++; if (*arg == 'V' || *arg == 'v') { arg++; } lflag = 1; varnum = scopedvar_getnum(fr, 0, arg); } else if (*arg == 'S' || *arg == 's') { arg++; if (*arg == 'V' || *arg == 'v') { arg++; } sflag = 1; } else if (*arg == 'V' || *arg == 'v') { arg++; } if (varnum > -1) { i = varnum; } else if (number(arg)) { i = atoi(arg); } else { notify_nolisten(player, "I don't know which variable you mean.", 1); return; } if (i >= MAX_VAR || i < 0) { anotify_nolisten(player, CINFO "Variable number out of range.", 1); return; } if (sflag) { struct inst *tmp = scopedvar_get(fr, 0, i); if (!tmp) { notify_nolisten(player, "Scoped variable number out of range.", 1); return; } notify_nolisten(player, insttotext(fr, 0, tmp, buf, sizeof(buf), 4000, -1), 1); } else if (lflag) { struct localvars *lvars = localvars_get(fr, program); notify_nolisten(player, insttotext(fr, 0, &(lvars->lvars[i]), buf, sizeof(buf), 4000, -1), 1); } else { notify_nolisten(player, insttotext(fr, 0, &(fr->variables[i]), buf, sizeof(buf), 4000, -1), 1); } }
void muf_backtrace(dbref player, dbref program, int count, struct frame *fr) { char buf[BUFFER_LEN]; char buf2[BUFFER_LEN]; char buf3[BUFFER_LEN]; char *ptr; dbref ref; int i, j, cnt, flag; struct inst *pinst, *lastinst; int lev; anotify_nolisten(player, CINFO "System stack backtrace:", 1); i = count; if (!i) i = STACK_SIZE; ref = program; pinst = NULL; j = fr->system.top + 1; while (j > 1 && i-- > 0) { cnt = 0; do { lastinst = pinst; if (--j == fr->system.top) { pinst = fr->pc + 1; } else { ref = fr->system.st[j].progref; pinst = fr->system.st[j].offset; } ptr = unparse_sysreturn(&ref, pinst); cnt++; } while (pinst == lastinst && j > 1); if (cnt > 1) { sprintf(buf, " [repeats %d times]", cnt); notify_nolisten(player, buf, 1); } lev = fr->system.top - j; if (ptr) { int k; char *bufend = buf2; struct inst *fntop = fr->pc; struct inst *varinst; while (fntop->type != PROG_FUNCTION) --fntop; bufend += sprintf(buf2, "%.512s" SYSWHITE "(" SYSNORMAL, ptr); for (k = 0; k < fntop->data.mufproc->args; ++k) { const char *nam = scopedvar_getname(fr, lev, k); char *val; const char *fmt; if (!nam) { break; } varinst = scopedvar_get(fr, lev, k); val = insttotext(fr, lev, varinst, buf3, sizeof(buf3), 30, program); if (k) { fmt = SYSWHITE ", %s=" SYSNORMAL "%s"; } else { fmt = SYSWHITE "%s=" SYSNORMAL "%s"; } bufend += snprintf(bufend, buf2 - bufend - 18, fmt, nam, val); } bufend += snprintf(bufend, buf2 - bufend - 1, SYSWHITE ")" SYSNORMAL, ptr); ptr = buf2; } if (pinst != lastinst) { sprintf(buf, "%3d) %s(#%d) %s:", j, NAME(ref), ref, ptr); notify_nolisten(player, buf, 1); flag = ((FLAGS(player) & INTERNAL) ? 1 : 0); FLAGS(player) &= ~INTERNAL; list_proglines(player, ref, fr, (pinst - 1)->line, 0); if (flag) { FLAGS(player) |= INTERNAL; } } } anotify_nolisten(player, CINFO "Done.", 1); }