Skip to content

Commit 7615825

Browse files
committed
info script: return real current source file
And allow current source file to be set Fixes: #268 Signed-off-by: Steve Bennett <[email protected]>
1 parent d765fc5 commit 7615825

File tree

3 files changed

+47
-4
lines changed

3 files changed

+47
-4
lines changed

jim.c

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,23 @@ static int utf8_tounicode_case(const char *s, int *uc, int upper)
172172
return l;
173173
}
174174

175+
/* A common pattern is to save an object from interp and set a new
176+
* value, and then restore the original. Use this pattern:
177+
*
178+
* Jim_Obj *saveObj = JimPushInterpObj(interp->obj, newobj);
179+
* JimPopInterpObj(interp, interp->obj, saveObj);
180+
*/
181+
static Jim_Obj *JimPushInterpObjImpl(Jim_Obj **iop, Jim_Obj *no)
182+
{
183+
Jim_Obj *io = *iop;
184+
Jim_IncrRefCount(no);
185+
*iop = no;
186+
return io;
187+
}
188+
189+
#define JimPushInterpObj(IO, NO) JimPushInterpObjImpl(&(IO), NO)
190+
#define JimPopInterpObj(I, IO, SO) do { Jim_DecrRefCount(I, IO); IO = SO; } while (0)
191+
175192
/* These can be used in addition to JIM_CASESENS/JIM_NOCASE */
176193
#define JIM_CHARSET_SCAN 2
177194
#define JIM_CHARSET_GLOB 0
@@ -5741,6 +5758,7 @@ Jim_Interp *Jim_CreateInterp(void)
57415758
i->errorProc = i->emptyObj;
57425759
i->nullScriptObj = Jim_NewEmptyStringObj(i);
57435760
i->evalFrame = &i->topEvalFrame;
5761+
i->currentFilenameObj = Jim_NewEmptyStringObj(i);
57445762
Jim_IncrRefCount(i->emptyObj);
57455763
Jim_IncrRefCount(i->result);
57465764
Jim_IncrRefCount(i->stackTrace);
@@ -5750,6 +5768,7 @@ Jim_Interp *Jim_CreateInterp(void)
57505768
Jim_IncrRefCount(i->errorProc);
57515769
Jim_IncrRefCount(i->trueObj);
57525770
Jim_IncrRefCount(i->falseObj);
5771+
Jim_IncrRefCount(i->currentFilenameObj);
57535772

57545773
/* Initialize key variables every interpreter should contain */
57555774
Jim_SetVariableStrWithStr(i, JIM_LIBPATH, TCL_LIBRARY);
@@ -5794,6 +5813,7 @@ void Jim_FreeInterp(Jim_Interp *i)
57945813
Jim_DecrRefCount(i, i->unknown);
57955814
Jim_DecrRefCount(i, i->defer);
57965815
Jim_DecrRefCount(i, i->nullScriptObj);
5816+
Jim_DecrRefCount(i, i->currentFilenameObj);
57975817

57985818
/* This will disard any cached commands */
57995819
Jim_InterpIncrProcEpoch(i);
@@ -11641,17 +11661,25 @@ static Jim_Obj *JimReadTextFile(Jim_Interp *interp, const char *filename)
1164111661

1164211662
int Jim_EvalFile(Jim_Interp *interp, const char *filename)
1164311663
{
11664+
Jim_Obj *filenameObj;
11665+
Jim_Obj *oldFilenameObj;
1164411666
Jim_Obj *scriptObjPtr;
1164511667
int retcode;
1164611668

1164711669
scriptObjPtr = JimReadTextFile(interp, filename);
1164811670
if (!scriptObjPtr) {
1164911671
return JIM_ERR;
1165011672
}
11651-
JimSetSourceInfo(interp, scriptObjPtr, Jim_NewStringObj(interp, filename, -1), 1);
11673+
11674+
filenameObj = Jim_NewStringObj(interp, filename, -1);
11675+
JimSetSourceInfo(interp, scriptObjPtr, filenameObj, 1);
11676+
11677+
oldFilenameObj = JimPushInterpObj(interp->currentFilenameObj, filenameObj);
1165211678

1165311679
retcode = Jim_EvalObj(interp, scriptObjPtr);
1165411680

11681+
JimPopInterpObj(interp, interp->currentFilenameObj, oldFilenameObj);
11682+
1165511683
/* Handle the JIM_RETURN return code */
1165611684
if (retcode == JIM_RETURN) {
1165711685
if (--interp->returnLevel <= 0) {
@@ -15565,7 +15593,7 @@ static int Jim_InfoCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg
1556515593
JIM_DEF_SUBCMD("procs", "?pattern?", 0, 1),
1556615594
JIM_DEF_SUBCMD("references", NULL, 0, 0),
1556715595
JIM_DEF_SUBCMD("returncodes", "?code?", 0, 1),
15568-
JIM_DEF_SUBCMD("script", NULL, 0, 0),
15596+
JIM_DEF_SUBCMD("script", "?filename?", 0, 1),
1556915597
JIM_DEF_SUBCMD("source", "source ?filename line?", 1, 3),
1557015598
JIM_DEF_SUBCMD("stacktrace", NULL, 0, 0),
1557115599
JIM_DEF_SUBCMD("statics", "procname", 1, 1),
@@ -15655,7 +15683,12 @@ static int Jim_InfoCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg
1565515683
return JIM_OK;
1565615684

1565715685
case INFO_SCRIPT:
15658-
Jim_SetResult(interp, JimGetScript(interp, interp->evalFrame->scriptObj)->fileNameObj);
15686+
if (argc == 3) {
15687+
Jim_IncrRefCount(argv[2]);
15688+
Jim_DecrRefCount(interp, interp->currentFilenameObj);
15689+
interp->currentFilenameObj = argv[2];
15690+
}
15691+
Jim_SetResult(interp, interp->currentFilenameObj);
1565915692
return JIM_OK;
1566015693

1566115694
case INFO_SOURCE:{

jim.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -541,7 +541,7 @@ typedef struct Jim_PrngState {
541541
typedef struct Jim_Interp {
542542
Jim_Obj *result; /* object returned by the last command called. */
543543
int unused_errorLine; /* Error line where an error occurred. */
544-
Jim_Obj *unused_errorFileNameObj; /* Error file where an error occurred. */
544+
Jim_Obj *currentFilenameObj; /* filename of current Jim_EvalFile() */
545545
int unused_addStackTrace;
546546
int maxCallFrameDepth; /* Used for infinite loop detection. */
547547
int maxEvalDepth; /* Used for infinite loop detection. */

tests/jim.test

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3339,6 +3339,16 @@ test info-7.5 {info vars with temporary variables} {
33393339
}
33403340
t1
33413341
} {a}
3342+
test info-8.1 {info script} {
3343+
file tail [info script]
3344+
} {jim.test}
3345+
test info-8.2 {info script - set} {
3346+
set save [info script]
3347+
list [info script abc] [info script] [file tail [info script $save]]
3348+
} {abc abc jim.test}
3349+
test info-8.3 {info script - usage} -body {
3350+
info script too many args
3351+
} -returnCodes error -result {wrong # args: should be "info script ?filename?"}
33423352

33433353
################################################################################
33443354
# RANGE

0 commit comments

Comments
 (0)