simgear/nasal/code.c:setupFuncall(): improve diagnostic if not callable.
If we have an uncallable object error, also show the type and value of the uncallable object. To make this work, have upgraded simgear/nasal/lib.c:dosprintf() to be globally available. Could perhaps rename it and declare in a different header. But it's C so we don't want to make it part of simgear's general utility functions.
This commit is contained in:
@@ -328,6 +328,24 @@ static void checkNamedArgs(naContext ctx, struct naCode* c, struct naHash* h)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* This is a C equivalent to NasalRefDescription() in
|
||||
flightgear/src/Scripting/NasalSys_private.hxx. */
|
||||
static char* NasalRefDescription(naRef val)
|
||||
{
|
||||
if (naIsNil(val)) return dosprintf("nil");
|
||||
else if (naIsNum(val)) return dosprintf("num: %f", naNumValue(val).num);
|
||||
else if (naIsString(val)) return dosprintf("string: %s", naStr_data(val));
|
||||
else if (naIsScalar(val)) return dosprintf("scalar");
|
||||
else if (naIsVector(val)) return dosprintf("vector");
|
||||
else if (naIsHash(val)) return dosprintf("hash");
|
||||
else if (naIsFunc(val)) return dosprintf("func");
|
||||
else if (naIsCode(val)) return dosprintf("code");
|
||||
else if (naIsCCode(val)) return dosprintf("ccode");
|
||||
else if (naIsGhost(val)) return dosprintf("ghost");
|
||||
else return dosprintf("?");
|
||||
}
|
||||
|
||||
static struct Frame* setupFuncall(naContext ctx, int nargs, int mcall, int named)
|
||||
{
|
||||
naRef *args, func, code, obj = naNil();
|
||||
@@ -336,7 +354,13 @@ static struct Frame* setupFuncall(naContext ctx, int nargs, int mcall, int named
|
||||
|
||||
args = &ctx->opStack[opf];
|
||||
func = ctx->opStack[--opf];
|
||||
if(!IS_FUNC(func)) ERR(ctx, "function/method call on uncallable object");
|
||||
if(!IS_FUNC(func)) {
|
||||
char* func_description = NasalRefDescription(func);
|
||||
char* description = dosprintf("function/method call on uncallable object: %s", func_description);
|
||||
ERR(ctx, description);
|
||||
naFree(description);
|
||||
naFree(func_description);
|
||||
}
|
||||
code = PTR(func).func->code;
|
||||
if(mcall) obj = ctx->opStack[--opf];
|
||||
ctx->opFrame = opf;
|
||||
|
||||
@@ -375,11 +375,7 @@ static naRef f_die(naContext c, naRef me, int argc, naRef* args)
|
||||
return naNil(); // never executes
|
||||
}
|
||||
|
||||
// Wrapper around vsnprintf that will allocate the required size
|
||||
// by calling vsnprintf with NULL and 0 - and vsnsprintf will measure the
|
||||
// required amount of characters which we then allocate and return
|
||||
// Returned buffer should be freed by the caller.
|
||||
static char* dosprintf(char* f, ...)
|
||||
char* dosprintf(char* f, ...)
|
||||
{
|
||||
char* buf;
|
||||
|
||||
|
||||
@@ -152,6 +152,12 @@ void naRethrowError(naContext subc);
|
||||
int naMember_get(naContext c, naRef obj, naRef field, naRef* out);
|
||||
int naMember_cget(naContext c, naRef obj, const char* field, naRef* out);
|
||||
|
||||
// Wrapper around vsnprintf that will allocate the required size
|
||||
// by calling vsnprintf with NULL and 0 - and vsnsprintf will measure the
|
||||
// required amount of characters which we then allocate and return
|
||||
// Returned buffer should be freed by the caller with naFree().
|
||||
char* dosprintf(char* f, ...);
|
||||
|
||||
// Returns a hash containing functions from the Nasal standard library
|
||||
// Useful for passing as a namespace to an initial function call
|
||||
naRef naInit_std(naContext c);
|
||||
|
||||
Reference in New Issue
Block a user