From e4c1890a2550ef4a24816283ca9cacd53d6282c5 Mon Sep 17 00:00:00 2001 From: Jonathan Schleifer Date: Fri, 7 Mar 2025 22:44:37 +0000 Subject: [PATCH] Make execute() take an OFString FossilOrigin-Name: acc50da079501c3c301f3a742f14cdfe7ac4b6fd56a6ee46acb32cfbaa059dcf --- src/Command.mm | 4 +- src/clientgame.mm | 16 ++---- src/commands.mm | 126 ++++++++++++++++++++----------------------- src/console.mm | 18 ++----- src/menus.mm | 5 +- src/protos.h | 2 +- src/serverbrowser.mm | 6 ++- src/world.mm | 10 ++-- 8 files changed, 79 insertions(+), 108 deletions(-) diff --git a/src/Command.mm b/src/Command.mm index ad4194f..69dc391 100644 --- a/src/Command.mm +++ b/src/Command.mm @@ -78,12 +78,12 @@ case ARG_1EXP: if (isDown) return ((int(__cdecl *)(int))_function)( - execute(arguments[1])); + execute(@(arguments[1]))); break; case ARG_2EXP: if (isDown) return ((int(__cdecl *)(int, int))_function)( - execute(arguments[1]), execute(arguments[2])); + execute(@(arguments[1])), execute(@(arguments[2]))); break; case ARG_1EST: if (isDown) diff --git a/src/clientgame.mm b/src/clientgame.mm index 6df78f8..0f557ee 100644 --- a/src/clientgame.mm +++ b/src/clientgame.mm @@ -2,8 +2,6 @@ #include "cube.h" -#include - int nextmode = 0; // nextmode becomes gamemode after next map load VAR(gamemode, 1, 0, 0); @@ -247,11 +245,7 @@ updateworld(int millis) // main game update loop curtime = millis - lastmillis; if (sleepwait && lastmillis > sleepwait) { sleepwait = 0; - @autoreleasepool { - std::unique_ptr cmd( - strdup(sleepcmd.UTF8String)); - execute(cmd.get()); - } + execute(sleepcmd); } physicsframe(); checkquad(curtime); @@ -265,7 +259,7 @@ updateworld(int millis) // main game update loop // connected to server gets2c(); // do this first, so we have most accurate // information when our player moves - }; + } otherplayers(); if (!demoplayback) { monsterthink(); @@ -283,10 +277,10 @@ updateworld(int millis) // main game update loop }; c2sinfo(player1); // do this last, to reduce the // effective frame lag - }; - }; + } + } lastmillis = millis; -}; +} void entinmap(dynent * diff --git a/src/commands.mm b/src/commands.mm index 9deae9b..083548f 100644 --- a/src/commands.mm +++ b/src/commands.mm @@ -135,9 +135,10 @@ parseexp(char *&p, int right) // parse any nested set of () or [] char *s = newstring(word, p - word - 1); if (left == '(') { string t; - itoa(t, - execute( - s)); // evaluate () exps directly, and substitute result + // evaluate () exps directly, and substitute result + @autoreleasepool { + itoa(t, execute(@(s))); + } s = exchangestr(s, t); } return s; @@ -188,41 +189,47 @@ lookup(char *n) // find value of ident referenced with $ in exp } 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 - char *w[MAXWORDS]; - int val = 0; - for (bool cont = true; cont;) // for each ; seperated statement - { - int numargs = MAXWORDS; - loopi(MAXWORDS) // collect all argument values - { - w[i] = ""; - if (i > numargs) - continue; - char *s = parseword(p); // parse and evaluate exps - if (!s) { - numargs = i; - s = ""; + @autoreleasepool { + std::unique_ptr copy(strdup(string.UTF8String)); + char *p = copy.get(); + const int MAXWORDS = 25; // limit, remove + char *w[MAXWORDS]; + int val = 0; + for (bool cont = true; cont;) { + // for each ; seperated statement + int numargs = MAXWORDS; + loopi(MAXWORDS) + { + // collect all argument values + w[i] = ""; + if (i > numargs) + 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"); - cont = *p++ != - 0; // more statements if this isn't the end of the string - char *c = w[0]; - if (*c == '/') - c++; // strip irc-style command prefix - if (!*c) - continue; // empty statement + p += strcspn(p, ";\n\0"); + // more statements if this isn't the end of the string + cont = *p++ != 0; + char *c = w[0]; + // strip irc-style command prefix + if (*c == '/') + c++; + // empty statement + if (!*c) + continue; - @autoreleasepool { __kindof Identifier *identifier = identifiers[@(c)]; - if (identifier == nil) { val = ATOI(c); if (!val && *c != '0') @@ -230,9 +237,9 @@ execute(char *p, bool isdown) // all evaluation happens here, recursively } else { if ([identifier isKindOfClass:[Command class]]) { - // game defined commands - // use very ad-hoc function signature, - // and just call it + // game defined commands use very + // ad-hoc function signature, and just + // call it val = [identifier callWithArguments:w numArguments:numargs @@ -267,18 +274,16 @@ execute(char *p, bool isdown) // all evaluation happens here, recursively } // create new string here because alias // could rebind itself - char *action = newstring( - [identifier action].UTF8String); - val = execute(action, isdown); - gp()->deallocstr(action); + val = execute( + [[identifier action] copy], isdown); break; } } + loopj(numargs) gp()->deallocstr(w[j]); } - loopj(numargs) gp()->deallocstr(w[j]); - } - return val; + return val; + } } // tab-completion of all identifiers @@ -345,7 +350,7 @@ execfile(OFString *cfgfile) // Ensure \0 termination. [data addItem:""]; - execute((char *)data.mutableItems); + execute(@((char *)data.mutableItems)); return true; } } @@ -427,56 +432,41 @@ intset(OFString *name, int v) void ifthen(OFString *cond, OFString *thenp, OFString *elsep) { - @autoreleasepool { - std::unique_ptr cmd(strdup( - (cond.UTF8String[0] != '0' ? thenp : elsep).UTF8String)); - - execute(cmd.get()); - } + execute((![cond hasPrefix:@"0"] ? thenp : elsep)); } void -loopa(OFString *times, OFString *body_) +loopa(OFString *times, OFString *body) { @autoreleasepool { int t = (int)times.longLongValue; - std::unique_ptr body(strdup(body_.UTF8String)); loopi(t) { intset(@"i", i); - execute(body.get()); + execute(body); } } } void -whilea(OFString *cond_, OFString *body_) +whilea(OFString *cond, OFString *body) { - @autoreleasepool { - std::unique_ptr cond(strdup(cond_.UTF8String)); - std::unique_ptr body(strdup(body_.UTF8String)); - - while (execute(cond.get())) - execute(body.get()); - } + while (execute(cond)) + execute(body); } void onrelease(bool on, OFString *body) { - if (!on) { - std::unique_ptr copy(strdup(body.UTF8String)); - execute(copy.get()); - } + if (!on) + execute(body); } void concat(OFString *s) { - @autoreleasepool { - alias(@"s", s); - } + alias(@"s", s); } void diff --git a/src/console.mm b/src/console.mm index 7b659db..e85eb55 100644 --- a/src/console.mm +++ b/src/console.mm @@ -3,7 +3,6 @@ #include "cube.h" #include -#include #import "KeyMapping.h" @@ -173,9 +172,7 @@ history(int n) if (!rec && n >= 0 && n < vhistory.count) { rec = true; - OFString *cmd = vhistory[vhistory.count - n - 1]; - std::unique_ptr copy(strdup(cmd.UTF8String)); - execute(copy.get()); + execute(vhistory[vhistory.count - n - 1]); rec = false; } } @@ -249,12 +246,9 @@ keypress(int code, bool isdown, int cooked) } } histpos = vhistory.count; - if ([commandbuf hasPrefix:@"/"]) { - std::unique_ptr copy( - strdup( - commandbuf.UTF8String)); - execute(copy.get(), true); - } else + if ([commandbuf hasPrefix:@"/"]) + execute(commandbuf, true); + else toserver(commandbuf); } saycommand(NULL); @@ -269,9 +263,7 @@ keypress(int code, bool isdown, int cooked) if (mapping.code == code) { // keystrokes go to game, lookup in keymap and // execute - string temp; - strcpy_s(temp, mapping.action.UTF8String); - execute(temp, isdown); + execute(mapping.action, isdown); return; } } diff --git a/src/menus.mm b/src/menus.mm index a3af707..5ba9eca 100644 --- a/src/menus.mm +++ b/src/menus.mm @@ -2,8 +2,6 @@ #include "cube.h" -#include - #import "Menu.h" #import "MenuItem.h" @@ -168,8 +166,7 @@ menukey(int code, bool isdown) [menuStack addObject:@(vmenu)]; menuset(-1); - std::unique_ptr copy(strdup(action.UTF8String)); - execute(copy.get(), true); + execute(action, true); } } diff --git a/src/protos.h b/src/protos.h index 298e078..0d7e518 100644 --- a/src/protos.h +++ b/src/protos.h @@ -7,7 +7,7 @@ extern void setvar(OFString *name, int i); extern int getvar(OFString *name); extern bool identexists(OFString *name); 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 bool execfile(OFString *cfgfile); extern void resetcomplete(); diff --git a/src/serverbrowser.mm b/src/serverbrowser.mm index ce0e155..ff4fd89 100644 --- a/src/serverbrowser.mm +++ b/src/serverbrowser.mm @@ -317,8 +317,10 @@ updatefrommaster() conoutf(@"master server not replying"); else { servers.setsize(0); - execute((char *)reply); - }; + @autoreleasepool { + execute(@((char *)reply)); + } + } servermenu(); } diff --git a/src/world.mm b/src/world.mm index d4908c3..f71d687 100644 --- a/src/world.mm +++ b/src/world.mm @@ -2,8 +2,6 @@ #include "cube.h" -#include - extern OFString *entnames[]; // lookup from map entities above to strings sqr *world = NULL; @@ -70,10 +68,8 @@ trigger(int tag, int type, bool savegame) OFString *aliasname = [OFString stringWithFormat:@"level_trigger_%d", tag]; - if (identexists(aliasname)) { - std::unique_ptr cmd(strdup(aliasname.UTF8String)); - execute(cmd.get()); - } + if (identexists(aliasname)) + execute(aliasname); } if (type == 2) @@ -502,7 +498,7 @@ empty_world( if (oldworld) { free(oldworld); toggleedit(); - execute("fullbright 1"); + execute(@"fullbright 1"); } }