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:
Julian Smith
2021-08-26 22:19:08 +01:00
parent 624581f470
commit 629b681a29
3 changed files with 32 additions and 6 deletions

View File

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

View File

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

View File

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