From caa643c5781fbdfdf20836b619d61c71158d5c10 Mon Sep 17 00:00:00 2001 From: Lee Salzman Date: Mon, 15 Sep 2008 05:03:59 +0000 Subject: [PATCH] context removal fixes git-svn-id: svn://svn.code.sf.net/p/actiongame/code/trunk/ac@2612 e016b1c5-ed68-44aa-a2f7-31cac88cffde --- source/src/command.cpp | 63 +++++++++++++++++++++++++++++++----------- 1 file changed, 47 insertions(+), 16 deletions(-) diff --git a/source/src/command.cpp b/source/src/command.cpp index 82ef699e..671333a2 100644 --- a/source/src/command.cpp +++ b/source/src/command.cpp @@ -7,6 +7,9 @@ bool allowidentaccess(ident *id); char *exchangestr(char *o, const char *n) { delete[] o; return newstring(n); } +vector contextstack; +bool contextsealed = false; +bool contextisolated[IEXC_NUM] = { false }; int execcontext; hashtable *idents = NULL; // contains ALL vars/commands/aliases @@ -26,7 +29,7 @@ void clearstack(ident &id) id.stack = NULL; } -void pushident(ident &id, char *val) +void pushident(ident &id, char *val, int context = execcontext) { if(id.type != ID_ALIAS) return; identstack *stack = new identstack; @@ -35,7 +38,7 @@ void pushident(ident &id, char *val) stack->next = id.stack; id.stack = stack; id.action = val; - id.context = execcontext; + id.context = context; } void popident(ident &id) @@ -49,12 +52,12 @@ void popident(ident &id) delete stack; } -ident *newident(const char *name) +ident *newident(const char *name, int context = execcontext) { ident *id = idents->access(name); if(!id) { - ident init(ID_ALIAS, newstring(name), newstring(""), persistidents, IEXC_CORE); + ident init(ID_ALIAS, newstring(name), newstring(""), persistidents, context); id = &idents->access(init.name, init); } return id; @@ -62,7 +65,13 @@ ident *newident(const char *name) void pusha(const char *name, char *action) { - pushident(*newident(name), action); + ident *id = newident(name, execcontext); + if(contextisolated[execcontext] && execcontext > id->context) + { + conoutf("cannot redefine alias %s in this execution context", id->name); + return; + } + pushident(*id, action); } void push(const char *name, const char *action) @@ -73,7 +82,13 @@ void push(const char *name, const char *action) void pop(const char *name) { ident *id = idents->access(name); - if(id) popident(*id); + if(!id) return; + if(contextisolated[execcontext] && execcontext > id->context) + { + conoutf("cannot redefine alias %s in this execution context", id->name); + return; + } + popident(*id); } COMMAND(push, ARG_2STR); @@ -89,6 +104,11 @@ void alias(const char *name, const char *action) } else if(b->type==ID_ALIAS) { + if(contextisolated[execcontext] && execcontext > b->context) + { + conoutf("cannot redefine alias %s in this execution context", b->name); + return; + } if(b->action!=b->executing) delete[] b->action; b->action = newstring(action); if(b->persist!=persistidents) b->persist = persistidents; @@ -391,7 +411,7 @@ char *executeret(const char *p) // all evaluation hap if(i > argids.length()) { s_sprintfd(argname)("arg%d", i); - argids.add(newident(argname)); + argids.add(newident(argname, IEXC_CORE)); } pushident(*argids[i-1], w[i]); // set any arguments as (global) arg values so functions can access them } @@ -554,12 +574,19 @@ void loopa(char *var, char *times, char *body) { int t = ATOI(times); if(t<=0) return; - ident *id = newident(var); + ident *id = newident(var, execcontext); if(id->type!=ID_ALIAS) return; - loopi(t) + char *buf = newstring("0", 16); + pushident(*id, buf); + execute(body); + loopi(t-1) { - if(i) itoa(id->action, i); - else pushident(*id, newstring("0", 16)); + if(buf != id->action) + { + if(id->action != id->executing) delete[] id->action; + id->action = buf = newstring(16); + } + itoa(id->action, i); execute(body); } popident(*id); @@ -753,10 +780,6 @@ void identnames(vector &names, bool builtinonly) }); } -vector contextstack; -bool contextsealed = false; -bool contextisolated[IEXC_NUM] = { false }; - void pushscontext(int newcontext) { contextstack.add((execcontext = newcontext)); @@ -773,7 +796,15 @@ int popscontext() enumeratekt(*idents, const char *, name, ident, id, { if(id.type == ID_ALIAS && id.context > execcontext) - idents->remove(name); + { + while(id.stack && id.stack->context > execcontext) + popident(id); + if(id.context > execcontext) + { + if(id.action != id.executing) delete[] id.action; + idents->remove(name); + } + } }); } return execcontext;