3 # This file contains a collection of tests for one or more of the Tcl
4 # built-in commands. Sourcing this file into Tcl runs the tests and
5 # generates output for errors. No output means no errors were found.
6 # (Don't panic if you are seeing this as part of the reg distribution
7 # and aren't using Tcl -- reg's own regression tester also knows how
8 # to read this file, ignoring the Tcl-isms.)
10 # Copyright (c) 1998, 1999 Henry Spencer. All rights reserved.
13 if {[lsearch [namespace children] ::tcltest] == -1} {
14 package require tcltest 2
15 namespace import -force ::tcltest::*
18 # All tests require the testregexp command, return if this
19 # command doesn't exist
21 ::tcltest::testConstraint testregexp \
22 [expr {[info commands testregexp] != {}}]
23 ::tcltest::testConstraint localeRegexp 0
25 # This file uses some custom procedures, defined below, for regexp regression
26 # testing. The name of the procedure indicates the general nature of the
28 # e compile error expected
29 # f match failure expected
31 # i successful match with -indices (used in checking things like
32 # nonparticipating subexpressions)
33 # p unsuccessful match with -indices (!!) (used in checking
34 # partial-match reporting)
35 # There is also "doing" which sets up title and major test number for each
38 # The first 3 arguments are constant: a minor number (which often gets
39 # a letter or two suffixed to it internally), some flags, and the RE itself.
40 # For e, the remaining argument is the name of the compile error expected,
41 # less the leading "REG_". For the rest, the next argument is the string
42 # to try the match against. Remaining arguments are the substring expected
43 # to be matched, and any substrings expected to be matched by subexpressions.
44 # (For f, these arguments are optional, and if present are ignored except
45 # that they indicate how many subexpressions should be present in the RE.)
46 # It is an error for the number of subexpression arguments to be wrong.
47 # Cases involving nonparticipating subexpressions, checking where empty
48 # substrings are located, etc. should be done using i and p.
50 # The flag characters are complex and a bit eclectic. Generally speaking,
51 # lowercase letters are compile options, uppercase are expected re_info
52 # bits, and nonalphabetics are match options, controls for how the test is
53 # run, or testing options. The one small surprise is that AREs are the
54 # default, and you must explicitly request lesser flavors of RE. The flags
55 # are as follows. It is admitted that some are not very mnemonic.
56 # There are some others which are purely debugging tools and are not
57 # useful in this file.
59 # - no-op (placeholder)
60 # + provide fake xy equivalence class and ch collating element
61 # % force small state-set cache in matcher (to test cache replace)
62 # ^ beginning of string is not beginning of line
63 # $ end of string is not end of line
64 # * test is Unicode-specific, needs big character set
66 # & test as both ARE and BRE
69 # a turn advanced-features bit on (error unless ERE already)
70 # q literal string, no metacharacters at all
72 # i case-independent matching
73 # o ("opaque") no subexpression capture
74 # p newlines are half-magic, excluded from . and [^ only
75 # w newlines are half-magic, significant to ^ and $ only
76 # n newlines are fully magic, both effects
77 # x expanded RE syntax
78 # t incomplete-match reporting
80 # A backslash-_a_lphanumeric seen
81 # B ERE/ARE literal-_b_race heuristic used
82 # E backslash (_e_scape) seen within []
83 # H looka_h_ead constraint seen
84 # I _i_mpossible to match
85 # L _l_ocale-specific construct seen
86 # M unportable (_m_achine-specific) construct seen
87 # N RE can match empty (_n_ull) string
88 # P non-_P_OSIX construct seen
89 # Q {} _q_uantifier seen
90 # R back _r_eference seen
91 # S POSIX-un_s_pecified syntax seen
92 # T prefers shortest (_t_iny)
93 # U saw original-POSIX botch: unmatched right paren in ERE (_u_gh)
95 # The one area we can't easily test is memory-allocation failures (which
96 # are hard to provoke on command). Embedded NULs also are not tested at
97 # the moment, but this is a historical accident which should be fixed.
101 # test procedures and related
107 # re_info abbreviation mapping table
108 set infonames(A) "REG_UBSALNUM"
109 set infonames(B) "REG_UBRACES"
110 set infonames(E) "REG_UBBS"
111 set infonames(H) "REG_ULOOKAHEAD"
112 set infonames(I) "REG_UIMPOSSIBLE"
113 set infonames(L) "REG_ULOCALE"
114 set infonames(M) "REG_UUNPORT"
115 set infonames(N) "REG_UEMPTYMATCH"
116 set infonames(P) "REG_UNONPOSIX"
117 set infonames(Q) "REG_UBOUNDS"
118 set infonames(R) "REG_UBACKREF"
119 set infonames(S) "REG_UUNSPEC"
120 set infonames(T) "REG_USHORTEST"
121 set infonames(U) "REG_UPBOTCH"
122 set infonameorder "RHQBAUEPSMLNIT" ;# must match bit order, lsb first
124 # set major test number and description
125 proc doing {major desc} {
126 global prefix description testbypassed
128 if {$testbypassed != 0} {
129 puts stdout "!!! bypassed $testbypassed tests in\
130 $prefix, `$description'"
133 set prefix reg-$major
134 set description "reg $desc"
138 # build test number (internal)
140 return [join $testid .]
143 # build description, with possible modifiers (internal)
148 if {[llength $testid] > 1} {
149 set d "([lreplace $testid 0 0]) $d"
154 # build trailing options and flags argument from a flags string (internal)
160 foreach f [split $fl ""] {
161 switch -exact -- $f {
162 "i" { lappend args "-nocase" }
163 "x" { lappend args "-expanded" }
164 "n" { lappend args "-line" }
165 "p" { lappend args "-linestop" }
166 "w" { lappend args "-lineanchor" }
168 default { append flags $f }
171 if {[string compare $flags ""] != 0} {
172 lappend args -$xflags $flags
177 # build info-flags list from a flags string (internal)
178 proc infoflags {fl} {
179 global infonames infonameorder
182 foreach f [split $infonameorder ""] {
183 if {[string first $f $fl] >= 0} {
184 lappend ret $infonames($f)
190 # compilation error expected
191 proc e {testid flags re err} {
192 global prefix ask errorCode
194 # Tcl locale stuff doesn't do the ch/xy test fakery yet
195 if {[string first "+" $flags] >= 0} {
196 # This will register as a skipped test
197 test $prefix.[tno $testid] [desc $testid] localeRegexp {} {}
201 # if &, test as both ARE and BRE
202 set amp [string first "&" $flags]
204 set f [string range $flags 0 [expr $amp - 1]]
205 append f [string range $flags [expr $amp + 1] end]
206 e [linsert $testid end ARE] ${f} $re $err
207 e [linsert $testid end BRE] ${f}b $re $err
211 set cmd [concat [list testregexp -$ask] [flags $flags] [list $re]]
212 set run "list \[catch \{$cmd\}\] \[lindex \$errorCode 1\]"
213 test $prefix.[tno $testid] [desc $testid] \
214 {testregexp} $run [list 1 REG_$err]
217 # match failure expected
218 proc f {testid flags re target args} {
219 global prefix description ask
221 # Tcl locale stuff doesn't do the ch/xy test fakery yet
222 if {[string first "+" $flags] >= 0} {
223 # This will register as a skipped test
224 test $prefix.[tno $testid] [desc $testid] localeRegexp {} {}
228 # if &, test as both ARE and BRE
229 set amp [string first "&" $flags]
231 set f [string range $flags 0 [expr $amp - 1]]
232 append f [string range $flags [expr $amp + 1] end]
233 eval [linsert $args 0 f [linsert $testid end ARE] ${f} $re \
235 eval [linsert $args 0 f [linsert $testid end BRE] ${f}b $re \
241 set infoflags [infoflags $flags]
242 set ccmd [concat [list testregexp -$ask] $f [list $re]]
243 set nsub [expr [llength $args] - 1]
245 # didn't tell us number of subexps
246 set ccmd "lreplace \[$ccmd\] 0 0"
247 set info [list $infoflags]
249 set info [list $nsub $infoflags]
251 lappend testid "compile"
252 test $prefix.[tno $testid] [desc $testid] {testregexp} $ccmd $info
254 set testid [lreplace $testid end end "execute"]
255 set ecmd [concat [list testregexp] $f [list $re $target]]
256 test $prefix.[tno $testid] [desc $testid] {testregexp} $ecmd 0
259 # match expected, internal routine that does the work
260 # parameters like the "real" routines except they don't have "opts",
261 # which is a possibly-empty list of switches for the regexp match attempt
262 # The ! flag is used to indicate expected match failure (for REG_EXPECT,
263 # which wants argument testing even in the event of failure).
264 proc matchexpected {opts testid flags re target args} {
265 global prefix description ask regBug
267 if {[info exists regBug] && $regBug} {
268 # This will register as a skipped test
269 test $prefix.[tno $testid] [desc $testid] knownBug {format 0} {1}
273 # Tcl locale stuff doesn't do the ch/xy test fakery yet
274 if {[string first "+" $flags] >= 0} {
275 # This will register as a skipped test
276 test $prefix.[tno $testid] [desc $testid] localeRegexp {} {}
280 # if &, test as both BRE and ARE
281 set amp [string first "&" $flags]
283 set f [string range $flags 0 [expr $amp - 1]]
284 append f [string range $flags [expr $amp + 1] end]
285 eval [concat [list matchexpected $opts \
286 [linsert $testid end ARE] ${f} $re $target] $args]
287 eval [concat [list matchexpected $opts \
288 [linsert $testid end BRE] ${f}b $re $target] $args]
293 set infoflags [infoflags $flags]
294 set ccmd [concat [list testregexp -$ask] $f [list $re]]
295 set ecmd [concat [list testregexp] $opts $f [list $re $target]]
297 set nsub [expr [llength $args] - 1]
300 for {set i 0} {$i <= $nsub} {incr i} {
307 append refs " \$$name"
310 if {[string first "o" $flags] >= 0} { ;# REG_NOSUB kludge
311 set nsub 0 ;# unsigned value cannot be -1
313 if {[string first "t" $flags] >= 0} { ;# REG_EXPECT
314 incr nsub -1 ;# the extra does not count
316 set ecmd [concat $ecmd $names]
317 set erun "list \[$ecmd\] $refs"
319 if {[string first "!" $flags] >= 0} {
322 set result [concat $retcode $args]
324 set info [list $nsub $infoflags]
325 lappend testid "compile"
326 test $prefix.[tno $testid] [desc $testid] {testregexp} $ccmd $info
327 set testid [lreplace $testid end end "execute"]
328 test $prefix.[tno $testid] [desc $testid] {testregexp} $erun $result
331 # match expected (no missing, empty, or ambiguous submatches)
332 # m testno flags re target mat submat ...
334 eval matchexpected [linsert $args 0 [list]]
337 # match expected (full fanciness)
338 # i testno flags re target mat submat ...
340 eval matchexpected [linsert $args 0 [list "-indices"]]
343 # partial match expected
344 # p testno flags re target mat "" ...
345 # Quirk: number of ""s must be one more than number of subREs.
347 set f [lindex $args 1] ;# add ! flag
348 set args [lreplace $args 1 1 "!$f"]
349 eval matchexpected [linsert $args 0 [list "-indices"]]
353 proc knownBug {args} {
361 # the tests themselves
365 # support functions and preliminary misc.
366 # This is sensitive to changes in message wording, but we really have to
367 # test the code->message expansion at least once.
368 test reg-0.1 "regexp error reporting" {
369 list [catch {regexp (*) ign} msg] $msg
370 } {1 {couldn't compile regular expression pattern: quantifier operand invalid}}
374 doing 1 "basic sanity checks"
377 m 3 & abc xyabxabce abc
381 doing 2 "invalid option combinations"
390 doing 3 "basic syntax"
400 doing 4 "parentheses"
403 m 3 b {\(a\)b} ab ab a
404 m 4 - a((b)c) abc abc bc b
405 m 5 - a(b)(c) abc abc b c
408 # sigh, we blew it on the specs here... someday this will be fixed in POSIX,
409 # but meanwhile, it's fixed in AREs
413 m 11 P a(?:b)c abc abc
414 e 12 e a(?:b)c BADRPT
415 i 13 S a()b ab {0 1} {1 0}
417 i 15 S a(|b)c ac {0 1} {1 0}
418 m 16 S a(b|)c abc abc b
422 doing 5 "simple one-char matching"
423 # general case of brackets done later
426 m 3 & {a[bc]d} abd abd
427 m 4 & {a[bc]d} acd acd
430 m 7 & {a[^bc]d} aed aed
431 f 8 &p "a\[^bc]d" "a\nd"
435 doing 6 "context-dependent syntax"
446 m 10 n "\n^" "x\nb" "\n"
450 m 14 bS {\(x$\)} x x x
452 m 16 b {x$y} "x\$y" "x\$y"
454 m 18 n "x\$\n" "x\n" "x\n"
460 doing 7 "simple quantifiers"
480 m 1 NQ "a{0,1}" "" ""
483 e 4 - "a{1,2,3}" BADBR
485 e 6 - "a{1000}" BADBR
488 m 9 BS "a{b" "a\{b" "a\{b"
489 m 10 BS "a{" "a\{" "a\{"
490 m 11 bQ "a\\{0,1\\}b" cb b
491 e 12 b "a\\{0,1" EBRACE
492 e 13 - "a{0,1\\" BADBR
494 m 15 Q "a{0,0}b" ab b
495 m 16 Q "a{0,1}b" ab ab
497 m 18 Q "a{0,2}b" aab aab
498 m 19 Q "a{0,}b" aab aab
499 m 20 Q "a{1,1}b" aab ab
500 m 21 Q "a{1,3}b" aaaab aaab
502 m 23 Q "a{1,}b" aab aab
504 m 25 Q "a{2,3}b" aaaab aaab
506 m 27 Q "a{2,}b" aaaab aaaab
513 m 3 & {a[[.-.]]} a- a-
514 m 4 &L {a[[.zero.]]} a0 a0
515 m 5 &LM {a[[.zero.]-9]} a2 a2
516 m 6 &M {a[0-[.9.]]} a2 a2
517 m 7 &+L {a[[=x=]]} ax ax
518 m 8 &+L {a[[=x=]]} ay ay
519 f 9 &+L {a[[=x=]]} az
520 e 10 & {a[0-[=x=]]} ERANGE
521 m 11 &L {a[[:digit:]]} a0 a0
522 e 12 & {a[[:woopsie:]]} ECTYPE
523 f 13 &L {a[[:digit:]]} ab
524 e 14 & {a[0-[:digit:]]} ERANGE
525 m 15 &LP {[[:<:]]a} a a
526 m 16 &LP {a[[:>:]]} a a
527 e 17 & {a[[..]]b} ECOLLATE
528 e 18 & {a[[==]]b} ECOLLATE
529 e 19 & {a[[::]]b} ECTYPE
530 e 20 & {a[[.a} EBRACK
531 e 21 & {a[[=a} EBRACK
532 e 22 & {a[[:a} EBRACK
536 e 26 & {a[b-c} EBRACK
537 m 27 &M {a[b-c]} ab ab
538 m 28 & {a[b-b]} ab ab
539 m 29 &M {a[1-2]} a2 a2
540 e 30 & {a[c-b]} ERANGE
541 e 31 & {a[a-b-c]} ERANGE
542 m 32 &M {a[--?]b} a?b a?b
543 m 33 & {a[---]b} a-b a-b
544 m 34 & {a[]b]c} a]c a]c
545 m 35 EP {a[\]]b} a]b a]b
547 m 37 bE {a[\]]b} "a\\]b" "a\\]b"
548 m 38 eE {a[\]]b} "a\\]b" "a\\]b"
549 m 39 EP {a[\\]b} "a\\b" "a\\b"
550 m 40 eE {a[\\]b} "a\\b" "a\\b"
551 m 41 bE {a[\\]b} "a\\b" "a\\b"
552 e 42 - {a[\Z]b} EESCAPE
553 m 43 & {a[[b]c} "a\[c" "a\[c"
554 m 44 EMP* {a[\u00fe-\u0507][\u00ff-\u0300]b} \
555 "a\u0102\u02ffb" "a\u0102\u02ffb"
559 doing 10 "anchors and newlines"
567 m 8 &n "^a" "b\na" "a"
568 i 9 &w "^a" "a\na" {0 0}
569 i 10 &n^ "^a" "a\na" {2 2}
571 m 12 &n "a\$" "a\nb" "a"
572 i 13 &n "a\$" "a\na" {0 0}
576 m 17 b {$$} "\$" "\$"
579 i 20 &nN "^\$" "a\n\nb" {2 1}
581 m 22 b {$^} "\$^" "\$^"
584 f 25 ^nP {\Aa} "b\na"
587 f 28 {$nP} {a\Z} "a\nb"
595 doing 11 "boundary constraints"
596 m 1 &LP {[[:<:]]a} a a
597 m 2 &LP {[[:<:]]a} -a a
598 f 3 &LP {[[:<:]]a} ba
599 m 4 &LP {a[[:>:]]} a a
600 m 5 &LP {a[[:>:]]} a- a
601 f 6 &LP {a[[:>:]]} ab
616 e 21 - {[[:<:]]*} BADRPT
617 e 22 - {[[:>:]]*} BADRPT
631 doing 12 "character classes"
632 m 1 LP {a\db} a0b a0b
635 m 4 LP {a\Db} axb axb
636 m 5 LP "a\\sb" "a b" "a b"
637 m 6 LP "a\\sb" "a\tb" "a\tb"
638 m 7 LP "a\\sb" "a\nb" "a\nb"
640 m 9 LP {a\Sb} axb axb
641 f 10 LP "a\\Sb" "a b"
642 m 11 LP {a\wb} axb axb
645 m 14 LP {a\Wb} a-b a-b
646 m 15 LP {\y\w+z\y} adze-guz guz
647 m 16 LPE {a[\d]b} a1b a1b
648 m 17 LPE "a\[\\s]b" "a b" "a b"
649 m 18 LPE {a[\w]b} axb axb
657 m 4 bAS {a\wb} awb awb
658 m 5 eAS {a\wb} awb awb
659 m 6 PL "a\\ab" "a\007b" "a\007b"
660 m 7 P "a\\bb" "a\bb" "a\bb"
661 m 8 P {a\Bb} "a\\b" "a\\b"
662 m 9 MP "a\\chb" "a\bb" "a\bb"
663 m 10 MP "a\\cHb" "a\bb" "a\bb"
664 m 11 LMP "a\\e" "a\033" "a\033"
665 m 12 P "a\\fb" "a\fb" "a\fb"
666 m 13 P "a\\nb" "a\nb" "a\nb"
667 m 14 P "a\\rb" "a\rb" "a\rb"
668 m 15 P "a\\tb" "a\tb" "a\tb"
669 m 16 P "a\\u0008x" "a\bx" "a\bx"
670 e 17 - {a\u008x} EESCAPE
671 m 18 P "a\\u00088x" "a\b8x" "a\b8x"
672 m 19 P "a\\U00000008x" "a\bx" "a\bx"
673 e 20 - {a\U0000008x} EESCAPE
674 m 21 P "a\\vb" "a\vb" "a\vb"
675 m 22 MP "a\\x08x" "a\bx" "a\bx"
676 e 23 - {a\xq} EESCAPE
677 m 24 MP "a\\x0008x" "a\bx" "a\bx"
679 m 26 MP "a\\010b" "a\bb" "a\bb"
683 doing 14 "back references"
685 m 1 RP {a(b*)c\1} abbcbb abbcbb bb
686 m 2 RP {a(b*)c\1} ac ac ""
687 f 3 RP {a(b*)c\1} abbcb
688 m 4 RP {a(b*)\1} abbcbb abb b
689 m 5 RP {a(b|bb)\1} abbcbb abb b
690 m 6 RP {a([bc])\1} abb abb b
691 f 7 RP {a([bc])\1} abc
692 m 8 RP {a([bc])\1} abcabb abb b
693 f 9 RP {a([bc])*\1} abc
694 f 10 RP {a([bc])\1} abB
695 m 11 iRP {a([bc])\1} abB abB b
696 m 12 RP {a([bc])\1+} abbb abbb b
697 m 13 QRP "a(\[bc])\\1{3,4}" abbbb abbbb b
698 f 14 QRP "a(\[bc])\\1{3,4}" abbb
699 m 15 RP {a([bc])\1*} abbb abbb b
700 m 16 RP {a([bc])\1*} ab ab b
701 m 17 RP {a([bc])(\1*)} ab ab b ""
702 e 18 - {a((b)\1)} ESUBREG
703 e 19 - {a(b)c\2} ESUBREG
704 m 20 bR {a\(b*\)c\1} abbcbb abbcbb bb
708 doing 15 "octal escapes vs back references"
709 # initial zero is always octal
710 m 1 MP "a\\010b" "a\bb" "a\bb"
711 m 2 MP "a\\0070b" "a\0070b" "a\0070b"
712 m 3 MP "a\\07b" "a\007b" "a\007b"
713 m 4 MP "a(b)(b)(b)(b)(b)(b)(b)(b)(b)(b)\\07c" "abbbbbbbbbb\007c" \
714 "abbbbbbbbbb\007c" "b" "b" "b" "b" "b" "b" \
716 # a single digit is always a backref
718 # otherwise it's a backref only if within range (barf!)
719 m 6 MP "a\\10b" "a\bb" "a\bb"
720 m 7 MP {a\101b} aAb aAb
721 m 8 RP {a(b)(b)(b)(b)(b)(b)(b)(b)(b)(b)\10c} abbbbbbbbbbbc \
722 abbbbbbbbbbbc b b b b b b b \
724 # but we're fussy about border cases -- guys who want octal should use the zero
725 e 9 - {a((((((((((b\10))))))))))c} ESUBREG
726 # BREs don't have octal, EREs don't have backrefs
727 m 10 MP "a\\12b" "a\nb" "a\nb"
728 e 11 b {a\12b} ESUBREG
729 m 12 eAS {a\12b} a12b a12b
733 doing 16 "expanded syntax"
734 m 1 xP "a b c" "abc" "abc"
735 m 2 xP "a b #oops\nc\td" "abcd" "abcd"
736 m 3 x "a\\ b\\\tc" "a b\tc" "a b\tc"
737 m 4 xP "a b\\#c" "ab#c" "ab#c"
738 m 5 xP "a b\[c d]e" "ab e" "ab e"
739 m 6 xP "a b\[c#d]e" "ab#e" "ab#e"
740 m 7 xP "a b\[c#d]e" "abde" "abde"
741 m 8 xSPB "ab{ d" "ab\{d" "ab\{d"
742 m 9 xPQ "ab{ 1 , 2 }c" "abc" "abc"
746 doing 17 "misc syntax"
747 m 1 P a(?#comment)b ab ab
751 doing 18 "unmatchable REs"
756 doing 19 "case independence"
760 m 4 &iM {a[b-d]} aC aC
765 doing 20 "directors and embedded options"
768 m 3 &P ***=a*b a*b a*b
769 m 4 q ***=a*b ***=a*b ***=a*b
770 m 5 bLP {***:\w+} ab ab
771 m 6 eLP {***:\w+} ab ab
772 e 7 & ***:***=a*b BADRPT
773 m 8 &P ***:(?b)a+b a+b a+b
774 m 9 P (?b)a+b a+b a+b
775 e 10 e {(?b)\w+} BADRPT
776 m 11 bAS {(?b)\w+} (?b)w+ (?b)w+
779 m 14 APS {(?e)\W+} WW WW
781 f 16 P "(?m)a.b" "a\nb"
782 m 17 P "(?m)^b" "a\nb" "b"
783 f 18 P "(?n)a.b" "a\nb"
784 m 19 P "(?n)^b" "a\nb" "b"
785 f 20 P "(?p)a.b" "a\nb"
786 f 21 P "(?p)^b" "a\nb"
787 m 22 P (?q)a+b a+b a+b
788 m 23 nP "(?s)a.b" "a\nb" "a\nb"
789 m 24 xP "(?t)a b" "a b" "a b"
790 m 25 P "(?w)a.b" "a\nb" "a\nb"
791 m 26 P "(?w)^b" "a\nb" "b"
792 m 27 P "(?x)a b" "ab" "ab"
794 m 29 P (?ici)a+ Aa Aa
795 e 30 P (?i)(?q)a+ BADRPT
796 m 31 P (?q)(?i)a+ (?i)a+ (?i)a+
798 m 33 xP "(?q)a b" "a b" "a b"
799 m 34 P "(?qx)a b" "a b" "a b"
805 m 1 - a(b)c abc abc b
806 m 2 P a(?:b)c xabc abc
807 m 3 - a((b))c xabcy abc b b
808 m 4 P a(?:(b))c abcy abc b
809 m 5 P a((?:b))c abc abc b
810 m 6 P a(?:(?:b))c abc abc
811 i 7 Q "a(b){0}c" ac {0 1} {-1 -1}
812 m 8 - a(b)c(d)e abcde abcde b d
813 m 9 - (b)c(d)e bcde bcde b d
814 m 10 - a(b)(d)e abde abde b d
815 m 11 - a(b)c(d) abcd abcd b d
816 m 12 - (ab)(cd) xabcdy abcd ab cd
817 m 13 - a(b)?c xabcy abc b
818 i 14 - a(b)?c xacy {1 2} {-1 -1}
819 m 15 - a(b)?c(d)?e xabcdey abcde b d
820 i 16 - a(b)?c(d)?e xacdey {1 4} {-1 -1} {3 3}
821 i 17 - a(b)?c(d)?e xabcey {1 4} {2 2} {-1 -1}
822 i 18 - a(b)?c(d)?e xacey {1 3} {-1 -1} {-1 -1}
823 m 19 - a(b)*c xabcy abc b
824 i 20 - a(b)*c xabbbcy {1 5} {4 4}
825 i 21 - a(b)*c xacy {1 2} {-1 -1}
826 m 22 - a(b*)c xabbbcy abbbc bbb
827 m 23 - a(b*)c xacy ac ""
829 m 25 - a(b)+c xabcy abc b
830 i 26 - a(b)+c xabbbcy {1 5} {4 4}
831 m 27 - a(b+)c xabbbcy abbbc bbb
832 i 28 Q "a(b){2,3}c" xabbbcy {1 5} {4 4}
833 i 29 Q "a(b){2,3}c" xabbcy {1 4} {3 3}
834 f 30 Q "a(b){2,3}c" xabcy
835 m 31 LP "\\y(\\w+)\\y" "-- abc-" "abc" "abc"
836 m 32 - a((b|c)d+)+ abacdbd acdbd bd b
837 m 33 N (.*).* abc abc abc
838 m 34 N (a*)* bc "" ""
842 doing 22 "multicharacter collating elements"
844 m 1 &+L {a[c]e} ace ace
846 m 3 &+L {a[[.ch.]]} ach ach
847 f 4 &+L {a[[.ch.]]} ace
848 m 5 &+L {a[c[.ch.]]} ac ac
849 m 6 &+L {a[c[.ch.]]} ace ac
850 m 7 &+L {a[c[.ch.]]} ache ach
852 m 9 &+L {a[^c]e} abe abe
853 m 10 &+L {a[^c]e} ache ache
854 f 11 &+L {a[^[.ch.]]} ach
855 m 12 &+L {a[^[.ch.]]} ace ac
856 m 13 &+L {a[^[.ch.]]} ac ac
857 m 14 &+L {a[^[.ch.]]} abe ab
858 f 15 &+L {a[^c[.ch.]]} ach
859 f 16 &+L {a[^c[.ch.]]} ace
860 f 17 &+L {a[^c[.ch.]]} ac
861 m 18 &+L {a[^c[.ch.]]} abe ab
862 m 19 &+L {a[^b]} ac ac
863 m 20 &+L {a[^b]} ace ac
864 m 21 &+L {a[^b]} ach ach
869 doing 23 "lookahead constraints"
870 m 1 HP a(?=b)b* ab ab
872 m 3 HP a(?=b)b*(?=c)c* abc abc
873 f 4 HP a(?=b)b*(?=c)c* ab
881 doing 24 "non-greedy quantifiers"
883 m 2 PT ab+?c abbc abbc
885 m 4 PT ab*?c abbc abbc
888 m 7 PQT "ab{2,4}?" abbbb abb
889 m 8 PQT "ab{2,4}?c" abbbbc abbbbc
890 m 9 - 3z* 123zzzz456 3zzzz
891 m 10 PT 3z*? 123zzzz456 3
892 m 11 - z*4 123zzzz456 zzzz4
893 m 12 PT z*?4 123zzzz456 zzzz4
897 doing 25 "mixed quantifiers"
898 # this is very incomplete as yet
900 m 1 PNT {^(.*?)(a*)$} xyza xyza xyz a
901 m 2 PNT {^(.*?)(a*)$} xyzaa xyzaa xyz aa
902 m 3 PNT {^(.*?)(a*)$} xyz xyz xyz ""
906 doing 26 "tricky cases"
907 # attempts to trick the matcher into accepting a short match
908 m 1 - (week|wee)(night|knights) weeknights weeknights \
910 m 2 RP {a(bc*).*\1} abccbccb abccbccb b
911 m 3 - {a(b.[bc]*)+} abcbd abcbd bd
915 doing 27 "implementation misc."
916 # duplicate arcs are suppressed
917 m 1 P a(?:b|b)c abc abc
918 # make color/subcolor relationship go back and forth
919 m 2 & {[ab][ab][ab]} aba aba
920 m 3 & {[ab][ab][ab][ab][ab][ab][ab]} abababa abababa
924 doing 28 "boundary busters etc."
925 # color-descriptor allocation changes at 10
926 m 1 & abcdefghijkl abcdefghijkl abcdefghijkl
927 # so does arc allocation
928 m 2 P a(?:b|c|d|e|f|g|h|i|j|k|l|m)n agn agn
929 # subexpression tracking also at 10
930 m 3 - a(((((((((((((b)))))))))))))c abc abc b b b b b b b b b b b b b
931 # state-set handling changes slightly at unsigned size (might be 64...)
932 # (also stresses arc allocation)
933 m 4 Q "ab{1,100}c" abbc abbc
934 m 5 Q "ab{1,100}c" abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbc \
935 abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbc
937 abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbc \
938 abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbc
939 # force small cache and bust it, several ways
940 m 7 LP {\w+abcdefgh} xyzabcdefgh xyzabcdefgh
941 m 8 %LP {\w+abcdefgh} xyzabcdefgh xyzabcdefgh
942 m 9 %LP {\w+abcdefghijklmnopqrst} xyzabcdefghijklmnopqrst \
943 xyzabcdefghijklmnopqrst
944 i 10 %LP {\w+(abcdefgh)?} xyz {0 2} {-1 -1}
945 i 11 %LP {\w+(abcdefgh)?} xyzabcdefg {0 9} {-1 -1}
946 i 12 %LP {\w+(abcdefghijklmnopqrst)?} xyzabcdefghijklmnopqrs \
951 doing 29 "incomplete matches"
952 p 1 t def abc {3 2} ""
953 p 2 t bcd abc {1 2} ""
954 p 3 t abc abab {0 3} ""
955 p 4 t abc abdab {3 4} ""
956 i 5 t abc abc {0 2} {0 2}
957 i 6 t abc xyabc {2 4} {2 4}
958 p 7 t abc+ xyab {2 3} ""
959 i 8 t abc+ xyabc {2 4} {2 4}
960 knownBug i 9 t abc+ xyabcd {2 4} {6 5}
961 i 10 t abc+ xyabcdd {2 4} {7 6}
962 p 11 tPT abc+? xyab {2 3} ""
963 # the retain numbers in these two may look wrong, but they aren't
964 i 12 tPT abc+? xyabc {2 4} {5 4}
965 i 13 tPT abc+? xyabcc {2 4} {6 5}
966 i 14 tPT abc+? xyabcd {2 4} {6 5}
967 i 15 tPT abc+? xyabcdd {2 4} {7 6}
968 i 16 t abcd|bc xyabc {3 4} {2 4}
969 p 17 tn .*k "xx\nyyy" {3 5} ""
972 doing 30 "misc. oddities and old bugs"
977 m 5 & ^a*b aaaab aaaab
978 m 6 &M {[0-6][1-2][0-3][0-6][1-6][0-6]} 010010 010010
979 # temporary REG_BOSONLY kludge
982 # back to normal stuff
983 m 9 HLP {(?n)^(?![t#])\S+} "tk\n\n#\n#\nit0" it0
986 # flush any leftover complaints
989 # Tests resulting from bugs reported by users
990 test reg-31.1 {[[:xdigit:]] behaves correctly when followed by [[:space:]]} {
991 set str {2:::DebugWin32}
992 set re {([[:xdigit:]])([[:space:]]*)}
993 list [regexp $re $str match xdigit spaces] $match $xdigit $spaces
994 # Code used to produce {1 2:::DebugWin32 2 :::DebugWin32} !!!
997 test reg-32.1 {canmatch functionality -- at end} {
1000 # can match at the final d, if '%' follows
1001 set res [testregexp -xflags -- c $pat $line resvar]
1005 test reg-32.2 {canmatch functionality -- at end} {
1008 # can only match after the end of the string
1009 set res [testregexp -xflags -- c $pat $line resvar]
1013 test reg-32.3 {canmatch functionality -- not last char} {
1016 # can only match after the end of the string
1017 set res [testregexp -xflags -- c $pat $line resvar]
1021 test reg-32.3.1 {canmatch functionality -- no match} {
1024 # can match the last char, if followed by x
1025 set res [testregexp -xflags -- c $pat $line resvar]
1029 test reg-32.4 {canmatch functionality -- last char} {knownBug} {
1032 # can match the last char, if followed by x
1033 set res [testregexp -xflags -- c $pat $line resvar]
1037 test reg-32.4.1 {canmatch functionality -- last char} {knownBug} {
1040 # can match the last char, if followed by x
1041 set res [testregexp -xflags -- c $pat $line resvar]
1045 test reg-32.5 {canmatch functionality -- last char} {knownBug} {
1048 # can match the last char, if followed by not-d and x.
1049 set res [testregexp -xflags -- c $pat $line resvar]
1053 test reg-32.6 {canmatch functionality -- last char} {knownBug} {
1054 set pat {[^a]%[^\r\n]*$}
1056 # can match at the final d, if '%' follows
1057 set res [testregexp -xflags -- c $pat $line resvar]
1061 test reg-32.7 {canmatch functionality -- last char} {knownBug} {
1064 # can match at the final d, if '%' follows
1065 set res [testregexp -xflags -- c $pat $line resvar]
1069 test reg-32.8 {canmatch functionality -- last char} {knownBug} {
1072 # can match at the final d, if '%' follows
1073 set res [testregexp -xflags -- c $pat $line resvar]
1077 test reg-32.9 {canmatch functionality -- more complex case} {knownBug} {
1078 set pat {((\B\B|\Bh+line)[ \t]*|[^\B]%[^\r\n]*)$}
1080 # can match at the final d, if '%' follows
1081 set res [testregexp -xflags -- c $pat $line resvar]
1085 # Tests reg-33.*: Checks for bug fixes
1087 test reg-33.1 {Bug 230589} {
1088 regexp {[ ]*(^|[^%])%V} "*%V2" m s
1091 test reg-33.2 {Bug 504785} {
1092 regexp -inline {([^_.]*)([^.]*)\.(..)(.).*} bbcos_001_c01.q1la
1093 } {bbcos_001_c01.q1la bbcos _001_c01 q1 l}
1095 test reg-33.3 {Bug 505048} {
1096 regexp {\A\s*[^<]*\s*<([^>]+)>} a<a>
1099 test reg-33.4 {Bug 505048} {
1100 regexp {\A\s*([^b]*)b} ab
1103 test reg-33.5 {Bug 505048} {
1104 regexp {\A\s*[^b]*(b)} ab
1107 test reg-33.6 {Bug 505048} {
1108 regexp {\A(\s*)[^b]*(b)} ab
1111 test reg-33.7 {Bug 505048} {
1112 regexp {\A\s*[^b]*b} ab
1115 test reg-33.8 {Bug 505048} {
1116 regexp -inline {\A\s*[^b]*b} ab
1119 test reg-33.9 {Bug 505048} {
1120 regexp -indices -inline {\A\s*[^b]*b} ab
1123 test reg-33.10 {Bug 840258} {
1124 regsub {(^|\n)+\.*b} \n.b {} tmp
1127 test reg-33.11 {Bug 840258} {
1128 regsub {(^|[\n\r]+)\.*\?<.*?(\n|\r)+} \
1129 "TQ\r\n.?<5000267>Test already stopped\r\n" {} tmp
1133 ::tcltest::cleanupTests