--- /dev/null
+# reg.test --
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+# (Don't panic if you are seeing this as part of the reg distribution
+# and aren't using Tcl -- reg's own regression tester also knows how
+# to read this file, ignoring the Tcl-isms.)
+#
+# Copyright (c) 1998, 1999 Henry Spencer. All rights reserved.
+#
+# RCS: @(#) $Id$
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+# All tests require the testregexp command, return if this
+# command doesn't exist
+
+::tcltest::testConstraint testregexp \
+ [expr {[info commands testregexp] != {}}]
+::tcltest::testConstraint localeRegexp 0
+
+# This file uses some custom procedures, defined below, for regexp regression
+# testing. The name of the procedure indicates the general nature of the
+# test:
+# e compile error expected
+# f match failure expected
+# m successful match
+# i successful match with -indices (used in checking things like
+# nonparticipating subexpressions)
+# p unsuccessful match with -indices (!!) (used in checking
+# partial-match reporting)
+# There is also "doing" which sets up title and major test number for each
+# block of tests.
+
+# The first 3 arguments are constant: a minor number (which often gets
+# a letter or two suffixed to it internally), some flags, and the RE itself.
+# For e, the remaining argument is the name of the compile error expected,
+# less the leading "REG_". For the rest, the next argument is the string
+# to try the match against. Remaining arguments are the substring expected
+# to be matched, and any substrings expected to be matched by subexpressions.
+# (For f, these arguments are optional, and if present are ignored except
+# that they indicate how many subexpressions should be present in the RE.)
+# It is an error for the number of subexpression arguments to be wrong.
+# Cases involving nonparticipating subexpressions, checking where empty
+# substrings are located, etc. should be done using i and p.
+
+# The flag characters are complex and a bit eclectic. Generally speaking,
+# lowercase letters are compile options, uppercase are expected re_info
+# bits, and nonalphabetics are match options, controls for how the test is
+# run, or testing options. The one small surprise is that AREs are the
+# default, and you must explicitly request lesser flavors of RE. The flags
+# are as follows. It is admitted that some are not very mnemonic.
+# There are some others which are purely debugging tools and are not
+# useful in this file.
+#
+# - no-op (placeholder)
+# + provide fake xy equivalence class and ch collating element
+# % force small state-set cache in matcher (to test cache replace)
+# ^ beginning of string is not beginning of line
+# $ end of string is not end of line
+# * test is Unicode-specific, needs big character set
+#
+# & test as both ARE and BRE
+# b BRE
+# e ERE
+# a turn advanced-features bit on (error unless ERE already)
+# q literal string, no metacharacters at all
+#
+# i case-independent matching
+# o ("opaque") no subexpression capture
+# p newlines are half-magic, excluded from . and [^ only
+# w newlines are half-magic, significant to ^ and $ only
+# n newlines are fully magic, both effects
+# x expanded RE syntax
+# t incomplete-match reporting
+#
+# A backslash-_a_lphanumeric seen
+# B ERE/ARE literal-_b_race heuristic used
+# E backslash (_e_scape) seen within []
+# H looka_h_ead constraint seen
+# I _i_mpossible to match
+# L _l_ocale-specific construct seen
+# M unportable (_m_achine-specific) construct seen
+# N RE can match empty (_n_ull) string
+# P non-_P_OSIX construct seen
+# Q {} _q_uantifier seen
+# R back _r_eference seen
+# S POSIX-un_s_pecified syntax seen
+# T prefers shortest (_t_iny)
+# U saw original-POSIX botch: unmatched right paren in ERE (_u_gh)
+
+# The one area we can't easily test is memory-allocation failures (which
+# are hard to provoke on command). Embedded NULs also are not tested at
+# the moment, but this is a historical accident which should be fixed.
+
+
+
+# test procedures and related
+
+set ask "about"
+set xflags "xflags"
+set testbypassed 0
+
+# re_info abbreviation mapping table
+set infonames(A) "REG_UBSALNUM"
+set infonames(B) "REG_UBRACES"
+set infonames(E) "REG_UBBS"
+set infonames(H) "REG_ULOOKAHEAD"
+set infonames(I) "REG_UIMPOSSIBLE"
+set infonames(L) "REG_ULOCALE"
+set infonames(M) "REG_UUNPORT"
+set infonames(N) "REG_UEMPTYMATCH"
+set infonames(P) "REG_UNONPOSIX"
+set infonames(Q) "REG_UBOUNDS"
+set infonames(R) "REG_UBACKREF"
+set infonames(S) "REG_UUNSPEC"
+set infonames(T) "REG_USHORTEST"
+set infonames(U) "REG_UPBOTCH"
+set infonameorder "RHQBAUEPSMLNIT" ;# must match bit order, lsb first
+
+# set major test number and description
+proc doing {major desc} {
+ global prefix description testbypassed
+
+ if {$testbypassed != 0} {
+ puts stdout "!!! bypassed $testbypassed tests in\
+ $prefix, `$description'"
+ }
+
+ set prefix reg-$major
+ set description "reg $desc"
+ set testbypassed 0
+}
+
+# build test number (internal)
+proc tno {testid} {
+ return [join $testid .]
+}
+
+# build description, with possible modifiers (internal)
+proc desc {testid} {
+ global description
+
+ set d $description
+ if {[llength $testid] > 1} {
+ set d "([lreplace $testid 0 0]) $d"
+ }
+ return $d
+}
+
+# build trailing options and flags argument from a flags string (internal)
+proc flags {fl} {
+ global xflags
+
+ set args [list]
+ set flags ""
+ foreach f [split $fl ""] {
+ switch -exact -- $f {
+ "i" { lappend args "-nocase" }
+ "x" { lappend args "-expanded" }
+ "n" { lappend args "-line" }
+ "p" { lappend args "-linestop" }
+ "w" { lappend args "-lineanchor" }
+ "-" { }
+ default { append flags $f }
+ }
+ }
+ if {[string compare $flags ""] != 0} {
+ lappend args -$xflags $flags
+ }
+ return $args
+}
+
+# build info-flags list from a flags string (internal)
+proc infoflags {fl} {
+ global infonames infonameorder
+
+ set ret [list]
+ foreach f [split $infonameorder ""] {
+ if {[string first $f $fl] >= 0} {
+ lappend ret $infonames($f)
+ }
+ }
+ return $ret
+}
+
+# compilation error expected
+proc e {testid flags re err} {
+ global prefix ask errorCode
+
+ # Tcl locale stuff doesn't do the ch/xy test fakery yet
+ if {[string first "+" $flags] >= 0} {
+ # This will register as a skipped test
+ test $prefix.[tno $testid] [desc $testid] localeRegexp {} {}
+ return
+ }
+
+ # if &, test as both ARE and BRE
+ set amp [string first "&" $flags]
+ if {$amp >= 0} {
+ set f [string range $flags 0 [expr $amp - 1]]
+ append f [string range $flags [expr $amp + 1] end]
+ e [linsert $testid end ARE] ${f} $re $err
+ e [linsert $testid end BRE] ${f}b $re $err
+ return
+ }
+
+ set cmd [concat [list testregexp -$ask] [flags $flags] [list $re]]
+ set run "list \[catch \{$cmd\}\] \[lindex \$errorCode 1\]"
+ test $prefix.[tno $testid] [desc $testid] \
+ {testregexp} $run [list 1 REG_$err]
+}
+
+# match failure expected
+proc f {testid flags re target args} {
+ global prefix description ask
+
+ # Tcl locale stuff doesn't do the ch/xy test fakery yet
+ if {[string first "+" $flags] >= 0} {
+ # This will register as a skipped test
+ test $prefix.[tno $testid] [desc $testid] localeRegexp {} {}
+ return
+ }
+
+ # if &, test as both ARE and BRE
+ set amp [string first "&" $flags]
+ if {$amp >= 0} {
+ set f [string range $flags 0 [expr $amp - 1]]
+ append f [string range $flags [expr $amp + 1] end]
+ eval [linsert $args 0 f [linsert $testid end ARE] ${f} $re \
+ $target]
+ eval [linsert $args 0 f [linsert $testid end BRE] ${f}b $re \
+ $target]
+ return
+ }
+
+ set f [flags $flags]
+ set infoflags [infoflags $flags]
+ set ccmd [concat [list testregexp -$ask] $f [list $re]]
+ set nsub [expr [llength $args] - 1]
+ if {$nsub == -1} {
+ # didn't tell us number of subexps
+ set ccmd "lreplace \[$ccmd\] 0 0"
+ set info [list $infoflags]
+ } else {
+ set info [list $nsub $infoflags]
+ }
+ lappend testid "compile"
+ test $prefix.[tno $testid] [desc $testid] {testregexp} $ccmd $info
+
+ set testid [lreplace $testid end end "execute"]
+ set ecmd [concat [list testregexp] $f [list $re $target]]
+ test $prefix.[tno $testid] [desc $testid] {testregexp} $ecmd 0
+}
+
+# match expected, internal routine that does the work
+# parameters like the "real" routines except they don't have "opts",
+# which is a possibly-empty list of switches for the regexp match attempt
+# The ! flag is used to indicate expected match failure (for REG_EXPECT,
+# which wants argument testing even in the event of failure).
+proc matchexpected {opts testid flags re target args} {
+ global prefix description ask regBug
+
+ if {[info exists regBug] && $regBug} {
+ # This will register as a skipped test
+ test $prefix.[tno $testid] [desc $testid] knownBug {format 0} {1}
+ return
+ }
+
+ # Tcl locale stuff doesn't do the ch/xy test fakery yet
+ if {[string first "+" $flags] >= 0} {
+ # This will register as a skipped test
+ test $prefix.[tno $testid] [desc $testid] localeRegexp {} {}
+ return
+ }
+
+ # if &, test as both BRE and ARE
+ set amp [string first "&" $flags]
+ if {$amp >= 0} {
+ set f [string range $flags 0 [expr $amp - 1]]
+ append f [string range $flags [expr $amp + 1] end]
+ eval [concat [list matchexpected $opts \
+ [linsert $testid end ARE] ${f} $re $target] $args]
+ eval [concat [list matchexpected $opts \
+ [linsert $testid end BRE] ${f}b $re $target] $args]
+ return
+ }
+
+ set f [flags $flags]
+ set infoflags [infoflags $flags]
+ set ccmd [concat [list testregexp -$ask] $f [list $re]]
+ set ecmd [concat [list testregexp] $opts $f [list $re $target]]
+
+ set nsub [expr [llength $args] - 1]
+ set names [list]
+ set refs ""
+ for {set i 0} {$i <= $nsub} {incr i} {
+ if {$i == 0} {
+ set name match
+ } else {
+ set name sub$i
+ }
+ lappend names $name
+ append refs " \$$name"
+ set $name ""
+ }
+ if {[string first "o" $flags] >= 0} { ;# REG_NOSUB kludge
+ set nsub 0 ;# unsigned value cannot be -1
+ }
+ if {[string first "t" $flags] >= 0} { ;# REG_EXPECT
+ incr nsub -1 ;# the extra does not count
+ }
+ set ecmd [concat $ecmd $names]
+ set erun "list \[$ecmd\] $refs"
+ set retcode [list 1]
+ if {[string first "!" $flags] >= 0} {
+ set retcode [list 0]
+ }
+ set result [concat $retcode $args]
+
+ set info [list $nsub $infoflags]
+ lappend testid "compile"
+ test $prefix.[tno $testid] [desc $testid] {testregexp} $ccmd $info
+ set testid [lreplace $testid end end "execute"]
+ test $prefix.[tno $testid] [desc $testid] {testregexp} $erun $result
+}
+
+# match expected (no missing, empty, or ambiguous submatches)
+# m testno flags re target mat submat ...
+proc m {args} {
+ eval matchexpected [linsert $args 0 [list]]
+}
+
+# match expected (full fanciness)
+# i testno flags re target mat submat ...
+proc i {args} {
+ eval matchexpected [linsert $args 0 [list "-indices"]]
+}
+
+# partial match expected
+# p testno flags re target mat "" ...
+# Quirk: number of ""s must be one more than number of subREs.
+proc p {args} {
+ set f [lindex $args 1] ;# add ! flag
+ set args [lreplace $args 1 1 "!$f"]
+ eval matchexpected [linsert $args 0 [list "-indices"]]
+}
+
+# test is a knownBug
+proc knownBug {args} {
+ set ::regBug 1
+ uplevel #0 $args
+ set ::regBug 0
+}
+
+
+
+# the tests themselves
+
+
+
+# support functions and preliminary misc.
+# This is sensitive to changes in message wording, but we really have to
+# test the code->message expansion at least once.
+test reg-0.1 "regexp error reporting" {
+ list [catch {regexp (*) ign} msg] $msg
+} {1 {couldn't compile regular expression pattern: quantifier operand invalid}}
+
+
+
+doing 1 "basic sanity checks"
+m 1 & abc abc abc
+f 2 & abc def
+m 3 & abc xyabxabce abc
+
+
+
+doing 2 "invalid option combinations"
+e 1 qe a INVARG
+e 2 qa a INVARG
+e 3 qx a INVARG
+e 4 qn a INVARG
+e 5 ba a INVARG
+
+
+
+doing 3 "basic syntax"
+i 1 &NS "" a {0 -1}
+m 2 NS a| a a
+m 3 - a|b a a
+m 4 - a|b b b
+m 5 NS a||b b b
+m 6 & ab ab ab
+
+
+
+doing 4 "parentheses"
+m 1 - (a)e ae ae a
+m 2 o (a)e ae
+m 3 b {\(a\)b} ab ab a
+m 4 - a((b)c) abc abc bc b
+m 5 - a(b)(c) abc abc b c
+e 6 - a(b EPAREN
+e 7 b {a\(b} EPAREN
+# sigh, we blew it on the specs here... someday this will be fixed in POSIX,
+# but meanwhile, it's fixed in AREs
+m 8 eU a)b a)b a)b
+e 9 - a)b EPAREN
+e 10 b {a\)b} EPAREN
+m 11 P a(?:b)c abc abc
+e 12 e a(?:b)c BADRPT
+i 13 S a()b ab {0 1} {1 0}
+m 14 SP a(?:)b ab ab
+i 15 S a(|b)c ac {0 1} {1 0}
+m 16 S a(b|)c abc abc b
+
+
+
+doing 5 "simple one-char matching"
+# general case of brackets done later
+m 1 & a.b axb axb
+f 2 &n "a.b" "a\nb"
+m 3 & {a[bc]d} abd abd
+m 4 & {a[bc]d} acd acd
+f 5 & {a[bc]d} aed
+f 6 & {a[^bc]d} abd
+m 7 & {a[^bc]d} aed aed
+f 8 &p "a\[^bc]d" "a\nd"
+
+
+
+doing 6 "context-dependent syntax"
+# plus odds and ends
+e 1 - * BADRPT
+m 2 b * * *
+m 3 b {\(*\)} * * *
+e 4 - (*) BADRPT
+m 5 b ^* * *
+e 6 - ^* BADRPT
+f 7 & ^b ^b
+m 8 b x^ x^ x^
+f 9 I x^ x
+m 10 n "\n^" "x\nb" "\n"
+f 11 bS {\(^b\)} ^b
+m 12 - (^b) b b b
+m 13 & {x$} x x
+m 14 bS {\(x$\)} x x x
+m 15 - {(x$)} x x x
+m 16 b {x$y} "x\$y" "x\$y"
+f 17 I {x$y} xy
+m 18 n "x\$\n" "x\n" "x\n"
+e 19 - + BADRPT
+e 20 - ? BADRPT
+
+
+
+doing 7 "simple quantifiers"
+m 1 &N a* aa aa
+i 2 &N a* b {0 -1}
+m 3 - a+ aa aa
+m 4 - a?b ab ab
+m 5 - a?b b b
+e 6 - ** BADRPT
+m 7 bN ** *** ***
+e 8 & a** BADRPT
+e 9 & a**b BADRPT
+e 10 & *** BADRPT
+e 11 - a++ BADRPT
+e 12 - a?+ BADRPT
+e 13 - a?* BADRPT
+e 14 - a+* BADRPT
+e 15 - a*+ BADRPT
+
+
+
+doing 8 "braces"
+m 1 NQ "a{0,1}" "" ""
+m 2 NQ "a{0,1}" ac a
+e 3 - "a{1,0}" BADBR
+e 4 - "a{1,2,3}" BADBR
+e 5 - "a{257}" BADBR
+e 6 - "a{1000}" BADBR
+e 7 - "a{1" EBRACE
+e 8 - "a{1n}" BADBR
+m 9 BS "a{b" "a\{b" "a\{b"
+m 10 BS "a{" "a\{" "a\{"
+m 11 bQ "a\\{0,1\\}b" cb b
+e 12 b "a\\{0,1" EBRACE
+e 13 - "a{0,1\\" BADBR
+m 14 Q "a{0}b" ab b
+m 15 Q "a{0,0}b" ab b
+m 16 Q "a{0,1}b" ab ab
+m 17 Q "a{0,2}b" b b
+m 18 Q "a{0,2}b" aab aab
+m 19 Q "a{0,}b" aab aab
+m 20 Q "a{1,1}b" aab ab
+m 21 Q "a{1,3}b" aaaab aaab
+f 22 Q "a{1,3}b" b
+m 23 Q "a{1,}b" aab aab
+f 24 Q "a{2,3}b" ab
+m 25 Q "a{2,3}b" aaaab aaab
+f 26 Q "a{2,}b" ab
+m 27 Q "a{2,}b" aaaab aaaab
+
+
+
+doing 9 "brackets"
+m 1 & {a[bc]} ac ac
+m 2 & {a[-]} a- a-
+m 3 & {a[[.-.]]} a- a-
+m 4 &L {a[[.zero.]]} a0 a0
+m 5 &LM {a[[.zero.]-9]} a2 a2
+m 6 &M {a[0-[.9.]]} a2 a2
+m 7 &+L {a[[=x=]]} ax ax
+m 8 &+L {a[[=x=]]} ay ay
+f 9 &+L {a[[=x=]]} az
+e 10 & {a[0-[=x=]]} ERANGE
+m 11 &L {a[[:digit:]]} a0 a0
+e 12 & {a[[:woopsie:]]} ECTYPE
+f 13 &L {a[[:digit:]]} ab
+e 14 & {a[0-[:digit:]]} ERANGE
+m 15 &LP {[[:<:]]a} a a
+m 16 &LP {a[[:>:]]} a a
+e 17 & {a[[..]]b} ECOLLATE
+e 18 & {a[[==]]b} ECOLLATE
+e 19 & {a[[::]]b} ECTYPE
+e 20 & {a[[.a} EBRACK
+e 21 & {a[[=a} EBRACK
+e 22 & {a[[:a} EBRACK
+e 23 & {a[} EBRACK
+e 24 & {a[b} EBRACK
+e 25 & {a[b-} EBRACK
+e 26 & {a[b-c} EBRACK
+m 27 &M {a[b-c]} ab ab
+m 28 & {a[b-b]} ab ab
+m 29 &M {a[1-2]} a2 a2
+e 30 & {a[c-b]} ERANGE
+e 31 & {a[a-b-c]} ERANGE
+m 32 &M {a[--?]b} a?b a?b
+m 33 & {a[---]b} a-b a-b
+m 34 & {a[]b]c} a]c a]c
+m 35 EP {a[\]]b} a]b a]b
+f 36 bE {a[\]]b} a]b
+m 37 bE {a[\]]b} "a\\]b" "a\\]b"
+m 38 eE {a[\]]b} "a\\]b" "a\\]b"
+m 39 EP {a[\\]b} "a\\b" "a\\b"
+m 40 eE {a[\\]b} "a\\b" "a\\b"
+m 41 bE {a[\\]b} "a\\b" "a\\b"
+e 42 - {a[\Z]b} EESCAPE
+m 43 & {a[[b]c} "a\[c" "a\[c"
+m 44 EMP* {a[\u00fe-\u0507][\u00ff-\u0300]b} \
+ "a\u0102\u02ffb" "a\u0102\u02ffb"
+
+
+
+doing 10 "anchors and newlines"
+m 1 & ^a a a
+f 2 &^ ^a a
+i 3 &N ^ a {0 -1}
+i 4 & {a$} aba {2 2}
+f 5 {&$} {a$} a
+i 6 &N {$} ab {2 1}
+m 7 &n ^a a a
+m 8 &n "^a" "b\na" "a"
+i 9 &w "^a" "a\na" {0 0}
+i 10 &n^ "^a" "a\na" {2 2}
+m 11 &n {a$} a a
+m 12 &n "a\$" "a\nb" "a"
+i 13 &n "a\$" "a\na" {0 0}
+i 14 N ^^ a {0 -1}
+m 15 b ^^ ^ ^
+i 16 N {$$} a {1 0}
+m 17 b {$$} "\$" "\$"
+m 18 &N {^$} "" ""
+f 19 &N {^$} a
+i 20 &nN "^\$" "a\n\nb" {2 1}
+m 21 N {$^} "" ""
+m 22 b {$^} "\$^" "\$^"
+m 23 P {\Aa} a a
+m 24 ^P {\Aa} a a
+f 25 ^nP {\Aa} "b\na"
+m 26 P {a\Z} a a
+m 27 {$P} {a\Z} a a
+f 28 {$nP} {a\Z} "a\nb"
+e 29 - ^* BADRPT
+e 30 - {$*} BADRPT
+e 31 - {\A*} BADRPT
+e 32 - {\Z*} BADRPT
+
+
+
+doing 11 "boundary constraints"
+m 1 &LP {[[:<:]]a} a a
+m 2 &LP {[[:<:]]a} -a a
+f 3 &LP {[[:<:]]a} ba
+m 4 &LP {a[[:>:]]} a a
+m 5 &LP {a[[:>:]]} a- a
+f 6 &LP {a[[:>:]]} ab
+m 7 bLP {\<a} a a
+f 8 bLP {\<a} ba
+m 9 bLP {a\>} a a
+f 10 bLP {a\>} ab
+m 11 LP {\ya} a a
+f 12 LP {\ya} ba
+m 13 LP {a\y} a a
+f 14 LP {a\y} ab
+m 15 LP {a\Y} ab a
+f 16 LP {a\Y} a-
+f 17 LP {a\Y} a
+f 18 LP {-\Y} -a
+m 19 LP {-\Y} -% -
+f 20 LP {\Y-} a-
+e 21 - {[[:<:]]*} BADRPT
+e 22 - {[[:>:]]*} BADRPT
+e 23 b {\<*} BADRPT
+e 24 b {\>*} BADRPT
+e 25 - {\y*} BADRPT
+e 26 - {\Y*} BADRPT
+m 27 LP {\ma} a a
+f 28 LP {\ma} ba
+m 29 LP {a\M} a a
+f 30 LP {a\M} ab
+f 31 ILP {\Ma} a
+f 32 ILP {a\m} a
+
+
+
+doing 12 "character classes"
+m 1 LP {a\db} a0b a0b
+f 2 LP {a\db} axb
+f 3 LP {a\Db} a0b
+m 4 LP {a\Db} axb axb
+m 5 LP "a\\sb" "a b" "a b"
+m 6 LP "a\\sb" "a\tb" "a\tb"
+m 7 LP "a\\sb" "a\nb" "a\nb"
+f 8 LP {a\sb} axb
+m 9 LP {a\Sb} axb axb
+f 10 LP "a\\Sb" "a b"
+m 11 LP {a\wb} axb axb
+f 12 LP {a\wb} a-b
+f 13 LP {a\Wb} axb
+m 14 LP {a\Wb} a-b a-b
+m 15 LP {\y\w+z\y} adze-guz guz
+m 16 LPE {a[\d]b} a1b a1b
+m 17 LPE "a\[\\s]b" "a b" "a b"
+m 18 LPE {a[\w]b} axb axb
+
+
+
+doing 13 "escapes"
+e 1 & "a\\" EESCAPE
+m 2 - {a\<b} a<b a<b
+m 3 e {a\<b} a<b a<b
+m 4 bAS {a\wb} awb awb
+m 5 eAS {a\wb} awb awb
+m 6 PL "a\\ab" "a\007b" "a\007b"
+m 7 P "a\\bb" "a\bb" "a\bb"
+m 8 P {a\Bb} "a\\b" "a\\b"
+m 9 MP "a\\chb" "a\bb" "a\bb"
+m 10 MP "a\\cHb" "a\bb" "a\bb"
+m 11 LMP "a\\e" "a\033" "a\033"
+m 12 P "a\\fb" "a\fb" "a\fb"
+m 13 P "a\\nb" "a\nb" "a\nb"
+m 14 P "a\\rb" "a\rb" "a\rb"
+m 15 P "a\\tb" "a\tb" "a\tb"
+m 16 P "a\\u0008x" "a\bx" "a\bx"
+e 17 - {a\u008x} EESCAPE
+m 18 P "a\\u00088x" "a\b8x" "a\b8x"
+m 19 P "a\\U00000008x" "a\bx" "a\bx"
+e 20 - {a\U0000008x} EESCAPE
+m 21 P "a\\vb" "a\vb" "a\vb"
+m 22 MP "a\\x08x" "a\bx" "a\bx"
+e 23 - {a\xq} EESCAPE
+m 24 MP "a\\x0008x" "a\bx" "a\bx"
+e 25 - {a\z} EESCAPE
+m 26 MP "a\\010b" "a\bb" "a\bb"
+
+
+
+doing 14 "back references"
+# ugh
+m 1 RP {a(b*)c\1} abbcbb abbcbb bb
+m 2 RP {a(b*)c\1} ac ac ""
+f 3 RP {a(b*)c\1} abbcb
+m 4 RP {a(b*)\1} abbcbb abb b
+m 5 RP {a(b|bb)\1} abbcbb abb b
+m 6 RP {a([bc])\1} abb abb b
+f 7 RP {a([bc])\1} abc
+m 8 RP {a([bc])\1} abcabb abb b
+f 9 RP {a([bc])*\1} abc
+f 10 RP {a([bc])\1} abB
+m 11 iRP {a([bc])\1} abB abB b
+m 12 RP {a([bc])\1+} abbb abbb b
+m 13 QRP "a(\[bc])\\1{3,4}" abbbb abbbb b
+f 14 QRP "a(\[bc])\\1{3,4}" abbb
+m 15 RP {a([bc])\1*} abbb abbb b
+m 16 RP {a([bc])\1*} ab ab b
+m 17 RP {a([bc])(\1*)} ab ab b ""
+e 18 - {a((b)\1)} ESUBREG
+e 19 - {a(b)c\2} ESUBREG
+m 20 bR {a\(b*\)c\1} abbcbb abbcbb bb
+
+
+
+doing 15 "octal escapes vs back references"
+# initial zero is always octal
+m 1 MP "a\\010b" "a\bb" "a\bb"
+m 2 MP "a\\0070b" "a\0070b" "a\0070b"
+m 3 MP "a\\07b" "a\007b" "a\007b"
+m 4 MP "a(b)(b)(b)(b)(b)(b)(b)(b)(b)(b)\\07c" "abbbbbbbbbb\007c" \
+ "abbbbbbbbbb\007c" "b" "b" "b" "b" "b" "b" \
+ "b" "b" "b" "b"
+# a single digit is always a backref
+e 5 - {a\7b} ESUBREG
+# otherwise it's a backref only if within range (barf!)
+m 6 MP "a\\10b" "a\bb" "a\bb"
+m 7 MP {a\101b} aAb aAb
+m 8 RP {a(b)(b)(b)(b)(b)(b)(b)(b)(b)(b)\10c} abbbbbbbbbbbc \
+ abbbbbbbbbbbc b b b b b b b \
+ b b b
+# but we're fussy about border cases -- guys who want octal should use the zero
+e 9 - {a((((((((((b\10))))))))))c} ESUBREG
+# BREs don't have octal, EREs don't have backrefs
+m 10 MP "a\\12b" "a\nb" "a\nb"
+e 11 b {a\12b} ESUBREG
+m 12 eAS {a\12b} a12b a12b
+
+
+
+doing 16 "expanded syntax"
+m 1 xP "a b c" "abc" "abc"
+m 2 xP "a b #oops\nc\td" "abcd" "abcd"
+m 3 x "a\\ b\\\tc" "a b\tc" "a b\tc"
+m 4 xP "a b\\#c" "ab#c" "ab#c"
+m 5 xP "a b\[c d]e" "ab e" "ab e"
+m 6 xP "a b\[c#d]e" "ab#e" "ab#e"
+m 7 xP "a b\[c#d]e" "abde" "abde"
+m 8 xSPB "ab{ d" "ab\{d" "ab\{d"
+m 9 xPQ "ab{ 1 , 2 }c" "abc" "abc"
+
+
+
+doing 17 "misc syntax"
+m 1 P a(?#comment)b ab ab
+
+
+
+doing 18 "unmatchable REs"
+f 1 I a^b ab
+
+
+
+doing 19 "case independence"
+m 1 &i ab Ab Ab
+m 2 &i {a[bc]} aC aC
+f 3 &i {a[^bc]} aB
+m 4 &iM {a[b-d]} aC aC
+f 5 &iM {a[^b-d]} aC
+
+
+
+doing 20 "directors and embedded options"
+e 1 & ***? BADPAT
+m 2 q ***? ***? ***?
+m 3 &P ***=a*b a*b a*b
+m 4 q ***=a*b ***=a*b ***=a*b
+m 5 bLP {***:\w+} ab ab
+m 6 eLP {***:\w+} ab ab
+e 7 & ***:***=a*b BADRPT
+m 8 &P ***:(?b)a+b a+b a+b
+m 9 P (?b)a+b a+b a+b
+e 10 e {(?b)\w+} BADRPT
+m 11 bAS {(?b)\w+} (?b)w+ (?b)w+
+m 12 iP (?c)a a a
+f 13 iP (?c)a A
+m 14 APS {(?e)\W+} WW WW
+m 15 P (?i)a+ Aa Aa
+f 16 P "(?m)a.b" "a\nb"
+m 17 P "(?m)^b" "a\nb" "b"
+f 18 P "(?n)a.b" "a\nb"
+m 19 P "(?n)^b" "a\nb" "b"
+f 20 P "(?p)a.b" "a\nb"
+f 21 P "(?p)^b" "a\nb"
+m 22 P (?q)a+b a+b a+b
+m 23 nP "(?s)a.b" "a\nb" "a\nb"
+m 24 xP "(?t)a b" "a b" "a b"
+m 25 P "(?w)a.b" "a\nb" "a\nb"
+m 26 P "(?w)^b" "a\nb" "b"
+m 27 P "(?x)a b" "ab" "ab"
+e 28 - (?z)ab BADOPT
+m 29 P (?ici)a+ Aa Aa
+e 30 P (?i)(?q)a+ BADRPT
+m 31 P (?q)(?i)a+ (?i)a+ (?i)a+
+m 32 P (?qe)a+ a a
+m 33 xP "(?q)a b" "a b" "a b"
+m 34 P "(?qx)a b" "a b" "a b"
+m 35 P (?qi)ab Ab Ab
+
+
+
+doing 21 "capturing"
+m 1 - a(b)c abc abc b
+m 2 P a(?:b)c xabc abc
+m 3 - a((b))c xabcy abc b b
+m 4 P a(?:(b))c abcy abc b
+m 5 P a((?:b))c abc abc b
+m 6 P a(?:(?:b))c abc abc
+i 7 Q "a(b){0}c" ac {0 1} {-1 -1}
+m 8 - a(b)c(d)e abcde abcde b d
+m 9 - (b)c(d)e bcde bcde b d
+m 10 - a(b)(d)e abde abde b d
+m 11 - a(b)c(d) abcd abcd b d
+m 12 - (ab)(cd) xabcdy abcd ab cd
+m 13 - a(b)?c xabcy abc b
+i 14 - a(b)?c xacy {1 2} {-1 -1}
+m 15 - a(b)?c(d)?e xabcdey abcde b d
+i 16 - a(b)?c(d)?e xacdey {1 4} {-1 -1} {3 3}
+i 17 - a(b)?c(d)?e xabcey {1 4} {2 2} {-1 -1}
+i 18 - a(b)?c(d)?e xacey {1 3} {-1 -1} {-1 -1}
+m 19 - a(b)*c xabcy abc b
+i 20 - a(b)*c xabbbcy {1 5} {4 4}
+i 21 - a(b)*c xacy {1 2} {-1 -1}
+m 22 - a(b*)c xabbbcy abbbc bbb
+m 23 - a(b*)c xacy ac ""
+f 24 - a(b)+c xacy
+m 25 - a(b)+c xabcy abc b
+i 26 - a(b)+c xabbbcy {1 5} {4 4}
+m 27 - a(b+)c xabbbcy abbbc bbb
+i 28 Q "a(b){2,3}c" xabbbcy {1 5} {4 4}
+i 29 Q "a(b){2,3}c" xabbcy {1 4} {3 3}
+f 30 Q "a(b){2,3}c" xabcy
+m 31 LP "\\y(\\w+)\\y" "-- abc-" "abc" "abc"
+m 32 - a((b|c)d+)+ abacdbd acdbd bd b
+m 33 N (.*).* abc abc abc
+m 34 N (a*)* bc "" ""
+
+
+
+doing 22 "multicharacter collating elements"
+# again ugh
+m 1 &+L {a[c]e} ace ace
+f 2 &+IL {a[c]h} ach
+m 3 &+L {a[[.ch.]]} ach ach
+f 4 &+L {a[[.ch.]]} ace
+m 5 &+L {a[c[.ch.]]} ac ac
+m 6 &+L {a[c[.ch.]]} ace ac
+m 7 &+L {a[c[.ch.]]} ache ach
+f 8 &+L {a[^c]e} ace
+m 9 &+L {a[^c]e} abe abe
+m 10 &+L {a[^c]e} ache ache
+f 11 &+L {a[^[.ch.]]} ach
+m 12 &+L {a[^[.ch.]]} ace ac
+m 13 &+L {a[^[.ch.]]} ac ac
+m 14 &+L {a[^[.ch.]]} abe ab
+f 15 &+L {a[^c[.ch.]]} ach
+f 16 &+L {a[^c[.ch.]]} ace
+f 17 &+L {a[^c[.ch.]]} ac
+m 18 &+L {a[^c[.ch.]]} abe ab
+m 19 &+L {a[^b]} ac ac
+m 20 &+L {a[^b]} ace ac
+m 21 &+L {a[^b]} ach ach
+f 22 &+L {a[^b]} abe
+
+
+
+doing 23 "lookahead constraints"
+m 1 HP a(?=b)b* ab ab
+f 2 HP a(?=b)b* a
+m 3 HP a(?=b)b*(?=c)c* abc abc
+f 4 HP a(?=b)b*(?=c)c* ab
+f 5 HP a(?!b)b* ab
+m 6 HP a(?!b)b* a a
+m 7 HP (?=b)b b b
+f 8 HP (?=b)b a
+
+
+
+doing 24 "non-greedy quantifiers"
+m 1 PT ab+? abb ab
+m 2 PT ab+?c abbc abbc
+m 3 PT ab*? abb a
+m 4 PT ab*?c abbc abbc
+m 5 PT ab?? ab a
+m 6 PT ab??c abc abc
+m 7 PQT "ab{2,4}?" abbbb abb
+m 8 PQT "ab{2,4}?c" abbbbc abbbbc
+m 9 - 3z* 123zzzz456 3zzzz
+m 10 PT 3z*? 123zzzz456 3
+m 11 - z*4 123zzzz456 zzzz4
+m 12 PT z*?4 123zzzz456 zzzz4
+
+
+
+doing 25 "mixed quantifiers"
+# this is very incomplete as yet
+# should include |
+m 1 PNT {^(.*?)(a*)$} xyza xyza xyz a
+m 2 PNT {^(.*?)(a*)$} xyzaa xyzaa xyz aa
+m 3 PNT {^(.*?)(a*)$} xyz xyz xyz ""
+
+
+
+doing 26 "tricky cases"
+# attempts to trick the matcher into accepting a short match
+m 1 - (week|wee)(night|knights) weeknights weeknights \
+ wee knights
+m 2 RP {a(bc*).*\1} abccbccb abccbccb b
+m 3 - {a(b.[bc]*)+} abcbd abcbd bd
+
+
+
+doing 27 "implementation misc."
+# duplicate arcs are suppressed
+m 1 P a(?:b|b)c abc abc
+# make color/subcolor relationship go back and forth
+m 2 & {[ab][ab][ab]} aba aba
+m 3 & {[ab][ab][ab][ab][ab][ab][ab]} abababa abababa
+
+
+
+doing 28 "boundary busters etc."
+# color-descriptor allocation changes at 10
+m 1 & abcdefghijkl abcdefghijkl abcdefghijkl
+# so does arc allocation
+m 2 P a(?:b|c|d|e|f|g|h|i|j|k|l|m)n agn agn
+# subexpression tracking also at 10
+m 3 - a(((((((((((((b)))))))))))))c abc abc b b b b b b b b b b b b b
+# state-set handling changes slightly at unsigned size (might be 64...)
+# (also stresses arc allocation)
+m 4 Q "ab{1,100}c" abbc abbc
+m 5 Q "ab{1,100}c" abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbc \
+ abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbc
+m 6 Q "ab{1,100}c" \
+ abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbc \
+ abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbc
+# force small cache and bust it, several ways
+m 7 LP {\w+abcdefgh} xyzabcdefgh xyzabcdefgh
+m 8 %LP {\w+abcdefgh} xyzabcdefgh xyzabcdefgh
+m 9 %LP {\w+abcdefghijklmnopqrst} xyzabcdefghijklmnopqrst \
+ xyzabcdefghijklmnopqrst
+i 10 %LP {\w+(abcdefgh)?} xyz {0 2} {-1 -1}
+i 11 %LP {\w+(abcdefgh)?} xyzabcdefg {0 9} {-1 -1}
+i 12 %LP {\w+(abcdefghijklmnopqrst)?} xyzabcdefghijklmnopqrs \
+ {0 21} {-1 -1}
+
+
+
+doing 29 "incomplete matches"
+p 1 t def abc {3 2} ""
+p 2 t bcd abc {1 2} ""
+p 3 t abc abab {0 3} ""
+p 4 t abc abdab {3 4} ""
+i 5 t abc abc {0 2} {0 2}
+i 6 t abc xyabc {2 4} {2 4}
+p 7 t abc+ xyab {2 3} ""
+i 8 t abc+ xyabc {2 4} {2 4}
+knownBug i 9 t abc+ xyabcd {2 4} {6 5}
+i 10 t abc+ xyabcdd {2 4} {7 6}
+p 11 tPT abc+? xyab {2 3} ""
+# the retain numbers in these two may look wrong, but they aren't
+i 12 tPT abc+? xyabc {2 4} {5 4}
+i 13 tPT abc+? xyabcc {2 4} {6 5}
+i 14 tPT abc+? xyabcd {2 4} {6 5}
+i 15 tPT abc+? xyabcdd {2 4} {7 6}
+i 16 t abcd|bc xyabc {3 4} {2 4}
+p 17 tn .*k "xx\nyyy" {3 5} ""
+
+
+doing 30 "misc. oddities and old bugs"
+e 1 & *** BADRPT
+m 2 N a?b* abb abb
+m 3 N a?b* bb bb
+m 4 & a*b aab aab
+m 5 & ^a*b aaaab aaaab
+m 6 &M {[0-6][1-2][0-3][0-6][1-6][0-6]} 010010 010010
+# temporary REG_BOSONLY kludge
+m 7 s abc abcd abc
+f 8 s abc xabcd
+# back to normal stuff
+m 9 HLP {(?n)^(?![t#])\S+} "tk\n\n#\n#\nit0" it0
+
+
+# flush any leftover complaints
+doing 0 "flush"
+
+# Tests resulting from bugs reported by users
+test reg-31.1 {[[:xdigit:]] behaves correctly when followed by [[:space:]]} {
+ set str {2:::DebugWin32}
+ set re {([[:xdigit:]])([[:space:]]*)}
+ list [regexp $re $str match xdigit spaces] $match $xdigit $spaces
+ # Code used to produce {1 2:::DebugWin32 2 :::DebugWin32} !!!
+} {1 2 2 {}}
+
+test reg-32.1 {canmatch functionality -- at end} {
+ set pat {blah}
+ set line "asd asd"
+ # can match at the final d, if '%' follows
+ set res [testregexp -xflags -- c $pat $line resvar]
+ lappend res $resvar
+} {0 7}
+
+test reg-32.2 {canmatch functionality -- at end} {
+ set pat {s%$}
+ set line "asd asd"
+ # can only match after the end of the string
+ set res [testregexp -xflags -- c $pat $line resvar]
+ lappend res $resvar
+} {0 7}
+
+test reg-32.3 {canmatch functionality -- not last char} {
+ set pat {[^d]%$}
+ set line "asd asd"
+ # can only match after the end of the string
+ set res [testregexp -xflags -- c $pat $line resvar]
+ lappend res $resvar
+} {0 7}
+
+test reg-32.3.1 {canmatch functionality -- no match} {
+ set pat {\Zx}
+ set line "asd asd"
+ # can match the last char, if followed by x
+ set res [testregexp -xflags -- c $pat $line resvar]
+ lappend res $resvar
+} {0 -1}
+
+test reg-32.4 {canmatch functionality -- last char} {knownBug} {
+ set pat {.x}
+ set line "asd asd"
+ # can match the last char, if followed by x
+ set res [testregexp -xflags -- c $pat $line resvar]
+ lappend res $resvar
+} {0 6}
+
+test reg-32.4.1 {canmatch functionality -- last char} {knownBug} {
+ set pat {.x$}
+ set line "asd asd"
+ # can match the last char, if followed by x
+ set res [testregexp -xflags -- c $pat $line resvar]
+ lappend res $resvar
+} {0 6}
+
+test reg-32.5 {canmatch functionality -- last char} {knownBug} {
+ set pat {.[^d]x$}
+ set line "asd asd"
+ # can match the last char, if followed by not-d and x.
+ set res [testregexp -xflags -- c $pat $line resvar]
+ lappend res $resvar
+} {0 6}
+
+test reg-32.6 {canmatch functionality -- last char} {knownBug} {
+ set pat {[^a]%[^\r\n]*$}
+ set line "asd asd"
+ # can match at the final d, if '%' follows
+ set res [testregexp -xflags -- c $pat $line resvar]
+ lappend res $resvar
+} {0 6}
+
+test reg-32.7 {canmatch functionality -- last char} {knownBug} {
+ set pat {[^a]%$}
+ set line "asd asd"
+ # can match at the final d, if '%' follows
+ set res [testregexp -xflags -- c $pat $line resvar]
+ lappend res $resvar
+} {0 6}
+
+test reg-32.8 {canmatch functionality -- last char} {knownBug} {
+ set pat {[^x]%$}
+ set line "asd asd"
+ # can match at the final d, if '%' follows
+ set res [testregexp -xflags -- c $pat $line resvar]
+ lappend res $resvar
+} {0 6}
+
+test reg-32.9 {canmatch functionality -- more complex case} {knownBug} {
+ set pat {((\B\B|\Bh+line)[ \t]*|[^\B]%[^\r\n]*)$}
+ set line "asd asd"
+ # can match at the final d, if '%' follows
+ set res [testregexp -xflags -- c $pat $line resvar]
+ lappend res $resvar
+} {0 6}
+
+# Tests reg-33.*: Checks for bug fixes
+
+test reg-33.1 {Bug 230589} {
+ regexp {[ ]*(^|[^%])%V} "*%V2" m s
+} 1
+
+test reg-33.2 {Bug 504785} {
+ regexp -inline {([^_.]*)([^.]*)\.(..)(.).*} bbcos_001_c01.q1la
+} {bbcos_001_c01.q1la bbcos _001_c01 q1 l}
+
+test reg-33.3 {Bug 505048} {
+ regexp {\A\s*[^<]*\s*<([^>]+)>} a<a>
+} 1
+
+test reg-33.4 {Bug 505048} {
+ regexp {\A\s*([^b]*)b} ab
+} 1
+
+test reg-33.5 {Bug 505048} {
+ regexp {\A\s*[^b]*(b)} ab
+} 1
+
+test reg-33.6 {Bug 505048} {
+ regexp {\A(\s*)[^b]*(b)} ab
+} 1
+
+test reg-33.7 {Bug 505048} {
+ regexp {\A\s*[^b]*b} ab
+} 1
+
+test reg-33.8 {Bug 505048} {
+ regexp -inline {\A\s*[^b]*b} ab
+} ab
+
+test reg-33.9 {Bug 505048} {
+ regexp -indices -inline {\A\s*[^b]*b} ab
+} {{0 1}}
+
+test reg-33.10 {Bug 840258} {
+ regsub {(^|\n)+\.*b} \n.b {} tmp
+} 1
+
+test reg-33.11 {Bug 840258} {
+ regsub {(^|[\n\r]+)\.*\?<.*?(\n|\r)+} \
+ "TQ\r\n.?<5000267>Test already stopped\r\n" {} tmp
+} 1
+
+# cleanup
+::tcltest::cleanupTests
+return
--- /dev/null
+/*
+ * Test data for wxRegEx (UTF-8 encoded)
+ *
+ * Generated Fri Mar 5 21:35:22 2004 by regex.pl from the following files:
+ *
+ * reg.test: Copyright (c) 1998, 1999 Henry Spencer. All rights reserved.
+ * wxreg.test: Copyright (c) 2004 Mike Wetherell.
+ *
+ * Test types:
+ * e compile error expected
+ * f match failure expected
+ * m successful match
+ * i successful match with -indices (used in checking things like
+ * nonparticipating subexpressions)
+ * p unsuccessful match with -indices (!!) (used in checking
+ * partial-match reporting)
+ *
+ * Flag characters:
+ * - no-op (placeholder)
+ * + provide fake xy equivalence class and ch collating element
+ * % force small state-set cache in matcher (to test cache replace)
+ * ^ beginning of string is not beginning of line
+ * $ end of string is not end of line
+ * * test is Unicode-specific, needs big character set
+ *
+ * & test as both ARE and BRE
+ * b BRE
+ * e ERE
+ * a turn advanced-features bit on (error unless ERE already)
+ * q literal string, no metacharacters at all
+ *
+ * i case-independent matching
+ * o ("opaque") no subexpression capture
+ * p newlines are half-magic, excluded from . and [^ only
+ * w newlines are half-magic, significant to ^ and $ only
+ * n newlines are fully magic, both effects
+ * x expanded RE syntax
+ * t incomplete-match reporting
+ *
+ * A backslash-_a_lphanumeric seen
+ * B ERE/ARE literal-_b_race heuristic used
+ * E backslash (_e_scape) seen within []
+ * H looka_h_ead constraint seen
+ * I _i_mpossible to match
+ * L _l_ocale-specific construct seen
+ * M unportable (_m_achine-specific) construct seen
+ * N RE can match empty (_n_ull) string
+ * P non-_P_OSIX construct seen
+ * Q {} _q_uantifier seen
+ * R back _r_eference seen
+ * S POSIX-un_s_pecified syntax seen
+ * T prefers shortest (_t_iny)
+ * U saw original-POSIX botch: unmatched right paren in ERE (_u_gh)
+ */
+
+
+/*
+ * 1 basic sanity checks
+ */
+
+class regextest_1 : public RegExTestSuite
+{
+public:
+ regextest_1() : RegExTestSuite("regex.1") { }
+ static Test *suite();
+};
+
+Test *regextest_1::suite()
+{
+ RegExTestSuite *suite = new regextest_1;
+
+ suite->add("m", "1", "&", "abc", "abc", "abc", NULL);
+ suite->add("f", "2", "&", "abc", "def", NULL);
+ suite->add("m", "3", "&", "abc", "xyabxabce", "abc", NULL);
+
+ return suite;
+}
+
+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(regextest_1, "regex.1");
+
+
+/*
+ * 2 invalid option combinations
+ */
+
+class regextest_2 : public RegExTestSuite
+{
+public:
+ regextest_2() : RegExTestSuite("regex.2") { }
+ static Test *suite();
+};
+
+Test *regextest_2::suite()
+{
+ RegExTestSuite *suite = new regextest_2;
+
+ suite->add("e", "1", "qe", "a", "INVARG", NULL);
+ suite->add("e", "2", "qa", "a", "INVARG", NULL);
+ suite->add("e", "3", "qx", "a", "INVARG", NULL);
+ suite->add("e", "4", "qn", "a", "INVARG", NULL);
+ suite->add("e", "5", "ba", "a", "INVARG", NULL);
+
+ return suite;
+}
+
+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(regextest_2, "regex.2");
+
+
+/*
+ * 3 basic syntax
+ */
+
+class regextest_3 : public RegExTestSuite
+{
+public:
+ regextest_3() : RegExTestSuite("regex.3") { }
+ static Test *suite();
+};
+
+Test *regextest_3::suite()
+{
+ RegExTestSuite *suite = new regextest_3;
+
+ suite->add("i", "1", "&NS", "", "a", "0 -1", NULL);
+ suite->add("m", "2", "NS", "a|", "a", "a", NULL);
+ suite->add("m", "3", "-", "a|b", "a", "a", NULL);
+ suite->add("m", "4", "-", "a|b", "b", "b", NULL);
+ suite->add("m", "5", "NS", "a||b", "b", "b", NULL);
+ suite->add("m", "6", "&", "ab", "ab", "ab", NULL);
+
+ return suite;
+}
+
+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(regextest_3, "regex.3");
+
+
+/*
+ * 4 parentheses
+ */
+
+class regextest_4 : public RegExTestSuite
+{
+public:
+ regextest_4() : RegExTestSuite("regex.4") { }
+ static Test *suite();
+};
+
+Test *regextest_4::suite()
+{
+ RegExTestSuite *suite = new regextest_4;
+
+ suite->add("m", "1", "-", "(a)e", "ae", "ae", "a", NULL);
+ suite->add("m", "2", "o", "(a)e", "ae", NULL);
+ suite->add("m", "3", "b", "\\(a\\)b", "ab", "ab", "a", NULL);
+ suite->add("m", "4", "-", "a((b)c)", "abc", "abc", "bc", "b", NULL);
+ suite->add("m", "5", "-", "a(b)(c)", "abc", "abc", "b", "c", NULL);
+ suite->add("e", "6", "-", "a(b", "EPAREN", NULL);
+ suite->add("e", "7", "b", "a\\(b", "EPAREN", NULL);
+ suite->add("m", "8", "eU", "a)b", "a)b", "a)b", NULL);
+ suite->add("e", "9", "-", "a)b", "EPAREN", NULL);
+ suite->add("e", "10", "b", "a\\)b", "EPAREN", NULL);
+ suite->add("m", "11", "P", "a(?:b)c", "abc", "abc", NULL);
+ suite->add("e", "12", "e", "a(?:b)c", "BADRPT", NULL);
+ suite->add("i", "13", "S", "a()b", "ab", "0 1", "1 0", NULL);
+ suite->add("m", "14", "SP", "a(?:)b", "ab", "ab", NULL);
+ suite->add("i", "15", "S", "a(|b)c", "ac", "0 1", "1 0", NULL);
+ suite->add("m", "16", "S", "a(b|)c", "abc", "abc", "b", NULL);
+
+ return suite;
+}
+
+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(regextest_4, "regex.4");
+
+
+/*
+ * 5 simple one-char matching
+ */
+
+class regextest_5 : public RegExTestSuite
+{
+public:
+ regextest_5() : RegExTestSuite("regex.5") { }
+ static Test *suite();
+};
+
+Test *regextest_5::suite()
+{
+ RegExTestSuite *suite = new regextest_5;
+
+ suite->add("m", "1", "&", "a.b", "axb", "axb", NULL);
+ suite->add("f", "2", "&n", "a.b", "a\nb", NULL);
+ suite->add("m", "3", "&", "a[bc]d", "abd", "abd", NULL);
+ suite->add("m", "4", "&", "a[bc]d", "acd", "acd", NULL);
+ suite->add("f", "5", "&", "a[bc]d", "aed", NULL);
+ suite->add("f", "6", "&", "a[^bc]d", "abd", NULL);
+ suite->add("m", "7", "&", "a[^bc]d", "aed", "aed", NULL);
+ suite->add("f", "8", "&p", "a[^bc]d", "a\nd", NULL);
+
+ return suite;
+}
+
+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(regextest_5, "regex.5");
+
+
+/*
+ * 6 context-dependent syntax
+ */
+
+class regextest_6 : public RegExTestSuite
+{
+public:
+ regextest_6() : RegExTestSuite("regex.6") { }
+ static Test *suite();
+};
+
+Test *regextest_6::suite()
+{
+ RegExTestSuite *suite = new regextest_6;
+
+ suite->add("e", "1", "-", "*", "BADRPT", NULL);
+ suite->add("m", "2", "b", "*", "*", "*", NULL);
+ suite->add("m", "3", "b", "\\(*\\)", "*", "*", "*", NULL);
+ suite->add("e", "4", "-", "(*)", "BADRPT", NULL);
+ suite->add("m", "5", "b", "^*", "*", "*", NULL);
+ suite->add("e", "6", "-", "^*", "BADRPT", NULL);
+ suite->add("f", "7", "&", "^b", "^b", NULL);
+ suite->add("m", "8", "b", "x^", "x^", "x^", NULL);
+ suite->add("f", "9", "I", "x^", "x", NULL);
+ suite->add("m", "10", "n", "\n^", "x\nb", "\n", NULL);
+ suite->add("f", "11", "bS", "\\(^b\\)", "^b", NULL);
+ suite->add("m", "12", "-", "(^b)", "b", "b", "b", NULL);
+ suite->add("m", "13", "&", "x$", "x", "x", NULL);
+ suite->add("m", "14", "bS", "\\(x$\\)", "x", "x", "x", NULL);
+ suite->add("m", "15", "-", "(x$)", "x", "x", "x", NULL);
+ suite->add("m", "16", "b", "x$y", "x$y", "x$y", NULL);
+ suite->add("f", "17", "I", "x$y", "xy", NULL);
+ suite->add("m", "18", "n", "x$\n", "x\n", "x\n", NULL);
+ suite->add("e", "19", "-", "+", "BADRPT", NULL);
+ suite->add("e", "20", "-", "?", "BADRPT", NULL);
+
+ return suite;
+}
+
+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(regextest_6, "regex.6");
+
+
+/*
+ * 7 simple quantifiers
+ */
+
+class regextest_7 : public RegExTestSuite
+{
+public:
+ regextest_7() : RegExTestSuite("regex.7") { }
+ static Test *suite();
+};
+
+Test *regextest_7::suite()
+{
+ RegExTestSuite *suite = new regextest_7;
+
+ suite->add("m", "1", "&N", "a*", "aa", "aa", NULL);
+ suite->add("i", "2", "&N", "a*", "b", "0 -1", NULL);
+ suite->add("m", "3", "-", "a+", "aa", "aa", NULL);
+ suite->add("m", "4", "-", "a?b", "ab", "ab", NULL);
+ suite->add("m", "5", "-", "a?b", "b", "b", NULL);
+ suite->add("e", "6", "-", "**", "BADRPT", NULL);
+ suite->add("m", "7", "bN", "**", "***", "***", NULL);
+ suite->add("e", "8", "&", "a**", "BADRPT", NULL);
+ suite->add("e", "9", "&", "a**b", "BADRPT", NULL);
+ suite->add("e", "10", "&", "***", "BADRPT", NULL);
+ suite->add("e", "11", "-", "a++", "BADRPT", NULL);
+ suite->add("e", "12", "-", "a?+", "BADRPT", NULL);
+ suite->add("e", "13", "-", "a?*", "BADRPT", NULL);
+ suite->add("e", "14", "-", "a+*", "BADRPT", NULL);
+ suite->add("e", "15", "-", "a*+", "BADRPT", NULL);
+
+ return suite;
+}
+
+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(regextest_7, "regex.7");
+
+
+/*
+ * 8 braces
+ */
+
+class regextest_8 : public RegExTestSuite
+{
+public:
+ regextest_8() : RegExTestSuite("regex.8") { }
+ static Test *suite();
+};
+
+Test *regextest_8::suite()
+{
+ RegExTestSuite *suite = new regextest_8;
+
+ suite->add("m", "1", "NQ", "a{0,1}", "", "", NULL);
+ suite->add("m", "2", "NQ", "a{0,1}", "ac", "a", NULL);
+ suite->add("e", "3", "-", "a{1,0}", "BADBR", NULL);
+ suite->add("e", "4", "-", "a{1,2,3}", "BADBR", NULL);
+ suite->add("e", "5", "-", "a{257}", "BADBR", NULL);
+ suite->add("e", "6", "-", "a{1000}", "BADBR", NULL);
+ suite->add("e", "7", "-", "a{1", "EBRACE", NULL);
+ suite->add("e", "8", "-", "a{1n}", "BADBR", NULL);
+ suite->add("m", "9", "BS", "a{b", "a{b", "a{b", NULL);
+ suite->add("m", "10", "BS", "a{", "a{", "a{", NULL);
+ suite->add("m", "11", "bQ", "a\\{0,1\\}b", "cb", "b", NULL);
+ suite->add("e", "12", "b", "a\\{0,1", "EBRACE", NULL);
+ suite->add("e", "13", "-", "a{0,1\\", "BADBR", NULL);
+ suite->add("m", "14", "Q", "a{0}b", "ab", "b", NULL);
+ suite->add("m", "15", "Q", "a{0,0}b", "ab", "b", NULL);
+ suite->add("m", "16", "Q", "a{0,1}b", "ab", "ab", NULL);
+ suite->add("m", "17", "Q", "a{0,2}b", "b", "b", NULL);
+ suite->add("m", "18", "Q", "a{0,2}b", "aab", "aab", NULL);
+ suite->add("m", "19", "Q", "a{0,}b", "aab", "aab", NULL);
+ suite->add("m", "20", "Q", "a{1,1}b", "aab", "ab", NULL);
+ suite->add("m", "21", "Q", "a{1,3}b", "aaaab", "aaab", NULL);
+ suite->add("f", "22", "Q", "a{1,3}b", "b", NULL);
+ suite->add("m", "23", "Q", "a{1,}b", "aab", "aab", NULL);
+ suite->add("f", "24", "Q", "a{2,3}b", "ab", NULL);
+ suite->add("m", "25", "Q", "a{2,3}b", "aaaab", "aaab", NULL);
+ suite->add("f", "26", "Q", "a{2,}b", "ab", NULL);
+ suite->add("m", "27", "Q", "a{2,}b", "aaaab", "aaaab", NULL);
+
+ return suite;
+}
+
+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(regextest_8, "regex.8");
+
+
+/*
+ * 9 brackets
+ */
+
+class regextest_9 : public RegExTestSuite
+{
+public:
+ regextest_9() : RegExTestSuite("regex.9") { }
+ static Test *suite();
+};
+
+Test *regextest_9::suite()
+{
+ RegExTestSuite *suite = new regextest_9;
+
+ suite->add("m", "1", "&", "a[bc]", "ac", "ac", NULL);
+ suite->add("m", "2", "&", "a[-]", "a-", "a-", NULL);
+ suite->add("m", "3", "&", "a[[.-.]]", "a-", "a-", NULL);
+ suite->add("m", "4", "&L", "a[[.zero.]]", "a0", "a0", NULL);
+ suite->add("m", "5", "&LM", "a[[.zero.]-9]", "a2", "a2", NULL);
+ suite->add("m", "6", "&M", "a[0-[.9.]]", "a2", "a2", NULL);
+ suite->add("m", "7", "&+L", "a[[=x=]]", "ax", "ax", NULL);
+ suite->add("m", "8", "&+L", "a[[=x=]]", "ay", "ay", NULL);
+ suite->add("f", "9", "&+L", "a[[=x=]]", "az", NULL);
+ suite->add("e", "10", "&", "a[0-[=x=]]", "ERANGE", NULL);
+ suite->add("m", "11", "&L", "a[[:digit:]]", "a0", "a0", NULL);
+ suite->add("e", "12", "&", "a[[:woopsie:]]", "ECTYPE", NULL);
+ suite->add("f", "13", "&L", "a[[:digit:]]", "ab", NULL);
+ suite->add("e", "14", "&", "a[0-[:digit:]]", "ERANGE", NULL);
+ suite->add("m", "15", "&LP", "[[:<:]]a", "a", "a", NULL);
+ suite->add("m", "16", "&LP", "a[[:>:]]", "a", "a", NULL);
+ suite->add("e", "17", "&", "a[[..]]b", "ECOLLATE", NULL);
+ suite->add("e", "18", "&", "a[[==]]b", "ECOLLATE", NULL);
+ suite->add("e", "19", "&", "a[[::]]b", "ECTYPE", NULL);
+ suite->add("e", "20", "&", "a[[.a", "EBRACK", NULL);
+ suite->add("e", "21", "&", "a[[=a", "EBRACK", NULL);
+ suite->add("e", "22", "&", "a[[:a", "EBRACK", NULL);
+ suite->add("e", "23", "&", "a[", "EBRACK", NULL);
+ suite->add("e", "24", "&", "a[b", "EBRACK", NULL);
+ suite->add("e", "25", "&", "a[b-", "EBRACK", NULL);
+ suite->add("e", "26", "&", "a[b-c", "EBRACK", NULL);
+ suite->add("m", "27", "&M", "a[b-c]", "ab", "ab", NULL);
+ suite->add("m", "28", "&", "a[b-b]", "ab", "ab", NULL);
+ suite->add("m", "29", "&M", "a[1-2]", "a2", "a2", NULL);
+ suite->add("e", "30", "&", "a[c-b]", "ERANGE", NULL);
+ suite->add("e", "31", "&", "a[a-b-c]", "ERANGE", NULL);
+ suite->add("m", "32", "&M", "a[--?]b", "a?b", "a?b", NULL);
+ suite->add("m", "33", "&", "a[---]b", "a-b", "a-b", NULL);
+ suite->add("m", "34", "&", "a[]b]c", "a]c", "a]c", NULL);
+ suite->add("m", "35", "EP", "a[\\]]b", "a]b", "a]b", NULL);
+ suite->add("f", "36", "bE", "a[\\]]b", "a]b", NULL);
+ suite->add("m", "37", "bE", "a[\\]]b", "a\\]b", "a\\]b", NULL);
+ suite->add("m", "38", "eE", "a[\\]]b", "a\\]b", "a\\]b", NULL);
+ suite->add("m", "39", "EP", "a[\\\\]b", "a\\b", "a\\b", NULL);
+ suite->add("m", "40", "eE", "a[\\\\]b", "a\\b", "a\\b", NULL);
+ suite->add("m", "41", "bE", "a[\\\\]b", "a\\b", "a\\b", NULL);
+ suite->add("e", "42", "-", "a[\\Z]b", "EESCAPE", NULL);
+ suite->add("m", "43", "&", "a[[b]c", "a[c", "a[c", NULL);
+ suite->add("m", "44", "EMP*", "a[\\u00fe-\\u0507][\\u00ff-\\u0300]b", "aĂ˿b", "aĂ˿b", NULL);
+
+ return suite;
+}
+
+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(regextest_9, "regex.9");
+
+
+/*
+ * 10 anchors and newlines
+ */
+
+class regextest_10 : public RegExTestSuite
+{
+public:
+ regextest_10() : RegExTestSuite("regex.10") { }
+ static Test *suite();
+};
+
+Test *regextest_10::suite()
+{
+ RegExTestSuite *suite = new regextest_10;
+
+ suite->add("m", "1", "&", "^a", "a", "a", NULL);
+ suite->add("f", "2", "&^", "^a", "a", NULL);
+ suite->add("i", "3", "&N", "^", "a", "0 -1", NULL);
+ suite->add("i", "4", "&", "a$", "aba", "2 2", NULL);
+ suite->add("f", "5", "&$", "a$", "a", NULL);
+ suite->add("i", "6", "&N", "$", "ab", "2 1", NULL);
+ suite->add("m", "7", "&n", "^a", "a", "a", NULL);
+ suite->add("m", "8", "&n", "^a", "b\na", "a", NULL);
+ suite->add("i", "9", "&w", "^a", "a\na", "0 0", NULL);
+ suite->add("i", "10", "&n^", "^a", "a\na", "2 2", NULL);
+ suite->add("m", "11", "&n", "a$", "a", "a", NULL);
+ suite->add("m", "12", "&n", "a$", "a\nb", "a", NULL);
+ suite->add("i", "13", "&n", "a$", "a\na", "0 0", NULL);
+ suite->add("i", "14", "N", "^^", "a", "0 -1", NULL);
+ suite->add("m", "15", "b", "^^", "^", "^", NULL);
+ suite->add("i", "16", "N", "$$", "a", "1 0", NULL);
+ suite->add("m", "17", "b", "$$", "$", "$", NULL);
+ suite->add("m", "18", "&N", "^$", "", "", NULL);
+ suite->add("f", "19", "&N", "^$", "a", NULL);
+ suite->add("i", "20", "&nN", "^$", "a\n\nb", "2 1", NULL);
+ suite->add("m", "21", "N", "$^", "", "", NULL);
+ suite->add("m", "22", "b", "$^", "$^", "$^", NULL);
+ suite->add("m", "23", "P", "\\Aa", "a", "a", NULL);
+ suite->add("m", "24", "^P", "\\Aa", "a", "a", NULL);
+ suite->add("f", "25", "^nP", "\\Aa", "b\na", NULL);
+ suite->add("m", "26", "P", "a\\Z", "a", "a", NULL);
+ suite->add("m", "27", "$P", "a\\Z", "a", "a", NULL);
+ suite->add("f", "28", "$nP", "a\\Z", "a\nb", NULL);
+ suite->add("e", "29", "-", "^*", "BADRPT", NULL);
+ suite->add("e", "30", "-", "$*", "BADRPT", NULL);
+ suite->add("e", "31", "-", "\\A*", "BADRPT", NULL);
+ suite->add("e", "32", "-", "\\Z*", "BADRPT", NULL);
+
+ return suite;
+}
+
+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(regextest_10, "regex.10");
+
+
+/*
+ * 11 boundary constraints
+ */
+
+class regextest_11 : public RegExTestSuite
+{
+public:
+ regextest_11() : RegExTestSuite("regex.11") { }
+ static Test *suite();
+};
+
+Test *regextest_11::suite()
+{
+ RegExTestSuite *suite = new regextest_11;
+
+ suite->add("m", "1", "&LP", "[[:<:]]a", "a", "a", NULL);
+ suite->add("m", "2", "&LP", "[[:<:]]a", "-a", "a", NULL);
+ suite->add("f", "3", "&LP", "[[:<:]]a", "ba", NULL);
+ suite->add("m", "4", "&LP", "a[[:>:]]", "a", "a", NULL);
+ suite->add("m", "5", "&LP", "a[[:>:]]", "a-", "a", NULL);
+ suite->add("f", "6", "&LP", "a[[:>:]]", "ab", NULL);
+ suite->add("m", "7", "bLP", "\\<a", "a", "a", NULL);
+ suite->add("f", "8", "bLP", "\\<a", "ba", NULL);
+ suite->add("m", "9", "bLP", "a\\>", "a", "a", NULL);
+ suite->add("f", "10", "bLP", "a\\>", "ab", NULL);
+ suite->add("m", "11", "LP", "\\ya", "a", "a", NULL);
+ suite->add("f", "12", "LP", "\\ya", "ba", NULL);
+ suite->add("m", "13", "LP", "a\\y", "a", "a", NULL);
+ suite->add("f", "14", "LP", "a\\y", "ab", NULL);
+ suite->add("m", "15", "LP", "a\\Y", "ab", "a", NULL);
+ suite->add("f", "16", "LP", "a\\Y", "a-", NULL);
+ suite->add("f", "17", "LP", "a\\Y", "a", NULL);
+ suite->add("f", "18", "LP", "-\\Y", "-a", NULL);
+ suite->add("m", "19", "LP", "-\\Y", "-%", "-", NULL);
+ suite->add("f", "20", "LP", "\\Y-", "a-", NULL);
+ suite->add("e", "21", "-", "[[:<:]]*", "BADRPT", NULL);
+ suite->add("e", "22", "-", "[[:>:]]*", "BADRPT", NULL);
+ suite->add("e", "23", "b", "\\<*", "BADRPT", NULL);
+ suite->add("e", "24", "b", "\\>*", "BADRPT", NULL);
+ suite->add("e", "25", "-", "\\y*", "BADRPT", NULL);
+ suite->add("e", "26", "-", "\\Y*", "BADRPT", NULL);
+ suite->add("m", "27", "LP", "\\ma", "a", "a", NULL);
+ suite->add("f", "28", "LP", "\\ma", "ba", NULL);
+ suite->add("m", "29", "LP", "a\\M", "a", "a", NULL);
+ suite->add("f", "30", "LP", "a\\M", "ab", NULL);
+ suite->add("f", "31", "ILP", "\\Ma", "a", NULL);
+ suite->add("f", "32", "ILP", "a\\m", "a", NULL);
+
+ return suite;
+}
+
+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(regextest_11, "regex.11");
+
+
+/*
+ * 12 character classes
+ */
+
+class regextest_12 : public RegExTestSuite
+{
+public:
+ regextest_12() : RegExTestSuite("regex.12") { }
+ static Test *suite();
+};
+
+Test *regextest_12::suite()
+{
+ RegExTestSuite *suite = new regextest_12;
+
+ suite->add("m", "1", "LP", "a\\db", "a0b", "a0b", NULL);
+ suite->add("f", "2", "LP", "a\\db", "axb", NULL);
+ suite->add("f", "3", "LP", "a\\Db", "a0b", NULL);
+ suite->add("m", "4", "LP", "a\\Db", "axb", "axb", NULL);
+ suite->add("m", "5", "LP", "a\\sb", "a b", "a b", NULL);
+ suite->add("m", "6", "LP", "a\\sb", "a\tb", "a\tb", NULL);
+ suite->add("m", "7", "LP", "a\\sb", "a\nb", "a\nb", NULL);
+ suite->add("f", "8", "LP", "a\\sb", "axb", NULL);
+ suite->add("m", "9", "LP", "a\\Sb", "axb", "axb", NULL);
+ suite->add("f", "10", "LP", "a\\Sb", "a b", NULL);
+ suite->add("m", "11", "LP", "a\\wb", "axb", "axb", NULL);
+ suite->add("f", "12", "LP", "a\\wb", "a-b", NULL);
+ suite->add("f", "13", "LP", "a\\Wb", "axb", NULL);
+ suite->add("m", "14", "LP", "a\\Wb", "a-b", "a-b", NULL);
+ suite->add("m", "15", "LP", "\\y\\w+z\\y", "adze-guz", "guz", NULL);
+ suite->add("m", "16", "LPE", "a[\\d]b", "a1b", "a1b", NULL);
+ suite->add("m", "17", "LPE", "a[\\s]b", "a b", "a b", NULL);
+ suite->add("m", "18", "LPE", "a[\\w]b", "axb", "axb", NULL);
+
+ return suite;
+}
+
+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(regextest_12, "regex.12");
+
+
+/*
+ * 13 escapes
+ */
+
+class regextest_13 : public RegExTestSuite
+{
+public:
+ regextest_13() : RegExTestSuite("regex.13") { }
+ static Test *suite();
+};
+
+Test *regextest_13::suite()
+{
+ RegExTestSuite *suite = new regextest_13;
+
+ suite->add("e", "1", "&", "a\\", "EESCAPE", NULL);
+ suite->add("m", "2", "-", "a\\<b", "a<b", "a<b", NULL);
+ suite->add("m", "3", "e", "a\\<b", "a<b", "a<b", NULL);
+ suite->add("m", "4", "bAS", "a\\wb", "awb", "awb", NULL);
+ suite->add("m", "5", "eAS", "a\\wb", "awb", "awb", NULL);
+ suite->add("m", "6", "PL", "a\\ab", "a\ab", "a\ab", NULL);
+ suite->add("m", "7", "P", "a\\bb", "a\bb", "a\bb", NULL);
+ suite->add("m", "8", "P", "a\\Bb", "a\\b", "a\\b", NULL);
+ suite->add("m", "9", "MP", "a\\chb", "a\bb", "a\bb", NULL);
+ suite->add("m", "10", "MP", "a\\cHb", "a\bb", "a\bb", NULL);
+ suite->add("m", "11", "LMP", "a\\e", "a\033", "a\033", NULL);
+ suite->add("m", "12", "P", "a\\fb", "a\fb", "a\fb", NULL);
+ suite->add("m", "13", "P", "a\\nb", "a\nb", "a\nb", NULL);
+ suite->add("m", "14", "P", "a\\rb", "a\rb", "a\rb", NULL);
+ suite->add("m", "15", "P", "a\\tb", "a\tb", "a\tb", NULL);
+ suite->add("m", "16", "P", "a\\u0008x", "a\bx", "a\bx", NULL);
+ suite->add("e", "17", "-", "a\\u008x", "EESCAPE", NULL);
+ suite->add("m", "18", "P", "a\\u00088x", "a\b8x", "a\b8x", NULL);
+ suite->add("m", "19", "P", "a\\U00000008x", "a\bx", "a\bx", NULL);
+ suite->add("e", "20", "-", "a\\U0000008x", "EESCAPE", NULL);
+ suite->add("m", "21", "P", "a\\vb", "a\vb", "a\vb", NULL);
+ suite->add("m", "22", "MP", "a\\x08x", "a\bx", "a\bx", NULL);
+ suite->add("e", "23", "-", "a\\xq", "EESCAPE", NULL);
+ suite->add("m", "24", "MP", "a\\x0008x", "a\bx", "a\bx", NULL);
+ suite->add("e", "25", "-", "a\\z", "EESCAPE", NULL);
+ suite->add("m", "26", "MP", "a\\010b", "a\bb", "a\bb", NULL);
+
+ return suite;
+}
+
+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(regextest_13, "regex.13");
+
+
+/*
+ * 14 back references
+ */
+
+class regextest_14 : public RegExTestSuite
+{
+public:
+ regextest_14() : RegExTestSuite("regex.14") { }
+ static Test *suite();
+};
+
+Test *regextest_14::suite()
+{
+ RegExTestSuite *suite = new regextest_14;
+
+ suite->add("m", "1", "RP", "a(b*)c\\1", "abbcbb", "abbcbb", "bb", NULL);
+ suite->add("m", "2", "RP", "a(b*)c\\1", "ac", "ac", "", NULL);
+ suite->add("f", "3", "RP", "a(b*)c\\1", "abbcb", NULL);
+ suite->add("m", "4", "RP", "a(b*)\\1", "abbcbb", "abb", "b", NULL);
+ suite->add("m", "5", "RP", "a(b|bb)\\1", "abbcbb", "abb", "b", NULL);
+ suite->add("m", "6", "RP", "a([bc])\\1", "abb", "abb", "b", NULL);
+ suite->add("f", "7", "RP", "a([bc])\\1", "abc", NULL);
+ suite->add("m", "8", "RP", "a([bc])\\1", "abcabb", "abb", "b", NULL);
+ suite->add("f", "9", "RP", "a([bc])*\\1", "abc", NULL);
+ suite->add("f", "10", "RP", "a([bc])\\1", "abB", NULL);
+ suite->add("m", "11", "iRP", "a([bc])\\1", "abB", "abB", "b", NULL);
+ suite->add("m", "12", "RP", "a([bc])\\1+", "abbb", "abbb", "b", NULL);
+ suite->add("m", "13", "QRP", "a([bc])\\1{3,4}", "abbbb", "abbbb", "b", NULL);
+ suite->add("f", "14", "QRP", "a([bc])\\1{3,4}", "abbb", NULL);
+ suite->add("m", "15", "RP", "a([bc])\\1*", "abbb", "abbb", "b", NULL);
+ suite->add("m", "16", "RP", "a([bc])\\1*", "ab", "ab", "b", NULL);
+ suite->add("m", "17", "RP", "a([bc])(\\1*)", "ab", "ab", "b", "", NULL);
+ suite->add("e", "18", "-", "a((b)\\1)", "ESUBREG", NULL);
+ suite->add("e", "19", "-", "a(b)c\\2", "ESUBREG", NULL);
+ suite->add("m", "20", "bR", "a\\(b*\\)c\\1", "abbcbb", "abbcbb", "bb", NULL);
+
+ return suite;
+}
+
+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(regextest_14, "regex.14");
+
+
+/*
+ * 15 octal escapes vs back references
+ */
+
+class regextest_15 : public RegExTestSuite
+{
+public:
+ regextest_15() : RegExTestSuite("regex.15") { }
+ static Test *suite();
+};
+
+Test *regextest_15::suite()
+{
+ RegExTestSuite *suite = new regextest_15;
+
+ suite->add("m", "1", "MP", "a\\010b", "a\bb", "a\bb", NULL);
+ suite->add("m", "2", "MP", "a\\0070b", "a\a0b", "a\a0b", NULL);
+ suite->add("m", "3", "MP", "a\\07b", "a\ab", "a\ab", NULL);
+ suite->add("m", "4", "MP", "a(b)(b)(b)(b)(b)(b)(b)(b)(b)(b)\\07c", "abbbbbbbbbb\ac", "abbbbbbbbbb\ac", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", NULL);
+ suite->add("e", "5", "-", "a\\7b", "ESUBREG", NULL);
+ suite->add("m", "6", "MP", "a\\10b", "a\bb", "a\bb", NULL);
+ suite->add("m", "7", "MP", "a\\101b", "aAb", "aAb", NULL);
+ suite->add("m", "8", "RP", "a(b)(b)(b)(b)(b)(b)(b)(b)(b)(b)\\10c", "abbbbbbbbbbbc", "abbbbbbbbbbbc", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", NULL);
+ suite->add("e", "9", "-", "a((((((((((b\\10))))))))))c", "ESUBREG", NULL);
+ suite->add("m", "10", "MP", "a\\12b", "a\nb", "a\nb", NULL);
+ suite->add("e", "11", "b", "a\\12b", "ESUBREG", NULL);
+ suite->add("m", "12", "eAS", "a\\12b", "a12b", "a12b", NULL);
+
+ return suite;
+}
+
+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(regextest_15, "regex.15");
+
+
+/*
+ * 16 expanded syntax
+ */
+
+class regextest_16 : public RegExTestSuite
+{
+public:
+ regextest_16() : RegExTestSuite("regex.16") { }
+ static Test *suite();
+};
+
+Test *regextest_16::suite()
+{
+ RegExTestSuite *suite = new regextest_16;
+
+ suite->add("m", "1", "xP", "a b c", "abc", "abc", NULL);
+ suite->add("m", "2", "xP", "a b #oops\nc\td", "abcd", "abcd", NULL);
+ suite->add("m", "3", "x", "a\\ b\\\tc", "a b\tc", "a b\tc", NULL);
+ suite->add("m", "4", "xP", "a b\\#c", "ab#c", "ab#c", NULL);
+ suite->add("m", "5", "xP", "a b[c d]e", "ab e", "ab e", NULL);
+ suite->add("m", "6", "xP", "a b[c#d]e", "ab#e", "ab#e", NULL);
+ suite->add("m", "7", "xP", "a b[c#d]e", "abde", "abde", NULL);
+ suite->add("m", "8", "xSPB", "ab{ d", "ab{d", "ab{d", NULL);
+ suite->add("m", "9", "xPQ", "ab{ 1 , 2 }c", "abc", "abc", NULL);
+
+ return suite;
+}
+
+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(regextest_16, "regex.16");
+
+
+/*
+ * 17 misc syntax
+ */
+
+class regextest_17 : public RegExTestSuite
+{
+public:
+ regextest_17() : RegExTestSuite("regex.17") { }
+ static Test *suite();
+};
+
+Test *regextest_17::suite()
+{
+ RegExTestSuite *suite = new regextest_17;
+
+ suite->add("m", "1", "P", "a(?#comment)b", "ab", "ab", NULL);
+
+ return suite;
+}
+
+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(regextest_17, "regex.17");
+
+
+/*
+ * 18 unmatchable REs
+ */
+
+class regextest_18 : public RegExTestSuite
+{
+public:
+ regextest_18() : RegExTestSuite("regex.18") { }
+ static Test *suite();
+};
+
+Test *regextest_18::suite()
+{
+ RegExTestSuite *suite = new regextest_18;
+
+ suite->add("f", "1", "I", "a^b", "ab", NULL);
+
+ return suite;
+}
+
+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(regextest_18, "regex.18");
+
+
+/*
+ * 19 case independence
+ */
+
+class regextest_19 : public RegExTestSuite
+{
+public:
+ regextest_19() : RegExTestSuite("regex.19") { }
+ static Test *suite();
+};
+
+Test *regextest_19::suite()
+{
+ RegExTestSuite *suite = new regextest_19;
+
+ suite->add("m", "1", "&i", "ab", "Ab", "Ab", NULL);
+ suite->add("m", "2", "&i", "a[bc]", "aC", "aC", NULL);
+ suite->add("f", "3", "&i", "a[^bc]", "aB", NULL);
+ suite->add("m", "4", "&iM", "a[b-d]", "aC", "aC", NULL);
+ suite->add("f", "5", "&iM", "a[^b-d]", "aC", NULL);
+
+ return suite;
+}
+
+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(regextest_19, "regex.19");
+
+
+/*
+ * 20 directors and embedded options
+ */
+
+class regextest_20 : public RegExTestSuite
+{
+public:
+ regextest_20() : RegExTestSuite("regex.20") { }
+ static Test *suite();
+};
+
+Test *regextest_20::suite()
+{
+ RegExTestSuite *suite = new regextest_20;
+
+ suite->add("e", "1", "&", "***?", "BADPAT", NULL);
+ suite->add("m", "2", "q", "***?", "***?", "***?", NULL);
+ suite->add("m", "3", "&P", "***=a*b", "a*b", "a*b", NULL);
+ suite->add("m", "4", "q", "***=a*b", "***=a*b", "***=a*b", NULL);
+ suite->add("m", "5", "bLP", "***:\\w+", "ab", "ab", NULL);
+ suite->add("m", "6", "eLP", "***:\\w+", "ab", "ab", NULL);
+ suite->add("e", "7", "&", "***:***=a*b", "BADRPT", NULL);
+ suite->add("m", "8", "&P", "***:(?b)a+b", "a+b", "a+b", NULL);
+ suite->add("m", "9", "P", "(?b)a+b", "a+b", "a+b", NULL);
+ suite->add("e", "10", "e", "(?b)\\w+", "BADRPT", NULL);
+ suite->add("m", "11", "bAS", "(?b)\\w+", "(?b)w+", "(?b)w+", NULL);
+ suite->add("m", "12", "iP", "(?c)a", "a", "a", NULL);
+ suite->add("f", "13", "iP", "(?c)a", "A", NULL);
+ suite->add("m", "14", "APS", "(?e)\\W+", "WW", "WW", NULL);
+ suite->add("m", "15", "P", "(?i)a+", "Aa", "Aa", NULL);
+ suite->add("f", "16", "P", "(?m)a.b", "a\nb", NULL);
+ suite->add("m", "17", "P", "(?m)^b", "a\nb", "b", NULL);
+ suite->add("f", "18", "P", "(?n)a.b", "a\nb", NULL);
+ suite->add("m", "19", "P", "(?n)^b", "a\nb", "b", NULL);
+ suite->add("f", "20", "P", "(?p)a.b", "a\nb", NULL);
+ suite->add("f", "21", "P", "(?p)^b", "a\nb", NULL);
+ suite->add("m", "22", "P", "(?q)a+b", "a+b", "a+b", NULL);
+ suite->add("m", "23", "nP", "(?s)a.b", "a\nb", "a\nb", NULL);
+ suite->add("m", "24", "xP", "(?t)a b", "a b", "a b", NULL);
+ suite->add("m", "25", "P", "(?w)a.b", "a\nb", "a\nb", NULL);
+ suite->add("m", "26", "P", "(?w)^b", "a\nb", "b", NULL);
+ suite->add("m", "27", "P", "(?x)a b", "ab", "ab", NULL);
+ suite->add("e", "28", "-", "(?z)ab", "BADOPT", NULL);
+ suite->add("m", "29", "P", "(?ici)a+", "Aa", "Aa", NULL);
+ suite->add("e", "30", "P", "(?i)(?q)a+", "BADRPT", NULL);
+ suite->add("m", "31", "P", "(?q)(?i)a+", "(?i)a+", "(?i)a+", NULL);
+ suite->add("m", "32", "P", "(?qe)a+", "a", "a", NULL);
+ suite->add("m", "33", "xP", "(?q)a b", "a b", "a b", NULL);
+ suite->add("m", "34", "P", "(?qx)a b", "a b", "a b", NULL);
+ suite->add("m", "35", "P", "(?qi)ab", "Ab", "Ab", NULL);
+
+ return suite;
+}
+
+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(regextest_20, "regex.20");
+
+
+/*
+ * 21 capturing
+ */
+
+class regextest_21 : public RegExTestSuite
+{
+public:
+ regextest_21() : RegExTestSuite("regex.21") { }
+ static Test *suite();
+};
+
+Test *regextest_21::suite()
+{
+ RegExTestSuite *suite = new regextest_21;
+
+ suite->add("m", "1", "-", "a(b)c", "abc", "abc", "b", NULL);
+ suite->add("m", "2", "P", "a(?:b)c", "xabc", "abc", NULL);
+ suite->add("m", "3", "-", "a((b))c", "xabcy", "abc", "b", "b", NULL);
+ suite->add("m", "4", "P", "a(?:(b))c", "abcy", "abc", "b", NULL);
+ suite->add("m", "5", "P", "a((?:b))c", "abc", "abc", "b", NULL);
+ suite->add("m", "6", "P", "a(?:(?:b))c", "abc", "abc", NULL);
+ suite->add("i", "7", "Q", "a(b){0}c", "ac", "0 1", "-1 -1", NULL);
+ suite->add("m", "8", "-", "a(b)c(d)e", "abcde", "abcde", "b", "d", NULL);
+ suite->add("m", "9", "-", "(b)c(d)e", "bcde", "bcde", "b", "d", NULL);
+ suite->add("m", "10", "-", "a(b)(d)e", "abde", "abde", "b", "d", NULL);
+ suite->add("m", "11", "-", "a(b)c(d)", "abcd", "abcd", "b", "d", NULL);
+ suite->add("m", "12", "-", "(ab)(cd)", "xabcdy", "abcd", "ab", "cd", NULL);
+ suite->add("m", "13", "-", "a(b)?c", "xabcy", "abc", "b", NULL);
+ suite->add("i", "14", "-", "a(b)?c", "xacy", "1 2", "-1 -1", NULL);
+ suite->add("m", "15", "-", "a(b)?c(d)?e", "xabcdey", "abcde", "b", "d", NULL);
+ suite->add("i", "16", "-", "a(b)?c(d)?e", "xacdey", "1 4", "-1 -1", "3 3", NULL);
+ suite->add("i", "17", "-", "a(b)?c(d)?e", "xabcey", "1 4", "2 2", "-1 -1", NULL);
+ suite->add("i", "18", "-", "a(b)?c(d)?e", "xacey", "1 3", "-1 -1", "-1 -1", NULL);
+ suite->add("m", "19", "-", "a(b)*c", "xabcy", "abc", "b", NULL);
+ suite->add("i", "20", "-", "a(b)*c", "xabbbcy", "1 5", "4 4", NULL);
+ suite->add("i", "21", "-", "a(b)*c", "xacy", "1 2", "-1 -1", NULL);
+ suite->add("m", "22", "-", "a(b*)c", "xabbbcy", "abbbc", "bbb", NULL);
+ suite->add("m", "23", "-", "a(b*)c", "xacy", "ac", "", NULL);
+ suite->add("f", "24", "-", "a(b)+c", "xacy", NULL);
+ suite->add("m", "25", "-", "a(b)+c", "xabcy", "abc", "b", NULL);
+ suite->add("i", "26", "-", "a(b)+c", "xabbbcy", "1 5", "4 4", NULL);
+ suite->add("m", "27", "-", "a(b+)c", "xabbbcy", "abbbc", "bbb", NULL);
+ suite->add("i", "28", "Q", "a(b){2,3}c", "xabbbcy", "1 5", "4 4", NULL);
+ suite->add("i", "29", "Q", "a(b){2,3}c", "xabbcy", "1 4", "3 3", NULL);
+ suite->add("f", "30", "Q", "a(b){2,3}c", "xabcy", NULL);
+ suite->add("m", "31", "LP", "\\y(\\w+)\\y", "-- abc-", "abc", "abc", NULL);
+ suite->add("m", "32", "-", "a((b|c)d+)+", "abacdbd", "acdbd", "bd", "b", NULL);
+ suite->add("m", "33", "N", "(.*).*", "abc", "abc", "abc", NULL);
+ suite->add("m", "34", "N", "(a*)*", "bc", "", "", NULL);
+
+ return suite;
+}
+
+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(regextest_21, "regex.21");
+
+
+/*
+ * 22 multicharacter collating elements
+ */
+
+class regextest_22 : public RegExTestSuite
+{
+public:
+ regextest_22() : RegExTestSuite("regex.22") { }
+ static Test *suite();
+};
+
+Test *regextest_22::suite()
+{
+ RegExTestSuite *suite = new regextest_22;
+
+ suite->add("m", "1", "&+L", "a[c]e", "ace", "ace", NULL);
+ suite->add("f", "2", "&+IL", "a[c]h", "ach", NULL);
+ suite->add("m", "3", "&+L", "a[[.ch.]]", "ach", "ach", NULL);
+ suite->add("f", "4", "&+L", "a[[.ch.]]", "ace", NULL);
+ suite->add("m", "5", "&+L", "a[c[.ch.]]", "ac", "ac", NULL);
+ suite->add("m", "6", "&+L", "a[c[.ch.]]", "ace", "ac", NULL);
+ suite->add("m", "7", "&+L", "a[c[.ch.]]", "ache", "ach", NULL);
+ suite->add("f", "8", "&+L", "a[^c]e", "ace", NULL);
+ suite->add("m", "9", "&+L", "a[^c]e", "abe", "abe", NULL);
+ suite->add("m", "10", "&+L", "a[^c]e", "ache", "ache", NULL);
+ suite->add("f", "11", "&+L", "a[^[.ch.]]", "ach", NULL);
+ suite->add("m", "12", "&+L", "a[^[.ch.]]", "ace", "ac", NULL);
+ suite->add("m", "13", "&+L", "a[^[.ch.]]", "ac", "ac", NULL);
+ suite->add("m", "14", "&+L", "a[^[.ch.]]", "abe", "ab", NULL);
+ suite->add("f", "15", "&+L", "a[^c[.ch.]]", "ach", NULL);
+ suite->add("f", "16", "&+L", "a[^c[.ch.]]", "ace", NULL);
+ suite->add("f", "17", "&+L", "a[^c[.ch.]]", "ac", NULL);
+ suite->add("m", "18", "&+L", "a[^c[.ch.]]", "abe", "ab", NULL);
+ suite->add("m", "19", "&+L", "a[^b]", "ac", "ac", NULL);
+ suite->add("m", "20", "&+L", "a[^b]", "ace", "ac", NULL);
+ suite->add("m", "21", "&+L", "a[^b]", "ach", "ach", NULL);
+ suite->add("f", "22", "&+L", "a[^b]", "abe", NULL);
+
+ return suite;
+}
+
+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(regextest_22, "regex.22");
+
+
+/*
+ * 23 lookahead constraints
+ */
+
+class regextest_23 : public RegExTestSuite
+{
+public:
+ regextest_23() : RegExTestSuite("regex.23") { }
+ static Test *suite();
+};
+
+Test *regextest_23::suite()
+{
+ RegExTestSuite *suite = new regextest_23;
+
+ suite->add("m", "1", "HP", "a(?=b)b*", "ab", "ab", NULL);
+ suite->add("f", "2", "HP", "a(?=b)b*", "a", NULL);
+ suite->add("m", "3", "HP", "a(?=b)b*(?=c)c*", "abc", "abc", NULL);
+ suite->add("f", "4", "HP", "a(?=b)b*(?=c)c*", "ab", NULL);
+ suite->add("f", "5", "HP", "a(?!b)b*", "ab", NULL);
+ suite->add("m", "6", "HP", "a(?!b)b*", "a", "a", NULL);
+ suite->add("m", "7", "HP", "(?=b)b", "b", "b", NULL);
+ suite->add("f", "8", "HP", "(?=b)b", "a", NULL);
+
+ return suite;
+}
+
+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(regextest_23, "regex.23");
+
+
+/*
+ * 24 non-greedy quantifiers
+ */
+
+class regextest_24 : public RegExTestSuite
+{
+public:
+ regextest_24() : RegExTestSuite("regex.24") { }
+ static Test *suite();
+};
+
+Test *regextest_24::suite()
+{
+ RegExTestSuite *suite = new regextest_24;
+
+ suite->add("m", "1", "PT", "ab+?", "abb", "ab", NULL);
+ suite->add("m", "2", "PT", "ab+?c", "abbc", "abbc", NULL);
+ suite->add("m", "3", "PT", "ab*?", "abb", "a", NULL);
+ suite->add("m", "4", "PT", "ab*?c", "abbc", "abbc", NULL);
+ suite->add("m", "5", "PT", "ab??", "ab", "a", NULL);
+ suite->add("m", "6", "PT", "ab??c", "abc", "abc", NULL);
+ suite->add("m", "7", "PQT", "ab{2,4}?", "abbbb", "abb", NULL);
+ suite->add("m", "8", "PQT", "ab{2,4}?c", "abbbbc", "abbbbc", NULL);
+ suite->add("m", "9", "-", "3z*", "123zzzz456", "3zzzz", NULL);
+ suite->add("m", "10", "PT", "3z*?", "123zzzz456", "3", NULL);
+ suite->add("m", "11", "-", "z*4", "123zzzz456", "zzzz4", NULL);
+ suite->add("m", "12", "PT", "z*?4", "123zzzz456", "zzzz4", NULL);
+
+ return suite;
+}
+
+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(regextest_24, "regex.24");
+
+
+/*
+ * 25 mixed quantifiers
+ */
+
+class regextest_25 : public RegExTestSuite
+{
+public:
+ regextest_25() : RegExTestSuite("regex.25") { }
+ static Test *suite();
+};
+
+Test *regextest_25::suite()
+{
+ RegExTestSuite *suite = new regextest_25;
+
+ suite->add("m", "1", "PNT", "^(.*?)(a*)$", "xyza", "xyza", "xyz", "a", NULL);
+ suite->add("m", "2", "PNT", "^(.*?)(a*)$", "xyzaa", "xyzaa", "xyz", "aa", NULL);
+ suite->add("m", "3", "PNT", "^(.*?)(a*)$", "xyz", "xyz", "xyz", "", NULL);
+
+ return suite;
+}
+
+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(regextest_25, "regex.25");
+
+
+/*
+ * 26 tricky cases
+ */
+
+class regextest_26 : public RegExTestSuite
+{
+public:
+ regextest_26() : RegExTestSuite("regex.26") { }
+ static Test *suite();
+};
+
+Test *regextest_26::suite()
+{
+ RegExTestSuite *suite = new regextest_26;
+
+ suite->add("m", "1", "-", "(week|wee)(night|knights)", "weeknights", "weeknights", "wee", "knights", NULL);
+ suite->add("m", "2", "RP", "a(bc*).*\\1", "abccbccb", "abccbccb", "b", NULL);
+ suite->add("m", "3", "-", "a(b.[bc]*)+", "abcbd", "abcbd", "bd", NULL);
+
+ return suite;
+}
+
+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(regextest_26, "regex.26");
+
+
+/*
+ * 27 implementation misc.
+ */
+
+class regextest_27 : public RegExTestSuite
+{
+public:
+ regextest_27() : RegExTestSuite("regex.27") { }
+ static Test *suite();
+};
+
+Test *regextest_27::suite()
+{
+ RegExTestSuite *suite = new regextest_27;
+
+ suite->add("m", "1", "P", "a(?:b|b)c", "abc", "abc", NULL);
+ suite->add("m", "2", "&", "[ab][ab][ab]", "aba", "aba", NULL);
+ suite->add("m", "3", "&", "[ab][ab][ab][ab][ab][ab][ab]", "abababa", "abababa", NULL);
+
+ return suite;
+}
+
+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(regextest_27, "regex.27");
+
+
+/*
+ * 28 boundary busters etc.
+ */
+
+class regextest_28 : public RegExTestSuite
+{
+public:
+ regextest_28() : RegExTestSuite("regex.28") { }
+ static Test *suite();
+};
+
+Test *regextest_28::suite()
+{
+ RegExTestSuite *suite = new regextest_28;
+
+ suite->add("m", "1", "&", "abcdefghijkl", "abcdefghijkl", "abcdefghijkl", NULL);
+ suite->add("m", "2", "P", "a(?:b|c|d|e|f|g|h|i|j|k|l|m)n", "agn", "agn", NULL);
+ suite->add("m", "3", "-", "a(((((((((((((b)))))))))))))c", "abc", "abc", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", NULL);
+ suite->add("m", "4", "Q", "ab{1,100}c", "abbc", "abbc", NULL);
+ suite->add("m", "5", "Q", "ab{1,100}c", "abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbc", "abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbc", NULL);
+ suite->add("m", "6", "Q", "ab{1,100}c", "abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbc", "abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbc", NULL);
+ suite->add("m", "7", "LP", "\\w+abcdefgh", "xyzabcdefgh", "xyzabcdefgh", NULL);
+ suite->add("m", "8", "%LP", "\\w+abcdefgh", "xyzabcdefgh", "xyzabcdefgh", NULL);
+ suite->add("m", "9", "%LP", "\\w+abcdefghijklmnopqrst", "xyzabcdefghijklmnopqrst", "xyzabcdefghijklmnopqrst", NULL);
+ suite->add("i", "10", "%LP", "\\w+(abcdefgh)?", "xyz", "0 2", "-1 -1", NULL);
+ suite->add("i", "11", "%LP", "\\w+(abcdefgh)?", "xyzabcdefg", "0 9", "-1 -1", NULL);
+ suite->add("i", "12", "%LP", "\\w+(abcdefghijklmnopqrst)?", "xyzabcdefghijklmnopqrs", "0 21", "-1 -1", NULL);
+
+ return suite;
+}
+
+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(regextest_28, "regex.28");
+
+
+/*
+ * 29 incomplete matches
+ */
+
+class regextest_29 : public RegExTestSuite
+{
+public:
+ regextest_29() : RegExTestSuite("regex.29") { }
+ static Test *suite();
+};
+
+Test *regextest_29::suite()
+{
+ RegExTestSuite *suite = new regextest_29;
+
+ suite->add("p", "1", "t", "def", "abc", "3 2", "", NULL);
+ suite->add("p", "2", "t", "bcd", "abc", "1 2", "", NULL);
+ suite->add("p", "3", "t", "abc", "abab", "0 3", "", NULL);
+ suite->add("p", "4", "t", "abc", "abdab", "3 4", "", NULL);
+ suite->add("i", "5", "t", "abc", "abc", "0 2", "0 2", NULL);
+ suite->add("i", "6", "t", "abc", "xyabc", "2 4", "2 4", NULL);
+ suite->add("p", "7", "t", "abc+", "xyab", "2 3", "", NULL);
+ suite->add("i", "8", "t", "abc+", "xyabc", "2 4", "2 4", NULL);
+ suite->add("i", "10", "t", "abc+", "xyabcdd", "2 4", "7 6", NULL);
+ suite->add("p", "11", "tPT", "abc+?", "xyab", "2 3", "", NULL);
+ suite->add("i", "12", "tPT", "abc+?", "xyabc", "2 4", "5 4", NULL);
+ suite->add("i", "13", "tPT", "abc+?", "xyabcc", "2 4", "6 5", NULL);
+ suite->add("i", "14", "tPT", "abc+?", "xyabcd", "2 4", "6 5", NULL);
+ suite->add("i", "15", "tPT", "abc+?", "xyabcdd", "2 4", "7 6", NULL);
+ suite->add("i", "16", "t", "abcd|bc", "xyabc", "3 4", "2 4", NULL);
+ suite->add("p", "17", "tn", ".*k", "xx\nyyy", "3 5", "", NULL);
+
+ return suite;
+}
+
+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(regextest_29, "regex.29");
+
+
+/*
+ * 30 misc. oddities and old bugs
+ */
+
+class regextest_30 : public RegExTestSuite
+{
+public:
+ regextest_30() : RegExTestSuite("regex.30") { }
+ static Test *suite();
+};
+
+Test *regextest_30::suite()
+{
+ RegExTestSuite *suite = new regextest_30;
+
+ suite->add("e", "1", "&", "***", "BADRPT", NULL);
+ suite->add("m", "2", "N", "a?b*", "abb", "abb", NULL);
+ suite->add("m", "3", "N", "a?b*", "bb", "bb", NULL);
+ suite->add("m", "4", "&", "a*b", "aab", "aab", NULL);
+ suite->add("m", "5", "&", "^a*b", "aaaab", "aaaab", NULL);
+ suite->add("m", "6", "&M", "[0-6][1-2][0-3][0-6][1-6][0-6]", "010010", "010010", NULL);
+ suite->add("m", "7", "s", "abc", "abcd", "abc", NULL);
+ suite->add("f", "8", "s", "abc", "xabcd", NULL);
+ suite->add("m", "9", "HLP", "(?n)^(?![t#])\\S+", "tk\n\n#\n#\nit0", "it0", NULL);
+
+ return suite;
+}
+
+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(regextest_30, "regex.30");
+
+
+/*
+ * extra_1 checks for bug fixes
+ */
+
+class regextest_extra_1 : public RegExTestSuite
+{
+public:
+ regextest_extra_1() : RegExTestSuite("regex.extra_1") { }
+ static Test *suite();
+};
+
+Test *regextest_extra_1::suite()
+{
+ RegExTestSuite *suite = new regextest_extra_1;
+
+ suite->add("m", "Bug 230589", "-", "[ ]*(^|[^%])%V", "*%V2", NULL);
+ suite->add("m", "Bug 504785", "-", "([^_.]*)([^.]*)\\.(..)(.).*", "bbcos_001_c01.q1la", "bbcos_001_c01.q1la", "bbcos", "_001_c01", "q1", "l", NULL);
+ suite->add("m", "Bug 505048", "-", "\\A\\s*[^<]*\\s*<([^>]+)>", "a<a>", NULL);
+ suite->add("m", "Bug 505048", "-", "\\A\\s*([^b]*)b", "ab", NULL);
+ suite->add("m", "Bug 505048", "-", "\\A\\s*[^b]*(b)", "ab", NULL);
+ suite->add("m", "Bug 505048", "-", "\\A(\\s*)[^b]*(b)", "ab", NULL);
+ suite->add("m", "Bug 505048", "-", "\\A\\s*[^b]*b", "ab", NULL);
+ suite->add("m", "Bug 505048", "-", "\\A\\s*[^b]*b", "ab", "ab", NULL);
+ suite->add("i", "Bug 505048", "-", "\\A\\s*[^b]*b", "ab", "0 1", NULL);
+
+ return suite;
+}
+
+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(regextest_extra_1, "regex.extra_1");
+
+
+/*
+ * wx_1 character classification: ascii
+ */
+
+class regextest_wx_1 : public RegExTestSuite
+{
+public:
+ regextest_wx_1() : RegExTestSuite("regex.wx_1") { }
+ static Test *suite();
+};
+
+Test *regextest_wx_1::suite()
+{
+ RegExTestSuite *suite = new regextest_wx_1;
+
+ suite->add("m", "1", "&", "[^[:alnum:]]", "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!", "!", NULL);
+ suite->add("m", "2", "&", "[[:alnum:]]", "\a\b\t\n\v\f\r !\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~X", "X", NULL);
+ suite->add("m", "3", "&", "[^[:alpha:]]", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!", "!", NULL);
+ suite->add("m", "4", "&", "[[:alpha:]]", "\a\b\t\n\v\f\r !\"#$%&'()*+,-./0123456789:;<=>?@[\\]^_`{|}~X", "X", NULL);
+ suite->add("m", "5", "&", "[^[:cntrl:]]", "\a\b\t\n\v\f\r!", "!", NULL);
+ suite->add("m", "6", "&", "[[:cntrl:]]", " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\n", "\n", NULL);
+ suite->add("m", "7", "&", "[^[:digit:]]", "0123456789!", "!", NULL);
+ suite->add("m", "8", "&", "[[:digit:]]", "\a\b\t\n\v\f\r !\"#$%&'()*+,-./:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ 0", "0", NULL);
+ suite->add("m", "9", "&", "[^[:graph:]]", "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\n", "\n", NULL);
+ suite->add("m", "10", "&", "[[:graph:]]", "\a\b\t\n\v\f\r !", "!", NULL);
+ suite->add("m", "11", "&", "[^[:lower:]]", "abcdefghijklmnopqrstuvwxyz!", "!", NULL);
+ suite->add("m", "12", "&", "[[:lower:]]", "\a\b\t\n\v\f\r !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`{|}~x", "x", NULL);
+ suite->add("m", "13", "&", "[^[:print:]]", "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\n", "\n", NULL);
+ suite->add("m", "14", "&", "[[:print:]]", "\a\b\n\v\f\rX", "X", NULL);
+ suite->add("m", "15", "&", "[^[:punct:]]", "!\"#%&'()*,-./:;?@[\\]_{}X", "X", NULL);
+ suite->add("m", "16", "&", "[[:punct:]]", "\a\b\t\n\v\f\r 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!", "!", NULL);
+ suite->add("m", "17", "&", "[^[:space:]]", "\t\n\v\f\r X", "X", NULL);
+ suite->add("m", "18", "&", "[[:space:]]", "\a\b!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\n", "\n", NULL);
+ suite->add("m", "19", "&", "[^[:upper:]]", "ABCDEFGHIJKLMNOPQRSTUVWXYZ!", "!", NULL);
+ suite->add("m", "20", "&", "[[:upper:]]", "\a\b\t\n\v\f\r !\"#$%&'()*+,-./0123456789:;<=>?@[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~X", "X", NULL);
+ suite->add("m", "21", "&", "[^[:xdigit:]]", "0123456789ABCDEFabcdef!", "!", NULL);
+ suite->add("m", "22", "&", "[[:xdigit:]]", "\a\b\t\n\v\f\r !\"#$%&'()*+,-./:;<=>?@GHIJKLMNOPQRSTUVWXYZ[\\]^_`ghijklmnopqrstuvwxyz{|}~a", "a", NULL);
+ suite->add("i", "23", "&i", "AbCdEfGhIjKlMnOpQrStUvWxYz", "aBcDeFgHiJkLmNoPqRsTuVwXyZ", "0 25", NULL);
+
+ return suite;
+}
+
+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(regextest_wx_1, "regex.wx_1");
+
+
+/*
+ * wx_2 character classification: western european
+ */
+
+class regextest_wx_2 : public RegExTestSuite
+{
+public:
+ regextest_wx_2() : RegExTestSuite("regex.wx_2") { }
+ static Test *suite();
+};
+
+Test *regextest_wx_2::suite()
+{
+ RegExTestSuite *suite = new regextest_wx_2;
+
+ suite->add("m", "1", "&", "[^[:alpha:]]", "ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ!", "!", NULL);
+ suite->add("m", "2", "&", "[[:alpha:]]", " ¡¢£¤¥¦§¨©«¬®¯°±²³´¶·¸¹»¼½¾¿×÷X", "X", NULL);
+ suite->add("m", "3", "&", "[^[:lower:]]", "ßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ!", "!", NULL);
+ suite->add("m", "4", "&", "[[:lower:]]", " ¡¢£¤¥¦§¨©«¬®¯°±²³´¶·¸¹»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞ÷x", "x", NULL);
+ suite->add("m", "5", "&", "[^[:upper:]]", "ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞ!", "!", NULL);
+ suite->add("m", "6", "&", "[[:upper:]]", " ¡¢£¤¥¦§¨©«¬®¯°±²³´¶·¸¹»¼½¾¿×ßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿX", "X", NULL);
+ suite->add("i", "7", "&i*", "ÀáÂãÄåÆçÈéÊëÌíÎïÐñÒóÔõÖøÙúÛüÝþ", "àÁâÃäÅæÇèÉêËìÍîÏðÑòÓôÕöØùÚûÜýÞ", "0 29", NULL);
+
+ return suite;
+}
+
+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(regextest_wx_2, "regex.wx_2");
+
+
+/*
+ * wx_3 character classification: cyrillic
+ */
+
+class regextest_wx_3 : public RegExTestSuite
+{
+public:
+ regextest_wx_3() : RegExTestSuite("regex.wx_3") { }
+ static Test *suite();
+};
+
+Test *regextest_wx_3::suite()
+{
+ RegExTestSuite *suite = new regextest_wx_3;
+
+ suite->add("m", "1", "&", "[^[:alpha:]]", "ёЁюабцдефгхийклмнопярстужвьызшэщчъЮАБЦДЕФГХИЙКЛМНОПЯРСТУЖВЬЫЗШЭЩЧЪ!", "!", NULL);
+ suite->add("m", "2", "&", "[^[:lower:]]", "ёюабцдефгхийклмнопярстужвьызшэщчъ!", "!", NULL);
+ suite->add("m", "3", "&", "[[:lower:]]", "ЁЮАБЦДЕФГХИЙКЛМНОПЯРСТУЖВЬЫЗШЭЩЧЪx", "x", NULL);
+ suite->add("m", "4", "&", "[^[:upper:]]", "ЁЮАБЦДЕФГХИЙКЛМНОПЯРСТУЖВЬЫЗШЭЩЧЪ!", "!", NULL);
+ suite->add("m", "5", "&", "[[:upper:]]", "ёюабцдефгхийклмнопярстужвьызшэщчъX", "X", NULL);
+ suite->add("i", "6", "&i*", "ЁюАбЦдЕфГхИйКлМнОпЯрСтУжВьЫзШэЩчЪ", "ёЮаБцДеФгХиЙкЛмНоПяРсТуЖвЬыЗшЭщЧъ", "0 32", NULL);
+
+ return suite;
+}
+
+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(regextest_wx_3, "regex.wx_3");
+
+
+/*
+ * A suite containing all the above suites
+ */
+
+class regextest : public TestSuite
+{
+public:
+ regextest() : TestSuite("regex") { }
+ static Test *suite();
+};
+
+Test *regextest::suite()
+{
+ TestSuite *suite = new regextest;
+
+ suite->addTest(regextest_1::suite());
+ suite->addTest(regextest_2::suite());
+ suite->addTest(regextest_3::suite());
+ suite->addTest(regextest_4::suite());
+ suite->addTest(regextest_5::suite());
+ suite->addTest(regextest_6::suite());
+ suite->addTest(regextest_7::suite());
+ suite->addTest(regextest_8::suite());
+ suite->addTest(regextest_9::suite());
+ suite->addTest(regextest_10::suite());
+ suite->addTest(regextest_11::suite());
+ suite->addTest(regextest_12::suite());
+ suite->addTest(regextest_13::suite());
+ suite->addTest(regextest_14::suite());
+ suite->addTest(regextest_15::suite());
+ suite->addTest(regextest_16::suite());
+ suite->addTest(regextest_17::suite());
+ suite->addTest(regextest_18::suite());
+ suite->addTest(regextest_19::suite());
+ suite->addTest(regextest_20::suite());
+ suite->addTest(regextest_21::suite());
+ suite->addTest(regextest_22::suite());
+ suite->addTest(regextest_23::suite());
+ suite->addTest(regextest_24::suite());
+ suite->addTest(regextest_25::suite());
+ suite->addTest(regextest_26::suite());
+ suite->addTest(regextest_27::suite());
+ suite->addTest(regextest_28::suite());
+ suite->addTest(regextest_29::suite());
+ suite->addTest(regextest_30::suite());
+ suite->addTest(regextest_extra_1::suite());
+ suite->addTest(regextest_wx_1::suite());
+ suite->addTest(regextest_wx_2::suite());
+ suite->addTest(regextest_wx_3::suite());
+
+ return suite;
+}
+
+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(regextest, "regex");
+CPPUNIT_TEST_SUITE_REGISTRATION(regextest);