summaryrefslogtreecommitdiffstats
path: root/generic
diff options
context:
space:
mode:
authordkf <donal.k.fellows@manchester.ac.uk>2020-11-08 17:30:37 (GMT)
committerdkf <donal.k.fellows@manchester.ac.uk>2020-11-08 17:30:37 (GMT)
commita748303dfa5acf9a2cf632fe16dabed351e81881 (patch)
tree38c15b07d8d567391dfbf7abf81157a5a2ea6367 /generic
parent4f03addd7ef49cab94988511228be280c4a97ec7 (diff)
parent40b3d4d5dd32bfe69a1f7771c6aa470265aa06bf (diff)
downloadtcl-a748303dfa5acf9a2cf632fe16dabed351e81881.zip
tcl-a748303dfa5acf9a2cf632fe16dabed351e81881.tar.gz
tcl-a748303dfa5acf9a2cf632fe16dabed351e81881.tar.bz2
Merge 8.7
Diffstat (limited to 'generic')
-rw-r--r--generic/tclCompExpr.c54
1 files changed, 50 insertions, 4 deletions
diff --git a/generic/tclCompExpr.c b/generic/tclCompExpr.c
index bf677da..2db2c8a 100644
--- a/generic/tclCompExpr.c
+++ b/generic/tclCompExpr.c
@@ -164,6 +164,8 @@ enum Marks {
* "=" is encountered. */
#define INVALID 5 /* A parse error. Used when any punctuation
* appears that's not a supported operator. */
+#define COMMENT 6 /* Comment. Lasts to end of line or end of
+ * expression, whichever comes first. */
/* Leaf lexemes */
@@ -462,7 +464,7 @@ static const unsigned char Lexeme[] = {
INVALID /* FS */, INVALID /* GS */,
INVALID /* RS */, INVALID /* US */,
INVALID /* SPACE */, 0 /* ! or != */,
- QUOTED /* " */, INVALID /* # */,
+ QUOTED /* " */, 0 /* # */,
VARIABLE /* $ */, MOD /* % */,
0 /* & or && */, INVALID /* ' */,
OPEN_PAREN /* ( */, CLOSE_PAREN /* ) */,
@@ -674,9 +676,10 @@ ParseExpr(
OpNode *newPtr = NULL;
do {
- if (size <= UINT_MAX/sizeof(OpNode)) {
- newPtr = (OpNode *)Tcl_AttemptRealloc(nodes, size * sizeof(OpNode));
- }
+ if (size <= UINT_MAX/sizeof(OpNode)) {
+ newPtr = (OpNode *) Tcl_AttemptRealloc(nodes,
+ size * sizeof(OpNode));
+ }
} while ((newPtr == NULL)
&& ((size -= (size - nodesUsed) / 2) > nodesUsed));
if (newPtr == NULL) {
@@ -708,6 +711,10 @@ ParseExpr(
int b;
switch (lexeme) {
+ case COMMENT:
+ start += scanned;
+ numBytes -= scanned;
+ continue;
case INVALID:
msg = Tcl_ObjPrintf("invalid character \"%.*s\"",
(int)scanned, start);
@@ -742,6 +749,32 @@ ParseExpr(
} else if (Tcl_GetBooleanFromObj(NULL,literal,&b) == TCL_OK) {
lexeme = BOOLEAN;
} else {
+ /*
+ * Tricky case: see test expr-62.10
+ */
+
+ int scanned2 = scanned;
+ do {
+ scanned2 += TclParseAllWhiteSpace(
+ start + scanned2, numBytes - scanned2);
+ scanned2 += ParseLexeme(
+ start + scanned2, numBytes - scanned2, &lexeme,
+ NULL);
+ } while (lexeme == COMMENT);
+ if (lexeme == OPEN_PAREN) {
+ /*
+ * Actually a function call, but with obscuring
+ * comments. Skip to the start of the parentheses.
+ * Note that we assume that open parentheses are one
+ * byte long.
+ */
+
+ lexeme = FUNCTION;
+ Tcl_ListObjAppendElement(NULL, funcList, literal);
+ scanned = scanned2 - 1;
+ break;
+ }
+
Tcl_DecrRefCount(literal);
msg = Tcl_ObjPrintf("invalid bareword \"%.*s%s\"",
(scanned < limit) ? (int)scanned : (int)limit - 3, start,
@@ -1908,6 +1941,19 @@ ParseLexeme(
return 1;
}
switch (byte) {
+ case '#': {
+ /*
+ * Scan forward over the comment contents.
+ */
+ size_t size;
+
+ for (size = 0; byte != '\n' && byte != 0 && size < numBytes; size++) {
+ byte = UCHAR(start[size]);
+ }
+ *lexemePtr = COMMENT;
+ return size - (byte == '\n');
+ }
+
case '*':
if ((numBytes > 1) && (start[1] == '*')) {
*lexemePtr = EXPON;