aboutsummaryrefslogtreecommitdiff
path: root/internal/cond
diff options
context:
space:
mode:
authorLukasz Kasprzak <lukas@labunix.xyz>2026-09-14 23:34:51 +0200
committerLukasz Kasprzak <lukas@labunix.xyz>2026-09-14 23:34:51 +0200
commit3990586a85e91923c0a3ae1a1f0f61420db555ac (patch)
tree041692e7961cb66333b2c7b47d32a25487c6522d /internal/cond
parent01b0cfe2055e23cf03870d9a9f60648037b4005e (diff)
downloadkrino-3990586a85e91923c0a3ae1a1f0f61420db555ac.tar.gz
krino-3990586a85e91923c0a3ae1a1f0f61420db555ac.zip
captures keep the name's diacritics
Diffstat (limited to 'internal/cond')
-rw-r--r--internal/cond/eval.go30
-rw-r--r--internal/cond/eval_test.go17
2 files changed, 40 insertions, 7 deletions
diff --git a/internal/cond/eval.go b/internal/cond/eval.go
index b0ee828..f241504 100644
--- a/internal/cond/eval.go
+++ b/internal/cond/eval.go
@@ -164,17 +164,33 @@ func (c *Cond) evalLeaf(n *node, f Facts) (ok bool, reason, warn string, caps []
subj = f.Rel()
word = "path"
}
- subj = norm.Name(subj, c.opt.Fold)
+ if n.kind == kPath {
+ subj = norm.Name(subj, c.opt.Fold)
+ for _, p := range n.patterns {
+ if p.re.MatchString(subj) {
+ return true, word + ` "` + p.src + `"`, "", nil
+ }
+ }
+ return false, "", "", nil
+ }
+ // A name test matches the folded name, but its captures are read
+ // back from the original, so {1} keeps the name's diacritics.
+ folded := norm.Folded{Text: subj}
+ if c.opt.Fold {
+ folded = norm.FoldMapped(subj)
+ }
for _, p := range n.patterns {
- m := p.re.FindStringSubmatch(subj)
- if m == nil {
+ loc := p.re.FindStringSubmatchIndex(folded.Text)
+ if loc == nil {
continue
}
- reason = word + ` "` + p.src + `"`
- if n.kind == kName {
- return true, reason, "", m
+ caps := make([]string, len(loc)/2)
+ for g := range caps {
+ if loc[2*g] >= 0 {
+ caps[g] = folded.Source(loc[2*g], loc[2*g+1])
+ }
}
- return true, reason, "", nil
+ return true, word + ` "` + p.src + `"`, "", caps
}
return false, "", "", nil
diff --git a/internal/cond/eval_test.go b/internal/cond/eval_test.go
index 88612ac..2e8bcfd 100644
--- a/internal/cond/eval_test.go
+++ b/internal/cond/eval_test.go
@@ -240,3 +240,20 @@ func TestEvalReportsUnreadableContent(t *testing.T) {
t.Errorf("not reached: Match %v Unreadable %v; want true, false", r.Match, r.Unreadable)
}
}
+
+// TestCapturesKeepDiacritics: a name test matches the folded name, but its
+// captures are the original name's characters, so {1} keeps "Łódź".
+func TestCapturesKeepDiacritics(t *testing.T) {
+ f := &fake{name: "Łódź-Faktura.pdf"}
+ r := eval(t, `(name "^(.+)-faktura")`, Options{IgnoreCase: true, Fold: true}, f)
+ if !r.Match {
+ t.Fatal("no match")
+ }
+ if want := []string{"Łódź-Faktura", "Łódź"}; !reflect.DeepEqual(r.Captures, want) {
+ t.Errorf("captures = %q, want %q", r.Captures, want)
+ }
+ r = eval(t, `(name "^(lodz)?(x)?-")`, Options{IgnoreCase: true, Fold: true}, f)
+ if want := []string{"Łódź-", "Łódź", ""}; !reflect.DeepEqual(r.Captures, want) {
+ t.Errorf("captures with a group that did not take part = %q, want %q", r.Captures, want)
+ }
+}