Make execute() take an OFString

FossilOrigin-Name: acc50da079501c3c301f3a742f14cdfe7ac4b6fd56a6ee46acb32cfbaa059dcf
This commit is contained in:
Jonathan Schleifer 2025-03-07 22:44:37 +00:00
parent 039efe612d
commit e4c1890a25
8 changed files with 79 additions and 108 deletions

View file

@ -78,12 +78,12 @@
case ARG_1EXP: case ARG_1EXP:
if (isDown) if (isDown)
return ((int(__cdecl *)(int))_function)( return ((int(__cdecl *)(int))_function)(
execute(arguments[1])); execute(@(arguments[1])));
break; break;
case ARG_2EXP: case ARG_2EXP:
if (isDown) if (isDown)
return ((int(__cdecl *)(int, int))_function)( return ((int(__cdecl *)(int, int))_function)(
execute(arguments[1]), execute(arguments[2])); execute(@(arguments[1])), execute(@(arguments[2])));
break; break;
case ARG_1EST: case ARG_1EST:
if (isDown) if (isDown)

View file

@ -2,8 +2,6 @@
#include "cube.h" #include "cube.h"
#include <memory>
int nextmode = 0; // nextmode becomes gamemode after next map load int nextmode = 0; // nextmode becomes gamemode after next map load
VAR(gamemode, 1, 0, 0); VAR(gamemode, 1, 0, 0);
@ -247,11 +245,7 @@ updateworld(int millis) // main game update loop
curtime = millis - lastmillis; curtime = millis - lastmillis;
if (sleepwait && lastmillis > sleepwait) { if (sleepwait && lastmillis > sleepwait) {
sleepwait = 0; sleepwait = 0;
@autoreleasepool { execute(sleepcmd);
std::unique_ptr<char> cmd(
strdup(sleepcmd.UTF8String));
execute(cmd.get());
}
} }
physicsframe(); physicsframe();
checkquad(curtime); checkquad(curtime);
@ -265,7 +259,7 @@ updateworld(int millis) // main game update loop
// connected to server // connected to server
gets2c(); // do this first, so we have most accurate gets2c(); // do this first, so we have most accurate
// information when our player moves // information when our player moves
}; }
otherplayers(); otherplayers();
if (!demoplayback) { if (!demoplayback) {
monsterthink(); monsterthink();
@ -283,10 +277,10 @@ updateworld(int millis) // main game update loop
}; };
c2sinfo(player1); // do this last, to reduce the c2sinfo(player1); // do this last, to reduce the
// effective frame lag // effective frame lag
}; }
}; }
lastmillis = millis; lastmillis = millis;
}; }
void void
entinmap(dynent * entinmap(dynent *

View file

@ -135,9 +135,10 @@ parseexp(char *&p, int right) // parse any nested set of () or []
char *s = newstring(word, p - word - 1); char *s = newstring(word, p - word - 1);
if (left == '(') { if (left == '(') {
string t; string t;
itoa(t, // evaluate () exps directly, and substitute result
execute( @autoreleasepool {
s)); // evaluate () exps directly, and substitute result itoa(t, execute(@(s)));
}
s = exchangestr(s, t); s = exchangestr(s, t);
} }
return s; return s;
@ -188,41 +189,47 @@ lookup(char *n) // find value of ident referenced with $ in exp
} }
int int
execute(char *p, bool isdown) // all evaluation happens here, recursively execute(
OFString *string, bool isdown) // all evaluation happens here, recursively
{ {
const int MAXWORDS = 25; // limit, remove @autoreleasepool {
char *w[MAXWORDS]; std::unique_ptr<char> copy(strdup(string.UTF8String));
int val = 0; char *p = copy.get();
for (bool cont = true; cont;) // for each ; seperated statement const int MAXWORDS = 25; // limit, remove
{ char *w[MAXWORDS];
int numargs = MAXWORDS; int val = 0;
loopi(MAXWORDS) // collect all argument values for (bool cont = true; cont;) {
{ // for each ; seperated statement
w[i] = ""; int numargs = MAXWORDS;
if (i > numargs) loopi(MAXWORDS)
continue; {
char *s = parseword(p); // parse and evaluate exps // collect all argument values
if (!s) { w[i] = "";
numargs = i; if (i > numargs)
s = ""; continue;
// parse and evaluate exps
char *s = parseword(p);
if (!s) {
numargs = i;
s = "";
}
if (*s == '$')
s = lookup(s); // substitute variables
w[i] = s;
} }
if (*s == '$')
s = lookup(s); // substitute variables
w[i] = s;
}
p += strcspn(p, ";\n\0"); p += strcspn(p, ";\n\0");
cont = *p++ != // more statements if this isn't the end of the string
0; // more statements if this isn't the end of the string cont = *p++ != 0;
char *c = w[0]; char *c = w[0];
if (*c == '/') // strip irc-style command prefix
c++; // strip irc-style command prefix if (*c == '/')
if (!*c) c++;
continue; // empty statement // empty statement
if (!*c)
continue;
@autoreleasepool {
__kindof Identifier *identifier = identifiers[@(c)]; __kindof Identifier *identifier = identifiers[@(c)];
if (identifier == nil) { if (identifier == nil) {
val = ATOI(c); val = ATOI(c);
if (!val && *c != '0') if (!val && *c != '0')
@ -230,9 +237,9 @@ execute(char *p, bool isdown) // all evaluation happens here, recursively
} else { } else {
if ([identifier if ([identifier
isKindOfClass:[Command class]]) { isKindOfClass:[Command class]]) {
// game defined commands // game defined commands use very
// use very ad-hoc function signature, // ad-hoc function signature, and just
// and just call it // call it
val = [identifier val = [identifier
callWithArguments:w callWithArguments:w
numArguments:numargs numArguments:numargs
@ -267,18 +274,16 @@ execute(char *p, bool isdown) // all evaluation happens here, recursively
} }
// create new string here because alias // create new string here because alias
// could rebind itself // could rebind itself
char *action = newstring( val = execute(
[identifier action].UTF8String); [[identifier action] copy], isdown);
val = execute(action, isdown);
gp()->deallocstr(action);
break; break;
} }
} }
loopj(numargs) gp()->deallocstr(w[j]);
} }
loopj(numargs) gp()->deallocstr(w[j]);
}
return val; return val;
}
} }
// tab-completion of all identifiers // tab-completion of all identifiers
@ -345,7 +350,7 @@ execfile(OFString *cfgfile)
// Ensure \0 termination. // Ensure \0 termination.
[data addItem:""]; [data addItem:""];
execute((char *)data.mutableItems); execute(@((char *)data.mutableItems));
return true; return true;
} }
} }
@ -427,56 +432,41 @@ intset(OFString *name, int v)
void void
ifthen(OFString *cond, OFString *thenp, OFString *elsep) ifthen(OFString *cond, OFString *thenp, OFString *elsep)
{ {
@autoreleasepool { execute((![cond hasPrefix:@"0"] ? thenp : elsep));
std::unique_ptr<char> cmd(strdup(
(cond.UTF8String[0] != '0' ? thenp : elsep).UTF8String));
execute(cmd.get());
}
} }
void void
loopa(OFString *times, OFString *body_) loopa(OFString *times, OFString *body)
{ {
@autoreleasepool { @autoreleasepool {
int t = (int)times.longLongValue; int t = (int)times.longLongValue;
std::unique_ptr<char> body(strdup(body_.UTF8String));
loopi(t) loopi(t)
{ {
intset(@"i", i); intset(@"i", i);
execute(body.get()); execute(body);
} }
} }
} }
void void
whilea(OFString *cond_, OFString *body_) whilea(OFString *cond, OFString *body)
{ {
@autoreleasepool { while (execute(cond))
std::unique_ptr<char> cond(strdup(cond_.UTF8String)); execute(body);
std::unique_ptr<char> body(strdup(body_.UTF8String));
while (execute(cond.get()))
execute(body.get());
}
} }
void void
onrelease(bool on, OFString *body) onrelease(bool on, OFString *body)
{ {
if (!on) { if (!on)
std::unique_ptr<char> copy(strdup(body.UTF8String)); execute(body);
execute(copy.get());
}
} }
void void
concat(OFString *s) concat(OFString *s)
{ {
@autoreleasepool { alias(@"s", s);
alias(@"s", s);
}
} }
void void

View file

@ -3,7 +3,6 @@
#include "cube.h" #include "cube.h"
#include <ctype.h> #include <ctype.h>
#include <memory>
#import "KeyMapping.h" #import "KeyMapping.h"
@ -173,9 +172,7 @@ history(int n)
if (!rec && n >= 0 && n < vhistory.count) { if (!rec && n >= 0 && n < vhistory.count) {
rec = true; rec = true;
OFString *cmd = vhistory[vhistory.count - n - 1]; execute(vhistory[vhistory.count - n - 1]);
std::unique_ptr<char> copy(strdup(cmd.UTF8String));
execute(copy.get());
rec = false; rec = false;
} }
} }
@ -249,12 +246,9 @@ keypress(int code, bool isdown, int cooked)
} }
} }
histpos = vhistory.count; histpos = vhistory.count;
if ([commandbuf hasPrefix:@"/"]) { if ([commandbuf hasPrefix:@"/"])
std::unique_ptr<char> copy( execute(commandbuf, true);
strdup( else
commandbuf.UTF8String));
execute(copy.get(), true);
} else
toserver(commandbuf); toserver(commandbuf);
} }
saycommand(NULL); saycommand(NULL);
@ -269,9 +263,7 @@ keypress(int code, bool isdown, int cooked)
if (mapping.code == code) { if (mapping.code == code) {
// keystrokes go to game, lookup in keymap and // keystrokes go to game, lookup in keymap and
// execute // execute
string temp; execute(mapping.action, isdown);
strcpy_s(temp, mapping.action.UTF8String);
execute(temp, isdown);
return; return;
} }
} }

View file

@ -2,8 +2,6 @@
#include "cube.h" #include "cube.h"
#include <memory>
#import "Menu.h" #import "Menu.h"
#import "MenuItem.h" #import "MenuItem.h"
@ -168,8 +166,7 @@ menukey(int code, bool isdown)
[menuStack addObject:@(vmenu)]; [menuStack addObject:@(vmenu)];
menuset(-1); menuset(-1);
std::unique_ptr<char> copy(strdup(action.UTF8String)); execute(action, true);
execute(copy.get(), true);
} }
} }

View file

@ -7,7 +7,7 @@ extern void setvar(OFString *name, int i);
extern int getvar(OFString *name); extern int getvar(OFString *name);
extern bool identexists(OFString *name); extern bool identexists(OFString *name);
extern bool addcommand(OFString *name, void (*fun)(), int narg); extern bool addcommand(OFString *name, void (*fun)(), int narg);
extern int execute(char *p, bool down = true); extern int execute(OFString *p, bool down = true);
extern void exec(OFString *cfgfile); extern void exec(OFString *cfgfile);
extern bool execfile(OFString *cfgfile); extern bool execfile(OFString *cfgfile);
extern void resetcomplete(); extern void resetcomplete();

View file

@ -317,8 +317,10 @@ updatefrommaster()
conoutf(@"master server not replying"); conoutf(@"master server not replying");
else { else {
servers.setsize(0); servers.setsize(0);
execute((char *)reply); @autoreleasepool {
}; execute(@((char *)reply));
}
}
servermenu(); servermenu();
} }

View file

@ -2,8 +2,6 @@
#include "cube.h" #include "cube.h"
#include <memory>
extern OFString *entnames[]; // lookup from map entities above to strings extern OFString *entnames[]; // lookup from map entities above to strings
sqr *world = NULL; sqr *world = NULL;
@ -70,10 +68,8 @@ trigger(int tag, int type, bool savegame)
OFString *aliasname = OFString *aliasname =
[OFString stringWithFormat:@"level_trigger_%d", tag]; [OFString stringWithFormat:@"level_trigger_%d", tag];
if (identexists(aliasname)) { if (identexists(aliasname))
std::unique_ptr<char> cmd(strdup(aliasname.UTF8String)); execute(aliasname);
execute(cmd.get());
}
} }
if (type == 2) if (type == 2)
@ -502,7 +498,7 @@ empty_world(
if (oldworld) { if (oldworld) {
free(oldworld); free(oldworld);
toggleedit(); toggleedit();
execute("fullbright 1"); execute(@"fullbright 1");
} }
} }