summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2022-02-04 19:39:39 -0800
committerKaz Kylheku <kaz@kylheku.com>2022-02-04 19:39:39 -0800
commit1bc3c2aa2cf90fcf8e52b8662b3227130b8ed5de (patch)
treeb72a33e42a4a3a671c269e8110cd84af25276f46
parentf4c54fbad69d1181057fe5025f537802b9eec610 (diff)
downloadtxr-1bc3c2aa2cf90fcf8e52b8662b3227130b8ed5de.tar.gz
txr-1bc3c2aa2cf90fcf8e52b8662b3227130b8ed5de.tar.bz2
txr-1bc3c2aa2cf90fcf8e52b8662b3227130b8ed5de.zip
matcher: bug: quasiliteral allowing prefix matches.
* stdlib/match.tl (expand-quasi-match): When matching `text` or `@var`, which are matching in the final position of the specimen, it is not good enough that match-str returns true; we must check that the entire string was matched. Reported by Paul A. Patience.
-rw-r--r--stdlib/match.tl7
-rw-r--r--tests/011/patmatch.tl5
2 files changed, 8 insertions, 4 deletions
diff --git a/stdlib/match.tl b/stdlib/match.tl
index 47593fb3..cdc1415c 100644
--- a/stdlib/match.tl
+++ b/stdlib/match.tl
@@ -920,7 +920,7 @@
(match-case args
;; `text`
((@(stringp @txt))
- (list ^@(require @nil (match-str ,str ,txt ,pos))))
+ (list ^@(require @nil (eql (len ,str) (match-str ,str ,txt ,pos)))))
;; `txt@...`
((@(stringp @txt) . @rest)
(with-gensyms (npos)
@@ -940,8 +940,9 @@
(quasi-match vlist rest vars str npos))))
;; `@var` (existing binding)
(((@(eq 'sys:var) @(bound-p vlist vars @sym) . @nil))
- (list ^@(require @nil (match-str ,str (sys:quasi ,(car args))
- ,pos))))
+ (list ^@(require @nil (eql (len ,str)
+ (match-str ,str (sys:quasi ,(car args))
+ ,pos)))))
;; `@var@...` (existing binding)
((@(as avar (@(eq 'sys:var) @(bound-p vlist vars @sym) . @nil))
. @rest)
diff --git a/tests/011/patmatch.tl b/tests/011/patmatch.tl
index 4b44eca9..c9eb3d39 100644
--- a/tests/011/patmatch.tl
+++ b/tests/011/patmatch.tl
@@ -355,7 +355,10 @@
(mtest
(when-match `` "" t) t
(when-match `abc` "abc" t) t
- (when-match `@a` "abc" a) "abc")
+ (when-match `abc` "abcdef" t) nil
+ (when-match `@a` "abc" a) "abc"
+ (let ((x "foo")) (when-match `@x` "foobar" t)) nil
+ (let ((x "foo")) (when-match `@x` "foo" x)) "foo")
(mtest
(when-match `@a@b` "abc" a) :error