Clean up argument passing of commands
FossilOrigin-Name: 22520cd0d9f9e9a106f9680d90f4c5ac87da8db1c1c304342d6c637557012b22
This commit is contained in:
parent
e4c1890a25
commit
6ecfc000d1
3 changed files with 69 additions and 73 deletions
|
@ -10,9 +10,7 @@ OF_ASSUME_NONNULL_BEGIN
|
|||
- (instancetype)initWithName:(OFString *)name
|
||||
function:(void (*)())function
|
||||
argumentsTypes:(int)argumentsTypes;
|
||||
- (int)callWithArguments:(char *_Nonnull *_Nonnull)arguments
|
||||
numArguments:(size_t)numArguments
|
||||
isDown:(bool)isDown;
|
||||
- (int)callWithArguments:(OFArray<OFString *> *)arguments isDown:(bool)isDown;
|
||||
@end
|
||||
|
||||
OF_ASSUME_NONNULL_END
|
||||
|
|
|
@ -15,31 +15,34 @@
|
|||
return self;
|
||||
}
|
||||
|
||||
- (int)callWithArguments:(char **)arguments
|
||||
numArguments:(size_t)numArguments
|
||||
isDown:(bool)isDown
|
||||
- (int)callWithArguments:(OFArray<OFString *> *)arguments isDown:(bool)isDown
|
||||
{
|
||||
switch (_argumentsTypes) {
|
||||
case ARG_1INT:
|
||||
if (isDown)
|
||||
((void(__cdecl *)(int))_function)(ATOI(arguments[1]));
|
||||
((void(__cdecl *)(int))_function)(
|
||||
(int)[arguments[1] longLongValueWithBase:0]);
|
||||
break;
|
||||
case ARG_2INT:
|
||||
if (isDown)
|
||||
((void(__cdecl *)(int, int))_function)(
|
||||
ATOI(arguments[1]), ATOI(arguments[2]));
|
||||
(int)[arguments[1] longLongValueWithBase:0],
|
||||
(int)[arguments[2] longLongValueWithBase:0]);
|
||||
break;
|
||||
case ARG_3INT:
|
||||
if (isDown)
|
||||
((void(__cdecl *)(int, int, int))_function)(
|
||||
ATOI(arguments[1]), ATOI(arguments[2]),
|
||||
ATOI(arguments[3]));
|
||||
(int)[arguments[1] longLongValueWithBase:0],
|
||||
(int)[arguments[2] longLongValueWithBase:0],
|
||||
(int)[arguments[3] longLongValueWithBase:0]);
|
||||
break;
|
||||
case ARG_4INT:
|
||||
if (isDown)
|
||||
((void(__cdecl *)(int, int, int, int))_function)(
|
||||
ATOI(arguments[1]), ATOI(arguments[2]),
|
||||
ATOI(arguments[3]), ATOI(arguments[4]));
|
||||
(int)[arguments[1] longLongValueWithBase:0],
|
||||
(int)[arguments[2] longLongValueWithBase:0],
|
||||
(int)[arguments[3] longLongValueWithBase:0],
|
||||
(int)[arguments[4] longLongValueWithBase:0]);
|
||||
break;
|
||||
case ARG_NONE:
|
||||
if (isDown)
|
||||
|
@ -47,69 +50,59 @@
|
|||
break;
|
||||
case ARG_1STR:
|
||||
if (isDown)
|
||||
((void(__cdecl *)(OFString *))_function)(
|
||||
@(arguments[1]));
|
||||
((void(__cdecl *)(OFString *))_function)(arguments[1]);
|
||||
break;
|
||||
case ARG_2STR:
|
||||
if (isDown)
|
||||
((void(__cdecl *)(OFString *, OFString *))_function)(
|
||||
@(arguments[1]), @(arguments[2]));
|
||||
arguments[1], arguments[2]);
|
||||
break;
|
||||
case ARG_3STR:
|
||||
if (isDown)
|
||||
((void(__cdecl *)(
|
||||
OFString *, OFString *, OFString *))_function)(
|
||||
@(arguments[1]), @(arguments[2]), @(arguments[3]));
|
||||
arguments[1], arguments[2], arguments[3]);
|
||||
break;
|
||||
case ARG_5STR:
|
||||
if (isDown)
|
||||
((void(__cdecl *)(OFString *, OFString *, OFString *,
|
||||
OFString *, OFString *))_function)(@(arguments[1]),
|
||||
@(arguments[2]), @(arguments[3]), @(arguments[4]),
|
||||
@(arguments[5]));
|
||||
OFString *, OFString *))_function)(arguments[1],
|
||||
arguments[2], arguments[3], arguments[4],
|
||||
arguments[5]);
|
||||
break;
|
||||
case ARG_DOWN:
|
||||
((void(__cdecl *)(bool))_function)(isDown);
|
||||
break;
|
||||
case ARG_DWN1:
|
||||
((void(__cdecl *)(bool, OFString *))_function)(
|
||||
isDown, @(arguments[1]));
|
||||
isDown, arguments[1]);
|
||||
break;
|
||||
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)
|
||||
return ((int(__cdecl *)(OFString *))_function)(
|
||||
@(arguments[1]));
|
||||
arguments[1]);
|
||||
break;
|
||||
case ARG_2EST:
|
||||
if (isDown)
|
||||
return (
|
||||
(int(__cdecl *)(OFString *, OFString *))_function)(
|
||||
@(arguments[1]), @(arguments[2]));
|
||||
return ((int(__cdecl *)(OFString *,
|
||||
OFString *))_function)(arguments[1], arguments[2]);
|
||||
break;
|
||||
case ARG_VARI:
|
||||
if (isDown) {
|
||||
if (isDown)
|
||||
// limit, remove
|
||||
string r;
|
||||
r[0] = 0;
|
||||
for (int i = 1; i < numArguments; i++) {
|
||||
// make string-list out of all arguments
|
||||
strcat_s(r, arguments[i]);
|
||||
if (i == numArguments - 1)
|
||||
break;
|
||||
strcat_s(r, " ");
|
||||
}
|
||||
((void(__cdecl *)(OFString *))_function)(@(r));
|
||||
}
|
||||
((void(__cdecl *)(OFString *))_function)([[arguments
|
||||
objectsInRange:OFMakeRange(1, arguments.count - 1)]
|
||||
componentsJoinedByString:@" "]);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -170,21 +170,21 @@ parseword(char *&p) // parse single argument, including expressions
|
|||
return newstring(word, p - word);
|
||||
}
|
||||
|
||||
char *
|
||||
lookup(char *n) // find value of ident referenced with $ in exp
|
||||
OFString *
|
||||
lookup(OFString *n) // find value of ident referenced with $ in exp
|
||||
{
|
||||
@autoreleasepool {
|
||||
__kindof Identifier *identifier = identifiers[@(n + 1)];
|
||||
__kindof Identifier *identifier =
|
||||
identifiers[[n substringFromIndex:1]];
|
||||
|
||||
if ([identifier isKindOfClass:[Variable class]]) {
|
||||
string t;
|
||||
itoa(t, *[identifier storage]);
|
||||
return exchangestr(n, t);
|
||||
return [OFString
|
||||
stringWithFormat:@"%d", *[identifier storage]];
|
||||
} else if ([identifier isKindOfClass:[Alias class]])
|
||||
return exchangestr(n, [identifier action].UTF8String);
|
||||
return [identifier action];
|
||||
}
|
||||
|
||||
conoutf(@"unknown alias lookup: %s", n + 1);
|
||||
conoutf(@"unknown alias lookup: %@", [n substringFromIndex:1]);
|
||||
return n;
|
||||
}
|
||||
|
||||
|
@ -196,7 +196,7 @@ execute(
|
|||
std::unique_ptr<char> copy(strdup(string.UTF8String));
|
||||
char *p = copy.get();
|
||||
const int MAXWORDS = 25; // limit, remove
|
||||
char *w[MAXWORDS];
|
||||
OFString *w[MAXWORDS];
|
||||
int val = 0;
|
||||
for (bool cont = true; cont;) {
|
||||
// for each ; seperated statement
|
||||
|
@ -204,7 +204,7 @@ execute(
|
|||
loopi(MAXWORDS)
|
||||
{
|
||||
// collect all argument values
|
||||
w[i] = "";
|
||||
w[i] = @"";
|
||||
if (i > numargs)
|
||||
continue;
|
||||
// parse and evaluate exps
|
||||
|
@ -214,63 +214,69 @@ execute(
|
|||
s = "";
|
||||
}
|
||||
if (*s == '$')
|
||||
s = lookup(s); // substitute variables
|
||||
w[i] = s;
|
||||
// substitute variables
|
||||
w[i] = lookup(@(s));
|
||||
else
|
||||
w[i] = @(s);
|
||||
}
|
||||
|
||||
p += strcspn(p, ";\n\0");
|
||||
// more statements if this isn't the end of the string
|
||||
cont = *p++ != 0;
|
||||
char *c = w[0];
|
||||
OFString *c = w[0];
|
||||
// strip irc-style command prefix
|
||||
if (*c == '/')
|
||||
c++;
|
||||
if ([c hasPrefix:@"/"])
|
||||
c = [c substringFromIndex:1];
|
||||
// empty statement
|
||||
if (!*c)
|
||||
if (c.length == 0)
|
||||
continue;
|
||||
|
||||
__kindof Identifier *identifier = identifiers[@(c)];
|
||||
__kindof Identifier *identifier = identifiers[c];
|
||||
if (identifier == nil) {
|
||||
val = ATOI(c);
|
||||
if (!val && *c != '0')
|
||||
@try {
|
||||
val = (int)[c longLongValueWithBase:0];
|
||||
} @catch (OFInvalidFormatException *e) {
|
||||
conoutf(@"unknown command: %s", c);
|
||||
}
|
||||
} else {
|
||||
if ([identifier
|
||||
isKindOfClass:[Command class]]) {
|
||||
// game defined commands use very
|
||||
// ad-hoc function signature, and just
|
||||
// call it
|
||||
OFArray<OFString *> *arguments =
|
||||
[[OFArray alloc]
|
||||
initWithObjects:w
|
||||
count:numargs + 1];
|
||||
val = [identifier
|
||||
callWithArguments:w
|
||||
numArguments:numargs
|
||||
callWithArguments:arguments
|
||||
isDown:isdown];
|
||||
} else if ([identifier
|
||||
isKindOfClass:[Variable
|
||||
class]]) {
|
||||
// game defined variables
|
||||
if (isdown) {
|
||||
if (!w[1][0])
|
||||
if (w[1].length == 0)
|
||||
[identifier printValue];
|
||||
else
|
||||
[identifier
|
||||
setValue:ATOI(
|
||||
w[1])];
|
||||
setValue:
|
||||
(int)[w[1]
|
||||
longLongValueWithBase:
|
||||
0]];
|
||||
}
|
||||
} else if ([identifier
|
||||
isKindOfClass:[Alias class]]) {
|
||||
// alias, also used as functions and
|
||||
// (global) variables
|
||||
for (int i = 1; i < numargs; i++) {
|
||||
@autoreleasepool {
|
||||
// set any arguments as
|
||||
// (global) arg values
|
||||
// so functions can
|
||||
// access them
|
||||
// (global) arg values so
|
||||
// functions can access them
|
||||
OFString *t = [OFString
|
||||
stringWithFormat:
|
||||
@"arg%d", i];
|
||||
alias(t, @(w[i]));
|
||||
}
|
||||
stringWithFormat:@"arg%d",
|
||||
i];
|
||||
alias(t, w[i]);
|
||||
}
|
||||
// create new string here because alias
|
||||
// could rebind itself
|
||||
|
@ -279,7 +285,6 @@ execute(
|
|||
break;
|
||||
}
|
||||
}
|
||||
loopj(numargs) gp()->deallocstr(w[j]);
|
||||
}
|
||||
|
||||
return val;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue