summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2014-08-13 06:55:07 -0700
committerKaz Kylheku <kaz@kylheku.com>2014-08-13 06:55:07 -0700
commite05a39e67e5259263ecc4955f3efa8724d887e90 (patch)
treee804ef38705005afca9f1314cd2cadb13de56e93
parent9aee8dd619826e3fa73f665e72522a342742af0b (diff)
downloadtxr-e05a39e67e5259263ecc4955f3efa8724d887e90.tar.gz
txr-e05a39e67e5259263ecc4955f3efa8724d887e90.tar.bz2
txr-e05a39e67e5259263ecc4955f3efa8724d887e90.zip
Fix regression in previous change: we must match a compound text
element whole, and not break it up. * match.c (search_match): Take a spec argument. (h_var): Turn a text element into a one-element spec and process with search_match. * txr.1: Updated text about matching of variables followed by a directive or function, and about consecutive variables via directive.
-rw-r--r--ChangeLog13
-rw-r--r--match.c21
-rw-r--r--txr.146
3 files changed, 46 insertions, 34 deletions
diff --git a/ChangeLog b/ChangeLog
index f042933a..ff2620bf 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2014-08-13 Kaz Kylheku <kaz@kylheku.com>
+
+ Fix regression in previous change: we must match a compound text
+ element whole, and not break it up.
+
+ * match.c (search_match): Take a spec argument.
+ (h_var): Turn a text element into a one-element spec and process
+ with search_match.
+
+ * txr.1: Updated text about matching of variables
+ followed by a directive or function, and about consecutive
+ variables via directive.
+
2014-08-12 Kaz Kylheku <kaz@kylheku.com>
When a variable is delimited by some form other than
diff --git a/match.c b/match.c
index fe6a918f..67d917ea 100644
--- a/match.c
+++ b/match.c
@@ -450,9 +450,8 @@ static void consume_prefix(match_line_ctx *c)
}
-static val search_match(match_line_ctx *c, val from_end)
+static val search_match(match_line_ctx *c, val from_end, val spec)
{
- val spec = c->specline;
val pos = from_end ? length_str(c->dataline) : c->pos;
val step = from_end ? negone : one;
@@ -640,11 +639,17 @@ static val h_var(match_line_ctx *c)
return repeat_spec_k;
}
} else if (op == text_s) {
- /* Clumped texts: break out the first one. */
- val text_elem = rlcp(second(next), c->specline);
- val rest_texts = cons(text_s, rest(rest(next)));
- c->specline = cons(elem, cons(text_elem,
- cons(rest_texts, rest(c->specline))));
+ val text_only_spec = cons(next, nil);
+ val find = search_match(c, modifier, text_only_spec);
+ val fpos = car(find);
+ if (!find) {
+ LOG_MISMATCH("var delimiting text compound");
+ return nil;
+ }
+ LOG_MATCH("var delimiting text compound", fpos);
+ if (sym)
+ c->bindings = acons(sym, sub_str(c->dataline, c->pos, fpos), c->bindings);
+ c->pos = fpos;
return repeat_spec_k;
} else if (consp(op) || stringp(op)) {
cons_bind (find, len, search_str_tree(c->dataline, next, c->pos, modifier));
@@ -656,7 +661,7 @@ static val h_var(match_line_ctx *c)
c->bindings = acons(sym, sub_str(c->dataline, c->pos, find), c->bindings);
c->pos = plus(find, len);
} else {
- val find = search_match(c, modifier);
+ val find = search_match(c, modifier, c->specline);
val fpos = car(find);
if (!find) {
LOG_MISMATCH("var delimiting spec");
diff --git a/txr.1 b/txr.1
index 6956d497..6234284f 100644
--- a/txr.1
+++ b/txr.1
@@ -722,32 +722,28 @@ text which is bound to FOO.
.SS Variable Followed by a Function Call or Directive
If the variable is followed by a function call, or a directive, the extent is
-determined by scanning the text for the first position where a match occurs for
-the regular expression, call or directive. (For a description of functions,
+determined by scanning the text for the first position where a match occurs
+for the entire remainder of the line. (For a description of functions,
see FUNCTIONS.)
-Note that the given variable and the function or directive are considered
-in isolation. This means, for instance, that @var@(skip)text is a degenerate
-form. The @(skip) will be processed alone, without regard for the trailing
-text and so consume the input to the end of the line. The right way to
-express the most probable intent of this is @{var}text.
-
-Another degenerate case is @var@(bind ...), or in general, a variable
-followed by some directive not used for matching text. Watch out for
-the following pitfall:
+For example:
- @a @b@(bind have_ab "y")
+ @foo@(bind a "abc")xyz
-The intent here is that the variable b captures everything after the space to
-the end of the line, and then the variable have_ab is set to "y". But since
-@(bind) always succeeds, b captures an empty string, and then the whole line
-fails if there is any material after the space. The right way to do this is:
+Here, foo will match the text from the current position to where "xyz"
+occurs, even though there is a @(bind) directive. Furthermore, if
+more material is added after the xyz, it is part of the search.
+Note the difference between the following two:
- @a @b@(eol)@(bind have_ab "y")
+ @foo@/abc/@(func)
+ @foo@(func)@/abc/
-That is to say, match an explicit @(eol) after the variable. This will
-search for the end of the line and capture the spanning text into b, as
-intended. The bind then happens afterward.
+In the first example, the variable foo matches the text from the current
+position until the match for the regular expression abc. @(func) is not
+considered when processing @foo. In the second example, the variable foo
+matches the text from the current position until the position whcih matches
+the function call, followed by a match for the regular expression.
+The entire sequence @(func)@/abc/ is considered.
.SS Consecutive Variables
@@ -810,12 +806,10 @@ following example:
@var1@(all)@var2@(end)
-The @(all) directive does nothing other than assert that all clauses must
-match. It has only one clause, @var2. So this is equivalent to just @var1@var2,
-except that if both variables are unbound, no semantic error is identified in
-this situation. Such a situation is handled as a variable followed by a
-directive. Of course @var2 matches everything at the current position, and so
-@var1 ends up with nothing.
+This is treated just like the variable followed by directive. No semantic
+error is identified, even if both variables are unbound. Here, @var2
+@var2 matches everything at the current position, and so @var1 ends up
+bound to the empty string.
Example 1: b matches at position 0 and a gets nothing: