Commit 21e671de authored by Russ Cox's avatar Russ Cox

exp/regexp: add CompilePOSIX, more tests

R=r
CC=golang-dev
https://golang.org/cl/4967060
parent 177dca77
......@@ -6,9 +6,12 @@ package regexp
import (
"bufio"
"compress/gzip"
"compress/bzip2"
"exp/regexp/syntax"
"fmt"
"io"
"os"
"path/filepath"
"strconv"
"strings"
"testing"
......@@ -59,24 +62,34 @@ import (
// At time of writing, re2.txt is 32 MB but compresses to 760 kB,
// so we store re2.txt.gz in the repository and decompress it on the fly.
//
func TestRE2(t *testing.T) {
func TestRE2Search(t *testing.T) {
testRE2(t, "testdata/re2-search.txt")
}
func TestRE2Exhaustive(t *testing.T) {
if testing.Short() {
t.Log("skipping TestRE2 during short test")
t.Log("skipping TestRE2Exhaustive during short test")
return
}
testRE2(t, "testdata/re2-exhaustive.txt.bz2")
}
f, err := os.Open("re2.txt.gz")
func testRE2(t *testing.T, file string) {
f, err := os.Open(file)
if err != nil {
t.Fatal(err)
}
defer f.Close()
gz, err := gzip.NewReader(f)
if err != nil {
t.Fatalf("decompress re2.txt.gz: %v", err)
var txt io.Reader
if strings.HasSuffix(file, ".bz2") {
z := bzip2.NewReader(f)
txt = z
file = file[:len(file)-len(".bz2")] // for error messages
} else {
txt = f
}
defer gz.Close()
lineno := 0
r := bufio.NewReader(gz)
r := bufio.NewReader(txt)
var (
str []string
input []string
......@@ -92,13 +105,13 @@ func TestRE2(t *testing.T) {
if err == os.EOF {
break
}
t.Fatalf("re2.txt:%d: %v", lineno, err)
t.Fatalf("%s:%d: %v", file, lineno, err)
}
line = line[:len(line)-1] // chop \n
lineno++
switch {
case line == "":
t.Fatalf("re2.txt:%d: unexpected blank line", lineno)
t.Fatalf("%s:%d: unexpected blank line", file, lineno)
case line[0] == '#':
continue
case 'A' <= line[0] && line[0] <= 'Z':
......@@ -114,7 +127,7 @@ func TestRE2(t *testing.T) {
q, err := strconv.Unquote(line)
if err != nil {
// Fatal because we'll get out of sync.
t.Fatalf("re2.txt:%d: unquote %s: %v", lineno, line, err)
t.Fatalf("%s:%d: unquote %s: %v", file, lineno, line, err)
}
if inStrings {
str = append(str, q)
......@@ -122,7 +135,7 @@ func TestRE2(t *testing.T) {
}
// Is a regexp.
if len(input) != 0 {
t.Fatalf("re2.txt:%d: out of sync: have %d strings left before %#q", lineno, len(input), q)
t.Fatalf("%s:%d: out of sync: have %d strings left before %#q", file, lineno, len(input), q)
}
re, err = tryCompile(q)
if err != nil {
......@@ -130,7 +143,7 @@ func TestRE2(t *testing.T) {
// We don't and likely never will support \C; keep going.
continue
}
t.Errorf("re2.txt:%d: compile %#q: %v", lineno, q, err)
t.Errorf("%s:%d: compile %#q: %v", file, lineno, q, err)
if nfail++; nfail >= 100 {
t.Fatalf("stopping after %d errors", nfail)
}
......@@ -140,7 +153,7 @@ func TestRE2(t *testing.T) {
refull, err = tryCompile(full)
if err != nil {
// Fatal because q worked, so this should always work.
t.Fatalf("re2.txt:%d: compile full %#q: %v", lineno, full, err)
t.Fatalf("%s:%d: compile full %#q: %v", file, lineno, full, err)
}
input = str
case line[0] == '-' || '0' <= line[0] && line[0] <= '9':
......@@ -151,7 +164,7 @@ func TestRE2(t *testing.T) {
continue
}
if len(input) == 0 {
t.Fatalf("re2.txt:%d: out of sync: no input remaining", lineno)
t.Fatalf("%s:%d: out of sync: no input remaining", file, lineno)
}
var text string
text, input = input[0], input[1:]
......@@ -165,13 +178,13 @@ func TestRE2(t *testing.T) {
}
res := strings.Split(line, ";")
if len(res) != len(run) {
t.Fatalf("re2.txt:%d: have %d test results, want %d", lineno, len(res), len(run))
t.Fatalf("%s:%d: have %d test results, want %d", file, lineno, len(res), len(run))
}
for i := range res {
have, suffix := run[i](re, refull, text)
want := parseResult(t, lineno, res[i])
want := parseResult(t, file, lineno, res[i])
if !same(have, want) {
t.Errorf("re2.txt:%d: %#q%s.FindSubmatchIndex(%#q) = %v, want %v", lineno, re, suffix, text, have, want)
t.Errorf("%s:%d: %#q%s.FindSubmatchIndex(%#q) = %v, want %v", file, lineno, re, suffix, text, have, want)
if nfail++; nfail >= 100 {
t.Fatalf("stopping after %d errors", nfail)
}
......@@ -179,7 +192,7 @@ func TestRE2(t *testing.T) {
}
b, suffix := match[i](re, refull, text)
if b != (want != nil) {
t.Errorf("re2.txt:%d: %#q%s.MatchString(%#q) = %v, want %v", lineno, re, suffix, text, b, !b)
t.Errorf("%s:%d: %#q%s.MatchString(%#q) = %v, want %v", file, lineno, re, suffix, text, b, !b)
if nfail++; nfail >= 100 {
t.Fatalf("stopping after %d errors", nfail)
}
......@@ -188,11 +201,11 @@ func TestRE2(t *testing.T) {
}
default:
t.Fatalf("re2.txt:%d: out of sync: %s\n", lineno, line)
t.Fatalf("%s:%d: out of sync: %s\n", file, lineno, line)
}
}
if len(input) != 0 {
t.Fatalf("re2.txt:%d: out of sync: have %d strings left at EOF", lineno, len(input))
t.Fatalf("%s:%d: out of sync: have %d strings left at EOF", file, lineno, len(input))
}
t.Logf("%d cases tested", ncase)
}
......@@ -270,7 +283,7 @@ func tryCompile(s string) (re *Regexp, err os.Error) {
return Compile(s)
}
func parseResult(t *testing.T, lineno int, res string) []int {
func parseResult(t *testing.T, file string, lineno int, res string) []int {
// A single - indicates no match.
if res == "-" {
return nil
......@@ -295,12 +308,12 @@ func parseResult(t *testing.T, lineno int, res string) []int {
} else {
k := strings.Index(pair, "-")
if k < 0 {
t.Fatalf("re2.txt:%d: invalid pair %s", lineno, pair)
t.Fatalf("%s:%d: invalid pair %s", file, lineno, pair)
}
lo, err1 := strconv.Atoi(pair[:k])
hi, err2 := strconv.Atoi(pair[k+1:])
if err1 != nil || err2 != nil || lo > hi {
t.Fatalf("re2.txt:%d: invalid pair %s", lineno, pair)
t.Fatalf("%s:%d: invalid pair %s", file, lineno, pair)
}
out[n] = lo
out[n+1] = hi
......@@ -323,3 +336,314 @@ func same(x, y []int) bool {
}
return true
}
// TestFowler runs this package's regexp API against the
// POSIX regular expression tests collected by Glenn Fowler
// at http://www2.research.att.com/~gsf/testregex/.
func TestFowler(t *testing.T) {
files, err := filepath.Glob("testdata/*.dat")
if err != nil {
t.Fatal(err)
}
for _, file := range files {
t.Log(file)
testFowler(t, file)
}
}
var notab = MustCompile(`[^\t]+`)
func testFowler(t *testing.T, file string) {
f, err := os.Open(file)
if err != nil {
t.Error(err)
return
}
defer f.Close()
b := bufio.NewReader(f)
lineno := 0
lastRegexp := ""
Reading:
for {
lineno++
line, err := b.ReadString('\n')
if err != nil {
if err != os.EOF {
t.Errorf("%s:%d: %v", file, lineno, err)
}
break Reading
}
// http://www2.research.att.com/~gsf/man/man1/testregex.html
//
// INPUT FORMAT
// Input lines may be blank, a comment beginning with #, or a test
// specification. A specification is five fields separated by one
// or more tabs. NULL denotes the empty string and NIL denotes the
// 0 pointer.
if line[0] == '#' || line[0] == '\n' {
continue Reading
}
line = line[:len(line)-1]
field := notab.FindAllString(line, -1)
for i, f := range field {
if f == "NULL" {
field[i] = ""
}
if f == "NIL" {
t.Logf("%s:%d: skip: %s", file, lineno, line)
continue Reading
}
}
if len(field) == 0 {
continue Reading
}
// Field 1: the regex(3) flags to apply, one character per REG_feature
// flag. The test is skipped if REG_feature is not supported by the
// implementation. If the first character is not [BEASKLP] then the
// specification is a global control line. One or more of [BEASKLP] may be
// specified; the test will be repeated for each mode.
//
// B basic BRE (grep, ed, sed)
// E REG_EXTENDED ERE (egrep)
// A REG_AUGMENTED ARE (egrep with negation)
// S REG_SHELL SRE (sh glob)
// K REG_SHELL|REG_AUGMENTED KRE (ksh glob)
// L REG_LITERAL LRE (fgrep)
//
// a REG_LEFT|REG_RIGHT implicit ^...$
// b REG_NOTBOL lhs does not match ^
// c REG_COMMENT ignore space and #...\n
// d REG_SHELL_DOT explicit leading . match
// e REG_NOTEOL rhs does not match $
// f REG_MULTIPLE multiple \n separated patterns
// g FNM_LEADING_DIR testfnmatch only -- match until /
// h REG_MULTIREF multiple digit backref
// i REG_ICASE ignore case
// j REG_SPAN . matches \n
// k REG_ESCAPE \ to ecape [...] delimiter
// l REG_LEFT implicit ^...
// m REG_MINIMAL minimal match
// n REG_NEWLINE explicit \n match
// o REG_ENCLOSED (|&) magic inside [@|&](...)
// p REG_SHELL_PATH explicit / match
// q REG_DELIMITED delimited pattern
// r REG_RIGHT implicit ...$
// s REG_SHELL_ESCAPED \ not special
// t REG_MUSTDELIM all delimiters must be specified
// u standard unspecified behavior -- errors not counted
// v REG_CLASS_ESCAPE \ special inside [...]
// w REG_NOSUB no subexpression match array
// x REG_LENIENT let some errors slide
// y REG_LEFT regexec() implicit ^...
// z REG_NULL NULL subexpressions ok
// $ expand C \c escapes in fields 2 and 3
// / field 2 is a regsubcomp() expression
// = field 3 is a regdecomp() expression
//
// Field 1 control lines:
//
// C set LC_COLLATE and LC_CTYPE to locale in field 2
//
// ?test ... output field 5 if passed and != EXPECTED, silent otherwise
// &test ... output field 5 if current and previous passed
// |test ... output field 5 if current passed and previous failed
// ; ... output field 2 if previous failed
// {test ... skip if failed until }
// } end of skip
//
// : comment comment copied as output NOTE
// :comment:test :comment: ignored
// N[OTE] comment comment copied as output NOTE
// T[EST] comment comment
//
// number use number for nmatch (20 by default)
flag := field[0]
switch flag[0] {
case '?', '&', '|', ';', '{', '}':
// Ignore all the control operators.
// Just run everything.
flag = flag[1:]
if flag == "" {
continue Reading
}
case ':':
i := strings.Index(flag[1:], ":")
if i < 0 {
t.Logf("skip: %s", line)
continue Reading
}
flag = flag[1+i+1:]
case 'C', 'N', 'T', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
t.Logf("skip: %s", line)
continue Reading
}
// Can check field count now that we've handled the myriad comment formats.
if len(field) < 4 {
t.Errorf("%s:%d: too few fields: %s", file, lineno, line)
continue Reading
}
// Expand C escapes (a.k.a. Go escapes).
if strings.Contains(flag, "$") {
f := `"` + field[1] + `"`
if field[1], err = strconv.Unquote(f); err != nil {
t.Errorf("%s:%d: cannot unquote %s", file, lineno, f)
}
f = `"` + field[2] + `"`
if field[2], err = strconv.Unquote(f); err != nil {
t.Errorf("%s:%d: cannot unquote %s", file, lineno, f)
}
}
// Field 2: the regular expression pattern; SAME uses the pattern from
// the previous specification.
//
if field[1] == "SAME" {
field[1] = lastRegexp
}
lastRegexp = field[1]
// Field 3: the string to match.
text := field[2]
// Field 4: the test outcome...
ok, shouldCompile, shouldMatch, pos := parseFowlerResult(field[3])
if !ok {
t.Errorf("%s:%d: cannot parse result %#q", file, lineno, field[3])
continue Reading
}
// Field 5: optional comment appended to the report.
Testing:
// Run test once for each specified capital letter mode that we support.
for _, c := range flag {
pattern := field[1]
syn := syntax.POSIX | syntax.ClassNL
switch c {
default:
continue Testing
case 'E':
// extended regexp (what we support)
case 'L':
// literal
pattern = QuoteMeta(pattern)
}
for _, c := range flag {
switch c {
case 'i':
syn |= syntax.FoldCase
}
}
re, err := compile(pattern, syn, true)
if err != nil {
if shouldCompile {
t.Errorf("%s:%d: %#q did not compile", file, lineno, pattern)
}
continue Testing
}
if !shouldCompile {
t.Errorf("%s:%d: %#q should not compile", file, lineno, pattern)
continue Testing
}
match := re.MatchString(text)
if match != shouldMatch {
t.Errorf("%s:%d: %#q.Match(%#q) = %v, want %v", file, lineno, pattern, text, match, shouldMatch)
continue Testing
}
have := re.FindStringSubmatchIndex(text)
if (len(have) > 0) != match {
t.Errorf("%s:%d: %#q.Match(%#q) = %v, but %#q.FindSubmatchIndex(%#q) = %v", file, lineno, pattern, text, match, text, have)
continue Testing
}
if len(have) > len(pos) {
have = have[:len(pos)]
}
if !same(have, pos) {
t.Errorf("%s:%d: %#q.FindSubmatchIndex(%#q) = %v, want %v", file, lineno, pattern, text, have, pos)
}
}
}
}
func parseFowlerResult(s string) (ok, compiled, matched bool, pos []int) {
// Field 4: the test outcome. This is either one of the posix error
// codes (with REG_ omitted) or the match array, a list of (m,n)
// entries with m and n being first and last+1 positions in the
// field 3 string, or NULL if REG_NOSUB is in effect and success
// is expected. BADPAT is acceptable in place of any regcomp(3)
// error code. The match[] array is initialized to (-2,-2) before
// each test. All array elements from 0 to nmatch-1 must be specified
// in the outcome. Unspecified endpoints (offset -1) are denoted by ?.
// Unset endpoints (offset -2) are denoted by X. {x}(o:n) denotes a
// matched (?{...}) expression, where x is the text enclosed by {...},
// o is the expression ordinal counting from 1, and n is the length of
// the unmatched portion of the subject string. If x starts with a
// number then that is the return value of re_execf(), otherwise 0 is
// returned.
switch {
case s == "":
// Match with no position information.
ok = true
compiled = true
matched = true
return
case s == "NOMATCH":
// Match failure.
ok = true
compiled = true
matched = false
return
case 'A' <= s[0] && s[0] <= 'Z':
// All the other error codes are compile errors.
ok = true
compiled = false
return
}
compiled = true
var x []int
for s != "" {
var end byte = ')'
if len(x)%2 == 0 {
if s[0] != '(' {
ok = false
return
}
s = s[1:]
end = ','
}
i := 0
for i < len(s) && s[i] != end {
i++
}
if i == 0 || i == len(s) {
ok = false
return
}
var v = -1
var err os.Error
if s[:i] != "?" {
v, err = strconv.Atoi(s[:i])
if err != nil {
ok = false
return
}
}
x = append(x, v)
s = s[i+1:]
}
if len(x)%2 != 0 {
ok = false
return
}
ok = true
matched = true
pos = x
return
}
......@@ -98,6 +98,15 @@ var findTests = []FindTest{
{`\B`, "x y", nil},
{`\B`, "xx yy", build(2, 1, 1, 4, 4)},
// RE2 tests
{`[^\S\s]`, "abcd", nil},
{`[^\S[:space:]]`, "abcd", nil},
{`[^\D\d]`, "abcd", nil},
{`[^\D[:digit:]]`, "abcd", nil},
{`(?i)\W`, "x", nil},
{`(?i)\W`, "k", nil},
{`(?i)\W`, "s", nil},
// can backslash-escape any punctuation
{`\!\"\#\$\%\&\'\(\)\*\+\,\-\.\/\:\;\<\=\>\?\@\[\\\]\^\_\{\|\}\~`,
`!"#$%&'()*+,-./:;<=>?@[\]^_{|}~`, build(1, 0, 31)},
......
......@@ -97,10 +97,45 @@ func (re *Regexp) String() string {
return re.expr
}
// Compile parses a regular expression and returns, if successful, a Regexp
// object that can be used to match against text.
// Compile parses a regular expression and returns, if successful,
// a Regexp object that can be used to match against text.
//
// When matching against text, the regexp returns a match that
// begins as early as possible in the input (leftmost), and among those
// it chooses the one that a backtracking search would have found first.
// This so-called leftmost-first matching is the same semantics
// that Perl, Python, and other implementations use, although this
// package implements it without the expense of backtracking.
// For POSIX leftmost-longest matching, see CompilePOSIX.
func Compile(expr string) (*Regexp, os.Error) {
re, err := syntax.Parse(expr, syntax.Perl)
return compile(expr, syntax.Perl, false)
}
// CompilePOSIX is like Compile but restricts the regular expression
// to POSIX ERE (egrep) syntax and changes the match semantics to
// leftmost-longest.
//
// That is, when matching against text, the regexp returns a match that
// begins as early as possible in the input (leftmost), and among those
// it chooses a match that is as long as possible.
// This so-called leftmost-longest matching is the same semantics
// that early regular expression implementations used and that POSIX
// specifies.
//
// However, there can be multiple leftmost-longest matches, with different
// submatch choices, and here this package diverges from POSIX.
// Among the possible leftmost-longest matches, this package chooses
// the one that a backtracking search would have found first, while POSIX
// specifies that the match be chosen to maximize the length of the first
// subexpression, then the second, and so on from left to right.
// The POSIX rule is computationally prohibitive and not even well-defined.
// See http://swtch.com/~rsc/regexp/regexp2.html#posix for details.
func CompilePOSIX(expr string) (*Regexp, os.Error) {
return compile(expr, syntax.POSIX, true)
}
func compile(expr string, mode syntax.Flags, longest bool) (*Regexp, os.Error) {
re, err := syntax.Parse(expr, mode)
if err != nil {
return nil, err
}
......@@ -114,6 +149,8 @@ func Compile(expr string) (*Regexp, os.Error) {
expr: expr,
prog: prog,
numSubexp: maxCap,
cond: prog.StartCond(),
longest: longest,
}
regexp.prefix, regexp.prefixComplete = prog.Prefix()
if regexp.prefix != "" {
......@@ -122,7 +159,6 @@ func Compile(expr string) (*Regexp, os.Error) {
regexp.prefixBytes = []byte(regexp.prefix)
regexp.prefixRune, _ = utf8.DecodeRuneInString(regexp.prefix)
}
regexp.cond = prog.StartCond()
return regexp, nil
}
......
AT&T POSIX Test Files
See textregex.c for copyright + license.
testregex.c http://www2.research.att.com/~gsf/testregex/testregex.c
basic.dat http://www2.research.att.com/~gsf/testregex/basic.dat
nullsubexpr.dat http://www2.research.att.com/~gsf/testregex/nullsubexpr.dat
repetition.dat http://www2.research.att.com/~gsf/testregex/repetition.dat
The test data has been edited to reflect RE2/Go differences:
* In a star of a possibly empty match like (a*)* matching x,
the no match case runs the starred subexpression zero times,
not once. This is consistent with (a*)* matching a, which
runs the starred subexpression one time, not twice.
* The submatch choice is first match, not the POSIX rule.
Such changes are marked with 'RE2/Go'.
RE2 Test Files
re2-exhaustive.txt.bz2 and re2-search.txt are built by running
'make log' in the RE2 distribution. http://code.google.com/p/re2/.
The exhaustive file is compressed because it is huge.
NOTE all standard compliant implementations should pass these : 2002-05-31
BE abracadabra$ abracadabracadabra (7,18)
BE a...b abababbb (2,7)
BE XXXXXX ..XXXXXX (2,8)
E \) () (1,2)
BE a] a]a (0,2)
B } } (0,1)
E \} } (0,1)
BE \] ] (0,1)
B ] ] (0,1)
E ] ] (0,1)
B { { (0,1)
B } } (0,1)
BE ^a ax (0,1)
BE \^a a^a (1,3)
BE a\^ a^ (0,2)
BE a$ aa (1,2)
BE a\$ a$ (0,2)
BE ^$ NULL (0,0)
E $^ NULL (0,0)
E a($) aa (1,2)(2,2)
E a*(^a) aa (0,1)(0,1)
E (..)*(...)* a (0,0)
E (..)*(...)* abcd (0,4)(2,4)
E (ab|a)(bc|c) abc (0,3)(0,2)(2,3)
E (ab)c|abc abc (0,3)(0,2)
E a{0}b ab (1,2)
E (a*)(b?)(b+)b{3} aaabbbbbbb (0,10)(0,3)(3,4)(4,7)
E (a*)(b{0,1})(b{1,})b{3} aaabbbbbbb (0,10)(0,3)(3,4)(4,7)
E a{9876543210} NULL BADBR
E ((a|a)|a) a (0,1)(0,1)(0,1)
E (a*)(a|aa) aaaa (0,4)(0,3)(3,4)
E a*(a.|aa) aaaa (0,4)(2,4)
E a(b)|c(d)|a(e)f aef (0,3)(?,?)(?,?)(1,2)
E (a|b)?.* b (0,1)(0,1)
E (a|b)c|a(b|c) ac (0,2)(0,1)
E (a|b)c|a(b|c) ab (0,2)(?,?)(1,2)
E (a|b)*c|(a|ab)*c abc (0,3)(1,2)
E (a|b)*c|(a|ab)*c xc (1,2)
E (.a|.b).*|.*(.a|.b) xa (0,2)(0,2)
E a?(ab|ba)ab abab (0,4)(0,2)
E a?(ac{0}b|ba)ab abab (0,4)(0,2)
E ab|abab abbabab (0,2)
E aba|bab|bba baaabbbaba (5,8)
E aba|bab baaabbbaba (6,9)
E (aa|aaa)*|(a|aaaaa) aa (0,2)(0,2)
E (a.|.a.)*|(a|.a...) aa (0,2)(0,2)
E ab|a xabc (1,3)
E ab|a xxabc (2,4)
Ei (Ab|cD)* aBcD (0,4)(2,4)
BE [^-] --a (2,3)
BE [a-]* --a (0,3)
BE [a-m-]* --amoma-- (0,4)
E :::1:::0:|:::1:1:0: :::0:::1:::1:::0: (8,17)
E :::1:::0:|:::1:1:1: :::0:::1:::1:::0: (8,17)
{E [[:upper:]] A (0,1) [[<element>]] not supported
E [[:lower:]]+ `az{ (1,3)
E [[:upper:]]+ @AZ[ (1,3)
# No collation in Go
#BE [[-]] [[-]] (2,4)
#BE [[.NIL.]] NULL ECOLLATE
#BE [[=aleph=]] NULL ECOLLATE
}
BE$ \n \n (0,1)
BEn$ \n \n (0,1)
BE$ [^a] \n (0,1)
BE$ \na \na (0,2)
E (a)(b)(c) abc (0,3)(0,1)(1,2)(2,3)
BE xxx xxx (0,3)
E1 (^|[ (,;])((([Ff]eb[^ ]* *|0*2/|\* */?)0*[6-7]))([^0-9]|$) feb 6, (0,6)
E1 (^|[ (,;])((([Ff]eb[^ ]* *|0*2/|\* */?)0*[6-7]))([^0-9]|$) 2/7 (0,3)
E1 (^|[ (,;])((([Ff]eb[^ ]* *|0*2/|\* */?)0*[6-7]))([^0-9]|$) feb 1,Feb 6 (5,11)
E3 ((((((((((((((((((((((((((((((x)))))))))))))))))))))))))))))) x (0,1)(0,1)(0,1)
E3 ((((((((((((((((((((((((((((((x))))))))))))))))))))))))))))))* xx (0,2)(1,2)(1,2)
E a?(ab|ba)* ababababababababababababababababababababababababababababababababababababababababa (0,81)(79,81)
E abaa|abbaa|abbbaa|abbbbaa ababbabbbabbbabbbbabbbbaa (18,25)
E abaa|abbaa|abbbaa|abbbbaa ababbabbbabbbabbbbabaa (18,22)
E aaac|aabc|abac|abbc|baac|babc|bbac|bbbc baaabbbabac (7,11)
BE$ .* \x01\xff (0,2)
E aaaa|bbbb|cccc|ddddd|eeeeee|fffffff|gggg|hhhh|iiiii|jjjjj|kkkkk|llll XaaaXbbbXcccXdddXeeeXfffXgggXhhhXiiiXjjjXkkkXlllXcbaXaaaa (53,57)
L aaaa\nbbbb\ncccc\nddddd\neeeeee\nfffffff\ngggg\nhhhh\niiiii\njjjjj\nkkkkk\nllll XaaaXbbbXcccXdddXeeeXfffXgggXhhhXiiiXjjjXkkkXlllXcbaXaaaa NOMATCH
E a*a*a*a*a*b aaaaaaaaab (0,10)
BE ^ NULL (0,0)
BE $ NULL (0,0)
BE ^$ NULL (0,0)
BE ^a$ a (0,1)
BE abc abc (0,3)
BE abc xabcy (1,4)
BE abc ababc (2,5)
BE ab*c abc (0,3)
BE ab*bc abc (0,3)
BE ab*bc abbc (0,4)
BE ab*bc abbbbc (0,6)
E ab+bc abbc (0,4)
E ab+bc abbbbc (0,6)
E ab?bc abbc (0,4)
E ab?bc abc (0,3)
E ab?c abc (0,3)
BE ^abc$ abc (0,3)
BE ^abc abcc (0,3)
BE abc$ aabc (1,4)
BE ^ abc (0,0)
BE $ abc (3,3)
BE a.c abc (0,3)
BE a.c axc (0,3)
BE a.*c axyzc (0,5)
BE a[bc]d abd (0,3)
BE a[b-d]e ace (0,3)
BE a[b-d] aac (1,3)
BE a[-b] a- (0,2)
BE a[b-] a- (0,2)
BE a] a] (0,2)
BE a[]]b a]b (0,3)
BE a[^bc]d aed (0,3)
BE a[^-b]c adc (0,3)
BE a[^]b]c adc (0,3)
E ab|cd abc (0,2)
E ab|cd abcd (0,2)
E a\(b a(b (0,3)
E a\(*b ab (0,2)
E a\(*b a((b (0,4)
E ((a)) abc (0,1)(0,1)(0,1)
E (a)b(c) abc (0,3)(0,1)(2,3)
E a+b+c aabbabc (4,7)
E a* aaa (0,3)
#E (a*)* - (0,0)(0,0)
E (a*)* - (0,0)(?,?) RE2/Go
E (a*)+ - (0,0)(0,0)
#E (a*|b)* - (0,0)(0,0)
E (a*|b)* - (0,0)(?,?) RE2/Go
E (a+|b)* ab (0,2)(1,2)
E (a+|b)+ ab (0,2)(1,2)
E (a+|b)? ab (0,1)(0,1)
BE [^ab]* cde (0,3)
#E (^)* - (0,0)(0,0)
E (^)* - (0,0)(?,?) RE2/Go
BE a* NULL (0,0)
E ([abc])*d abbbcd (0,6)(4,5)
E ([abc])*bcd abcd (0,4)(0,1)
E a|b|c|d|e e (0,1)
E (a|b|c|d|e)f ef (0,2)(0,1)
#E ((a*|b))* - (0,0)(0,0)(0,0)
E ((a*|b))* - (0,0)(?,?)(?,?) RE2/Go
BE abcd*efg abcdefg (0,7)
BE ab* xabyabbbz (1,3)
BE ab* xayabbbz (1,2)
E (ab|cd)e abcde (2,5)(2,4)
BE [abhgefdc]ij hij (0,3)
E (a|b)c*d abcd (1,4)(1,2)
E (ab|ab*)bc abc (0,3)(0,1)
E a([bc]*)c* abc (0,3)(1,3)
E a([bc]*)(c*d) abcd (0,4)(1,3)(3,4)
E a([bc]+)(c*d) abcd (0,4)(1,3)(3,4)
E a([bc]*)(c+d) abcd (0,4)(1,2)(2,4)
E a[bcd]*dcdcde adcdcde (0,7)
E (ab|a)b*c abc (0,3)(0,2)
E ((a)(b)c)(d) abcd (0,4)(0,3)(0,1)(1,2)(3,4)
BE [A-Za-z_][A-Za-z0-9_]* alpha (0,5)
E ^a(bc+|b[eh])g|.h$ abh (1,3)
E (bc+d$|ef*g.|h?i(j|k)) effgz (0,5)(0,5)
E (bc+d$|ef*g.|h?i(j|k)) ij (0,2)(0,2)(1,2)
E (bc+d$|ef*g.|h?i(j|k)) reffgz (1,6)(1,6)
E (((((((((a))))))))) a (0,1)(0,1)(0,1)(0,1)(0,1)(0,1)(0,1)(0,1)(0,1)(0,1)
BE multiple words multiple words yeah (0,14)
E (.*)c(.*) abcde (0,5)(0,2)(3,5)
BE abcd abcd (0,4)
E a(bc)d abcd (0,4)(1,3)
E a[-]?c ac (0,3)
E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Muammar Qaddafi (0,15)(?,?)(10,12)
E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Mo'ammar Gadhafi (0,16)(?,?)(11,13)
E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Muammar Kaddafi (0,15)(?,?)(10,12)
E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Muammar Qadhafi (0,15)(?,?)(10,12)
E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Muammar Gadafi (0,14)(?,?)(10,11)
E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Mu'ammar Qadafi (0,15)(?,?)(11,12)
E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Moamar Gaddafi (0,14)(?,?)(9,11)
E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Mu'ammar Qadhdhafi (0,18)(?,?)(13,15)
E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Muammar Khaddafi (0,16)(?,?)(11,13)
E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Muammar Ghaddafy (0,16)(?,?)(11,13)
E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Muammar Ghadafi (0,15)(?,?)(11,12)
E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Muammar Ghaddafi (0,16)(?,?)(11,13)
E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Muamar Kaddafi (0,14)(?,?)(9,11)
E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Muammar Quathafi (0,16)(?,?)(11,13)
E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Muammar Gheddafi (0,16)(?,?)(11,13)
E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Moammar Khadafy (0,15)(?,?)(11,12)
E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Moammar Qudhafi (0,15)(?,?)(10,12)
E a+(b|c)*d+ aabcdd (0,6)(3,4)
E ^.+$ vivi (0,4)
E ^(.+)$ vivi (0,4)(0,4)
E ^([^!.]+).att.com!(.+)$ gryphon.att.com!eby (0,19)(0,7)(16,19)
E ^([^!]+!)?([^!]+)$ bas (0,3)(?,?)(0,3)
E ^([^!]+!)?([^!]+)$ bar!bas (0,7)(0,4)(4,7)
E ^([^!]+!)?([^!]+)$ foo!bas (0,7)(0,4)(4,7)
E ^.+!([^!]+!)([^!]+)$ foo!bar!bas (0,11)(4,8)(8,11)
E ((foo)|(bar))!bas bar!bas (0,7)(0,3)(?,?)(0,3)
E ((foo)|(bar))!bas foo!bar!bas (4,11)(4,7)(?,?)(4,7)
E ((foo)|(bar))!bas foo!bas (0,7)(0,3)(0,3)
E ((foo)|bar)!bas bar!bas (0,7)(0,3)
E ((foo)|bar)!bas foo!bar!bas (4,11)(4,7)
E ((foo)|bar)!bas foo!bas (0,7)(0,3)(0,3)
E (foo|(bar))!bas bar!bas (0,7)(0,3)(0,3)
E (foo|(bar))!bas foo!bar!bas (4,11)(4,7)(4,7)
E (foo|(bar))!bas foo!bas (0,7)(0,3)
E (foo|bar)!bas bar!bas (0,7)(0,3)
E (foo|bar)!bas foo!bar!bas (4,11)(4,7)
E (foo|bar)!bas foo!bas (0,7)(0,3)
E ^(([^!]+!)?([^!]+)|.+!([^!]+!)([^!]+))$ foo!bar!bas (0,11)(0,11)(?,?)(?,?)(4,8)(8,11)
E ^([^!]+!)?([^!]+)$|^.+!([^!]+!)([^!]+)$ bas (0,3)(?,?)(0,3)
E ^([^!]+!)?([^!]+)$|^.+!([^!]+!)([^!]+)$ bar!bas (0,7)(0,4)(4,7)
E ^([^!]+!)?([^!]+)$|^.+!([^!]+!)([^!]+)$ foo!bar!bas (0,11)(?,?)(?,?)(4,8)(8,11)
E ^([^!]+!)?([^!]+)$|^.+!([^!]+!)([^!]+)$ foo!bas (0,7)(0,4)(4,7)
E ^(([^!]+!)?([^!]+)|.+!([^!]+!)([^!]+))$ bas (0,3)(0,3)(?,?)(0,3)
E ^(([^!]+!)?([^!]+)|.+!([^!]+!)([^!]+))$ bar!bas (0,7)(0,7)(0,4)(4,7)
E ^(([^!]+!)?([^!]+)|.+!([^!]+!)([^!]+))$ foo!bar!bas (0,11)(0,11)(?,?)(?,?)(4,8)(8,11)
E ^(([^!]+!)?([^!]+)|.+!([^!]+!)([^!]+))$ foo!bas (0,7)(0,7)(0,4)(4,7)
E .*(/XXX).* /XXX (0,4)(0,4)
E .*(\\XXX).* \XXX (0,4)(0,4)
E \\XXX \XXX (0,4)
E .*(/000).* /000 (0,4)(0,4)
E .*(\\000).* \000 (0,4)(0,4)
E \\000 \000 (0,4)
NOTE null subexpression matches : 2002-06-06
E (a*)* a (0,1)(0,1)
#E SAME x (0,0)(0,0)
E SAME x (0,0)(?,?) RE2/Go
E SAME aaaaaa (0,6)(0,6)
E SAME aaaaaax (0,6)(0,6)
E (a*)+ a (0,1)(0,1)
E SAME x (0,0)(0,0)
E SAME aaaaaa (0,6)(0,6)
E SAME aaaaaax (0,6)(0,6)
E (a+)* a (0,1)(0,1)
E SAME x (0,0)
E SAME aaaaaa (0,6)(0,6)
E SAME aaaaaax (0,6)(0,6)
E (a+)+ a (0,1)(0,1)
E SAME x NOMATCH
E SAME aaaaaa (0,6)(0,6)
E SAME aaaaaax (0,6)(0,6)
E ([a]*)* a (0,1)(0,1)
#E SAME x (0,0)(0,0)
E SAME x (0,0)(?,?) RE2/Go
E SAME aaaaaa (0,6)(0,6)
E SAME aaaaaax (0,6)(0,6)
E ([a]*)+ a (0,1)(0,1)
E SAME x (0,0)(0,0)
E SAME aaaaaa (0,6)(0,6)
E SAME aaaaaax (0,6)(0,6)
E ([^b]*)* a (0,1)(0,1)
#E SAME b (0,0)(0,0)
E SAME b (0,0)(?,?) RE2/Go
E SAME aaaaaa (0,6)(0,6)
E SAME aaaaaab (0,6)(0,6)
E ([ab]*)* a (0,1)(0,1)
E SAME aaaaaa (0,6)(0,6)
E SAME ababab (0,6)(0,6)
E SAME bababa (0,6)(0,6)
E SAME b (0,1)(0,1)
E SAME bbbbbb (0,6)(0,6)
E SAME aaaabcde (0,5)(0,5)
E ([^a]*)* b (0,1)(0,1)
E SAME bbbbbb (0,6)(0,6)
#E SAME aaaaaa (0,0)(0,0)
E SAME aaaaaa (0,0)(?,?) RE2/Go
E ([^ab]*)* ccccxx (0,6)(0,6)
#E SAME ababab (0,0)(0,0)
E SAME ababab (0,0)(?,?) RE2/Go
E ((z)+|a)* zabcde (0,2)(1,2)
#{E a+? aaaaaa (0,1) no *? +? mimimal match ops
#E (a) aaa (0,1)(0,1)
#E (a*?) aaa (0,0)(0,0)
#E (a)*? aaa (0,0)
#E (a*?)*? aaa (0,0)
#}
B \(a*\)*\(x\) x (0,1)(0,0)(0,1)
B \(a*\)*\(x\) ax (0,2)(0,1)(1,2)
B \(a*\)*\(x\) axa (0,2)(0,1)(1,2)
B \(a*\)*\(x\)\(\1\) x (0,1)(0,0)(0,1)(1,1)
B \(a*\)*\(x\)\(\1\) ax (0,2)(1,1)(1,2)(2,2)
B \(a*\)*\(x\)\(\1\) axa (0,3)(0,1)(1,2)(2,3)
B \(a*\)*\(x\)\(\1\)\(x\) axax (0,4)(0,1)(1,2)(2,3)(3,4)
B \(a*\)*\(x\)\(\1\)\(x\) axxa (0,3)(1,1)(1,2)(2,2)(2,3)
#E (a*)*(x) x (0,1)(0,0)(0,1)
E (a*)*(x) x (0,1)(?,?)(0,1) RE2/Go
E (a*)*(x) ax (0,2)(0,1)(1,2)
E (a*)*(x) axa (0,2)(0,1)(1,2)
E (a*)+(x) x (0,1)(0,0)(0,1)
E (a*)+(x) ax (0,2)(0,1)(1,2)
E (a*)+(x) axa (0,2)(0,1)(1,2)
E (a*){2}(x) x (0,1)(0,0)(0,1)
E (a*){2}(x) ax (0,2)(1,1)(1,2)
E (a*){2}(x) axa (0,2)(1,1)(1,2)
# RE2 basic search tests built by make log
# Thu Sep 8 13:43:43 EDT 2011
Regexp.SearchTests
strings
""
"a"
regexps
"a"
-;-;-;-
0-1;0-1;0-1;0-1
"^(?:a)$"
-;-;-;-
0-1;0-1;0-1;0-1
"^(?:a)"
-;-;-;-
0-1;0-1;0-1;0-1
"(?:a)$"
-;-;-;-
0-1;0-1;0-1;0-1
strings
""
"zyzzyva"
regexps
"a"
-;-;-;-
-;6-7;-;6-7
"^(?:a)$"
-;-;-;-
-;-;-;-
"^(?:a)"
-;-;-;-
-;-;-;-
"(?:a)$"
-;-;-;-
-;6-7;-;6-7
strings
""
"aa"
regexps
"a+"
-;-;-;-
0-2;0-2;0-2;0-2
"^(?:a+)$"
-;-;-;-
0-2;0-2;0-2;0-2
"^(?:a+)"
-;-;-;-
0-2;0-2;0-2;0-2
"(?:a+)$"
-;-;-;-
0-2;0-2;0-2;0-2
strings
""
"ab"
regexps
"(a+|b)+"
-;-;-;-
0-2 1-2;0-2 1-2;0-2 1-2;0-2 1-2
"^(?:(a+|b)+)$"
-;-;-;-
0-2 1-2;0-2 1-2;0-2 1-2;0-2 1-2
"^(?:(a+|b)+)"
-;-;-;-
0-2 1-2;0-2 1-2;0-2 1-2;0-2 1-2
"(?:(a+|b)+)$"
-;-;-;-
0-2 1-2;0-2 1-2;0-2 1-2;0-2 1-2
strings
""
"xabcdx"
regexps
"ab|cd"
-;-;-;-
-;1-3;-;1-3
"^(?:ab|cd)$"
-;-;-;-
-;-;-;-
"^(?:ab|cd)"
-;-;-;-
-;-;-;-
"(?:ab|cd)$"
-;-;-;-
-;-;-;-
strings
""
"hello\ngoodbye\n"
regexps
"h.*od?"
-;-;-;-
-;0-5;-;0-5
"^(?:h.*od?)$"
-;-;-;-
-;-;-;-
"^(?:h.*od?)"
-;-;-;-
-;0-5;-;0-5
"(?:h.*od?)$"
-;-;-;-
-;-;-;-
strings
""
"hello\ngoodbye\n"
regexps
"h.*o"
-;-;-;-
-;0-5;-;0-5
"^(?:h.*o)$"
-;-;-;-
-;-;-;-
"^(?:h.*o)"
-;-;-;-
-;0-5;-;0-5
"(?:h.*o)$"
-;-;-;-
-;-;-;-
strings
""
"goodbye\nhello\n"
regexps
"h.*o"
-;-;-;-
-;8-13;-;8-13
"^(?:h.*o)$"
-;-;-;-
-;-;-;-
"^(?:h.*o)"
-;-;-;-
-;-;-;-
"(?:h.*o)$"
-;-;-;-
-;-;-;-
strings
""
"hello world"
regexps
"h.*o"
-;-;-;-
-;0-8;-;0-8
"^(?:h.*o)$"
-;-;-;-
-;-;-;-
"^(?:h.*o)"
-;-;-;-
-;0-8;-;0-8
"(?:h.*o)$"
-;-;-;-
-;-;-;-
strings
""
"othello, world"
regexps
"h.*o"
-;-;-;-
-;2-11;-;2-11
"^(?:h.*o)$"
-;-;-;-
-;-;-;-
"^(?:h.*o)"
-;-;-;-
-;-;-;-
"(?:h.*o)$"
-;-;-;-
-;-;-;-
strings
""
"aaaaaaa"
regexps
"[^\\s\\S]"
-;-;-;-
-;-;-;-
"^(?:[^\\s\\S])$"
-;-;-;-
-;-;-;-
"^(?:[^\\s\\S])"
-;-;-;-
-;-;-;-
"(?:[^\\s\\S])$"
-;-;-;-
-;-;-;-
strings
""
"aaaaaaa"
regexps
"a"
-;-;-;-
-;0-1;-;0-1
"^(?:a)$"
-;-;-;-
-;-;-;-
"^(?:a)"
-;-;-;-
-;0-1;-;0-1
"(?:a)$"
-;-;-;-
-;6-7;-;6-7
strings
""
"aaaaaaa"
regexps
"a*"
0-0;0-0;0-0;0-0
0-7;0-7;0-7;0-7
"^(?:a*)$"
0-0;0-0;0-0;0-0
0-7;0-7;0-7;0-7
"^(?:a*)"
0-0;0-0;0-0;0-0
0-7;0-7;0-7;0-7
"(?:a*)$"
0-0;0-0;0-0;0-0
0-7;0-7;0-7;0-7
strings
""
""
regexps
"a*"
0-0;0-0;0-0;0-0
0-0;0-0;0-0;0-0
"^(?:a*)$"
0-0;0-0;0-0;0-0
0-0;0-0;0-0;0-0
"^(?:a*)"
0-0;0-0;0-0;0-0
0-0;0-0;0-0;0-0
"(?:a*)$"
0-0;0-0;0-0;0-0
0-0;0-0;0-0;0-0
strings
""
""
regexps
"a*"
0-0;0-0;0-0;0-0
0-0;0-0;0-0;0-0
"^(?:a*)$"
0-0;0-0;0-0;0-0
0-0;0-0;0-0;0-0
"^(?:a*)"
0-0;0-0;0-0;0-0
0-0;0-0;0-0;0-0
"(?:a*)$"
0-0;0-0;0-0;0-0
0-0;0-0;0-0;0-0
strings
""
"xabcdx"
regexps
"ab|cd"
-;-;-;-
-;1-3;-;1-3
"^(?:ab|cd)$"
-;-;-;-
-;-;-;-
"^(?:ab|cd)"
-;-;-;-
-;-;-;-
"(?:ab|cd)$"
-;-;-;-
-;-;-;-
strings
""
"cab"
regexps
"a"
-;-;-;-
-;1-2;-;1-2
"^(?:a)$"
-;-;-;-
-;-;-;-
"^(?:a)"
-;-;-;-
-;-;-;-
"(?:a)$"
-;-;-;-
-;-;-;-
strings
""
"cab"
regexps
"a*b"
-;-;-;-
-;1-3;-;1-3
"^(?:a*b)$"
-;-;-;-
-;-;-;-
"^(?:a*b)"
-;-;-;-
-;-;-;-
"(?:a*b)$"
-;-;-;-
-;1-3;-;1-3
strings
""
"x"
regexps
"((((((((((((((((((((x))))))))))))))))))))"
-;-;-;-
0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1;0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1;0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1;0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1
"^(?:((((((((((((((((((((x)))))))))))))))))))))$"
-;-;-;-
0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1;0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1;0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1;0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1
"^(?:((((((((((((((((((((x)))))))))))))))))))))"
-;-;-;-
0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1;0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1;0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1;0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1
"(?:((((((((((((((((((((x)))))))))))))))))))))$"
-;-;-;-
0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1;0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1;0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1;0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1
strings
""
"xxxabcdxxx"
regexps
"[abcd]"
-;-;-;-
-;3-4;-;3-4
"^(?:[abcd])$"
-;-;-;-
-;-;-;-
"^(?:[abcd])"
-;-;-;-
-;-;-;-
"(?:[abcd])$"
-;-;-;-
-;-;-;-
strings
""
"xxxabcdxxx"
regexps
"[^x]"
-;-;-;-
-;3-4;-;3-4
"^(?:[^x])$"
-;-;-;-
-;-;-;-
"^(?:[^x])"
-;-;-;-
-;-;-;-
"(?:[^x])$"
-;-;-;-
-;-;-;-
strings
""
"xxxabcdxxx"
regexps
"[abcd]+"
-;-;-;-
-;3-7;-;3-7
"^(?:[abcd]+)$"
-;-;-;-
-;-;-;-
"^(?:[abcd]+)"
-;-;-;-
-;-;-;-
"(?:[abcd]+)$"
-;-;-;-
-;-;-;-
strings
""
"xxxabcdxxx"
regexps
"[^x]+"
-;-;-;-
-;3-7;-;3-7
"^(?:[^x]+)$"
-;-;-;-
-;-;-;-
"^(?:[^x]+)"
-;-;-;-
-;-;-;-
"(?:[^x]+)$"
-;-;-;-
-;-;-;-
strings
""
"fo"
regexps
"(fo|foo)"
-;-;-;-
0-2 0-2;0-2 0-2;0-2 0-2;0-2 0-2
"^(?:(fo|foo))$"
-;-;-;-
0-2 0-2;0-2 0-2;0-2 0-2;0-2 0-2
"^(?:(fo|foo))"
-;-;-;-
0-2 0-2;0-2 0-2;0-2 0-2;0-2 0-2
"(?:(fo|foo))$"
-;-;-;-
0-2 0-2;0-2 0-2;0-2 0-2;0-2 0-2
strings
""
"foo"
regexps
"(foo|fo)"
-;-;-;-
0-3 0-3;0-3 0-3;0-3 0-3;0-3 0-3
"^(?:(foo|fo))$"
-;-;-;-
0-3 0-3;0-3 0-3;0-3 0-3;0-3 0-3
"^(?:(foo|fo))"
-;-;-;-
0-3 0-3;0-3 0-3;0-3 0-3;0-3 0-3
"(?:(foo|fo))$"
-;-;-;-
0-3 0-3;0-3 0-3;0-3 0-3;0-3 0-3
strings
""
"aA"
regexps
"aa"
-;-;-;-
-;-;-;-
"^(?:aa)$"
-;-;-;-
-;-;-;-
"^(?:aa)"
-;-;-;-
-;-;-;-
"(?:aa)$"
-;-;-;-
-;-;-;-
strings
""
"Aa"
regexps
"a"
-;-;-;-
-;1-2;-;1-2
"^(?:a)$"
-;-;-;-
-;-;-;-
"^(?:a)"
-;-;-;-
-;-;-;-
"(?:a)$"
-;-;-;-
-;1-2;-;1-2
strings
""
"A"
regexps
"a"
-;-;-;-
-;-;-;-
"^(?:a)$"
-;-;-;-
-;-;-;-
"^(?:a)"
-;-;-;-
-;-;-;-
"(?:a)$"
-;-;-;-
-;-;-;-
strings
""
"abc"
regexps
"ABC"
-;-;-;-
-;-;-;-
"^(?:ABC)$"
-;-;-;-
-;-;-;-
"^(?:ABC)"
-;-;-;-
-;-;-;-
"(?:ABC)$"
-;-;-;-
-;-;-;-
strings
""
"XABCY"
regexps
"abc"
-;-;-;-
-;-;-;-
"^(?:abc)$"
-;-;-;-
-;-;-;-
"^(?:abc)"
-;-;-;-
-;-;-;-
"(?:abc)$"
-;-;-;-
-;-;-;-
strings
""
"xabcy"
regexps
"ABC"
-;-;-;-
-;-;-;-
"^(?:ABC)$"
-;-;-;-
-;-;-;-
"^(?:ABC)"
-;-;-;-
-;-;-;-
"(?:ABC)$"
-;-;-;-
-;-;-;-
strings
""
"foo"
regexps
"foo|bar|[A-Z]"
-;-;-;-
0-3;0-3;0-3;0-3
"^(?:foo|bar|[A-Z])$"
-;-;-;-
0-3;0-3;0-3;0-3
"^(?:foo|bar|[A-Z])"
-;-;-;-
0-3;0-3;0-3;0-3
"(?:foo|bar|[A-Z])$"
-;-;-;-
0-3;0-3;0-3;0-3
strings
""
"foo"
regexps
"^(foo|bar|[A-Z])"
-;-;-;-
0-3 0-3;0-3 0-3;0-3 0-3;0-3 0-3
"^(?:^(foo|bar|[A-Z]))$"
-;-;-;-
0-3 0-3;0-3 0-3;0-3 0-3;0-3 0-3
"^(?:^(foo|bar|[A-Z]))"
-;-;-;-
0-3 0-3;0-3 0-3;0-3 0-3;0-3 0-3
"(?:^(foo|bar|[A-Z]))$"
-;-;-;-
0-3 0-3;0-3 0-3;0-3 0-3;0-3 0-3
strings
""
"foo\n"
regexps
"(foo|bar|[A-Z])$"
-;-;-;-
-;-;-;-
"^(?:(foo|bar|[A-Z])$)$"
-;-;-;-
-;-;-;-
"^(?:(foo|bar|[A-Z])$)"
-;-;-;-
-;-;-;-
"(?:(foo|bar|[A-Z])$)$"
-;-;-;-
-;-;-;-
strings
""
"foo"
regexps
"(foo|bar|[A-Z])$"
-;-;-;-
0-3 0-3;0-3 0-3;0-3 0-3;0-3 0-3
"^(?:(foo|bar|[A-Z])$)$"
-;-;-;-
0-3 0-3;0-3 0-3;0-3 0-3;0-3 0-3
"^(?:(foo|bar|[A-Z])$)"
-;-;-;-
0-3 0-3;0-3 0-3;0-3 0-3;0-3 0-3
"(?:(foo|bar|[A-Z])$)$"
-;-;-;-
0-3 0-3;0-3 0-3;0-3 0-3;0-3 0-3
strings
""
"foo\n"
regexps
"^(foo|bar|[A-Z])$"
-;-;-;-
-;-;-;-
"^(?:^(foo|bar|[A-Z])$)$"
-;-;-;-
-;-;-;-
"^(?:^(foo|bar|[A-Z])$)"
-;-;-;-
-;-;-;-
"(?:^(foo|bar|[A-Z])$)$"
-;-;-;-
-;-;-;-
strings
""
"foo"
regexps
"^(foo|bar|[A-Z])$"
-;-;-;-
0-3 0-3;0-3 0-3;0-3 0-3;0-3 0-3
"^(?:^(foo|bar|[A-Z])$)$"
-;-;-;-
0-3 0-3;0-3 0-3;0-3 0-3;0-3 0-3
"^(?:^(foo|bar|[A-Z])$)"
-;-;-;-
0-3 0-3;0-3 0-3;0-3 0-3;0-3 0-3
"(?:^(foo|bar|[A-Z])$)$"
-;-;-;-
0-3 0-3;0-3 0-3;0-3 0-3;0-3 0-3
strings
""
"bar"
regexps
"^(foo|bar|[A-Z])$"
-;-;-;-
0-3 0-3;0-3 0-3;0-3 0-3;0-3 0-3
"^(?:^(foo|bar|[A-Z])$)$"
-;-;-;-
0-3 0-3;0-3 0-3;0-3 0-3;0-3 0-3
"^(?:^(foo|bar|[A-Z])$)"
-;-;-;-
0-3 0-3;0-3 0-3;0-3 0-3;0-3 0-3
"(?:^(foo|bar|[A-Z])$)$"
-;-;-;-
0-3 0-3;0-3 0-3;0-3 0-3;0-3 0-3
strings
""
"X"
regexps
"^(foo|bar|[A-Z])$"
-;-;-;-
0-1 0-1;0-1 0-1;0-1 0-1;0-1 0-1
"^(?:^(foo|bar|[A-Z])$)$"
-;-;-;-
0-1 0-1;0-1 0-1;0-1 0-1;0-1 0-1
"^(?:^(foo|bar|[A-Z])$)"
-;-;-;-
0-1 0-1;0-1 0-1;0-1 0-1;0-1 0-1
"(?:^(foo|bar|[A-Z])$)$"
-;-;-;-
0-1 0-1;0-1 0-1;0-1 0-1;0-1 0-1
strings
""
"XY"
regexps
"^(foo|bar|[A-Z])$"
-;-;-;-
-;-;-;-
"^(?:^(foo|bar|[A-Z])$)$"
-;-;-;-
-;-;-;-
"^(?:^(foo|bar|[A-Z])$)"
-;-;-;-
-;-;-;-
"(?:^(foo|bar|[A-Z])$)$"
-;-;-;-
-;-;-;-
strings
""
"fo"
regexps
"^(fo|foo)$"
-;-;-;-
0-2 0-2;0-2 0-2;0-2 0-2;0-2 0-2
"^(?:^(fo|foo)$)$"
-;-;-;-
0-2 0-2;0-2 0-2;0-2 0-2;0-2 0-2
"^(?:^(fo|foo)$)"
-;-;-;-
0-2 0-2;0-2 0-2;0-2 0-2;0-2 0-2
"(?:^(fo|foo)$)$"
-;-;-;-
0-2 0-2;0-2 0-2;0-2 0-2;0-2 0-2
strings
""
"foo"
regexps
"^(fo|foo)$"
-;-;-;-
0-3 0-3;0-3 0-3;0-3 0-3;0-3 0-3
"^(?:^(fo|foo)$)$"
-;-;-;-
0-3 0-3;0-3 0-3;0-3 0-3;0-3 0-3
"^(?:^(fo|foo)$)"
-;-;-;-
0-3 0-3;0-3 0-3;0-3 0-3;0-3 0-3
"(?:^(fo|foo)$)$"
-;-;-;-
0-3 0-3;0-3 0-3;0-3 0-3;0-3 0-3
strings
""
"fo"
regexps
"^^(fo|foo)$"
-;-;-;-
0-2 0-2;0-2 0-2;0-2 0-2;0-2 0-2
"^(?:^^(fo|foo)$)$"
-;-;-;-
0-2 0-2;0-2 0-2;0-2 0-2;0-2 0-2
"^(?:^^(fo|foo)$)"
-;-;-;-
0-2 0-2;0-2 0-2;0-2 0-2;0-2 0-2
"(?:^^(fo|foo)$)$"
-;-;-;-
0-2 0-2;0-2 0-2;0-2 0-2;0-2 0-2
strings
""
"foo"
regexps
"^^(fo|foo)$"
-;-;-;-
0-3 0-3;0-3 0-3;0-3 0-3;0-3 0-3
"^(?:^^(fo|foo)$)$"
-;-;-;-
0-3 0-3;0-3 0-3;0-3 0-3;0-3 0-3
"^(?:^^(fo|foo)$)"
-;-;-;-
0-3 0-3;0-3 0-3;0-3 0-3;0-3 0-3
"(?:^^(fo|foo)$)$"
-;-;-;-
0-3 0-3;0-3 0-3;0-3 0-3;0-3 0-3
strings
""
""
regexps
"^$"
0-0;0-0;0-0;0-0
0-0;0-0;0-0;0-0
"^(?:^$)$"
0-0;0-0;0-0;0-0
0-0;0-0;0-0;0-0
"^(?:^$)"
0-0;0-0;0-0;0-0
0-0;0-0;0-0;0-0
"(?:^$)$"
0-0;0-0;0-0;0-0
0-0;0-0;0-0;0-0
strings
""
"x"
regexps
"^$"
0-0;0-0;0-0;0-0
-;-;-;-
"^(?:^$)$"
0-0;0-0;0-0;0-0
-;-;-;-
"^(?:^$)"
0-0;0-0;0-0;0-0
-;-;-;-
"(?:^$)$"
0-0;0-0;0-0;0-0
-;-;-;-
strings
""
""
regexps
"^^$"
0-0;0-0;0-0;0-0
0-0;0-0;0-0;0-0
"^(?:^^$)$"
0-0;0-0;0-0;0-0
0-0;0-0;0-0;0-0
"^(?:^^$)"
0-0;0-0;0-0;0-0
0-0;0-0;0-0;0-0
"(?:^^$)$"
0-0;0-0;0-0;0-0
0-0;0-0;0-0;0-0
strings
""
""
regexps
"^$$"
0-0;0-0;0-0;0-0
0-0;0-0;0-0;0-0
"^(?:^$$)$"
0-0;0-0;0-0;0-0
0-0;0-0;0-0;0-0
"^(?:^$$)"
0-0;0-0;0-0;0-0
0-0;0-0;0-0;0-0
"(?:^$$)$"
0-0;0-0;0-0;0-0
0-0;0-0;0-0;0-0
strings
""
"x"
regexps
"^^$"
0-0;0-0;0-0;0-0
-;-;-;-
"^(?:^^$)$"
0-0;0-0;0-0;0-0
-;-;-;-
"^(?:^^$)"
0-0;0-0;0-0;0-0
-;-;-;-
"(?:^^$)$"
0-0;0-0;0-0;0-0
-;-;-;-
strings
""
"x"
regexps
"^$$"
0-0;0-0;0-0;0-0
-;-;-;-
"^(?:^$$)$"
0-0;0-0;0-0;0-0
-;-;-;-
"^(?:^$$)"
0-0;0-0;0-0;0-0
-;-;-;-
"(?:^$$)$"
0-0;0-0;0-0;0-0
-;-;-;-
strings
""
""
regexps
"^^$$"
0-0;0-0;0-0;0-0
0-0;0-0;0-0;0-0
"^(?:^^$$)$"
0-0;0-0;0-0;0-0
0-0;0-0;0-0;0-0
"^(?:^^$$)"
0-0;0-0;0-0;0-0
0-0;0-0;0-0;0-0
"(?:^^$$)$"
0-0;0-0;0-0;0-0
0-0;0-0;0-0;0-0
strings
""
"x"
regexps
"^^$$"
0-0;0-0;0-0;0-0
-;-;-;-
"^(?:^^$$)$"
0-0;0-0;0-0;0-0
-;-;-;-
"^(?:^^$$)"
0-0;0-0;0-0;0-0
-;-;-;-
"(?:^^$$)$"
0-0;0-0;0-0;0-0
-;-;-;-
strings
""
""
regexps
"^^^^^^^^$$$$$$$$"
0-0;0-0;0-0;0-0
0-0;0-0;0-0;0-0
"^(?:^^^^^^^^$$$$$$$$)$"
0-0;0-0;0-0;0-0
0-0;0-0;0-0;0-0
"^(?:^^^^^^^^$$$$$$$$)"
0-0;0-0;0-0;0-0
0-0;0-0;0-0;0-0
"(?:^^^^^^^^$$$$$$$$)$"
0-0;0-0;0-0;0-0
0-0;0-0;0-0;0-0
strings
""
"x"
regexps
"^"
0-0;0-0;0-0;0-0
-;0-0;-;0-0
"^(?:^)$"
0-0;0-0;0-0;0-0
-;-;-;-
"^(?:^)"
0-0;0-0;0-0;0-0
-;0-0;-;0-0
"(?:^)$"
0-0;0-0;0-0;0-0
-;-;-;-
strings
""
"x"
regexps
"$"
0-0;0-0;0-0;0-0
-;1-1;-;1-1
"^(?:$)$"
0-0;0-0;0-0;0-0
-;-;-;-
"^(?:$)"
0-0;0-0;0-0;0-0
-;-;-;-
"(?:$)$"
0-0;0-0;0-0;0-0
-;1-1;-;1-1
strings
""
"nofoo foo that"
regexps
"\\bfoo\\b"
-;-;-;-
-;6-9;-;6-9
"^(?:\\bfoo\\b)$"
-;-;-;-
-;-;-;-
"^(?:\\bfoo\\b)"
-;-;-;-
-;-;-;-
"(?:\\bfoo\\b)$"
-;-;-;-
-;-;-;-
strings
""
"faoa x"
regexps
"a\\b"
-;-;-;-
-;3-4;-;3-4
"^(?:a\\b)$"
-;-;-;-
-;-;-;-
"^(?:a\\b)"
-;-;-;-
-;-;-;-
"(?:a\\b)$"
-;-;-;-
-;-;-;-
strings
""
"bar x"
regexps
"\\bbar"
-;-;-;-
-;0-3;-;0-3
"^(?:\\bbar)$"
-;-;-;-
-;-;-;-
"^(?:\\bbar)"
-;-;-;-
-;0-3;-;0-3
"(?:\\bbar)$"
-;-;-;-
-;-;-;-
strings
""
"foo\nbar x"
regexps
"\\bbar"
-;-;-;-
-;4-7;-;4-7
"^(?:\\bbar)$"
-;-;-;-
-;-;-;-
"^(?:\\bbar)"
-;-;-;-
-;-;-;-
"(?:\\bbar)$"
-;-;-;-
-;-;-;-
strings
""
"foobar"
regexps
"bar\\b"
-;-;-;-
-;3-6;-;3-6
"^(?:bar\\b)$"
-;-;-;-
-;-;-;-
"^(?:bar\\b)"
-;-;-;-
-;-;-;-
"(?:bar\\b)$"
-;-;-;-
-;3-6;-;3-6
strings
""
"foobar\nxxx"
regexps
"bar\\b"
-;-;-;-
-;3-6;-;3-6
"^(?:bar\\b)$"
-;-;-;-
-;-;-;-
"^(?:bar\\b)"
-;-;-;-
-;-;-;-
"(?:bar\\b)$"
-;-;-;-
-;-;-;-
strings
""
"foo"
regexps
"(foo|bar|[A-Z])\\b"
-;-;-;-
0-3 0-3;0-3 0-3;0-3 0-3;0-3 0-3
"^(?:(foo|bar|[A-Z])\\b)$"
-;-;-;-
0-3 0-3;0-3 0-3;0-3 0-3;0-3 0-3
"^(?:(foo|bar|[A-Z])\\b)"
-;-;-;-
0-3 0-3;0-3 0-3;0-3 0-3;0-3 0-3
"(?:(foo|bar|[A-Z])\\b)$"
-;-;-;-
0-3 0-3;0-3 0-3;0-3 0-3;0-3 0-3
strings
""
"foo\n"
regexps
"(foo|bar|[A-Z])\\b"
-;-;-;-
-;0-3 0-3;-;0-3 0-3
"^(?:(foo|bar|[A-Z])\\b)$"
-;-;-;-
-;-;-;-
"^(?:(foo|bar|[A-Z])\\b)"
-;-;-;-
-;0-3 0-3;-;0-3 0-3
"(?:(foo|bar|[A-Z])\\b)$"
-;-;-;-
-;-;-;-
strings
""
""
regexps
"\\b"
-;-;-;-
-;-;-;-
"^(?:\\b)$"
-;-;-;-
-;-;-;-
"^(?:\\b)"
-;-;-;-
-;-;-;-
"(?:\\b)$"
-;-;-;-
-;-;-;-
strings
""
"x"
regexps
"\\b"
-;-;-;-
-;0-0;-;0-0
"^(?:\\b)$"
-;-;-;-
-;-;-;-
"^(?:\\b)"
-;-;-;-
-;0-0;-;0-0
"(?:\\b)$"
-;-;-;-
-;1-1;-;1-1
strings
""
"foo"
regexps
"\\b(foo|bar|[A-Z])"
-;-;-;-
0-3 0-3;0-3 0-3;0-3 0-3;0-3 0-3
"^(?:\\b(foo|bar|[A-Z]))$"
-;-;-;-
0-3 0-3;0-3 0-3;0-3 0-3;0-3 0-3
"^(?:\\b(foo|bar|[A-Z]))"
-;-;-;-
0-3 0-3;0-3 0-3;0-3 0-3;0-3 0-3
"(?:\\b(foo|bar|[A-Z]))$"
-;-;-;-
0-3 0-3;0-3 0-3;0-3 0-3;0-3 0-3
strings
""
"X"
regexps
"\\b(foo|bar|[A-Z])\\b"
-;-;-;-
0-1 0-1;0-1 0-1;0-1 0-1;0-1 0-1
"^(?:\\b(foo|bar|[A-Z])\\b)$"
-;-;-;-
0-1 0-1;0-1 0-1;0-1 0-1;0-1 0-1
"^(?:\\b(foo|bar|[A-Z])\\b)"
-;-;-;-
0-1 0-1;0-1 0-1;0-1 0-1;0-1 0-1
"(?:\\b(foo|bar|[A-Z])\\b)$"
-;-;-;-
0-1 0-1;0-1 0-1;0-1 0-1;0-1 0-1
strings
""
"XY"
regexps
"\\b(foo|bar|[A-Z])\\b"
-;-;-;-
-;-;-;-
"^(?:\\b(foo|bar|[A-Z])\\b)$"
-;-;-;-
-;-;-;-
"^(?:\\b(foo|bar|[A-Z])\\b)"
-;-;-;-
-;-;-;-
"(?:\\b(foo|bar|[A-Z])\\b)$"
-;-;-;-
-;-;-;-
strings
""
"bar"
regexps
"\\b(foo|bar|[A-Z])\\b"
-;-;-;-
0-3 0-3;0-3 0-3;0-3 0-3;0-3 0-3
"^(?:\\b(foo|bar|[A-Z])\\b)$"
-;-;-;-
0-3 0-3;0-3 0-3;0-3 0-3;0-3 0-3
"^(?:\\b(foo|bar|[A-Z])\\b)"
-;-;-;-
0-3 0-3;0-3 0-3;0-3 0-3;0-3 0-3
"(?:\\b(foo|bar|[A-Z])\\b)$"
-;-;-;-
0-3 0-3;0-3 0-3;0-3 0-3;0-3 0-3
strings
""
"foo"
regexps
"\\b(foo|bar|[A-Z])\\b"
-;-;-;-
0-3 0-3;0-3 0-3;0-3 0-3;0-3 0-3
"^(?:\\b(foo|bar|[A-Z])\\b)$"
-;-;-;-
0-3 0-3;0-3 0-3;0-3 0-3;0-3 0-3
"^(?:\\b(foo|bar|[A-Z])\\b)"
-;-;-;-
0-3 0-3;0-3 0-3;0-3 0-3;0-3 0-3
"(?:\\b(foo|bar|[A-Z])\\b)$"
-;-;-;-
0-3 0-3;0-3 0-3;0-3 0-3;0-3 0-3
strings
""
"foo\n"
regexps
"\\b(foo|bar|[A-Z])\\b"
-;-;-;-
-;0-3 0-3;-;0-3 0-3
"^(?:\\b(foo|bar|[A-Z])\\b)$"
-;-;-;-
-;-;-;-
"^(?:\\b(foo|bar|[A-Z])\\b)"
-;-;-;-
-;0-3 0-3;-;0-3 0-3
"(?:\\b(foo|bar|[A-Z])\\b)$"
-;-;-;-
-;-;-;-
strings
""
"ffoo bbar N x"
regexps
"\\b(foo|bar|[A-Z])\\b"
-;-;-;-
-;10-11 10-11;-;10-11 10-11
"^(?:\\b(foo|bar|[A-Z])\\b)$"
-;-;-;-
-;-;-;-
"^(?:\\b(foo|bar|[A-Z])\\b)"
-;-;-;-
-;-;-;-
"(?:\\b(foo|bar|[A-Z])\\b)$"
-;-;-;-
-;-;-;-
strings
""
"fo"
regexps
"\\b(fo|foo)\\b"
-;-;-;-
0-2 0-2;0-2 0-2;0-2 0-2;0-2 0-2
"^(?:\\b(fo|foo)\\b)$"
-;-;-;-
0-2 0-2;0-2 0-2;0-2 0-2;0-2 0-2
"^(?:\\b(fo|foo)\\b)"
-;-;-;-
0-2 0-2;0-2 0-2;0-2 0-2;0-2 0-2
"(?:\\b(fo|foo)\\b)$"
-;-;-;-
0-2 0-2;0-2 0-2;0-2 0-2;0-2 0-2
strings
""
"foo"
regexps
"\\b(fo|foo)\\b"
-;-;-;-
0-3 0-3;0-3 0-3;0-3 0-3;0-3 0-3
"^(?:\\b(fo|foo)\\b)$"
-;-;-;-
0-3 0-3;0-3 0-3;0-3 0-3;0-3 0-3
"^(?:\\b(fo|foo)\\b)"
-;-;-;-
0-3 0-3;0-3 0-3;0-3 0-3;0-3 0-3
"(?:\\b(fo|foo)\\b)$"
-;-;-;-
0-3 0-3;0-3 0-3;0-3 0-3;0-3 0-3
strings
""
""
regexps
"\\b\\b"
-;-;-;-
-;-;-;-
"^(?:\\b\\b)$"
-;-;-;-
-;-;-;-
"^(?:\\b\\b)"
-;-;-;-
-;-;-;-
"(?:\\b\\b)$"
-;-;-;-
-;-;-;-
strings
""
"x"
regexps
"\\b\\b"
-;-;-;-
-;0-0;-;0-0
"^(?:\\b\\b)$"
-;-;-;-
-;-;-;-
"^(?:\\b\\b)"
-;-;-;-
-;0-0;-;0-0
"(?:\\b\\b)$"
-;-;-;-
-;1-1;-;1-1
strings
""
""
regexps
"\\b$"
-;-;-;-
-;-;-;-
"^(?:\\b$)$"
-;-;-;-
-;-;-;-
"^(?:\\b$)"
-;-;-;-
-;-;-;-
"(?:\\b$)$"
-;-;-;-
-;-;-;-
strings
""
"x"
regexps
"\\b$"
-;-;-;-
-;1-1;-;1-1
"^(?:\\b$)$"
-;-;-;-
-;-;-;-
"^(?:\\b$)"
-;-;-;-
-;-;-;-
"(?:\\b$)$"
-;-;-;-
-;1-1;-;1-1
strings
""
"y x"
regexps
"\\b$"
-;-;-;-
-;3-3;-;3-3
"^(?:\\b$)$"
-;-;-;-
-;-;-;-
"^(?:\\b$)"
-;-;-;-
-;-;-;-
"(?:\\b$)$"
-;-;-;-
-;3-3;-;3-3
strings
""
"x"
regexps
"\\b.$"
-;-;-;-
0-1;0-1;0-1;0-1
"^(?:\\b.$)$"
-;-;-;-
0-1;0-1;0-1;0-1
"^(?:\\b.$)"
-;-;-;-
0-1;0-1;0-1;0-1
"(?:\\b.$)$"
-;-;-;-
0-1;0-1;0-1;0-1
strings
""
"fo"
regexps
"^\\b(fo|foo)\\b"
-;-;-;-
0-2 0-2;0-2 0-2;0-2 0-2;0-2 0-2
"^(?:^\\b(fo|foo)\\b)$"
-;-;-;-
0-2 0-2;0-2 0-2;0-2 0-2;0-2 0-2
"^(?:^\\b(fo|foo)\\b)"
-;-;-;-
0-2 0-2;0-2 0-2;0-2 0-2;0-2 0-2
"(?:^\\b(fo|foo)\\b)$"
-;-;-;-
0-2 0-2;0-2 0-2;0-2 0-2;0-2 0-2
strings
""
"foo"
regexps
"^\\b(fo|foo)\\b"
-;-;-;-
0-3 0-3;0-3 0-3;0-3 0-3;0-3 0-3
"^(?:^\\b(fo|foo)\\b)$"
-;-;-;-
0-3 0-3;0-3 0-3;0-3 0-3;0-3 0-3
"^(?:^\\b(fo|foo)\\b)"
-;-;-;-
0-3 0-3;0-3 0-3;0-3 0-3;0-3 0-3
"(?:^\\b(fo|foo)\\b)$"
-;-;-;-
0-3 0-3;0-3 0-3;0-3 0-3;0-3 0-3
strings
""
""
regexps
"^\\b"
-;-;-;-
-;-;-;-
"^(?:^\\b)$"
-;-;-;-
-;-;-;-
"^(?:^\\b)"
-;-;-;-
-;-;-;-
"(?:^\\b)$"
-;-;-;-
-;-;-;-
strings
""
"x"
regexps
"^\\b"
-;-;-;-
-;0-0;-;0-0
"^(?:^\\b)$"
-;-;-;-
-;-;-;-
"^(?:^\\b)"
-;-;-;-
-;0-0;-;0-0
"(?:^\\b)$"
-;-;-;-
-;-;-;-
strings
""
""
regexps
"^\\b\\b"
-;-;-;-
-;-;-;-
"^(?:^\\b\\b)$"
-;-;-;-
-;-;-;-
"^(?:^\\b\\b)"
-;-;-;-
-;-;-;-
"(?:^\\b\\b)$"
-;-;-;-
-;-;-;-
strings
""
"x"
regexps
"^\\b\\b"
-;-;-;-
-;0-0;-;0-0
"^(?:^\\b\\b)$"
-;-;-;-
-;-;-;-
"^(?:^\\b\\b)"
-;-;-;-
-;0-0;-;0-0
"(?:^\\b\\b)$"
-;-;-;-
-;-;-;-
strings
""
""
regexps
"^\\b$"
-;-;-;-
-;-;-;-
"^(?:^\\b$)$"
-;-;-;-
-;-;-;-
"^(?:^\\b$)"
-;-;-;-
-;-;-;-
"(?:^\\b$)$"
-;-;-;-
-;-;-;-
strings
""
"x"
regexps
"^\\b$"
-;-;-;-
-;-;-;-
"^(?:^\\b$)$"
-;-;-;-
-;-;-;-
"^(?:^\\b$)"
-;-;-;-
-;-;-;-
"(?:^\\b$)$"
-;-;-;-
-;-;-;-
strings
""
"x"
regexps
"^\\b.$"
-;-;-;-
0-1;0-1;0-1;0-1
"^(?:^\\b.$)$"
-;-;-;-
0-1;0-1;0-1;0-1
"^(?:^\\b.$)"
-;-;-;-
0-1;0-1;0-1;0-1
"(?:^\\b.$)$"
-;-;-;-
0-1;0-1;0-1;0-1
strings
""
"x"
regexps
"^\\b.\\b$"
-;-;-;-
0-1;0-1;0-1;0-1
"^(?:^\\b.\\b$)$"
-;-;-;-
0-1;0-1;0-1;0-1
"^(?:^\\b.\\b$)"
-;-;-;-
0-1;0-1;0-1;0-1
"(?:^\\b.\\b$)$"
-;-;-;-
0-1;0-1;0-1;0-1
strings
""
""
regexps
"^^^^^^^^\\b$$$$$$$"
-;-;-;-
-;-;-;-
"^(?:^^^^^^^^\\b$$$$$$$)$"
-;-;-;-
-;-;-;-
"^(?:^^^^^^^^\\b$$$$$$$)"
-;-;-;-
-;-;-;-
"(?:^^^^^^^^\\b$$$$$$$)$"
-;-;-;-
-;-;-;-
strings
""
"x"
regexps
"^^^^^^^^\\b.$$$$$$"
-;-;-;-
0-1;0-1;0-1;0-1
"^(?:^^^^^^^^\\b.$$$$$$)$"
-;-;-;-
0-1;0-1;0-1;0-1
"^(?:^^^^^^^^\\b.$$$$$$)"
-;-;-;-
0-1;0-1;0-1;0-1
"(?:^^^^^^^^\\b.$$$$$$)$"
-;-;-;-
0-1;0-1;0-1;0-1
strings
""
"x"
regexps
"^^^^^^^^\\b$$$$$$$"
-;-;-;-
-;-;-;-
"^(?:^^^^^^^^\\b$$$$$$$)$"
-;-;-;-
-;-;-;-
"^(?:^^^^^^^^\\b$$$$$$$)"
-;-;-;-
-;-;-;-
"(?:^^^^^^^^\\b$$$$$$$)$"
-;-;-;-
-;-;-;-
strings
""
"n foo xfoox that"
regexps
"\\Bfoo\\B"
-;-;-;-
-;7-10;-;7-10
"^(?:\\Bfoo\\B)$"
-;-;-;-
-;-;-;-
"^(?:\\Bfoo\\B)"
-;-;-;-
-;-;-;-
"(?:\\Bfoo\\B)$"
-;-;-;-
-;-;-;-
strings
""
"faoa x"
regexps
"a\\B"
-;-;-;-
-;1-2;-;1-2
"^(?:a\\B)$"
-;-;-;-
-;-;-;-
"^(?:a\\B)"
-;-;-;-
-;-;-;-
"(?:a\\B)$"
-;-;-;-
-;-;-;-
strings
""
"bar x"
regexps
"\\Bbar"
-;-;-;-
-;-;-;-
"^(?:\\Bbar)$"
-;-;-;-
-;-;-;-
"^(?:\\Bbar)"
-;-;-;-
-;-;-;-
"(?:\\Bbar)$"
-;-;-;-
-;-;-;-
strings
""
"foo\nbar x"
regexps
"\\Bbar"
-;-;-;-
-;-;-;-
"^(?:\\Bbar)$"
-;-;-;-
-;-;-;-
"^(?:\\Bbar)"
-;-;-;-
-;-;-;-
"(?:\\Bbar)$"
-;-;-;-
-;-;-;-
strings
""
"foobar"
regexps
"bar\\B"
-;-;-;-
-;-;-;-
"^(?:bar\\B)$"
-;-;-;-
-;-;-;-
"^(?:bar\\B)"
-;-;-;-
-;-;-;-
"(?:bar\\B)$"
-;-;-;-
-;-;-;-
strings
""
"foobar\nxxx"
regexps
"bar\\B"
-;-;-;-
-;-;-;-
"^(?:bar\\B)$"
-;-;-;-
-;-;-;-
"^(?:bar\\B)"
-;-;-;-
-;-;-;-
"(?:bar\\B)$"
-;-;-;-
-;-;-;-
strings
""
"foox"
regexps
"(foo|bar|[A-Z])\\B"
-;-;-;-
-;0-3 0-3;-;0-3 0-3
"^(?:(foo|bar|[A-Z])\\B)$"
-;-;-;-
-;-;-;-
"^(?:(foo|bar|[A-Z])\\B)"
-;-;-;-
-;0-3 0-3;-;0-3 0-3
"(?:(foo|bar|[A-Z])\\B)$"
-;-;-;-
-;-;-;-
strings
""
"foo\n"
regexps
"(foo|bar|[A-Z])\\B"
-;-;-;-
-;-;-;-
"^(?:(foo|bar|[A-Z])\\B)$"
-;-;-;-
-;-;-;-
"^(?:(foo|bar|[A-Z])\\B)"
-;-;-;-
-;-;-;-
"(?:(foo|bar|[A-Z])\\B)$"
-;-;-;-
-;-;-;-
strings
""
""
regexps
"\\B"
0-0;0-0;0-0;0-0
0-0;0-0;0-0;0-0
"^(?:\\B)$"
0-0;0-0;0-0;0-0
0-0;0-0;0-0;0-0
"^(?:\\B)"
0-0;0-0;0-0;0-0
0-0;0-0;0-0;0-0
"(?:\\B)$"
0-0;0-0;0-0;0-0
0-0;0-0;0-0;0-0
strings
""
"x"
regexps
"\\B"
0-0;0-0;0-0;0-0
-;-;-;-
"^(?:\\B)$"
0-0;0-0;0-0;0-0
-;-;-;-
"^(?:\\B)"
0-0;0-0;0-0;0-0
-;-;-;-
"(?:\\B)$"
0-0;0-0;0-0;0-0
-;-;-;-
strings
""
"foo"
regexps
"\\B(foo|bar|[A-Z])"
-;-;-;-
-;-;-;-
"^(?:\\B(foo|bar|[A-Z]))$"
-;-;-;-
-;-;-;-
"^(?:\\B(foo|bar|[A-Z]))"
-;-;-;-
-;-;-;-
"(?:\\B(foo|bar|[A-Z]))$"
-;-;-;-
-;-;-;-
strings
""
"xXy"
regexps
"\\B(foo|bar|[A-Z])\\B"
-;-;-;-
-;1-2 1-2;-;1-2 1-2
"^(?:\\B(foo|bar|[A-Z])\\B)$"
-;-;-;-
-;-;-;-
"^(?:\\B(foo|bar|[A-Z])\\B)"
-;-;-;-
-;-;-;-
"(?:\\B(foo|bar|[A-Z])\\B)$"
-;-;-;-
-;-;-;-
strings
""
"XY"
regexps
"\\B(foo|bar|[A-Z])\\B"
-;-;-;-
-;-;-;-
"^(?:\\B(foo|bar|[A-Z])\\B)$"
-;-;-;-
-;-;-;-
"^(?:\\B(foo|bar|[A-Z])\\B)"
-;-;-;-
-;-;-;-
"(?:\\B(foo|bar|[A-Z])\\B)$"
-;-;-;-
-;-;-;-
strings
""
"XYZ"
regexps
"\\B(foo|bar|[A-Z])\\B"
-;-;-;-
-;1-2 1-2;-;1-2 1-2
"^(?:\\B(foo|bar|[A-Z])\\B)$"
-;-;-;-
-;-;-;-
"^(?:\\B(foo|bar|[A-Z])\\B)"
-;-;-;-
-;-;-;-
"(?:\\B(foo|bar|[A-Z])\\B)$"
-;-;-;-
-;-;-;-
strings
""
"abara"
regexps
"\\B(foo|bar|[A-Z])\\B"
-;-;-;-
-;1-4 1-4;-;1-4 1-4
"^(?:\\B(foo|bar|[A-Z])\\B)$"
-;-;-;-
-;-;-;-
"^(?:\\B(foo|bar|[A-Z])\\B)"
-;-;-;-
-;-;-;-
"(?:\\B(foo|bar|[A-Z])\\B)$"
-;-;-;-
-;-;-;-
strings
""
"xfoo_"
regexps
"\\B(foo|bar|[A-Z])\\B"
-;-;-;-
-;1-4 1-4;-;1-4 1-4
"^(?:\\B(foo|bar|[A-Z])\\B)$"
-;-;-;-
-;-;-;-
"^(?:\\B(foo|bar|[A-Z])\\B)"
-;-;-;-
-;-;-;-
"(?:\\B(foo|bar|[A-Z])\\B)$"
-;-;-;-
-;-;-;-
strings
""
"xfoo\n"
regexps
"\\B(foo|bar|[A-Z])\\B"
-;-;-;-
-;-;-;-
"^(?:\\B(foo|bar|[A-Z])\\B)$"
-;-;-;-
-;-;-;-
"^(?:\\B(foo|bar|[A-Z])\\B)"
-;-;-;-
-;-;-;-
"(?:\\B(foo|bar|[A-Z])\\B)$"
-;-;-;-
-;-;-;-
strings
""
"foo bar vNx"
regexps
"\\B(foo|bar|[A-Z])\\B"
-;-;-;-
-;9-10 9-10;-;9-10 9-10
"^(?:\\B(foo|bar|[A-Z])\\B)$"
-;-;-;-
-;-;-;-
"^(?:\\B(foo|bar|[A-Z])\\B)"
-;-;-;-
-;-;-;-
"(?:\\B(foo|bar|[A-Z])\\B)$"
-;-;-;-
-;-;-;-
strings
""
"xfoo"
regexps
"\\B(fo|foo)\\B"
-;-;-;-
-;1-3 1-3;-;1-3 1-3
"^(?:\\B(fo|foo)\\B)$"
-;-;-;-
-;-;-;-
"^(?:\\B(fo|foo)\\B)"
-;-;-;-
-;-;-;-
"(?:\\B(fo|foo)\\B)$"
-;-;-;-
-;-;-;-
strings
""
"xfooo"
regexps
"\\B(foo|fo)\\B"
-;-;-;-
-;1-4 1-4;-;1-4 1-4
"^(?:\\B(foo|fo)\\B)$"
-;-;-;-
-;-;-;-
"^(?:\\B(foo|fo)\\B)"
-;-;-;-
-;-;-;-
"(?:\\B(foo|fo)\\B)$"
-;-;-;-
-;-;-;-
strings
""
""
regexps
"\\B\\B"
0-0;0-0;0-0;0-0
0-0;0-0;0-0;0-0
"^(?:\\B\\B)$"
0-0;0-0;0-0;0-0
0-0;0-0;0-0;0-0
"^(?:\\B\\B)"
0-0;0-0;0-0;0-0
0-0;0-0;0-0;0-0
"(?:\\B\\B)$"
0-0;0-0;0-0;0-0
0-0;0-0;0-0;0-0
strings
""
"x"
regexps
"\\B\\B"
0-0;0-0;0-0;0-0
-;-;-;-
"^(?:\\B\\B)$"
0-0;0-0;0-0;0-0
-;-;-;-
"^(?:\\B\\B)"
0-0;0-0;0-0;0-0
-;-;-;-
"(?:\\B\\B)$"
0-0;0-0;0-0;0-0
-;-;-;-
strings
""
""
regexps
"\\B$"
0-0;0-0;0-0;0-0
0-0;0-0;0-0;0-0
"^(?:\\B$)$"
0-0;0-0;0-0;0-0
0-0;0-0;0-0;0-0
"^(?:\\B$)"
0-0;0-0;0-0;0-0
0-0;0-0;0-0;0-0
"(?:\\B$)$"
0-0;0-0;0-0;0-0
0-0;0-0;0-0;0-0
strings
""
"x"
regexps
"\\B$"
0-0;0-0;0-0;0-0
-;-;-;-
"^(?:\\B$)$"
0-0;0-0;0-0;0-0
-;-;-;-
"^(?:\\B$)"
0-0;0-0;0-0;0-0
-;-;-;-
"(?:\\B$)$"
0-0;0-0;0-0;0-0
-;-;-;-
strings
""
"y x"
regexps
"\\B$"
0-0;0-0;0-0;0-0
-;-;-;-
"^(?:\\B$)$"
0-0;0-0;0-0;0-0
-;-;-;-
"^(?:\\B$)"
0-0;0-0;0-0;0-0
-;-;-;-
"(?:\\B$)$"
0-0;0-0;0-0;0-0
-;-;-;-
strings
""
"x"
regexps
"\\B.$"
-;-;-;-
-;-;-;-
"^(?:\\B.$)$"
-;-;-;-
-;-;-;-
"^(?:\\B.$)"
-;-;-;-
-;-;-;-
"(?:\\B.$)$"
-;-;-;-
-;-;-;-
strings
""
"fo"
regexps
"^\\B(fo|foo)\\B"
-;-;-;-
-;-;-;-
"^(?:^\\B(fo|foo)\\B)$"
-;-;-;-
-;-;-;-
"^(?:^\\B(fo|foo)\\B)"
-;-;-;-
-;-;-;-
"(?:^\\B(fo|foo)\\B)$"
-;-;-;-
-;-;-;-
strings
""
"foo"
regexps
"^\\B(fo|foo)\\B"
-;-;-;-
-;-;-;-
"^(?:^\\B(fo|foo)\\B)$"
-;-;-;-
-;-;-;-
"^(?:^\\B(fo|foo)\\B)"
-;-;-;-
-;-;-;-
"(?:^\\B(fo|foo)\\B)$"
-;-;-;-
-;-;-;-
strings
""
""
regexps
"^\\B"
0-0;0-0;0-0;0-0
0-0;0-0;0-0;0-0
"^(?:^\\B)$"
0-0;0-0;0-0;0-0
0-0;0-0;0-0;0-0
"^(?:^\\B)"
0-0;0-0;0-0;0-0
0-0;0-0;0-0;0-0
"(?:^\\B)$"
0-0;0-0;0-0;0-0
0-0;0-0;0-0;0-0
strings
""
"x"
regexps
"^\\B"
0-0;0-0;0-0;0-0
-;-;-;-
"^(?:^\\B)$"
0-0;0-0;0-0;0-0
-;-;-;-
"^(?:^\\B)"
0-0;0-0;0-0;0-0
-;-;-;-
"(?:^\\B)$"
0-0;0-0;0-0;0-0
-;-;-;-
strings
""
""
regexps
"^\\B\\B"
0-0;0-0;0-0;0-0
0-0;0-0;0-0;0-0
"^(?:^\\B\\B)$"
0-0;0-0;0-0;0-0
0-0;0-0;0-0;0-0
"^(?:^\\B\\B)"
0-0;0-0;0-0;0-0
0-0;0-0;0-0;0-0
"(?:^\\B\\B)$"
0-0;0-0;0-0;0-0
0-0;0-0;0-0;0-0
strings
""
"x"
regexps
"^\\B\\B"
0-0;0-0;0-0;0-0
-;-;-;-
"^(?:^\\B\\B)$"
0-0;0-0;0-0;0-0
-;-;-;-
"^(?:^\\B\\B)"
0-0;0-0;0-0;0-0
-;-;-;-
"(?:^\\B\\B)$"
0-0;0-0;0-0;0-0
-;-;-;-
strings
""
""
regexps
"^\\B$"
0-0;0-0;0-0;0-0
0-0;0-0;0-0;0-0
"^(?:^\\B$)$"
0-0;0-0;0-0;0-0
0-0;0-0;0-0;0-0
"^(?:^\\B$)"
0-0;0-0;0-0;0-0
0-0;0-0;0-0;0-0
"(?:^\\B$)$"
0-0;0-0;0-0;0-0
0-0;0-0;0-0;0-0
strings
""
"x"
regexps
"^\\B$"
0-0;0-0;0-0;0-0
-;-;-;-
"^(?:^\\B$)$"
0-0;0-0;0-0;0-0
-;-;-;-
"^(?:^\\B$)"
0-0;0-0;0-0;0-0
-;-;-;-
"(?:^\\B$)$"
0-0;0-0;0-0;0-0
-;-;-;-
strings
""
"x"
regexps
"^\\B.$"
-;-;-;-
-;-;-;-
"^(?:^\\B.$)$"
-;-;-;-
-;-;-;-
"^(?:^\\B.$)"
-;-;-;-
-;-;-;-
"(?:^\\B.$)$"
-;-;-;-
-;-;-;-
strings
""
"x"
regexps
"^\\B.\\B$"
-;-;-;-
-;-;-;-
"^(?:^\\B.\\B$)$"
-;-;-;-
-;-;-;-
"^(?:^\\B.\\B$)"
-;-;-;-
-;-;-;-
"(?:^\\B.\\B$)$"
-;-;-;-
-;-;-;-
strings
""
""
regexps
"^^^^^^^^\\B$$$$$$$"
0-0;0-0;0-0;0-0
0-0;0-0;0-0;0-0
"^(?:^^^^^^^^\\B$$$$$$$)$"
0-0;0-0;0-0;0-0
0-0;0-0;0-0;0-0
"^(?:^^^^^^^^\\B$$$$$$$)"
0-0;0-0;0-0;0-0
0-0;0-0;0-0;0-0
"(?:^^^^^^^^\\B$$$$$$$)$"
0-0;0-0;0-0;0-0
0-0;0-0;0-0;0-0
strings
""
"x"
regexps
"^^^^^^^^\\B.$$$$$$"
-;-;-;-
-;-;-;-
"^(?:^^^^^^^^\\B.$$$$$$)$"
-;-;-;-
-;-;-;-
"^(?:^^^^^^^^\\B.$$$$$$)"
-;-;-;-
-;-;-;-
"(?:^^^^^^^^\\B.$$$$$$)$"
-;-;-;-
-;-;-;-
strings
""
"x"
regexps
"^^^^^^^^\\B$$$$$$$"
0-0;0-0;0-0;0-0
-;-;-;-
"^(?:^^^^^^^^\\B$$$$$$$)$"
0-0;0-0;0-0;0-0
-;-;-;-
"^(?:^^^^^^^^\\B$$$$$$$)"
0-0;0-0;0-0;0-0
-;-;-;-
"(?:^^^^^^^^\\B$$$$$$$)$"
0-0;0-0;0-0;0-0
-;-;-;-
strings
""
"x"
regexps
"\\bx\\b"
-;-;-;-
0-1;0-1;0-1;0-1
"^(?:\\bx\\b)$"
-;-;-;-
0-1;0-1;0-1;0-1
"^(?:\\bx\\b)"
-;-;-;-
0-1;0-1;0-1;0-1
"(?:\\bx\\b)$"
-;-;-;-
0-1;0-1;0-1;0-1
strings
""
"x>"
regexps
"\\bx\\b"
-;-;-;-
-;0-1;-;0-1
"^(?:\\bx\\b)$"
-;-;-;-
-;-;-;-
"^(?:\\bx\\b)"
-;-;-;-
-;0-1;-;0-1
"(?:\\bx\\b)$"
-;-;-;-
-;-;-;-
strings
""
"<x"
regexps
"\\bx\\b"
-;-;-;-
-;1-2;-;1-2
"^(?:\\bx\\b)$"
-;-;-;-
-;-;-;-
"^(?:\\bx\\b)"
-;-;-;-
-;-;-;-
"(?:\\bx\\b)$"
-;-;-;-
-;1-2;-;1-2
strings
""
"<x>"
regexps
"\\bx\\b"
-;-;-;-
-;1-2;-;1-2
"^(?:\\bx\\b)$"
-;-;-;-
-;-;-;-
"^(?:\\bx\\b)"
-;-;-;-
-;-;-;-
"(?:\\bx\\b)$"
-;-;-;-
-;-;-;-
strings
""
"ax"
regexps
"\\bx\\b"
-;-;-;-
-;-;-;-
"^(?:\\bx\\b)$"
-;-;-;-
-;-;-;-
"^(?:\\bx\\b)"
-;-;-;-
-;-;-;-
"(?:\\bx\\b)$"
-;-;-;-
-;-;-;-
strings
""
"xb"
regexps
"\\bx\\b"
-;-;-;-
-;-;-;-
"^(?:\\bx\\b)$"
-;-;-;-
-;-;-;-
"^(?:\\bx\\b)"
-;-;-;-
-;-;-;-
"(?:\\bx\\b)$"
-;-;-;-
-;-;-;-
strings
""
"axb"
regexps
"\\bx\\b"
-;-;-;-
-;-;-;-
"^(?:\\bx\\b)$"
-;-;-;-
-;-;-;-
"^(?:\\bx\\b)"
-;-;-;-
-;-;-;-
"(?:\\bx\\b)$"
-;-;-;-
-;-;-;-
strings
""
"«x"
regexps
"\\bx\\b"
-;-;-;-
-;2-3;-;2-3
"^(?:\\bx\\b)$"
-;-;-;-
-;-;-;-
"^(?:\\bx\\b)"
-;-;-;-
-;-;-;-
"(?:\\bx\\b)$"
-;-;-;-
-;2-3;-;2-3
strings
""
"x»"
regexps
"\\bx\\b"
-;-;-;-
-;0-1;-;0-1
"^(?:\\bx\\b)$"
-;-;-;-
-;-;-;-
"^(?:\\bx\\b)"
-;-;-;-
-;0-1;-;0-1
"(?:\\bx\\b)$"
-;-;-;-
-;-;-;-
strings
""
"«x»"
regexps
"\\bx\\b"
-;-;-;-
-;2-3;-;2-3
"^(?:\\bx\\b)$"
-;-;-;-
-;-;-;-
"^(?:\\bx\\b)"
-;-;-;-
-;-;-;-
"(?:\\bx\\b)$"
-;-;-;-
-;-;-;-
strings
""
"axb"
regexps
"\\bx\\b"
-;-;-;-
-;-;-;-
"^(?:\\bx\\b)$"
-;-;-;-
-;-;-;-
"^(?:\\bx\\b)"
-;-;-;-
-;-;-;-
"(?:\\bx\\b)$"
-;-;-;-
-;-;-;-
strings
""
"áxβ"
regexps
"\\bx\\b"
-;-;-;-
-;2-3;-;2-3
"^(?:\\bx\\b)$"
-;-;-;-
-;-;-;-
"^(?:\\bx\\b)"
-;-;-;-
-;-;-;-
"(?:\\bx\\b)$"
-;-;-;-
-;-;-;-
strings
""
"axb"
regexps
"\\Bx\\B"
-;-;-;-
-;1-2;-;1-2
"^(?:\\Bx\\B)$"
-;-;-;-
-;-;-;-
"^(?:\\Bx\\B)"
-;-;-;-
-;-;-;-
"(?:\\Bx\\B)$"
-;-;-;-
-;-;-;-
strings
""
"áxβ"
regexps
"\\Bx\\B"
-;-;-;-
-;-;-;-
"^(?:\\Bx\\B)$"
-;-;-;-
-;-;-;-
"^(?:\\Bx\\B)"
-;-;-;-
-;-;-;-
"(?:\\Bx\\B)$"
-;-;-;-
-;-;-;-
strings
""
""
regexps
"^$^$"
0-0;0-0;0-0;0-0
0-0;0-0;0-0;0-0
"^(?:^$^$)$"
0-0;0-0;0-0;0-0
0-0;0-0;0-0;0-0
"^(?:^$^$)"
0-0;0-0;0-0;0-0
0-0;0-0;0-0;0-0
"(?:^$^$)$"
0-0;0-0;0-0;0-0
0-0;0-0;0-0;0-0
strings
""
""
regexps
"^$^"
0-0;0-0;0-0;0-0
0-0;0-0;0-0;0-0
"^(?:^$^)$"
0-0;0-0;0-0;0-0
0-0;0-0;0-0;0-0
"^(?:^$^)"
0-0;0-0;0-0;0-0
0-0;0-0;0-0;0-0
"(?:^$^)$"
0-0;0-0;0-0;0-0
0-0;0-0;0-0;0-0
strings
""
""
regexps
"$^$"
0-0;0-0;0-0;0-0
0-0;0-0;0-0;0-0
"^(?:$^$)$"
0-0;0-0;0-0;0-0
0-0;0-0;0-0;0-0
"^(?:$^$)"
0-0;0-0;0-0;0-0
0-0;0-0;0-0;0-0
"(?:$^$)$"
0-0;0-0;0-0;0-0
0-0;0-0;0-0;0-0
strings
""
"x"
regexps
"^$^$"
0-0;0-0;0-0;0-0
-;-;-;-
"^(?:^$^$)$"
0-0;0-0;0-0;0-0
-;-;-;-
"^(?:^$^$)"
0-0;0-0;0-0;0-0
-;-;-;-
"(?:^$^$)$"
0-0;0-0;0-0;0-0
-;-;-;-
strings
""
"x"
regexps
"^$^"
0-0;0-0;0-0;0-0
-;-;-;-
"^(?:^$^)$"
0-0;0-0;0-0;0-0
-;-;-;-
"^(?:^$^)"
0-0;0-0;0-0;0-0
-;-;-;-
"(?:^$^)$"
0-0;0-0;0-0;0-0
-;-;-;-
strings
""
"x"
regexps
"$^$"
0-0;0-0;0-0;0-0
-;-;-;-
"^(?:$^$)$"
0-0;0-0;0-0;0-0
-;-;-;-
"^(?:$^$)"
0-0;0-0;0-0;0-0
-;-;-;-
"(?:$^$)$"
0-0;0-0;0-0;0-0
-;-;-;-
strings
""
"x\ny"
regexps
"^$^$"
0-0;0-0;0-0;0-0
-;-;-;-
"^(?:^$^$)$"
0-0;0-0;0-0;0-0
-;-;-;-
"^(?:^$^$)"
0-0;0-0;0-0;0-0
-;-;-;-
"(?:^$^$)$"
0-0;0-0;0-0;0-0
-;-;-;-
strings
""
"x\ny"
regexps
"^$^"
0-0;0-0;0-0;0-0
-;-;-;-
"^(?:^$^)$"
0-0;0-0;0-0;0-0
-;-;-;-
"^(?:^$^)"
0-0;0-0;0-0;0-0
-;-;-;-
"(?:^$^)$"
0-0;0-0;0-0;0-0
-;-;-;-
strings
""
"x\ny"
regexps
"$^$"
0-0;0-0;0-0;0-0
-;-;-;-
"^(?:$^$)$"
0-0;0-0;0-0;0-0
-;-;-;-
"^(?:$^$)"
0-0;0-0;0-0;0-0
-;-;-;-
"(?:$^$)$"
0-0;0-0;0-0;0-0
-;-;-;-
strings
""
"x\n\ny"
regexps
"^$^$"
0-0;0-0;0-0;0-0
-;-;-;-
"^(?:^$^$)$"
0-0;0-0;0-0;0-0
-;-;-;-
"^(?:^$^$)"
0-0;0-0;0-0;0-0
-;-;-;-
"(?:^$^$)$"
0-0;0-0;0-0;0-0
-;-;-;-
strings
""
"x\n\ny"
regexps
"^$^"
0-0;0-0;0-0;0-0
-;-;-;-
"^(?:^$^)$"
0-0;0-0;0-0;0-0
-;-;-;-
"^(?:^$^)"
0-0;0-0;0-0;0-0
-;-;-;-
"(?:^$^)$"
0-0;0-0;0-0;0-0
-;-;-;-
strings
""
"x\n\ny"
regexps
"$^$"
0-0;0-0;0-0;0-0
-;-;-;-
"^(?:$^$)$"
0-0;0-0;0-0;0-0
-;-;-;-
"^(?:$^$)"
0-0;0-0;0-0;0-0
-;-;-;-
"(?:$^$)$"
0-0;0-0;0-0;0-0
-;-;-;-
strings
""
"foo$bar"
regexps
"^(foo\\$)$"
-;-;-;-
-;-;-;-
"^(?:^(foo\\$)$)$"
-;-;-;-
-;-;-;-
"^(?:^(foo\\$)$)"
-;-;-;-
-;-;-;-
"(?:^(foo\\$)$)$"
-;-;-;-
-;-;-;-
strings
""
"foo$bar"
regexps
"(foo\\$)"
-;-;-;-
-;0-4 0-4;-;0-4 0-4
"^(?:(foo\\$))$"
-;-;-;-
-;-;-;-
"^(?:(foo\\$))"
-;-;-;-
-;0-4 0-4;-;0-4 0-4
"(?:(foo\\$))$"
-;-;-;-
-;-;-;-
strings
""
"abc"
regexps
"^...$"
-;-;-;-
0-3;0-3;0-3;0-3
"^(?:^...$)$"
-;-;-;-
0-3;0-3;0-3;0-3
"^(?:^...$)"
-;-;-;-
0-3;0-3;0-3;0-3
"(?:^...$)$"
-;-;-;-
0-3;0-3;0-3;0-3
strings
""
"本"
regexps
"^本$"
-;-;-;-
0-3;0-3;0-3;0-3
"^(?:^本$)$"
-;-;-;-
0-3;0-3;0-3;0-3
"^(?:^本$)"
-;-;-;-
0-3;0-3;0-3;0-3
"(?:^本$)$"
-;-;-;-
0-3;0-3;0-3;0-3
strings
""
"日本語"
regexps
"^...$"
-;-;-;-
0-9;0-9;0-9;0-9
"^(?:^...$)$"
-;-;-;-
0-9;0-9;0-9;0-9
"^(?:^...$)"
-;-;-;-
0-9;0-9;0-9;0-9
"(?:^...$)$"
-;-;-;-
0-9;0-9;0-9;0-9
strings
""
".本."
regexps
"^...$"
-;-;-;-
0-5;0-5;0-5;0-5
"^(?:^...$)$"
-;-;-;-
0-5;0-5;0-5;0-5
"^(?:^...$)"
-;-;-;-
0-5;0-5;0-5;0-5
"(?:^...$)$"
-;-;-;-
0-5;0-5;0-5;0-5
strings
""
"本"
regexps
"^\\C\\C\\C$"
-;-;-;-
0-3;0-3;0-3;0-3
"^(?:^\\C\\C\\C$)$"
-;-;-;-
0-3;0-3;0-3;0-3
"^(?:^\\C\\C\\C$)"
-;-;-;-
0-3;0-3;0-3;0-3
"(?:^\\C\\C\\C$)$"
-;-;-;-
0-3;0-3;0-3;0-3
strings
""
"本"
regexps
"^\\C$"
-;-;-;-
-;-;-;-
"^(?:^\\C$)$"
-;-;-;-
-;-;-;-
"^(?:^\\C$)"
-;-;-;-
-;-;-;-
"(?:^\\C$)$"
-;-;-;-
-;-;-;-
strings
""
"日本語"
regexps
"^\\C\\C\\C$"
-;-;-;-
-;-;-;-
"^(?:^\\C\\C\\C$)$"
-;-;-;-
-;-;-;-
"^(?:^\\C\\C\\C$)"
-;-;-;-
-;-;-;-
"(?:^\\C\\C\\C$)$"
-;-;-;-
-;-;-;-
strings
""
"日本語"
regexps
"^...$"
-;-;-;-
0-9;0-9;0-9;0-9
"^(?:^...$)$"
-;-;-;-
0-9;0-9;0-9;0-9
"^(?:^...$)"
-;-;-;-
0-9;0-9;0-9;0-9
"(?:^...$)$"
-;-;-;-
0-9;0-9;0-9;0-9
strings
""
"日本語"
regexps
"^.........$"
-;-;-;-
-;-;-;-
"^(?:^.........$)$"
-;-;-;-
-;-;-;-
"^(?:^.........$)"
-;-;-;-
-;-;-;-
"(?:^.........$)$"
-;-;-;-
-;-;-;-
strings
""
".本."
regexps
"^...$"
-;-;-;-
0-5;0-5;0-5;0-5
"^(?:^...$)$"
-;-;-;-
0-5;0-5;0-5;0-5
"^(?:^...$)"
-;-;-;-
0-5;0-5;0-5;0-5
"(?:^...$)$"
-;-;-;-
0-5;0-5;0-5;0-5
strings
""
".本."
regexps
"^.....$"
-;-;-;-
-;-;-;-
"^(?:^.....$)$"
-;-;-;-
-;-;-;-
"^(?:^.....$)"
-;-;-;-
-;-;-;-
"(?:^.....$)$"
-;-;-;-
-;-;-;-
strings
""
"xfooo"
regexps
"\\B(fo|foo)\\B"
-;-;-;-
-;1-3 1-3;-;1-4 1-4
"^(?:\\B(fo|foo)\\B)$"
-;-;-;-
-;-;-;-
"^(?:\\B(fo|foo)\\B)"
-;-;-;-
-;-;-;-
"(?:\\B(fo|foo)\\B)$"
-;-;-;-
-;-;-;-
strings
""
"foo"
regexps
"(fo|foo)"
-;-;-;-
0-3 0-3;0-2 0-2;0-3 0-3;0-3 0-3
"^(?:(fo|foo))$"
-;-;-;-
0-3 0-3;0-3 0-3;0-3 0-3;0-3 0-3
"^(?:(fo|foo))"
-;-;-;-
0-3 0-3;0-2 0-2;0-3 0-3;0-3 0-3
"(?:(fo|foo))$"
-;-;-;-
0-3 0-3;0-3 0-3;0-3 0-3;0-3 0-3
strings
""
"a"
regexps
"\\141"
-;-;-;-
0-1;0-1;0-1;0-1
"^(?:\\141)$"
-;-;-;-
0-1;0-1;0-1;0-1
"^(?:\\141)"
-;-;-;-
0-1;0-1;0-1;0-1
"(?:\\141)$"
-;-;-;-
0-1;0-1;0-1;0-1
strings
""
"0"
regexps
"\\060"
-;-;-;-
0-1;0-1;0-1;0-1
"^(?:\\060)$"
-;-;-;-
0-1;0-1;0-1;0-1
"^(?:\\060)"
-;-;-;-
0-1;0-1;0-1;0-1
"(?:\\060)$"
-;-;-;-
0-1;0-1;0-1;0-1
strings
""
"00"
regexps
"\\0600"
-;-;-;-
0-2;0-2;0-2;0-2
"^(?:\\0600)$"
-;-;-;-
0-2;0-2;0-2;0-2
"^(?:\\0600)"
-;-;-;-
0-2;0-2;0-2;0-2
"(?:\\0600)$"
-;-;-;-
0-2;0-2;0-2;0-2
strings
""
"08"
regexps
"\\608"
-;-;-;-
0-2;0-2;0-2;0-2
"^(?:\\608)$"
-;-;-;-
0-2;0-2;0-2;0-2
"^(?:\\608)"
-;-;-;-
0-2;0-2;0-2;0-2
"(?:\\608)$"
-;-;-;-
0-2;0-2;0-2;0-2
strings
""
""
regexps
"\\01"
-;-;-;-
0-1;0-1;0-1;0-1
"^(?:\\01)$"
-;-;-;-
0-1;0-1;0-1;0-1
"^(?:\\01)"
-;-;-;-
0-1;0-1;0-1;0-1
"(?:\\01)$"
-;-;-;-
0-1;0-1;0-1;0-1
strings
""
"8"
regexps
"\\018"
-;-;-;-
0-2;0-2;0-2;0-2
"^(?:\\018)$"
-;-;-;-
0-2;0-2;0-2;0-2
"^(?:\\018)"
-;-;-;-
0-2;0-2;0-2;0-2
"(?:\\018)$"
-;-;-;-
0-2;0-2;0-2;0-2
strings
""
"a"
regexps
"\\x{61}"
-;-;-;-
0-1;0-1;0-1;0-1
"^(?:\\x{61})$"
-;-;-;-
0-1;0-1;0-1;0-1
"^(?:\\x{61})"
-;-;-;-
0-1;0-1;0-1;0-1
"(?:\\x{61})$"
-;-;-;-
0-1;0-1;0-1;0-1
strings
""
"a"
regexps
"\\x61"
-;-;-;-
0-1;0-1;0-1;0-1
"^(?:\\x61)$"
-;-;-;-
0-1;0-1;0-1;0-1
"^(?:\\x61)"
-;-;-;-
0-1;0-1;0-1;0-1
"(?:\\x61)$"
-;-;-;-
0-1;0-1;0-1;0-1
strings
""
"a"
regexps
"\\x{00000061}"
-;-;-;-
0-1;0-1;0-1;0-1
"^(?:\\x{00000061})$"
-;-;-;-
0-1;0-1;0-1;0-1
"^(?:\\x{00000061})"
-;-;-;-
0-1;0-1;0-1;0-1
"(?:\\x{00000061})$"
-;-;-;-
0-1;0-1;0-1;0-1
strings
""
"aαβb"
regexps
"\\p{Greek}+"
-;-;-;-
-;1-5;-;1-5
"^(?:\\p{Greek}+)$"
-;-;-;-
-;-;-;-
"^(?:\\p{Greek}+)"
-;-;-;-
-;-;-;-
"(?:\\p{Greek}+)$"
-;-;-;-
-;-;-;-
strings
""
"aαβb"
regexps
"\\P{Greek}+"
-;-;-;-
-;0-1;-;0-1
"^(?:\\P{Greek}+)$"
-;-;-;-
-;-;-;-
"^(?:\\P{Greek}+)"
-;-;-;-
-;0-1;-;0-1
"(?:\\P{Greek}+)$"
-;-;-;-
-;5-6;-;5-6
strings
""
"aαβb"
regexps
"\\p{^Greek}+"
-;-;-;-
-;0-1;-;0-1
"^(?:\\p{^Greek}+)$"
-;-;-;-
-;-;-;-
"^(?:\\p{^Greek}+)"
-;-;-;-
-;0-1;-;0-1
"(?:\\p{^Greek}+)$"
-;-;-;-
-;5-6;-;5-6
strings
""
"aαβb"
regexps
"\\P{^Greek}+"
-;-;-;-
-;1-5;-;1-5
"^(?:\\P{^Greek}+)$"
-;-;-;-
-;-;-;-
"^(?:\\P{^Greek}+)"
-;-;-;-
-;-;-;-
"(?:\\P{^Greek}+)$"
-;-;-;-
-;-;-;-
strings
""
"abc123"
regexps
"[^0-9]+"
-;-;-;-
-;0-3;-;0-3
"^(?:[^0-9]+)$"
-;-;-;-
-;-;-;-
"^(?:[^0-9]+)"
-;-;-;-
-;0-3;-;0-3
"(?:[^0-9]+)$"
-;-;-;-
-;-;-;-
strings
""
"abc123²³¼½¾₀₉"
regexps
"\\p{Nd}+"
-;-;-;-
-;3-6;-;3-6
"^(?:\\p{Nd}+)$"
-;-;-;-
-;-;-;-
"^(?:\\p{Nd}+)"
-;-;-;-
-;-;-;-
"(?:\\p{Nd}+)$"
-;-;-;-
-;-;-;-
strings
""
"abc123²³¼½¾₀₉"
regexps
"\\p{^Nd}+"
-;-;-;-
-;0-3;-;0-3
"^(?:\\p{^Nd}+)$"
-;-;-;-
-;-;-;-
"^(?:\\p{^Nd}+)"
-;-;-;-
-;0-3;-;0-3
"(?:\\p{^Nd}+)$"
-;-;-;-
-;6-22;-;6-22
strings
""
"abc123²³¼½¾₀₉"
regexps
"\\P{Nd}+"
-;-;-;-
-;0-3;-;0-3
"^(?:\\P{Nd}+)$"
-;-;-;-
-;-;-;-
"^(?:\\P{Nd}+)"
-;-;-;-
-;0-3;-;0-3
"(?:\\P{Nd}+)$"
-;-;-;-
-;6-22;-;6-22
strings
""
"abc123²³¼½¾₀₉"
regexps
"\\P{^Nd}+"
-;-;-;-
-;3-6;-;3-6
"^(?:\\P{^Nd}+)$"
-;-;-;-
-;-;-;-
"^(?:\\P{^Nd}+)"
-;-;-;-
-;-;-;-
"(?:\\P{^Nd}+)$"
-;-;-;-
-;-;-;-
strings
""
"abc123²³¼½¾₀₉"
regexps
"\\pN+"
-;-;-;-
-;3-22;-;3-22
"^(?:\\pN+)$"
-;-;-;-
-;-;-;-
"^(?:\\pN+)"
-;-;-;-
-;-;-;-
"(?:\\pN+)$"
-;-;-;-
-;3-22;-;3-22
strings
""
"abc123²³¼½¾₀₉"
regexps
"\\p{N}+"
-;-;-;-
-;3-22;-;3-22
"^(?:\\p{N}+)$"
-;-;-;-
-;-;-;-
"^(?:\\p{N}+)"
-;-;-;-
-;-;-;-
"(?:\\p{N}+)$"
-;-;-;-
-;3-22;-;3-22
strings
""
"abc123²³¼½¾₀₉"
regexps
"\\p{^N}+"
-;-;-;-
-;0-3;-;0-3
"^(?:\\p{^N}+)$"
-;-;-;-
-;-;-;-
"^(?:\\p{^N}+)"
-;-;-;-
-;0-3;-;0-3
"(?:\\p{^N}+)$"
-;-;-;-
-;-;-;-
strings
""
"abc123"
regexps
"\\p{Any}+"
-;-;-;-
0-6;0-6;0-6;0-6
"^(?:\\p{Any}+)$"
-;-;-;-
0-6;0-6;0-6;0-6
"^(?:\\p{Any}+)"
-;-;-;-
0-6;0-6;0-6;0-6
"(?:\\p{Any}+)$"
-;-;-;-
0-6;0-6;0-6;0-6
strings
""
"@AaB"
regexps
"(?i)[@-A]+"
-;-;-;-
-;0-3;-;0-3
"^(?:(?i)[@-A]+)$"
-;-;-;-
-;-;-;-
"^(?:(?i)[@-A]+)"
-;-;-;-
-;0-3;-;0-3
"(?:(?i)[@-A]+)$"
-;-;-;-
-;-;-;-
strings
""
"aAzZ"
regexps
"(?i)[A-Z]+"
-;-;-;-
0-4;0-4;0-4;0-4
"^(?:(?i)[A-Z]+)$"
-;-;-;-
0-4;0-4;0-4;0-4
"^(?:(?i)[A-Z]+)"
-;-;-;-
0-4;0-4;0-4;0-4
"(?:(?i)[A-Z]+)$"
-;-;-;-
0-4;0-4;0-4;0-4
strings
""
"Aa\\"
regexps
"(?i)[^\\\\]+"
-;-;-;-
-;0-2;-;0-2
"^(?:(?i)[^\\\\]+)$"
-;-;-;-
-;-;-;-
"^(?:(?i)[^\\\\]+)"
-;-;-;-
-;0-2;-;0-2
"(?:(?i)[^\\\\]+)$"
-;-;-;-
-;-;-;-
strings
""
"acegikmoqsuwyACEGIKMOQSUWY"
regexps
"(?i)[acegikmoqsuwy]+"
-;-;-;-
0-26;0-26;0-26;0-26
"^(?:(?i)[acegikmoqsuwy]+)$"
-;-;-;-
0-26;0-26;0-26;0-26
"^(?:(?i)[acegikmoqsuwy]+)"
-;-;-;-
0-26;0-26;0-26;0-26
"(?:(?i)[acegikmoqsuwy]+)$"
-;-;-;-
0-26;0-26;0-26;0-26
strings
""
"@AaB"
regexps
"[@-A]+"
-;-;-;-
-;0-2;-;0-2
"^(?:[@-A]+)$"
-;-;-;-
-;-;-;-
"^(?:[@-A]+)"
-;-;-;-
-;0-2;-;0-2
"(?:[@-A]+)$"
-;-;-;-
-;-;-;-
strings
""
"aAzZ"
regexps
"[A-Z]+"
-;-;-;-
-;1-2;-;1-2
"^(?:[A-Z]+)$"
-;-;-;-
-;-;-;-
"^(?:[A-Z]+)"
-;-;-;-
-;-;-;-
"(?:[A-Z]+)$"
-;-;-;-
-;3-4;-;3-4
strings
""
"Aa\\"
regexps
"[^\\\\]+"
-;-;-;-
-;0-2;-;0-2
"^(?:[^\\\\]+)$"
-;-;-;-
-;-;-;-
"^(?:[^\\\\]+)"
-;-;-;-
-;0-2;-;0-2
"(?:[^\\\\]+)$"
-;-;-;-
-;-;-;-
strings
""
"acegikmoqsuwyACEGIKMOQSUWY"
regexps
"[acegikmoqsuwy]+"
-;-;-;-
-;0-13;-;0-13
"^(?:[acegikmoqsuwy]+)$"
-;-;-;-
-;-;-;-
"^(?:[acegikmoqsuwy]+)"
-;-;-;-
-;0-13;-;0-13
"(?:[acegikmoqsuwy]+)$"
-;-;-;-
-;-;-;-
strings
""
"abcdef"
regexps
"^abc"
-;-;-;-
-;0-3;-;0-3
"^(?:^abc)$"
-;-;-;-
-;-;-;-
"^(?:^abc)"
-;-;-;-
-;0-3;-;0-3
"(?:^abc)$"
-;-;-;-
-;-;-;-
strings
""
"aabcdef"
regexps
"^abc"
-;-;-;-
-;-;-;-
"^(?:^abc)$"
-;-;-;-
-;-;-;-
"^(?:^abc)"
-;-;-;-
-;-;-;-
"(?:^abc)$"
-;-;-;-
-;-;-;-
strings
""
"abcdef"
regexps
"^[ay]*[bx]+c"
-;-;-;-
-;0-3;-;0-3
"^(?:^[ay]*[bx]+c)$"
-;-;-;-
-;-;-;-
"^(?:^[ay]*[bx]+c)"
-;-;-;-
-;0-3;-;0-3
"(?:^[ay]*[bx]+c)$"
-;-;-;-
-;-;-;-
strings
""
"aabcdef"
regexps
"^[ay]*[bx]+c"
-;-;-;-
-;0-4;-;0-4
"^(?:^[ay]*[bx]+c)$"
-;-;-;-
-;-;-;-
"^(?:^[ay]*[bx]+c)"
-;-;-;-
-;0-4;-;0-4
"(?:^[ay]*[bx]+c)$"
-;-;-;-
-;-;-;-
strings
""
"abcdef"
regexps
"def$"
-;-;-;-
-;3-6;-;3-6
"^(?:def$)$"
-;-;-;-
-;-;-;-
"^(?:def$)"
-;-;-;-
-;-;-;-
"(?:def$)$"
-;-;-;-
-;3-6;-;3-6
strings
""
"abcdeff"
regexps
"def$"
-;-;-;-
-;-;-;-
"^(?:def$)$"
-;-;-;-
-;-;-;-
"^(?:def$)"
-;-;-;-
-;-;-;-
"(?:def$)$"
-;-;-;-
-;-;-;-
strings
""
"abcdef"
regexps
"d[ex][fy]$"
-;-;-;-
-;3-6;-;3-6
"^(?:d[ex][fy]$)$"
-;-;-;-
-;-;-;-
"^(?:d[ex][fy]$)"
-;-;-;-
-;-;-;-
"(?:d[ex][fy]$)$"
-;-;-;-
-;3-6;-;3-6
strings
""
"abcdeff"
regexps
"d[ex][fy]$"
-;-;-;-
-;-;-;-
"^(?:d[ex][fy]$)$"
-;-;-;-
-;-;-;-
"^(?:d[ex][fy]$)"
-;-;-;-
-;-;-;-
"(?:d[ex][fy]$)$"
-;-;-;-
-;-;-;-
strings
""
"abcdef"
regexps
"[dz][ex][fy]$"
-;-;-;-
-;3-6;-;3-6
"^(?:[dz][ex][fy]$)$"
-;-;-;-
-;-;-;-
"^(?:[dz][ex][fy]$)"
-;-;-;-
-;-;-;-
"(?:[dz][ex][fy]$)$"
-;-;-;-
-;3-6;-;3-6
strings
""
"abcdeff"
regexps
"[dz][ex][fy]$"
-;-;-;-
-;-;-;-
"^(?:[dz][ex][fy]$)$"
-;-;-;-
-;-;-;-
"^(?:[dz][ex][fy]$)"
-;-;-;-
-;-;-;-
"(?:[dz][ex][fy]$)$"
-;-;-;-
-;-;-;-
strings
""
"abcdef"
regexps
"(?m)^abc"
-;-;-;-
-;0-3;-;0-3
"^(?:(?m)^abc)$"
-;-;-;-
-;-;-;-
"^(?:(?m)^abc)"
-;-;-;-
-;0-3;-;0-3
"(?:(?m)^abc)$"
-;-;-;-
-;-;-;-
strings
""
"aabcdef"
regexps
"(?m)^abc"
-;-;-;-
-;-;-;-
"^(?:(?m)^abc)$"
-;-;-;-
-;-;-;-
"^(?:(?m)^abc)"
-;-;-;-
-;-;-;-
"(?:(?m)^abc)$"
-;-;-;-
-;-;-;-
strings
""
"abcdef"
regexps
"(?m)^[ay]*[bx]+c"
-;-;-;-
-;0-3;-;0-3
"^(?:(?m)^[ay]*[bx]+c)$"
-;-;-;-
-;-;-;-
"^(?:(?m)^[ay]*[bx]+c)"
-;-;-;-
-;0-3;-;0-3
"(?:(?m)^[ay]*[bx]+c)$"
-;-;-;-
-;-;-;-
strings
""
"aabcdef"
regexps
"(?m)^[ay]*[bx]+c"
-;-;-;-
-;0-4;-;0-4
"^(?:(?m)^[ay]*[bx]+c)$"
-;-;-;-
-;-;-;-
"^(?:(?m)^[ay]*[bx]+c)"
-;-;-;-
-;0-4;-;0-4
"(?:(?m)^[ay]*[bx]+c)$"
-;-;-;-
-;-;-;-
strings
""
"abcdef"
regexps
"(?m)def$"
-;-;-;-
-;3-6;-;3-6
"^(?:(?m)def$)$"
-;-;-;-
-;-;-;-
"^(?:(?m)def$)"
-;-;-;-
-;-;-;-
"(?:(?m)def$)$"
-;-;-;-
-;3-6;-;3-6
strings
""
"abcdeff"
regexps
"(?m)def$"
-;-;-;-
-;-;-;-
"^(?:(?m)def$)$"
-;-;-;-
-;-;-;-
"^(?:(?m)def$)"
-;-;-;-
-;-;-;-
"(?:(?m)def$)$"
-;-;-;-
-;-;-;-
strings
""
"abcdef"
regexps
"(?m)d[ex][fy]$"
-;-;-;-
-;3-6;-;3-6
"^(?:(?m)d[ex][fy]$)$"
-;-;-;-
-;-;-;-
"^(?:(?m)d[ex][fy]$)"
-;-;-;-
-;-;-;-
"(?:(?m)d[ex][fy]$)$"
-;-;-;-
-;3-6;-;3-6
strings
""
"abcdeff"
regexps
"(?m)d[ex][fy]$"
-;-;-;-
-;-;-;-
"^(?:(?m)d[ex][fy]$)$"
-;-;-;-
-;-;-;-
"^(?:(?m)d[ex][fy]$)"
-;-;-;-
-;-;-;-
"(?:(?m)d[ex][fy]$)$"
-;-;-;-
-;-;-;-
strings
""
"abcdef"
regexps
"(?m)[dz][ex][fy]$"
-;-;-;-
-;3-6;-;3-6
"^(?:(?m)[dz][ex][fy]$)$"
-;-;-;-
-;-;-;-
"^(?:(?m)[dz][ex][fy]$)"
-;-;-;-
-;-;-;-
"(?:(?m)[dz][ex][fy]$)$"
-;-;-;-
-;3-6;-;3-6
strings
""
"abcdeff"
regexps
"(?m)[dz][ex][fy]$"
-;-;-;-
-;-;-;-
"^(?:(?m)[dz][ex][fy]$)$"
-;-;-;-
-;-;-;-
"^(?:(?m)[dz][ex][fy]$)"
-;-;-;-
-;-;-;-
"(?:(?m)[dz][ex][fy]$)$"
-;-;-;-
-;-;-;-
strings
""
"a"
regexps
"^"
0-0;0-0;0-0;0-0
-;0-0;-;0-0
"^(?:^)$"
0-0;0-0;0-0;0-0
-;-;-;-
"^(?:^)"
0-0;0-0;0-0;0-0
-;0-0;-;0-0
"(?:^)$"
0-0;0-0;0-0;0-0
-;-;-;-
strings
""
"a"
regexps
"^^"
0-0;0-0;0-0;0-0
-;0-0;-;0-0
"^(?:^^)$"
0-0;0-0;0-0;0-0
-;-;-;-
"^(?:^^)"
0-0;0-0;0-0;0-0
-;0-0;-;0-0
"(?:^^)$"
0-0;0-0;0-0;0-0
-;-;-;-
strings
""
"a"
regexps
"a"
-;-;-;-
0-1;0-1;0-1;0-1
"^(?:a)$"
-;-;-;-
0-1;0-1;0-1;0-1
"^(?:a)"
-;-;-;-
0-1;0-1;0-1;0-1
"(?:a)$"
-;-;-;-
0-1;0-1;0-1;0-1
strings
""
"a"
regexps
"ab*"
-;-;-;-
0-1;0-1;0-1;0-1
"^(?:ab*)$"
-;-;-;-
0-1;0-1;0-1;0-1
"^(?:ab*)"
-;-;-;-
0-1;0-1;0-1;0-1
"(?:ab*)$"
-;-;-;-
0-1;0-1;0-1;0-1
strings
""
"a"
regexps
"a\\C*"
-;-;-;-
0-1;0-1;0-1;0-1
"^(?:a\\C*)$"
-;-;-;-
0-1;0-1;0-1;0-1
"^(?:a\\C*)"
-;-;-;-
0-1;0-1;0-1;0-1
"(?:a\\C*)$"
-;-;-;-
0-1;0-1;0-1;0-1
strings
""
"baba"
regexps
"a\\C*|ba\\C"
-;-;-;-
-;0-3;-;0-3
"^(?:a\\C*|ba\\C)$"
-;-;-;-
-;-;-;-
"^(?:a\\C*|ba\\C)"
-;-;-;-
-;0-3;-;0-3
"(?:a\\C*|ba\\C)$"
-;-;-;-
-;1-4;-;1-4
NOTE implicit vs. explicit repetitions : 2009-02-02
# Glenn Fowler <gsf@research.att.com>
# conforming matches (column 4) must match one of the following BREs
# NOMATCH
# (0,.)\((\(.\),\(.\))(?,?)(\2,\3)\)*
# (0,.)\((\(.\),\(.\))(\2,\3)(?,?)\)*
# i.e., each 3-tuple has two identical elements and one (?,?)
E ((..)|(.)) NULL NOMATCH
E ((..)|(.))((..)|(.)) NULL NOMATCH
E ((..)|(.))((..)|(.))((..)|(.)) NULL NOMATCH
E ((..)|(.)){1} NULL NOMATCH
E ((..)|(.)){2} NULL NOMATCH
E ((..)|(.)){3} NULL NOMATCH
E ((..)|(.))* NULL (0,0)
E ((..)|(.)) a (0,1)(0,1)(?,?)(0,1)
E ((..)|(.))((..)|(.)) a NOMATCH
E ((..)|(.))((..)|(.))((..)|(.)) a NOMATCH
E ((..)|(.)){1} a (0,1)(0,1)(?,?)(0,1)
E ((..)|(.)){2} a NOMATCH
E ((..)|(.)){3} a NOMATCH
E ((..)|(.))* a (0,1)(0,1)(?,?)(0,1)
E ((..)|(.)) aa (0,2)(0,2)(0,2)(?,?)
E ((..)|(.))((..)|(.)) aa (0,2)(0,1)(?,?)(0,1)(1,2)(?,?)(1,2)
E ((..)|(.))((..)|(.))((..)|(.)) aa NOMATCH
E ((..)|(.)){1} aa (0,2)(0,2)(0,2)(?,?)
E ((..)|(.)){2} aa (0,2)(1,2)(?,?)(1,2)
E ((..)|(.)){3} aa NOMATCH
E ((..)|(.))* aa (0,2)(0,2)(0,2)(?,?)
E ((..)|(.)) aaa (0,2)(0,2)(0,2)(?,?)
E ((..)|(.))((..)|(.)) aaa (0,3)(0,2)(0,2)(?,?)(2,3)(?,?)(2,3)
E ((..)|(.))((..)|(.))((..)|(.)) aaa (0,3)(0,1)(?,?)(0,1)(1,2)(?,?)(1,2)(2,3)(?,?)(2,3)
E ((..)|(.)){1} aaa (0,2)(0,2)(0,2)(?,?)
#E ((..)|(.)){2} aaa (0,3)(2,3)(?,?)(2,3)
E ((..)|(.)){2} aaa (0,3)(2,3)(0,2)(2,3) RE2/Go
E ((..)|(.)){3} aaa (0,3)(2,3)(?,?)(2,3)
#E ((..)|(.))* aaa (0,3)(2,3)(?,?)(2,3)
E ((..)|(.))* aaa (0,3)(2,3)(0,2)(2,3) RE2/Go
E ((..)|(.)) aaaa (0,2)(0,2)(0,2)(?,?)
E ((..)|(.))((..)|(.)) aaaa (0,4)(0,2)(0,2)(?,?)(2,4)(2,4)(?,?)
E ((..)|(.))((..)|(.))((..)|(.)) aaaa (0,4)(0,2)(0,2)(?,?)(2,3)(?,?)(2,3)(3,4)(?,?)(3,4)
E ((..)|(.)){1} aaaa (0,2)(0,2)(0,2)(?,?)
E ((..)|(.)){2} aaaa (0,4)(2,4)(2,4)(?,?)
#E ((..)|(.)){3} aaaa (0,4)(3,4)(?,?)(3,4)
E ((..)|(.)){3} aaaa (0,4)(3,4)(0,2)(3,4) RE2/Go
E ((..)|(.))* aaaa (0,4)(2,4)(2,4)(?,?)
E ((..)|(.)) aaaaa (0,2)(0,2)(0,2)(?,?)
E ((..)|(.))((..)|(.)) aaaaa (0,4)(0,2)(0,2)(?,?)(2,4)(2,4)(?,?)
E ((..)|(.))((..)|(.))((..)|(.)) aaaaa (0,5)(0,2)(0,2)(?,?)(2,4)(2,4)(?,?)(4,5)(?,?)(4,5)
E ((..)|(.)){1} aaaaa (0,2)(0,2)(0,2)(?,?)
E ((..)|(.)){2} aaaaa (0,4)(2,4)(2,4)(?,?)
#E ((..)|(.)){3} aaaaa (0,5)(4,5)(?,?)(4,5)
E ((..)|(.)){3} aaaaa (0,5)(4,5)(2,4)(4,5) RE2/Go
#E ((..)|(.))* aaaaa (0,5)(4,5)(?,?)(4,5)
E ((..)|(.))* aaaaa (0,5)(4,5)(2,4)(4,5) RE2/Go
E ((..)|(.)) aaaaaa (0,2)(0,2)(0,2)(?,?)
E ((..)|(.))((..)|(.)) aaaaaa (0,4)(0,2)(0,2)(?,?)(2,4)(2,4)(?,?)
E ((..)|(.))((..)|(.))((..)|(.)) aaaaaa (0,6)(0,2)(0,2)(?,?)(2,4)(2,4)(?,?)(4,6)(4,6)(?,?)
E ((..)|(.)){1} aaaaaa (0,2)(0,2)(0,2)(?,?)
E ((..)|(.)){2} aaaaaa (0,4)(2,4)(2,4)(?,?)
E ((..)|(.)){3} aaaaaa (0,6)(4,6)(4,6)(?,?)
E ((..)|(.))* aaaaaa (0,6)(4,6)(4,6)(?,?)
NOTE additional repetition tests graciously provided by Chris Kuklewicz www.haskell.org 2009-02-02
# These test a bug in OS X / FreeBSD / NetBSD, and libtree.
# Linux/GLIBC gets the {8,} and {8,8} wrong.
:HA#100:E X(.?){0,}Y X1234567Y (0,9)(7,8)
:HA#101:E X(.?){1,}Y X1234567Y (0,9)(7,8)
:HA#102:E X(.?){2,}Y X1234567Y (0,9)(7,8)
:HA#103:E X(.?){3,}Y X1234567Y (0,9)(7,8)
:HA#104:E X(.?){4,}Y X1234567Y (0,9)(7,8)
:HA#105:E X(.?){5,}Y X1234567Y (0,9)(7,8)
:HA#106:E X(.?){6,}Y X1234567Y (0,9)(7,8)
:HA#107:E X(.?){7,}Y X1234567Y (0,9)(7,8)
:HA#108:E X(.?){8,}Y X1234567Y (0,9)(8,8)
#:HA#110:E X(.?){0,8}Y X1234567Y (0,9)(7,8)
:HA#110:E X(.?){0,8}Y X1234567Y (0,9)(8,8) RE2/Go
#:HA#111:E X(.?){1,8}Y X1234567Y (0,9)(7,8)
:HA#111:E X(.?){1,8}Y X1234567Y (0,9)(8,8) RE2/Go
#:HA#112:E X(.?){2,8}Y X1234567Y (0,9)(7,8)
:HA#112:E X(.?){2,8}Y X1234567Y (0,9)(8,8) RE2/Go
#:HA#113:E X(.?){3,8}Y X1234567Y (0,9)(7,8)
:HA#113:E X(.?){3,8}Y X1234567Y (0,9)(8,8) RE2/Go
#:HA#114:E X(.?){4,8}Y X1234567Y (0,9)(7,8)
:HA#114:E X(.?){4,8}Y X1234567Y (0,9)(8,8) RE2/Go
#:HA#115:E X(.?){5,8}Y X1234567Y (0,9)(7,8)
:HA#115:E X(.?){5,8}Y X1234567Y (0,9)(8,8) RE2/Go
#:HA#116:E X(.?){6,8}Y X1234567Y (0,9)(7,8)
:HA#116:E X(.?){6,8}Y X1234567Y (0,9)(8,8) RE2/Go
#:HA#117:E X(.?){7,8}Y X1234567Y (0,9)(7,8)
:HA#117:E X(.?){7,8}Y X1234567Y (0,9)(8,8) RE2/Go
:HA#118:E X(.?){8,8}Y X1234567Y (0,9)(8,8)
# These test a fixed bug in my regex-tdfa that did not keep the expanded
# form properly grouped, so right association did the wrong thing with
# these ambiguous patterns (crafted just to test my code when I became
# suspicious of my implementation). The first subexpression should use
# "ab" then "a" then "bcd".
# OS X / FreeBSD / NetBSD badly fail many of these, with impossible
# results like (0,6)(4,5)(6,6).
:HA#260:E (a|ab|c|bcd){0,}(d*) ababcd (0,6)(3,6)(6,6)
:HA#261:E (a|ab|c|bcd){1,}(d*) ababcd (0,6)(3,6)(6,6)
:HA#262:E (a|ab|c|bcd){2,}(d*) ababcd (0,6)(3,6)(6,6)
:HA#263:E (a|ab|c|bcd){3,}(d*) ababcd (0,6)(3,6)(6,6)
:HA#264:E (a|ab|c|bcd){4,}(d*) ababcd NOMATCH
:HA#265:E (a|ab|c|bcd){0,10}(d*) ababcd (0,6)(3,6)(6,6)
:HA#266:E (a|ab|c|bcd){1,10}(d*) ababcd (0,6)(3,6)(6,6)
:HA#267:E (a|ab|c|bcd){2,10}(d*) ababcd (0,6)(3,6)(6,6)
:HA#268:E (a|ab|c|bcd){3,10}(d*) ababcd (0,6)(3,6)(6,6)
:HA#269:E (a|ab|c|bcd){4,10}(d*) ababcd NOMATCH
:HA#270:E (a|ab|c|bcd)*(d*) ababcd (0,6)(3,6)(6,6)
:HA#271:E (a|ab|c|bcd)+(d*) ababcd (0,6)(3,6)(6,6)
# The above worked on Linux/GLIBC but the following often fail.
# They also trip up OS X / FreeBSD / NetBSD:
#:HA#280:E (ab|a|c|bcd){0,}(d*) ababcd (0,6)(3,6)(6,6)
:HA#280:E (ab|a|c|bcd){0,}(d*) ababcd (0,6)(4,5)(5,6) RE2/Go
#:HA#281:E (ab|a|c|bcd){1,}(d*) ababcd (0,6)(3,6)(6,6)
:HA#281:E (ab|a|c|bcd){1,}(d*) ababcd (0,6)(4,5)(5,6) RE2/Go
#:HA#282:E (ab|a|c|bcd){2,}(d*) ababcd (0,6)(3,6)(6,6)
:HA#282:E (ab|a|c|bcd){2,}(d*) ababcd (0,6)(4,5)(5,6) RE2/Go
#:HA#283:E (ab|a|c|bcd){3,}(d*) ababcd (0,6)(3,6)(6,6)
:HA#283:E (ab|a|c|bcd){3,}(d*) ababcd (0,6)(4,5)(5,6) RE2/Go
:HA#284:E (ab|a|c|bcd){4,}(d*) ababcd NOMATCH
#:HA#285:E (ab|a|c|bcd){0,10}(d*) ababcd (0,6)(3,6)(6,6)
:HA#285:E (ab|a|c|bcd){0,10}(d*) ababcd (0,6)(4,5)(5,6) RE2/Go
#:HA#286:E (ab|a|c|bcd){1,10}(d*) ababcd (0,6)(3,6)(6,6)
:HA#286:E (ab|a|c|bcd){1,10}(d*) ababcd (0,6)(4,5)(5,6) RE2/Go
#:HA#287:E (ab|a|c|bcd){2,10}(d*) ababcd (0,6)(3,6)(6,6)
:HA#287:E (ab|a|c|bcd){2,10}(d*) ababcd (0,6)(4,5)(5,6) RE2/Go
#:HA#288:E (ab|a|c|bcd){3,10}(d*) ababcd (0,6)(3,6)(6,6)
:HA#288:E (ab|a|c|bcd){3,10}(d*) ababcd (0,6)(4,5)(5,6) RE2/Go
:HA#289:E (ab|a|c|bcd){4,10}(d*) ababcd NOMATCH
#:HA#290:E (ab|a|c|bcd)*(d*) ababcd (0,6)(3,6)(6,6)
:HA#290:E (ab|a|c|bcd)*(d*) ababcd (0,6)(4,5)(5,6) RE2/Go
#:HA#291:E (ab|a|c|bcd)+(d*) ababcd (0,6)(3,6)(6,6)
:HA#291:E (ab|a|c|bcd)+(d*) ababcd (0,6)(4,5)(5,6) RE2/Go
#pragma prototyped noticed
/*
* regex(3) test harness
*
* build: cc -o testregex testregex.c
* help: testregex --man
* note: REG_* features are detected by #ifdef; if REG_* are enums
* then supply #define REG_foo REG_foo for each enum REG_foo
*
* Glenn Fowler <gsf@research.att.com>
* AT&T Research
*
* PLEASE: publish your tests so everyone can benefit
*
* The following license covers testregex.c and all associated test data.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of THIS SOFTWARE FILE (the "Software"), to deal in the Software
* without restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, and/or sell copies of the
* Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following disclaimer:
*
* THIS SOFTWARE IS PROVIDED BY AT&T ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL AT&T BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
static const char id[] = "\n@(#)$Id: testregex (AT&T Research) 2010-06-10 $\0\n";
#if _PACKAGE_ast
#include <ast.h>
#else
#include <sys/types.h>
#endif
#include <stdio.h>
#include <regex.h>
#include <ctype.h>
#include <setjmp.h>
#include <signal.h>
#include <string.h>
#include <unistd.h>
#ifdef __STDC__
#include <stdlib.h>
#include <locale.h>
#endif
#ifndef RE_DUP_MAX
#define RE_DUP_MAX 32767
#endif
#if !_PACKAGE_ast
#undef REG_DISCIPLINE
#endif
#ifndef REG_DELIMITED
#undef _REG_subcomp
#endif
#define TEST_ARE 0x00000001
#define TEST_BRE 0x00000002
#define TEST_ERE 0x00000004
#define TEST_KRE 0x00000008
#define TEST_LRE 0x00000010
#define TEST_SRE 0x00000020
#define TEST_EXPAND 0x00000100
#define TEST_LENIENT 0x00000200
#define TEST_QUERY 0x00000400
#define TEST_SUB 0x00000800
#define TEST_UNSPECIFIED 0x00001000
#define TEST_VERIFY 0x00002000
#define TEST_AND 0x00004000
#define TEST_OR 0x00008000
#define TEST_DELIMIT 0x00010000
#define TEST_OK 0x00020000
#define TEST_SAME 0x00040000
#define TEST_ACTUAL 0x00100000
#define TEST_BASELINE 0x00200000
#define TEST_FAIL 0x00400000
#define TEST_PASS 0x00800000
#define TEST_SUMMARY 0x01000000
#define TEST_IGNORE_ERROR 0x02000000
#define TEST_IGNORE_OVER 0x04000000
#define TEST_IGNORE_POSITION 0x08000000
#define TEST_CATCH 0x10000000
#define TEST_VERBOSE 0x20000000
#define TEST_DECOMP 0x40000000
#define TEST_GLOBAL (TEST_ACTUAL|TEST_AND|TEST_BASELINE|TEST_CATCH|TEST_FAIL|TEST_IGNORE_ERROR|TEST_IGNORE_OVER|TEST_IGNORE_POSITION|TEST_OR|TEST_PASS|TEST_SUMMARY|TEST_VERBOSE)
#ifdef REG_DISCIPLINE
#include <stk.h>
typedef struct Disc_s
{
regdisc_t disc;
int ordinal;
Sfio_t* sp;
} Disc_t;
static void*
compf(const regex_t* re, const char* xstr, size_t xlen, regdisc_t* disc)
{
Disc_t* dp = (Disc_t*)disc;
return (void*)((char*)0 + ++dp->ordinal);
}
static int
execf(const regex_t* re, void* data, const char* xstr, size_t xlen, const char* sstr, size_t slen, char** snxt, regdisc_t* disc)
{
Disc_t* dp = (Disc_t*)disc;
sfprintf(dp->sp, "{%-.*s}(%lu:%d)", xlen, xstr, (char*)data - (char*)0, slen);
return atoi(xstr);
}
static void*
resizef(void* handle, void* data, size_t size)
{
if (!size)
return 0;
return stkalloc((Sfio_t*)handle, size);
}
#endif
#ifndef NiL
#ifdef __STDC__
#define NiL 0
#else
#define NiL (char*)0
#endif
#endif
#define H(x) do{if(html)fprintf(stderr,x);}while(0)
#define T(x) fprintf(stderr,x)
static void
help(int html)
{
H("<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML//EN\">\n");
H("<HTML>\n");
H("<HEAD>\n");
H("<TITLE>testregex man document</TITLE>\n");
H("</HEAD>\n");
H("<BODY bgcolor=white>\n");
H("<PRE>\n");
T("NAME\n");
T(" testregex - regex(3) test harness\n");
T("\n");
T("SYNOPSIS\n");
T(" testregex [ options ]\n");
T("\n");
T("DESCRIPTION\n");
T(" testregex reads regex(3) test specifications, one per line, from the\n");
T(" standard input and writes one output line for each failed test. A\n");
T(" summary line is written after all tests are done. Each successful\n");
T(" test is run again with REG_NOSUB. Unsupported features are noted\n");
T(" before the first test, and tests requiring these features are\n");
T(" silently ignored.\n");
T("\n");
T("OPTIONS\n");
T(" -c catch signals and non-terminating calls\n");
T(" -e ignore error return mismatches\n");
T(" -h list help on standard error\n");
T(" -n do not repeat successful tests with regnexec()\n");
T(" -o ignore match[] overrun errors\n");
T(" -p ignore negative position mismatches\n");
T(" -s use stack instead of malloc\n");
T(" -x do not repeat successful tests with REG_NOSUB\n");
T(" -v list each test line\n");
T(" -A list failed test lines with actual answers\n");
T(" -B list all test lines with actual answers\n");
T(" -F list failed test lines\n");
T(" -P list passed test lines\n");
T(" -S output one summary line\n");
T("\n");
T("INPUT FORMAT\n");
T(" Input lines may be blank, a comment beginning with #, or a test\n");
T(" specification. A specification is five fields separated by one\n");
T(" or more tabs. NULL denotes the empty string and NIL denotes the\n");
T(" 0 pointer.\n");
T("\n");
T(" Field 1: the regex(3) flags to apply, one character per REG_feature\n");
T(" flag. The test is skipped if REG_feature is not supported by the\n");
T(" implementation. If the first character is not [BEASKLP] then the\n");
T(" specification is a global control line. One or more of [BEASKLP] may be\n");
T(" specified; the test will be repeated for each mode.\n");
T("\n");
T(" B basic BRE (grep, ed, sed)\n");
T(" E REG_EXTENDED ERE (egrep)\n");
T(" A REG_AUGMENTED ARE (egrep with negation)\n");
T(" S REG_SHELL SRE (sh glob)\n");
T(" K REG_SHELL|REG_AUGMENTED KRE (ksh glob)\n");
T(" L REG_LITERAL LRE (fgrep)\n");
T("\n");
T(" a REG_LEFT|REG_RIGHT implicit ^...$\n");
T(" b REG_NOTBOL lhs does not match ^\n");
T(" c REG_COMMENT ignore space and #...\\n\n");
T(" d REG_SHELL_DOT explicit leading . match\n");
T(" e REG_NOTEOL rhs does not match $\n");
T(" f REG_MULTIPLE multiple \\n separated patterns\n");
T(" g FNM_LEADING_DIR testfnmatch only -- match until /\n");
T(" h REG_MULTIREF multiple digit backref\n");
T(" i REG_ICASE ignore case\n");
T(" j REG_SPAN . matches \\n\n");
T(" k REG_ESCAPE \\ to ecape [...] delimiter\n");
T(" l REG_LEFT implicit ^...\n");
T(" m REG_MINIMAL minimal match\n");
T(" n REG_NEWLINE explicit \\n match\n");
T(" o REG_ENCLOSED (|&) magic inside [@|&](...)\n");
T(" p REG_SHELL_PATH explicit / match\n");
T(" q REG_DELIMITED delimited pattern\n");
T(" r REG_RIGHT implicit ...$\n");
T(" s REG_SHELL_ESCAPED \\ not special\n");
T(" t REG_MUSTDELIM all delimiters must be specified\n");
T(" u standard unspecified behavior -- errors not counted\n");
T(" v REG_CLASS_ESCAPE \\ special inside [...]\n");
T(" w REG_NOSUB no subexpression match array\n");
T(" x REG_LENIENT let some errors slide\n");
T(" y REG_LEFT regexec() implicit ^...\n");
T(" z REG_NULL NULL subexpressions ok\n");
T(" $ expand C \\c escapes in fields 2 and 3\n");
T(" / field 2 is a regsubcomp() expression\n");
T(" = field 3 is a regdecomp() expression\n");
T("\n");
T(" Field 1 control lines:\n");
T("\n");
T(" C set LC_COLLATE and LC_CTYPE to locale in field 2\n");
T("\n");
T(" ?test ... output field 5 if passed and != EXPECTED, silent otherwise\n");
T(" &test ... output field 5 if current and previous passed\n");
T(" |test ... output field 5 if current passed and previous failed\n");
T(" ; ... output field 2 if previous failed\n");
T(" {test ... skip if failed until }\n");
T(" } end of skip\n");
T("\n");
T(" : comment comment copied as output NOTE\n");
T(" :comment:test :comment: ignored\n");
T(" N[OTE] comment comment copied as output NOTE\n");
T(" T[EST] comment comment\n");
T("\n");
T(" number use number for nmatch (20 by default)\n");
T("\n");
T(" Field 2: the regular expression pattern; SAME uses the pattern from\n");
T(" the previous specification. RE_DUP_MAX inside {...} expands to the\n");
T(" value from <limits.h>.\n");
T("\n");
T(" Field 3: the string to match. X...{RE_DUP_MAX} expands to RE_DUP_MAX\n");
T(" copies of X.\n");
T("\n");
T(" Field 4: the test outcome. This is either one of the posix error\n");
T(" codes (with REG_ omitted) or the match array, a list of (m,n)\n");
T(" entries with m and n being first and last+1 positions in the\n");
T(" field 3 string, or NULL if REG_NOSUB is in effect and success\n");
T(" is expected. BADPAT is acceptable in place of any regcomp(3)\n");
T(" error code. The match[] array is initialized to (-2,-2) before\n");
T(" each test. All array elements from 0 to nmatch-1 must be specified\n");
T(" in the outcome. Unspecified endpoints (offset -1) are denoted by ?.\n");
T(" Unset endpoints (offset -2) are denoted by X. {x}(o:n) denotes a\n");
T(" matched (?{...}) expression, where x is the text enclosed by {...},\n");
T(" o is the expression ordinal counting from 1, and n is the length of\n");
T(" the unmatched portion of the subject string. If x starts with a\n");
T(" number then that is the return value of re_execf(), otherwise 0 is\n");
T(" returned. RE_DUP_MAX[-+]N expands to the <limits.h> value -+N.\n");
T("\n");
T(" Field 5: optional comment appended to the report.\n");
T("\n");
T("CAVEAT\n");
T(" If a regex implementation misbehaves with memory then all bets are off.\n");
T("\n");
T("CONTRIBUTORS\n");
T(" Glenn Fowler gsf@research.att.com (ksh strmatch, regex extensions)\n");
T(" David Korn dgk@research.att.com (ksh glob matcher)\n");
T(" Doug McIlroy mcilroy@dartmouth.edu (ast regex/testre in C++)\n");
T(" Tom Lord lord@regexps.com (rx tests)\n");
T(" Henry Spencer henry@zoo.toronto.edu (original public regex)\n");
T(" Andrew Hume andrew@research.att.com (gre tests)\n");
T(" John Maddock John_Maddock@compuserve.com (regex++ tests)\n");
T(" Philip Hazel ph10@cam.ac.uk (pcre tests)\n");
T(" Ville Laurikari vl@iki.fi (libtre tests)\n");
H("</PRE>\n");
H("</BODY>\n");
H("</HTML>\n");
}
#ifndef elementsof
#define elementsof(x) (sizeof(x)/sizeof(x[0]))
#endif
#ifndef streq
#define streq(a,b) (*(a)==*(b)&&!strcmp(a,b))
#endif
#define HUNG 2
#define NOTEST (~0)
#ifndef REG_TEST_DEFAULT
#define REG_TEST_DEFAULT 0
#endif
#ifndef REG_EXEC_DEFAULT
#define REG_EXEC_DEFAULT 0
#endif
static const char* unsupported[] =
{
"BASIC",
#ifndef REG_EXTENDED
"EXTENDED",
#endif
#ifndef REG_AUGMENTED
"AUGMENTED",
#endif
#ifndef REG_SHELL
"SHELL",
#endif
#ifndef REG_CLASS_ESCAPE
"CLASS_ESCAPE",
#endif
#ifndef REG_COMMENT
"COMMENT",
#endif
#ifndef REG_DELIMITED
"DELIMITED",
#endif
#ifndef REG_DISCIPLINE
"DISCIPLINE",
#endif
#ifndef REG_ESCAPE
"ESCAPE",
#endif
#ifndef REG_ICASE
"ICASE",
#endif
#ifndef REG_LEFT
"LEFT",
#endif
#ifndef REG_LENIENT
"LENIENT",
#endif
#ifndef REG_LITERAL
"LITERAL",
#endif
#ifndef REG_MINIMAL
"MINIMAL",
#endif
#ifndef REG_MULTIPLE
"MULTIPLE",
#endif
#ifndef REG_MULTIREF
"MULTIREF",
#endif
#ifndef REG_MUSTDELIM
"MUSTDELIM",
#endif
#ifndef REG_NEWLINE
"NEWLINE",
#endif
#ifndef REG_NOTBOL
"NOTBOL",
#endif
#ifndef REG_NOTEOL
"NOTEOL",
#endif
#ifndef REG_NULL
"NULL",
#endif
#ifndef REG_RIGHT
"RIGHT",
#endif
#ifndef REG_SHELL_DOT
"SHELL_DOT",
#endif
#ifndef REG_SHELL_ESCAPED
"SHELL_ESCAPED",
#endif
#ifndef REG_SHELL_GROUP
"SHELL_GROUP",
#endif
#ifndef REG_SHELL_PATH
"SHELL_PATH",
#endif
#ifndef REG_SPAN
"SPAN",
#endif
#if REG_NOSUB & REG_TEST_DEFAULT
"SUBMATCH",
#endif
#if !_REG_nexec
"regnexec",
#endif
#if !_REG_subcomp
"regsubcomp",
#endif
#if !_REG_decomp
"redecomp",
#endif
0
};
#ifndef REG_CLASS_ESCAPE
#define REG_CLASS_ESCAPE NOTEST
#endif
#ifndef REG_COMMENT
#define REG_COMMENT NOTEST
#endif
#ifndef REG_DELIMITED
#define REG_DELIMITED NOTEST
#endif
#ifndef REG_ESCAPE
#define REG_ESCAPE NOTEST
#endif
#ifndef REG_ICASE
#define REG_ICASE NOTEST
#endif
#ifndef REG_LEFT
#define REG_LEFT NOTEST
#endif
#ifndef REG_LENIENT
#define REG_LENIENT 0
#endif
#ifndef REG_MINIMAL
#define REG_MINIMAL NOTEST
#endif
#ifndef REG_MULTIPLE
#define REG_MULTIPLE NOTEST
#endif
#ifndef REG_MULTIREF
#define REG_MULTIREF NOTEST
#endif
#ifndef REG_MUSTDELIM
#define REG_MUSTDELIM NOTEST
#endif
#ifndef REG_NEWLINE
#define REG_NEWLINE NOTEST
#endif
#ifndef REG_NOTBOL
#define REG_NOTBOL NOTEST
#endif
#ifndef REG_NOTEOL
#define REG_NOTEOL NOTEST
#endif
#ifndef REG_NULL
#define REG_NULL NOTEST
#endif
#ifndef REG_RIGHT
#define REG_RIGHT NOTEST
#endif
#ifndef REG_SHELL_DOT
#define REG_SHELL_DOT NOTEST
#endif
#ifndef REG_SHELL_ESCAPED
#define REG_SHELL_ESCAPED NOTEST
#endif
#ifndef REG_SHELL_GROUP
#define REG_SHELL_GROUP NOTEST
#endif
#ifndef REG_SHELL_PATH
#define REG_SHELL_PATH NOTEST
#endif
#ifndef REG_SPAN
#define REG_SPAN NOTEST
#endif
#define REG_UNKNOWN (-1)
#ifndef REG_ENEWLINE
#define REG_ENEWLINE (REG_UNKNOWN-1)
#endif
#ifndef REG_ENULL
#ifndef REG_EMPTY
#define REG_ENULL (REG_UNKNOWN-2)
#else
#define REG_ENULL REG_EMPTY
#endif
#endif
#ifndef REG_ECOUNT
#define REG_ECOUNT (REG_UNKNOWN-3)
#endif
#ifndef REG_BADESC
#define REG_BADESC (REG_UNKNOWN-4)
#endif
#ifndef REG_EMEM
#define REG_EMEM (REG_UNKNOWN-5)
#endif
#ifndef REG_EHUNG
#define REG_EHUNG (REG_UNKNOWN-6)
#endif
#ifndef REG_EBUS
#define REG_EBUS (REG_UNKNOWN-7)
#endif
#ifndef REG_EFAULT
#define REG_EFAULT (REG_UNKNOWN-8)
#endif
#ifndef REG_EFLAGS
#define REG_EFLAGS (REG_UNKNOWN-9)
#endif
#ifndef REG_EDELIM
#define REG_EDELIM (REG_UNKNOWN-9)
#endif
static const struct { int code; char* name; } codes[] =
{
REG_UNKNOWN, "UNKNOWN",
REG_NOMATCH, "NOMATCH",
REG_BADPAT, "BADPAT",
REG_ECOLLATE, "ECOLLATE",
REG_ECTYPE, "ECTYPE",
REG_EESCAPE, "EESCAPE",
REG_ESUBREG, "ESUBREG",
REG_EBRACK, "EBRACK",
REG_EPAREN, "EPAREN",
REG_EBRACE, "EBRACE",
REG_BADBR, "BADBR",
REG_ERANGE, "ERANGE",
REG_ESPACE, "ESPACE",
REG_BADRPT, "BADRPT",
REG_ENEWLINE, "ENEWLINE",
REG_ENULL, "ENULL",
REG_ECOUNT, "ECOUNT",
REG_BADESC, "BADESC",
REG_EMEM, "EMEM",
REG_EHUNG, "EHUNG",
REG_EBUS, "EBUS",
REG_EFAULT, "EFAULT",
REG_EFLAGS, "EFLAGS",
REG_EDELIM, "EDELIM",
};
static struct
{
regmatch_t NOMATCH;
int errors;
int extracted;
int ignored;
int lineno;
int passed;
int signals;
int unspecified;
int verify;
int warnings;
char* file;
char* stack;
char* which;
jmp_buf gotcha;
#ifdef REG_DISCIPLINE
Disc_t disc;
#endif
} state;
static void
quote(char* s, int len, unsigned long test)
{
unsigned char* u = (unsigned char*)s;
unsigned char* e;
int c;
#ifdef MB_CUR_MAX
int w;
#endif
if (!u)
printf("NIL");
else if (!*u && len <= 1)
printf("NULL");
else if (test & TEST_EXPAND)
{
if (len < 0)
len = strlen((char*)u);
e = u + len;
if (test & TEST_DELIMIT)
printf("\"");
while (u < e)
switch (c = *u++)
{
case '\\':
printf("\\\\");
break;
case '"':
if (test & TEST_DELIMIT)
printf("\\\"");
else
printf("\"");
break;
case '\a':
printf("\\a");
break;
case '\b':
printf("\\b");
break;
case 033:
printf("\\e");
break;
case '\f':
printf("\\f");
break;
case '\n':
printf("\\n");
break;
case '\r':
printf("\\r");
break;
case '\t':
printf("\\t");
break;
case '\v':
printf("\\v");
break;
default:
#ifdef MB_CUR_MAX
s = (char*)u - 1;
if ((w = mblen(s, (char*)e - s)) > 1)
{
u += w - 1;
fwrite(s, 1, w, stdout);
}
else
#endif
if (!iscntrl(c) && isprint(c))
putchar(c);
else
printf("\\x%02x", c);
break;
}
if (test & TEST_DELIMIT)
printf("\"");
}
else
printf("%s", s);
}
static void
report(char* comment, char* fun, char* re, char* s, int len, char* msg, int flags, unsigned long test)
{
if (state.file)
printf("%s:", state.file);
printf("%d:", state.lineno);
if (re)
{
printf(" ");
quote(re, -1, test|TEST_DELIMIT);
if (s)
{
printf(" versus ");
quote(s, len, test|TEST_DELIMIT);
}
}
if (test & TEST_UNSPECIFIED)
{
state.unspecified++;
printf(" unspecified behavior");
}
else
state.errors++;
if (state.which)
printf(" %s", state.which);
if (flags & REG_NOSUB)
printf(" NOSUB");
if (fun)
printf(" %s", fun);
if (comment[strlen(comment)-1] == '\n')
printf(" %s", comment);
else
{
printf(" %s: ", comment);
if (msg)
printf("%s: ", msg);
}
}
static void
error(regex_t* preg, int code)
{
char* msg;
char buf[256];
switch (code)
{
case REG_EBUS:
msg = "bus error";
break;
case REG_EFAULT:
msg = "memory fault";
break;
case REG_EHUNG:
msg = "did not terminate";
break;
default:
regerror(code, preg, msg = buf, sizeof buf);
break;
}
printf("%s\n", msg);
}
static void
bad(char* comment, char* re, char* s, int len, unsigned long test)
{
printf("bad test case ");
report(comment, NiL, re, s, len, NiL, 0, test);
exit(1);
}
static int
escape(char* s)
{
char* b;
char* t;
char* q;
char* e;
int c;
for (b = t = s; *t = *s; s++, t++)
if (*s == '\\')
switch (*++s)
{
case '\\':
break;
case 'a':
*t = '\a';
break;
case 'b':
*t = '\b';
break;
case 'c':
if (*t = *++s)
*t &= 037;
else
s--;
break;
case 'e':
case 'E':
*t = 033;
break;
case 'f':
*t = '\f';
break;
case 'n':
*t = '\n';
break;
case 'r':
*t = '\r';
break;
case 's':
*t = ' ';
break;
case 't':
*t = '\t';
break;
case 'v':
*t = '\v';
break;
case 'u':
case 'x':
c = 0;
q = c == 'u' ? (s + 5) : (char*)0;
e = s + 1;
while (!e || !q || s < q)
{
switch (*++s)
{
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
c = (c << 4) + *s - 'a' + 10;
continue;
case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
c = (c << 4) + *s - 'A' + 10;
continue;
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
c = (c << 4) + *s - '0';
continue;
case '{':
case '[':
if (s != e)
{
s--;
break;
}
e = 0;
continue;
case '}':
case ']':
if (e)
s--;
break;
default:
s--;
break;
}
break;
}
*t = c;
break;
case '0': case '1': case '2': case '3':
case '4': case '5': case '6': case '7':
c = *s - '0';
q = s + 2;
while (s < q)
{
switch (*++s)
{
case '0': case '1': case '2': case '3':
case '4': case '5': case '6': case '7':
c = (c << 3) + *s - '0';
break;
default:
q = --s;
break;
}
}
*t = c;
break;
default:
*(s + 1) = 0;
bad("invalid C \\ escape\n", s - 1, NiL, 0, 0);
}
return t - b;
}
static void
matchoffprint(int off)
{
switch (off)
{
case -2:
printf("X");
break;
case -1:
printf("?");
break;
default:
printf("%d", off);
break;
}
}
static void
matchprint(regmatch_t* match, int nmatch, int nsub, char* ans, unsigned long test)
{
int i;
for (; nmatch > nsub + 1; nmatch--)
if ((match[nmatch-1].rm_so != -1 || match[nmatch-1].rm_eo != -1) && (!(test & TEST_IGNORE_POSITION) || match[nmatch-1].rm_so >= 0 && match[nmatch-1].rm_eo >= 0))
break;
for (i = 0; i < nmatch; i++)
{
printf("(");
matchoffprint(match[i].rm_so);
printf(",");
matchoffprint(match[i].rm_eo);
printf(")");
}
if (!(test & (TEST_ACTUAL|TEST_BASELINE)))
{
if (ans)
printf(" expected: %s", ans);
printf("\n");
}
}
static int
matchcheck(regmatch_t* match, int nmatch, int nsub, char* ans, char* re, char* s, int len, int flags, unsigned long test)
{
char* p;
int i;
int m;
int n;
if (streq(ans, "OK"))
return test & (TEST_BASELINE|TEST_PASS|TEST_VERIFY);
for (i = 0, p = ans; i < nmatch && *p; i++)
{
if (*p == '{')
{
#ifdef REG_DISCIPLINE
char* x;
if (!(x = sfstruse(state.disc.sp)))
bad("out of space [discipline string]\n", NiL, NiL, 0, 0);
if (strcmp(p, x))
{
if (test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_QUERY|TEST_SUMMARY|TEST_VERIFY))
return 0;
report("callout failed", NiL, re, s, len, NiL, flags, test);
quote(p, -1, test);
printf(" expected, ");
quote(x, -1, test);
printf(" returned\n");
}
#endif
break;
}
if (*p++ != '(')
bad("improper answer\n", re, s, -1, test);
if (*p == '?')
{
m = -1;
p++;
}
else if (*p == 'R' && !memcmp(p, "RE_DUP_MAX", 10))
{
m = RE_DUP_MAX;
p += 10;
if (*p == '+' || *p == '-')
m += strtol(p, &p, 10);
}
else
m = strtol(p, &p, 10);
if (*p++ != ',')
bad("improper answer\n", re, s, -1, test);
if (*p == '?')
{
n = -1;
p++;
}
else if (*p == 'R' && !memcmp(p, "RE_DUP_MAX", 10))
{
n = RE_DUP_MAX;
p += 10;
if (*p == '+' || *p == '-')
n += strtol(p, &p, 10);
}
else
n = strtol(p, &p, 10);
if (*p++ != ')')
bad("improper answer\n", re, s, -1, test);
if (m!=match[i].rm_so || n!=match[i].rm_eo)
{
if (!(test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_QUERY|TEST_SUMMARY|TEST_VERIFY)))
{
report("failed: match was", NiL, re, s, len, NiL, flags, test);
matchprint(match, nmatch, nsub, ans, test);
}
return 0;
}
}
for (; i < nmatch; i++)
{
if (match[i].rm_so!=-1 || match[i].rm_eo!=-1)
{
if (!(test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_QUERY|TEST_VERIFY)))
{
if ((test & TEST_IGNORE_POSITION) && (match[i].rm_so<0 || match[i].rm_eo<0))
{
state.ignored++;
return 0;
}
if (!(test & TEST_SUMMARY))
{
report("failed: match was", NiL, re, s, len, NiL, flags, test);
matchprint(match, nmatch, nsub, ans, test);
}
}
return 0;
}
}
if (!(test & TEST_IGNORE_OVER) && match[nmatch].rm_so != state.NOMATCH.rm_so)
{
if (!(test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_QUERY|TEST_SUMMARY|TEST_VERIFY)))
{
report("failed: overran match array", NiL, re, s, len, NiL, flags, test);
matchprint(match, nmatch + 1, nsub, NiL, test);
}
return 0;
}
return 1;
}
static void
sigunblock(int s)
{
#ifdef SIG_SETMASK
int op;
sigset_t mask;
sigemptyset(&mask);
if (s)
{
sigaddset(&mask, s);
op = SIG_UNBLOCK;
}
else op = SIG_SETMASK;
sigprocmask(op, &mask, NiL);
#else
#ifdef sigmask
sigsetmask(s ? (sigsetmask(0L) & ~sigmask(s)) : 0L);
#endif
#endif
}
static void
gotcha(int sig)
{
int ret;
signal(sig, gotcha);
alarm(0);
state.signals++;
switch (sig)
{
case SIGALRM:
ret = REG_EHUNG;
break;
case SIGBUS:
ret = REG_EBUS;
break;
default:
ret = REG_EFAULT;
break;
}
sigunblock(sig);
longjmp(state.gotcha, ret);
}
static char*
getline(FILE* fp)
{
static char buf[32 * 1024];
register char* s = buf;
register char* e = &buf[sizeof(buf)];
register char* b;
for (;;)
{
if (!(b = fgets(s, e - s, fp)))
return 0;
state.lineno++;
s += strlen(s);
if (s == b || *--s != '\n' || s == b || *(s - 1) != '\\')
{
*s = 0;
break;
}
s--;
}
return buf;
}
static unsigned long
note(unsigned long level, char* msg, unsigned long skip, unsigned long test)
{
if (!(test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_SUMMARY)) && !skip)
{
printf("NOTE\t");
if (msg)
printf("%s: ", msg);
printf("skipping lines %d", state.lineno);
}
return skip | level;
}
#define TABS(n) &ts[7-((n)&7)]
static char ts[] = "\t\t\t\t\t\t\t";
static unsigned long
extract(int* tabs, char* spec, char* re, char* s, char* ans, char* msg, char* accept, regmatch_t* match, int nmatch, int nsub, unsigned long skip, unsigned long level, unsigned long test)
{
if (test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_OK|TEST_PASS|TEST_SUMMARY))
{
state.extracted = 1;
if (test & TEST_OK)
{
state.passed++;
if ((test & TEST_VERIFY) && !(test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_SUMMARY)))
{
if (msg && strcmp(msg, "EXPECTED"))
printf("NOTE\t%s\n", msg);
return skip;
}
test &= ~(TEST_PASS|TEST_QUERY);
}
if (test & (TEST_QUERY|TEST_VERIFY))
{
if (test & TEST_BASELINE)
test &= ~(TEST_BASELINE|TEST_PASS);
else
test |= TEST_PASS;
skip |= level;
}
if (!(test & TEST_OK))
{
if (test & TEST_UNSPECIFIED)
state.unspecified++;
else
state.errors++;
}
if (test & (TEST_PASS|TEST_SUMMARY))
return skip;
test &= ~TEST_DELIMIT;
printf("%s%s", spec, TABS(*tabs++));
if ((test & (TEST_BASELINE|TEST_SAME)) == (TEST_BASELINE|TEST_SAME))
printf("SAME");
else
quote(re, -1, test);
printf("%s", TABS(*tabs++));
quote(s, -1, test);
printf("%s", TABS(*tabs++));
if (!(test & (TEST_ACTUAL|TEST_BASELINE)) || !accept && !match)
printf("%s", ans);
else if (accept)
printf("%s", accept);
else
matchprint(match, nmatch, nsub, NiL, test);
if (msg)
printf("%s%s", TABS(*tabs++), msg);
putchar('\n');
}
else if (test & TEST_QUERY)
skip = note(level, msg, skip, test);
else if (test & TEST_VERIFY)
state.extracted = 1;
return skip;
}
static int
catchfree(regex_t* preg, int flags, int* tabs, char* spec, char* re, char* s, char* ans, char* msg, char* accept, regmatch_t* match, int nmatch, int nsub, unsigned long skip, unsigned long level, unsigned long test)
{
int eret;
if (!(test & TEST_CATCH))
{
regfree(preg);
eret = 0;
}
else if (!(eret = setjmp(state.gotcha)))
{
alarm(HUNG);
regfree(preg);
alarm(0);
}
else if (test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_QUERY|TEST_SUMMARY|TEST_VERIFY))
extract(tabs, spec, re, s, ans, msg, NiL, NiL, 0, 0, skip, level, test);
else
{
report("failed", "regfree", re, NiL, -1, msg, flags, test);
error(preg, eret);
}
return eret;
}
static char*
expand(char* os, char* ot)
{
char* s = os;
char* t;
int n = 0;
int r;
long m;
for (;;)
{
switch (*s++)
{
case 0:
break;
case '{':
n++;
continue;
case '}':
n--;
continue;
case 'R':
if (n == 1 && !memcmp(s, "E_DUP_MAX", 9))
{
s--;
for (t = ot; os < s; *t++ = *os++);
r = ((t - ot) >= 5 && t[-1] == '{' && t[-2] == '.' && t[-3] == '.' && t[-4] == '.') ? t[-5] : 0;
os = ot;
m = RE_DUP_MAX;
if (*(s += 10) == '+' || *s == '-')
m += strtol(s, &s, 10);
if (r)
{
t -= 5;
while (m-- > 0)
*t++ = r;
while (*s && *s++ != '}');
}
else
t += snprintf(t, 32, "%ld", m);
while (*t = *s++)
t++;
break;
}
continue;
default:
continue;
}
break;
}
return os;
}
int
main(int argc, char** argv)
{
int flags;
int cflags;
int eflags;
int nmatch;
int nexec;
int nstr;
int cret;
int eret;
int nsub;
int i;
int j;
int expected;
int got;
int locale;
int subunitlen;
int testno;
unsigned long level;
unsigned long skip;
char* p;
char* line;
char* spec;
char* re;
char* s;
char* ans;
char* msg;
char* fun;
char* ppat;
char* subunit;
char* version;
char* field[6];
char* delim[6];
FILE* fp;
int tabs[6];
char unit[64];
regmatch_t match[100];
regex_t preg;
static char pat[32 * 1024];
static char patbuf[32 * 1024];
static char strbuf[32 * 1024];
int nonosub = REG_NOSUB == 0;
int nonexec = 0;
unsigned long test = 0;
static char* filter[] = { "-", 0 };
state.NOMATCH.rm_so = state.NOMATCH.rm_eo = -2;
p = unit;
version = (char*)id + 10;
while (p < &unit[sizeof(unit)-1] && (*p = *version++) && !isspace(*p))
p++;
*p = 0;
while ((p = *++argv) && *p == '-')
for (;;)
{
switch (*++p)
{
case 0:
break;
case 'c':
test |= TEST_CATCH;
continue;
case 'e':
test |= TEST_IGNORE_ERROR;
continue;
case 'h':
case '?':
help(0);
return 2;
case '-':
help(p[1] == 'h');
return 2;
case 'n':
nonexec = 1;
continue;
case 'o':
test |= TEST_IGNORE_OVER;
continue;
case 'p':
test |= TEST_IGNORE_POSITION;
continue;
case 's':
#ifdef REG_DISCIPLINE
if (!(state.stack = stkalloc(stkstd, 0)))
fprintf(stderr, "%s: out of space [stack]", unit);
state.disc.disc.re_resizef = resizef;
state.disc.disc.re_resizehandle = (void*)stkstd;
#endif
continue;
case 'x':
nonosub = 1;
continue;
case 'v':
test |= TEST_VERBOSE;
continue;
case 'A':
test |= TEST_ACTUAL;
continue;
case 'B':
test |= TEST_BASELINE;
continue;
case 'F':
test |= TEST_FAIL;
continue;
case 'P':
test |= TEST_PASS;
continue;
case 'S':
test |= TEST_SUMMARY;
continue;
default:
fprintf(stderr, "%s: %c: invalid option\n", unit, *p);
return 2;
}
break;
}
if (!*argv)
argv = filter;
locale = 0;
while (state.file = *argv++)
{
if (streq(state.file, "-") || streq(state.file, "/dev/stdin") || streq(state.file, "/dev/fd/0"))
{
state.file = 0;
fp = stdin;
}
else if (!(fp = fopen(state.file, "r")))
{
fprintf(stderr, "%s: %s: cannot read\n", unit, state.file);
return 2;
}
testno = state.errors = state.ignored = state.lineno = state.passed =
state.signals = state.unspecified = state.warnings = 0;
skip = 0;
level = 1;
if (!(test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_SUMMARY)))
{
printf("TEST\t%s ", unit);
if (s = state.file)
{
subunit = p = 0;
for (;;)
{
switch (*s++)
{
case 0:
break;
case '/':
subunit = s;
continue;
case '.':
p = s - 1;
continue;
default:
continue;
}
break;
}
if (!subunit)
subunit = state.file;
if (p < subunit)
p = s - 1;
subunitlen = p - subunit;
printf("%-.*s ", subunitlen, subunit);
}
else
subunit = 0;
for (s = version; *s && (*s != ' ' || *(s + 1) != '$'); s++)
putchar(*s);
if (test & TEST_CATCH)
printf(", catch");
if (test & TEST_IGNORE_ERROR)
printf(", ignore error code mismatches");
if (test & TEST_IGNORE_POSITION)
printf(", ignore negative position mismatches");
#ifdef REG_DISCIPLINE
if (state.stack)
printf(", stack");
#endif
if (test & TEST_VERBOSE)
printf(", verbose");
printf("\n");
#ifdef REG_VERSIONID
if (regerror(REG_VERSIONID, NiL, pat, sizeof(pat)) > 0)
s = pat;
else
#endif
#ifdef REG_TEST_VERSION
s = REG_TEST_VERSION;
#else
s = "regex";
#endif
printf("NOTE\t%s\n", s);
if (elementsof(unsupported) > 1)
{
#if (REG_TEST_DEFAULT & (REG_AUGMENTED|REG_EXTENDED|REG_SHELL)) || !defined(REG_EXTENDED)
i = 0;
#else
i = REG_EXTENDED != 0;
#endif
for (got = 0; i < elementsof(unsupported) - 1; i++)
{
if (!got)
{
got = 1;
printf("NOTE\tunsupported: %s", unsupported[i]);
}
else
printf(",%s", unsupported[i]);
}
if (got)
printf("\n");
}
}
#ifdef REG_DISCIPLINE
state.disc.disc.re_version = REG_VERSION;
state.disc.disc.re_compf = compf;
state.disc.disc.re_execf = execf;
if (!(state.disc.sp = sfstropen()))
bad("out of space [discipline string stream]\n", NiL, NiL, 0, 0);
preg.re_disc = &state.disc.disc;
#endif
if (test & TEST_CATCH)
{
signal(SIGALRM, gotcha);
signal(SIGBUS, gotcha);
signal(SIGSEGV, gotcha);
}
while (p = getline(fp))
{
/* parse: */
line = p;
if (*p == ':' && !isspace(*(p + 1)))
{
while (*++p && *p != ':');
if (!*p++)
{
if (test & TEST_BASELINE)
printf("%s\n", line);
continue;
}
}
while (isspace(*p))
p++;
if (*p == 0 || *p == '#' || *p == 'T')
{
if (test & TEST_BASELINE)
printf("%s\n", line);
continue;
}
if (*p == ':' || *p == 'N')
{
if (test & TEST_BASELINE)
printf("%s\n", line);
else if (!(test & (TEST_ACTUAL|TEST_FAIL|TEST_PASS|TEST_SUMMARY)))
{
while (*++p && !isspace(*p));
while (isspace(*p))
p++;
printf("NOTE %s\n", p);
}
continue;
}
j = 0;
i = 0;
field[i++] = p;
for (;;)
{
switch (*p++)
{
case 0:
p--;
j = 0;
goto checkfield;
case '\t':
*(delim[i] = p - 1) = 0;
j = 1;
checkfield:
s = field[i - 1];
if (streq(s, "NIL"))
field[i - 1] = 0;
else if (streq(s, "NULL"))
*s = 0;
while (*p == '\t')
{
p++;
j++;
}
tabs[i - 1] = j;
if (!*p)
break;
if (i >= elementsof(field))
bad("too many fields\n", NiL, NiL, 0, 0);
field[i++] = p;
/*FALLTHROUGH*/
default:
continue;
}
break;
}
if (!(spec = field[0]))
bad("NIL spec\n", NiL, NiL, 0, 0);
/* interpret: */
cflags = REG_TEST_DEFAULT;
eflags = REG_EXEC_DEFAULT;
test &= TEST_GLOBAL;
state.extracted = 0;
nmatch = 20;
nsub = -1;
for (p = spec; *p; p++)
{
if (isdigit(*p))
{
nmatch = strtol(p, &p, 10);
if (nmatch >= elementsof(match))
bad("nmatch must be < 100\n", NiL, NiL, 0, 0);
p--;
continue;
}
switch (*p)
{
case 'A':
test |= TEST_ARE;
continue;
case 'B':
test |= TEST_BRE;
continue;
case 'C':
if (!(test & TEST_QUERY) && !(skip & level))
bad("locale must be nested\n", NiL, NiL, 0, 0);
test &= ~TEST_QUERY;
if (locale)
bad("locale nesting not supported\n", NiL, NiL, 0, 0);
if (i != 2)
bad("locale field expected\n", NiL, NiL, 0, 0);
if (!(skip & level))
{
#if defined(LC_COLLATE) && defined(LC_CTYPE)
s = field[1];
if (!s || streq(s, "POSIX"))
s = "C";
if ((ans = setlocale(LC_COLLATE, s)) && streq(ans, "POSIX"))
ans = "C";
if (!ans || !streq(ans, s) && streq(s, "C"))
ans = 0;
else if ((ans = setlocale(LC_CTYPE, s)) && streq(ans, "POSIX"))
ans = "C";
if (!ans || !streq(ans, s) && streq(s, "C"))
skip = note(level, s, skip, test);
else
{
if (!(test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_SUMMARY)))
printf("NOTE \"%s\" locale\n", s);
locale = level;
}
#else
skip = note(level, skip, test, "locales not supported");
#endif
}
cflags = NOTEST;
continue;
case 'E':
test |= TEST_ERE;
continue;
case 'K':
test |= TEST_KRE;
continue;
case 'L':
test |= TEST_LRE;
continue;
case 'S':
test |= TEST_SRE;
continue;
case 'a':
cflags |= REG_LEFT|REG_RIGHT;
continue;
case 'b':
eflags |= REG_NOTBOL;
continue;
case 'c':
cflags |= REG_COMMENT;
continue;
case 'd':
cflags |= REG_SHELL_DOT;
continue;
case 'e':
eflags |= REG_NOTEOL;
continue;
case 'f':
cflags |= REG_MULTIPLE;
continue;
case 'g':
cflags |= NOTEST;
continue;
case 'h':
cflags |= REG_MULTIREF;
continue;
case 'i':
cflags |= REG_ICASE;
continue;
case 'j':
cflags |= REG_SPAN;
continue;
case 'k':
cflags |= REG_ESCAPE;
continue;
case 'l':
cflags |= REG_LEFT;
continue;
case 'm':
cflags |= REG_MINIMAL;
continue;
case 'n':
cflags |= REG_NEWLINE;
continue;
case 'o':
cflags |= REG_SHELL_GROUP;
continue;
case 'p':
cflags |= REG_SHELL_PATH;
continue;
case 'q':
cflags |= REG_DELIMITED;
continue;
case 'r':
cflags |= REG_RIGHT;
continue;
case 's':
cflags |= REG_SHELL_ESCAPED;
continue;
case 't':
cflags |= REG_MUSTDELIM;
continue;
case 'u':
test |= TEST_UNSPECIFIED;
continue;
case 'v':
cflags |= REG_CLASS_ESCAPE;
continue;
case 'w':
cflags |= REG_NOSUB;
continue;
case 'x':
if (REG_LENIENT)
cflags |= REG_LENIENT;
else
test |= TEST_LENIENT;
continue;
case 'y':
eflags |= REG_LEFT;
continue;
case 'z':
cflags |= REG_NULL;
continue;
case '$':
test |= TEST_EXPAND;
continue;
case '/':
test |= TEST_SUB;
continue;
case '=':
test |= TEST_DECOMP;
continue;
case '?':
test |= TEST_VERIFY;
test &= ~(TEST_AND|TEST_OR);
state.verify = state.passed;
continue;
case '&':
test |= TEST_VERIFY|TEST_AND;
test &= ~TEST_OR;
continue;
case '|':
test |= TEST_VERIFY|TEST_OR;
test &= ~TEST_AND;
continue;
case ';':
test |= TEST_OR;
test &= ~TEST_AND;
continue;
case '{':
level <<= 1;
if (skip & (level >> 1))
{
skip |= level;
cflags = NOTEST;
}
else
{
skip &= ~level;
test |= TEST_QUERY;
}
continue;
case '}':
if (level == 1)
bad("invalid {...} nesting\n", NiL, NiL, 0, 0);
if ((skip & level) && !(skip & (level>>1)))
{
if (!(test & (TEST_BASELINE|TEST_SUMMARY)))
{
if (test & (TEST_ACTUAL|TEST_FAIL))
printf("}\n");
else if (!(test & TEST_PASS))
printf("-%d\n", state.lineno);
}
}
#if defined(LC_COLLATE) && defined(LC_CTYPE)
else if (locale & level)
{
locale = 0;
if (!(skip & level))
{
s = "C";
setlocale(LC_COLLATE, s);
setlocale(LC_CTYPE, s);
if (!(test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_SUMMARY)))
printf("NOTE \"%s\" locale\n", s);
else if (test & (TEST_ACTUAL|TEST_BASELINE|TEST_PASS))
printf("}\n");
}
else if (test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL))
printf("}\n");
}
#endif
level >>= 1;
cflags = NOTEST;
continue;
default:
bad("bad spec\n", spec, NiL, 0, test);
break;
}
break;
}
if ((cflags|eflags) == NOTEST || (skip & level) && (test & TEST_BASELINE))
{
if (test & TEST_BASELINE)
{
while (i > 1)
*delim[--i] = '\t';
printf("%s\n", line);
}
continue;
}
if (test & TEST_OR)
{
if (!(test & TEST_VERIFY))
{
test &= ~TEST_OR;
if (state.passed == state.verify && i > 1)
printf("NOTE\t%s\n", field[1]);
continue;
}
else if (state.passed > state.verify)
continue;
}
else if (test & TEST_AND)
{
if (state.passed == state.verify)
continue;
state.passed = state.verify;
}
if (i < ((test & TEST_DECOMP) ? 3 : 4))
bad("too few fields\n", NiL, NiL, 0, test);
while (i < elementsof(field))
field[i++] = 0;
if (re = field[1])
{
if (streq(re, "SAME"))
{
re = ppat;
test |= TEST_SAME;
}
else
{
if (test & TEST_EXPAND)
escape(re);
re = expand(re, patbuf);
strcpy(ppat = pat, re);
}
}
else
ppat = 0;
nstr = -1;
if (s = field[2])
{
s = expand(s, strbuf);
if (test & TEST_EXPAND)
{
nstr = escape(s);
#if _REG_nexec
if (nstr != strlen(s))
nexec = nstr;
#endif
}
}
if (!(ans = field[(test & TEST_DECOMP) ? 2 : 3]))
bad("NIL answer\n", NiL, NiL, 0, test);
msg = field[4];
fflush(stdout);
if (test & TEST_SUB)
#if _REG_subcomp
cflags |= REG_DELIMITED;
#else
continue;
#endif
#if !_REG_decomp
if (test & TEST_DECOMP)
continue;
#endif
compile:
if (state.extracted || (skip & level))
continue;
#if !(REG_TEST_DEFAULT & (REG_AUGMENTED|REG_EXTENDED|REG_SHELL))
#ifdef REG_EXTENDED
if (REG_EXTENDED != 0 && (test & TEST_BRE))
#else
if (test & TEST_BRE)
#endif
{
test &= ~TEST_BRE;
flags = cflags;
state.which = "BRE";
}
else
#endif
#ifdef REG_EXTENDED
if (test & TEST_ERE)
{
test &= ~TEST_ERE;
flags = cflags | REG_EXTENDED;
state.which = "ERE";
}
else
#endif
#ifdef REG_AUGMENTED
if (test & TEST_ARE)
{
test &= ~TEST_ARE;
flags = cflags | REG_AUGMENTED;
state.which = "ARE";
}
else
#endif
#ifdef REG_LITERAL
if (test & TEST_LRE)
{
test &= ~TEST_LRE;
flags = cflags | REG_LITERAL;
state.which = "LRE";
}
else
#endif
#ifdef REG_SHELL
if (test & TEST_SRE)
{
test &= ~TEST_SRE;
flags = cflags | REG_SHELL;
state.which = "SRE";
}
else
#ifdef REG_AUGMENTED
if (test & TEST_KRE)
{
test &= ~TEST_KRE;
flags = cflags | REG_SHELL | REG_AUGMENTED;
state.which = "KRE";
}
else
#endif
#endif
{
if (test & (TEST_BASELINE|TEST_PASS|TEST_VERIFY))
extract(tabs, line, re, s, ans, msg, NiL, NiL, 0, 0, skip, level, test|TEST_OK);
continue;
}
if ((test & (TEST_QUERY|TEST_VERBOSE|TEST_VERIFY)) == TEST_VERBOSE)
{
printf("test %-3d %s ", state.lineno, state.which);
quote(re, -1, test|TEST_DELIMIT);
printf(" ");
quote(s, nstr, test|TEST_DELIMIT);
printf("\n");
}
nosub:
fun = "regcomp";
#if _REG_nexec
if (nstr >= 0 && nstr != strlen(s))
nexec = nstr;
else
#endif
nexec = -1;
if (state.extracted || (skip & level))
continue;
if (!(test & TEST_QUERY))
testno++;
#ifdef REG_DISCIPLINE
if (state.stack)
stkset(stkstd, state.stack, 0);
flags |= REG_DISCIPLINE;
state.disc.ordinal = 0;
sfstrseek(state.disc.sp, 0, SEEK_SET);
#endif
if (!(test & TEST_CATCH))
cret = regcomp(&preg, re, flags);
else if (!(cret = setjmp(state.gotcha)))
{
alarm(HUNG);
cret = regcomp(&preg, re, flags);
alarm(0);
}
#if _REG_subcomp
if (!cret && (test & TEST_SUB))
{
fun = "regsubcomp";
p = re + preg.re_npat;
if (!(test & TEST_CATCH))
cret = regsubcomp(&preg, p, NiL, 0, 0);
else if (!(cret = setjmp(state.gotcha)))
{
alarm(HUNG);
cret = regsubcomp(&preg, p, NiL, 0, 0);
alarm(0);
}
if (!cret && *(p += preg.re_npat) && !(preg.re_sub->re_flags & REG_SUB_LAST))
{
if (catchfree(&preg, flags, tabs, line, re, s, ans, msg, NiL, NiL, 0, 0, skip, level, test))
continue;
cret = REG_EFLAGS;
}
}
#endif
#if _REG_decomp
if (!cret && (test & TEST_DECOMP))
{
char buf[128];
if ((j = nmatch) > sizeof(buf))
j = sizeof(buf);
fun = "regdecomp";
p = re + preg.re_npat;
if (!(test & TEST_CATCH))
i = regdecomp(&preg, -1, buf, j);
else if (!(cret = setjmp(state.gotcha)))
{
alarm(HUNG);
i = regdecomp(&preg, -1, buf, j);
alarm(0);
}
if (!cret)
{
catchfree(&preg, flags, tabs, line, re, s, ans, msg, NiL, NiL, 0, 0, skip, level, test);
if (i > j)
{
if (i != (strlen(ans) + 1))
{
report("failed", fun, re, s, nstr, msg, flags, test);
printf(" %d byte buffer supplied, %d byte buffer required\n", j, i);
}
}
else if (strcmp(buf, ans))
{
report("failed", fun, re, s, nstr, msg, flags, test);
quote(ans, -1, test|TEST_DELIMIT);
printf(" expected, ");
quote(buf, -1, test|TEST_DELIMIT);
printf(" returned\n");
}
continue;
}
}
#endif
if (!cret)
{
if (!(flags & REG_NOSUB) && nsub < 0 && *ans == '(')
{
for (p = ans; *p; p++)
if (*p == '(')
nsub++;
else if (*p == '{')
nsub--;
if (nsub >= 0)
{
if (test & TEST_IGNORE_OVER)
{
if (nmatch > nsub)
nmatch = nsub + 1;
}
else if (nsub != preg.re_nsub)
{
if (nsub > preg.re_nsub)
{
if (test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_QUERY|TEST_SUMMARY|TEST_VERIFY))
skip = extract(tabs, line, re, s, ans, msg, "OK", NiL, 0, 0, skip, level, test|TEST_DELIMIT);
else
{
report("re_nsub incorrect", fun, re, NiL, -1, msg, flags, test);
printf("at least %d expected, %d returned\n", nsub, preg.re_nsub);
state.errors++;
}
}
else
nsub = preg.re_nsub;
}
}
}
if (!(test & (TEST_DECOMP|TEST_SUB)) && *ans && *ans != '(' && !streq(ans, "OK") && !streq(ans, "NOMATCH"))
{
if (test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_QUERY|TEST_SUMMARY|TEST_VERIFY))
skip = extract(tabs, line, re, s, ans, msg, "OK", NiL, 0, 0, skip, level, test|TEST_DELIMIT);
else if (!(test & TEST_LENIENT))
{
report("failed", fun, re, NiL, -1, msg, flags, test);
printf("%s expected, OK returned\n", ans);
}
catchfree(&preg, flags, tabs, line, re, s, ans, msg, NiL, NiL, 0, 0, skip, level, test);
continue;
}
}
else
{
if (test & TEST_LENIENT)
/* we'll let it go this time */;
else if (!*ans || ans[0]=='(' || cret == REG_BADPAT && streq(ans, "NOMATCH"))
{
got = 0;
for (i = 1; i < elementsof(codes); i++)
if (cret==codes[i].code)
got = i;
if (test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_QUERY|TEST_SUMMARY|TEST_VERIFY))
skip = extract(tabs, line, re, s, ans, msg, codes[got].name, NiL, 0, 0, skip, level, test|TEST_DELIMIT);
else
{
report("failed", fun, re, NiL, -1, msg, flags, test);
printf("%s returned: ", codes[got].name);
error(&preg, cret);
}
}
else
{
expected = got = 0;
for (i = 1; i < elementsof(codes); i++)
{
if (streq(ans, codes[i].name))
expected = i;
if (cret==codes[i].code)
got = i;
}
if (!expected)
{
if (test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_QUERY|TEST_SUMMARY|TEST_VERIFY))
skip = extract(tabs, line, re, s, ans, msg, codes[got].name, NiL, 0, 0, skip, level, test|TEST_DELIMIT);
else
{
report("failed: invalid error code", NiL, re, NiL, -1, msg, flags, test);
printf("%s expected, %s returned\n", ans, codes[got].name);
}
}
else if (cret != codes[expected].code && cret != REG_BADPAT)
{
if (test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_QUERY|TEST_SUMMARY|TEST_VERIFY))
skip = extract(tabs, line, re, s, ans, msg, codes[got].name, NiL, 0, 0, skip, level, test|TEST_DELIMIT);
else if (test & TEST_IGNORE_ERROR)
state.ignored++;
else
{
report("should fail and did", fun, re, NiL, -1, msg, flags, test);
printf("%s expected, %s returned: ", ans, codes[got].name);
state.errors--;
state.warnings++;
error(&preg, cret);
}
}
}
goto compile;
}
#if _REG_nexec
execute:
if (nexec >= 0)
fun = "regnexec";
else
#endif
fun = "regexec";
for (i = 0; i < elementsof(match); i++)
match[i] = state.NOMATCH;
#if _REG_nexec
if (nexec >= 0)
{
eret = regnexec(&preg, s, nexec, nmatch, match, eflags);
s[nexec] = 0;
}
else
#endif
{
if (!(test & TEST_CATCH))
eret = regexec(&preg, s, nmatch, match, eflags);
else if (!(eret = setjmp(state.gotcha)))
{
alarm(HUNG);
eret = regexec(&preg, s, nmatch, match, eflags);
alarm(0);
}
}
#if _REG_subcomp
if ((test & TEST_SUB) && !eret)
{
fun = "regsubexec";
if (!(test & TEST_CATCH))
eret = regsubexec(&preg, s, nmatch, match);
else if (!(eret = setjmp(state.gotcha)))
{
alarm(HUNG);
eret = regsubexec(&preg, s, nmatch, match);
alarm(0);
}
}
#endif
if (flags & REG_NOSUB)
{
if (eret)
{
if (eret != REG_NOMATCH || !streq(ans, "NOMATCH"))
{
if (test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_QUERY|TEST_SUMMARY|TEST_VERIFY))
skip = extract(tabs, line, re, s, ans, msg, "NOMATCH", NiL, 0, 0, skip, level, test|TEST_DELIMIT);
else
{
report("REG_NOSUB failed", fun, re, s, nstr, msg, flags, test);
error(&preg, eret);
}
}
}
else if (streq(ans, "NOMATCH"))
{
if (test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_QUERY|TEST_SUMMARY|TEST_VERIFY))
skip = extract(tabs, line, re, s, ans, msg, NiL, match, nmatch, nsub, skip, level, test|TEST_DELIMIT);
else
{
report("should fail and didn't", fun, re, s, nstr, msg, flags, test);
error(&preg, eret);
}
}
}
else if (eret)
{
if (eret != REG_NOMATCH || !streq(ans, "NOMATCH"))
{
if (test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_QUERY|TEST_SUMMARY|TEST_VERIFY))
skip = extract(tabs, line, re, s, ans, msg, "NOMATCH", NiL, 0, nsub, skip, level, test|TEST_DELIMIT);
else
{
report("failed", fun, re, s, nstr, msg, flags, test);
if (eret != REG_NOMATCH)
error(&preg, eret);
else if (*ans)
printf("expected: %s\n", ans);
else
printf("\n");
}
}
}
else if (streq(ans, "NOMATCH"))
{
if (test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_QUERY|TEST_SUMMARY|TEST_VERIFY))
skip = extract(tabs, line, re, s, ans, msg, NiL, match, nmatch, nsub, skip, level, test|TEST_DELIMIT);
else
{
report("should fail and didn't", fun, re, s, nstr, msg, flags, test);
matchprint(match, nmatch, nsub, NiL, test);
}
}
#if _REG_subcomp
else if (test & TEST_SUB)
{
p = preg.re_sub->re_buf;
if (strcmp(p, ans))
{
report("failed", fun, re, s, nstr, msg, flags, test);
quote(ans, -1, test|TEST_DELIMIT);
printf(" expected, ");
quote(p, -1, test|TEST_DELIMIT);
printf(" returned\n");
}
}
#endif
else if (!*ans)
{
if (match[0].rm_so != state.NOMATCH.rm_so)
{
if (test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_QUERY|TEST_SUMMARY|TEST_VERIFY))
skip = extract(tabs, line, re, s, ans, msg, NiL, NiL, 0, 0, skip, level, test);
else
{
report("failed: no match but match array assigned", NiL, re, s, nstr, msg, flags, test);
matchprint(match, nmatch, nsub, NiL, test);
}
}
}
else if (matchcheck(match, nmatch, nsub, ans, re, s, nstr, flags, test))
{
#if _REG_nexec
if (nexec < 0 && !nonexec)
{
nexec = nstr >= 0 ? nstr : strlen(s);
s[nexec] = '\n';
testno++;
goto execute;
}
#endif
if (!(test & (TEST_DECOMP|TEST_SUB|TEST_VERIFY)) && !nonosub)
{
if (catchfree(&preg, flags, tabs, line, re, s, ans, msg, NiL, NiL, 0, 0, skip, level, test))
continue;
flags |= REG_NOSUB;
goto nosub;
}
if (test & (TEST_BASELINE|TEST_PASS|TEST_VERIFY))
skip = extract(tabs, line, re, s, ans, msg, NiL, match, nmatch, nsub, skip, level, test|TEST_OK);
}
else if (test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_QUERY|TEST_SUMMARY|TEST_VERIFY))
skip = extract(tabs, line, re, s, ans, msg, NiL, match, nmatch, nsub, skip, level, test|TEST_DELIMIT);
if (catchfree(&preg, flags, tabs, line, re, s, ans, msg, NiL, NiL, 0, 0, skip, level, test))
continue;
goto compile;
}
if (test & TEST_SUMMARY)
printf("tests=%-4d errors=%-4d warnings=%-2d ignored=%-2d unspecified=%-2d signals=%d\n", testno, state.errors, state.warnings, state.ignored, state.unspecified, state.signals);
else if (!(test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS)))
{
printf("TEST\t%s", unit);
if (subunit)
printf(" %-.*s", subunitlen, subunit);
printf(", %d test%s", testno, testno == 1 ? "" : "s");
if (state.ignored)
printf(", %d ignored mismatche%s", state.ignored, state.ignored == 1 ? "" : "s");
if (state.warnings)
printf(", %d warning%s", state.warnings, state.warnings == 1 ? "" : "s");
if (state.unspecified)
printf(", %d unspecified difference%s", state.unspecified, state.unspecified == 1 ? "" : "s");
if (state.signals)
printf(", %d signal%s", state.signals, state.signals == 1 ? "" : "s");
printf(", %d error%s\n", state.errors, state.errors == 1 ? "" : "s");
}
if (fp != stdin)
fclose(fp);
}
return 0;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment