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:
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)

View file

@ -2,8 +2,6 @@
#include "cube.h"
#include <memory>
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<char> 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 *

View file

@ -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,20 +189,26 @@ 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
{
@autoreleasepool {
std::unique_ptr<char> 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
{
for (bool cont = true; cont;) {
// for each ; seperated statement
int numargs = MAXWORDS;
loopi(MAXWORDS) // collect all argument values
loopi(MAXWORDS)
{
// collect all argument values
w[i] = "";
if (i > numargs)
continue;
char *s = parseword(p); // parse and evaluate exps
// parse and evaluate exps
char *s = parseword(p);
if (!s) {
numargs = i;
s = "";
@ -212,17 +219,17 @@ execute(char *p, bool isdown) // all evaluation happens here, recursively
}
p += strcspn(p, ";\n\0");
cont = *p++ !=
0; // more statements if this isn't the end of the string
// 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++; // strip irc-style command prefix
c++;
// empty statement
if (!*c)
continue; // empty statement
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]);
}
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<char> 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<char> 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<char> cond(strdup(cond_.UTF8String));
std::unique_ptr<char> 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<char> copy(strdup(body.UTF8String));
execute(copy.get());
}
if (!on)
execute(body);
}
void
concat(OFString *s)
{
@autoreleasepool {
alias(@"s", s);
}
}
void

View file

@ -3,7 +3,6 @@
#include "cube.h"
#include <ctype.h>
#include <memory>
#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<char> 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<char> 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;
}
}

View file

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

View file

@ -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();

View file

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

View file

@ -2,8 +2,6 @@
#include "cube.h"
#include <memory>
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<char> 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");
}
}