aboutsummaryrefslogtreecommitdiff
path: root/jim.c
diff options
context:
space:
mode:
Diffstat (limited to 'jim.c')
-rw-r--r--jim.c798
1 files changed, 381 insertions, 417 deletions
diff --git a/jim.c b/jim.c
index b486741..30ab7c4 100644
--- a/jim.c
+++ b/jim.c
@@ -2442,10 +2442,7 @@ static Jim_Obj *Jim_FormatString_Inner(Jim_Interp *interp, Jim_Obj *fmtObjPtr,
break;
default:
spec[0] = *fmt; spec[1] = '\0';
- Jim_FreeNewObj(interp, resObjPtr);
- Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
- Jim_AppendStrings(interp, Jim_GetResult(interp),
- "bad field specifier \"", spec, "\"", NULL);
+ Jim_SetResultFormatted(interp, "bad field specifier \"%s\"", spec);
return NULL;
}
/* force terminate */
@@ -2850,16 +2847,6 @@ static void ScriptObjAddTokens(Jim_Interp *interp, struct ScriptObj *script, Par
len = t->len;
- if (t->type != JIM_TT_ESC) {
- /* No escape conversion needed, so just copy it. */
- str = Jim_StrDupLen(t->token, len);
- }
- else {
- /* Else convert the escape chars. */
- str = Jim_Alloc(len+1);
- len = JimEscape(str, t->token, len);
- }
-
if (t->type == JIM_TT_SEP || t->type == JIM_TT_EOL) {
/* No need for a separate object here */
token->objPtr = interp->emptyObj;
@@ -2875,6 +2862,16 @@ static void ScriptObjAddTokens(Jim_Interp *interp, struct ScriptObj *script, Par
}
}
else {
+ if (t->type != JIM_TT_ESC) {
+ /* No escape conversion needed, so just copy it. */
+ str = Jim_StrDupLen(t->token, len);
+ }
+ else {
+ /* Else convert the escape chars. */
+ str = Jim_Alloc(len+1);
+ len = JimEscape(str, t->token, len);
+ }
+
/* Every object is initially a string, but the
* internal type may be specialized during execution of the
* script. */
@@ -3194,13 +3191,9 @@ int Jim_CreateProcedure(Jim_Interp *interp, const char *cmdName,
initObjPtr = Jim_GetVariable(interp, nameObjPtr,
JIM_NONE);
if (initObjPtr == NULL) {
- Jim_SetResult(interp,
- Jim_NewEmptyStringObj(interp));
- Jim_AppendStrings(interp, Jim_GetResult(interp),
- "variable for initialization of static \"",
- Jim_GetString(nameObjPtr, NULL),
- "\" not found in the local context",
- NULL);
+ Jim_SetResultFormatted(interp,
+ "variable for initialization of static \"%#s\" not found in the local context",
+ nameObjPtr);
goto err;
}
} else {
@@ -3214,20 +3207,15 @@ int Jim_CreateProcedure(Jim_Interp *interp, const char *cmdName,
Jim_GetString(nameObjPtr, NULL),
varPtr) != JIM_OK)
{
- Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
- Jim_AppendStrings(interp, Jim_GetResult(interp),
- "static variable name \"",
- Jim_GetString(objPtr, NULL), "\"",
- " duplicated in statics list", NULL);
+ Jim_SetResultFormatted(interp,
+ "static variable name \"%#s\" duplicated in statics list",
+ nameObjPtr);
Jim_DecrRefCount(interp, initObjPtr);
Jim_Free(varPtr);
goto err;
}
} else {
- Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
- Jim_AppendStrings(interp, Jim_GetResult(interp),
- "too many fields in static specifier \"",
- objPtr, "\"", NULL);
+ Jim_SetResultFormatted(interp, "too many fields in static specifier \"%#s\"", objPtr);
goto err;
}
}
@@ -3345,10 +3333,7 @@ Jim_Cmd *Jim_GetCommand(Jim_Interp *interp, Jim_Obj *objPtr, int flags)
objPtr->internalRep.cmdValue.procEpoch != interp->procEpoch) &&
SetCommandFromAny(interp, objPtr) == JIM_ERR) {
if (flags & JIM_ERRMSG) {
- Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
- Jim_AppendStrings(interp, Jim_GetResult(interp),
- "invalid command name \"", objPtr->bytes, "\"",
- NULL);
+ Jim_SetResultFormatted(interp, "invalid command name \"%#s\"", objPtr);
}
return NULL;
}
@@ -3569,9 +3554,7 @@ int Jim_SetVariableLink(Jim_Interp *interp, Jim_Obj *nameObjPtr,
varName = Jim_GetString(nameObjPtr, &len);
if (Jim_FindHashEntry(&interp->framePtr->vars, varName)) {
- Jim_SetResultString(interp, "", -1);
- Jim_AppendStrings(interp, Jim_GetResult(interp),
- "variable \"", varName, "\" already exists", NULL);
+ Jim_SetResultFormatted(interp, "variable \"%#s\" already exists", nameObjPtr);
return JIM_ERR;
}
@@ -3612,22 +3595,15 @@ int Jim_SetVariableLink(Jim_Interp *interp, Jim_Obj *nameObjPtr,
Jim_Obj *Jim_GetVariable(Jim_Interp *interp, Jim_Obj *nameObjPtr, int flags)
{
int err;
+ Jim_Obj *objPtr = NULL;
/* All the rest is handled here */
if ((err = SetVariableFromAny(interp, nameObjPtr)) != JIM_OK) {
/* Check for [dict] syntax sugar. */
if (err == JIM_DICT_SUGAR)
return JimDictSugarGet(interp, nameObjPtr);
- if (flags & JIM_ERRMSG) {
- Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
- Jim_AppendStrings(interp, Jim_GetResult(interp),
- "can't read \"", nameObjPtr->bytes,
- "\": no such variable", NULL);
- }
- return NULL;
} else {
Jim_Var *varPtr;
- Jim_Obj *objPtr;
Jim_CallFrame *savedCallFrame;
varPtr = nameObjPtr->internalRep.varValue.varPtr;
@@ -3637,15 +3613,12 @@ Jim_Obj *Jim_GetVariable(Jim_Interp *interp, Jim_Obj *nameObjPtr, int flags)
savedCallFrame = interp->framePtr;
interp->framePtr = varPtr->linkFramePtr;
objPtr = Jim_GetVariable(interp, varPtr->objPtr, JIM_NONE);
- if (objPtr == NULL && flags & JIM_ERRMSG) {
- Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
- Jim_AppendStrings(interp, Jim_GetResult(interp),
- "can't read \"", nameObjPtr->bytes,
- "\": no such variable", NULL);
- }
interp->framePtr = savedCallFrame;
- return objPtr;
}
+ if (objPtr == NULL && (flags & JIM_ERRMSG)) {
+ Jim_SetResultFormatted(interp, "can't read \"%#s\": no such variable", nameObjPtr);
+ }
+ return objPtr;
}
Jim_Obj *Jim_GetGlobalVariable(Jim_Interp *interp, Jim_Obj *nameObjPtr,
@@ -3694,57 +3667,43 @@ int Jim_UnsetVariable(Jim_Interp *interp, Jim_Obj *nameObjPtr, int flags)
{
const char *name;
Jim_Var *varPtr;
- int err;
+ int retval;
- if ((err = SetVariableFromAny(interp, nameObjPtr)) != JIM_OK) {
- /* Check for [dict] syntax sugar. */
- if (err == JIM_DICT_SUGAR)
- if (JimDictSugarSet(interp, nameObjPtr, NULL) == JIM_OK)
- return JIM_OK;
- if (flags & JIM_ERRMSG) {
- Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
- Jim_AppendStrings(interp, Jim_GetResult(interp),
- "can't unset \"", nameObjPtr->bytes,
- "\": no such variable", NULL);
- }
- return JIM_ERR; /* var not found */
+ retval = SetVariableFromAny(interp, nameObjPtr);
+ if (retval == JIM_DICT_SUGAR) {
+ /* [dict] syntax sugar. */
+ return JimDictSugarSet(interp, nameObjPtr, NULL);
}
- varPtr = nameObjPtr->internalRep.varValue.varPtr;
- /* If it's a link call UnsetVariable recursively */
- if (varPtr->linkFramePtr) {
- int retval;
+ else if (retval == JIM_OK) {
+ varPtr = nameObjPtr->internalRep.varValue.varPtr;
- Jim_CallFrame *savedCallFrame;
+ /* If it's a link call UnsetVariable recursively */
+ if (varPtr->linkFramePtr) {
+ Jim_CallFrame *savedCallFrame;
- savedCallFrame = interp->framePtr;
- interp->framePtr = varPtr->linkFramePtr;
- retval = Jim_UnsetVariable(interp, varPtr->objPtr, JIM_NONE);
- interp->framePtr = savedCallFrame;
- if (retval != JIM_OK && flags & JIM_ERRMSG) {
- Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
- Jim_AppendStrings(interp, Jim_GetResult(interp),
- "can't unset \"", nameObjPtr->bytes,
- "\": no such variable", NULL);
- }
- return retval;
- } else {
- Jim_CallFrame *framePtr = interp->framePtr;
+ savedCallFrame = interp->framePtr;
+ interp->framePtr = varPtr->linkFramePtr;
+ retval = Jim_UnsetVariable(interp, varPtr->objPtr, JIM_NONE);
+ interp->framePtr = savedCallFrame;
+ } else {
+ Jim_CallFrame *framePtr = interp->framePtr;
- name = Jim_GetString(nameObjPtr, NULL);
- if (name[0] == ':' && name[1] == ':') {
- framePtr = interp->topFramePtr;
- if (Jim_DeleteHashEntry(&framePtr->vars, name + 2) != JIM_OK) {
- return JIM_ERR;
+ name = Jim_GetString(nameObjPtr, NULL);
+ if (name[0] == ':' && name[1] == ':') {
+ framePtr = interp->topFramePtr;
+ name += 2;
+ }
+ retval = Jim_DeleteHashEntry(&framePtr->vars, name);
+ if (retval == JIM_OK) {
+ /* Change the callframe id, invalidating var lookup caching */
+ JimChangeCallFrameId(interp, framePtr);
}
}
- else if (Jim_DeleteHashEntry(&framePtr->vars, name) != JIM_OK) {
- return JIM_ERR;
- }
- /* Change the callframe id, invalidating var lookup caching */
- JimChangeCallFrameId(interp, framePtr);
-
- return JIM_OK;
}
+ if (retval != JIM_OK && (flags & JIM_ERRMSG)) {
+ Jim_SetResultFormatted(interp, "can't unset \"%#s\": no such variable", nameObjPtr);
+ }
+ return retval;
}
/* ---------- Dict syntax sugar (similar to array Tcl syntax) -------------- */
@@ -3802,15 +3761,20 @@ static int JimDictSugarSet(Jim_Interp *interp, Jim_Obj *objPtr,
err = Jim_SetDictKeysVector(interp, objPtr->internalRep.dictSubstValue.varNameObjPtr,
&objPtr->internalRep.dictSubstValue.indexObjPtr, 1, valObjPtr);
- /* Don't keep an extra ref to the result */
if (err == JIM_OK) {
+ /* Don't keep an extra ref to the result */
Jim_SetEmptyResult(interp);
}
else {
+ if (!valObjPtr) {
+ /* Better error message for unset a(2) where a exists but a(2) doesn't */
+ if (Jim_GetVariable(interp, objPtr->internalRep.dictSubstValue.varNameObjPtr, JIM_NONE)) {
+ Jim_SetResultFormatted(interp, "can't unset \"%#s\": no such element in array", objPtr);
+ return err;
+ }
+ }
/* Make the error more informative and Tcl-compatible */
- Jim_SetResultString(interp, "", -1);
- Jim_AppendStrings(interp, Jim_GetResult(interp),
- "can't set \"", Jim_GetString(objPtr, NULL), "\": variable isn't array", NULL);
+ Jim_SetResultFormatted(interp, "can't %s \"%#s\": variable isn't array", (valObjPtr ? "set" : "unset"), objPtr);
}
return err;
}
@@ -3828,19 +3792,15 @@ static Jim_Obj *JimDictExpandArrayVariable(Jim_Interp *interp, Jim_Obj *varObjPt
ret = Jim_DictKey(interp, dictObjPtr, keyObjPtr, &resObjPtr, JIM_NONE);
if (ret != JIM_OK) {
- const char *msg;
-
resObjPtr = NULL;
if (ret < 0) {
- msg = "variable isn't array";
+ Jim_SetResultFormatted(interp,
+ "can't read \"%#s(%#s)\": variable isn't array", varObjPtr, keyObjPtr);
}
else {
- msg = "no such element in array";
+ Jim_SetResultFormatted(interp,
+ "can't read \"%#s(%#s)\": no such element in array", varObjPtr, keyObjPtr);
}
-
- Jim_SetResultString(interp, "", -1);
- Jim_AppendStrings(interp, Jim_GetResult(interp),
- "can't read \"", Jim_GetString(varObjPtr, NULL), "(", Jim_GetString(keyObjPtr, NULL), ")\": ", msg, NULL);
}
return resObjPtr;
@@ -4150,9 +4110,7 @@ int SetReferenceFromAny(Jim_Interp *interp, Jim_Obj *objPtr)
/* Check if the reference really exists! */
he = Jim_FindHashEntry(&interp->references, &wideValue);
if (he == NULL) {
- Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
- Jim_AppendStrings(interp, Jim_GetResult(interp),
- "Invalid reference ID \"", str, "\"", NULL);
+ Jim_SetResultFormatted(interp, "invalid reference id \"%#s\"", objPtr);
return JIM_ERR;
}
refPtr = he->val;
@@ -4164,9 +4122,7 @@ int SetReferenceFromAny(Jim_Interp *interp, Jim_Obj *objPtr)
return JIM_OK;
badformat:
- Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
- Jim_AppendStrings(interp, Jim_GetResult(interp),
- "expected reference but got \"", str, "\"", NULL);
+ Jim_SetResultFormatted(interp, "expected reference but got \"%#s\"", objPtr);
return JIM_ERR;
}
@@ -4613,9 +4569,7 @@ int Jim_GetCallFrameByLevel(Jim_Interp *interp, Jim_Obj *levelObjPtr,
*framePtrPtr = framePtr;
return JIM_OK;
badlevel:
- Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
- Jim_AppendStrings(interp, Jim_GetResult(interp),
- "bad level \"", str, "\"", NULL);
+ Jim_SetResultFormatted(interp, "bad level \"%s\"", str);
return JIM_ERR;
}
@@ -4646,9 +4600,7 @@ static int JimGetCallFrameByInteger(Jim_Interp *interp, Jim_Obj *levelObjPtr,
*framePtrPtr = framePtr;
return JIM_OK;
badlevel:
- Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
- Jim_AppendStrings(interp, Jim_GetResult(interp),
- "bad level \"", Jim_GetString(levelObjPtr, NULL), "\"", NULL);
+ Jim_SetResultFormatted(interp, "bad level \"%#s\"", levelObjPtr);
return JIM_ERR;
}
@@ -4855,9 +4807,7 @@ int SetIntFromAny(Jim_Interp *interp, Jim_Obj *objPtr, int flags)
/* Try to convert into a jim_wide */
if (Jim_StringToWide(str, &wideValue, 0) != JIM_OK) {
if (flags & JIM_ERRMSG) {
- Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
- Jim_AppendStrings(interp, Jim_GetResult(interp),
- "expected integer but got \"", str, "\"", NULL);
+ Jim_SetResultFormatted(interp, "expected integer but got \"%#s\"", objPtr);
}
return JIM_ERR;
}
@@ -4997,9 +4947,7 @@ int SetDoubleFromAny(Jim_Interp *interp, Jim_Obj *objPtr)
else {
/* Try to convert into a double */
if (Jim_StringToDouble(str, &doubleValue) != JIM_OK) {
- Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
- Jim_AppendStrings(interp, Jim_GetResult(interp),
- "expected number but got '", str, "'", NULL);
+ Jim_SetResultFormatted(interp, "expected number but got \"%#s\"", objPtr);
return JIM_ERR;
}
/* Free the old internal repr and set the new one. */
@@ -5994,6 +5942,7 @@ static int SetDictFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr)
Jim_FreeNewObj(interp, objv[0]);
objPtr->typePtr = NULL;
Jim_FreeHashTable(ht);
+ Jim_Free(ht);
#ifdef JIM_OPTIMIZATION
badlist:
#endif
@@ -6082,10 +6031,7 @@ int Jim_DictKey(Jim_Interp *interp, Jim_Obj *dictPtr, Jim_Obj *keyPtr,
ht = dictPtr->internalRep.ptr;
if ((he = Jim_FindHashEntry(ht, keyPtr)) == NULL) {
if (flags & JIM_ERRMSG) {
- Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
- Jim_AppendStrings(interp, Jim_GetResult(interp),
- "key \"", Jim_GetString(keyPtr, NULL),
- "\" not found in dictionary", NULL);
+ Jim_SetResultFormatted(interp, "key \"%#s\" not found in dictionary", keyPtr);
}
return JIM_ERR;
}
@@ -6200,9 +6146,9 @@ int Jim_SetDictKeysVector(Jim_Interp *interp, Jim_Obj *varNamePtr,
DictAddElement(interp, dictObjPtr, keyv[i], objPtr);
}
}
- if (Jim_DictAddElement(interp, objPtr, keyv[keyc-1], newObjPtr)
- != JIM_OK)
+ if (Jim_DictAddElement(interp, objPtr, keyv[keyc-1], newObjPtr) != JIM_OK) {
goto err;
+ }
Jim_InvalidateStringRep(objPtr);
Jim_InvalidateStringRep(varObjPtr);
if (Jim_SetVariable(interp, varNamePtr, varObjPtr) != JIM_OK)
@@ -6307,10 +6253,7 @@ int SetIndexFromAny(Jim_Interp *interp, Jim_Obj *objPtr)
return JIM_OK;
badindex:
- Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
- Jim_AppendStrings(interp, Jim_GetResult(interp),
- "bad index \"", Jim_GetString(objPtr, NULL), "\": "
- "must be integer?[+-]integer? or end?[+-]integer?", NULL);
+ Jim_SetResultFormatted(interp, "bad index \"%#s\": must be integer?[+-]integer? or end?[+-]integer?", objPtr);
return JIM_ERR;
}
@@ -6382,10 +6325,7 @@ int SetReturnCodeFromAny(Jim_Interp *interp, Jim_Obj *objPtr)
if (JimGetWideNoErr(interp, objPtr, &wideValue) != JIM_ERR)
returnCode = (int) wideValue;
else if (Jim_GetEnum(interp, objPtr, jimReturnCodes, &returnCode, NULL, JIM_NONE) != JIM_OK) {
- Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
- Jim_AppendStrings(interp, Jim_GetResult(interp),
- "expected return code but got '", Jim_GetString(objPtr, NULL), "'",
- NULL);
+ Jim_SetResultFormatted(interp, "expected return code but got \"%#s\"", objPtr);
return JIM_ERR;
}
/* Free the old internal repr and set the new one. */
@@ -7689,14 +7629,12 @@ int SetExprFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr)
if (JimParseExpression(&parser) != JIM_OK) {
ScriptTokenListFree(&tokenlist);
invalidexpr:
- Jim_SetResultString(interp, "syntax error in expression: ", -1);
- Jim_AppendStrings(interp, Jim_GetResult(interp), exprText, NULL);
+ Jim_SetResultFormatted(interp, "syntax error in expression: \"%#s\"", objPtr);
expr = NULL;
goto err;
}
ScriptAddToken(&tokenlist, parser.tstart, parser.tend - parser.tstart + 1, parser.tt, parser.tline);
- //printf("ExprAddToken type=%s/line=%d/'%.*s'\n", tt_name(parser.tt), parser.tline, (int)(parser.tend - parser.tstart + 1), parser.tstart);
}
/* Now create the expression bytecode from the tokenlist */
@@ -7878,7 +7816,6 @@ int Jim_EvalExpression(Jim_Interp *interp, Jim_Obj *exprObjPtr,
}
*exprResultPtrPtr = cmpRes ? interp->trueObj : interp->falseObj;
Jim_IncrRefCount(*exprResultPtrPtr);
- //printf("optimised: %s\n", Jim_GetString(exprObjPtr, NULL));
return JIM_OK;
}
}
@@ -7887,8 +7824,6 @@ int Jim_EvalExpression(Jim_Interp *interp, Jim_Obj *exprObjPtr,
}
break;
}
-
- //printf("no optimisation for: %s\n", Jim_GetString(exprObjPtr, NULL));
}
#endif
@@ -7995,26 +7930,19 @@ int Jim_GetBoolFromExpr(Jim_Interp *interp, Jim_Obj *exprObjPtr, int *boolPtr)
if (retcode != JIM_OK)
return retcode;
- if (exprResultPtr == interp->trueObj) {
- *boolPtr = 1;
- }
- else if (exprResultPtr == interp->falseObj) {
- *boolPtr = 0;
- }
- else {
- if (JimGetWideNoErr(interp, exprResultPtr, &wideValue) != JIM_OK) {
- if (Jim_GetDouble(interp, exprResultPtr, &doubleValue) != JIM_OK)
- {
- Jim_DecrRefCount(interp, exprResultPtr);
- return JIM_ERR;
- } else {
- Jim_DecrRefCount(interp, exprResultPtr);
- *boolPtr = doubleValue != 0;
- return JIM_OK;
- }
+ if (JimGetWideNoErr(interp, exprResultPtr, &wideValue) != JIM_OK) {
+ if (Jim_GetDouble(interp, exprResultPtr, &doubleValue) != JIM_OK)
+ {
+ Jim_DecrRefCount(interp, exprResultPtr);
+ return JIM_ERR;
+ } else {
+ Jim_DecrRefCount(interp, exprResultPtr);
+ *boolPtr = doubleValue != 0;
+ return JIM_OK;
}
- *boolPtr = wideValue != 0;
}
+ *boolPtr = wideValue != 0;
+
Jim_DecrRefCount(interp, exprResultPtr);
return JIM_OK;
}
@@ -9140,20 +9068,16 @@ int JimCallProcedure(Jim_Interp *interp, Jim_Cmd *cmd, int argc,
/* Check arity */
if (argc - 1 < cmd->leftArity + cmd->rightArity ||
(!cmd->args && argc - 1 > cmd->leftArity + cmd->rightArity + cmd->optionalArgs)) {
- const char *argList = Jim_GetString(cmd->argListObjPtr, NULL);
- Jim_Obj *objPtr = Jim_NewEmptyStringObj(interp);
- Jim_AppendStrings(interp, objPtr,
- "wrong # args: should be \"", Jim_GetString(procname, NULL),
- (*argList) ? " " : "", argList, "\"", NULL);
- Jim_SetResult(interp, objPtr);
- goto err;
+ Jim_SetResultFormatted(interp, "wrong # args: should be \"%#s%s%#s\"", procname,
+ Jim_ListLength(interp, cmd->argListObjPtr) ? " " : "", cmd->argListObjPtr);
+ return JIM_ERR;
}
/* Check if there are too nested calls */
if (interp->numLevels == interp->maxNestingDepth) {
Jim_SetResultString(interp,
"Too many nested calls. Infinite recursion?", -1);
- goto err;
+ return JIM_ERR;
}
/* Create a new callframe */
@@ -9261,7 +9185,6 @@ int JimCallProcedure(Jim_Interp *interp, Jim_Cmd *cmd, int argc,
interp->returnCode = JIM_OK;
}
if (retcode == JIM_ERR) {
-err:
retcode = JIM_ERR_ADDSTACK;
Jim_DecrRefCount(interp, interp->errorProc);
interp->errorProc = procname;
@@ -9354,12 +9277,10 @@ int Jim_EvalFile(Jim_Interp *interp, const char *filename)
Jim_Obj *prevScriptObj;
struct stat sb;
int retcode;
+ int readlen;
if (stat(filename, &sb) != 0 || (fp = fopen(filename, "r")) == NULL) {
- Jim_SetResultString(interp, "", 0);
- Jim_AppendStrings(interp, Jim_GetResult(interp),
- "Error loading script \"", filename, "\"",
- " err: ", strerror(errno), NULL);
+ Jim_SetResultFormatted(interp, "couldn't read file \"%s\": %s", filename, strerror(errno));
return JIM_ERR_ADDSTACK;
}
if (sb.st_size == 0) {
@@ -9368,7 +9289,9 @@ int Jim_EvalFile(Jim_Interp *interp, const char *filename)
}
buf = Jim_Alloc(sb.st_size + 1);
- if (buf == 0 || fread(buf, sb.st_size, 1, fp) != 1) {
+ readlen = fread(buf, sb.st_size, 1, fp);
+ fclose(fp);
+ if (readlen != 1) {
Jim_Free(buf);
return JIM_ERR_ADDSTACK;
}
@@ -9703,6 +9626,7 @@ static Jim_Obj *JimCommandsList(Jim_Interp *interp, Jim_Obj *patternObjPtr, int
return listObjPtr;
}
+/* Keep this in order */
#define JIM_VARLIST_GLOBALS 0
#define JIM_VARLIST_LOCALS 1
#define JIM_VARLIST_VARS 2
@@ -9753,10 +9677,7 @@ static int JimInfoLevel(Jim_Interp *interp, Jim_Obj *levelObjPtr,
return JIM_ERR;
/* No proc call at toplevel callframe */
if (targetCallFrame == interp->topFramePtr) {
- Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
- Jim_AppendStrings(interp, Jim_GetResult(interp),
- "bad level \"",
- Jim_GetString(levelObjPtr, NULL), "\"", NULL);
+ Jim_SetResultFormatted(interp, "bad level \"%#s\"", levelObjPtr);
return JIM_ERR;
}
*objPtrPtr = Jim_NewListObj(interp,
@@ -9814,7 +9735,7 @@ static int Jim_AddMulHelper(Jim_Interp *interp, int argc,
else
res *= wideValue;
}
- Jim_SetResult(interp, Jim_NewIntObj(interp, res));
+ Jim_SetResultInt(interp, res);
return JIM_OK;
trydouble:
doubleRes = (double) res;
@@ -9861,7 +9782,7 @@ static int Jim_SubDivHelper(Jim_Interp *interp, int argc,
}
if (op == JIM_EXPROP_SUB) {
res = -wideValue;
- Jim_SetResult(interp, Jim_NewIntObj(interp, res));
+ Jim_SetResultInt(interp, res);
} else {
doubleRes = 1.0/wideValue;
Jim_SetResult(interp, Jim_NewDoubleObj(interp,
@@ -9888,7 +9809,7 @@ static int Jim_SubDivHelper(Jim_Interp *interp, int argc,
else
res /= wideValue;
}
- Jim_SetResult(interp, Jim_NewIntObj(interp, res));
+ Jim_SetResultInt(interp, res);
return JIM_OK;
trydouble:
for (;i < argc; i++) {
@@ -10314,8 +10235,6 @@ static int JimForeachMapHelper(Jim_Interp *interp, int argc,
++varIdx; /* Next variable */
continue;
}
- Jim_SetResultString(interp, "couldn't set loop variable: ", -1);
- Jim_AppendStrings(interp, Jim_GetResult(interp), Jim_GetString(varName, NULL), NULL);
goto err;
}
}
@@ -10436,16 +10355,22 @@ int Jim_CommandMatchObj(Jim_Interp *interp, Jim_Obj *commandObj, Jim_Obj *patter
return eq;
}
-enum {SWITCH_EXACT, SWITCH_GLOB, SWITCH_RE, SWITCH_CMD, SWITCH_UNKNOWN};
+enum {SWITCH_EXACT, SWITCH_GLOB, SWITCH_RE, SWITCH_CMD };
/* [switch] */
static int Jim_SwitchCoreCommand(Jim_Interp *interp, int argc,
Jim_Obj *const *argv)
{
- int retcode = JIM_ERR, matchOpt = SWITCH_EXACT, opt=1, patCount, i;
+ int matchOpt = SWITCH_EXACT, opt=1, patCount, i;
Jim_Obj *command = 0, *const *caseList = 0, *strObj;
Jim_Obj *script = 0;
- if (argc < 3) goto wrongnumargs;
+ if (argc < 3) {
+wrongnumargs:
+ Jim_WrongNumArgs(interp, 1, argv, "?options? string "
+ "pattern body ... ?default body? or "
+ "{pattern body ?pattern body ...?}");
+ return JIM_ERR;
+ }
for (opt=1; opt < argc; ++opt) {
const char *option = Jim_GetString(argv[opt], 0);
if (*option != '-') break;
@@ -10457,11 +10382,8 @@ static int Jim_SwitchCoreCommand(Jim_Interp *interp, int argc,
if ((argc - opt) < 2) goto wrongnumargs;
command = argv[++opt];
} else {
- Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
- Jim_AppendStrings(interp, Jim_GetResult(interp),
- "bad option \"", option, "\": must be -exact, -glob, "
- "-regexp, -command procname or --", 0);
- goto err;
+ Jim_SetResultFormatted(interp, "bad option \"%#s\": must be -exact, -glob, -regexp, -command procname or --", argv[opt]);
+ return JIM_ERR;
}
if ((argc - opt) < 2) goto wrongnumargs;
}
@@ -10503,18 +10425,12 @@ static int Jim_SwitchCoreCommand(Jim_Interp *interp, int argc,
}
/* command is here already decref'd */
if (rc < 0) {
- retcode = -rc;
- goto err;
+ return -rc;
}
if (rc)
script = caseList[i+1];
break;
}
- default:
- Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
- Jim_AppendStrings(interp, Jim_GetResult(interp),
- "internal error: no such option implemented", 0);
- goto err;
}
} else {
script = caseList[i+1];
@@ -10524,23 +10440,14 @@ static int Jim_SwitchCoreCommand(Jim_Interp *interp, int argc,
i += 2)
script = caseList[i+1];
if (script && Jim_CompareStringImmediate(interp, script, "-")) {
- Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
- Jim_AppendStrings(interp, Jim_GetResult(interp),
- "no body specified for pattern \"",
- Jim_GetString(caseList[i-2], 0), "\"", 0);
- goto err;
+ Jim_SetResultFormatted(interp, "no body specified for pattern \"%#s\"", caseList[i-2]);
+ return JIM_ERR;
}
- retcode = JIM_OK;
Jim_SetEmptyResult(interp);
- if (script != 0)
- retcode = Jim_EvalObj(interp, script);
- return retcode;
-wrongnumargs:
- Jim_WrongNumArgs(interp, 1, argv, "?options? string "
- "pattern body ... ?default body? or "
- "{pattern body ?pattern body ...?}");
-err:
- return retcode;
+ if (script) {
+ return Jim_EvalObj(interp, script);
+ }
+ return JIM_OK;
}
/* [list] */
@@ -10728,7 +10635,7 @@ wrongargs:
else {
/* No match */
if (opt_bool) {
- Jim_SetResultInt(interp, opt_not);
+ Jim_SetResultBool(interp, opt_not);
}
else if (!opt_inline) {
Jim_SetResultInt(interp, -1);
@@ -11013,7 +10920,7 @@ static int Jim_DebugCoreCommand(Jim_Interp *interp, int argc,
Jim_WrongNumArgs(interp, 2, argv, "object");
return JIM_ERR;
}
- Jim_SetResult(interp, Jim_NewIntObj(interp, argv[2]->refCount));
+ Jim_SetResultInt(interp, argv[2]->refCount);
return JIM_OK;
} else if (option == OPT_OBJCOUNT) {
int freeobj = 0, liveobj = 0;
@@ -11082,7 +10989,7 @@ static int Jim_DebugCoreCommand(Jim_Interp *interp, int argc,
return JIM_ERR;
}
script = Jim_GetScript(interp, argv[2]);
- Jim_SetResult(interp, Jim_NewIntObj(interp, script->len));
+ Jim_SetResultInt(interp, script->len);
return JIM_OK;
} else if (option == OPT_EXPRLEN) {
ExprByteCode *expr;
@@ -11093,7 +11000,7 @@ static int Jim_DebugCoreCommand(Jim_Interp *interp, int argc,
expr = Jim_GetExpression(interp, argv[2]);
if (expr == NULL)
return JIM_ERR;
- Jim_SetResult(interp, Jim_NewIntObj(interp, expr->len));
+ Jim_SetResultInt(interp, expr->len);
return JIM_OK;
} else if (option == OPT_EXPRBC) {
Jim_Obj *objPtr;
@@ -11572,7 +11479,7 @@ static int Jim_StringCoreCommand(Jim_Interp *interp, int argc,
Jim_SetResultInt(interp, Jim_StringCompareObj(argv[2], argv[3], !opt_case));
}
else {
- Jim_SetResultInt(interp, Jim_StringEqObj(argv[2], argv[3], !opt_case));
+ Jim_SetResultBool(interp, Jim_StringEqObj(argv[2], argv[3], !opt_case));
}
return JIM_OK;
@@ -11586,7 +11493,7 @@ static int Jim_StringCoreCommand(Jim_Interp *interp, int argc,
if (opt_case == 0) {
argv++;
}
- Jim_SetResultInt(interp, Jim_StringMatchObj(argv[2], argv[3], !opt_case));
+ Jim_SetResultBool(interp, Jim_StringMatchObj(argv[2], argv[3], !opt_case));
return JIM_OK;
case OPT_MAP: {
@@ -11893,7 +11800,7 @@ wrongargs:
!= JIM_OK)
return JIM_ERR;
}
- Jim_SetResult(interp, Jim_NewIntObj(interp, exitCode));
+ Jim_SetResultInt(interp, exitCode);
return JIM_OK;
}
@@ -11958,7 +11865,7 @@ static int Jim_CollectCoreCommand(Jim_Interp *interp, int argc,
Jim_WrongNumArgs(interp, 1, argv, "");
return JIM_ERR;
}
- Jim_SetResult(interp, Jim_NewIntObj(interp, Jim_Collect(interp)));
+ Jim_SetResultInt(interp, Jim_Collect(interp));
return JIM_OK;
}
@@ -12001,10 +11908,7 @@ static int Jim_RenameCoreCommand(Jim_Interp *interp, int argc,
oldName = Jim_GetString(argv[1], NULL);
newName = Jim_GetString(argv[2], NULL);
if (Jim_RenameCommand(interp, oldName, newName) != JIM_OK) {
- Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
- Jim_AppendStrings(interp, Jim_GetResult(interp),
- "can't rename \"", oldName, "\": ",
- "command doesn't exist", NULL);
+ Jim_SetResultFormatted(interp, "can't rename \"%#s\": command doesn't exist", argv[1]);
return JIM_ERR;
}
return JIM_OK;
@@ -12014,6 +11918,7 @@ static int Jim_RenameCoreCommand(Jim_Interp *interp, int argc,
static int Jim_DictCoreCommand(Jim_Interp *interp, int argc,
Jim_Obj *const *argv)
{
+ Jim_Obj *objPtr;
int option;
const char *options[] = {
"create", "get", "set", "unset", "exists", NULL
@@ -12027,61 +11932,48 @@ static int Jim_DictCoreCommand(Jim_Interp *interp, int argc,
return JIM_ERR;
}
- if (Jim_GetEnum(interp, argv[1], options, &option, "subcommand",
- JIM_ERRMSG) != JIM_OK)
+ if (Jim_GetEnum(interp, argv[1], options, &option, "subcommand", JIM_ERRMSG) != JIM_OK) {
return JIM_ERR;
+ }
- if (option == OPT_CREATE) {
- Jim_Obj *objPtr;
+ switch (option) {
+ case OPT_GET:
+ if (Jim_DictKeysVector(interp, argv[2], argv+3, argc-3, &objPtr, JIM_ERRMSG) != JIM_OK) {
+ return JIM_ERR;
+ }
+ Jim_SetResult(interp, objPtr);
+ return JIM_OK;
- if (argc % 2) {
- Jim_WrongNumArgs(interp, 2, argv, "?key value ...?");
- return JIM_ERR;
- }
- objPtr = Jim_NewDictObj(interp, argv+2, argc-2);
- Jim_SetResult(interp, objPtr);
- return JIM_OK;
- } else if (option == OPT_GET) {
- Jim_Obj *objPtr;
+ case OPT_SET:
+ if (argc < 5) {
+ Jim_WrongNumArgs(interp, 2, argv, "varName key ?key ...? value");
+ return JIM_ERR;
+ }
+ return Jim_SetDictKeysVector(interp, argv[2], argv+3, argc-4, argv[argc-1]);
- if (Jim_DictKeysVector(interp, argv[2], argv+3, argc-3, &objPtr,
- JIM_ERRMSG) != JIM_OK)
- return JIM_ERR;
- Jim_SetResult(interp, objPtr);
- return JIM_OK;
- } else if (option == OPT_SET) {
- if (argc < 5) {
- Jim_WrongNumArgs(interp, 2, argv, "varName key ?key ...? value");
- return JIM_ERR;
- }
- return Jim_SetDictKeysVector(interp, argv[2], argv+3, argc-4,
- argv[argc-1]);
- } else if (option == OPT_UNSET) {
- if (argc < 4) {
- Jim_WrongNumArgs(interp, 2, argv, "varName key ?key ...?");
- return JIM_ERR;
- }
- return Jim_SetDictKeysVector(interp, argv[2], argv+3, argc-3,
- NULL);
- } else if (option == OPT_EXIST) {
- Jim_Obj *objPtr;
- int exists;
+ case OPT_EXIST:
+ Jim_SetResultBool(interp, Jim_DictKeysVector(interp, argv[2], argv+3, argc-3, &objPtr, JIM_ERRMSG) == JIM_OK);
+ return JIM_OK;
- if (Jim_DictKeysVector(interp, argv[2], argv+3, argc-3, &objPtr,
- JIM_ERRMSG) == JIM_OK)
- exists = 1;
- else
- exists = 0;
- Jim_SetResult(interp, Jim_NewIntObj(interp, exists));
- return JIM_OK;
- } else {
- Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
- Jim_AppendStrings(interp, Jim_GetResult(interp),
- "bad option \"", Jim_GetString(argv[1], NULL), "\":",
- " must be create, get, set", NULL);
- return JIM_ERR;
+ case OPT_UNSET:
+ if (argc < 4) {
+ Jim_WrongNumArgs(interp, 2, argv, "varName key ?key ...?");
+ return JIM_ERR;
+ }
+ return Jim_SetDictKeysVector(interp, argv[2], argv+3, argc-3, NULL);
+
+ case OPT_CREATE:
+ if (argc % 2) {
+ Jim_WrongNumArgs(interp, 2, argv, "?key value ...?");
+ return JIM_ERR;
+ }
+ objPtr = Jim_NewDictObj(interp, argv+2, argc-2);
+ Jim_SetResult(interp, objPtr);
+ return JIM_OK;
+
+ default:
+ abort();
}
- return JIM_OK;
}
/* [subst] */
@@ -12123,7 +12015,10 @@ static int Jim_SubstCoreCommand(Jim_Interp *interp, int argc,
static int Jim_InfoCoreCommand(Jim_Interp *interp, int argc,
Jim_Obj *const *argv)
{
- int cmd, result = JIM_OK;
+ int cmd;
+ Jim_Obj *objPtr;
+ int mode = 0;
+
static const char *commands[] = {
"body", "commands", "procs", "exists", "globals", "level", "locals",
"vars", "version", "patchlevel", "complete", "args", "hostname",
@@ -12142,143 +12037,161 @@ static int Jim_InfoCoreCommand(Jim_Interp *interp, int argc,
!= JIM_OK) {
return JIM_ERR;
}
-
- if (cmd == INFO_COMMANDS || cmd == INFO_PROCS) {
- if (argc != 2 && argc != 3) {
- Jim_WrongNumArgs(interp, 2, argv, "?pattern?");
- return JIM_ERR;
- }
- Jim_SetResult(interp, JimCommandsList(interp, (argc == 3) ? argv[2] : NULL, (cmd == INFO_PROCS)));
- } else if (cmd == INFO_EXISTS) {
- Jim_Obj *exists;
- if (argc != 3) {
- Jim_WrongNumArgs(interp, 2, argv, "varName");
- return JIM_ERR;
- }
- exists = Jim_GetVariable(interp, argv[2], 0);
- Jim_SetResult(interp, Jim_NewIntObj(interp, exists != 0));
- } else if (cmd == INFO_SCRIPT) {
- ScriptObj *script;
- if (argc != 2) {
- Jim_WrongNumArgs(interp, 2, argv, "");
- return JIM_ERR;
- }
- script = Jim_GetScript(interp, interp->currentScriptObj);
- Jim_SetResultString(interp, script->fileName, -1);
- } else if (cmd == INFO_SOURCE) {
- const char *filename = "";
- int line = 0;
- Jim_Obj *resObjPtr;
- if (argc != 3) {
- Jim_WrongNumArgs(interp, 2, argv, "source");
- return JIM_ERR;
+ /* Test for the the most common commands first, just in case it makes a difference */
+ switch (cmd) {
+ case INFO_EXISTS: {
+ if (argc != 3) {
+ Jim_WrongNumArgs(interp, 2, argv, "varName");
+ return JIM_ERR;
+ }
+ Jim_SetResultBool(interp, Jim_GetVariable(interp, argv[2], 0) != NULL);
+ break;
}
- if (argv[2]->typePtr == &sourceObjType) {
- filename = argv[2]->internalRep.sourceValue.fileName;
- line = argv[2]->internalRep.sourceValue.lineNumber;
- }
- else if (argv[2]->typePtr == &scriptObjType) {
- ScriptObj *script = Jim_GetScript(interp, argv[2]);
- filename = script->fileName;
- if (script->token) {
- line = script->token->linenr;
- }
- }
- resObjPtr = Jim_NewListObj(interp, NULL, 0);
- Jim_ListAppendElement(interp, resObjPtr, Jim_NewStringObj(interp, filename, -1));
- Jim_ListAppendElement(interp, resObjPtr, Jim_NewIntObj(interp, line));
- Jim_SetResult(interp, resObjPtr);
- } else if (cmd == INFO_STACKTRACE) {
- Jim_SetResult(interp, interp->stackTrace);
- } else if (cmd == INFO_GLOBALS || cmd == INFO_LOCALS || cmd == INFO_VARS) {
- int mode;
- switch (cmd) {
- case INFO_GLOBALS: mode = JIM_VARLIST_GLOBALS; break;
- case INFO_LOCALS: mode = JIM_VARLIST_LOCALS; break;
- case INFO_VARS: mode = JIM_VARLIST_VARS; break;
- default: mode = 0; /* avoid warning */; break;
- }
- if (argc != 2 && argc != 3) {
- Jim_WrongNumArgs(interp, 2, argv, "?pattern?");
- return JIM_ERR;
+
+ case INFO_COMMANDS:
+ case INFO_PROCS:
+ if (argc != 2 && argc != 3) {
+ Jim_WrongNumArgs(interp, 2, argv, "?pattern?");
+ return JIM_ERR;
+ }
+ Jim_SetResult(interp, JimCommandsList(interp, (argc == 3) ? argv[2] : NULL, (cmd == INFO_PROCS)));
+ break;
+
+ case INFO_VARS:
+ mode++; /* JIM_VARLIST_VARS */
+ case INFO_LOCALS:
+ mode++; /* JIM_VARLIST_LOCALS */
+ case INFO_GLOBALS:
+ /* mode 0 => JIM_VARLIST_GLOBALS */
+ if (argc != 2 && argc != 3) {
+ Jim_WrongNumArgs(interp, 2, argv, "?pattern?");
+ return JIM_ERR;
+ }
+ Jim_SetResult(interp,JimVariablesList(interp, argc == 3 ? argv[2] : NULL, mode));
+ break;
+
+ case INFO_SCRIPT:
+ if (argc != 2) {
+ Jim_WrongNumArgs(interp, 2, argv, "");
+ return JIM_ERR;
+ }
+ Jim_SetResultString(interp, Jim_GetScript(interp, interp->currentScriptObj)->fileName, -1);
+ break;
+
+ case INFO_SOURCE: {
+ const char *filename = "";
+ int line = 0;
+ Jim_Obj *resObjPtr;
+
+ if (argc != 3) {
+ Jim_WrongNumArgs(interp, 2, argv, "source");
+ return JIM_ERR;
+ }
+ if (argv[2]->typePtr == &sourceObjType) {
+ filename = argv[2]->internalRep.sourceValue.fileName;
+ line = argv[2]->internalRep.sourceValue.lineNumber;
+ }
+ else if (argv[2]->typePtr == &scriptObjType) {
+ ScriptObj *script = Jim_GetScript(interp, argv[2]);
+ filename = script->fileName;
+ if (script->token) {
+ line = script->token->linenr;
+ }
+ }
+ resObjPtr = Jim_NewListObj(interp, NULL, 0);
+ Jim_ListAppendElement(interp, resObjPtr, Jim_NewStringObj(interp, filename, -1));
+ Jim_ListAppendElement(interp, resObjPtr, Jim_NewIntObj(interp, line));
+ Jim_SetResult(interp, resObjPtr);
+ break;
}
- if (argc == 3)
- Jim_SetResult(interp,JimVariablesList(interp, argv[2], mode));
- else
- Jim_SetResult(interp, JimVariablesList(interp, NULL, mode));
- } else if (cmd == INFO_LEVEL) {
- Jim_Obj *objPtr;
- switch (argc) {
- case 2:
- Jim_SetResult(interp,
- Jim_NewIntObj(interp, interp->numLevels));
- break;
- case 3:
- if (JimInfoLevel(interp, argv[2], &objPtr) != JIM_OK)
+
+ case INFO_STACKTRACE:
+ Jim_SetResult(interp, interp->stackTrace);
+ break;
+
+ case INFO_LEVEL:
+ switch (argc) {
+ case 2:
+ Jim_SetResultInt(interp, interp->numLevels);
+ break;
+
+ case 3:
+ if (JimInfoLevel(interp, argv[2], &objPtr) != JIM_OK) {
+ return JIM_ERR;
+ }
+ Jim_SetResult(interp, objPtr);
+ break;
+
+ default:
+ Jim_WrongNumArgs(interp, 2, argv, "?levelNum?");
return JIM_ERR;
- Jim_SetResult(interp, objPtr);
- break;
- default:
- Jim_WrongNumArgs(interp, 2, argv, "?levelNum?");
+ }
+ break;
+
+ case INFO_BODY:
+ case INFO_ARGS: {
+ Jim_Cmd *cmdPtr;
+
+ if (argc != 3) {
+ Jim_WrongNumArgs(interp, 2, argv, "procname");
return JIM_ERR;
+ }
+ if ((cmdPtr = Jim_GetCommand(interp, argv[2], JIM_ERRMSG)) == NULL) {
+ return JIM_ERR;
+ }
+ if (cmdPtr->cmdProc != NULL) {
+ Jim_SetResultFormatted(interp, "command \"%#s\" is not a procedure", argv[2]);
+ return JIM_ERR;
+ }
+ Jim_SetResult(interp, cmd == INFO_BODY ? cmdPtr->bodyObjPtr : cmdPtr->argListObjPtr);
+ break;
}
- } else if (cmd == INFO_BODY || cmd == INFO_ARGS) {
- Jim_Cmd *cmdPtr;
- if (argc != 3) {
- Jim_WrongNumArgs(interp, 2, argv, "procname");
- return JIM_ERR;
- }
- if ((cmdPtr = Jim_GetCommand(interp, argv[2], JIM_ERRMSG)) == NULL)
- return JIM_ERR;
- if (cmdPtr->cmdProc != NULL) {
- Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
- Jim_AppendStrings(interp, Jim_GetResult(interp),
- "command \"", Jim_GetString(argv[2], NULL),
- "\" is not a procedure", NULL);
- return JIM_ERR;
+ case INFO_VERSION:
+ case INFO_PATCHLEVEL: {
+ char buf[(JIM_INTEGER_SPACE * 2) + 1];
+ sprintf(buf, "%d.%d",
+ JIM_VERSION / 100, JIM_VERSION % 100);
+ Jim_SetResultString(interp, buf, -1);
+ break;
}
- if (cmd == INFO_BODY)
- Jim_SetResult(interp, cmdPtr->bodyObjPtr);
- else
- Jim_SetResult(interp, cmdPtr->argListObjPtr);
- } else if (cmd == INFO_VERSION || cmd == INFO_PATCHLEVEL) {
- char buf[(JIM_INTEGER_SPACE * 2) + 1];
- sprintf(buf, "%d.%d",
- JIM_VERSION / 100, JIM_VERSION % 100);
- Jim_SetResultString(interp, buf, -1);
- } else if (cmd == INFO_COMPLETE) {
- const char *s;
- int len;
- if (argc != 3) {
- Jim_WrongNumArgs(interp, 2, argv, "script");
- return JIM_ERR;
- }
- s = Jim_GetString(argv[2], &len);
- Jim_SetResult(interp,
- Jim_NewIntObj(interp, Jim_ScriptIsComplete(s, len, NULL)));
- } else if (cmd == INFO_HOSTNAME) {
- /* Redirect to os.gethostname if it exists */
- return Jim_Eval(interp, "os.gethostname");
- } else if (cmd == INFO_NAMEOFEXECUTABLE) {
- /* Redirect to Tcl proc */
- return Jim_Eval(interp, "info_nameofexecutable");
- }
- else if (cmd == INFO_RETURNCODES) {
- Jim_Obj *listObjPtr = Jim_NewListObj(interp, NULL, 0);
- int i;
+ case INFO_COMPLETE:
+ if (argc != 3) {
+ Jim_WrongNumArgs(interp, 2, argv, "script");
+ return JIM_ERR;
+ }
+ else {
+ int len;
+ const char *s = Jim_GetString(argv[2], &len);
- for (i = 0; jimReturnCodes[i]; i++) {
- Jim_ListAppendElement(interp, listObjPtr, Jim_NewIntObj(interp, i));
- Jim_ListAppendElement(interp, listObjPtr, Jim_NewStringObj(interp, jimReturnCodes[i], -1));
- }
+ Jim_SetResultBool(interp, Jim_ScriptIsComplete(s, len, NULL));
+ }
+ break;
- Jim_SetResult(interp, listObjPtr);
- return JIM_OK;
+ case INFO_HOSTNAME:
+ /* Redirect to os.gethostname if it exists */
+ return Jim_Eval(interp, "os.gethostname");
+
+ case INFO_NAMEOFEXECUTABLE:
+ /* Redirect to Tcl proc */
+ return Jim_Eval(interp, "info_nameofexecutable");
+
+ case INFO_RETURNCODES: {
+ int i;
+ Jim_Obj *listObjPtr = Jim_NewListObj(interp, NULL, 0);
+
+ for (i = 0; jimReturnCodes[i]; i++) {
+ Jim_ListAppendElement(interp, listObjPtr, Jim_NewIntObj(interp, i));
+ Jim_ListAppendElement(interp, listObjPtr, Jim_NewStringObj(interp, jimReturnCodes[i], -1));
+ }
+
+ Jim_SetResult(interp, listObjPtr);
+ break;
+ }
}
- return result;
+ return JIM_OK;
}
/* [split] */
@@ -12563,10 +12476,7 @@ static int Jim_EnvCoreCommand(Jim_Interp *interp, int argc,
val = getenv(key);
if (val == NULL) {
if (argc < 3) {
- Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
- Jim_AppendStrings(interp, Jim_GetResult(interp),
- "environment variable \"",
- key, "\" does not exist", NULL);
+ Jim_SetResultFormatted(interp, "environment variable \"%#s\" does not exist", argv[1]);
return JIM_ERR;
}
val = Jim_GetString(argv[2], NULL);
@@ -12695,7 +12605,7 @@ static int Jim_RandCoreCommand(Jim_Interp *interp, int argc,
JimRandomBytes(interp, &r, sizeof(jim_wide));
if (r < 0 || r >= maxMul) continue;
r = (len == 0) ? 0 : r%len;
- Jim_SetResult(interp, Jim_NewIntObj(interp, min+r));
+ Jim_SetResultInt(interp, min+r);
return JIM_OK;
}
}
@@ -12854,22 +12764,22 @@ static void JimSetFailedEnumResult(Jim_Interp *interp, const char *arg, const ch
for (count = 0; tablePtr[count]; count++) {
}
- if (name == NULL)
+ if (name == NULL) {
name = "option";
- Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
- Jim_AppendStrings(interp, Jim_GetResult(interp),
- badtype, name, " \"", arg, "\": must be ",
- NULL);
+ }
+
+ Jim_SetResultFormatted(interp, "%s%s \"%s\": must be ", badtype, name, arg);
tablePtrSorted = Jim_Alloc(sizeof(char*)*count);
memcpy(tablePtrSorted, tablePtr, sizeof(char*)*count);
qsort(tablePtrSorted, count, sizeof(char*), qsortCompareStringPointers);
for (i = 0; i < count; i++) {
- if (i+1 == count && count > 1)
+ if (i+1 == count && count > 1) {
Jim_AppendString(interp, Jim_GetResult(interp), "or ", -1);
- Jim_AppendStrings(interp, Jim_GetResult(interp),
- prefix, tablePtrSorted[i], NULL);
- if (i+1 != count)
+ }
+ Jim_AppendStrings(interp, Jim_GetResult(interp), prefix, tablePtrSorted[i], NULL);
+ if (i+1 != count) {
Jim_AppendString(interp, Jim_GetResult(interp), ", ", -1);
+ }
}
Jim_Free(tablePtrSorted);
}
@@ -12943,6 +12853,60 @@ int Jim_IsList(Jim_Obj *objPtr)
return objPtr->typePtr == &listObjType;
}
+/**
+ * Very simple printf-like formatting, designed for error messages.
+ *
+ * The format may contain up to 5 '%s' or '%#s', corresponding to variable arguments.
+ * The resulting string is created and set as the result.
+ *
+ * Each '%s' should correspond to a regular string parameter.
+ * Each '%#s' should correspond to a (Jim_Obj *) parameter.
+ * Any other printf specifier is not allowed (but %% is allowed for the % character).
+ *
+ * e.g. Jim_SetResultFormatted(interp, "Bad option \"%#s\" in proc \"%#s\"", optionObjPtr, procNamePtr);
+ *
+ * Note: We take advantage of the fact that printf has the same behaviour for both %s and %#s
+ */
+void Jim_SetResultFormatted(Jim_Interp *interp, const char *format, ...)
+{
+ /* Initial space needed */
+ int len = strlen(format);
+ int extra = 0;
+ int n = 0;
+ const char *params[5];
+ char *buf;
+ va_list args;
+ int i;
+
+ va_start(args, format);
+
+ for (i = 0; i < len && n < 5; i++) {
+ int l;
+ if (strncmp(format + i, "%s", 2) == 0) {
+ params[n] = va_arg(args, char*);
+ l = strlen(params[n]);
+ }
+ else if (strncmp(format + i, "%#s", 3) == 0) {
+ Jim_Obj *objPtr = va_arg(args, Jim_Obj*);
+ params[n] = Jim_GetString(objPtr, &l);
+ }
+ else {
+ if (format[i] == '%') {
+ i++;
+ }
+ continue;
+ }
+ n++;
+ extra += l;
+ }
+
+ len += extra;
+ buf = Jim_Alloc(len + 1);
+ len = snprintf(buf, len + 1, format, params[0], params[1], params[2], params[3], params[4]);
+
+ Jim_SetResult(interp, Jim_NewStringObjNoAlloc(interp, buf, len));
+}
+
/*
* Local Variables: ***
* c-basic-offset: 4 ***