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