diff options
author | dgp <dgp@users.sourceforge.net> | 2009-09-04 17:33:11 (GMT) |
---|---|---|
committer | dgp <dgp@users.sourceforge.net> | 2009-09-04 17:33:11 (GMT) |
commit | ec6f24d1c6194c2ea9a6a128f03ec6ef8c5e3e3b (patch) | |
tree | bda8162950789931d2ac4e2f18c24f5e1125e2b5 /generic/tclParse.c | |
parent | 923c5dca54d5508b1fe4ca3f9b388545ffcba1ba (diff) | |
download | tcl-ec6f24d1c6194c2ea9a6a128f03ec6ef8c5e3e3b.zip tcl-ec6f24d1c6194c2ea9a6a128f03ec6ef8c5e3e3b.tar.gz tcl-ec6f24d1c6194c2ea9a6a128f03ec6ef8c5e3e3b.tar.bz2 |
* generic/tclCompCmds.c (TclCompileSubstCmd): Added a bytecode
* generic/tclBasic.c: compiler routine for the [subst] command.
* generic/tclCmdMZ.c: This is a partial solution to the need to
* generic/tclCompile.c: NR-enable [subst] since bytecode execution is
* generic/tclCompile.h: already NR-enabled. [Bug 2314561] Two new
* generic/tclExecute.c: bytecode instructions, INST_NOP and
* generic/tclInt.h: INST_RETURN_CODE_BRANCH were added to support
* generic/tclParse.c: the new routine. INST_RETURN_CODE_BRANCH is
* tests/basic.test: likely to be useful in any future effort to
* tests/info.test: add a bytecode compiler routine for [try].
* tests/parse.test:
Diffstat (limited to 'generic/tclParse.c')
-rw-r--r-- | generic/tclParse.c | 61 |
1 files changed, 37 insertions, 24 deletions
diff --git a/generic/tclParse.c b/generic/tclParse.c index aca6048..efb4422 100644 --- a/generic/tclParse.c +++ b/generic/tclParse.c @@ -1880,18 +1880,17 @@ Tcl_ParseQuotedString( *---------------------------------------------------------------------- */ -Tcl_Obj * -Tcl_SubstObj( - Tcl_Interp *interp, /* Interpreter in which substitution occurs */ - Tcl_Obj *objPtr, /* The value to be substituted. */ - int flags) /* What substitutions to do. */ +void +TclSubstParse( + Tcl_Interp *interp, + const char *bytes, + int numBytes, + int flags, + Tcl_Parse *parsePtr, + Tcl_InterpState *statePtr) { - int length, tokensLeft, code; - Tcl_Token *endTokenPtr; - Tcl_Obj *result, *errMsg = NULL; - const char *p = TclGetStringFromObj(objPtr, &length); - Tcl_Parse *parsePtr = (Tcl_Parse *) - TclStackAlloc(interp, sizeof(Tcl_Parse)); + int length = numBytes; + const char *p = bytes; TclParseInit(interp, p, length, parsePtr); @@ -1903,12 +1902,11 @@ Tcl_SubstObj( if (TCL_OK != ParseTokens(p, length, /* mask */ 0, flags, parsePtr)) { /* - * There was a parse error. Save the error message for possible - * reporting later. + * There was a parse error. Save the interpreter state for possible + * error reporting later. */ - errMsg = Tcl_GetObjResult(interp); - Tcl_IncrRefCount(errMsg); + *statePtr = Tcl_SaveInterpState(interp, TCL_ERROR); /* * We need to re-parse to get the portion of the string we can [subst] @@ -2054,6 +2052,23 @@ Tcl_SubstObj( Tcl_Panic("bad parse in Tcl_SubstObj: %c", p[length]); } } +} + +Tcl_Obj * +Tcl_SubstObj( + Tcl_Interp *interp, /* Interpreter in which substitution occurs */ + Tcl_Obj *objPtr, /* The value to be substituted. */ + int flags) /* What substitutions to do. */ +{ + int tokensLeft, code, numBytes; + Tcl_Token *endTokenPtr; + Tcl_Obj *result; + Tcl_Parse *parsePtr = (Tcl_Parse *) + TclStackAlloc(interp, sizeof(Tcl_Parse)); + Tcl_InterpState state = NULL; + const char *bytes = TclGetStringFromObj(objPtr, &numBytes); + + TclSubstParse(interp, bytes, numBytes, flags, parsePtr, &state); /* * Next, substitute the parsed tokens just as in normal Tcl evaluation. @@ -2066,9 +2081,8 @@ Tcl_SubstObj( if (code == TCL_OK) { Tcl_FreeParse(parsePtr); TclStackFree(interp, parsePtr); - if (errMsg != NULL) { - Tcl_SetObjResult(interp, errMsg); - Tcl_DecrRefCount(errMsg); + if (state != NULL) { + Tcl_RestoreInterpState(interp, state); return NULL; } return Tcl_GetObjResult(interp); @@ -2081,8 +2095,8 @@ Tcl_SubstObj( Tcl_FreeParse(parsePtr); TclStackFree(interp, parsePtr); Tcl_DecrRefCount(result); - if (errMsg != NULL) { - Tcl_DecrRefCount(errMsg); + if (state != NULL) { + Tcl_DiscardInterpState(state); } return NULL; case TCL_BREAK: @@ -2094,14 +2108,13 @@ Tcl_SubstObj( if (tokensLeft == 0) { Tcl_FreeParse(parsePtr); TclStackFree(interp, parsePtr); - if (errMsg != NULL) { + if (state != NULL) { if (code != TCL_BREAK) { Tcl_DecrRefCount(result); - Tcl_SetObjResult(interp, errMsg); - Tcl_DecrRefCount(errMsg); + Tcl_RestoreInterpState(interp, state); return NULL; } - Tcl_DecrRefCount(errMsg); + Tcl_DiscardInterpState(state); } return result; } |