summaryrefslogtreecommitdiffstats
path: root/generic/tclParse.c
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2003-11-14 20:44:43 (GMT)
committerdgp <dgp@users.sourceforge.net>2003-11-14 20:44:43 (GMT)
commit17f540b256d78b8a6fc8bd9121a633dac6c23b19 (patch)
tree1abdc7a020d4095171e8cb7f16def9be025cb664 /generic/tclParse.c
parentf745c9aa31bbdf8f71589fa25d30ce50cad94652 (diff)
downloadtcl-17f540b256d78b8a6fc8bd9121a633dac6c23b19.zip
tcl-17f540b256d78b8a6fc8bd9121a633dac6c23b19.tar.gz
tcl-17f540b256d78b8a6fc8bd9121a633dac6c23b19.tar.bz2
* doc/ParseCmd.3: Implementation of TIP 157. Adds recognition
* doc/Tcl.n: of the new leading {expand} syntax on words. * generic/tcl.h: Parses such words as the new Tcl_Token type * generic/tclBasic.c: TCL_TOKEN_EXPAND_WORD. Updated Tcl_EvalEx * generic/tclCompile.c: and the bytecode compiler/execution engine * generic/tclCompile.h: to recognize the new token type. New opcodes * generic/tclExecute.c: INST_LIST_VERIFY and INST_INVOKE_EXP and a new * generic/tclParse.c: operand type OPERAND_ULIST1 are defined. Docs * generic/tclTest.c: and tests are included. * tests/basic.test: * tests/compile.test: * tests/parse.test: * library/auto.tcl: Replaced several [eval]s used to perform * library/package.tcl: argument expansion with the new syntax. * library/safe.tcl: In the test files lindex.test and lset.test, * tests/cmdInfo.test: replaced use of [eval] to force direct * tests/encoding.test: string evaluation with use of [testevalex] * tests/execute.test: which more directly and robustly serves the * tests/fCmd.test: same purpose. * tests/http.test: * tests/init.test: * tests/interp.test: * tests/io.test: * tests/ioUtil.test: * tests/iogt.test: * tests/lindex.test: * tests/lset.test: * tests/namespace-old.test: * tests/namespace.test: * tests/pkg.test: * tests/pkgMkIndex.test: * tests/proc.test: * tests/reg.test: * tests/trace.test: * tests/upvar.test: * tests/winConsole.test: * tests/winFCmd.test:
Diffstat (limited to 'generic/tclParse.c')
-rw-r--r--generic/tclParse.c42
1 files changed, 38 insertions, 4 deletions
diff --git a/generic/tclParse.c b/generic/tclParse.c
index 4dd2fcb..475f1e9 100644
--- a/generic/tclParse.c
+++ b/generic/tclParse.c
@@ -13,7 +13,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclParse.c,v 1.28 2003/11/02 18:57:35 dkf Exp $
+ * RCS: @(#) $Id: tclParse.c,v 1.29 2003/11/14 20:44:45 dgp Exp $
*/
#include "tclInt.h"
@@ -287,6 +287,8 @@ Tcl_ParseCommand(interp, string, numBytes, nested, parsePtr)
parsePtr->commandStart = src;
while (1) {
+ int expandWord = 0;
+
/*
* Create the token for the word.
*/
@@ -319,11 +321,12 @@ Tcl_ParseCommand(interp, string, numBytes, nested, parsePtr)
parsePtr->numWords++;
/*
- * At this point the word can have one of three forms: something
- * enclosed in quotes, something enclosed in braces, or an
- * unquoted word (anything else).
+ * At this point the word can have one of four forms: something
+ * enclosed in quotes, something enclosed in braces, and
+ * expanding word, or an unquoted word (anything else).
*/
+parseWord:
if (*src == '"') {
if (Tcl_ParseQuotedString(interp, src, numBytes,
parsePtr, 1, &termPtr) != TCL_OK) {
@@ -331,11 +334,39 @@ Tcl_ParseCommand(interp, string, numBytes, nested, parsePtr)
}
src = termPtr; numBytes = parsePtr->end - src;
} else if (*src == '{') {
+ static char expPfx[] = "expand";
+ CONST size_t expPfxLen = sizeof(expPfx) - 1;
+ int expIdx = wordIndex + 1;
+ Tcl_Token *expPtr;
+
if (Tcl_ParseBraces(interp, src, numBytes,
parsePtr, 1, &termPtr) != TCL_OK) {
goto error;
}
src = termPtr; numBytes = parsePtr->end - src;
+
+ /*
+ * Check whether the braces contained
+ * the word expansion prefix.
+ */
+
+ expPtr = &parsePtr->tokenPtr[expIdx];
+ if ( (expPfxLen == expPtr->size)
+ /* Same length as prefix */
+ && (0 == expandWord)
+ /* Haven't seen prefix already */
+ && (1 == parsePtr->numTokens - expIdx)
+ /* Only one token */
+ && (0 == strncmp(expPfx,expPtr->start,expPfxLen))
+ /* Is the prefix */
+ && (numBytes > 0)
+ && (0 == TclParseWhiteSpace(termPtr, 1, parsePtr, &type))
+ /* Non-whitespace follows */
+ ) {
+ expandWord = 1;
+ parsePtr->numTokens--;
+ goto parseWord;
+ }
} else {
/*
* This is an unquoted word. Call ParseTokens and let it do
@@ -362,6 +393,9 @@ Tcl_ParseCommand(interp, string, numBytes, nested, parsePtr)
&& (tokenPtr[1].type == TCL_TOKEN_TEXT)) {
tokenPtr->type = TCL_TOKEN_SIMPLE_WORD;
}
+ if (expandWord) {
+ tokenPtr->type = TCL_TOKEN_EXPAND_WORD;
+ }
/*
* Do two additional checks: (a) make sure we're really at the