foreach: Avoid memory leak in case of error
[jimtcl.git] / jim-interp.c
bloba5da93e290cee09e316b7f6519e871463ae24509
1 #include <assert.h>
3 #include "jim.h"
4 #include "jimautoconf.h"
5 #include "jim-subcmd.h"
7 static void JimInterpDelProc(Jim_Interp *interp, void *privData)
9 Jim_FreeInterp((Jim_Interp *)privData);
12 /* Everything passing between interpreters must be converted to a string */
13 static Jim_Obj *JimInterpCopyObj(Jim_Interp *target, Jim_Obj *obj)
15 const char *rep;
16 int len;
18 rep = Jim_GetString(obj, &len);
19 return Jim_NewStringObj(target, rep, len);
22 #define JimInterpCopyResult(to, from) Jim_SetResult((to), JimInterpCopyObj((to), Jim_GetResult((from))))
24 static int interp_cmd_eval(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
26 int ret;
27 Jim_Interp *child = Jim_CmdPrivData(interp);
28 Jim_Obj *scriptObj;
29 Jim_Obj *targetScriptObj;
31 scriptObj = Jim_ConcatObj(interp, argc, argv);
32 targetScriptObj = JimInterpCopyObj(child, scriptObj);
33 Jim_FreeNewObj(interp, scriptObj);
35 Jim_IncrRefCount(targetScriptObj);
36 ret = Jim_EvalObj(child, targetScriptObj);
37 Jim_DecrRefCount(child, targetScriptObj);
39 JimInterpCopyResult(interp, child);
40 return ret;
43 static int interp_cmd_delete(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
45 return Jim_DeleteCommand(interp, Jim_String(argv[0]));
48 static void JimInterpDelAlias(Jim_Interp *interp, void *privData)
50 Jim_Interp *parent = Jim_GetAssocData(interp, "interp.parent");
51 Jim_DecrRefCount(parent, (Jim_Obj *)privData);
54 static int JimInterpAliasProc(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
56 int i, ret;
57 Jim_Interp *parent = Jim_GetAssocData(interp, "interp.parent");
58 Jim_Obj *targetPrefixObj = Jim_CmdPrivData(interp);
59 Jim_Obj *targetScriptObj;
61 assert(parent);
63 /* Build the complete command */
64 targetScriptObj = Jim_DuplicateObj(parent, targetPrefixObj);
65 for (i = 1; i < argc; i++) {
66 Jim_ListAppendElement(parent, targetScriptObj,
67 JimInterpCopyObj(parent, argv[i]));
70 Jim_IncrRefCount(targetScriptObj);
71 ret = Jim_EvalObj(parent, targetScriptObj);
72 Jim_DecrRefCount(parent, targetScriptObj);
74 JimInterpCopyResult(interp, parent);
75 return ret;
78 static int interp_cmd_alias(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
80 Jim_Interp *child = Jim_CmdPrivData(interp);
81 Jim_Obj *aliasPrefixList;
83 /* The prefix list will be held inside the child, but it still belongs
84 * to the parent!
87 aliasPrefixList = Jim_NewListObj(interp, argv + 1, argc - 1);
88 Jim_IncrRefCount(aliasPrefixList);
90 Jim_CreateCommand(child, Jim_String(argv[0]), JimInterpAliasProc, aliasPrefixList, JimInterpDelAlias);
91 return JIM_OK;
94 static const jim_subcmd_type interp_command_table[] = {
95 { "eval",
96 "script ...",
97 interp_cmd_eval,
99 -1,
100 /* Description: Concat the args and evaluate the script in the interpreter */
102 { "delete",
103 NULL,
104 interp_cmd_delete,
107 JIM_MODFLAG_FULLARGV,
108 /* Description: Delete this interpreter */
110 { "alias",
111 "childcmd parentcmd ?arg ...?",
112 interp_cmd_alias,
115 /* Description: Create an alias which refers to a script in the parent interpreter */
117 { NULL }
120 static int JimInterpSubCmdProc(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
122 return Jim_CallSubCmd(interp, Jim_ParseSubCmd(interp, interp_command_table, argc, argv), argc, argv);
125 static void JimInterpCopyVariable(Jim_Interp *target, Jim_Interp *source, const char *var, const char *default_value)
127 Jim_Obj *value = Jim_GetGlobalVariableStr(source, var, JIM_NONE);
128 const char *str;
130 str = value ? Jim_String(value) : default_value;
131 if (str) {
132 Jim_SetGlobalVariableStr(target, var, Jim_NewStringObj(target, str, -1));
137 * [interp] creates a new interpreter.
139 static int JimInterpCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
141 Jim_Interp *child;
142 char buf[32];
144 if (argc != 1) {
145 Jim_WrongNumArgs(interp, 1, argv, "");
146 return JIM_ERR;
149 /* Create the interpreter command */
150 child = Jim_CreateInterp();
151 Jim_RegisterCoreCommands(child);
152 Jim_InitStaticExtensions(child);
154 /* Copy some core variables to the new interpreter */
155 JimInterpCopyVariable(child, interp, "argv", NULL);
156 JimInterpCopyVariable(child, interp, "argc", NULL);
157 JimInterpCopyVariable(child, interp, "argv0", NULL);
158 JimInterpCopyVariable(child, interp, "jim::argv0", NULL);
159 JimInterpCopyVariable(child, interp, "jim::exe", NULL);
161 /* Allow the child interpreter to find the parent */
162 Jim_SetAssocData(child, "interp.parent", NULL, interp);
164 snprintf(buf, sizeof(buf), "interp.handle%ld", Jim_GetId(interp));
165 Jim_CreateCommand(interp, buf, JimInterpSubCmdProc, child, JimInterpDelProc);
166 Jim_SetResult(interp, Jim_MakeGlobalNamespaceName(interp, Jim_NewStringObj(interp, buf, -1)));
167 return JIM_OK;
170 int Jim_interpInit(Jim_Interp *interp)
172 if (Jim_PackageProvide(interp, "interp", "1.0", JIM_ERRMSG))
173 return JIM_ERR;
175 Jim_CreateCommand(interp, "interp", JimInterpCommand, NULL, NULL);
177 return JIM_OK;