diff options
author | dgp <dgp@users.sourceforge.net> | 2003-11-14 20:44:43 (GMT) |
---|---|---|
committer | dgp <dgp@users.sourceforge.net> | 2003-11-14 20:44:43 (GMT) |
commit | 17f540b256d78b8a6fc8bd9121a633dac6c23b19 (patch) | |
tree | 1abdc7a020d4095171e8cb7f16def9be025cb664 /generic/tclParse.c | |
parent | f745c9aa31bbdf8f71589fa25d30ce50cad94652 (diff) | |
download | tcl-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.c | 42 |
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 |