aboutsummaryrefslogtreecommitdiff
path: root/gnu/lib/libregex/test
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/lib/libregex/test')
-rw-r--r--gnu/lib/libregex/test/ChangeLog77
-rw-r--r--gnu/lib/libregex/test/Makefile169
-rw-r--r--gnu/lib/libregex/test/Makefile.in168
-rw-r--r--gnu/lib/libregex/test/TAGS373
-rw-r--r--gnu/lib/libregex/test/alloca.c194
-rw-r--r--gnu/lib/libregex/test/bsd-interf.c38
-rw-r--r--gnu/lib/libregex/test/debugmalloc.c273
-rw-r--r--gnu/lib/libregex/test/emacsmalloc.c844
-rw-r--r--gnu/lib/libregex/test/fileregex.c77
-rw-r--r--gnu/lib/libregex/test/g++malloc.c1288
-rw-r--r--gnu/lib/libregex/test/getpagesize.h25
-rw-r--r--gnu/lib/libregex/test/iregex.c164
-rw-r--r--gnu/lib/libregex/test/main.c49
-rw-r--r--gnu/lib/libregex/test/malloc-test.c47
-rw-r--r--gnu/lib/libregex/test/other.c503
-rw-r--r--gnu/lib/libregex/test/printchar.c14
-rw-r--r--gnu/lib/libregex/test/psx-basic.c253
-rw-r--r--gnu/lib/libregex/test/psx-extend.c1244
-rw-r--r--gnu/lib/libregex/test/psx-generic.c336
-rw-r--r--gnu/lib/libregex/test/psx-group.c440
-rw-r--r--gnu/lib/libregex/test/psx-interf.c624
-rw-r--r--gnu/lib/libregex/test/psx-interv.c140
-rw-r--r--gnu/lib/libregex/test/regexcpp.sed8
-rw-r--r--gnu/lib/libregex/test/syntax.skel74
-rw-r--r--gnu/lib/libregex/test/test.c782
-rw-r--r--gnu/lib/libregex/test/test.h141
-rw-r--r--gnu/lib/libregex/test/tregress.c464
-rw-r--r--gnu/lib/libregex/test/upcase.c39
-rw-r--r--gnu/lib/libregex/test/xmalloc.c21
29 files changed, 8869 insertions, 0 deletions
diff --git a/gnu/lib/libregex/test/ChangeLog b/gnu/lib/libregex/test/ChangeLog
new file mode 100644
index 000000000000..f0265bb26a6a
--- /dev/null
+++ b/gnu/lib/libregex/test/ChangeLog
@@ -0,0 +1,77 @@
+Thu Mar 25 21:23:43 1993 Jim Blandy (jimb@totoro.cs.oberlin.edu)
+
+ * debugmalloc.c: #include <string.h>, and remove declaration of
+ memcpy.
+
+Sun Dec 13 20:59:32 1992 Jim Blandy (jimb@totoro.cs.oberlin.edu)
+
+ * tregress.c (test_regress): Add regression test for matching
+ "[a-a]" against "a" with the upcase translation map.
+
+ * iregex.c (print_regs): Don't print a newline after the register
+ contents.
+ (main): Instead, write out newlines here after printing match and
+ search results; this way, we get a newline whether or not the
+ pattern matched.
+
+Fri Dec 11 03:30:50 1992 Jim Blandy (jimb@totoro.cs.oberlin.edu)
+
+ * tregress.c (test_regress): Add new test to catch bug fixed by
+ change to regex.c today.
+
+ * Makefile.in (dregex.o): Depend on `../regex.[ch]', not `regex.[ch]'.
+
+Sun Nov 15 07:51:40 1992 Karl Berry (karl@cs.umb.edu)
+
+ * debugmalloc.c (memcpy): Declare; also, include <assert.h>.
+
+ * psx-interf.c (fill_pmatch): Declare offsets as `regoff_t'
+ instead of `off_t'.
+
+Thu Nov 12 11:29:58 1992 Karl Berry (karl@cs.umb.edu)
+
+ * iregex.c (main): Remove unused variable `c'; initialize
+ the char array in C code; only call print_regs if the match and
+ search succeeded.
+ (strlen): Declare.
+
+ * tregress.c (test_regress): Bug from enami.
+
+Tue Nov 10 10:36:53 1992 Karl Berry (karl@cs.umb.edu)
+
+ * tregress.c (test_regress): Remove Emacs 19 diff bug from rms, as
+ it was never the right thing to test anyway, and the test itself
+ had bugs in it.
+
+Mon Nov 9 10:09:40 1992 Karl Berry (karl@cs.umb.edu)
+
+ * tregress.c (test_regress): Bug from meyering.
+
+Thu Sep 24 10:48:34 1992 Karl Berry (karl@cs.umb.edu)
+
+ * Makefile.in: avoid $< (except in implicit rule).
+
+Sat Sep 19 15:38:29 1992 Karl Berry (karl@hayley)
+
+ * Makefile.in (TAGS): include regex.c and regex.h.
+
+Wed Sep 16 09:29:27 1992 Karl Berry (karl@hayley)
+
+ * xmalloc.c (xmalloc): use char *, not void *, as some compilers
+ bomb out on the latter.
+
+ * Makefile.in (LOADLIBES): use LIBS instead, as that what's
+ Autoconf wants to define.
+
+ * other.c: remove tests for ^/$ around newlines.
+
+Tue Sep 15 11:01:15 1992 Karl Berry (karl@hayley)
+
+ * fileregex.c (main): call re_search_2 instead of re_search.
+
+ * Makefile.in (regex.o): make target dregex.o, so VPATH doesn't
+ find ../regex.o.
+
+Sun Sep 13 06:50:03 1992 Karl Berry (karl@hayley)
+
+ * Created.
diff --git a/gnu/lib/libregex/test/Makefile b/gnu/lib/libregex/test/Makefile
new file mode 100644
index 000000000000..5a8656a76e9a
--- /dev/null
+++ b/gnu/lib/libregex/test/Makefile
@@ -0,0 +1,169 @@
+# Generated automatically from Makefile.in by configure.
+# Makefile for regex testing.
+#
+# Copyright (C) 1992 Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+CPPFLAGS =
+CFLAGS = -g
+LDFLAGS =
+
+srcdir = .
+VPATH = .:../.
+
+CC = gcc
+DEFS = -DHAVE_STRING_H=1
+LIBS = $(LOADLIBES)
+
+ETAGS = etags
+SHELL = /bin/sh
+
+debug = -DDEBUG
+ALL_CPPFLAGS = -I. -I$(srcdir) -I../$(srcdir) $(DEFS) $(CPPFLAGS) $(debug)
+
+.c.o:
+ $(CC) $(ALL_CPPFLAGS) $(CFLAGS) -c $<
+
+
+# Define this as `../regex.o' to get the optimized version.
+regex_o = dregex.o
+test_h = test.h
+test_o = test.o bsd-interf.o other.o tregress.o psx-basic.o psx-extend.o \
+ psx-generic.o psx-group.o psx-interf.o psx-interv.o
+common_o = printchar.o upcase.o xmalloc.o $(malloc)
+
+# We have a lot of mallocs we can try when we run afoul of strange bugs.
+malloc =
+#malloc = # the libc malloc
+#malloc = g++malloc.o
+#malloc = debugmalloc.o
+#malloc = emacsmalloc.o
+emacsmallocflags = -Drcheck -Dbotch=abort -DUSG
+
+# default is to do nothing.
+default:
+
+all: regex syntax
+
+regex: $(regex_o) $(common_o) $(test_o) main.o
+ $(CC) -o $@ $(LDFLAGS) $^ $(LIBS)
+
+# As long as we're doing tests, we enable debugging.
+dregex.o: ../regex.c ../regex.h
+ rm -f $@
+ $(CC) $(ALL_CPPFLAGS) $(CFLAGS) -c ../$(srcdir)/regex.c
+ mv regex.o $@
+
+# iregex is the interactive regex.
+iregex: $(common_o) $(regex_o) iregex.o
+ $(CC) -o $@ $(LDFLAGS) $^ $(LIBS)
+
+# fileregex searches for an r.e. in every line of a given file.
+fileregex_o = fileregex.o printchar.o $(regex_o)
+fileregex: $(fileregex_o)
+ $(CC) -o $@ $(LDFLAGS) $(fileregex_o) $(LIBS)
+
+# cppregex is regex with a preprocessed regex.c. Useful when the
+# problem is inside some macro.
+cppregex: regexcpp.o $(common_o) $(test_o) main.o
+ $(CC) -o $@ $(LDFLAGS) $^ $(LIBS)
+
+regexcpp.o: regexcpp.c
+
+regexcpp.c: regex.c regexcpp.sed
+ rm -f regexcpp.c
+ $(CC) -E $(ALL_CPPFLAGS) ../$(srcdir)/regex.c \
+ | egrep -v '^#|^ *$$' \
+ | sed -f regexcpp.sed \
+ > regexcpp.c
+ chmod a-w regexcpp.c
+
+# Have to give this malloc special flags.
+emacsmalloc.o: emacsmalloc.c
+ $(CC) -c $(CFLAGS) $(ALL_CPPFLAGS) $(emacsmallocflags) \
+ ../$(srcdir)/test/emacsmalloc.c
+
+syntax: syntax.o
+ $(CC) $(CFLAGS) -o $@ syntax.o
+
+syntax.c: syntax.skel bits
+ sed '/\[\[\[replace.*\]\]\]/r bits' syntax.skel > $@
+
+bits: regex.h
+ sed -n 1,/RE_SYNTAX_EMACS/p ../$(srcdir)/regex.h \
+ | grep "#define RE_.*1" \
+ | sed 's/^#define \(RE_[A-Z_]*\) .*/ TEST_BIT (\1);/' > $@
+
+check: regex
+ ./regex
+
+TAGS: regex.c regex.h *.h *.c
+ $(ETAGS) -t $^
+
+depend:
+ gcc -MM $(ALL_CPPFLAGS) *.c > /tmp/depend
+.PHONY: depend
+
+install:
+.PHONY: install
+
+clean mostlyclean:
+ rm -f *.o regex cppregex iregex fileregex regexcpp.c syntax
+
+distclean: clean
+ rm -f bits syntax.c Makefile
+
+extraclean: distclean
+ rm -f *~* *\#* patch* *.orig *.rej *.bak core a.out
+
+realclean: distclean
+ rm -f TAGS
+
+Makefile: Makefile.in ../config.status
+ (cd ..; sh config.status)
+
+# Prevent GNU make 3 from overflowing arg limit on system V.
+.NOEXPORT:
+
+# Assumes $(distdir) is the place to put our files.
+distfiles = ChangeLog TAGS *.in *.c *.h regexcpp.sed syntax.skel
+dist: Makefile TAGS
+ mkdir $(distdir)
+ ln $(distfiles) $(distdir)
+
+# Automatically-generated dependencies below here.
+alloca.o : alloca.c
+bsd-interf.o : bsd-interf.c
+debugmalloc.o : debugmalloc.c
+emacsmalloc.o : emacsmalloc.c getpagesize.h
+fileregex.o : fileregex.c .././regex.h
+g++malloc.o : g++malloc.c //usr/include/stdio.h getpagesize.h
+iregex.o : iregex.c .././regex.h
+main.o : main.c test.h .././regex.h
+malloc-test.o : malloc-test.c
+other.o : other.c test.h .././regex.h
+printchar.o : printchar.c
+psx-basic.o : psx-basic.c test.h .././regex.h
+psx-extend.o : psx-extend.c test.h .././regex.h
+psx-generic.o : psx-generic.c test.h .././regex.h
+psx-group.o : psx-group.c test.h .././regex.h
+psx-interf.o : psx-interf.c test.h .././regex.h
+psx-interv.o : psx-interv.c test.h .././regex.h
+syntax.o : syntax.c .././regex.h
+test.o : test.c test.h .././regex.h
+tregress.o : tregress.c test.h .././regex.h
+upcase.o : upcase.c
+xmalloc.o : xmalloc.c
diff --git a/gnu/lib/libregex/test/Makefile.in b/gnu/lib/libregex/test/Makefile.in
new file mode 100644
index 000000000000..b6a413384f08
--- /dev/null
+++ b/gnu/lib/libregex/test/Makefile.in
@@ -0,0 +1,168 @@
+# Makefile for regex testing.
+#
+# Copyright (C) 1992 Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+CPPFLAGS =
+CFLAGS = -g
+LDFLAGS =
+
+srcdir = @srcdir@
+VPATH = @srcdir@:../@srcdir@
+
+CC = @CC@
+DEFS = @DEFS@
+LIBS = @LIBS@ $(LOADLIBES)
+
+ETAGS = etags
+SHELL = /bin/sh
+
+debug = -DDEBUG
+ALL_CPPFLAGS = -I. -I$(srcdir) -I../$(srcdir) $(DEFS) $(CPPFLAGS) $(debug)
+
+.c.o:
+ $(CC) $(ALL_CPPFLAGS) $(CFLAGS) -c $<
+
+
+# Define this as `../regex.o' to get the optimized version.
+regex_o = dregex.o
+test_h = test.h
+test_o = test.o bsd-interf.o other.o tregress.o psx-basic.o psx-extend.o \
+ psx-generic.o psx-group.o psx-interf.o psx-interv.o
+common_o = printchar.o upcase.o xmalloc.o $(malloc)
+
+# We have a lot of mallocs we can try when we run afoul of strange bugs.
+malloc = @ALLOCA@
+#malloc = # the libc malloc
+#malloc = g++malloc.o
+#malloc = debugmalloc.o
+#malloc = emacsmalloc.o
+emacsmallocflags = -Drcheck -Dbotch=abort -DUSG
+
+# default is to do nothing.
+default:
+
+all: regex syntax
+
+regex: $(regex_o) $(common_o) $(test_o) main.o
+ $(CC) -o $@ $(LDFLAGS) $^ $(LIBS)
+
+# As long as we're doing tests, we enable debugging.
+dregex.o: ../regex.c ../regex.h
+ rm -f $@
+ $(CC) $(ALL_CPPFLAGS) $(CFLAGS) -c ../$(srcdir)/regex.c
+ mv regex.o $@
+
+# iregex is the interactive regex.
+iregex: $(common_o) $(regex_o) iregex.o
+ $(CC) -o $@ $(LDFLAGS) $^ $(LIBS)
+
+# fileregex searches for an r.e. in every line of a given file.
+fileregex_o = fileregex.o printchar.o $(regex_o)
+fileregex: $(fileregex_o)
+ $(CC) -o $@ $(LDFLAGS) $(fileregex_o) $(LIBS)
+
+# cppregex is regex with a preprocessed regex.c. Useful when the
+# problem is inside some macro.
+cppregex: regexcpp.o $(common_o) $(test_o) main.o
+ $(CC) -o $@ $(LDFLAGS) $^ $(LIBS)
+
+regexcpp.o: regexcpp.c
+
+regexcpp.c: regex.c regexcpp.sed
+ rm -f regexcpp.c
+ $(CC) -E $(ALL_CPPFLAGS) ../$(srcdir)/regex.c \
+ | egrep -v '^#|^ *$$' \
+ | sed -f regexcpp.sed \
+ > regexcpp.c
+ chmod a-w regexcpp.c
+
+# Have to give this malloc special flags.
+emacsmalloc.o: emacsmalloc.c
+ $(CC) -c $(CFLAGS) $(ALL_CPPFLAGS) $(emacsmallocflags) \
+ ../$(srcdir)/test/emacsmalloc.c
+
+syntax: syntax.o
+ $(CC) $(CFLAGS) -o $@ syntax.o
+
+syntax.c: syntax.skel bits
+ sed '/\[\[\[replace.*\]\]\]/r bits' syntax.skel > $@
+
+bits: regex.h
+ sed -n 1,/RE_SYNTAX_EMACS/p ../$(srcdir)/regex.h \
+ | grep "#define RE_.*1" \
+ | sed 's/^#define \(RE_[A-Z_]*\) .*/ TEST_BIT (\1);/' > $@
+
+check: regex
+ ./regex
+
+TAGS: regex.c regex.h *.h *.c
+ $(ETAGS) -t $^
+
+depend:
+ gcc -MM $(ALL_CPPFLAGS) *.c > /tmp/depend
+.PHONY: depend
+
+install:
+.PHONY: install
+
+clean mostlyclean:
+ rm -f *.o regex cppregex iregex fileregex regexcpp.c syntax
+
+distclean: clean
+ rm -f bits syntax.c Makefile
+
+extraclean: distclean
+ rm -f *~* *\#* patch* *.orig *.rej *.bak core a.out
+
+realclean: distclean
+ rm -f TAGS
+
+Makefile: Makefile.in ../config.status
+ (cd ..; sh config.status)
+
+# Prevent GNU make 3 from overflowing arg limit on system V.
+.NOEXPORT:
+
+# Assumes $(distdir) is the place to put our files.
+distfiles = ChangeLog TAGS *.in *.c *.h regexcpp.sed syntax.skel
+dist: Makefile TAGS
+ mkdir $(distdir)
+ ln $(distfiles) $(distdir)
+
+# Automatically-generated dependencies below here.
+alloca.o : alloca.c
+bsd-interf.o : bsd-interf.c
+debugmalloc.o : debugmalloc.c
+emacsmalloc.o : emacsmalloc.c getpagesize.h
+fileregex.o : fileregex.c .././regex.h
+g++malloc.o : g++malloc.c //usr/include/stdio.h getpagesize.h
+iregex.o : iregex.c .././regex.h
+main.o : main.c test.h .././regex.h
+malloc-test.o : malloc-test.c
+other.o : other.c test.h .././regex.h
+printchar.o : printchar.c
+psx-basic.o : psx-basic.c test.h .././regex.h
+psx-extend.o : psx-extend.c test.h .././regex.h
+psx-generic.o : psx-generic.c test.h .././regex.h
+psx-group.o : psx-group.c test.h .././regex.h
+psx-interf.o : psx-interf.c test.h .././regex.h
+psx-interv.o : psx-interv.c test.h .././regex.h
+syntax.o : syntax.c .././regex.h
+test.o : test.c test.h .././regex.h
+tregress.o : tregress.c test.h .././regex.h
+upcase.o : upcase.c
+xmalloc.o : xmalloc.c
diff --git a/gnu/lib/libregex/test/TAGS b/gnu/lib/libregex/test/TAGS
new file mode 100644
index 000000000000..d3aad750dcba
--- /dev/null
+++ b/gnu/lib/libregex/test/TAGS
@@ -0,0 +1,373 @@
+
+.././regex.c,4137
+#define AT_STRINGS_BEG(3078,98376
+#define AT_STRINGS_END(3079,98449
+#define AT_WORD_BOUNDARY(3093,99002
+#define BUF_PUSH(887,24995
+#define BUF_PUSH_2(895,25208
+#define BUF_PUSH_3(904,25437
+#define DEBUG_POP(2336,74614
+#define DEBUG_PRINT1(471,14296
+#define DEBUG_PRINT1(785,21263
+#define DEBUG_PRINT2(472,14342
+#define DEBUG_PRINT3(473,14398
+#define DEBUG_PRINT3(787,21316
+#define DEBUG_PRINT4(474,14462
+#define DEBUG_PRINT_COMPILED_PATTERN(475,14534
+#define DEBUG_PRINT_COMPILED_PATTERN(789,21386
+#define DEBUG_PRINT_DOUBLE_STRING(477,14637
+#define DEBUG_PUSH(2338,74684
+#define DEBUG_STATEMENT(470,14267
+#define DOUBLE_FAIL_STACK(2299,73230
+#define EVER_MATCHED_SOMETHING(3028,96680
+#define EXTEND_BUFFER(941,26834
+#define EXTRACT_NUMBER(403,12499
+#define EXTRACT_NUMBER(422,12960
+#define EXTRACT_NUMBER_AND_INCR(430,13181
+#define EXTRACT_NUMBER_AND_INCR(448,13583
+#define FAIL_STACK_EMPTY(2271,72289
+#define FAIL_STACK_FULL(2273,72404
+#define FAIL_STACK_PTR_EMPTY(2272,72344
+#define FAIL_STACK_TOP(2274,72473
+#define FIRST_STRING_P(221,5848
+#define FREE_VAR(3100,99186
+#define FREE_VARIABLES(3101,99240
+#define FREE_VARIABLES(3116,99751
+#define GET_BUFFER_SPACE(882,24802
+#define GET_UNSIGNED_NUMBER(1017,29312
+#define INIT_FAIL_STACK(2279,72612
+#define INSERT_JUMP(923,26079
+#define INSERT_JUMP2(927,26236
+#define ISALNUM(147,3407
+#define ISALPHA(148,3455
+#define ISBLANK(135,3062
+#define ISBLANK(137,3116
+#define ISCNTRL(149,3503
+#define ISDIGIT(146,3359
+#define ISGRAPH(140,3185
+#define ISGRAPH(142,3239
+#define ISLOWER(150,3551
+#define ISPRINT(145,3311
+#define ISPUNCT(151,3599
+#define ISSPACE(152,3647
+#define ISUPPER(153,3695
+#define ISXDIGIT(154,3743
+#define IS_ACTIVE(3026,96578
+#define IS_CHAR_CLASS(1035,29793
+#define MATCHED_SOMETHING(3027,96621
+#define MAX(233,6292
+#define MIN(234,6334
+#define PATFETCH(852,23769
+#define PATFETCH_RAW(860,24020
+#define POINTER_TO_OFFSET(3050,97433
+#define POP_FAILURE_ITEM(2331,74426
+#define POP_FAILURE_POINT(2461,79538
+#define PREFETCH(3064,97916
+#define PUSH_FAILURE_ITEM(2327,74253
+#define PUSH_FAILURE_POINT(2352,75048
+#define PUSH_PATTERN_OP(2317,73841
+#define REGEX_REALLOCATE(185,4875
+#define REGEX_REALLOCATE(210,5495
+#define REGEX_TALLOC(227,6137
+#define REG_MATCH_NULL_STRING_P(3025,96511
+#define REG_UNSET(3055,97649
+#define RETALLOC(226,6058
+#define SET_LIST_BIT(1011,29089
+#define SET_REGS_MATCHED(3034,96936
+#define SIGN_EXTEND_CHAR(166,4109
+#define SIGN_EXTEND_CHAR(169,4217
+#define STORE_JUMP(915,25800
+#define STORE_JUMP2(919,25917
+#define STORE_NUMBER(384,11919
+#define STORE_NUMBER_AND_INCR(394,12242
+#define STREQ(231,6244
+#define SYNTAX(120,2790
+#define TALLOC(225,6003
+#define TRANSLATE(873,24503
+#define WORDCHAR_P(3086,98755
+alt_match_null_string_p 4466,149039
+#define assert(782,21217
+at_begline_loc_p 2131,67979
+at_endline_loc_p 2150,68557
+#define bcmp(54,1656
+bcmp_translate 4591,151831
+#define bcopy(57,1726
+typedef char boolean;236,6377
+#define bzero(60,1793
+common_op_match_null_string_p 4503,149895
+compile_range 2200,69997
+} compile_stack_elt_t;990,28602
+} compile_stack_type;998,28748
+extract_number 411,12714
+extract_number_and_incr 438,13370
+} fail_stack_type;2269,72269
+group_in_compile_stack 2172,69174
+group_match_null_string_p 4357,145267
+init_syntax_once 94,2365
+insert_op1 2091,67107
+insert_op2 2110,67475
+#define isascii(131,3018
+typedef int pattern_offset_t;981,28388
+print_compiled_pattern 726,19792
+print_double_string 753,20605
+print_fastmap 486,14835
+print_partial_compiled_pattern 518,15475
+re_comp 4650,153479
+re_compile_fastmap 2532,82428
+re_compile_pattern 4617,152520
+re_exec 4688,154373
+re_match 3136,100557
+re_match_2 3161,101399
+} re_opcode_t;378,11781
+re_search 2844,90872
+re_search_2 2877,91998
+re_set_registers 2817,90247
+re_set_syntax 808,22087
+regcomp 4736,155972
+regerror 4876,160188
+regex_compile 1062,30922
+regexec 4811,158371
+regfree 4920,161247
+} register_info_type;3023,96488
+typedef unsigned regnum_t;974,28172
+store_op1 2063,66535
+store_op2 2076,66768
+typedef const unsigned 2262,72103
+
+.././regex.h,230
+#define _RE_ARGS(394,14981
+#define _RE_ARGS(398,15036
+} reg_errcode_t;270,10874
+typedef unsigned reg_syntax_t;38,1503
+typedef struct re_pattern_buffer regex_t;346,13556
+} regmatch_t;382,14634
+typedef int regoff_t;354,13814
+
+getpagesize.h,84
+#define getpagesize(12,137
+#define getpagesize(15,191
+#define getpagesize(20,302
+
+test.h,436
+#define BRACES_TO_OPS(107,3169
+#define INVALID_PATTERN(110,3328
+#define MATCH_SELF(114,3429
+#define PARENS_TO_OPS(108,3248
+#define SAFE_STRLEN(14,201
+#define TEST_POSITIONED_MATCH(116,3470
+#define TEST_REGISTERS(104,3011
+#define TEST_REGISTERS_2(97,2703
+#define TEST_SEARCH(127,3875
+#define TEST_SEARCH_2(123,3720
+#define TEST_TRUNCATED_MATCH(120,3608
+typedef enum { false = 0, true = 1 } boolean;16,255
+} test_type;33,572
+
+alloca.c,128
+alloca 141,3996
+find_stack_direction 85,2553
+} header;127,3538
+typedef void *pointer;51,1721
+typedef char *pointer;53,1778
+
+bsd-interf.c,51
+test_berk_search 8,106
+test_bsd_interface 33,738
+
+debugmalloc.c,395
+#define TRACE(8,143
+#define TRACE1(9,197
+#define TRACE2(10,254
+#define TRACE3(11,319
+#define TRACE4(12,392
+#define USER_ALLOC(61,1440
+typedef char *address;15,480
+} *chunk;54,1225
+chunk_delete 115,2778
+chunk_insert 96,2294
+chunk_to_mem 79,1916
+free 261,5604
+free_list_available 175,3947
+malloc 203,4343
+mem_to_chunk 68,1703
+realloc 242,5309
+validate_list 153,3478
+xsbrk 21,545
+
+emacsmalloc.c,574
+#define ASSERT(178,5884
+#define ASSERT(181,5985
+#define CHAIN(166,5430
+#define bcmp(73,2821
+#define bcopy(72,2777
+#define bzero(74,2868
+calloc 603,15983
+free 484,13255
+get_lim_data 736,18517
+get_lim_data 752,18767
+get_lim_data 759,18860
+getpool 374,10263
+malloc 413,11133
+malloc_init 218,6863
+malloc_mem_free 707,17940
+malloc_mem_used 688,17683
+malloc_stats 663,17320
+malloc_usable_size 233,7147
+memalign 618,16164
+morecore 244,7380
+realloc 541,14424
+#define start_of_data(110,3486
+#define start_of_data(115,3546
+sys_sbrk 815,20804
+valloc 645,17031
+
+fileregex.c,13
+main 11,156
+
+g++malloc.c,1543
+#define UPDATE_STATS(33,1090
+#define UPDATE_STATS(35,1131
+static inline int aligned_OK(343,11189
+void* calloc(1039,28692
+void cfree(1048,28894
+static inline void* chunk2mem(619,19336
+#define clear_inuse(592,18767
+static inline void consollink(716,21398
+static void do_free_stats(544,18016
+static void do_malloc_stats(534,17741
+766,22304
+extern 762,22235
+ for 1260,34165
+void free(1028,28553
+static inline void frontlink(732,21717
+static unsigned int gcd(557,18251
+ if 1212,32427
+ if 1216,32582
+ if 1220,32737
+ if 1224,32880
+ if 1229,33094
+ if 1233,33251
+ if 1238,33463
+ if 1242,33609
+ if 1247,33739
+#define inuse(590,18680
+static inline unsigned int lcm(580,18540
+void* malloc(939,26370
+static mchunkptr malloc_find_space(858,24561
+void malloc_stats(1201,32256
+unsigned int malloc_usable_size(1054,28936
+static volatile void malloc_user_error(286,9757
+static void malloc_user_error(288,9804
+typedef struct malloc_bin* mbinptr;320,10636
+typedef struct malloc_chunk* mchunkptr;309,10247
+static inline mchunkptr mem2chunk(643,19759
+void* memalign(1118,30363
+#define next_chunk(600,18910
+#define prev_chunk(604,19023
+void* realloc(1071,29263
+static inline unsigned int request2size(335,10993
+mchunkptr sanity_check(628,19486
+#define set_inuse(591,18723
+static inline void set_size(609,19149
+static inline mbinptr size2bin(499,16914
+static inline void split(685,20463
+static 768,22312
+static inline void unlink(671,20263
+void* valloc(1194,32107
+typedef volatile void 760,22184
+764,22271
+
+iregex.c,54
+main 20,390
+print_regs 141,2638
+scanstring 87,1839
+
+main.c,13
+main 12,242
+
+malloc-test.c,112
+#define BITS_BLOCK(12,168
+#define BITS_MASK(13,228
+} bits_list_type;6,56
+init_bits_list 16,311
+main(32,621
+
+other.c,18
+test_others 6,96
+
+printchar.c,15
+printchar 2,5
+
+psx-basic.c,23
+test_posix_basic 7,84
+
+psx-extend.c,26
+test_posix_extended 7,88
+
+psx-generic.c,26
+test_posix_generic 8,117
+
+psx-group.c,20
+test_grouping 7,92
+
+psx-interf.c,416
+fill_pmatch 174,4802
+get_error_string 18,260
+init_pattern_buffer 49,1434
+test_compile 67,1925
+test_eflags 245,6876
+test_error_code_allocation 562,16619
+test_error_code_message 524,15247
+test_ignore_case 303,8525
+test_newline 330,9199
+test_nsub 117,3319
+test_pmatch 188,5121
+test_posix_interface 614,18719
+test_posix_match 359,9938
+test_regcomp 138,3725
+test_regerror 592,17621
+test_regexec 394,10783
+
+psx-interv.c,21
+test_intervals 6,93
+
+test.c,607
+#define SET_FASTMAP(447,13999
+#define bcmp(18,362
+#define bcopy(19,415
+#define bzero(20,473
+compile_and_print_pattern 666,19653
+concat 97,2673
+delimiters_to_ops 571,17477
+general_test 115,2996
+invalid_pattern 542,16821
+#define memcmp(26,611
+#define memcpy(27,660
+print_pattern_info 635,18998
+set_all_registers 58,1390
+test_all_registers 506,15567
+test_case_fold 682,19993
+test_fastmap 460,14363
+test_fastmap_search 474,14668
+test_match 776,22235
+test_match_2 766,22040
+test_match_n_times 715,20798
+test_search_return 408,13011
+valid_nonposix_pattern 646,19239
+valid_pattern 557,17182
+
+tregress.c,208
+#define SIMPLE_MATCH(74,1463
+#define SIMPLE_NONMATCH(75,1528
+do_match 78,1599
+itoa 10,199
+simple_compile 44,882
+simple_fail 21,353
+simple_fastmap 55,1115
+simple_search 100,2020
+test_regress 124,2513
+
+upcase.c,0
+
+xmalloc.c,14
+xmalloc 9,87
diff --git a/gnu/lib/libregex/test/alloca.c b/gnu/lib/libregex/test/alloca.c
new file mode 100644
index 000000000000..c1ff22227f8e
--- /dev/null
+++ b/gnu/lib/libregex/test/alloca.c
@@ -0,0 +1,194 @@
+/*
+ alloca -- (mostly) portable public-domain implementation -- D A Gwyn
+
+ last edit: 86/05/30 rms
+ include config.h, since on VMS it renames some symbols.
+ Use xmalloc instead of malloc.
+
+ This implementation of the PWB library alloca() function,
+ which is used to allocate space off the run-time stack so
+ that it is automatically reclaimed upon procedure exit,
+ was inspired by discussions with J. Q. Johnson of Cornell.
+
+ It should work under any C implementation that uses an
+ actual procedure stack (as opposed to a linked list of
+ frames). There are some preprocessor constants that can
+ be defined when compiling for your specific system, for
+ improved efficiency; however, the defaults should be okay.
+
+ The general concept of this implementation is to keep
+ track of all alloca()-allocated blocks, and reclaim any
+ that are found to be deeper in the stack than the current
+ invocation. This heuristic does not reclaim storage as
+ soon as it becomes invalid, but it will do so eventually.
+
+ As a special case, alloca(0) reclaims storage without
+ allocating any. It is a good idea to use alloca(0) in
+ your main control loop, etc. to force garbage collection.
+*/
+#ifndef lint
+static char SCCSid[] = "@(#)alloca.c 1.1"; /* for the "what" utility */
+#endif
+
+#ifdef emacs
+#include "config.h"
+#ifdef static
+/* actually, only want this if static is defined as ""
+ -- this is for usg, in which emacs must undefine static
+ in order to make unexec workable
+ */
+#ifndef STACK_DIRECTION
+you
+lose
+-- must know STACK_DIRECTION at compile-time
+#endif /* STACK_DIRECTION undefined */
+#endif /* static */
+#endif /* emacs */
+
+#ifndef alloca /* If compiling with GCC, this file's not needed. */
+
+#ifdef __STDC__
+typedef void *pointer; /* generic pointer type */
+#else
+typedef char *pointer; /* generic pointer type */
+#endif
+
+#define NULL 0 /* null pointer constant */
+
+extern void free();
+extern pointer xmalloc();
+
+/*
+ Define STACK_DIRECTION if you know the direction of stack
+ growth for your system; otherwise it will be automatically
+ deduced at run-time.
+
+ STACK_DIRECTION > 0 => grows toward higher addresses
+ STACK_DIRECTION < 0 => grows toward lower addresses
+ STACK_DIRECTION = 0 => direction of growth unknown
+*/
+
+#ifndef STACK_DIRECTION
+#define STACK_DIRECTION 0 /* direction unknown */
+#endif
+
+#if STACK_DIRECTION != 0
+
+#define STACK_DIR STACK_DIRECTION /* known at compile-time */
+
+#else /* STACK_DIRECTION == 0; need run-time code */
+
+static int stack_dir; /* 1 or -1 once known */
+#define STACK_DIR stack_dir
+
+static void
+find_stack_direction (/* void */)
+{
+ static char *addr = NULL; /* address of first
+ `dummy', once known */
+ auto char dummy; /* to get stack address */
+
+ if (addr == NULL)
+ { /* initial entry */
+ addr = &dummy;
+
+ find_stack_direction (); /* recurse once */
+ }
+ else /* second entry */
+ if (&dummy > addr)
+ stack_dir = 1; /* stack grew upward */
+ else
+ stack_dir = -1; /* stack grew downward */
+}
+
+#endif /* STACK_DIRECTION == 0 */
+
+/*
+ An "alloca header" is used to:
+ (a) chain together all alloca()ed blocks;
+ (b) keep track of stack depth.
+
+ It is very important that sizeof(header) agree with malloc()
+ alignment chunk size. The following default should work okay.
+*/
+
+#ifndef ALIGN_SIZE
+#define ALIGN_SIZE sizeof(double)
+#endif
+
+typedef union hdr
+{
+ char align[ALIGN_SIZE]; /* to force sizeof(header) */
+ struct
+ {
+ union hdr *next; /* for chaining headers */
+ char *deep; /* for stack depth measure */
+ } h;
+} header;
+
+/*
+ alloca( size ) returns a pointer to at least `size' bytes of
+ storage which will be automatically reclaimed upon exit from
+ the procedure that called alloca(). Originally, this space
+ was supposed to be taken from the current stack frame of the
+ caller, but that method cannot be made to work for some
+ implementations of C, for example under Gould's UTX/32.
+*/
+
+static header *last_alloca_header = NULL; /* -> last alloca header */
+
+pointer
+alloca (size) /* returns pointer to storage */
+ unsigned size; /* # bytes to allocate */
+{
+ auto char probe; /* probes stack depth: */
+ register char *depth = &probe;
+
+#if STACK_DIRECTION == 0
+ if (STACK_DIR == 0) /* unknown growth direction */
+ find_stack_direction ();
+#endif
+
+ /* Reclaim garbage, defined as all alloca()ed storage that
+ was allocated from deeper in the stack than currently. */
+
+ {
+ register header *hp; /* traverses linked list */
+
+ for (hp = last_alloca_header; hp != NULL;)
+ if ((STACK_DIR > 0 && hp->h.deep > depth)
+ || (STACK_DIR < 0 && hp->h.deep < depth))
+ {
+ register header *np = hp->h.next;
+
+ free ((pointer) hp); /* collect garbage */
+
+ hp = np; /* -> next header */
+ }
+ else
+ break; /* rest are not deeper */
+
+ last_alloca_header = hp; /* -> last valid storage */
+ }
+
+ if (size == 0)
+ return NULL; /* no allocation required */
+
+ /* Allocate combined header + user data storage. */
+
+ {
+ register pointer new = xmalloc (sizeof (header) + size);
+ /* address of header */
+
+ ((header *)new)->h.next = last_alloca_header;
+ ((header *)new)->h.deep = depth;
+
+ last_alloca_header = (header *)new;
+
+ /* User storage begins just after header. */
+
+ return (pointer)((char *)new + sizeof(header));
+ }
+}
+
+#endif /* no alloca */
diff --git a/gnu/lib/libregex/test/bsd-interf.c b/gnu/lib/libregex/test/bsd-interf.c
new file mode 100644
index 000000000000..56f9e2a2fe68
--- /dev/null
+++ b/gnu/lib/libregex/test/bsd-interf.c
@@ -0,0 +1,38 @@
+/* bsd-interf.c: test BSD interface. */
+
+#ifndef _POSIX_SOURCE /* whole file */
+
+#include "test.h"
+
+void
+test_berk_search (pattern, string)
+ const char *pattern;
+ char *string;
+{
+ const char *return_value = re_comp (pattern);
+
+ if (return_value != 0)
+ {
+ printf ("This didn't compile: `%s'.\n", pattern);
+ printf (" The error message was: `%s'.\n", return_value);
+ }
+ else
+ if (test_should_match && re_exec (string) != strlen (string))
+ {
+ printf ("Should have matched but didn't:\n");
+ printf (" The pattern was: %s.\n", pattern);
+ if (string)
+ printf (" The string was: `%s'.'n", string);
+ else
+ printf (" The string was empty.\n");
+ }
+}
+
+
+void
+test_bsd_interface ()
+{
+ test_berk_search ("a", "ab");
+}
+
+#endif /* _POSIX_SOURCE */
diff --git a/gnu/lib/libregex/test/debugmalloc.c b/gnu/lib/libregex/test/debugmalloc.c
new file mode 100644
index 000000000000..5c468e212439
--- /dev/null
+++ b/gnu/lib/libregex/test/debugmalloc.c
@@ -0,0 +1,273 @@
+/* debugmalloc.c: a malloc for debugging purposes. */
+
+#include <stdio.h>
+#include <assert.h>
+#include <string.h>
+
+static unsigned trace = 0;
+#define TRACE(s) if (trace) fprintf (stderr, "%s", s)
+#define TRACE1(s, e1) if (trace) fprintf (stderr, s, e1)
+#define TRACE2(s, e1, e2) if (trace) fprintf (stderr, s, e1, e2)
+#define TRACE3(s, e1, e2, e3) if (trace) fprintf (stderr, s, e1, e2, e3)
+#define TRACE4(s, e1, e2, e3, e4) \
+ if (trace) fprintf (stderr, s, e1, e2, e3, e4)
+
+typedef char *address;
+
+
+/* Wrap our calls to sbrk. */
+
+address
+xsbrk (incr)
+ int incr;
+{
+ extern char *sbrk ();
+ address ret = sbrk (incr);
+
+ if (ret == (address) -1)
+ {
+ perror ("sbrk"); /* Actually, we should return NULL, not quit. */
+ abort ();
+ }
+
+ return ret;
+}
+
+
+
+typedef struct chunk_struct
+{
+ /* This is the size (in bytes) that has actually been actually
+ allocated, not the size that the user requested. */
+ unsigned alloc_size;
+
+ /* This is the size the user requested. */
+ unsigned user_size;
+
+ /* Points to the next block in one of the lists. */
+ struct chunk_struct *next;
+
+ /* Now comes the user's memory. */
+ address user_mem;
+
+ /* After the user's memory is a constant. */
+} *chunk;
+
+#define MALLOC_OVERHEAD 16
+
+/* We might play around with the `user_size' field, but the amount of
+ memory that is actually available in the chunk is always the size
+ allocated minus the overhead. */
+#define USER_ALLOC(c) ((c)->alloc_size - MALLOC_OVERHEAD)
+
+/* Given a pointer to a malloc-allocated block, the beginning of the
+ chunk should always be MALLOC_OVERHEAD - 4 bytes back, since the only
+ overhead after the user memory is the constant. */
+
+chunk
+mem_to_chunk (mem)
+ address mem;
+{
+ return (chunk) (mem - (MALLOC_OVERHEAD - 4));
+}
+
+
+/* The other direction is even easier, since the user's memory starts at
+ the `user_mem' member in the chunk. */
+
+address
+chunk_to_mem (c)
+ chunk c;
+{
+ return (address) &(c->user_mem);
+}
+
+
+
+/* We keep both all the allocated chunks and all the free chunks on
+ lists. Since we put the next pointers in the chunk structure, we
+ don't need a separate chunk_list structure. */
+chunk alloc_list = NULL, free_list = NULL;
+
+
+/* We always append the new chunk at the beginning of the list. */
+
+void
+chunk_insert (chunk_list, new_c)
+ chunk *chunk_list;
+ chunk new_c;
+{
+ chunk c = *chunk_list; /* old beginning of list */
+
+ TRACE3 (" Inserting 0x%x at the beginning of 0x%x, before 0x%x.\n",
+ new_c, chunk_list, c);
+
+ *chunk_list = new_c;
+ new_c->next = c;
+}
+
+
+/* Thus, removing an element means we have to search until we find it.
+ Have to delete before we insert, since insertion changes the next
+ pointer, which we need to put it on the other list. */
+
+void
+chunk_delete (chunk_list, dead_c)
+ chunk *chunk_list;
+ chunk dead_c;
+{
+ chunk c = *chunk_list;
+ chunk prev_c = NULL;
+
+ TRACE2 (" Deleting 0x%x from 0x%x:", dead_c, chunk_list);
+
+ while (c != dead_c && c != NULL)
+ {
+ TRACE1 (" 0x%x", c);
+ prev_c = c;
+ c = c->next;
+ }
+
+ if (c == NULL)
+ {
+ fprintf (stderr, "Chunk at 0x%x not found on list.\n", dead_c);
+ abort ();
+ }
+
+ if (prev_c == NULL)
+ {
+ TRACE1 (".\n Setting head to 0x%x.\n", c->next);
+ *chunk_list = c->next;
+ }
+ else
+ {
+ TRACE2 (".\n Linking next(0x%x) to 0x%x.\n", prev_c, c->next);
+ prev_c->next = c->next;
+ }
+}
+
+
+/* See if a list is hunky-dory. */
+
+void
+validate_list (chunk_list)
+ chunk *chunk_list;
+{
+ chunk c;
+
+ TRACE1 (" Validating list at 0x%x:", chunk_list);
+
+ for (c = *chunk_list; c != NULL; c = c->next)
+ {
+ assert (c->user_size < c->alloc_size);
+ assert (memcmp (chunk_to_mem (c) + c->user_size, "Karl", 4));
+ TRACE2 (" 0x%x/%d", c, c->user_size);
+ }
+
+ TRACE (".\n");
+}
+
+
+/* See if we have a free chunk of a given size. We'll take the first
+ one that is big enough. */
+
+chunk
+free_list_available (needed)
+ unsigned needed;
+{
+ chunk c;
+
+ TRACE1 (" Checking free list for %d bytes:", needed);
+
+ if (free_list == NULL)
+ {
+ return NULL;
+ }
+
+ c = free_list;
+
+ while (c != NULL && USER_ALLOC (c) < needed)
+ {
+ TRACE2 (" 0x%x/%d", c, USER_ALLOC (c));
+ c = c->next;
+ }
+
+ TRACE1 ("\n Returning 0x%x.\n", c);
+ return c;
+}
+
+
+
+
+address
+malloc (n)
+ unsigned n;
+{
+ address new_mem;
+ chunk c;
+
+ TRACE1 ("Mallocing %d bytes.\n", n);
+
+ validate_list (&free_list);
+ validate_list (&alloc_list);
+
+ c = free_list_available (n);
+
+ if (c == NULL)
+ { /* Nothing suitable on free list. Allocate a new chunk. */
+ TRACE (" not on free list.\n");
+ c = (chunk) xsbrk (n + MALLOC_OVERHEAD);
+ c->alloc_size = n + MALLOC_OVERHEAD;
+ }
+ else
+ { /* Found something on free list. Don't split it, just use as is. */
+ TRACE (" found on free list.\n");
+ chunk_delete (&free_list, c);
+ }
+
+ /* If we took this from the free list, then the user size might be
+ different now, and consequently the constant at the end might be in
+ the wrong place. */
+ c->user_size = n;
+ new_mem = chunk_to_mem (c);
+ memcpy (new_mem + n, "Karl", 4);
+ chunk_insert (&alloc_list, c);
+
+ TRACE2 ("Malloc returning 0x%x (chunk 0x%x).\n", new_mem, c);
+ return new_mem;
+}
+
+
+address
+realloc (mem, n)
+ address mem;
+ unsigned n;
+{
+ void free ();
+ chunk c = mem_to_chunk (mem);
+ address new_mem;
+
+ TRACE3 ("Reallocing %d bytes at 0x%x (chunk 0x%x).\n", n, mem, c);
+
+ new_mem = malloc (n);
+ memcpy (new_mem, mem, c->user_size);
+ free (mem);
+
+ return new_mem;
+}
+
+
+void
+free (mem)
+ address mem;
+{
+ chunk c = mem_to_chunk (mem);
+
+ TRACE2 ("Freeing memory at 0x%x (chunk at 0x%x).\n", mem, c);
+
+ validate_list (&free_list);
+ validate_list (&alloc_list);
+
+ chunk_delete (&alloc_list, c);
+ chunk_insert (&free_list, c);
+}
diff --git a/gnu/lib/libregex/test/emacsmalloc.c b/gnu/lib/libregex/test/emacsmalloc.c
new file mode 100644
index 000000000000..6eee1fae1acb
--- /dev/null
+++ b/gnu/lib/libregex/test/emacsmalloc.c
@@ -0,0 +1,844 @@
+/* dynamic memory allocation for GNU.
+ Copyright (C) 1985, 1987 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 1, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+In other words, you are welcome to use, share and improve this program.
+You are forbidden to forbid anyone else to use, share and improve
+what you give them. Help stamp out software-hoarding! */
+
+
+/*
+ * @(#)nmalloc.c 1 (Caltech) 2/21/82
+ *
+ * U of M Modified: 20 Jun 1983 ACT: strange hacks for Emacs
+ *
+ * Nov 1983, Mike@BRL, Added support for 4.1C/4.2 BSD.
+ *
+ * This is a very fast storage allocator. It allocates blocks of a small
+ * number of different sizes, and keeps free lists of each size. Blocks
+ * that don't exactly fit are passed up to the next larger size. In this
+ * implementation, the available sizes are (2^n)-4 (or -16) bytes long.
+ * This is designed for use in a program that uses vast quantities of
+ * memory, but bombs when it runs out. To make it a little better, it
+ * warns the user when he starts to get near the end.
+ *
+ * June 84, ACT: modified rcheck code to check the range given to malloc,
+ * rather than the range determined by the 2-power used.
+ *
+ * Jan 85, RMS: calls malloc_warning to issue warning on nearly full.
+ * No longer Emacs-specific; can serve as all-purpose malloc for GNU.
+ * You should call malloc_init to reinitialize after loading dumped Emacs.
+ * Call malloc_stats to get info on memory stats if MSTATS turned on.
+ * realloc knows how to return same block given, just changing its size,
+ * if the power of 2 is correct.
+ */
+
+/*
+ * nextf[i] is the pointer to the next free block of size 2^(i+3). The
+ * smallest allocatable block is 8 bytes. The overhead information will
+ * go in the first int of the block, and the returned pointer will point
+ * to the second.
+ *
+#ifdef MSTATS
+ * nmalloc[i] is the difference between the number of mallocs and frees
+ * for a given block size.
+#endif MSTATS
+ */
+
+#ifdef emacs
+/* config.h specifies which kind of system this is. */
+#include "config.h"
+#include <signal.h>
+#else
+
+/* Determine which kind of system this is. */
+#include <sys/types.h>
+#include <signal.h>
+
+#include <string.h>
+#define bcopy(s,d,n) memcpy ((d), (s), (n))
+#define bcmp(s1,s2,n) memcmp ((s1), (s2), (n))
+#define bzero(s,n) memset ((s), 0, (n))
+
+#ifndef SIGTSTP
+#ifndef VMS
+#ifndef USG
+#define USG
+#endif
+#endif /* not VMS */
+#else /* SIGTSTP */
+#ifdef SIGIO
+#define BSD4_2
+#endif /* SIGIO */
+#endif /* SIGTSTP */
+
+#endif /* not emacs */
+
+/* Define getpagesize () if the system does not. */
+#include "getpagesize.h"
+
+#ifdef BSD
+#ifdef BSD4_1
+#include <sys/vlimit.h> /* warn the user when near the end */
+#else /* if 4.2 or newer */
+#include <sys/time.h>
+#include <sys/resource.h>
+#endif /* if 4.2 or newer */
+#endif
+
+#ifdef VMS
+#include "vlimit.h"
+#endif
+
+extern char *start_of_data ();
+
+#ifdef BSD
+#ifndef DATA_SEG_BITS
+#define start_of_data() &etext
+#endif
+#endif
+
+#ifndef emacs
+#define start_of_data() &etext
+#endif
+
+#define ISALLOC ((char) 0xf7) /* magic byte that implies allocation */
+#define ISFREE ((char) 0x54) /* magic byte that implies free block */
+ /* this is for error checking only */
+#define ISMEMALIGN ((char) 0xd6) /* Stored before the value returned by
+ memalign, with the rest of the word
+ being the distance to the true
+ beginning of the block. */
+
+extern char etext;
+
+/* These two are for user programs to look at, when they are interested. */
+
+unsigned int malloc_sbrk_used; /* amount of data space used now */
+unsigned int malloc_sbrk_unused; /* amount more we can have */
+
+/* start of data space; can be changed by calling init_malloc */
+static char *data_space_start;
+
+#ifdef MSTATS
+static int nmalloc[30];
+static int nmal, nfre;
+#endif /* MSTATS */
+
+/* If range checking is not turned on, all we have is a flag indicating
+ whether memory is allocated, an index in nextf[], and a size field; to
+ realloc() memory we copy either size bytes or 1<<(index+3) bytes depending
+ on whether the former can hold the exact size (given the value of
+ 'index'). If range checking is on, we always need to know how much space
+ is allocated, so the 'size' field is never used. */
+
+struct mhead {
+ char mh_alloc; /* ISALLOC or ISFREE */
+ char mh_index; /* index in nextf[] */
+/* Remainder are valid only when block is allocated */
+ unsigned short mh_size; /* size, if < 0x10000 */
+#ifdef rcheck
+ unsigned mh_nbytes; /* number of bytes allocated */
+ int mh_magic4; /* should be == MAGIC4 */
+#endif /* rcheck */
+};
+
+/* Access free-list pointer of a block.
+ It is stored at block + 4.
+ This is not a field in the mhead structure
+ because we want sizeof (struct mhead)
+ to describe the overhead for when the block is in use,
+ and we do not want the free-list pointer to count in that. */
+
+#define CHAIN(a) \
+ (*(struct mhead **) (sizeof (char *) + (char *) (a)))
+
+#ifdef rcheck
+
+/* To implement range checking, we write magic values in at the beginning and
+ end of each allocated block, and make sure they are undisturbed whenever a
+ free or a realloc occurs. */
+/* Written in each of the 4 bytes following the block's real space */
+#define MAGIC1 0x55
+/* Written in the 4 bytes before the block's real space */
+#define MAGIC4 0x55555555
+#define ASSERT(p) if (!(p)) botch("p"); else
+#define EXTRA 4 /* 4 bytes extra for MAGIC1s */
+#else
+#define ASSERT(p) if (!(p)) abort (); else
+#define EXTRA 0
+#endif /* rcheck */
+
+
+/* nextf[i] is free list of blocks of size 2**(i + 3) */
+
+static struct mhead *nextf[30];
+
+/* busy[i] is nonzero while allocation of block size i is in progress. */
+
+static char busy[30];
+
+/* Number of bytes of writable memory we can expect to be able to get */
+static unsigned int lim_data;
+
+/* Level number of warnings already issued.
+ 0 -- no warnings issued.
+ 1 -- 75% warning already issued.
+ 2 -- 85% warning already issued.
+*/
+static int warnlevel;
+
+/* Function to call to issue a warning;
+ 0 means don't issue them. */
+static void (*warnfunction) ();
+
+/* nonzero once initial bunch of free blocks made */
+static int gotpool;
+
+char *_malloc_base;
+
+static void getpool ();
+
+/* Cause reinitialization based on job parameters;
+ also declare where the end of pure storage is. */
+void
+malloc_init (start, warnfun)
+ char *start;
+ void (*warnfun) ();
+{
+ if (start)
+ data_space_start = start;
+ lim_data = 0;
+ warnlevel = 0;
+ warnfunction = warnfun;
+}
+
+/* Return the maximum size to which MEM can be realloc'd
+ without actually requiring copying. */
+
+int
+malloc_usable_size (mem)
+ char *mem;
+{
+ struct mhead *p
+ = (struct mhead *) (mem - ((sizeof (struct mhead) + 7) & ~7));
+ int blocksize = 8 << p->mh_index;
+
+ return blocksize - sizeof (struct mhead) - EXTRA;
+}
+
+static void
+morecore (nu) /* ask system for more memory */
+ register int nu; /* size index to get more of */
+{
+ char *sbrk ();
+ register char *cp;
+ register int nblks;
+ register unsigned int siz;
+ int oldmask;
+
+#ifdef BSD
+#ifndef BSD4_1
+ int newmask = -1;
+ /* Blocking these signals interferes with debugging, at least on BSD on
+ the HP 9000/300. */
+#ifdef SIGTRAP
+ newmask &= ~(1 << SIGTRAP);
+#endif
+#ifdef SIGILL
+ newmask &= ~(1 << SIGILL);
+#endif
+#ifdef SIGTSTP
+ newmask &= ~(1 << SIGTSTP);
+#endif
+#ifdef SIGSTOP
+ newmask &= ~(1 << SIGSTOP);
+#endif
+ oldmask = sigsetmask (newmask);
+#endif
+#endif
+
+ if (!data_space_start)
+ {
+ data_space_start = start_of_data ();
+ }
+
+ if (lim_data == 0)
+ get_lim_data ();
+
+ /* On initial startup, get two blocks of each size up to 1k bytes */
+ if (!gotpool)
+ { getpool (); getpool (); gotpool = 1; }
+
+ /* Find current end of memory and issue warning if getting near max */
+
+#ifndef VMS
+ /* Maximum virtual memory on VMS is difficult to calculate since it
+ * depends on several dynmacially changing things. Also, alignment
+ * isn't that important. That is why much of the code here is ifdef'ed
+ * out for VMS systems.
+ */
+ cp = sbrk (0);
+ siz = cp - data_space_start;
+
+ if (warnfunction)
+ switch (warnlevel)
+ {
+ case 0:
+ if (siz > (lim_data / 4) * 3)
+ {
+ warnlevel++;
+ (*warnfunction) ("Warning: past 75% of memory limit");
+ }
+ break;
+ case 1:
+ if (siz > (lim_data / 20) * 17)
+ {
+ warnlevel++;
+ (*warnfunction) ("Warning: past 85% of memory limit");
+ }
+ break;
+ case 2:
+ if (siz > (lim_data / 20) * 19)
+ {
+ warnlevel++;
+ (*warnfunction) ("Warning: past 95% of memory limit");
+ }
+ break;
+ }
+
+ if ((int) cp & 0x3ff) /* land on 1K boundaries */
+ sbrk (1024 - ((int) cp & 0x3ff));
+#endif /* not VMS */
+
+ /* Take at least 2k, and figure out how many blocks of the desired size
+ we're about to get */
+ nblks = 1;
+ if ((siz = nu) < 8)
+ nblks = 1 << ((siz = 8) - nu);
+
+ if ((cp = sbrk (1 << (siz + 3))) == (char *) -1)
+ {
+#ifdef BSD
+#ifndef BSD4_1
+ sigsetmask (oldmask);
+#endif
+#endif
+ return; /* no more room! */
+ }
+ malloc_sbrk_used = siz;
+ malloc_sbrk_unused = lim_data - siz;
+
+#ifndef VMS
+ if ((int) cp & 7)
+ { /* shouldn't happen, but just in case */
+ cp = (char *) (((int) cp + 8) & ~7);
+ nblks--;
+ }
+#endif /* not VMS */
+
+ /* save new header and link the nblks blocks together */
+ nextf[nu] = (struct mhead *) cp;
+ siz = 1 << (nu + 3);
+ while (1)
+ {
+ ((struct mhead *) cp) -> mh_alloc = ISFREE;
+ ((struct mhead *) cp) -> mh_index = nu;
+ if (--nblks <= 0) break;
+ CHAIN ((struct mhead *) cp) = (struct mhead *) (cp + siz);
+ cp += siz;
+ }
+ CHAIN ((struct mhead *) cp) = 0;
+
+#ifdef BSD
+#ifndef BSD4_1
+ sigsetmask (oldmask);
+#endif
+#endif
+}
+
+static void
+getpool ()
+{
+ register int nu;
+ char * sbrk ();
+ register char *cp = sbrk (0);
+
+ if ((int) cp & 0x3ff) /* land on 1K boundaries */
+ sbrk (1024 - ((int) cp & 0x3ff));
+
+ /* Record address of start of space allocated by malloc. */
+ if (_malloc_base == 0)
+ _malloc_base = cp;
+
+ /* Get 2k of storage */
+
+ cp = sbrk (04000);
+ if (cp == (char *) -1)
+ return;
+
+ /* Divide it into an initial 8-word block
+ plus one block of size 2**nu for nu = 3 ... 10. */
+
+ CHAIN (cp) = nextf[0];
+ nextf[0] = (struct mhead *) cp;
+ ((struct mhead *) cp) -> mh_alloc = ISFREE;
+ ((struct mhead *) cp) -> mh_index = 0;
+ cp += 8;
+
+ for (nu = 0; nu < 7; nu++)
+ {
+ CHAIN (cp) = nextf[nu];
+ nextf[nu] = (struct mhead *) cp;
+ ((struct mhead *) cp) -> mh_alloc = ISFREE;
+ ((struct mhead *) cp) -> mh_index = nu;
+ cp += 8 << nu;
+ }
+}
+
+char *
+malloc (n) /* get a block */
+ unsigned n;
+{
+ register struct mhead *p;
+ register unsigned int nbytes;
+ register int nunits = 0;
+
+ /* Figure out how many bytes are required, rounding up to the nearest
+ multiple of 8, then figure out which nestf[] area to use.
+ Both the beginning of the header and the beginning of the
+ block should be on an eight byte boundary. */
+ nbytes = (n + ((sizeof *p + 7) & ~7) + EXTRA + 7) & ~7;
+ {
+ register unsigned int shiftr = (nbytes - 1) >> 2;
+
+ while (shiftr >>= 1)
+ nunits++;
+ }
+
+ /* In case this is reentrant use of malloc from signal handler,
+ pick a block size that no other malloc level is currently
+ trying to allocate. That's the easiest harmless way not to
+ interfere with the other level of execution. */
+ while (busy[nunits]) nunits++;
+ busy[nunits] = 1;
+
+ /* If there are no blocks of the appropriate size, go get some */
+ /* COULD SPLIT UP A LARGER BLOCK HERE ... ACT */
+ if (nextf[nunits] == 0)
+ morecore (nunits);
+
+ /* Get one block off the list, and set the new list head */
+ if ((p = nextf[nunits]) == 0)
+ {
+ busy[nunits] = 0;
+ return 0;
+ }
+ nextf[nunits] = CHAIN (p);
+ busy[nunits] = 0;
+
+ /* Check for free block clobbered */
+ /* If not for this check, we would gobble a clobbered free chain ptr */
+ /* and bomb out on the NEXT allocate of this size block */
+ if (p -> mh_alloc != ISFREE || p -> mh_index != nunits)
+#ifdef rcheck
+ botch ("block on free list clobbered");
+#else /* not rcheck */
+ abort ();
+#endif /* not rcheck */
+
+ /* Fill in the info, and if range checking, set up the magic numbers */
+ p -> mh_alloc = ISALLOC;
+#ifdef rcheck
+ p -> mh_nbytes = n;
+ p -> mh_magic4 = MAGIC4;
+ {
+ /* Get the location n after the beginning of the user's space. */
+ register char *m = (char *) p + ((sizeof *p + 7) & ~7) + n;
+
+ *m++ = MAGIC1, *m++ = MAGIC1, *m++ = MAGIC1, *m = MAGIC1;
+ }
+#else /* not rcheck */
+ p -> mh_size = n;
+#endif /* not rcheck */
+#ifdef MSTATS
+ nmalloc[nunits]++;
+ nmal++;
+#endif /* MSTATS */
+ return (char *) p + ((sizeof *p + 7) & ~7);
+}
+
+free (mem)
+ char *mem;
+{
+ register struct mhead *p;
+ {
+ register char *ap = mem;
+
+ if (ap == 0)
+ return;
+
+ p = (struct mhead *) (ap - ((sizeof *p + 7) & ~7));
+ if (p -> mh_alloc == ISMEMALIGN)
+ {
+ ap -= p->mh_size;
+ p = (struct mhead *) (ap - ((sizeof *p + 7) & ~7));
+ }
+
+#ifndef rcheck
+ if (p -> mh_alloc != ISALLOC)
+ abort ();
+
+#else rcheck
+ if (p -> mh_alloc != ISALLOC)
+ {
+ if (p -> mh_alloc == ISFREE)
+ botch ("free: Called with already freed block argument\n");
+ else
+ botch ("free: Called with bad argument\n");
+ }
+
+ ASSERT (p -> mh_magic4 == MAGIC4);
+ ap += p -> mh_nbytes;
+ ASSERT (*ap++ == MAGIC1); ASSERT (*ap++ == MAGIC1);
+ ASSERT (*ap++ == MAGIC1); ASSERT (*ap == MAGIC1);
+#endif /* rcheck */
+ }
+ {
+ register int nunits = p -> mh_index;
+
+ ASSERT (nunits <= 29);
+ p -> mh_alloc = ISFREE;
+
+ /* Protect against signal handlers calling malloc. */
+ busy[nunits] = 1;
+ /* Put this block on the free list. */
+ CHAIN (p) = nextf[nunits];
+ nextf[nunits] = p;
+ busy[nunits] = 0;
+
+#ifdef MSTATS
+ nmalloc[nunits]--;
+ nfre++;
+#endif /* MSTATS */
+ }
+}
+
+char *
+realloc (mem, n)
+ char *mem;
+ register unsigned n;
+{
+ register struct mhead *p;
+ register unsigned int tocopy;
+ register unsigned int nbytes;
+ register int nunits;
+
+ if (mem == 0)
+ return malloc (n);
+ p = (struct mhead *) (mem - ((sizeof *p + 7) & ~7));
+ nunits = p -> mh_index;
+ ASSERT (p -> mh_alloc == ISALLOC);
+#ifdef rcheck
+ ASSERT (p -> mh_magic4 == MAGIC4);
+ {
+ register char *m = mem + (tocopy = p -> mh_nbytes);
+ ASSERT (*m++ == MAGIC1); ASSERT (*m++ == MAGIC1);
+ ASSERT (*m++ == MAGIC1); ASSERT (*m == MAGIC1);
+ }
+#else /* not rcheck */
+ if (p -> mh_index >= 13)
+ tocopy = (1 << (p -> mh_index + 3)) - ((sizeof *p + 7) & ~7);
+ else
+ tocopy = p -> mh_size;
+#endif /* not rcheck */
+
+ /* See if desired size rounds to same power of 2 as actual size. */
+ nbytes = (n + ((sizeof *p + 7) & ~7) + EXTRA + 7) & ~7;
+
+ /* If ok, use the same block, just marking its size as changed. */
+ if (nbytes > (4 << nunits) && nbytes <= (8 << nunits))
+ {
+#ifdef rcheck
+ register char *m = mem + tocopy;
+ *m++ = 0; *m++ = 0; *m++ = 0; *m++ = 0;
+ p-> mh_nbytes = n;
+ m = mem + n;
+ *m++ = MAGIC1; *m++ = MAGIC1; *m++ = MAGIC1; *m++ = MAGIC1;
+#else /* not rcheck */
+ p -> mh_size = n;
+#endif /* not rcheck */
+ return mem;
+ }
+
+ if (n < tocopy)
+ tocopy = n;
+ {
+ register char *new;
+
+ if ((new = malloc (n)) == 0)
+ return 0;
+ bcopy (mem, new, tocopy);
+ free (mem);
+ return new;
+ }
+}
+
+/* This is in case something linked with Emacs calls calloc. */
+
+char *
+calloc (num, size)
+ unsigned num, size;
+{
+ register char *mem;
+
+ num *= size;
+ mem = malloc (num);
+ if (mem != 0)
+ bzero (mem, num);
+ return mem;
+}
+
+#ifndef VMS
+
+char *
+memalign (alignment, size)
+ unsigned alignment, size;
+{
+ register char *ptr = malloc (size + alignment);
+ register char *aligned;
+ register struct mhead *p;
+
+ if (ptr == 0)
+ return 0;
+ /* If entire block has the desired alignment, just accept it. */
+ if (((int) ptr & (alignment - 1)) == 0)
+ return ptr;
+ /* Otherwise, get address of byte in the block that has that alignment. */
+ aligned = (char *) (((int) ptr + alignment - 1) & -alignment);
+
+ /* Store a suitable indication of how to free the block,
+ so that free can find the true beginning of it. */
+ p = (struct mhead *) (aligned - ((7 + sizeof (struct mhead)) & ~7));
+ p -> mh_size = aligned - ptr;
+ p -> mh_alloc = ISMEMALIGN;
+ return aligned;
+}
+
+#ifndef HPUX
+/* This runs into trouble with getpagesize on HPUX.
+ Patching out seems cleaner than the ugly fix needed. */
+char *
+valloc (size)
+{
+ return memalign (getpagesize (), size);
+}
+#endif /* not HPUX */
+#endif /* not VMS */
+
+#ifdef MSTATS
+/* Return statistics describing allocation of blocks of size 2**n. */
+
+struct mstats_value
+ {
+ int blocksize;
+ int nfree;
+ int nused;
+ };
+
+struct mstats_value
+malloc_stats (size)
+ int size;
+{
+ struct mstats_value v;
+ register int i;
+ register struct mhead *p;
+
+ v.nfree = 0;
+
+ if (size < 0 || size >= 30)
+ {
+ v.blocksize = 0;
+ v.nused = 0;
+ return v;
+ }
+
+ v.blocksize = 1 << (size + 3);
+ v.nused = nmalloc[size];
+
+ for (p = nextf[size]; p; p = CHAIN (p))
+ v.nfree++;
+
+ return v;
+}
+int
+malloc_mem_used ()
+{
+ int i;
+ int size_used;
+
+ size_used = 0;
+
+ for (i = 0; i < 30; i++)
+ {
+ int allocation_size = 1 << (i + 3);
+ struct mhead *p;
+
+ size_used += nmalloc[i] * allocation_size;
+ }
+
+ return size_used;
+}
+
+int
+malloc_mem_free ()
+{
+ int i;
+ int size_unused;
+
+ size_unused = 0;
+
+ for (i = 0; i < 30; i++)
+ {
+ int allocation_size = 1 << (i + 3);
+ struct mhead *p;
+
+ for (p = nextf[i]; p ; p = CHAIN (p))
+ size_unused += allocation_size;
+ }
+
+ return size_unused;
+}
+#endif /* MSTATS */
+
+/*
+ * This function returns the total number of bytes that the process
+ * will be allowed to allocate via the sbrk(2) system call. On
+ * BSD systems this is the total space allocatable to stack and
+ * data. On USG systems this is the data space only.
+ */
+
+#ifdef USG
+
+get_lim_data ()
+{
+ extern long ulimit ();
+
+#ifdef ULIMIT_BREAK_VALUE
+ lim_data = ULIMIT_BREAK_VALUE;
+#else
+ lim_data = ulimit (3, 0);
+#endif
+
+ lim_data -= (long) data_space_start;
+}
+
+#else /* not USG */
+#if defined (BSD4_1) || defined (VMS)
+
+get_lim_data ()
+{
+ lim_data = vlimit (LIM_DATA, -1);
+}
+
+#else /* not BSD4_1 and not VMS */
+
+get_lim_data ()
+{
+ struct rlimit XXrlimit;
+
+ getrlimit (RLIMIT_DATA, &XXrlimit);
+#ifdef RLIM_INFINITY
+ lim_data = XXrlimit.rlim_cur & RLIM_INFINITY; /* soft limit */
+#else
+ lim_data = XXrlimit.rlim_cur; /* soft limit */
+#endif
+}
+
+#endif /* not BSD4_1 and not VMS */
+#endif /* not USG */
+
+#ifdef VMS
+/* There is a problem when dumping and restoring things on VMS. Calls
+ * to SBRK don't necessarily result in contiguous allocation. Dumping
+ * doesn't work when it isn't. Therefore, we make the initial
+ * allocation contiguous by allocating a big chunk, and do SBRKs from
+ * there. Once Emacs has dumped there is no reason to continue
+ * contiguous allocation, malloc doesn't depend on it.
+ *
+ * There is a further problem of using brk and sbrk while using VMS C
+ * run time library routines malloc, calloc, etc. The documentation
+ * says that this is a no-no, although I'm not sure why this would be
+ * a problem. In any case, we remove the necessity to call brk and
+ * sbrk, by calling calloc (to assure zero filled data) rather than
+ * sbrk.
+ *
+ * VMS_ALLOCATION_SIZE is the size of the allocation array. This
+ * should be larger than the malloc size before dumping. Making this
+ * too large will result in the startup procedure slowing down since
+ * it will require more space and time to map it in.
+ *
+ * The value for VMS_ALLOCATION_SIZE in the following define was determined
+ * by running emacs linked (and a large allocation) with the debugger and
+ * looking to see how much storage was used. The allocation was 201 pages,
+ * so I rounded it up to a power of two.
+ */
+#ifndef VMS_ALLOCATION_SIZE
+#define VMS_ALLOCATION_SIZE (512*256)
+#endif
+
+/* Use VMS RTL definitions */
+#undef sbrk
+#undef brk
+#undef malloc
+int vms_out_initial = 0;
+char vms_initial_buffer[VMS_ALLOCATION_SIZE];
+static char *vms_current_brk = &vms_initial_buffer;
+static char *vms_end_brk = &vms_initial_buffer[VMS_ALLOCATION_SIZE-1];
+
+#include <stdio.h>
+
+char *
+sys_sbrk (incr)
+ int incr;
+{
+ char *sbrk(), *temp, *ptr;
+
+ if (vms_out_initial)
+ {
+ /* out of initial allocation... */
+ if (!(temp = malloc (incr)))
+ temp = (char *) -1;
+ }
+ else
+ {
+ /* otherwise, go out of our area */
+ ptr = vms_current_brk + incr; /* new current_brk */
+ if (ptr <= vms_end_brk)
+ {
+ temp = vms_current_brk;
+ vms_current_brk = ptr;
+ }
+ else
+ {
+ vms_out_initial = 1; /* mark as out of initial allocation */
+ if (!(temp = malloc (incr)))
+ temp = (char *) -1;
+ }
+ }
+ return temp;
+}
+#endif /* VMS */
diff --git a/gnu/lib/libregex/test/fileregex.c b/gnu/lib/libregex/test/fileregex.c
new file mode 100644
index 000000000000..2c27a0f5ddcd
--- /dev/null
+++ b/gnu/lib/libregex/test/fileregex.c
@@ -0,0 +1,77 @@
+#include <sys/types.h>
+#include <stdio.h>
+#include "regex.h"
+
+#define BYTEWIDTH 8
+
+/* Sorry, but this is just a test program. */
+#define LINE_MAX 500
+
+int
+main (argc, argv)
+ int argc;
+ char *argv[];
+{
+ FILE *f;
+ char *filename;
+ char pat[500]; /* Sorry for that maximum size, too. */
+ char line[LINE_MAX];
+ struct re_pattern_buffer buf;
+ char fastmap[(1 << BYTEWIDTH)];
+ const char *compile_ret;
+ unsigned lineno = 1;
+ unsigned nfound = 0;
+
+ /* Actually, it might be useful to allow the data file to be standard
+ input, and to specify the pattern on the command line. */
+ if (argc != 2)
+ {
+ fprintf (stderr, "Usage: %s <filename>.\n", argv[0]);
+ exit (1);
+ }
+
+ filename = argv[1];
+ f = fopen (filename, "r");
+ if (f == NULL)
+ perror (filename);
+
+ buf.allocated = 0;
+ buf.buffer = NULL;
+ buf.fastmap = fastmap;
+
+ printf ("Pattern = ", pat);
+ gets (pat);
+
+ if (feof (stdin))
+ {
+ putchar ('\n');
+ exit (0);
+ }
+
+ compile_ret = re_compile_pattern (pat, strlen (pat), &buf);
+ if (compile_ret != NULL)
+ {
+ fprintf (stderr, "%s: %s\n", pat, compile_ret);
+ exit (1);
+ }
+
+ while (fgets (line, LINE_MAX, f) != NULL)
+ {
+ size_t len = strlen (line);
+ struct re_registers regs;
+ int search_ret
+ = re_search_2 (&buf, NULL, 0, line, len, 0, len, &regs, len);
+
+ if (search_ret == -2)
+ {
+ fprintf (stderr, "%s:%d: re_search failed.\n", filename, lineno);
+ exit (1);
+ }
+
+ nfound += search_ret != -1;
+ lineno++;
+ }
+
+ printf ("Matches found: %u (out of %u lines).\n", nfound, lineno - 1);
+ return 0;
+}
diff --git a/gnu/lib/libregex/test/g++malloc.c b/gnu/lib/libregex/test/g++malloc.c
new file mode 100644
index 000000000000..d55ce45643d3
--- /dev/null
+++ b/gnu/lib/libregex/test/g++malloc.c
@@ -0,0 +1,1288 @@
+#define inline
+
+/*
+Copyright (C) 1989 Free Software Foundation
+ written by Doug Lea (dl@oswego.edu)
+
+This file is part of GNU CC.
+
+GNU CC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY. No author or distributor
+accepts responsibility to anyone for the consequences of using it
+or for whether it serves any particular purpose or works at all,
+unless he says so in writing. Refer to the GNU CC General Public
+License for full details.
+
+Everyone is granted permission to copy, modify and redistribute
+GNU CC, but only under the conditions described in the
+GNU CC General Public License. A copy of this license is
+supposed to have been given to you along with GNU CC so you
+can know your rights and responsibilities. It should be in a
+file named COPYING. Among other things, the copyright notice
+and this notice must be preserved on all copies.
+*/
+
+
+
+#ifndef NO_LIBGXX_MALLOC /* ignore whole file otherwise */
+
+/* compile with -DMALLOC_STATS to collect statistics */
+/* collecting statistics slows down malloc by at least 15% */
+
+#ifdef MALLOC_STATS
+#define UPDATE_STATS(ARGS) {ARGS;}
+#else
+#define UPDATE_STATS(ARGS)
+#endif
+
+/* History
+
+
+ Tue Jan 16 04:54:27 1990 Doug Lea (dl at g.oswego.edu)
+
+ version 1 released in libg++
+
+ Sun Jan 21 05:52:47 1990 Doug Lea (dl at g.oswego.edu)
+
+ bins are now own struct for, sanity.
+
+ new victim search strategy: scan up and consolidate.
+ Both faster and less fragmentation.
+
+ refined when to scan bins for consolidation, via consollink, etc.
+
+ realloc: always try to expand chunk, avoiding some fragmentation.
+
+ changed a few inlines into macros
+
+ hardwired SBRK_UNIT to 4096 for uniformity across systems
+
+ Tue Mar 20 14:18:23 1990 Doug Lea (dl at g.oswego.edu)
+
+ calloc and cfree now correctly parameterized.
+
+ Sun Apr 1 10:00:48 1990 Doug Lea (dl at g.oswego.edu)
+
+ added memalign and valloc.
+
+ Sun Jun 24 05:46:48 1990 Doug Lea (dl at g.oswego.edu)
+
+ #include gepagesize.h only ifndef sun
+ cache pagesize after first call
+
+ Wed Jul 25 08:35:19 1990 Doug Lea (dl at g.oswego.edu)
+
+ No longer rely on a `designated victim':
+
+ 1. It sometimes caused splits of large chunks
+ when smaller ones would do, leading to
+ bad worst-case fragmentation.
+
+ 2. Scanning through the av array fast anyway,
+ so the overhead isn't worth it.
+
+ To compensate, several other minor changes:
+
+ 1. Unusable chunks are checked for consolidation during
+ searches inside bins, better distributing chunks
+ across bins.
+
+ 2. Chunks are returned when found in malloc_find_space,
+ rather than finishing cleaning everything up, to
+ avoid wasted iterations due to (1).
+*/
+
+/*
+ A version of malloc/free/realloc tuned for C++ applications.
+
+ Here's what you probably want to know first:
+
+ In various tests, this appears to be about as fast as,
+ and usually substantially less memory-wasteful than BSD/GNUemacs malloc.
+
+ Generally, it is slower (by perhaps 20%) than bsd-style malloc
+ only when bsd malloc would waste a great deal of space in
+ fragmented blocks, which this malloc recovers; or when, by
+ chance or design, nearly all requests are near the bsd malloc
+ power-of-2 allocation bin boundaries, and as many chunks are
+ used as are allocated.
+
+ It uses more space than bsd malloc only when, again by chance
+ or design, only bsdmalloc bin-sized requests are malloced, or when
+ little dynamic space is malloced, since this malloc may grab larger
+ chunks from the system at a time than bsd.
+
+ In other words, this malloc seems generally superior to bsd
+ except perhaps for programs that are specially tuned to
+ deal with bsdmalloc's characteristics. But even here, the
+ performance differences are slight.
+
+
+ This malloc, like any other, is a compromised design.
+
+
+ Chunks of memory are maintained using a `boundary tag' method as
+ described in e.g., Knuth or Standish. This means that the size of
+ the chunk is stored both in the front of the chunk and at the end.
+ This makes consolidating fragmented chunks into bigger chunks very fast.
+ The size field is also used to hold bits representing whether a
+ chunk is free or in use.
+
+ Malloced chunks have space overhead of 8 bytes: The preceding
+ and trailing size fields. When they are freed, the list pointer
+ fields are also needed.
+
+ Available chunks are kept in doubly linked lists. The lists are
+ maintained in an array of bins using a power-of-two method, except
+ that instead of 32 bins (one for each 1 << i), there are 128: each
+ power of two is split in quarters. The use of very fine bin sizes
+ closely approximates the use of one bin per actually used size,
+ without necessitating the overhead of locating such bins. It is
+ especially desirable in common C++ applications where large numbers
+ of identically-sized blocks are malloced/freed in some dynamic
+ manner, and then later are all freed. The finer bin sizes make
+ finding blocks fast, with little wasted overallocation. The
+ consolidation methods ensure that once the collection of blocks is
+ no longer useful, fragments are gathered into bigger chunks awaiting new
+ roles.
+
+ The bins av[i] serve as heads of the lists. Bins contain a dummy
+ header for the chunk lists, and a `dirty' field used to indicate
+ whether the list may need to be scanned for consolidation.
+
+ On allocation, the bin corresponding to the request size is
+ scanned, and if there is a chunk with size >= requested, it
+ is split, if too big, and used. Chunks on the list which are
+ too small are examined for consolidation during this traversal.
+
+ If no chunk exists in the list bigger bins are scanned in search of
+ a victim.
+
+ If no victim can be found, then smaller bins are examined for
+ consolidation in order to construct a victim.
+
+ Finally, if consolidation fails to come up with a usable chunk,
+ more space is obtained from the system.
+
+ After a split, the remainder is placed on
+ the back of the appropriate bin list. (All freed chunks are placed
+ on fronts of lists. All remaindered or consolidated chunks are
+ placed on the rear. Correspondingly, searching within a bin
+ starts at the front, but finding victims is from the back. All
+ of this approximates the effect of having 2 kinds of lists per
+ bin: returned chunks vs unallocated chunks, but without the overhead
+ of maintaining 2 lists.)
+
+ Deallocation (free) consists only of placing the chunk on
+ a list.
+
+ Reallocation proceeds in the usual way. If a chunk can be extended,
+ it is, else a malloc-copy-free sequence is taken.
+
+ memalign requests more than enough space from malloc, finds a
+ spot within that chunk that meets the alignment request, and
+ then possibly frees the leading and trailing space. Overreliance
+ on memalign is a sure way to fragment space.
+
+
+ Some other implementation matters:
+
+ 8 byte alignment is currently hardwired into the design. Calling
+ memalign will return a chunk that is both 8-byte aligned, and
+ meets the requested alignment.
+
+ The basic overhead of a used chunk is 8 bytes: 4 at the front and
+ 4 at the end.
+
+ When a chunk is free, 8 additional bytes are needed for free list
+ pointers. Thus, the minimum allocatable size is 16 bytes.
+
+ The existence of front and back overhead permits some reasonably
+ effective fence-bashing checks: The front and back fields must
+ be identical. This is checked only within free() and realloc().
+ The checks are fast enough to be made non-optional.
+
+ The overwriting of parts of freed memory with the freelist pointers
+ can also be very effective (albeit in an annoying way) in helping
+ users track down dangling pointers.
+
+ User overwriting of freed space will often result in crashes
+ within malloc or free.
+
+ These routines are also tuned to C++ in that free(0) is a noop and
+ a failed malloc automatically calls (*new_handler)().
+
+ malloc(0) returns a pointer to something of the minimum allocatable size.
+
+ Additional memory is gathered from the system (via sbrk) in a
+ way that allows chunks obtained across different sbrk calls to
+ be consolidated, but does not require contiguous memory: Thus,
+ it should be safe to intersperse mallocs with other sbrk calls.
+
+ This malloc is NOT designed to work in multiprocessing applications.
+ No semaphores or other concurrency control are provided to ensure
+ that multiple malloc or free calls don't run at the same time,
+ which could be disasterous.
+
+ VERY heavy use of inlines is made, for clarity. If this malloc
+ is ported via a compiler without inlining capabilities, all
+ inlines should be transformed into macros -- making them non-inline
+ makes malloc at least twice as slow.
+
+
+*/
+
+
+/* preliminaries */
+
+#ifdef __cplusplus
+#include <stdio.h>
+#else
+#include "//usr/include/stdio.h" /* needed for error reporting */
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef USG
+extern void* memset(void*, int, int);
+extern void* memcpy(void*, const void*, int);
+/*inline void bzero(void* s, int l) { memset(s, 0, l); }*/
+#else
+/*extern void bzero(void*, unsigned int);*/
+#endif
+
+/*extern void bcopy(void*, void*, unsigned int);*/
+
+extern void* sbrk(unsigned int);
+
+/* Put this in instead of commmented out stuff above. */
+#define bcopy(s,d,n) memcpy((d),(s),(n))
+#define bcmp(s1,s2,n) memcmp((s1),(s2),(n))
+#define bzero(s,n) memset((s),0,(n))
+
+
+#ifdef __GNUC__
+extern volatile void abort();
+#else
+extern void abort();
+#endif
+
+#ifdef __cplusplus
+}; /* end of extern "C" */
+#endif
+
+
+/* A good multiple to call sbrk with */
+
+#define SBRK_UNIT 4096
+
+
+
+/* how to die on detected error */
+
+#ifdef __GNUC__
+static volatile void malloc_user_error()
+#else
+static void malloc_user_error()
+#endif
+{
+ fputs("malloc/free/realloc: clobbered space detected\n", stderr); abort();
+}
+
+
+
+/* Basic overhead for each malloc'ed chunk */
+
+
+struct malloc_chunk
+{
+ unsigned int size; /* Size in bytes, including overhead. */
+ /* Or'ed with INUSE if in use. */
+
+ struct malloc_chunk* fd; /* double links -- used only if free. */
+ struct malloc_chunk* bk;
+
+};
+
+typedef struct malloc_chunk* mchunkptr;
+
+struct malloc_bin
+{
+ struct malloc_chunk hd; /* dummy list header */
+ unsigned int dirty; /* True if maybe consolidatable */
+ /* Wasting a word here makes */
+ /* sizeof(bin) a power of 2, */
+ /* which makes size2bin() faster */
+};
+
+typedef struct malloc_bin* mbinptr;
+
+
+/* sizes, alignments */
+
+
+#define SIZE_SZ (sizeof(unsigned int))
+#define MALLOC_MIN_OVERHEAD (SIZE_SZ + SIZE_SZ)
+#define MALLOC_ALIGN_MASK (MALLOC_MIN_OVERHEAD - 1)
+
+#define MINSIZE (sizeof(struct malloc_chunk) + SIZE_SZ) /* MUST == 16! */
+
+
+/* pad request bytes into a usable size */
+
+static inline unsigned int request2size(unsigned int request)
+{
+ return (request == 0) ? MINSIZE :
+ ((request + MALLOC_MIN_OVERHEAD + MALLOC_ALIGN_MASK)
+ & ~(MALLOC_ALIGN_MASK));
+}
+
+
+static inline int aligned_OK(void* m)
+{
+ return ((unsigned int)(m) & (MALLOC_ALIGN_MASK)) == 0;
+}
+
+
+/* size field or'd with INUSE when in use */
+#define INUSE 0x1
+
+
+
+/* the bins, initialized to have null double linked lists */
+
+#define MAXBIN 120 /* 1 more than needed for 32 bit addresses */
+
+#define FIRSTBIN (&(av[0]))
+
+static struct malloc_bin av[MAXBIN] =
+{
+ { { 0, &(av[0].hd), &(av[0].hd) }, 0 },
+ { { 0, &(av[1].hd), &(av[1].hd) }, 0 },
+ { { 0, &(av[2].hd), &(av[2].hd) }, 0 },
+ { { 0, &(av[3].hd), &(av[3].hd) }, 0 },
+ { { 0, &(av[4].hd), &(av[4].hd) }, 0 },
+ { { 0, &(av[5].hd), &(av[5].hd) }, 0 },
+ { { 0, &(av[6].hd), &(av[6].hd) }, 0 },
+ { { 0, &(av[7].hd), &(av[7].hd) }, 0 },
+ { { 0, &(av[8].hd), &(av[8].hd) }, 0 },
+ { { 0, &(av[9].hd), &(av[9].hd) }, 0 },
+
+ { { 0, &(av[10].hd), &(av[10].hd) }, 0 },
+ { { 0, &(av[11].hd), &(av[11].hd) }, 0 },
+ { { 0, &(av[12].hd), &(av[12].hd) }, 0 },
+ { { 0, &(av[13].hd), &(av[13].hd) }, 0 },
+ { { 0, &(av[14].hd), &(av[14].hd) }, 0 },
+ { { 0, &(av[15].hd), &(av[15].hd) }, 0 },
+ { { 0, &(av[16].hd), &(av[16].hd) }, 0 },
+ { { 0, &(av[17].hd), &(av[17].hd) }, 0 },
+ { { 0, &(av[18].hd), &(av[18].hd) }, 0 },
+ { { 0, &(av[19].hd), &(av[19].hd) }, 0 },
+
+ { { 0, &(av[20].hd), &(av[20].hd) }, 0 },
+ { { 0, &(av[21].hd), &(av[21].hd) }, 0 },
+ { { 0, &(av[22].hd), &(av[22].hd) }, 0 },
+ { { 0, &(av[23].hd), &(av[23].hd) }, 0 },
+ { { 0, &(av[24].hd), &(av[24].hd) }, 0 },
+ { { 0, &(av[25].hd), &(av[25].hd) }, 0 },
+ { { 0, &(av[26].hd), &(av[26].hd) }, 0 },
+ { { 0, &(av[27].hd), &(av[27].hd) }, 0 },
+ { { 0, &(av[28].hd), &(av[28].hd) }, 0 },
+ { { 0, &(av[29].hd), &(av[29].hd) }, 0 },
+
+ { { 0, &(av[30].hd), &(av[30].hd) }, 0 },
+ { { 0, &(av[31].hd), &(av[31].hd) }, 0 },
+ { { 0, &(av[32].hd), &(av[32].hd) }, 0 },
+ { { 0, &(av[33].hd), &(av[33].hd) }, 0 },
+ { { 0, &(av[34].hd), &(av[34].hd) }, 0 },
+ { { 0, &(av[35].hd), &(av[35].hd) }, 0 },
+ { { 0, &(av[36].hd), &(av[36].hd) }, 0 },
+ { { 0, &(av[37].hd), &(av[37].hd) }, 0 },
+ { { 0, &(av[38].hd), &(av[38].hd) }, 0 },
+ { { 0, &(av[39].hd), &(av[39].hd) }, 0 },
+
+ { { 0, &(av[40].hd), &(av[40].hd) }, 0 },
+ { { 0, &(av[41].hd), &(av[41].hd) }, 0 },
+ { { 0, &(av[42].hd), &(av[42].hd) }, 0 },
+ { { 0, &(av[43].hd), &(av[43].hd) }, 0 },
+ { { 0, &(av[44].hd), &(av[44].hd) }, 0 },
+ { { 0, &(av[45].hd), &(av[45].hd) }, 0 },
+ { { 0, &(av[46].hd), &(av[46].hd) }, 0 },
+ { { 0, &(av[47].hd), &(av[47].hd) }, 0 },
+ { { 0, &(av[48].hd), &(av[48].hd) }, 0 },
+ { { 0, &(av[49].hd), &(av[49].hd) }, 0 },
+
+ { { 0, &(av[50].hd), &(av[50].hd) }, 0 },
+ { { 0, &(av[51].hd), &(av[51].hd) }, 0 },
+ { { 0, &(av[52].hd), &(av[52].hd) }, 0 },
+ { { 0, &(av[53].hd), &(av[53].hd) }, 0 },
+ { { 0, &(av[54].hd), &(av[54].hd) }, 0 },
+ { { 0, &(av[55].hd), &(av[55].hd) }, 0 },
+ { { 0, &(av[56].hd), &(av[56].hd) }, 0 },
+ { { 0, &(av[57].hd), &(av[57].hd) }, 0 },
+ { { 0, &(av[58].hd), &(av[58].hd) }, 0 },
+ { { 0, &(av[59].hd), &(av[59].hd) }, 0 },
+
+ { { 0, &(av[60].hd), &(av[60].hd) }, 0 },
+ { { 0, &(av[61].hd), &(av[61].hd) }, 0 },
+ { { 0, &(av[62].hd), &(av[62].hd) }, 0 },
+ { { 0, &(av[63].hd), &(av[63].hd) }, 0 },
+ { { 0, &(av[64].hd), &(av[64].hd) }, 0 },
+ { { 0, &(av[65].hd), &(av[65].hd) }, 0 },
+ { { 0, &(av[66].hd), &(av[66].hd) }, 0 },
+ { { 0, &(av[67].hd), &(av[67].hd) }, 0 },
+ { { 0, &(av[68].hd), &(av[68].hd) }, 0 },
+ { { 0, &(av[69].hd), &(av[69].hd) }, 0 },
+
+ { { 0, &(av[70].hd), &(av[70].hd) }, 0 },
+ { { 0, &(av[71].hd), &(av[71].hd) }, 0 },
+ { { 0, &(av[72].hd), &(av[72].hd) }, 0 },
+ { { 0, &(av[73].hd), &(av[73].hd) }, 0 },
+ { { 0, &(av[74].hd), &(av[74].hd) }, 0 },
+ { { 0, &(av[75].hd), &(av[75].hd) }, 0 },
+ { { 0, &(av[76].hd), &(av[76].hd) }, 0 },
+ { { 0, &(av[77].hd), &(av[77].hd) }, 0 },
+ { { 0, &(av[78].hd), &(av[78].hd) }, 0 },
+ { { 0, &(av[79].hd), &(av[79].hd) }, 0 },
+
+ { { 0, &(av[80].hd), &(av[80].hd) }, 0 },
+ { { 0, &(av[81].hd), &(av[81].hd) }, 0 },
+ { { 0, &(av[82].hd), &(av[82].hd) }, 0 },
+ { { 0, &(av[83].hd), &(av[83].hd) }, 0 },
+ { { 0, &(av[84].hd), &(av[84].hd) }, 0 },
+ { { 0, &(av[85].hd), &(av[85].hd) }, 0 },
+ { { 0, &(av[86].hd), &(av[86].hd) }, 0 },
+ { { 0, &(av[87].hd), &(av[87].hd) }, 0 },
+ { { 0, &(av[88].hd), &(av[88].hd) }, 0 },
+ { { 0, &(av[89].hd), &(av[89].hd) }, 0 },
+
+ { { 0, &(av[90].hd), &(av[90].hd) }, 0 },
+ { { 0, &(av[91].hd), &(av[91].hd) }, 0 },
+ { { 0, &(av[92].hd), &(av[92].hd) }, 0 },
+ { { 0, &(av[93].hd), &(av[93].hd) }, 0 },
+ { { 0, &(av[94].hd), &(av[94].hd) }, 0 },
+ { { 0, &(av[95].hd), &(av[95].hd) }, 0 },
+ { { 0, &(av[96].hd), &(av[96].hd) }, 0 },
+ { { 0, &(av[97].hd), &(av[97].hd) }, 0 },
+ { { 0, &(av[98].hd), &(av[98].hd) }, 0 },
+ { { 0, &(av[99].hd), &(av[99].hd) }, 0 },
+
+ { { 0, &(av[100].hd), &(av[100].hd) }, 0 },
+ { { 0, &(av[101].hd), &(av[101].hd) }, 0 },
+ { { 0, &(av[102].hd), &(av[102].hd) }, 0 },
+ { { 0, &(av[103].hd), &(av[103].hd) }, 0 },
+ { { 0, &(av[104].hd), &(av[104].hd) }, 0 },
+ { { 0, &(av[105].hd), &(av[105].hd) }, 0 },
+ { { 0, &(av[106].hd), &(av[106].hd) }, 0 },
+ { { 0, &(av[107].hd), &(av[107].hd) }, 0 },
+ { { 0, &(av[108].hd), &(av[108].hd) }, 0 },
+ { { 0, &(av[109].hd), &(av[109].hd) }, 0 },
+
+ { { 0, &(av[110].hd), &(av[110].hd) }, 0 },
+ { { 0, &(av[111].hd), &(av[111].hd) }, 0 },
+ { { 0, &(av[112].hd), &(av[112].hd) }, 0 },
+ { { 0, &(av[113].hd), &(av[113].hd) }, 0 },
+ { { 0, &(av[114].hd), &(av[114].hd) }, 0 },
+ { { 0, &(av[115].hd), &(av[115].hd) }, 0 },
+ { { 0, &(av[116].hd), &(av[116].hd) }, 0 },
+ { { 0, &(av[117].hd), &(av[117].hd) }, 0 },
+ { { 0, &(av[118].hd), &(av[118].hd) }, 0 },
+ { { 0, &(av[119].hd), &(av[119].hd) }, 0 }
+};
+
+/*
+ indexing into bins
+*/
+
+static inline mbinptr size2bin(unsigned int sz)
+{
+ mbinptr b = av;
+ while (sz >= (MINSIZE * 2)) { b += 4; sz >>= 1; } /* find power of 2 */
+ b += (sz - MINSIZE) >> 2; /* find quadrant */
+ return b;
+}
+
+
+
+/* counts maintained if MALLOC_STATS defined */
+
+#ifdef MALLOC_STATS
+
+static unsigned int sbrked_mem;
+static unsigned int requested_mem;
+static unsigned int malloced_mem;
+static unsigned int freed_mem;
+static unsigned int max_used_mem;
+
+static unsigned int n_sbrks;
+static unsigned int n_mallocs;
+static unsigned int n_frees;
+static unsigned int n_reallocs;
+static unsigned int n_reallocs_with_copy;
+static unsigned int n_avail;
+static unsigned int max_inuse;
+
+static unsigned int n_malloc_chunks;
+static unsigned int n_malloc_bins;
+
+static unsigned int n_split;
+static unsigned int n_consol;
+
+
+static void do_malloc_stats(const mchunkptr p)
+{
+ ++n_mallocs;
+ if ((n_mallocs-n_frees) > max_inuse)
+ max_inuse = n_mallocs - n_frees;
+ malloced_mem += (p->size & ~(INUSE));
+ if (malloced_mem - freed_mem > max_used_mem)
+ max_used_mem = malloced_mem - freed_mem;
+}
+
+static void do_free_stats(const mchunkptr p)
+{
+ ++n_frees;
+ freed_mem += (p->size & ~(INUSE));
+}
+
+#endif
+
+
+
+/* Utilities needed below for memalign */
+/* This is redundant with libg++ support, but not if used stand-alone */
+
+static unsigned int gcd(unsigned int a, unsigned int b)
+{
+ unsigned int tmp;
+
+ if (b > a)
+ {
+ tmp = a; a = b; b = tmp;
+ }
+ for(;;)
+ {
+ if (b == 0)
+ return a;
+ else if (b == 1)
+ return b;
+ else
+ {
+ tmp = b;
+ b = a % b;
+ a = tmp;
+ }
+ }
+}
+
+static inline unsigned int lcm(unsigned int x, unsigned int y)
+{
+ return x / gcd(x, y) * y;
+}
+
+
+
+/* maintaining INUSE via size field */
+
+
+#define inuse(p) ((p)->size & INUSE)
+#define set_inuse(p) ((p)->size |= INUSE)
+#define clear_inuse(b) ((p)->size &= ~INUSE)
+
+
+/* operations on malloc_chunk addresses */
+
+
+/* return ptr to next physical malloc_chunk */
+
+#define next_chunk(p) ((mchunkptr)((char*)(p) + (p)->size))
+
+/* return ptr to previous physical malloc_chunk */
+
+#define prev_chunk(p) ((mchunkptr)((char*)(p)-((((int*)(p))[-1]) & ~(INUSE))))
+
+/* place size at front and back of chunk */
+
+
+static inline void set_size(mchunkptr p, unsigned int sz)
+{
+ p->size = *((int*)((char*)(p) + sz - SIZE_SZ)) = sz;
+}
+
+
+
+
+/* conversion from malloc headers to user pointers, and back */
+
+static inline void* chunk2mem(mchunkptr p)
+{
+ void *mem;
+ set_inuse(p);
+mem = (void*)((char*)(p) + SIZE_SZ);
+ return mem;
+}
+
+/* xxxx my own */
+mchunkptr sanity_check(void* mem)
+{
+ mchunkptr p = (mchunkptr)((char*)(mem) - SIZE_SZ);
+
+ /* a quick sanity check */
+ unsigned int sz = p->size & ~(INUSE);
+ if (p->size == sz || sz != *((int*)((char*)(p) + sz - SIZE_SZ)))
+ malloc_user_error();
+
+ return p;
+}
+
+
+
+
+static inline mchunkptr mem2chunk(void* mem)
+{
+ mchunkptr p = (mchunkptr)((char*)(mem) - SIZE_SZ);
+
+ /* a quick sanity check */
+ unsigned int sz = p->size & ~(INUSE);
+ if (p->size == sz || sz != *((int*)((char*)(p) + sz - SIZE_SZ)))
+ malloc_user_error();
+
+ p->size = sz; /* clears INUSE */
+ return p;
+}
+
+
+
+/* maintaining bins & pointers */
+
+
+/* maximum bin actually used */
+
+static mbinptr malloc_maxbin = FIRSTBIN;
+
+
+/* operations on lists inside bins */
+
+
+/* take a chunk off a list */
+
+static inline void unlink(mchunkptr p)
+{
+ mchunkptr b = p->bk;
+ mchunkptr f = p->fd;
+
+ f->bk = b; b->fd = f;
+
+ UPDATE_STATS (--n_avail);
+}
+
+
+
+/* split a chunk and place on the back of a list */
+
+static inline void split(mchunkptr p, unsigned int offset)
+{
+ unsigned int room = p->size - offset;
+ if (room >= MINSIZE)
+ {
+ mbinptr bn = size2bin(room); /* new bin */
+ mchunkptr h = &(bn->hd); /* its head */
+ mchunkptr b = h->bk; /* old back element */
+ mchunkptr t = (mchunkptr)((char*)(p) + offset); /* remaindered chunk */
+
+ /* set size */
+ t->size = *((int*)((char*)(t) + room - SIZE_SZ)) = room;
+
+ /* link up */
+ t->bk = b; t->fd = h; h->bk = b->fd = t;
+
+ /* adjust maxbin (h == b means was empty) */
+ if (h == b && bn > malloc_maxbin) malloc_maxbin = bn;
+
+ /* adjust size of chunk to be returned */
+ p->size = *((int*)((char*)(p) + offset - SIZE_SZ)) = offset;
+
+ UPDATE_STATS ((++n_split, ++n_avail));
+ }
+}
+
+
+
+/* place a consolidated chunk on the back of a list */
+/* like above, except no split */
+
+static inline void consollink(mchunkptr p)
+{
+ mbinptr bn = size2bin(p->size);
+ mchunkptr h = &(bn->hd);
+ mchunkptr b = h->bk;
+
+ p->bk = b; p->fd = h; h->bk = b->fd = p;
+
+ if (h == b && bn > malloc_maxbin) malloc_maxbin = bn;
+
+ UPDATE_STATS(++n_avail);
+}
+
+
+/* place a freed chunk on the front of a list */
+
+static inline void frontlink(mchunkptr p)
+{
+ mbinptr bn = size2bin(p->size);
+ mchunkptr h = &(bn->hd);
+ mchunkptr f = h->fd;
+
+ p->bk = h; p->fd = f; f->bk = h->fd = p;
+
+ if (h == f && bn > malloc_maxbin) malloc_maxbin = bn;
+
+ bn->dirty = 1;
+
+ UPDATE_STATS(++n_avail);
+}
+
+
+
+/* Dealing with sbrk */
+
+
+/* To link consecutive sbrk regions when possible */
+
+static int* last_sbrk_end;
+
+
+/* who to call when sbrk returns failure */
+
+#ifndef NO_NEW_HANDLER
+typedef volatile void (*vfp)();
+#ifdef __cplusplus
+extern "C" vfp __new_handler;
+#else
+extern vfp __new_handler;
+#endif
+#endif
+
+static mchunkptr malloc_from_sys(unsigned nb)
+{
+ mchunkptr p;
+ unsigned int sbrk_size;
+ int* ip;
+
+ /* Minimally, we need to pad with enough space */
+ /* to place dummy size/use fields to ends if needed */
+
+ sbrk_size = ((nb + SBRK_UNIT - 1 + SIZE_SZ + SIZE_SZ)
+ / SBRK_UNIT) * SBRK_UNIT;
+
+ ip = (int*)(sbrk(sbrk_size));
+ if ((char*)ip == (char*)(-1)) /* sbrk returns -1 on failure */
+ {
+#ifndef NO_NEW_HANDLER
+ (*__new_handler) ();
+#endif
+ return 0;
+ }
+
+ UPDATE_STATS ((++n_sbrks, sbrked_mem += sbrk_size));
+
+
+ if (last_sbrk_end != &ip[-1])
+ {
+ /* It's either first time through or someone else called sbrk. */
+ /* Arrange end-markers at front & back */
+
+ /* Shouldn't be necessary, but better to be safe */
+ while (!aligned_OK(ip)) { ++ip; sbrk_size -= SIZE_SZ; }
+
+
+ /* Mark the front as in use to prevent merging. */
+ /* Note we can get away with only 1 word, not MINSIZE overhead here */
+
+ *ip++ = SIZE_SZ | INUSE;
+
+ p = (mchunkptr)ip;
+ set_size(p,sbrk_size - (SIZE_SZ + SIZE_SZ));
+
+ }
+ else
+ {
+ mchunkptr l;
+
+ /* We can safely make the header start at end of prev sbrked chunk. */
+ /* We will still have space left at the end from a previous call */
+ /* to place the end marker, below */
+
+ p = (mchunkptr)(last_sbrk_end);
+ set_size(p, sbrk_size);
+
+
+ /* Even better, maybe we can merge with last fragment: */
+
+ l = prev_chunk(p);
+ if (!inuse(l))
+ {
+ unlink(l);
+ set_size(l, p->size + l->size);
+ p = l;
+ }
+
+ }
+
+ /* mark the end of sbrked space as in use to prevent merging */
+
+ last_sbrk_end = (int*)((char*)p + p->size);
+ *last_sbrk_end = SIZE_SZ | INUSE;
+
+ UPDATE_STATS((++n_avail, ++n_malloc_chunks));
+
+ /* make it safe to unlink in malloc */
+ UPDATE_STATS(++n_avail);
+ p->fd = p->bk = p;
+
+ return p;
+}
+
+
+
+/* Consolidate dirty bins. */
+/* Stop if found a chunk big enough to satisfy current malloc request */
+
+/* (It requires much less bookkeeping to consolidate entire bins */
+/* at once than to keep records of which chunks might be */
+/* consolidatable. So long as the lists are short, which we */
+/* try to ensure via small bin ranges, there is little wasted effort.) */
+
+static mchunkptr malloc_find_space(unsigned int nb)
+{
+ mbinptr b;
+
+ /* first, re-adjust max used bin */
+
+ while (malloc_maxbin >= FIRSTBIN &&
+ malloc_maxbin->hd.bk == &(malloc_maxbin->hd))
+ {
+ malloc_maxbin->dirty = 0;
+ --malloc_maxbin;
+ }
+
+ for (b = malloc_maxbin; b >= FIRSTBIN; --b)
+ {
+ UPDATE_STATS(++n_malloc_bins);
+
+ if (b->dirty)
+ {
+ mchunkptr h = &(b->hd); /* head of list */
+ mchunkptr p = h->fd; /* chunk traverser */
+
+ while (p != h)
+ {
+ mchunkptr nextp = p->fd; /* save, in case of relinks */
+ int consolidated = 0; /* only unlink/relink if consolidated */
+
+ mchunkptr t;
+
+ UPDATE_STATS(++n_malloc_chunks);
+
+ while (!inuse(t = prev_chunk(p))) /* consolidate backward */
+ {
+ if (!consolidated) { consolidated = 1; unlink(p); }
+ if (t == nextp) nextp = t->fd;
+ unlink(t);
+ set_size(t, t->size + p->size);
+ p = t;
+ UPDATE_STATS (++n_consol);
+ }
+
+ while (!inuse(t = next_chunk(p))) /* consolidate forward */
+ {
+ if (!consolidated) { consolidated = 1; unlink(p); }
+ if (t == nextp) nextp = t->fd;
+ unlink(t);
+ set_size(p, p->size + t->size);
+ UPDATE_STATS (++n_consol);
+ }
+
+ if (consolidated)
+ {
+ if (p->size >= nb)
+ {
+ /* make it safe to unlink in malloc */
+ UPDATE_STATS(++n_avail);
+ p->fd = p->bk = p;
+ return p;
+ }
+ else
+ consollink(p);
+ }
+
+ p = nextp;
+
+ }
+
+ b->dirty = 0;
+
+ }
+ }
+
+ /* nothing available - sbrk some more */
+
+ return malloc_from_sys(nb);
+}
+
+
+
+/* Finally, the user-level functions */
+
+void* malloc(unsigned int bytes)
+{
+ unsigned int nb = request2size(bytes); /* padded request size */
+ mbinptr b = size2bin(nb); /* corresponding bin */
+ mchunkptr hd = &(b->hd); /* head of its list */
+ mchunkptr p = hd->fd; /* chunk traverser */
+
+ UPDATE_STATS((requested_mem+=bytes, ++n_malloc_bins));
+
+ /* Try a (near) exact match in own bin */
+ /* clean out unusable but consolidatable chunks in bin while traversing */
+
+ while (p != hd)
+ {
+ UPDATE_STATS(++n_malloc_chunks);
+ if (p->size >= nb)
+ goto found;
+ else /* try to consolidate; same code as malloc_find_space */
+ {
+ mchunkptr nextp = p->fd; /* save, in case of relinks */
+ int consolidated = 0; /* only unlink/relink if consolidated */
+
+ mchunkptr t;
+
+ while (!inuse(t = prev_chunk(p))) /* consolidate backward */
+ {
+ if (!consolidated) { consolidated = 1; unlink(p); }
+ if (t == nextp) nextp = t->fd;
+ unlink(t);
+ set_size(t, t->size + p->size);
+ p = t;
+ UPDATE_STATS (++n_consol);
+ }
+
+ while (!inuse(t = next_chunk(p))) /* consolidate forward */
+ {
+ if (!consolidated) { consolidated = 1; unlink(p); }
+ if (t == nextp) nextp = t->fd;
+ unlink(t);
+ set_size(p, p->size + t->size);
+ UPDATE_STATS (++n_consol);
+ }
+
+ if (consolidated)
+ {
+ if (p->size >= nb)
+ {
+ /* make it safe to unlink again below */
+ UPDATE_STATS(++n_avail);
+ p->fd = p->bk = p;
+ goto found;
+ }
+ else
+ consollink(p);
+ }
+
+ p = nextp;
+
+ }
+ }
+
+ b->dirty = 0; /* true if got here */
+
+ /* Scan bigger bins for a victim */
+
+ while (++b <= malloc_maxbin)
+ {
+ UPDATE_STATS(++n_malloc_bins);
+ if ((p = b->hd.bk) != &(b->hd)) /* no need to check size */
+ goto found;
+ }
+
+ /* Consolidate or sbrk */
+
+ p = malloc_find_space(nb);
+
+ if (p == 0) return 0; /* allocation failure */
+
+ found: /* Use what we found */
+
+ unlink(p);
+ split(p, nb);
+ UPDATE_STATS(do_malloc_stats(p));
+ return chunk2mem(p);
+}
+
+
+
+
+void free(void* mem)
+{
+ if (mem != 0)
+ {
+ mchunkptr p = mem2chunk(mem);
+ UPDATE_STATS(do_free_stats(p));
+ frontlink(p);
+ }
+}
+
+
+void* calloc(unsigned int n, unsigned int elem_size)
+{
+ unsigned int sz = n * elem_size;
+ void* p = malloc(sz);
+ bzero(p, sz);
+ return p;
+};
+
+/* This is here for compatibility with older systems */
+void cfree(void *mem)
+{
+ free(mem);
+}
+
+
+unsigned int malloc_usable_size(void* mem)
+{
+ if (mem == 0)
+ return 0;
+ else
+ {
+ mchunkptr p = (mchunkptr)((char*)(mem) - SIZE_SZ);
+ unsigned int sz = p->size & ~(INUSE);
+ if (p->size == sz || sz != *((int*)((char*)(p) + sz - SIZE_SZ)))
+ return 0;
+ else
+ return sz - MALLOC_MIN_OVERHEAD;
+ }
+}
+
+
+
+void* realloc(void* mem, unsigned int bytes)
+{
+ if (mem == 0)
+ return malloc(bytes);
+ else
+ {
+ unsigned int nb = request2size(bytes);
+ mchunkptr p = mem2chunk(mem);
+ unsigned int oldsize = p->size;
+ int room;
+ mchunkptr nxt;
+
+ UPDATE_STATS((++n_reallocs, requested_mem += bytes-oldsize));
+
+ /* try to expand (even if already big enough), to clean up chunk */
+
+ while (!inuse(nxt = next_chunk(p)))
+ {
+ UPDATE_STATS ((malloced_mem += nxt->size, ++n_consol));
+ unlink(nxt);
+ set_size(p, p->size + nxt->size);
+ }
+
+ room = p->size - nb;
+ if (room >= 0)
+ {
+ split(p, nb);
+ UPDATE_STATS(malloced_mem -= room);
+ return chunk2mem(p);
+ }
+ else /* do the obvious */
+ {
+ void* newmem;
+ set_inuse(p); /* don't let malloc consolidate us yet! */
+ newmem = malloc(nb);
+ bcopy(mem, newmem, oldsize - SIZE_SZ);
+ free(mem);
+ UPDATE_STATS(++n_reallocs_with_copy);
+ return newmem;
+ }
+ }
+}
+
+
+
+/* return a pointer to space with at least the alignment requested */
+
+void* memalign(unsigned int alignment, unsigned int bytes)
+{
+ mchunkptr p;
+ unsigned int nb = request2size(bytes);
+
+ /* find an alignment that both we and the user can live with: */
+ /* least common multiple guarantees mutual happiness */
+ unsigned int align = lcm(alignment, MALLOC_MIN_OVERHEAD);
+ unsigned int mask = align - 1;
+
+ /* call malloc with worst case padding to hit alignment; */
+ /* we will give back extra */
+
+ unsigned int req = nb + align + MINSIZE;
+ void* m = malloc(req);
+
+ if (m == 0) return m;
+
+ p = mem2chunk(m);
+
+ /* keep statistics on track */
+
+ UPDATE_STATS(--n_mallocs);
+ UPDATE_STATS(malloced_mem -= p->size);
+ UPDATE_STATS(requested_mem -= req);
+ UPDATE_STATS(requested_mem += bytes);
+
+ if (((int)(m) & (mask)) != 0) /* misaligned */
+ {
+
+ /* find an aligned spot inside chunk */
+
+ mchunkptr ap = (mchunkptr)(( ((int)(m) + mask) & -align) - SIZE_SZ);
+
+ unsigned int gap = (unsigned int)(ap) - (unsigned int)(p);
+ unsigned int room;
+
+ /* we need to give back leading space in a chunk of at least MINSIZE */
+
+ if (gap < MINSIZE)
+ {
+ /* This works since align >= MINSIZE */
+ /* and we've malloc'd enough total room */
+
+ ap = (mchunkptr)( (int)(ap) + align );
+ gap += align;
+ }
+
+ if (gap + nb > p->size) /* can't happen unless chunk sizes corrupted */
+ malloc_user_error();
+
+ room = p->size - gap;
+
+ /* give back leader */
+ set_size(p, gap);
+ consollink(p);
+
+ /* use the rest */
+ p = ap;
+ set_size(p, room);
+ }
+
+ /* also give back spare room at the end */
+
+ split(p, nb);
+ UPDATE_STATS(do_malloc_stats(p));
+ return chunk2mem(p);
+
+}
+
+#ifndef sun
+#include "getpagesize.h"
+#endif
+
+static unsigned int malloc_pagesize = 0;
+
+void* valloc(unsigned int bytes)
+{
+ if (malloc_pagesize == 0) malloc_pagesize = getpagesize();
+ return memalign (malloc_pagesize, bytes);
+}
+
+
+void malloc_stats()
+{
+#ifndef MALLOC_STATS
+}
+#else
+ int i;
+ mchunkptr p;
+ double nm = (double)(n_mallocs + n_reallocs);
+
+ fprintf(stderr, "\nmalloc statistics\n\n");
+
+ if (n_mallocs != 0)
+ fprintf(stderr, "requests = %10u total size = %10u\tave = %10u\n",
+ n_mallocs, requested_mem, requested_mem/n_mallocs);
+
+ if (n_mallocs != 0)
+ fprintf(stderr, "mallocs = %10u total size = %10u\tave = %10u\n",
+ n_mallocs, malloced_mem, malloced_mem/n_mallocs);
+
+ if (n_frees != 0)
+ fprintf(stderr, "frees = %10u total size = %10u\tave = %10u\n",
+ n_frees, freed_mem, freed_mem/n_frees);
+
+ if (n_mallocs-n_frees != 0)
+ fprintf(stderr, "in use = %10u total size = %10u\tave = %10u\n",
+ n_mallocs-n_frees, malloced_mem-freed_mem,
+ (malloced_mem-freed_mem) / (n_mallocs-n_frees));
+
+ if (max_inuse != 0)
+ fprintf(stderr, "max in use= %10u total size = %10u\tave = %10u\n",
+ max_inuse, max_used_mem, max_used_mem / max_inuse);
+
+ if (n_avail != 0)
+ fprintf(stderr, "available = %10u total size = %10u\tave = %10u\n",
+ n_avail, sbrked_mem - (malloced_mem-freed_mem),
+ (sbrked_mem - (malloced_mem-freed_mem)) / n_avail);
+
+ if (n_sbrks != 0)
+ fprintf(stderr, "sbrks = %10u total size = %10u\tave = %10u\n\n",
+ n_sbrks, sbrked_mem, sbrked_mem/ n_sbrks);
+
+ if (n_reallocs != 0)
+ fprintf(stderr, "reallocs = %10u with copy = %10u\n\n",
+ n_reallocs, n_reallocs_with_copy);
+
+
+ if (nm != 0)
+ {
+ fprintf(stderr, "chunks scanned per malloc = %6.3f\n",
+ n_malloc_chunks / nm);
+ fprintf(stderr, "bins scanned per malloc = %6.3f\n",
+ n_malloc_bins / nm);
+ fprintf(stderr, "splits per malloc = %6.3f\n",
+ n_split / nm);
+ fprintf(stderr, "consolidations per malloc = %6.3f\n",
+ n_consol / nm);
+ }
+
+ fprintf(stderr, "\nfree chunks:\n");
+ for (i = 0; i < MAXBIN; ++i)
+ {
+ p = av[i].hd.fd;
+ if (p != &(av[i].hd))
+ {
+ unsigned int count = 1;
+ unsigned int sz = p->size;
+ for (p = p->fd; p != &(av[i].hd); p = p->fd)
+ {
+ if (p->size == sz)
+ ++count;
+ else
+ {
+ fprintf(stderr, "\tsize = %10u count = %5u\n", sz, count);
+ count = 1;
+ sz = p->size;
+ }
+ }
+
+ fprintf(stderr, "\tsize = %10u count = %5u\n", sz, count);
+
+ }
+ }
+}
+#endif /* MALLOC_STATS */
+
+#endif /* NO_LIBGXX_MALLOC */
+
+
diff --git a/gnu/lib/libregex/test/getpagesize.h b/gnu/lib/libregex/test/getpagesize.h
new file mode 100644
index 000000000000..32adae61efa2
--- /dev/null
+++ b/gnu/lib/libregex/test/getpagesize.h
@@ -0,0 +1,25 @@
+#ifdef BSD
+#ifndef BSD4_1
+#define HAVE_GETPAGESIZE
+#endif
+#endif
+
+#ifndef HAVE_GETPAGESIZE
+
+#include <sys/param.h>
+
+#ifdef EXEC_PAGESIZE
+#define getpagesize() EXEC_PAGESIZE
+#else
+#ifdef NBPG
+#define getpagesize() NBPG * CLSIZE
+#ifndef CLSIZE
+#define CLSIZE 1
+#endif /* no CLSIZE */
+#else /* no NBPG */
+#define getpagesize() NBPC
+#endif /* no NBPG */
+#endif /* no EXEC_PAGESIZE */
+
+#endif /* not HAVE_GETPAGESIZE */
+
diff --git a/gnu/lib/libregex/test/iregex.c b/gnu/lib/libregex/test/iregex.c
new file mode 100644
index 000000000000..2346d441fcdb
--- /dev/null
+++ b/gnu/lib/libregex/test/iregex.c
@@ -0,0 +1,164 @@
+/* Main program for interactive testing. For maximum output, compile
+ this and regex.c with -DDEBUG. */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include "regex.h"
+
+/* Don't bother to guess about <string.h> vs <strings.h>, etc. */
+extern int strlen ();
+
+#define BYTEWIDTH 8
+
+extern void printchar ();
+extern char upcase[];
+
+static void scanstring ();
+static void print_regs ();
+
+int
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ int i;
+ struct re_pattern_buffer buf;
+ char fastmap[(1 << BYTEWIDTH)];
+
+ /* Allow a command argument to specify the style of syntax. You can
+ use the `syntax' program to decode integer syntax values. */
+ if (argc > 1)
+ re_set_syntax (atoi (argv[1]));
+
+ buf.allocated = 0;
+ buf.buffer = NULL;
+ buf.fastmap = fastmap;
+ buf.translate = upcase;
+
+ for (;;)
+ {
+ char pat[500], str[500];
+ struct re_registers regs;
+
+ /* Some C compilers don't like `char pat[500] = ""'. */
+ pat[0] = 0;
+
+ printf ("Pattern (%s) = ", pat);
+ gets (pat);
+ scanstring (pat);
+
+ if (feof (stdin))
+ {
+ putchar ('\n');
+ exit (0);
+ }
+
+ if (*pat)
+ {
+ re_compile_pattern (pat, strlen (pat), &buf);
+ re_compile_fastmap (&buf);
+#ifdef DEBUG
+ print_compiled_pattern (&buf);
+#endif
+ }
+
+ printf ("String = ");
+ gets (str); /* Now read the string to match against */
+ scanstring (str);
+
+ i = re_match (&buf, str, strlen (str), 0, &regs);
+ printf ("Match value %d.\t", i);
+ if (i >= 0)
+ print_regs (regs);
+ putchar ('\n');
+
+ i = re_search (&buf, str, strlen (str), 0, strlen (str), &regs);
+ printf ("Search value %d.\t", i);
+ if (i >= 0)
+ print_regs (regs);
+ putchar ('\n');
+ }
+
+ /* We never get here, but what the heck. */
+ return 0;
+}
+
+void
+scanstring (s)
+ char *s;
+{
+ char *write = s;
+
+ while (*s != '\0')
+ {
+ if (*s == '\\')
+ {
+ s++;
+
+ switch (*s)
+ {
+ case '\0':
+ break;
+
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ *write = *s++ - '0';
+
+ if ('0' <= *s && *s <= '9')
+ {
+ *write = (*write << 3) + (*s++ - '0');
+ if ('0' <= *s && *s <= '9')
+ *write = (*write << 3) + (*s++ - '0');
+ }
+ write++;
+ break;
+
+ case 'n':
+ *write++ = '\n';
+ s++;
+ break;
+
+ case 't':
+ *write++ = '\t';
+ s++;
+ break;
+
+ default:
+ *write++ = *s++;
+ break;
+ }
+ }
+ else
+ *write++ = *s++;
+ }
+
+ *write++ = '\0';
+}
+
+/* Print REGS in human-readable form. */
+
+void
+print_regs (regs)
+ struct re_registers regs;
+{
+ int i, end;
+
+ printf ("Registers: ");
+
+ if (regs.num_regs == 0 || regs.start[0] == -1)
+ {
+ printf ("(none)");
+ }
+ else
+ {
+ /* Find the last register pair that matched. */
+ for (end = regs.num_regs - 1; end >= 0; end--)
+ if (regs.start[end] != -1)
+ break;
+
+ printf ("[%d ", regs.start[0]);
+ for (i = 1; i <= end; i++)
+ printf ("(%d %d) ", regs.start[i], regs.end[i]);
+ printf ("%d]", regs.end[0]);
+ }
+}
diff --git a/gnu/lib/libregex/test/main.c b/gnu/lib/libregex/test/main.c
new file mode 100644
index 000000000000..28ae31528579
--- /dev/null
+++ b/gnu/lib/libregex/test/main.c
@@ -0,0 +1,49 @@
+/* Main routine for running various tests. Meant only to be linked with
+ all the auxiliary test source files, with `test' undefined. */
+
+#include "test.h"
+
+test_type t = all_test;
+
+
+/* Use this to run the tests we've thought of. */
+
+int
+main ()
+{
+ switch (t)
+ {
+ case all_test:
+ test_regress ();
+ test_others ();
+ test_posix_basic ();
+ test_posix_extended ();
+ test_posix_interface ();
+ break;
+
+ case other_test:
+ test_others ();
+ break;
+
+ case posix_basic_test:
+ test_posix_basic ();
+ break;
+
+ case posix_extended_test:
+ test_posix_extended ();
+ break;
+
+ case posix_interface_test:
+ test_posix_interface ();
+ break;
+
+ case regress_test:
+ test_regress ();
+ break;
+
+ default:
+ fprintf (stderr, "Unknown test %d.\n", t);
+ }
+
+ return 0;
+}
diff --git a/gnu/lib/libregex/test/malloc-test.c b/gnu/lib/libregex/test/malloc-test.c
new file mode 100644
index 000000000000..7e27a15a8905
--- /dev/null
+++ b/gnu/lib/libregex/test/malloc-test.c
@@ -0,0 +1,47 @@
+
+
+typedef struct {
+ unsigned *bits;
+ unsigned size;
+} bits_list_type;
+
+#define BYTEWIDTH 8
+#define NULL 0
+
+#define BITS_BLOCK_SIZE (sizeof (unsigned) * BYTEWIDTH)
+#define BITS_BLOCK(position) ((position) / BITS_BLOCK_SIZE)
+#define BITS_MASK(position) (1 << ((position) % BITS_BLOCK_SIZE))
+
+static unsigned
+init_bits_list (bits_list_ptr)
+ bits_list_type *bits_list_ptr;
+{
+ bits_list_ptr->bits = NULL;
+ bits_list_ptr->bits = (unsigned *) malloc (sizeof (unsigned));
+
+ if (bits_list_ptr->bits == NULL)
+ return 0;
+
+ bits_list_ptr->bits[0] = (unsigned)0;
+ bits_list_ptr->size = BITS_BLOCK_SIZE;
+
+ return 1;
+}
+
+
+main()
+{
+ bits_list_type dummy;
+ bits_list_type dummy_1;
+ bits_list_type dummy_2;
+ bits_list_type dummy_3;
+
+ init_bits_list (&dummy);
+printf("init 1\n");
+ init_bits_list (&dummy_1);
+printf("init 2\n");
+ init_bits_list (&dummy_2);
+printf("init 3\n");
+ init_bits_list (&dummy_3);
+printf("init 4\n");
+}
diff --git a/gnu/lib/libregex/test/other.c b/gnu/lib/libregex/test/other.c
new file mode 100644
index 000000000000..d2ceb3844883
--- /dev/null
+++ b/gnu/lib/libregex/test/other.c
@@ -0,0 +1,503 @@
+/* other.c: test (not exhaustively) non-POSIX regular expressions. */
+
+#include "test.h"
+
+void
+test_others ()
+{
+ struct re_registers regs;
+
+ printf ("\nStarting non-POSIX tests.\n");
+ t = other_test;
+
+ test_should_match = true;
+
+ /* The big question: does the group participate in the match, or match
+ the empty string? */
+ re_set_syntax (RE_NO_BK_PARENS);
+ test_match ("(a*)*ab", "ab");
+ TEST_REGISTERS ("(a*)*ab", "ab", 0, 2, 0, 0, -1, -1);
+ test_match ("(a*)*", "");
+ TEST_REGISTERS ("(a*)*ab", "ab", 0, 0, 0, 0, -1, -1);
+
+ /* This tests finding the highest and lowest active registers. */
+ test_match ("(a(b)c(d(e)f)g)h(i(j)k(l(m)n)o)\\1\\2\\3\\4\\5\\6\\7\\8",
+ "abcdefghijklmnoabcdefgbdefeijklmnojlmnm");
+
+ /* Test that \< and \> match at the beginning and end of the string. */
+ test_match ("\\<abc\\>", "abc");
+
+ /* May as well test \` and \' while we're at it. */
+ test_match ("\\`abc\\'", "abc");
+
+#if 0
+ /* Test backreferencing and the fastmap -- which doesn't work. */
+ test_fastmap ("(a)*\\1", "a", 0, 0);
+#endif
+
+ /* But at least we shouldn't search improperly. */
+ test_search_return (-1, "(a)\\1", "");
+
+ re_set_syntax (RE_SYNTAX_EMACS);
+
+ MATCH_SELF("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
+ MATCH_SELF ("a^");
+ MATCH_SELF ("a^b");
+ MATCH_SELF ("$a");
+ MATCH_SELF ("a$b");
+
+ re_set_syntax (RE_BACKSLASH_ESCAPE_IN_LISTS);
+ test_match ("[\\^a]", "a");
+ test_match ("[\\^a]", "^");
+
+ /* These op characters should be ordinary if RE_CONTEXT_INVALID_OPS
+ isn't set. */
+ re_set_syntax (RE_NO_BK_VBAR | RE_NO_BK_BRACES | RE_INTERVALS
+ | RE_NO_BK_PARENS);
+ MATCH_SELF ("*");
+ test_match ("a|*", "*");
+ test_match ("(*)", "*");
+
+ MATCH_SELF ("+");
+ test_match ("a|+", "+");
+ test_match ("(+)", "+");
+
+ MATCH_SELF ("?");
+ test_match ("a|?", "?");
+ test_match ("(?)", "?");
+
+ MATCH_SELF ("{1}");
+ test_match ("a|{1}", "a");
+ test_match ("a|{1}", "{1}");
+ test_match ("({1})", "{1}");
+
+ test_match ("\\{", "{");
+
+
+ re_set_syntax (RE_LIMITED_OPS);
+ MATCH_SELF ("|");
+ MATCH_SELF ("a|");
+ MATCH_SELF ("a|");
+ MATCH_SELF ("a||");
+ MATCH_SELF ("a||");
+ MATCH_SELF ("(|)");
+
+ re_set_syntax (RE_SYNTAX_EMACS);
+ TEST_SEARCH ("^a", "b\na", 0, 3);
+ TEST_SEARCH ("b$", "b\na", 0, 3);
+
+#if 0
+ /* Newline is no longer special for anchors (16 Sep 92). --karl */
+ test_match_2 ("a\n^b", "a", "\nb");
+ test_match_2 ("a$\nb", "a\n", "b");
+#endif
+
+ /* Test grouping. */
+ re_set_syntax (RE_NO_BK_PARENS);
+
+ test_match ("()", "");
+ test_fastmap ("()", "", 0, 0);
+ TEST_REGISTERS ("()", "", 0, 0, 0, 0, -1, -1);
+
+ test_match ("((((((((()))))))))", "");
+ test_fastmap ("((((((((()))))))))", "", 0, 0);
+ test_match ("a()b", "ab");
+ TEST_REGISTERS ("a()b", "ab", 0, 2, 1, 1, -1, -1);
+
+ test_match ("(((((((((())))))))))", "");
+ test_fastmap ("(((((((((())))))))))", "", 0, 0);
+
+ test_match ("()*", "");
+ TEST_REGISTERS ("()*", "", 0, 0, 0, 0, -1, -1); /* empty string */
+ test_match ("(())*", "");
+
+ re_set_syntax (RE_CONTEXT_INDEP_OPS);
+ test_match ("*", "");
+
+ re_set_syntax (RE_INTERVALS | RE_CONTEXT_INDEP_OPS | RE_NO_BK_BRACES);
+ test_match ("{1}", ""); /* Should remain an interval. */
+ MATCH_SELF ("{1"); /* Not a valid interval. */
+
+ re_set_syntax (RE_NEWLINE_ALT);
+ test_match ("a\nb", "a");
+ test_match ("a\nb", "b");
+
+ re_set_syntax (RE_NO_BK_VBAR | RE_NO_BK_PARENS);
+ test_match ("^a", "a");
+ test_match ("(^a)", "a");
+ test_match ("(a|^b)", "b");
+ test_match ("a$", "a");
+ test_match ("(a$)", "a");
+ test_match ("a$|b", "a");
+
+ /* You should be able to have empty alternatives if RE_NO_EMPTY_ALTS
+ isn't set. */
+ re_set_syntax (RE_NO_BK_VBAR | RE_NO_BK_PARENS);
+
+ test_match ("|", "");
+ test_match ("^|a", "");
+ test_match ("^|a", "a");
+ test_match ("a|", "");
+ test_match ("a|", "a");
+ test_match ("a|$", "");
+ test_match ("a|$", "a");
+ test_match ("a||b", "a");
+ test_match ("a||b", "");
+ test_match ("a||b", "b");
+ test_match ("(|a)", "");
+ test_match ("(|a)", "a");
+ test_match ("(a|)", "");
+ test_match ("(a|)", "a");
+
+ TEST_SEARCH ("a|$", "xa", 0, 2);
+ TEST_SEARCH ("a|$", "x", 0, 1);
+ TEST_SEARCH ("$|b", "x", 0, 1);
+ TEST_SEARCH ("$|b", "xb", 0, 2);
+ TEST_SEARCH ("c(a|$)", "xca", 0, 3);
+ TEST_SEARCH ("c(a|$)", "xc", 0, 2);
+ TEST_SEARCH ("c($|b)", "xcb", 0, 3);
+ TEST_SEARCH ("c($|b)", "xc", 0, 2);
+ TEST_SEARCH ("c($|b$)", "xcb", 0, 3);
+ TEST_SEARCH ("c($|b$)", "xc", 0, 2);
+ TEST_SEARCH ("c(a$|$)", "xca", 0, 3);
+ TEST_SEARCH ("c(a$|$)", "xc", 0, 2);
+ TEST_SEARCH ("(a$|b$)|$", "x", 0, 1);
+ TEST_SEARCH ("(a$|b$)|$", "xa", 0, 2);
+ TEST_SEARCH ("(a$|b$)|$", "xb", 0, 2);
+ TEST_SEARCH ("(a$|$)|c$", "x", 0, 1);
+ TEST_SEARCH ("(a$|$)|c$", "xa", 0, 2);
+ TEST_SEARCH ("(a$|$)|c$", "xc", 0, 2);
+ TEST_SEARCH ("($|b$)|c$", "x", 0, 1);
+ TEST_SEARCH ("($|b$)|c$", "xb", 0, 2);
+ TEST_SEARCH ("($|b$)|c$", "xc", 0, 2);
+ TEST_SEARCH ("c$|(a$|$)", "x", 0, 1);
+ TEST_SEARCH ("c$|(a$|$)", "xa", 0, 2);
+ TEST_SEARCH ("c$|(a$|$)", "xc", 0, 2);
+ TEST_SEARCH ("c$|($|b$)", "x", 0, 1);
+ TEST_SEARCH ("c$|($|b$)", "xb", 0, 2);
+ TEST_SEARCH ("c$|($|b$)", "xc", 0, 2);
+ TEST_SEARCH ("$|(a$|b$)", "x", 0, 1);
+ TEST_SEARCH ("$|(a$|b$)", "xa", 0, 2);
+ TEST_SEARCH ("$|(a$|b$)", "xb", 0, 2);
+ TEST_SEARCH ("c(a$|b$)|$", "x", 0, 1);
+ TEST_SEARCH ("c(a$|b$)|$", "xca", 0, 3);
+ TEST_SEARCH ("c(a$|b$)|$", "xcb", 0, 3);
+ TEST_SEARCH ("c(a$|$)|d$", "xc", 0, 2);
+ TEST_SEARCH ("c(a$|$)|d$", "xca", 0, 3);
+ TEST_SEARCH ("c(a$|$)|d$", "xd", 0, 2);
+ TEST_SEARCH ("c($|b$)|d$", "xc", 0, 2);
+ TEST_SEARCH ("c($|b$)|d$", "xcb", 0, 3);
+ TEST_SEARCH ("c($|b$)|d$", "xd", 0, 2);
+ TEST_SEARCH ("d(c$|e((a$|$)))", "xdc", 0, 3);
+ TEST_SEARCH ("d(c$|e((a$|$)))", "xde", 0, 3);
+ TEST_SEARCH ("d(c$|e((a$|$)))", "xdea", 0, 4);
+ TEST_SEARCH ("d(c$|e(($|b$)))", "xdc", 0, 3);
+ TEST_SEARCH ("d(c$|e(($|b$)))", "xde", 0, 3);
+ TEST_SEARCH ("d(c$|e(($|b$)))", "xdeb", 0, 4);
+ TEST_SEARCH ("d($|e((a$|b$)))", "xd", 0, 2);
+ TEST_SEARCH ("d($|e((a$|b$)))", "xdea", 0, 4);
+ TEST_SEARCH ("d($|e((a$|b$)))", "xdeb", 0, 4);
+ TEST_SEARCH ("a(b$|c$)|$", "x", 0, 1);
+ TEST_SEARCH ("a(b$|c$)|$", "xab", 0, 3);
+ TEST_SEARCH ("a(b$|c$)|$", "xac", 0, 3);
+ TEST_SEARCH ("a(b$|$)|d$", "xa", 0, 2);
+ TEST_SEARCH ("a(b$|$)|d$", "xab", 0, 3);
+ TEST_SEARCH ("a(b$|$)|d$", "xd", 0, 2);
+ TEST_SEARCH ("a($|c$)|d$", "xa", 0, 2);
+ TEST_SEARCH ("a($|c$)|d$", "xac", 0, 3);
+ TEST_SEARCH ("a($|c$)|d$", "xd", 0, 2);
+ TEST_SEARCH ("d$|a(b$|$)", "xd", 0, 2);
+ TEST_SEARCH ("d$|a(b$|$)", "xa", 0, 2);
+ TEST_SEARCH ("d$|a(b$|$)", "xab", 0, 3);
+ TEST_SEARCH ("d$|a($|c$)", "xd", 0, 2);
+ TEST_SEARCH ("d$|a($|c$)", "xa", 0, 2);
+ TEST_SEARCH ("d$|a($|c$)", "xac", 0, 3);
+ TEST_SEARCH ("$|a(b$|c$)", "x", 0, 1);
+ TEST_SEARCH ("$|a(b$|c$)", "xab", 0, 3);
+ TEST_SEARCH ("$|a(b$|c$)", "xac", 0, 3);
+ TEST_SEARCH ("(a)(b$|c$)|d$", "xab", 0, 3);
+ TEST_SEARCH ("(a)(b$|c$)|d$", "xac", 0, 3);
+ TEST_SEARCH ("(a)(b$|c$)|d$", "xd", 0, 2);
+ TEST_SEARCH ("(a)(b$|$)|d$", "xa", 0, 2);
+ TEST_SEARCH ("(a)(b$|$)|d$", "xab", 0, 3);
+ TEST_SEARCH ("(a)(b$|$)|d$", "xd", 0, 2);
+ TEST_SEARCH ("(a)($|c$)|d$", "xa", 0, 2);
+ TEST_SEARCH ("(a)($|c$)|d$", "xac", 0, 3);
+ TEST_SEARCH ("(a)($|c$)|d$", "xd", 0, 2);
+ TEST_SEARCH ("d$|(a)(b$|$)", "xd", 0, 2);
+ TEST_SEARCH ("d$|(a)(b$|$)", "xa", 0, 2);
+ TEST_SEARCH ("d$|(a)(b$|$)", "xab", 0, 3);
+ TEST_SEARCH ("d$|(a)($|c$)", "xd", 0, 2);
+ TEST_SEARCH ("d$|(a)($|c$)", "xa", 0, 2);
+ TEST_SEARCH ("d$|(a)($|c$)", "xac", 0, 3);
+ TEST_SEARCH ("$|(a)(b$|c$)", "x", 0, 1);
+ TEST_SEARCH ("$|(a)(b$|c$)", "xab", 0, 3);
+ TEST_SEARCH ("$|(a)(b$|c$)", "xac", 0, 3);
+ TEST_SEARCH ("d$|(c$|(a$|$))", "x", 0, 1);
+ TEST_SEARCH ("d$|(c$|(a$|$))", "xd", 0, 2);
+ TEST_SEARCH ("d$|(c$|(a$|$))", "xc", 0, 2);
+ TEST_SEARCH ("d$|(c$|(a$|$))", "xa", 0, 2);
+ TEST_SEARCH ("d$|(c$|($|b$))", "x", 0, 1);
+ TEST_SEARCH ("d$|(c$|($|b$))", "xd", 0, 2);
+ TEST_SEARCH ("d$|(c$|($|b$))", "xc", 0, 2);
+ TEST_SEARCH ("d$|(c$|($|b$))", "xb", 0, 2);
+ TEST_SEARCH ("d$|($|(a$|b$))", "x", 0, 1);
+ TEST_SEARCH ("d$|($|(a$|b$))", "xd", 0, 2);
+ TEST_SEARCH ("d$|($|(a$|b$))", "xa", 0, 2);
+ TEST_SEARCH ("d$|($|(a$|b$))", "xb", 0, 2);
+ TEST_SEARCH ("$|(c$|(a$|b$))", "x", 0, 1);
+ TEST_SEARCH ("$|(c$|(a$|b$))", "xc", 0, 2);
+ TEST_SEARCH ("$|(c$|(a$|b$))", "xa", 0, 2);
+ TEST_SEARCH ("$|(c$|(a$|b$))", "xb", 0, 2);
+ TEST_SEARCH ("d$|c(a$|$)", "xd", 0, 2);
+ TEST_SEARCH ("d$|c(a$|$)", "xc", 0, 2);
+ TEST_SEARCH ("d$|c(a$|$)", "xca", 0, 3);
+ TEST_SEARCH ("d$|c($|b$)", "xd", 0, 2);
+ TEST_SEARCH ("d$|c($|b$)", "xc", 0, 2);
+ TEST_SEARCH ("d$|c($|b$)", "xcb", 0, 3);
+ TEST_SEARCH ("$|c(a$|b$)", "x", 0, 1);
+ TEST_SEARCH ("$|c(a$|b$)", "xca", 0, 3);
+ TEST_SEARCH ("$|c(a$|b$)", "xcb", 0, 3);
+ TEST_SEARCH ("e(d$|c((a$|$)))", "xed", 0, 3);
+ TEST_SEARCH ("e(d$|c((a$|$)))", "xec", 0, 3);
+ TEST_SEARCH ("e(d$|c((a$|$)))", "xeca", 0, 3);
+ TEST_SEARCH ("e(d$|c(($|b$)))", "xed", 0, 3);
+ TEST_SEARCH ("e(d$|c(($|b$)))", "xec", 0, 3);
+ TEST_SEARCH ("e(d$|c(($|b$)))", "xecb", 0, 4);
+ TEST_SEARCH ("e($|c((a$|b$)))", "xe", 0, 2);
+ TEST_SEARCH ("e($|c((a$|b$)))", "xeca", 0, 4);
+ TEST_SEARCH ("e($|c((a$|b$)))", "xecb", 0, 4);
+ TEST_SEARCH ("ed$|(c((a$|$)))", "xed", 0, 3);
+ TEST_SEARCH ("ed$|(c((a$|$)))", "xc", 0, 2);
+ TEST_SEARCH ("ed$|(c((a$|$)))", "xca", 0, 3);
+ TEST_SEARCH ("ed$|(c(($|b$)))", "xed", 0, 3);
+ TEST_SEARCH ("ed$|(c(($|b$)))", "xc", 0, 2);
+ TEST_SEARCH ("ed$|(c(($|b$)))", "xcb", 0, 3);
+ TEST_SEARCH ("$|(c((a$|b$)))", "x", 0, 1);
+ TEST_SEARCH ("$|(c((a$|b$)))", "xca", 0, 3);
+ TEST_SEARCH ("$|(c((a$|b$)))", "xcb", 0, 3);
+ TEST_SEARCH ("d$|($|(a|b)$)", "x", 0, 1);
+ TEST_SEARCH ("d$|($|(a|b)$)", "xa", 0, 2);
+ TEST_SEARCH ("d$|($|(a|b)$)", "xb", 0, 2);
+ TEST_SEARCH ("$|(c$|(a|b)$)", "x", 0, 1);
+ TEST_SEARCH ("$|(c$|(a|b)$)", "xc", 0, 2);
+ TEST_SEARCH ("$|(c$|(a|b)$)", "xa", 0, 2);
+ TEST_SEARCH ("$|(c$|(a|b)$)", "xb", 0, 2);
+
+ re_set_syntax (0);
+ test_match ("[^\n]", "a");
+ test_match ("[^a]", "\n");
+
+ TEST_SEARCH ("^a", "b\na", 0, 3);
+ TEST_SEARCH ("b$", "b\na", 0, 3);
+
+ test_case_fold ("[!-`]", "A");
+ test_case_fold ("[!-`]", "a");
+
+ re_set_syntax (RE_CONTEXT_INDEP_OPS | RE_NO_BK_VBAR | RE_NO_BK_PARENS
+ | RE_NO_BK_BRACES | RE_INTERVALS);
+ valid_nonposix_pattern ("()^a");
+ valid_nonposix_pattern ("()\\1^a");
+
+ /* Per Cederqvist (cedar@lysator.liu.se) bug. */
+
+ re_set_syntax (RE_SYNTAX_EMACS);
+
+ /* One `a' before the \n and 638 a's after it. */
+ test_search_return (0, "\\(.*\\)\n\\(\\(.\\|\n\\)*\\)$", "a\naaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
+
+ /* No a's before the \n and 639 a's after it. */
+ test_search_return (0, "\\(.*\\)\n\\(\\(.\\|\n\\)*\\)$", "\naaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
+
+ /* One `a' before the \n and 639 a's after it. */
+ test_search_return (0, "\\(.*\\)\n\\(\\(.\\|\n\\)*\\)$", "a\naaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
+
+ /* No a's before the \n and 640 a's after it. */
+ test_search_return (0, "\\(.*\\)\n\\(\\(.\\|\n\\)*\\)$", "\naaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
+
+ re_set_syntax (RE_NO_BK_VBAR | RE_NO_BK_PARENS);
+ TEST_SEARCH ("^(^a)", "ab", 0, 2);
+ TEST_SEARCH ("(a$)$", "ba", 0, 2);
+ test_match ("a|$b", "$b");
+
+ /* Mike's curiosity item. */
+ re_set_syntax (RE_NO_BK_VBAR | RE_NO_BK_PARENS);
+ test_all_registers ("(foo|foobar)(foo|bar)*\\1(foo|bar)*",
+ "foobarfoobar", "",
+ 0, 12, 0, 3, 3, 6, 9, 12, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1);
+
+ /* Another one from Mike. */
+ test_match ("(foo|foobarfoo)(bar)*", "foobarfoo");
+
+ /* And another. */
+ test_match("(foo|foobar)(bar|barfoo)?\\1", "foobarfoobar");
+
+ re_set_syntax (RE_NO_BK_PARENS | RE_INTERVALS | RE_NO_BK_VBAR
+ | RE_NO_BK_BRACES); /* xx get new ones from ext.*/
+ test_match ("((a{0,}{0,0}()\\3\\b\\B\\<\\>\\`\\')|b)*", "bb");
+ test_all_registers ("((a{0,}{0,0}()\\3\\b\\B\\<\\>\\`\\')|b)*", "", "bb",
+ 0, 2, 1, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1);
+
+ test_match ("((a+?*{0,}{0,0}()\\3\\b\\B\\<\\>\\`\\')|b)", "b");
+ test_all_registers ("((a+?*{0,}{0,0}()\\3\\b\\B\\<\\>\\`\\')|b)", "", "b",
+ 0, 1, 0, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1);
+
+ /* Valid anchoring. */
+ /* See generic_test.c and extended_test.c for more search
+ tests. xx Not sure all these tests are represented in the
+ search tests. */
+
+ re_set_syntax (RE_NO_BK_PARENS | RE_NO_BK_VBAR);
+ valid_nonposix_pattern
+ ("(((((((((((((((((((((((((((((((((^a)))))))))))))))))))))))))))))))))");
+ valid_nonposix_pattern
+ ("(((((((((((((((((((((((((((((((((a$)))))))))))))))))))))))))))))))))");
+ valid_nonposix_pattern ("\\b\\B\\<\\>\\`\\'^a");
+ valid_nonposix_pattern ("a$\\b\\B\\<\\>\\`\\'");
+ valid_nonposix_pattern ("(^a)");
+ valid_nonposix_pattern ("(a$)");
+ valid_nonposix_pattern ("(^a)b");
+ valid_nonposix_pattern ("b(a$)");
+ valid_nonposix_pattern ("(^a|^b)c");
+ valid_nonposix_pattern ("c(a$|b$)");
+ valid_nonposix_pattern ("(^a|^b)|^c");
+ valid_nonposix_pattern ("(a$|b$)|c$");
+ valid_nonposix_pattern ("^c|(^a|^b)");
+ valid_nonposix_pattern ("c$|(a$|b$)");
+ valid_nonposix_pattern ("(^a|^b)c|^d");
+ valid_nonposix_pattern ("c(a$|b$)|d$");
+ valid_nonposix_pattern ("(((^a|^b))c|^d)e");
+ valid_nonposix_pattern ("(c((a|b))|d)e$");
+ valid_nonposix_pattern ("^d(c|e((a|b)))");
+ valid_nonposix_pattern ("d(c$|e((a$|b$)))");
+ valid_nonposix_pattern ("(((^a|^b))c)|^de");
+ valid_nonposix_pattern ("(((a|b))c$)|de$");
+
+ valid_nonposix_pattern ("((a$)$)$");
+ valid_nonposix_pattern ("^(^(^a))");
+
+ valid_nonposix_pattern ("^de|^(c((a|b)))");
+ valid_nonposix_pattern ("^de|(^c((a|b)))");
+ valid_nonposix_pattern ("de$|(c((a|b)$))");
+ valid_nonposix_pattern ("de$|(c((a|b))$)");
+ valid_nonposix_pattern ("de$|(c((a|b)))$");
+
+ valid_nonposix_pattern ("^a(b|c)|^d");
+ valid_nonposix_pattern ("a(b$|c$)|d$");
+ valid_nonposix_pattern ("^d|^a(b|c)");
+ valid_nonposix_pattern ("d$|a(b$|c$)");
+ valid_nonposix_pattern ("^d|^(b|c)a");
+ valid_nonposix_pattern ("d$|(b|c)a$");
+ valid_nonposix_pattern ("^(a)(b|c)|^d");
+ valid_nonposix_pattern ("(a)(b|c)$|d$");
+ valid_nonposix_pattern ("(^a)(b|c)|^d");
+ valid_nonposix_pattern ("(a)(b$|c$)|d$");
+ valid_nonposix_pattern ("^d|^(b|c)(a)");
+ valid_nonposix_pattern ("d$|(b|c)(a)$");
+ valid_nonposix_pattern ("^d|(^b|^c)(a)");
+ valid_nonposix_pattern ("d$|(b|c)(a$)");
+ valid_nonposix_pattern ("^d|^(a)(b|c)");
+ valid_nonposix_pattern ("^d|(^a)(b|c)");
+ valid_nonposix_pattern ("d$|(a)(b$|c$)");
+ valid_nonposix_pattern ("((^a|^b)|^c)|^d");
+ valid_nonposix_pattern ("d$|(c$|(a$|b$))");
+
+
+ /* Tests shouldn't match. */
+ test_should_match = false;
+
+ /* Test that RE_CONTEXT_INVALID_OPS has precedence over
+ RE_CONTEXT_INDEP_OPS. */
+
+ re_set_syntax (RE_CONTEXT_INDEP_OPS | RE_CONTEXT_INVALID_OPS
+ | RE_NO_BK_VBAR | RE_NO_BK_PARENS
+ | RE_NO_BK_BRACES | RE_INTERVALS);
+ INVALID_PATTERN ("*");
+ INVALID_PATTERN ("^*");
+ INVALID_PATTERN ("a|*");
+ INVALID_PATTERN ("(*)");
+
+ INVALID_PATTERN ("^+");
+ INVALID_PATTERN ("+");
+ INVALID_PATTERN ("a|+");
+ INVALID_PATTERN ("(+)");
+
+ INVALID_PATTERN ("^?");
+ INVALID_PATTERN ("?");
+ INVALID_PATTERN ("a|?");
+ INVALID_PATTERN ("(?)");
+
+ INVALID_PATTERN ("^{1}");
+ INVALID_PATTERN ("{1}");
+ INVALID_PATTERN ("a|{1}");
+ INVALID_PATTERN ("({1})");
+
+#if 0
+ /* No longer have this syntax option -- POSIX says empty alternatives
+ are undefined as of draft 11.2. */
+
+ /* You can't have empty alternatives if RE_NO_EMPTY_ALTS is set. */
+
+ re_set_syntax (RE_NO_BK_VBAR | RE_NO_BK_PARENS | RE_NO_EMPTY_ALTS);
+
+ INVALID_PATTERN ("|");
+ INVALID_PATTERN ("^|a");
+ INVALID_PATTERN ("a|");
+ INVALID_PATTERN ("a||");
+ INVALID_PATTERN ("a||b");
+ INVALID_PATTERN ("(|a)");
+ INVALID_PATTERN ("(a|)");
+ INVALID_PATTERN ("(a|)");
+
+
+ /* Test above with `\(' and `\)'. */
+ re_set_syntax (RE_NO_BK_VBAR | RE_NO_EMPTY_ALTS);
+ INVALID_PATTERN ("\\(|a\\)");
+ INVALID_PATTERN ("\\(a|\\)");
+
+ re_set_syntax (RE_NO_BK_VBAR | RE_NO_BK_PARENS | RE_NO_EMPTY_ALTS);
+ INVALID_PATTERN ("(|)()$|d$");
+#endif
+
+ /* Test grouping. */
+ test_match ("()", "a");
+
+ /* Test backslashed intervals that are CONTEXTly invalid if have
+ nothing on which to operate. */
+
+ re_set_syntax (RE_INTERVALS | RE_CONTEXT_INVALID_OPS);
+ INVALID_PATTERN ("\\{1\\}");
+
+ re_set_syntax (0);
+ test_match ("z-a", "a");
+
+ re_set_syntax (RE_BK_PLUS_QM);
+ INVALID_PATTERN ("a*\\");
+
+ re_set_syntax (0);
+ INVALID_PATTERN ("a*\\");
+
+ re_set_syntax (RE_BACKSLASH_ESCAPE_IN_LISTS);
+ INVALID_PATTERN ("[\\");
+
+#if 0
+ /* Empty groups are always ok now. (13 Sep 92) */
+ re_set_syntax (RE_NO_BK_VBAR | RE_NO_BK_PARENS | RE_NO_EMPTY_GROUPS);
+ INVALID_PATTERN ("(|)()$|d$");
+#endif
+
+ printf ("\nFinished non-POSIX tests.\n");
+}
+
+
+
+/*
+Local variables:
+make-backup-files: t
+version-control: t
+trim-versions-without-asking: nil
+End:
+*/
diff --git a/gnu/lib/libregex/test/printchar.c b/gnu/lib/libregex/test/printchar.c
new file mode 100644
index 000000000000..1b756f441be3
--- /dev/null
+++ b/gnu/lib/libregex/test/printchar.c
@@ -0,0 +1,14 @@
+void
+printchar (c)
+ char c;
+{
+ if (c < 040 || c >= 0177)
+ {
+ putchar ('\\');
+ putchar (((c >> 6) & 3) + '0');
+ putchar (((c >> 3) & 7) + '0');
+ putchar ((c & 7) + '0');
+ }
+ else
+ putchar (c);
+}
diff --git a/gnu/lib/libregex/test/psx-basic.c b/gnu/lib/libregex/test/psx-basic.c
new file mode 100644
index 000000000000..52535b6b3076
--- /dev/null
+++ b/gnu/lib/libregex/test/psx-basic.c
@@ -0,0 +1,253 @@
+/* psx-basic.c: Test POSIX basic regular expressions. */
+
+#include "test.h"
+
+
+void
+test_posix_basic ()
+{
+ /* Intervals can only match up to RE_DUP_MAX occurences of anything. */
+ char dup_max_plus_one[6];
+ sprintf (dup_max_plus_one, "%d", RE_DUP_MAX + 1);
+
+ printf ("\nStarting POSIX basic tests.\n");
+ t = posix_basic_test;
+
+ re_set_syntax (RE_SYNTAX_POSIX_MINIMAL_BASIC);
+
+ test_posix_generic ();
+
+ printf ("\nContinuing POSIX basic tests.\n");
+
+/* Grouping tests that are not the same. */
+
+ test_should_match = false;
+ invalid_pattern (REG_EPAREN, PARENS_TO_OPS ("a)"));
+
+ test_should_match = true;
+ /* Special characters. */
+ MATCH_SELF ("*");
+ test_match ("\\(*\\)", "*");
+ test_match ("\\(^*\\)", "*");
+ test_match ("**", "***");
+ test_match ("***", "****");
+
+ MATCH_SELF ("{"); /* of extended... */
+ MATCH_SELF ("()"); /* also non-Posix. */
+ MATCH_SELF ("a+");
+ MATCH_SELF ("a?");
+ MATCH_SELF ("a|b");
+ MATCH_SELF ("a|"); /* No alternations, */
+ MATCH_SELF ("|a"); /* so OK if empty. */
+ MATCH_SELF ("a||");
+ test_match ("\\(|a\\)", "|a");
+ test_match ("\\(a|\\)", "a|");
+ test_match ("a\\+", "a+");
+ test_match ("a\\?", "a?");
+ test_match ("a\\|b", "a|b");
+ test_match ("^*", "*");
+ test_match ("^+", "+");
+ test_match ("^?", "?");
+ test_match ("^{", "{");
+ /* Valid subexpressions
+ (empty) in basic only. */
+ test_match ("\\(\\)", "");
+
+ test_match ("a\\(\\)", "a");
+ test_match ("\\(\\)b", "b");
+ test_match ("a\\(\\)b", "ab");
+ TEST_REGISTERS ("a\\(\\)b", "ab", 0, 2, 1, 1, -1, -1);
+
+ test_match ("\\(\\)*", "");
+ test_match ("\\(\\(\\)\\)*", "");
+ /* Valid back references. */
+
+ /* N.B.: back references to subexpressions that include a * are
+ undefined in the spec. The tests are in here to see if we handle
+ the situation consistently, but if it fails any of them, it doesn't
+ matter. */
+
+ test_match ("\\(\\)\\1", "");
+ TEST_REGISTERS ("\\(\\)\\1", "", 0, 0, 0, 0, -1, -1);
+
+ test_match ("\\(\\(\\)\\)\\(\\)\\2", "");
+
+ test_match ("\\(a\\)\\1", "aa");
+ TEST_REGISTERS ("\\(a\\)\\1", "aa", 0, 2, 0, 1, -1, -1);
+ TEST_REGISTERS ("\\(a\\)\\1", "xaax", 1, 3, 1, 2, -1, -1);
+
+ test_match ("\\(\\(a\\)\\)\\1", "aa");
+ test_match ("\\(a\\)\\(b\\)\\2\\1", "abba");
+
+ test_match ("\\(a\\)*\\1", "aa");
+ TEST_REGISTERS ("\\(a\\)*\\1", "aa", 0, 2, 0, 1, -1, -1);
+ TEST_REGISTERS ("\\(a\\)*\\1", "xaax", 0, 0, -1, -1, -1, -1);
+
+ test_match ("\\(\\(a\\)\\2b\\)*", "aab");
+ TEST_REGISTERS ("\\(\\(a\\)\\2b\\)*", "aab", 0, 3, 0, 3, 0, 1);
+ TEST_REGISTERS ("\\(\\(a\\)\\2b\\)*", "xaabx", 0, 0, -1, -1, -1, -1);
+
+ test_match ("\\(a*\\)*\\1", "");
+ test_match ("\\(a*\\)*\\1", "aa");
+ TEST_REGISTERS ("\\(a*\\)*\\1", "aa", 0, 2, 0, 1, -1, -1);
+ TEST_REGISTERS ("\\(a*\\)*\\1", "xaax", 0, 0, 0, 0, -1, -1);
+
+ test_match ("\\(a*\\)*\\1", "");
+ test_match ("\\(a*\\)*\\1", "aa");
+ test_match ("\\(\\(a*\\)*\\)*\\1", "aa");
+ test_match ("\\(ab*\\)*\\1", "abab");
+ TEST_REGISTERS ("\\(ab*\\)*\\1", "abab", 0, 4, 0, 2, -1, -1);
+ TEST_REGISTERS ("\\(ab*\\)*\\1", "xababx", 0, 0, -1, -1, -1, -1);
+
+ test_match ("\\(a*\\)ab\\1", "aaba");
+ TEST_REGISTERS ("\\(a*\\)ab\\1", "aaba", 0, 4, 0, 1, -1, -1);
+ TEST_REGISTERS ("\\(a*\\)ab\\1", "xaabax", 1, 5, 1, 2, -1, -1);
+
+ test_match ("\\(a*\\)*ab\\1", "aaba");
+ TEST_REGISTERS ("\\(a*\\)*ab\\1", "aaba", 0, 4, 0, 1, -1, -1);
+ TEST_REGISTERS ("\\(a*\\)*ab\\1", "xaabax", 1, 5, 1, 2, -1, -1);
+
+ test_match ("\\(\\(a*\\)b\\)*\\2", "abb");
+ TEST_REGISTERS ("\\(\\(a*\\)b\\)*\\2", "abb", 0, 3, 2, 3, 2, 2);
+ TEST_REGISTERS ("\\(\\(a*\\)b\\)*\\2", "xabbx", 0, 0, -1, -1, -1, -1);
+
+ /* Different from above. */
+ test_match ("\\(\\(a*\\)b*\\)*\\2", "aa");
+ TEST_REGISTERS ("\\(\\(a*\\)b*\\)*\\2", "aa", 0, 2, 0, 1, 0, 1);
+ TEST_REGISTERS ("\\(\\(a*\\)b*\\)*\\2", "xaax", 0, 0, 0, 0, 0, 0);
+
+ test_match ("\\(\\(a*\\)b*\\)*\\2", "aba");
+ TEST_REGISTERS ("\\(\\(a*\\)b*\\)*\\2", "aba", 0, 3, 0, 2, 0, 1);
+ TEST_REGISTERS ("\\(\\(a*\\)b*\\)*\\2", "xabax", 0, 0, 0, 0, 0, 0);
+
+ test_match ("\\(\\(a*\\)b\\)*\\2", "aababa");
+ TEST_REGISTERS ("\\(\\(a*\\)b\\)*\\2", "aababa", 0, 6, 3, 5, 3, 4);
+ TEST_REGISTERS ("\\(\\(a*\\)b\\)*\\2", "xaababax", 0, 0, -1, -1, -1, -1);
+
+ test_match ("\\(\\(a*\\)b*\\)*\\2", "aabaa");
+ TEST_REGISTERS ("\\(\\(a*\\)b*\\)*\\2", "aabaa", 0, 5, 0, 3, 0, 2);
+ TEST_REGISTERS ("\\(\\(a*\\)b*\\)*\\2", "xaabaax", 0, 0, 0, 0, 0, 0);
+
+ test_match ("\\(\\(a*\\)b*\\)*\\2", "aabbaa");
+ TEST_REGISTERS ("\\(\\(a*\\)b*\\)*\\2", "aabbaa", 0, 6, 0, 4, 0, 2);
+ TEST_REGISTERS ("\\(\\(a*\\)b*\\)*\\2", "xaabbaax", 0, 0, 0, 0, 0, 0);
+
+ test_match ("\\(\\(a*\\)b*\\)*\\2", "abaabaa");
+ TEST_REGISTERS ("\\(\\(a*\\)b*\\)*\\2", "abaabaa", 0, 7, 2, 5, 2, 4);
+ TEST_REGISTERS ("\\(\\(a*\\)b*\\)*\\2", "xaababaax", 0, 0, 0, 0, 0, 0);
+
+ test_match ("\\(\\(a*\\)b*\\)*a\\2", "aabaaa");
+ TEST_REGISTERS ("\\(\\(a*\\)b*a\\)*\\2", "aabaaa", 0, 6, 0, 3, 0, 2);
+ TEST_REGISTERS ("\\(\\(a*\\)b*a\\)*\\2", "xaabaax", 0, 0, -1, -1, -1, -1);
+
+ test_match ("\\(\\(a*\\)b*\\)*\\2a", "aabaaa");
+ TEST_REGISTERS ("\\(\\(a*\\)b*\\)*\\2a", "aabaaa", 0, 6, 0, 3, 0, 2);
+ TEST_REGISTERS ("\\(\\(a*\\)b*\\)*\\2a", "xaabaaax", 1, 7, 1, 4, 1, 3);
+
+ test_match ("\\(\\(a*\\)b\\)*\\2\\1", "abaabaaaab");
+ TEST_REGISTERS ("\\(\\(a*\\)b\\)*\\2\\1", "abaabaaaab", 0, 10, 2, 5, 2, 4);
+ /* We are matching the empty string here. */
+ TEST_REGISTERS ("\\(\\(a*\\)b\\)*\\2\\1", "xabaabaaaabx", 0, 0, -1, -1, -1, -1);
+
+ test_match ("\\(a*b\\)\\1", "abab");
+ test_match ("\\(a\\)\\1\\1", "aaa");
+ test_match ("\\(a\\(c\\)d\\)\\1\\2", "acdacdc");
+
+ test_match ("\\(a\\)\\1*", "aaa");
+ TEST_REGISTERS ("\\(a\\)\\1*", "aaa", 0, 3, 0, 1, -1, -1);
+ TEST_REGISTERS ("\\(a\\)\\1*", "xaaax", 1, 4, 1, 2, -1, -1);
+
+ test_match ("\\(a\\)\\{1,3\\}b\\1", "aba");
+ TEST_REGISTERS ("\\(a\\)\\{1,3\\}b\\1", "aba", 0, 3, 0, 1, -1, -1);
+ TEST_REGISTERS ("\\(a\\)\\{1,3\\}b\\1", "xabax", 1, 4, 1, 2, -1, -1);
+
+ test_match ("\\(\\(a\\)\\2\\)*", "aaaa"); /* rms? */
+ TEST_REGISTERS ("\\(\\(a*b\\)\\2\\)*", "bbabab", 0, 6, 2, 6, 2, 4); /* rms? */
+
+ test_match ("\\(\\(a\\)\\1\\)*", "a1a1");
+
+ test_match ("\\(\\(a\\)\\2\\)\\1", "aaaa");
+
+ test_match ("\\(\\(a*\\)\\2\\)\\1", "aaaa");
+ TEST_REGISTERS ("\\(\\(a*\\)\\2\\)\\1", "aaaa", 0, 4, 0, 2, 0, 1);
+ TEST_REGISTERS ("\\(\\(a*\\)\\2\\)\\1", "xaaaax", 0, 0, 0, 0, 0, 0);
+
+ test_match ("\\{1\\}", "{1}");
+ test_match ("^\\{1\\}", "{1}");
+
+ test_match ("\\(a\\)\\1\\{1,2\\}", "aaa");
+ TEST_REGISTERS ("\\(a\\)\\1\\{1,2\\}", "aaa", 0, 3, 0, 1, -1, -1);
+ TEST_REGISTERS ("\\(a\\)\\1\\{1,2\\}", "xaaax", 1, 4, 1, 2, -1, -1);
+
+
+ /* Per POSIX D11.1 p. 109, leftmost longest match. */
+
+ test_match (PARENS_TO_OPS ("(.*).*\\1"), "abcabc");
+
+
+ /* Per POSIX D11.1, p. 125, leftmost longest match. */
+
+ test_match (PARENS_TO_OPS ("(ac*)c*d[ac]*\\1"), "acdacaaa");
+ TEST_REGISTERS (PARENS_TO_OPS ("(ac*)c*d[ac]*\\1"), "acdacaaa",
+ 0, 8, 0, 1, -1, -1);
+
+ /* Anchors become ordinary, sometimes. */
+ MATCH_SELF ("a^");
+ MATCH_SELF ("$a");
+ MATCH_SELF ("$^");
+ test_fastmap ("$a^", "$", 0, 0);
+ test_match ("$^*", "$^^");
+ test_match ("\\($^\\)", "$^");
+ test_match ("$*", "$$");
+ /* xx -- known bug, solution pending test_match ("^^$", "^"); */
+ test_match ("$\\{0,\\}", "$$");
+ TEST_SEARCH ("^$*", "$$", 0, 2);
+ TEST_SEARCH ("^$\\{0,\\}", "$$", 0, 2);
+ MATCH_SELF ("2^10");
+ MATCH_SELF ("$HOME");
+ MATCH_SELF ("$1.35");
+
+
+ /* Basic regular expressions, continued; these don't match their strings. */
+ test_should_match = false;
+
+ invalid_pattern (REG_EESCAPE, "\\(a\\");
+ /* Invalid back references. */
+ test_match ("\\(a\\)\\1", "ab");
+ test_match ("\\(a\\)\\1\\1", "aab");
+ test_match ("\\(a\\)\\(b\\)\\2\\1", "abab");
+ test_match ("\\(a\\(c\\)d\\)\\1\\2", "acdc");
+ test_match ("\\(a*b\\)\\1", "abaab");
+ test_match ("\\(a\\)\\1*", "aaaaaaaaaab");
+ test_match ("\\(\\(a\\)\\1\\)*", "aaa");
+ invalid_pattern (REG_ESUBREG, "\\1");
+ invalid_pattern (REG_ESUBREG, "\\(a\\)\\2");
+ test_match ("\\(\\(a\\)\\2\\)*", "abaa");
+ test_match ("\\(\\(a\\)\\1\\)*", "a");
+ test_match ("\\(\\(a\\)\\2\\)\\1", "abaa");
+ test_match ("\\(\\(a*\\)\\2\\)\\1", "abaa");
+ /* Invalid intervals. */
+ invalid_pattern (REG_EBRACE, "a\\{");
+
+ invalid_pattern (REG_BADBR, "a\\{-1");
+ invalid_pattern (REG_BADBR, concat ("a\\{", (char *)dup_max_plus_one));
+ invalid_pattern (REG_BADBR, concat (concat ("a\\{", (char *)dup_max_plus_one), ","));
+ invalid_pattern (REG_BADBR, "a\\{1,0");
+
+ invalid_pattern (REG_EBRACE, "a\\{1");
+ invalid_pattern (REG_EBRACE, "a\\{0,");
+ invalid_pattern (REG_EBRACE, "a\\{0,1");
+ invalid_pattern (REG_EBRACE, "a\\{0,1}");
+
+ printf ("\nFinished POSIX basic tests.\n");
+}
+
+
+
+/*
+Local variables:
+make-backup-files: t
+version-control: t
+trim-versions-without-asking: nil
+End:
+*/
diff --git a/gnu/lib/libregex/test/psx-extend.c b/gnu/lib/libregex/test/psx-extend.c
new file mode 100644
index 000000000000..6f02d67b8219
--- /dev/null
+++ b/gnu/lib/libregex/test/psx-extend.c
@@ -0,0 +1,1244 @@
+/* psx-extend.c: Test POSIX extended regular expressions. */
+
+#include "test.h"
+
+
+void
+test_posix_extended ()
+{
+ /* Intervals can only match up to RE_DUP_MAX occurences of anything. */
+ char dup_max_plus_one[6];
+ sprintf (dup_max_plus_one, "%d", RE_DUP_MAX + 1);
+
+
+ printf ("\nStarting POSIX extended tests.\n");
+ t = posix_extended_test;
+
+ re_set_syntax (RE_SYNTAX_POSIX_MINIMAL_EXTENDED);
+
+ test_posix_generic ();
+
+ printf ("\nContinuing POSIX extended tests.\n");
+
+ /* Grouping tests that differ from basic's. */
+
+ test_should_match = true;
+ MATCH_SELF ("a)");
+
+ /* Valid use of special characters. */
+ test_match ("\\(a", "(a");
+ test_match ("a\\+", "a+");
+ test_match ("a\\?", "a?");
+ test_match ("\\{a", "{a");
+ test_match ("\\|a", "|a");
+ test_match ("a\\|b", "a|b");
+ test_match ("a\\|?", "a");
+ test_match ("a\\|?", "a|");
+ test_match ("a\\|*", "a");
+ test_match ("a\\|*", "a||");
+ test_match ("\\(*\\)", ")");
+ test_match ("\\(*\\)", "(()");
+ test_match ("a\\|+", "a|");
+ test_match ("a\\|+", "a||");
+ test_match ("\\(+\\)", "()");
+ test_match ("\\(+\\)", "(()");
+ test_match ("a\\||b", "a|");
+ test_match ("\\(?\\)", ")");
+ test_match ("\\(?\\)", "()");
+
+ test_match ("a+", "a");
+ test_match ("a+", "aa");
+ test_match ("a?", "");
+ test_match ("a?", "a");
+
+ /* Bracket expressions. */
+ test_match ("[(]", "(");
+ test_match ("[+]", "+");
+ test_match ("[?]", "?");
+ test_match ("[{]", "{");
+ test_match ("[|]", "|");
+ /* Subexpressions. */
+ test_match ("(a+)*", "");
+ test_match ("(a+)*", "aa");
+ test_match ("(a?)*", "");
+ test_match ("(a?)*", "aa");
+ /* (No) back references. */
+ test_match ("(a)\\1", "a1");
+ /* Invalid as intervals,
+ but are valid patterns. */
+ MATCH_SELF ("{");
+ test_match ("^{", "{");
+ test_match ("a|{", "{");
+ test_match ("({)", "{");
+ MATCH_SELF ("a{");
+ MATCH_SELF ("a{}");
+ MATCH_SELF ("a{-1");
+ MATCH_SELF ("a{-1}");
+ MATCH_SELF ("a{0");
+ MATCH_SELF ("a{0,");
+ MATCH_SELF (concat ("a{", dup_max_plus_one));
+ MATCH_SELF (concat (concat ("a{", dup_max_plus_one), ","));
+ MATCH_SELF ("a{1,0");
+ MATCH_SELF ("a{1,0}");
+ MATCH_SELF ("a{0,1");
+ test_match ("[a{0,1}]", "}");
+ test_match ("a{1,3}{-1}", "aaa{-1}");
+ test_match (concat ("a{1,3}{", dup_max_plus_one),
+ concat ("aaa{", dup_max_plus_one));
+ test_match ("a{1,3}{2,1}", "aaa{2,1}");
+ test_match ("a{1,3}{1,2", "aaa{1,2");
+ /* Valid consecutive repetitions. */
+ test_match ("a*+", "a");
+ test_match ("a*?", "a");
+ test_match ("a++", "a");
+ test_match ("a+*", "a");
+ test_match ("a+?", "a");
+ test_match ("a??", "a");
+ test_match ("a?*", "a");
+ test_match ("a?+", "a");
+
+ test_match ("a{2}?", "");
+ test_match ("a{2}?", "aa");
+ test_match ("a{2}+", "aa");
+ test_match ("a{2}{2}", "aaaa");
+
+ test_match ("a{1}?*", "");
+ test_match ("a{1}?*", "aa");
+
+ test_match ("(a?){0,3}b", "aaab");
+ test_fastmap ("(a?){0,3}b", "ab", 0, 0);
+ test_match ("(a+){0,3}b", "b");
+ test_fastmap ("(a+){0,3}b", "ab", 0, 0);
+ test_match ("(a+){0,3}b", "ab");
+ test_fastmap ("(a+){0,3}b", "ab", 0, 0);
+ test_match ("(a+){1,3}b", "aaab");
+ test_match ("(a?){1,3}b", "aaab");
+
+ test_match ("\\\\{1}", "\\"); /* Extended only. */
+
+ test_match ("(a?)?", "a");
+ test_match ("(a?b)?c", "abc");
+ test_match ("(a+)*b", "b");
+ /* Alternatives. */
+ test_match ("a|b", "a");
+ test_match ("a|b", "b");
+ test_fastmap ("a|b", "ab", 0, 0);
+
+ TEST_SEARCH ("a|b", "cb", 0, 2);
+ TEST_SEARCH ("a|b", "cb", 0, 2);
+
+ test_match ("(a|b|c)", "a");
+ test_match ("(a|b|c)", "b");
+ test_match ("(a|b|c)", "c");
+
+ test_match ("(a|b|c)*", "abccba");
+
+ test_match ("(a(b*))|c", "a"); /* xx do registers. */
+ test_match ("(a(b*))|c", "ab");
+ test_match ("(a(b*))|c", "c");
+
+ test_fastmap ("(a+?*|b)", "ab", 0, 0);
+ test_match ("(a+?*|b)", "b");
+ TEST_REGISTERS ("(a+?*|b)", "b", 0, 1, 0, 1, -1, -1);
+
+ test_fastmap ("(a+?*|b)*", "ab", 0, 0);
+ test_match ("(a+?*|b)*", "bb");
+ TEST_REGISTERS ("(a+?*|b)*", "bb", 0, 2, 1, 2, -1, -1);
+
+ test_fastmap ("(a*|b)*", "ab", 0, 0);
+ test_match ("(a*|b)*", "bb");
+ TEST_REGISTERS ("(a*|b)*", "bb", 0, 2, 1, 2, -1, -1);
+
+ test_fastmap ("((a*)|b)*", "ab", 0, 0);
+ test_match ("((a*)|b)*", "bb");
+ TEST_REGISTERS ("((a*)|b)*", "bb", 0, 2, 1, 2, 1, 1);
+
+ test_fastmap ("(a{0,}|b)*", "ab", 0, 0);
+ test_match ("(a{0,}|b)*", "bb");
+ TEST_REGISTERS ("(a{0,}|b)*", "bb", 0, 2, 1, 2, -1, -1);
+
+ test_fastmap ("((a{0,})|b)*", "ab", 0, 0);
+ test_match ("((a{0,})|b)*", "bb");
+ TEST_REGISTERS ("((a{0,})|b)*", "bb", 0, 2, 1, 2, 1, 1);
+
+ /* With c's */
+ test_fastmap ("(a+?*|b)c", "abc", 0, 0);
+ test_match ("(a+?*|b)c", "bc");
+ TEST_REGISTERS ("(a+?*|b)c", "bc", 0, 2, 0, 1, -1, -1);
+
+ test_fastmap ("(a+?*|b)*c", "abc", 0, 0);
+ test_match ("(a+?*|b)*c", "bbc");
+ TEST_REGISTERS ("(a+?*|b)*c", "bbc", 0, 3, 1, 2, -1, -1);
+
+ test_fastmap ("(a*|b)*c", "abc", 0, 0);
+ test_match ("(a*|b)*c", "bbc");
+ TEST_REGISTERS ("(a*|b)*c", "bbc", 0, 3, 1, 2, -1, -1);
+
+ test_fastmap ("((a*)|b)*c", "abc", 0, 0);
+ test_match ("((a*)|b)*c", "bbc");
+ TEST_REGISTERS ("((a*)|b)*c", "bbc", 0, 3, 1, 2, 1, 1);
+
+ test_fastmap ("(a{0,}|b)*c", "abc", 0, 0);
+ test_match ("(a{0,}|b)*c", "bbc");
+ TEST_REGISTERS ("(a{0,}|b)*c", "bbc", 0, 3, 1, 2, -1, -1);
+
+ test_fastmap ("((a{0,})|b)*c", "abc", 0, 0);
+ test_match ("((a{0,})|b)*c", "bbc");
+ TEST_REGISTERS ("((a{0,})|b)*c", "bbc", 0, 3, 1, 2, 1, 1);
+
+
+ test_fastmap ("((a{0,}\\b\\<)|b)", "ab", 0, 0);
+ test_match ("((a{0,}\\b\\<)|b)", "b");
+ TEST_REGISTERS ("((a{0,}\\b\\<)|b)", "b",
+ 0, 1, 0, 1, 0, 0);
+
+ test_fastmap ("((a{0,}\\b\\<)|b)*", "ab", 0, 0);
+ test_match ("((a{0,}\\b\\<)|b)*", "b");
+ TEST_REGISTERS ("((a{0,}\\b\\<)|b)*", "b",
+ 0, 1, 0, 1, 0, 0);
+
+ test_fastmap ("((a+?*{0,1}\\b\\<)|b)", "ab", 0, 0);
+ test_match ("((a+?*{0,1}\\b\\<)|b)", "b");
+ TEST_REGISTERS ("((a+?*{0,1}\\b\\<)|b)", "b",
+ 0, 1, 0, 1, 0, 0);
+
+ test_fastmap ("((a+?*{0,2}\\b\\<)|b)", "ab", 0, 0);
+ test_match ("((a+?*{0,2}\\b\\<)|b)", "b");
+ TEST_REGISTERS ("((a+?*{0,2}\\b\\<)|b)", "b",
+ 0, 1, 0, 1, 0, 0);
+
+
+ test_fastmap ("((a+?*{0,4095}\\b\\<)|b)", "ab", 0, 0);
+ test_match ("((a+?*{0,4095}\\b\\<)|b)", "b");
+ TEST_REGISTERS ("((a+?*{0,4095}\\b\\<)|b)", "b",
+ 0, 1, 0, 1, 0, 0);
+
+ test_fastmap ("((a+?*{0,5119}\\b\\<)|b)", "ab", 0, 0);
+ test_match ("((a+?*{0,5119}\\b\\<)|b)", "b");
+ TEST_REGISTERS ("((a+?*{0,5119}\\b\\<)|b)", "b",
+ 0, 1, 0, 1, 0, 0);
+
+ test_fastmap ("((a+?*{0,6143}\\b\\<)|b)", "ab", 0, 0);
+ test_match ("((a+?*{0,6143}\\b\\<)|b)", "b");
+ TEST_REGISTERS ("((a+?*{0,6143}\\b\\<)|b)", "b",
+ 0, 1, 0, 1, 0, 0);
+
+ test_fastmap ("((a+?*{0,8191}\\b\\<)|b)", "ab", 0, 0);
+ test_match ("((a+?*{0,8191}\\b\\<)|b)", "b");
+ TEST_REGISTERS ("((a+?*{0,8191}\\b\\<)|b)", "b",
+ 0, 1, 0, 1, 0, 0);
+
+ test_fastmap ("((a+?*{0,16383}\\b\\<)|b)", "ab", 0, 0);
+ test_match ("((a+?*{0,16383}\\b\\<)|b)", "b");
+ TEST_REGISTERS ("((a+?*{0,16383}\\b\\<)|b)", "b",
+ 0, 1, 0, 1, 0, 0);
+
+
+ test_fastmap ("((a+?*{0,}\\b\\<)|b)", "ab", 0, 0);
+ test_match ("((a+?*{0,}\\b\\<)|b)", "b");
+ TEST_REGISTERS ("((a+?*{0,}\\b\\<)|b)", "b",
+ 0, 1, 0, 1, 0, 0);
+
+ test_fastmap ("((a+?*{0,}\\b\\<)|b)*", "ab", 0, 0);
+ test_match ("((a+?*{0,}\\b\\<)|b)*", "b");
+ TEST_REGISTERS ("((a+?*{0,}\\b\\<)|b)*", "b",
+ 0, 1, 0, 1, 0, 0);
+
+ test_fastmap ("((a+?*{0,}\\b\\<)|b)*", "ab", 0, 0);
+ test_match ("((a+?*{0,}\\b\\<)|b)*", "bb");
+ TEST_REGISTERS ("((a+?*{0,}\\b\\<)|b)*", "bb",
+ 0, 2, 1, 2, 0, 0);
+
+
+ /* `*' after group. */
+ test_match ("(a*|b*)*c", "c");
+ TEST_REGISTERS ("(a*|b*)*c", "c", 0, 1, 0, 0, -1, -1);
+
+ test_match ("(a*|b*)*c", "ac");
+ TEST_REGISTERS ("(a*|b*)*c", "ac", 0, 2, 0, 1, -1, -1);
+
+ test_match ("(a*|b*)*c", "aac");
+ TEST_REGISTERS ("(a*|b*)*c", "aac", 0, 3, 0, 2, -1, -1);
+
+ test_match ("(a*|b*)*c", "bbc");
+ TEST_REGISTERS ("(a*|b*)*c", "bbc", 0, 3, 0, 2, -1, -1);
+
+ test_match ("(a*|b*)*c", "abc");
+ TEST_REGISTERS ("(a*|b*)*c", "abc", 0, 3, 1, 2, -1, -1);
+
+ /* No `*' after group. */
+ test_match ("(a*|b*)c", "c");
+ TEST_REGISTERS ("(a*|b*)c", "c", 0, 1, 0, 0, -1, -1);
+
+ test_match ("(a*|b*)c", "ac");
+ TEST_REGISTERS ("(a*|b*)c", "ac", 0, 2, 0, 1, -1, -1);
+
+ test_match ("(a*|b*)c", "bc");
+ TEST_REGISTERS ("(a*|b*)c", "bc", 0, 2, 0, 1, -1, -1);
+
+ test_match ("(a*|b*)c", "aac");
+ TEST_REGISTERS ("(a*|b*)c", "aac", 0, 3, 0, 2, -1, -1);
+
+ /* Same as above, but with no `*'s in alternatives.
+
+ test_match ("(a|b)*c", "c"); /* `*' after group. */
+ TEST_REGISTERS ("(a|b)*c", "c", 0, 1, -1, -1, -1, -1);
+
+ test_match ("(a|b)*c", "ac");
+ TEST_REGISTERS ("(a|b)*c", "ac", 0, 2, 0, 1, -1, -1);
+
+ test_match ("(a|b)*c", "bc");
+ TEST_REGISTERS ("(a|b)*c", "bc", 0, 2, 0, 1, -1, -1);
+
+ test_match ("(a|b)*c", "abc");
+ TEST_REGISTERS ("(a|b)*c", "abc", 0, 3, 1, 2, -1, -1);
+
+
+ test_match ("(a*|b*)c", "bbc");
+ TEST_REGISTERS ("(a*|b*)c", "bbc", 0, 3, 0, 2, -1, -1);
+
+ /* Complicated second alternative. */
+
+ test_match ("(a*|(b*)*)*c", "bc");
+ TEST_REGISTERS ("(a*|(b*)*)*c", "bc", 0, 2, 0, 1, 0, 1);
+
+ test_match ("(a*|(b*|c*)*)*d", "bd");
+ TEST_REGISTERS ("(a*|(b*|c*)*)*d", "bd", 0, 2, 0, 1, 0, 1);
+
+ test_match ("(a*|(b*|c*)*)*d", "bbd");
+ TEST_REGISTERS ("(a*|(b*|c*)*)*d", "bbd", 0, 3, 0, 2, 0, 2);
+
+ test_match ("(a*|(b*|c*)*)*d", "cd");
+ TEST_REGISTERS ("(a*|(b*|c*)*)*d", "cd", 0, 2, 0, 1, 0, 1);
+
+ test_match ("(a*|(b*|c*)*)*d", "ccd");
+ TEST_REGISTERS ("(a*|(b*|c*)*)*d", "ccd", 0, 3, 0, 2, 0, 2);
+
+ test_match ("(a*|b*|c*)*d", "aad");
+ TEST_REGISTERS ("(a*|b*|c*)*d", "aad", 0, 3, 0, 2, 0, 2);
+
+ test_match ("(a*|b*|c*)*d", "bbd");
+ TEST_REGISTERS ("(a*|b*|c*)*d", "bbd", 0, 3, 0, 2, 0, 2);
+
+ test_match ("(a*|b*|c*)*d", "ccd");
+ TEST_REGISTERS ("(a*|b*|c*)*d", "ccd", 0, 3, 0, 2, 0, 2);
+
+ /* Valid anchoring. */
+ valid_pattern ("a^");
+ valid_pattern ("a^b");
+ valid_pattern ("$a");
+ valid_pattern ("a$b");
+ valid_pattern ("foo^bar");
+ valid_pattern ("foo$bar");
+ valid_pattern ("(^)");
+ valid_pattern ("($)");
+ valid_pattern ("(^$)");
+
+ /* These are the same (but valid) as those (invalid) in other_test.c. */
+ valid_pattern
+ ("(((((((((((((((((((((((((((((((((a^)))))))))))))))))))))))))))))))))");
+ valid_pattern
+ ("((((((((((((((((((((((((((((((((($a)))))))))))))))))))))))))))))))))");
+ valid_pattern ("\\(^a\\)");
+ valid_pattern ("a\\|^b");
+ valid_pattern ("\\w^a");
+ valid_pattern ("\\W^a");
+ valid_pattern ("(a^)");
+ valid_pattern ("($a)");
+ valid_pattern ("a(^b)");
+ valid_pattern ("a$(b)");
+ valid_pattern ("(a)^b");
+ valid_pattern ("(a)$b");
+ valid_pattern ("(a)(^b)");
+ valid_pattern ("(a$)(b)");
+ valid_pattern ("(a|b)^c");
+ valid_pattern ("(a|b)$c");
+ valid_pattern ("(a$|b)c");
+ valid_pattern ("(a|b$)c");
+ valid_pattern ("a(b|^c)");
+ valid_pattern ("a(^b|c)");
+ valid_pattern ("a$(b|c)");
+ valid_pattern ("(a)(^b|c)");
+ valid_pattern ("(a)(b|^c)");
+ valid_pattern ("(b$|c)(a)");
+ valid_pattern ("(b|c$)(a)");
+ valid_pattern ("(a(^b|c))");
+ valid_pattern ("(a(b|^c))");
+ valid_pattern ("((b$|c)a)");
+ valid_pattern ("((b|c$)a)");
+ valid_pattern ("((^a|^b)^c)");
+ valid_pattern ("(c$(a$|b$))");
+ valid_pattern ("((^a|^b)^c)");
+ valid_pattern ("((a$|b$)c)");
+ valid_pattern ("(c$(a$|b$))");
+ valid_pattern ("((^a|^b)|^c)^d");
+ valid_pattern ("((a$|b$)|c$)d$");
+ valid_pattern ("d$(c$|(a$|b$))");
+ valid_pattern ("((^a|^b)|^c)(^d)");
+ valid_pattern ("((a$|b$)|c$)(d$)");
+ valid_pattern ("(d$)((a$|b$)|c$)");
+ valid_pattern ("((^a|^b)|^c)((^d))");
+ valid_pattern ("((a$|b$)|c$)((d$))");
+ valid_pattern ("((d$))((a$|b$)|c$)");
+ valid_pattern ("(((^a|^b))c|^d)^e");
+ valid_pattern ("(((a$|b$))c|d$)$e$");
+ valid_pattern ("e$(d$|c((a$|b$)))");
+ valid_pattern ("(^a)((^b))");
+ valid_pattern ("(a$)((b$))");
+ valid_pattern ("((^a))(^b)");
+ valid_pattern ("((a$))(b$)");
+ valid_pattern ("((^a))((^b))");
+ valid_pattern ("((a$))((b$))");
+ valid_pattern ("((^a)^b)");
+ valid_pattern ("((a$)b$)");
+ valid_pattern ("(b$(a$))");
+ valid_pattern ("(((^a)b)^c)");
+ valid_pattern ("(((a$)b)c$)");
+ valid_pattern ("(c$(b(a$)))");
+ valid_pattern ("(((^a)b)c)^d");
+ valid_pattern ("(((a$)b)c)d$");
+ valid_pattern ("d$(c(b(a$)))");
+ valid_pattern (".^a");
+ valid_pattern ("a$.");
+ valid_pattern ("[a]^b");
+ valid_pattern ("b$[a]");
+ valid_pattern ("\\(a$\\)");
+ valid_pattern ("a$\\|b");
+ valid_pattern ("(^a|^b)^c");
+ valid_pattern ("c$(a$|b$)");
+ valid_pattern ("(^a|^b)^|^c");
+ valid_pattern ("(a$|b$)$|$c$");
+ valid_pattern ("(a$|$b$)$|c$");
+ valid_pattern ("($a$|b$)$|c$");
+ valid_pattern ("$(a$|b$)$|c$");
+ valid_pattern ("^c|d(^a|^b)");
+ valid_pattern ("(^a|^b)|d^c");
+ valid_pattern ("c$|(a$|b$)d");
+ valid_pattern ("c$d|(a$|b$)");
+ valid_pattern ("c(^a|^b)|^d");
+ valid_pattern ("(a$|b$)c|d$");
+ valid_pattern ("c(((^a|^b))|^d)e");
+ valid_pattern ("(c((^a|^b))|^d)e");
+ valid_pattern ("((c(^a|^b))|^d)e");
+ valid_pattern ("(((^a|^b))|c^d)e");
+ valid_pattern ("(((^a|^b))|^d)^e");
+ valid_pattern ("(c$((a|b))|d)e$");
+ valid_pattern ("(c((a$|b$))|d)e$");
+ valid_pattern ("(c((a|b)$)|d)e$");
+ valid_pattern ("(c((a|b))|d$)e$");
+ valid_pattern ("^d(^c|e((a|b)))");
+ valid_pattern ("^d(c|^e((a|b)))");
+ valid_pattern ("^d(c|e(^(a|b)))");
+ valid_pattern ("^d(c|e((^a|b)))");
+ valid_pattern ("^d(c|e((a|^b)))");
+ valid_pattern ("^d(c|e((a|b^)))");
+ valid_pattern ("^d(c|e((a|b)^))");
+ valid_pattern ("^d(c|e((a|b))^)");
+ valid_pattern ("^d(c|e((a|b)))^");
+ valid_pattern ("d$(c$|e((a$|b$)))");
+ valid_pattern ("d(c$|e$((a$|b$)))");
+ valid_pattern ("(((^a|^b))^c)|^de");
+ valid_pattern ("(((^a|^b))c)|^d^e");
+ valid_pattern ("(((a$|b))c$)|de$");
+ valid_pattern ("(((a|b$))c$)|de$");
+ valid_pattern ("(((a|b))c$)|d$e$");
+ valid_pattern ("^d^e|^(c((a|b)))");
+ valid_pattern ("^de|^(c^((a|b)))");
+ valid_pattern ("^de|^(c(^(a|b)))");
+ valid_pattern ("^de|^(c((^a|b)))");
+ valid_pattern ("^de|^(c((a|^b)))");
+ valid_pattern ("^de|(^c(^(a|b)))");
+ valid_pattern ("^de|(^c((^a|b)))");
+ valid_pattern ("^de|(^c((a|^b)))");
+ valid_pattern ("de$|(c($(a|b)$))");
+ valid_pattern ("de$|(c$((a|b)$))");
+ valid_pattern ("de$|($c((a|b)$))");
+ valid_pattern ("de$|$(c((a|b)$))");
+ valid_pattern ("de$|(c($(a|b))$)");
+ valid_pattern ("de$|(c$((a|b))$)");
+ valid_pattern ("de$|$(c((a|b))$)");
+ valid_pattern ("de$|(c($(a|b)))$");
+ valid_pattern ("de$|(c$((a|b)))$");
+ valid_pattern ("de$|($c((a|b)))$");
+ valid_pattern ("de$|$(c((a|b)))$");
+ valid_pattern ("^a(^b|c)|^d");
+ valid_pattern ("^a(b|^c)|^d");
+ valid_pattern ("^a(b|c^)|^d");
+ valid_pattern ("^a(b|c)^|^d");
+ valid_pattern ("a$(b$|c$)|d$");
+ valid_pattern ("^d|^a(^b|c)");
+ valid_pattern ("^d|^a(b|^c)");
+ valid_pattern ("d$|a$(b$|c$)");
+ valid_pattern ("^d|^(b|c)^a");
+ valid_pattern ("d$|(b|c$)a$");
+ valid_pattern ("d$|(b$|c)a$");
+ valid_pattern ("^(a)^(b|c)|^d");
+ valid_pattern ("^(a)(^b|c)|^d");
+ valid_pattern ("^(a)(b|^c)|^d");
+ valid_pattern ("(a)$(b|c)$|d$");
+ valid_pattern ("(a$)(b|c)$|d$");
+ valid_pattern ("(^a)(^b|c)|^d");
+ valid_pattern ("(^a)(b|^c)|^d");
+ valid_pattern ("(a)$(b$|c$)|d$");
+ valid_pattern ("(a$)(b$|c$)|d$");
+ valid_pattern ("^d|^(b|c)^(a)");
+ valid_pattern ("^d|^(b|c)(^a)");
+ valid_pattern ("d$|(b|c$)(a)$");
+ valid_pattern ("d$|(b$|c)(a)$");
+ valid_pattern ("^d|(^b|^c)^(a)");
+ valid_pattern ("^d|(^b|^c)(^a)");
+ valid_pattern ("d$|(b|c)$(a$)");
+ valid_pattern ("d$|(b|c$)(a$)");
+ valid_pattern ("d$|(b$|c)(a$)");
+ valid_pattern ("^d|^(a)^(b|c)");
+ valid_pattern ("^d|^(a)(^b|c)");
+ valid_pattern ("^d|^(a)(b|^c)");
+ valid_pattern ("^d|(^a)^(b|c)");
+ valid_pattern ("^d|(^a)(^b|c)");
+ valid_pattern ("^d|(^a)(b|^c)");
+ valid_pattern ("d$|(a)$(b$|c$)");
+ valid_pattern ("d$|(a$)(b$|c$)");
+ valid_pattern ("((e^a|^b)|^c)|^d");
+ valid_pattern ("((^a|e^b)|^c)|^d");
+ valid_pattern ("((^a|^b)|e^c)|^d");
+ valid_pattern ("((^a|^b)|^c)|e^d");
+ valid_pattern ("d$e|(c$|(a$|b$))");
+ valid_pattern ("d$|(c$e|(a$|b$))");
+ valid_pattern ("d$|(c$|(a$e|b$))");
+ valid_pattern ("d$|(c$|(a$|b$e))");
+ valid_pattern ("d$|(c$|(a$|b$)e)");
+ valid_pattern ("d$|(c$|(a$|b$))e");
+ valid_pattern ("(a|b)^|c");
+ valid_pattern ("(a|b)|c^");
+ valid_pattern ("$(a|b)|c");
+ valid_pattern ("(a|b)|$c");
+ valid_pattern ("(a^|^b)|^c");
+ valid_pattern ("(^a|b^)|^c");
+ valid_pattern ("(^a|^b)|c^");
+ valid_pattern ("($a|b$)|c$");
+ valid_pattern ("(a$|$b)|c$");
+ valid_pattern ("(a$|b$)|$c");
+ valid_pattern ("c^|(^a|^b)");
+ valid_pattern ("^c|(a^|^b)");
+ valid_pattern ("^c|(^a|b^)");
+ valid_pattern ("$c|(a$|b$)");
+ valid_pattern ("c$|($a|b$)");
+ valid_pattern ("c$|(a$|$b)");
+ valid_pattern ("c^|^(a|b)");
+ valid_pattern ("^c|(a|b)^");
+ valid_pattern ("$c|(a|b)$");
+ valid_pattern ("c$|$(a|b)");
+ valid_pattern ("(a^|^b)c|^d");
+ valid_pattern ("(^a|b^)c|^d");
+ valid_pattern ("(^a|^b)c|d^");
+ valid_pattern ("(^a|^b)^c|^d");
+ valid_pattern ("(a|b)c$|$d");
+ valid_pattern ("(a|b)$c$|d$");
+ valid_pattern ("(a|b)$c$|d$");
+ valid_pattern ("(a|b$)c$|d$");
+ valid_pattern ("(a$|b)c$|d$");
+ valid_pattern ("($a|b)c$|d$");
+ valid_pattern ("$(a|b)c$|d$");
+ valid_pattern ("^d|^c^(a|b)");
+ valid_pattern ("^d|^c(^a|b)");
+ valid_pattern ("^d|^c(a|^b)");
+ valid_pattern ("^d|^c(a|b^)");
+ valid_pattern ("^d|^c(a|b)^");
+ valid_pattern ("$d|c(a$|b$)");
+ valid_pattern ("d$|c($a$|b$)");
+ valid_pattern ("d$|c$(a$|b$)");
+ valid_pattern ("d$|$c(a$|b$)");
+
+ valid_pattern ("(((a^|^b))c|^d)e");
+ valid_pattern ("(((^a|b^))c|^d)e");
+ valid_pattern ("(((^a|^b))^c|^d)e");
+ valid_pattern ("((^(a|b))c|d^)e");
+ valid_pattern ("(^((a|b))c|^d)^e");
+ valid_pattern ("(^((a|b)^)c|^d)e");
+ valid_pattern ("(^((a^|b))c|^d)e");
+ valid_pattern ("(^((a|b^))c|^d)e");
+ valid_pattern ("(^((a|b)^)c|^d)e");
+ valid_pattern ("(^((a|b))^c|^d)e");
+ valid_pattern ("(^((a|b))c^|^d)e");
+ valid_pattern ("(^((a|b))c|^d^)e");
+ valid_pattern ("(^((a|b))c|^d)^e");
+ valid_pattern ("(((a|b))c|d)$e$");
+ valid_pattern ("(((a|b))c|d$)e$");
+ valid_pattern ("(((a|b))c|$d)e$");
+ valid_pattern ("(((a|b))c$|d)e$");
+ valid_pattern ("(((a|b))$c|d)e$");
+ valid_pattern ("(((a|b)$)c|d)e$");
+ valid_pattern ("(((a|b$))c|d)e$");
+ valid_pattern ("(((a$|b))c|d)e$");
+ valid_pattern ("((($a|b))c|d)e$");
+ valid_pattern ("(($(a|b))c|d)e$");
+ valid_pattern ("($((a|b))c|d)e$");
+ valid_pattern ("$(((a|b))c|d)e$");
+ valid_pattern ("(^((a|b)^)c|^d)e");
+ valid_pattern ("(^((a|b))^c|^d)e");
+ valid_pattern ("(^((a|b))c|^d^)e");
+ valid_pattern ("(^((a|b))c|^d)^e");
+
+ valid_pattern ("^e(^d|c((a|b)))");
+ valid_pattern ("^e(d|^c((a|b)))");
+ valid_pattern ("^e(d|c^((a|b)))");
+ valid_pattern ("^e(d|c(^(a|b)))");
+ valid_pattern ("^e(d|c((^a|b)))");
+ valid_pattern ("^e(d|c((a|^b)))");
+ valid_pattern ("^e(d|c((a|b^)))");
+ valid_pattern ("^e(d|c((a|b)^))");
+ valid_pattern ("^e(d|c((a|b))^)");
+ valid_pattern ("^e(d|c((a|b)))^");
+ valid_pattern ("e$(d$|c((a$|b$)))");
+ valid_pattern ("e(d$|c$((a$|b$)))");
+ valid_pattern ("e(d$|c($(a$|b$)))");
+ valid_pattern ("e(d$|c(($a$|b$)))");
+ valid_pattern ("e$(d$|c((a|b)$))");
+ valid_pattern ("e($d$|c((a|b)$))");
+ valid_pattern ("e(d$|$c((a|b)$))");
+ valid_pattern ("e(d$|c$((a|b)$))");
+ valid_pattern ("e(d$|c($(a|b)$))");
+ valid_pattern ("e(d$|c(($a|b)$))");
+ valid_pattern ("e(d$|c((a|$b)$))");
+ valid_pattern ("e(d$|c((a$|$b$)))");
+
+ valid_pattern ("e$(d$|c((a|b))$)");
+ valid_pattern ("e($d$|c((a|b))$)");
+ valid_pattern ("e(d$|$c((a|b))$)");
+ valid_pattern ("e(d$|c$((a|b))$)");
+ valid_pattern ("e(d$|c($(a|b))$)");
+ valid_pattern ("e(d$|c(($a|b))$)");
+ valid_pattern ("e(d$|c((a|$b))$)");
+ valid_pattern ("e$(d$|c((a|b)))$");
+ valid_pattern ("e($d$|c((a|b)))$");
+ valid_pattern ("e(d$|$c((a|b)))$");
+ valid_pattern ("e(d$|c$((a|b)))$");
+ valid_pattern ("e(d$|c($(a|b)))$");
+ valid_pattern ("e(d$|c(($a|b)))$");
+ valid_pattern ("e(d$|c((a|$b)))$");
+ valid_pattern ("(((^a|^b)^)c)|^de");
+ valid_pattern ("(((^a|^b))^c)|^de");
+ valid_pattern ("(((^a|^b))c)^|^de");
+ valid_pattern ("$(((a|b))c$)|de$");
+ valid_pattern ("($((a|b))c$)|de$");
+ valid_pattern ("(($(a|b))c$)|de$");
+ valid_pattern ("((($a|b))c$)|de$");
+ valid_pattern ("(((a|$b))c$)|de$");
+ valid_pattern ("(((a|b)$)c$)|de$");
+ valid_pattern ("(((a|b))$c$)|de$");
+ valid_pattern ("$(((a|b))c)$|de$");
+ valid_pattern ("($((a|b))c)$|de$");
+ valid_pattern ("(($(a|b))c)$|de$");
+ valid_pattern ("((($a|b))c)$|de$");
+ valid_pattern ("(((a|$b))c)$|de$");
+ valid_pattern ("(((a|b)$)c)$|de$");
+ valid_pattern ("(((a|b))$c)$|de$");
+ valid_pattern ("^ed|^(c((a|b)))^");
+ valid_pattern ("^ed|^(c((a|b))^)");
+ valid_pattern ("^ed|^(c((a|b)^))");
+ valid_pattern ("^ed|^(c((a|b^)))");
+ valid_pattern ("^ed|^(c((a^|b)))");
+ valid_pattern ("^ed|^(c((^a|b)))");
+ valid_pattern ("^ed|^(c(^(a|b)))");
+ valid_pattern ("^ed|^(c^((a|b)))");
+ valid_pattern ("^ed|(^c((a|b)))^");
+ valid_pattern ("^ed|(^c((a|b))^)");
+ valid_pattern ("^ed|(^c((a|b)^))");
+ valid_pattern ("^ed|(^c((a|b^)))");
+ valid_pattern ("^ed|(^c((a|^b)))");
+ valid_pattern ("^ed|(^c((a^|b)))");
+ valid_pattern ("^ed|(^c((^a|b)))");
+ valid_pattern ("^ed|(^c(^(a|b)))");
+ valid_pattern ("^ed|(^c(^(a|b)))");
+ valid_pattern ("^ed|(^c^((a|b)))");
+ valid_pattern ("ed$|$(c((a|b)))$");
+ valid_pattern ("ed$|($c((a|b)))$");
+ valid_pattern ("ed$|(c$((a|b)))$");
+ valid_pattern ("ed$|(c($(a|b)))$");
+ valid_pattern ("ed$|(c(($a|b)))$");
+ valid_pattern ("ed$|(c((a|$b)))$");
+ valid_pattern ("ed$|$(c((a|b))$)");
+ valid_pattern ("ed$|($c((a|b))$)");
+ valid_pattern ("ed$|(c$((a|b))$)");
+ valid_pattern ("ed$|(c($(a|b))$)");
+ valid_pattern ("ed$|(c(($a|b))$)");
+ valid_pattern ("ed$|(c((a|$b))$)");
+ valid_pattern ("ed$|$(c((a|b)$))");
+ valid_pattern ("ed$|($c((a|b)$))");
+ valid_pattern ("ed$|(c$((a|b)$))");
+ valid_pattern ("ed$|(c($(a|b)$))");
+ valid_pattern ("ed$|(c(($a|b)$))");
+ valid_pattern ("ed$|(c((a|$b)$))");
+ valid_pattern ("ed$|$(c((a|b)$))");
+ valid_pattern ("ed$|($c((a|b)$))");
+ valid_pattern ("ed$|(c$((a|b)$))");
+ valid_pattern ("ed$|(c($(a|b)$))");
+ valid_pattern ("ed$|(c(($a|b)$))");
+ valid_pattern ("ed$|(c((a|$b)$))");
+ valid_pattern ("ed$|$(c((a|b)$))");
+ valid_pattern ("ed$|($c((a|b)$))");
+ valid_pattern ("ed$|(c$((a|b)$))");
+ valid_pattern ("ed$|(c($(a|b)$))");
+ valid_pattern ("ed$|(c(($a|b)$))");
+ valid_pattern ("ed$|(c((a|$b)$))");
+ valid_pattern ("ed$|$(c((a|b)$))");
+ valid_pattern ("ed$|($c((a|b)$))");
+ valid_pattern ("ed$|(c$((a|b)$))");
+ valid_pattern ("ed$|(c($(a|b)$))");
+ valid_pattern ("ed$|(c(($a|b)$))");
+ valid_pattern ("ed$|(c((a|$b)$))");
+ valid_pattern ("ed$|$(c((a|b)$))");
+ valid_pattern ("ed$|($c((a|b)$))");
+ valid_pattern ("ed$|(c$((a|b)$))");
+ valid_pattern ("ed$|(c($(a|b)$))");
+ valid_pattern ("ed$|(c(($a|b)$))");
+ valid_pattern ("ed$|(c((a|$b)$))");
+ valid_pattern ("ed$|$(c((a$|b$)))");
+ valid_pattern ("ed$|($c((a$|b$)))");
+ valid_pattern ("ed$|(c$((a$|b$)))");
+ valid_pattern ("ed$|(c($(a$|b$)))");
+ valid_pattern ("ed$|(c(($a$|b$)))");
+ valid_pattern ("ed$|(c((a$|$b$)))");
+ valid_pattern ("^a(b|c)^|^d");
+ valid_pattern ("^a(b|c^)|^d");
+ valid_pattern ("^a(b|^c)|^d");
+ valid_pattern ("^a(b^|c)|^d");
+ valid_pattern ("^a(^b|c)|^d");
+ valid_pattern ("^a^(b|c)|^d");
+ valid_pattern ("$a(b$|c$)|d$");
+ valid_pattern ("a$(b$|c$)|d$");
+ valid_pattern ("a($b$|c$)|d$");
+ valid_pattern ("a(b$|$c$)|d$");
+ valid_pattern ("a(b$|c$)|$d$");
+ valid_pattern ("^(a^)(b|c)|^d");
+ valid_pattern ("^(a)^(b|c)|^d");
+ valid_pattern ("^(a)(^b|c)|^d");
+ valid_pattern ("^(a)(b^|c)|^d");
+ valid_pattern ("^(a)(b|^c)|^d");
+ valid_pattern ("^(a)(b|c^)|^d");
+ valid_pattern ("^(a)(b|c)^|^d");
+ valid_pattern ("(^a^)(b|c)|^d");
+ valid_pattern ("(^a)^(b|c)|^d");
+ valid_pattern ("(^a)(^b|c)|^d");
+ valid_pattern ("(^a)(b^|c)|^d");
+ valid_pattern ("(^a)(b|^c)|^d");
+ valid_pattern ("(^a)(b|c^)|^d");
+ valid_pattern ("(^a)(b|c)^|^d");
+
+ valid_pattern ("(a)(b$|c$)d$");
+ valid_pattern ("(a)(b|$c)$|d$");
+ valid_pattern ("(a)($b|c)$|d$");
+ valid_pattern ("(a)$(b|c)$|d$");
+ valid_pattern ("(a$)(b|c)$|d$");
+ valid_pattern ("($a)(b|c)$|d$");
+ valid_pattern ("$(a)(b|c)$|d$");
+ valid_pattern ("(b|c)($a)$|d$");
+ valid_pattern ("(b|c)$(a)$|d$");
+ valid_pattern ("(b|c$)(a)$|d$");
+ valid_pattern ("(b|$c)(a)$|d$");
+ valid_pattern ("(b$|c)(a)$|d$");
+ valid_pattern ("($b|c)(a)$|d$");
+ valid_pattern ("$(b|c)(a)$|d$");
+ valid_pattern ("(b|c)($a$)|d$");
+ valid_pattern ("(b|c)$(a$)|d$");
+ valid_pattern ("(b|c$)(a$)|d$");
+ valid_pattern ("(b|$c)(a$)|d$");
+ valid_pattern ("(b$|c)(a$)|d$");
+ valid_pattern ("($b|c)(a$)|d$");
+ valid_pattern ("$(b|c)(a$)|d$");
+ valid_pattern ("(a)$(b$|c$)|d$");
+ valid_pattern ("(a$)(b$|c$)|d$");
+ valid_pattern ("($a)(b$|c$)|d$");
+ valid_pattern ("$(a)(b$|c$)|d$");
+ valid_pattern ("^d|^(b^|c)(a)");
+ valid_pattern ("^d|^(b|c^)(a)");
+ valid_pattern ("^d|^(b|c)^(a)");
+ valid_pattern ("^d|^(b|c)(^a)");
+ valid_pattern ("^d|^(b|c)(a^)");
+ valid_pattern ("^d|^(b|c)(a)^");
+ valid_pattern ("^d|(^b|^c^)(a)");
+ valid_pattern ("^d|(^b|^c)^(a)");
+ valid_pattern ("^d|(^b|^c)(^a)");
+ valid_pattern ("^d|(^b|^c)(a^)");
+ valid_pattern ("^d|(^b|^c)(a)^");
+ valid_pattern ("d$|(b|c)($a$)");
+ valid_pattern ("d$|(b|c)$(a$)");
+ valid_pattern ("d$|(b|c$)(a$)");
+ valid_pattern ("d$|(b$|c)(a$)");
+ valid_pattern ("d$|($b|c)(a$)");
+ valid_pattern ("d$|$(b|c)(a$)");
+ valid_pattern ("d$|(b|c)($a)$");
+ valid_pattern ("d$|(b|c)$(a)$");
+ valid_pattern ("d$|(b|c$)(a)$");
+ valid_pattern ("d$|(b$|c)(a)$");
+ valid_pattern ("d$|($b|c)(a)$");
+ valid_pattern ("d$|$(b|c)(a)$");
+ valid_pattern ("^d|^(a^)(b|c)");
+ valid_pattern ("^d|^(a)^(b|c)");
+ valid_pattern ("^d|^(a)(^b|c)");
+ valid_pattern ("^d|^(a)(b^|c)");
+ valid_pattern ("^d|^(a)(b|^c)");
+ valid_pattern ("^d|^(a)(b|c^)");
+ valid_pattern ("^d|^(a)(b|c)^");
+ valid_pattern ("^d|(^a^)(b|c)");
+ valid_pattern ("^d|(^a)^(b|c)");
+ valid_pattern ("^d|(^a)(^b|c)");
+ valid_pattern ("^d|(^a)(b^|c)");
+ valid_pattern ("^d|(^a)(b|^c)");
+ valid_pattern ("^d|(^a)(b|c^)");
+ valid_pattern ("^d|(^a)(b|c)^");
+ valid_pattern ("d$|(a)$(b$|c$)");
+ valid_pattern ("d$|(a$)(b$|c$)");
+ valid_pattern ("d$|($a)(b$|c$)");
+ valid_pattern ("d$|$(a)(b$|c$)");
+ valid_pattern ("d$|(a)(b|$c)$");
+ valid_pattern ("d$|(a)($b|c)$");
+ valid_pattern ("d$|(a)$(b|c)$");
+ valid_pattern ("d$|(a$)(b|c)$");
+ valid_pattern ("d$|($a)(b|c)$");
+ valid_pattern ("d$|$(a)(b|c)$");
+ valid_pattern ("((^a|^b)|^c)|^d^");
+ valid_pattern ("((^a|^b)|^c)^|^d");
+ valid_pattern ("((^a|^b)|^c^)|^d");
+ valid_pattern ("((^a|^b)^|^c)|^d");
+ valid_pattern ("((^a|^b^)|^c)|^d");
+ valid_pattern ("((^a^|^b)|^c)|^d");
+ valid_pattern ("((a|b)|c)|$d$");
+ valid_pattern ("((a|b)|$c)|d$");
+ valid_pattern ("((a|$b)|c)|d$");
+ valid_pattern ("(($a|b)|c)|d$");
+ valid_pattern ("($(a|b)|c)|d$");
+ valid_pattern ("$((a|b)|c)|d$");
+ valid_pattern ("^d^|(c|(a|b))");
+ valid_pattern ("^d|(c^|(a|b))");
+ valid_pattern ("^d|(c|(a^|b))");
+ valid_pattern ("^d|(c|(a|b^))");
+ valid_pattern ("^d|(c|(a|b)^)");
+ valid_pattern ("^d|(c|(a|b))^");
+ valid_pattern ("d$|(c$|(a$|$b$))");
+ valid_pattern ("d$|(c$|($a$|b$))");
+ valid_pattern ("d$|($c$|(a$|b$))");
+ valid_pattern ("d$|$(c$|(a$|b$))");
+ valid_pattern ("$d$|(c$|(a$|b$))");
+ valid_pattern ("d$|(c$|(a|$b)$)");
+ valid_pattern ("d$|(c$|($a|b)$)");
+ valid_pattern ("d$|($c$|(a|b)$)");
+ valid_pattern ("d$|$(c$|(a|b)$)");
+ valid_pattern ("$d$|(c$|(a|b)$)");
+ valid_pattern ("d$|(c$|(a|$b))$");
+ valid_pattern ("d$|(c$|($a|b))$");
+ valid_pattern ("d$|($c$|(a|b))$");
+ valid_pattern ("d$|$(c$|(a|b))$");
+ valid_pattern ("$d$|(c$|(a|b))$");
+ valid_pattern ("^c^|(^a|^b)");
+ valid_pattern ("^c|(^a^|^b)");
+ valid_pattern ("^c|(^a|^b^)");
+ valid_pattern ("^c|(^a|^b)^");
+ valid_pattern ("c$|(a$|$b$)");
+ valid_pattern ("c$|($a$|b$)");
+ valid_pattern ("c$|$(a$|b$)");
+ valid_pattern ("$c$|(a$|b$)");
+ valid_pattern ("^d^(c|e((a|b)))");
+ valid_pattern ("^d(^c|e((a|b)))");
+ valid_pattern ("^d(c^|e((a|b)))");
+ valid_pattern ("^d(c|^e((a|b)))");
+ valid_pattern ("^d(c|e^((a|b)))");
+ valid_pattern ("^d(c|e(^(a|b)))");
+ valid_pattern ("^d(c|e((^a|b)))");
+ valid_pattern ("^d(c|e((a|^b)))");
+ valid_pattern ("^d(c|e((a|b^)))");
+ valid_pattern ("^d(c|e((a|b)^))");
+ valid_pattern ("^d(c|e((a|b))^)");
+ valid_pattern ("^d(c|e((a|b)))^");
+ valid_pattern ("d(c$|e($(a$|b$)))");
+ valid_pattern ("d(c$|e$((a$|b$)))");
+ valid_pattern ("d(c$|$e((a$|b$)))");
+ valid_pattern ("d($c$|e((a$|b$)))");
+ valid_pattern ("d$(c$|e((a$|b$)))");
+ valid_pattern ("$d(c$|e((a$|b$)))");
+ valid_pattern ("^d|^a^(b|c)");
+ valid_pattern ("^d|^a(^b|c)");
+ valid_pattern ("^d|^a(b^|c)");
+ valid_pattern ("^d|^a(b|^c)");
+ valid_pattern ("^d|^a(b|c^)");
+ valid_pattern ("^d|^a(b|c)^");
+ valid_pattern ("d$|a($b$|c$)");
+ valid_pattern ("d$|a$(b$|c$)");
+ valid_pattern ("d$|$a(b$|c$)");
+ valid_pattern ("$d$|a(b$|c$)");
+ valid_pattern ("^d|^(b^|c)a");
+ valid_pattern ("^d|^(b|c^)a");
+ valid_pattern ("^d|^(b|c)^a");
+ valid_pattern ("^d|^(b|c)a^");
+ valid_pattern ("d$|(b|c)$a$");
+ valid_pattern ("d$|(b|c$)a$");
+ valid_pattern ("d$|(b|$c)a$");
+ valid_pattern ("d$|(b$|c)a$");
+ valid_pattern ("d$|($b|c)a$");
+ valid_pattern ("d$|$(b|c)a$");
+ valid_pattern ("$d$|(b|c)a$");
+
+ /* xx Do these use all the valid_nonposix_pattern ones in other_test.c? */
+
+ TEST_SEARCH ("(^a|^b)c", "ac", 0, 2);
+ TEST_SEARCH ("(^a|^b)c", "bc", 0, 2);
+ TEST_SEARCH ("c(a$|b$)", "ca", 0, 2);
+ TEST_SEARCH ("c(a$|b$)", "cb", 0, 2);
+ TEST_SEARCH ("^(a|b)|^c", "ad", 0, 2);
+ TEST_SEARCH ("^(a|b)|^c", "bd", 0, 2);
+ TEST_SEARCH ("(a|b)$|c$", "da", 0, 2);
+ TEST_SEARCH ("(a|b)$|c$", "db", 0, 2);
+ TEST_SEARCH ("(a|b)$|c$", "dc", 0, 2);
+ TEST_SEARCH ("(^a|^b)|^c", "ad", 0, 2);
+ TEST_SEARCH ("(^a|^b)|^c", "bd", 0, 2);
+ TEST_SEARCH ("(^a|^b)|^c", "cd", 0, 2);
+ TEST_SEARCH ("(a$|b$)|c$", "da", 0, 2);
+ TEST_SEARCH ("(a$|b$)|c$", "db", 0, 2);
+ TEST_SEARCH ("(a$|b$)|c$", "dc", 0, 2);
+ TEST_SEARCH ("^c|(^a|^b)", "ad", 0, 2);
+ TEST_SEARCH ("^c|(^a|^b)", "bd", 0, 2);
+ TEST_SEARCH ("^c|(^a|^b)", "cd", 0, 2);
+ TEST_SEARCH ("c$|(a$|b$)", "da", 0, 2);
+ TEST_SEARCH ("c$|(a$|b$)", "db", 0, 2);
+ TEST_SEARCH ("c$|(a$|b$)", "dc", 0, 2);
+ TEST_SEARCH ("^c|^(a|b)", "ad", 0, 2);
+ TEST_SEARCH ("^c|^(a|b)", "bd", 0, 2);
+ TEST_SEARCH ("^c|^(a|b)", "cd", 0, 2);
+ TEST_SEARCH ("c$|(a|b)$", "da", 0, 2);
+ TEST_SEARCH ("c$|(a|b)$", "db", 0, 2);
+ TEST_SEARCH ("c$|(a|b)$", "dc", 0, 2);
+ TEST_SEARCH ("(^a|^b)c|^d", "ace", 0, 3);
+ TEST_SEARCH ("(^a|^b)c|^d", "bce", 0, 3);
+ TEST_SEARCH ("(^a|^b)c|^d", "de", 0, 2);
+ TEST_SEARCH ("(a|b)c$|d$", "eac", 0, 3);
+ TEST_SEARCH ("(a|b)c$|d$", "ebc", 0, 3);
+ TEST_SEARCH ("(a|b)c$|d$", "ed", 0, 3);
+ TEST_SEARCH ("^d|^c(a|b)", "cae", 0, 3);
+ TEST_SEARCH ("^d|^c(a|b)", "cbe", 0, 3);
+ TEST_SEARCH ("^d|^c(a|b)", "de", 0, 3);
+ TEST_SEARCH ("d$|c(a$|b$)", "eca", 0, 3);
+ TEST_SEARCH ("d$|c(a$|b$)", "ecb", 0, 3);
+ TEST_SEARCH ("d$|c(a$|b$)", "ed", 0, 3);
+
+ TEST_SEARCH ("(((^a|^b))c|^d)e", "acef", 0, 4);
+ TEST_SEARCH ("(((^a|^b))c|^d)e", "bcef", 0, 4);
+ TEST_SEARCH ("(((^a|^b))c|^d)e", "def", 0, 3);
+
+ TEST_SEARCH ("((^(a|b))c|^d)e", "acef", 0, 4);
+ TEST_SEARCH ("((^(a|b))c|^d)e", "bcef", 0, 4);
+ TEST_SEARCH ("((^(a|b))c|^d)e", "def", 0, 3);
+
+ TEST_SEARCH ("(^((a|b))c|^d)e", "acef", 0, 4);
+ TEST_SEARCH ("(^((a|b))c|^d)e", "bcef", 0, 4);
+ TEST_SEARCH ("(^((a|b))c|^d)e", "def", 0, 3);
+
+ TEST_SEARCH ("(((a|b))c|d)e$", "face", 0, 4);
+ TEST_SEARCH ("(((a|b))c|d)e$", "fbce", 0, 4);
+ TEST_SEARCH ("(((a|b))c|d)e$", "fde", 0, 3);
+
+ TEST_SEARCH ("^e(d|c((a|b)))", "edf", 0, 3);
+ TEST_SEARCH ("^e(d|c((a|b)))", "ecaf", 0, 4);
+ TEST_SEARCH ("^e(d|c((a|b)))", "ecbf", 0, 4);
+
+ TEST_SEARCH ("e(d$|c((a$|b$)))", "fed", 0, 3);
+ TEST_SEARCH ("e(d$|c((a$|b$)))", "feca", 0, 4);
+ TEST_SEARCH ("e(d$|c((a$|b$)))", "fecb", 0, 4);
+
+ TEST_SEARCH ("e(d$|c((a|b)$))", "fed", 0, 3);
+ TEST_SEARCH ("e(d$|c((a|b)$))", "feca", 0, 4);
+ TEST_SEARCH ("e(d$|c((a|b)$))", "fecb", 0, 4);
+
+ TEST_SEARCH ("e(d$|c((a|b))$)", "fed", 0, 3);
+ TEST_SEARCH ("e(d$|c((a|b))$)", "feca", 0, 3);
+ TEST_SEARCH ("e(d$|c((a|b))$)", "fecb", 0, 3);
+
+ TEST_SEARCH ("e(d$|c((a|b)))$", "fed", 0, 3);
+ TEST_SEARCH ("e(d$|c((a|b)))$", "feca", 0, 3);
+ TEST_SEARCH ("e(d$|c((a|b)))$", "fecb", 0, 3);
+
+ TEST_SEARCH ("(((^a|^b))c)|^de", "acf", 0, 3);
+ TEST_SEARCH ("(((^a|^b))c)|^de", "bcf", 0, 3);
+ TEST_SEARCH ("(((^a|^b))c)|^de", "def", 0, 3);
+
+ TEST_SEARCH ("(((a|b))c$)|de$", "fac", 0, 3);
+ TEST_SEARCH ("(((a|b))c$)|de$", "fbc", 0, 3);
+ TEST_SEARCH ("(((a|b))c$)|de$", "fde", 0, 3);
+
+ TEST_SEARCH ("(((a|b))c)$|de$", "fac", 0, 3);
+ TEST_SEARCH ("(((a|b))c)$|de$", "fbc", 0, 3);
+ TEST_SEARCH ("(((a|b))c)$|de$", "fde", 0, 3);
+
+ TEST_SEARCH ("^ed|^(c((a|b)))", "edf", 0, 3);
+ TEST_SEARCH ("^ed|^(c((a|b)))", "caf", 0, 3);
+ TEST_SEARCH ("^ed|^(c((a|b)))", "cbf", 0, 3);
+
+ TEST_SEARCH ("^ed|(^c((a|b)))", "edf", 0, 3);
+ TEST_SEARCH ("^ed|(^c((a|b)))", "caf", 0, 3);
+ TEST_SEARCH ("^ed|(^c((a|b)))", "cbf", 0, 3);
+
+ TEST_SEARCH ("ed$|(c((a|b)))$", "fed", 0, 3);
+ TEST_SEARCH ("ed$|(c((a|b)))$", "fca", 0, 3);
+ TEST_SEARCH ("ed$|(c((a|b)))$", "fcb", 0, 3);
+
+ TEST_SEARCH ("ed$|(c((a|b))$)", "fed", 0, 3);
+ TEST_SEARCH ("ed$|(c((a|b))$)", "fca", 0, 3);
+ TEST_SEARCH ("ed$|(c((a|b))$)", "fcb", 0, 3);
+
+ TEST_SEARCH ("ed$|(c((a|b)$))", "fed", 0, 3);
+ TEST_SEARCH ("ed$|(c((a|b)$))", "fca", 0, 3);
+ TEST_SEARCH ("ed$|(c((a|b)$))", "fcb", 0, 3);
+
+ TEST_SEARCH ("ed$|(c((a$|b$)))", "fed", 0, 3);
+ TEST_SEARCH ("ed$|(c((a$|b$)))", "fca", 0, 3);
+ TEST_SEARCH ("ed$|(c((a$|b$)))", "fcb", 0, 3);
+
+ TEST_SEARCH ("^a(b|c)|^d", "abe", 0, 3);
+ TEST_SEARCH ("^a(b|c)|^d", "ace", 0, 3);
+ TEST_SEARCH ("^a(b|c)|^d", "df", 0, 2);
+
+ TEST_SEARCH ("a(b$|c$)|d$", "fab", 0, 3);
+ TEST_SEARCH ("a(b$|c$)|d$", "fac", 0, 3);
+ TEST_SEARCH ("a(b$|c$)|d$", "fd", 0, 2);
+
+ TEST_SEARCH ("^(a)(b|c)|^d", "abe", 0, 3);
+ TEST_SEARCH ("^(a)(b|c)|^d", "ace", 0, 3);
+ TEST_SEARCH ("^(a)(b|c)|^d", "df", 0, 2);
+
+ TEST_SEARCH ("(^a)(b|c)|^d", "abe", 0, 3);
+ TEST_SEARCH ("(^a)(b|c)|^d", "ace", 0, 3);
+ TEST_SEARCH ("(^a)(b|c)|^d", "df", 0, 2);
+
+ TEST_SEARCH ("(a)(b|c)$|d$", "fab", 0, 3);
+ TEST_SEARCH ("(a)(b|c)$|d$", "fac", 0, 3);
+ TEST_SEARCH ("(a)(b|c)$|d$", "fd", 0, 2);
+
+ TEST_SEARCH ("(b|c)(a)$|d$", "fba", 0, 3);
+ TEST_SEARCH ("(b|c)(a)$|d$", "fca", 0, 3);
+ TEST_SEARCH ("(b|c)(a)$|d$", "fd", 0, 2);
+
+ TEST_SEARCH ("(b|c)(a$)|d$", "fba", 0, 3);
+ TEST_SEARCH ("(b|c)(a$)|d$", "fca", 0, 3);
+ TEST_SEARCH ("(b|c)(a$)|d$", "fd", 0, 2);
+
+ TEST_SEARCH ("(a)(b$|c$)|d$", "fab", 0, 3);
+ TEST_SEARCH ("(a)(b$|c$)|d$", "fac", 0, 3);
+ TEST_SEARCH ("(a)(b$|c$)|d$", "fd", 0, 2);
+
+ TEST_SEARCH ("^d|^(b|c)(a)", "df", 0, 2);
+ TEST_SEARCH ("^d|^(b|c)(a)", "baf", 0, 3);
+ TEST_SEARCH ("^d|^(b|c)(a)", "caf", 0, 3);
+
+ TEST_SEARCH ("^d|(^b|^c)(a)", "df", 0, 2);
+ TEST_SEARCH ("^d|(^b|^c)(a)", "baf", 0, 3);
+ TEST_SEARCH ("^d|(^b|^c)(a)", "caf", 0, 3);
+
+ TEST_SEARCH ("d$|(b|c)(a$)", "fd", 0, 2);
+ TEST_SEARCH ("d$|(b|c)(a$)", "fba", 0, 3);
+ TEST_SEARCH ("d$|(b|c)(a$)", "fca", 0, 3);
+
+ TEST_SEARCH ("d$|(b|c)(a)$", "fd", 0, 2);
+ TEST_SEARCH ("d$|(b|c)(a)$", "fba", 0, 3);
+ TEST_SEARCH ("d$|(b|c)(a)$", "fca", 0, 3);
+
+ TEST_SEARCH ("d$|(b|c)(a$)", "fd", 0, 2);
+ TEST_SEARCH ("d$|(b|c)(a$)", "fba", 0, 3);
+ TEST_SEARCH ("d$|(b|c)(a$)", "fca", 0, 3);
+
+ TEST_SEARCH ("^d|^(a)(b|c)", "df", 0, 2);
+ TEST_SEARCH ("^d|^(a)(b|c)", "abf", 0, 3);
+ TEST_SEARCH ("^d|^(a)(b|c)", "acf", 0, 3);
+
+ TEST_SEARCH ("^d|(^a)(b|c)", "df", 0, 2);
+ TEST_SEARCH ("^d|(^a)(b|c)", "abf", 0, 3);
+ TEST_SEARCH ("^d|(^a)(b|c)", "acf", 0, 3);
+
+ TEST_SEARCH ("d$|(a)(b$|c$)", "fd", 0, 2);
+ TEST_SEARCH ("d$|(a)(b$|c$)", "fab", 0, 3);
+ TEST_SEARCH ("d$|(a)(b$|c$)", "fac", 0, 3);
+
+ TEST_SEARCH ("d$|(a)(b|c)$", "fd", 0, 2);
+ TEST_SEARCH ("d$|(a)(b|c)$", "fab", 0, 3);
+ TEST_SEARCH ("d$|(a)(b|c)$", "fac", 0, 3);
+
+ TEST_SEARCH ("((^a|^b)|^c)|^d", "ae", 0, 2);
+ TEST_SEARCH ("((^a|^b)|^c)|^d", "be", 0, 2);
+ TEST_SEARCH ("((^a|^b)|^c)|^d", "ce", 0, 2);
+ TEST_SEARCH ("((^a|^b)|^c)|^d", "de", 0, 2);
+
+ TEST_SEARCH ("((a|b)|c)|d$", "ed", 0, 2);
+ TEST_SEARCH ("((a|b)|c)|d$", "ea", 0, 2);
+ TEST_SEARCH ("((a|b)|c)|d$", "eb", 0, 2);
+ TEST_SEARCH ("((a|b)|c)|d$", "ec", 0, 2);
+
+ TEST_SEARCH ("^d|(c|(a|b))", "de", 0, 2);
+
+ TEST_SEARCH ("d$|(c$|(a$|b$))", "ed", 0, 2);
+ TEST_SEARCH ("d$|(c$|(a$|b$))", "ec", 0, 2);
+ TEST_SEARCH ("d$|(c$|(a$|b$))", "ea", 0, 2);
+ TEST_SEARCH ("d$|(c$|(a$|b$))", "eb", 0, 2);
+
+ TEST_SEARCH ("d$|(c$|(a|b)$)", "ed", 0, 2);
+ TEST_SEARCH ("d$|(c$|(a|b)$)", "ec", 0, 2);
+ TEST_SEARCH ("d$|(c$|(a|b)$)", "ea", 0, 2);
+ TEST_SEARCH ("d$|(c$|(a|b)$)", "eb", 0, 2);
+
+ TEST_SEARCH ("d$|(c$|(a|b))$", "ed", 0, 2);
+ TEST_SEARCH ("d$|(c$|(a|b))$", "ec", 0, 2);
+ TEST_SEARCH ("d$|(c$|(a|b))$", "ea", 0, 2);
+ TEST_SEARCH ("d$|(c$|(a|b))$", "eb", 0, 2);
+
+ test_match ("a|^b", "b");
+ test_match ("a|b$", "b");
+ test_match ("^b|a", "b");
+ test_match ("b$|a", "b");
+ test_match ("(^a)", "a");
+ test_match ("(a$)", "a");
+ TEST_SEARCH ("c|^ab", "aba", 0, 3);
+ TEST_SEARCH ("c|ba$", "aba", 0, 3);
+ TEST_SEARCH ("^ab|c", "aba", 0, 3);
+ TEST_SEARCH ("ba$|c", "aba", 0, 3);
+ TEST_SEARCH ("(^a)", "ab", 0, 2);
+ TEST_SEARCH ("(a$)", "ba", 0, 2);
+
+ TEST_SEARCH ("(^a$)", "a", 0, 1);
+ TEST_SEARCH ("(^a)", "ab", 0, 2);
+ TEST_SEARCH ("(b$)", "ab", 0, 2);
+
+ /* Backtracking. */
+ /* Per POSIX D11.1 p. 108, leftmost longest match. */
+ test_match ("(wee|week)(knights|night)", "weeknights");
+
+ test_match ("(fooq|foo)qbar", "fooqbar");
+ test_match ("(fooq|foo)(qbarx|bar)", "fooqbarx");
+
+ /* Take first alternative that does the longest match. */
+ test_all_registers ("(fooq|(foo)|(fo))((qbarx)|(oqbarx)|bar)", "fooqbarx",
+ "", 0, 8, 0, 3, 0, 3, -1, -1, 3, 8, 3, 8, -1, -1, -1, -1, -1, -1,
+ -1, -1);
+
+ test_match ("(fooq|foo)*qbar", "fooqbar");
+ test_match ("(fooq|foo)*(qbar)", "fooqbar");
+ test_match ("(fooq|foo)*(qbar)*", "fooqbar");
+
+ test_match ("(fooq|fo|o)*qbar", "fooqbar");
+ test_match ("(fooq|fo|o)*(qbar)", "fooqbar");
+ test_match ("(fooq|fo|o)*(qbar)*", "fooqbar");
+
+ test_match ("(fooq|fo|o)*(qbar|q)*", "fooqbar");
+ test_match ("(fooq|foo)*(qbarx|bar)", "fooqbarx");
+ test_match ("(fooq|foo)*(qbarx|bar)*", "fooqbarx");
+
+ test_match ("(fooq|fo|o)+(qbar|q)+", "fooqbar");
+ test_match ("(fooq|foo)+(qbarx|bar)", "fooqbarx");
+ test_match ("(fooq|foo)+(qbarx|bar)+", "fooqbarx");
+
+ /* Per Mike Haertel. */
+ test_match ("(foo|foobarfoo)(bar)*", "foobarfoo");
+
+ /* Combination. */
+ test_match ("[ab]?c", "ac");
+ test_match ("[ab]*c", "ac");
+ test_match ("[ab]+c", "ac");
+ test_match ("(a|b)?c", "ac");
+ test_match ("(a|b)*c", "ac");
+ test_match ("(a|b)+c", "ac");
+ test_match ("(a*c)?b", "b");
+ test_match ("(a*c)+b", "aacb");
+ /* Registers. */
+ /* Per David A. Willcox. */
+ test_match ("a((b)|(c))d", "acd");
+ test_all_registers ("a((b)|(c))d", "acd", "", 0, 3, 1, 2, -1, -1, 1, 2,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1);
+
+
+ /* Extended regular expressions, continued; these don't match their strings. */
+ test_should_match = false;
+
+#if 0
+ /* Invalid use of special characters. */
+ /* These are not invalid anymore, since POSIX says the behavior is
+ undefined, and we prefer context-independent to context-invalid. */
+ invalid_pattern (REG_BADRPT, "*");
+ invalid_pattern (REG_BADRPT, "a|*");
+ invalid_pattern (REG_BADRPT, "(*)");
+ invalid_pattern (REG_BADRPT, "^*");
+ invalid_pattern (REG_BADRPT, "+");
+ invalid_pattern (REG_BADRPT, "a|+");
+ invalid_pattern (REG_BADRPT, "(+)");
+ invalid_pattern (REG_BADRPT, "^+");
+
+ invalid_pattern (REG_BADRPT, "?");
+ invalid_pattern (REG_BADRPT, "a|?");
+ invalid_pattern (REG_BADRPT, "(?)");
+ invalid_pattern (REG_BADRPT, "^?");
+
+ invalid_pattern (REG_BADPAT, "|");
+ invalid_pattern (REG_BADPAT, "a|");
+ invalid_pattern (REG_BADPAT, "a||");
+ invalid_pattern (REG_BADPAT, "(|a)");
+ invalid_pattern (REG_BADPAT, "(a|)");
+
+ invalid_pattern (REG_BADPAT, PARENS_TO_OPS ("(|)"));
+
+ invalid_pattern (REG_BADRPT, "{1}");
+ invalid_pattern (REG_BADRPT, "a|{1}");
+ invalid_pattern (REG_BADRPT, "^{1}");
+ invalid_pattern (REG_BADRPT, "({1})");
+
+ invalid_pattern (REG_BADPAT, "|b");
+
+ invalid_pattern (REG_BADRPT, "^{0,}*");
+ invalid_pattern (REG_BADRPT, "$*");
+ invalid_pattern (REG_BADRPT, "${0,}*");
+#endif /* 0 */
+
+ invalid_pattern (REG_EESCAPE, "\\");
+
+ test_match ("a?b", "a");
+
+
+ test_match ("a+", "");
+ test_match ("a+b", "a");
+ test_match ("a?", "b");
+
+#if 0
+ /* We make empty groups valid now, since they are undefined in POSIX.
+ (13 Sep 92) */
+ /* Subexpressions. */
+ invalid_pattern (REG_BADPAT, "()");
+ invalid_pattern (REG_BADPAT, "a()");
+ invalid_pattern (REG_BADPAT, "()b");
+ invalid_pattern (REG_BADPAT, "a()b");
+ invalid_pattern (REG_BADPAT, "()*");
+ invalid_pattern (REG_BADPAT, "(()*");
+#endif
+ /* Invalid intervals. */
+ test_match ("a{2}*", "aaa");
+ test_match ("a{2}?", "aaa");
+ test_match ("a{2}+", "aaa");
+ test_match ("a{2}{2}", "aaa");
+ test_match ("a{1}{1}{2}", "aaa");
+ test_match ("a{1}{1}{2}", "a");
+ /* Invalid alternation. */
+ test_match ("a|b", "c");
+
+ TEST_SEARCH ("c|^ba", "aba", 0, 3);
+ TEST_SEARCH ("c|ab$", "aba", 0, 3);
+ TEST_SEARCH ("^ba|c", "aba", 0, 3);
+ TEST_SEARCH ("ab$|c", "aba", 0, 3);
+ /* Invalid anchoring. */
+ TEST_SEARCH ("(^a)", "ba", 0, 2);
+ TEST_SEARCH ("(b$)", "ba", 0, 2);
+
+ printf ("\nFinished POSIX extended tests.\n");
+}
+
+
+
+/*
+Local variables:
+make-backup-files: t
+version-control: t
+trim-versions-without-asking: nil
+End:
+*/
diff --git a/gnu/lib/libregex/test/psx-generic.c b/gnu/lib/libregex/test/psx-generic.c
new file mode 100644
index 000000000000..340e93875515
--- /dev/null
+++ b/gnu/lib/libregex/test/psx-generic.c
@@ -0,0 +1,336 @@
+/* psx-generic.c: test POSIX re's independent of us using basic or
+ extended syntax. */
+
+#include "test.h"
+
+
+void
+test_posix_generic ()
+{
+ int omit_generic_tests = 0; /* reset in debugger to skip */
+
+ if (omit_generic_tests)
+ return;
+ /* Tests somewhat in the order of P1003.2. */
+
+ /* Both posix basic and extended; should match. */
+
+ printf ("\nStarting generic POSIX tests.\n");
+ test_grouping ();
+ test_intervals ();
+
+ test_should_match = true;
+ /* Ordinary characters. */
+ printf ("\nContinuing generic POSIX tests.\n");
+
+ MATCH_SELF ("");
+ test_fastmap ("", "", 0, 0);
+ test_fastmap_search ("", "", "", 0, 0, 2, 0, 0);
+ TEST_REGISTERS ("", "", 0, 0, -1, -1, -1, -1);
+ TEST_SEARCH ("", "", 0, 0);
+ TEST_SEARCH_2 ("", "", "", 0, 1, 0);
+
+ MATCH_SELF ("abc");
+ test_fastmap ("abc", "a", 0, 0);
+ TEST_REGISTERS ("abc", "abc", 0, 3, -1, -1, -1, -1);
+ TEST_REGISTERS ("abc", "xabcx", 1, 4, -1, -1, -1, -1);
+
+ test_match ("\\a","a");
+ test_match ("\\0", "0");
+
+ TEST_SEARCH ("a", "ab", 0, 2);
+ TEST_SEARCH ("b", "ab", 0, 2);
+ TEST_SEARCH ("a", "ab", 1, -2);
+ TEST_SEARCH_2 ("a", "a", "b", 0, 2, 2);
+ TEST_SEARCH_2 ("b", "a", "b", 0, 2, 2);
+ TEST_SEARCH_2 ("a", "a", "b", 1, -2, 2);
+
+ test_match ("\n", "\n");
+ test_match ("a\n", "a\n");
+ test_match ("\nb", "\nb");
+ test_match ("a\nb", "a\nb");
+
+ TEST_SEARCH ("b", "baaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 236, -237);
+ /* Valid use of special characters. */
+ test_match ("a*", "aa");
+ test_fastmap ("a*", "a", 0, 0);
+ TEST_REGISTERS ("a*", "aa", 0, 2, -1, -1, -1, -1);
+
+ test_match ("a*b", "aab");
+ test_fastmap ("a*b", "ab", 0, 0);
+
+ test_match ("a*ab", "aab");
+ TEST_REGISTERS ("a*a", "aa", 0, 2, -1, -1, -1, -1);
+ TEST_REGISTERS ("a*a", "xaax", 1, 3, -1, -1, -1, -1);
+
+ test_match ("\\{", "{");
+ test_match ("\\^", "^");
+ test_match ("\\.", ".");
+ test_match ("\\*", "*");
+ test_match ("\\[", "[");
+ test_match ("\\$", "$");
+ test_match ("\\\\", "\\");
+
+ test_match ("ab*", "a");
+ test_match ("ab*", "abb");
+
+ /* Valid consecutive repetitions. */
+ test_match ("a**", "a");
+ /* Valid period. */
+ test_match (".", "a");
+ TEST_REGISTERS (".", "a", 0, 1, -1, -1, -1, -1);
+ test_match (".", "\004");
+ test_match (".", "\n");
+ /* Valid bracket expressions. */
+ test_match ("[ab]", "a");
+ test_match ("[ab]", "b");
+ test_fastmap ("[ab]", "ab", 0, 0);
+ TEST_REGISTERS ("[ab]", "a", 0, 1, -1, -1, -1, -1);
+ TEST_REGISTERS ("[ab]", "xax", 1, 2, -1, -1, -1, -1);
+
+ test_fastmap ("[^ab]", "ab", 1, 1);
+ test_match ("[^ab]", "c");
+ test_match ("[^a]", "\n");
+
+ test_match ("[a]*a", "aa");
+
+ test_match ("[[]", "[");
+ test_match ("[]]", "]");
+ test_match ("[.]", ".");
+ test_match ("[*]", "*");
+ test_match ("[\\]", "\\");
+ test_match ("[\\(]", "(");
+ test_match ("[\\)]", ")");
+ test_match ("[^]]", "a");
+ test_match ("[a^]", "^");
+ test_match ("[a$]", "$");
+ test_match ("[]a]", "]");
+ test_match ("[a][]]", "a]");
+ test_match ("[\n]", "\n");
+ test_match ("[^a]", "\n");
+ test_match ("[a-]", "a");
+
+ TEST_REGISTERS ("\\`[ \t\n]*", " karl (Karl Berry)", 0, 1, -1, -1, -1, -1);
+ TEST_REGISTERS ("[ \t\n]*\\'", " karl (Karl Berry)", 18, 18, -1, -1, -1, -1);
+
+ /* Collating, noncollating,
+ equivalence classes aren't
+ implemented yet. */
+
+
+ /* Character classes. */
+ test_match ("[:alpha:]", "p");
+ test_match ("[[:alpha:]]", "a");
+ test_match ("[[:alpha:]]", "z");
+ test_match ("[[:alpha:]]", "A");
+ test_match ("[[:alpha:]]", "Z");
+ test_match ("[[:upper:]]", "A");
+ test_match ("[[:upper:]]", "Z");
+ test_match ("[[:lower:]]", "a");
+ test_match ("[[:lower:]]", "z");
+
+ test_match ("[[:digit:]]", "0");
+ test_match ("[[:digit:]]", "9");
+ test_fastmap ("[[:digit:]]", "0123456789", 0, 0);
+
+ test_match ("[[:alnum:]]", "0");
+ test_match ("[[:alnum:]]", "9");
+ test_match ("[[:alnum:]]", "a");
+ test_match ("[[:alnum:]]", "z");
+ test_match ("[[:alnum:]]", "A");
+ test_match ("[[:alnum:]]", "Z");
+ test_match ("[[:xdigit:]]", "0");
+ test_match ("[[:xdigit:]]", "9");
+ test_match ("[[:xdigit:]]", "A");
+ test_match ("[[:xdigit:]]", "F");
+ test_match ("[[:xdigit:]]", "a");
+ test_match ("[[:xdigit:]]", "f");
+ test_match ("[[:space:]]", " ");
+ test_match ("[[:print:]]", " ");
+ test_match ("[[:print:]]", "~");
+ test_match ("[[:punct:]]", ",");
+ test_match ("[[:graph:]]", "!");
+ test_match ("[[:graph:]]", "~");
+ test_match ("[[:cntrl:]]", "\177");
+ test_match ("[[:digit:]a]", "a");
+ test_match ("[[:digit:]a]", "2");
+ test_match ("[a[:digit:]]", "a");
+ test_match ("[a[:digit:]]", "2");
+ test_match ("[[:]", "[");
+ test_match ("[:]", ":");
+ test_match ("[[:a]", "[");
+ test_match ("[[:alpha:a]", "[");
+ /* Valid ranges. */
+ test_match ("[a-a]", "a");
+ test_fastmap ("[a-a]", "a", 0, 0);
+ TEST_REGISTERS ("[a-a]", "xax", 1, 2, -1, -1, -1, -1);
+
+ test_match ("[a-z]", "z");
+ test_fastmap ("[a-z]", "abcdefghijklmnopqrstuvwxyz", 0, 0);
+ test_match ("[-a]", "-"); /* First */
+ test_match ("[-a]", "a");
+ test_match ("[a-]", "-"); /* Last */
+ test_match ("[a-]", "a");
+ test_match ("[--@]", "@"); /* First and starting point. */
+
+ test_match ("[%--a]", "%"); /* Ending point. */
+ test_match ("[%--a]", "-"); /* Ditto. */
+
+ test_match ("[a%--]", "%"); /* Both ending point and last. */
+ test_match ("[a%--]", "-");
+ test_match ("[%--a]", "a"); /* Ending point only. */
+ test_match ("[a-c-f]", "e"); /* Piggyback. */
+
+ test_match ("[)-+--/]", "*");
+ test_match ("[)-+--/]", ",");
+ test_match ("[)-+--/]", "/");
+ test_match ("[[:digit:]-]", "-");
+ /* Concatenation ????*/
+ test_match ("[ab][cd]", "ac");
+ test_fastmap ("[ab][cd]", "ab", 0, 0);
+ TEST_REGISTERS ("[ab][cd]", "ad", 0, 2, -1, -1, -1, -1);
+ TEST_REGISTERS ("[ab][cd]", "xadx", 1, 3, -1, -1, -1, -1);
+
+ /* Valid expression anchoring. */
+ test_match ("^a", "a");
+ test_fastmap ("^a", "a", 0, 0);
+ TEST_REGISTERS ("^a", "ax", 0, 1, -1, -1, -1, -1);
+
+ test_match ("^", "");
+ TEST_REGISTERS ("^", "", 0, 0, -1, -1, -1, -1);
+ test_match ("$", "");
+ TEST_REGISTERS ("$", "", 0, 0, -1, -1, -1, -1);
+
+ test_match ("a$", "a");
+ test_fastmap ("a$", "a", 0, 0);
+ TEST_REGISTERS ("a$", "xa", 1, 2, -1, -1, -1, -1);
+
+ test_match ("^ab$", "ab");
+ test_fastmap ("^ab$", "a", 0, 0);
+ TEST_REGISTERS ("^a$", "a", 0, 1, -1, -1, -1, -1);
+
+ test_fastmap ("^$", "", 0, 0);
+ test_match ("^$", "");
+ TEST_REGISTERS ("^$", "", 0, 0, -1, -1, -1, -1);
+
+ TEST_SEARCH (PARENS_TO_OPS ("(^a)"), "ab", 0, 2);
+ TEST_SEARCH (PARENS_TO_OPS ("(a$)"), "ba", 0, 2);
+ TEST_SEARCH (PARENS_TO_OPS ("^(^a)"), "ab", 0, 2);
+ TEST_SEARCH (PARENS_TO_OPS ("(a$)$"), "ba", 0, 2);
+
+ /* Two strings. */
+ test_match_2 ("ab", "a", "b");
+ TEST_REGISTERS_2 ("ab", "a", "b", 0, 2, -1, -1, -1, -1);
+
+ test_match_2 ("a", "", "a");
+ test_match_2 ("a", "a", "");
+ test_match_2 ("ab", "a", "b");
+ /* (start)pos. */
+ TEST_POSITIONED_MATCH ("b", "ab", 1);
+ /* mstop. */
+ TEST_TRUNCATED_MATCH ("a", "ab", 1);
+
+
+ /* Both basic and extended, continued; should not match. */
+
+ test_should_match = false;
+ /* Ordinary characters. */
+ test_match ("abc", "ab");
+
+ TEST_SEARCH ("c", "ab", 0, 2);
+ TEST_SEARCH ("c", "ab", 0, 2);
+ TEST_SEARCH ("c", "ab", 1, -2);
+ TEST_SEARCH ("c", "ab", 0, 10);
+ TEST_SEARCH ("c", "ab", 1, -10);
+ TEST_SEARCH_2 ("c", "a", "b", 0, 2, 2);
+ TEST_SEARCH_2 ("c", "a", "b", 0, 2, 2);
+ TEST_SEARCH_2 ("c", "a", "b", 0, 2, 2);
+ TEST_SEARCH_2 ("c", "a", "b", 1, -2, 2);
+ TEST_SEARCH_2 ("c", "a", "b", 1, -2, 2);
+
+ TEST_SEARCH ("c", "baaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 236, -237);
+
+ /* Invalid use of special characters. */
+ invalid_pattern (REG_EESCAPE, "\\");
+ invalid_pattern (REG_EESCAPE, "a\\");
+ invalid_pattern (REG_EESCAPE, "a*\\");
+ /* Invalid period. */
+ test_match (".", "");
+ /* Invalid bracket expressions. */
+ test_match ("[ab]", "c");
+ test_match ("[^b]", "b");
+ test_match ("[^]]", "]");
+
+ invalid_pattern (REG_EBRACK, "[");
+ invalid_pattern (REG_EBRACK, "[^");
+ invalid_pattern (REG_EBRACK, "[a");
+ invalid_pattern (REG_EBRACK, "[]");
+ invalid_pattern (REG_EBRACK, "[]a");
+ invalid_pattern (REG_EBRACK, "a[]a");
+
+
+ test_match ("[:alpha:]", "q"); /* Character classes. */
+ test_match ("[[:alpha:]]", "2");
+ test_match ("[[:upper:]]", "a");
+ test_match ("[[:lower:]]", "A");
+ test_match ("[[:digit:]]", "a");
+ test_match ("[[:alnum:]]", ":");
+ test_match ("[[:xdigit:]]", "g");
+ test_match ("[[:space:]]", "a");
+ test_match ("[[:print:]]", "\177");
+ test_match ("[[:punct:]]", "a");
+ test_match ("[[:graph:]]", " ");
+ test_match ("[[:cntrl:]]", "a");
+ invalid_pattern (REG_EBRACK, "[[:");
+ invalid_pattern (REG_EBRACK, "[[:alpha:");
+ invalid_pattern (REG_EBRACK, "[[:alpha:]");
+ invalid_pattern (REG_ECTYPE, "[[::]]");
+ invalid_pattern (REG_ECTYPE, "[[:a:]]");
+ invalid_pattern (REG_ECTYPE, "[[:alpo:]]");
+ invalid_pattern (REG_ECTYPE, "[[:a:]");
+
+ test_match ("[a-z]", "2"); /* Invalid ranges. */
+ test_match ("[^-a]", "-");
+ test_match ("[^a-]", "-");
+ test_match ("[)-+--/]", ".");
+ invalid_pattern (REG_ERANGE, "[z-a]"); /* Empty */
+ invalid_pattern (REG_ERANGE, "[a--]"); /* Empty */
+ invalid_pattern (REG_ERANGE, "[[:digit:]-9]");
+ invalid_pattern (REG_ERANGE, "[a-[:alpha:]]");
+ invalid_pattern (REG_ERANGE, "[a-");
+ invalid_pattern (REG_EBRACK, "[a-z");
+
+ test_match ("[ab][cd]", "ae"); /* Concatenation. */
+ test_match ("b*c", "b"); /* Star. */
+
+ /* Invalid anchoring. */
+ test_match ("^", "a");
+ test_match ("^a", "ba");
+ test_match ("$", "b");
+ test_match ("a$", "ab");
+ test_match ("^$", "a");
+ test_match ("^ab$", "a");
+
+ TEST_SEARCH ("^a", "b\na", 0, 3);
+ TEST_SEARCH ("b$", "b\na", 0, 3);
+
+ test_match_2 ("^a", "\n", "a");
+ test_match_2 ("a$", "a", "\n");
+
+ TEST_SEARCH (PARENS_TO_OPS ("(^a)"), "ba", 0, 2);
+ TEST_SEARCH (PARENS_TO_OPS ("(a$)"), "ab", 0, 2);
+ TEST_SEARCH (PARENS_TO_OPS ("^(^a)"), "ba", 0, 2);
+ TEST_SEARCH (PARENS_TO_OPS ("(a$)$"), "ab", 0, 2);
+
+ printf ("\nFinished generic POSIX tests.\n");
+}
+
+
+
+/*
+Local variables:
+make-backup-files: t
+version-control: t
+trim-versions-without-asking: nil
+End:
+*/
diff --git a/gnu/lib/libregex/test/psx-group.c b/gnu/lib/libregex/test/psx-group.c
new file mode 100644
index 000000000000..08ae8a28d37a
--- /dev/null
+++ b/gnu/lib/libregex/test/psx-group.c
@@ -0,0 +1,440 @@
+/* psx-group.c: test POSIX grouping, both basic and extended. */
+
+#include "test.h"
+
+
+void
+test_grouping ()
+{
+ printf ("\nStarting POSIX grouping tests.\n");
+
+ test_should_match = true;
+
+ test_fastmap (PARENS_TO_OPS ("(a)"), "a", 0, 0);
+ test_match (PARENS_TO_OPS ("(a)"), "a");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a)"), "a", 0, 1, 0, 1, -1, -1);
+ TEST_REGISTERS (PARENS_TO_OPS ("(a)"), "xax", 1, 2, 1, 2, -1, -1);
+
+ test_match (PARENS_TO_OPS ("((a))"), "a");
+ test_fastmap (PARENS_TO_OPS ("((a))"), "a", 0, 0);
+ TEST_REGISTERS (PARENS_TO_OPS ("((a))"), "a", 0, 1, 0, 1, 0, 1);
+ TEST_REGISTERS (PARENS_TO_OPS ("((a))"), "xax", 1, 2, 1, 2, 1, 2);
+
+ test_fastmap (PARENS_TO_OPS ("(a)(b)"), "a", 0, 0);
+ test_match (PARENS_TO_OPS ("(a)(b)"), "ab");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a)(b)"), "ab", 0, 2, 0, 1, 1, 2);
+
+ TEST_REGISTERS (PARENS_TO_OPS ("(a)(b)"), "xabx", 1, 3, 1, 2, 2, 3);
+
+ test_all_registers (PARENS_TO_OPS ("((a)(b))"), "ab", "", 0, 2, 0, 2, 0, 1,
+ 1, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1);
+
+
+ /* Test that we simply ignore groups past the 255th. */
+ test_match (PARENS_TO_OPS ("((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((a))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))"), "a");
+
+
+ /* Per POSIX D11.1, p. 125. */
+
+ test_fastmap (PARENS_TO_OPS ("(a)*"), "a", 0, 0);
+ test_match (PARENS_TO_OPS ("(a)*"), "");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a)*"), "", 0, 0, -1, -1, -1, -1);
+ TEST_REGISTERS (PARENS_TO_OPS ("(a)*"), "aa", 0, 2, 1, 2, -1, -1);
+
+ test_fastmap (PARENS_TO_OPS ("(a*)"), "a", 0, 0);
+ test_match (PARENS_TO_OPS ("(a*)"), "");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*)"), "", 0, 0, 0, 0, -1, -1);
+
+ test_fastmap (PARENS_TO_OPS ("(a*)"), "a", 0, 0);
+ test_match (PARENS_TO_OPS ("(a*)"), "a");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*)"), "a", 0, 1, 0, 1, -1, -1);
+
+ test_fastmap (PARENS_TO_OPS ("(a*)b"), "ab", 0, 0);
+ test_match (PARENS_TO_OPS ("(a*)b"), "b");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*)b"), "b", 0, 1, 0, 0, -1, -1);
+
+ test_match (PARENS_TO_OPS ("(a*)b"), "ab");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*)b"), "ab", 0, 2, 0, 1, -1, -1);
+
+ test_fastmap (PARENS_TO_OPS ("((a*)b)*"), "ab", 0, 0);
+ test_match (PARENS_TO_OPS ("((a*)b)*"), "");
+ TEST_REGISTERS (PARENS_TO_OPS ("((a*)b)*"), "", 0, 0, -1, -1, -1, -1);
+
+ test_match (PARENS_TO_OPS ("((a*)b)*"), "ab");
+ TEST_REGISTERS (PARENS_TO_OPS ("((a*)b)*"), "ab", 0, 2, 0, 2, 0, 1);
+
+ test_match (PARENS_TO_OPS ("((a*)b)*"), "abb");
+ TEST_REGISTERS (PARENS_TO_OPS ("((a*)b)*"), "abb", 0, 3, 2, 3, 2, 2);
+
+ test_match (PARENS_TO_OPS ("((a*)b)*"), "aabab");
+ TEST_REGISTERS (PARENS_TO_OPS ("((a*)b)*"), "aabab", 0, 5, 3, 5, 3, 4);
+
+ test_match (PARENS_TO_OPS ("((a*)b)*"), "abbab");
+ TEST_REGISTERS (PARENS_TO_OPS ("((a*)b)*"), "abbab", 0, 5, 3, 5, 3, 4);
+
+ TEST_REGISTERS (PARENS_TO_OPS ("((a*)b)*"), "xabbabx", 0, 0, -1, -1, -1, -1);
+
+ test_match (PARENS_TO_OPS ("((a*)b)*"), "abaabaaaab");
+ TEST_REGISTERS (PARENS_TO_OPS ("((a*)b)*"), "abaabaaab", 0, 9, 5, 9, 5, 8);
+
+ test_fastmap (PARENS_TO_OPS ("(ab)*"), "a", 0, 0);
+ test_match (PARENS_TO_OPS ("(ab)*"), "");
+ TEST_REGISTERS (PARENS_TO_OPS ("(ab)*"), "", 0, 0, -1, -1, -1, -1);
+
+ test_match (PARENS_TO_OPS ("(ab)*"), "abab");
+ TEST_REGISTERS (PARENS_TO_OPS ("(ab)*"), "abab", 0, 4, 2, 4, -1, -1);
+
+ /* We match the empty string here. */
+ TEST_REGISTERS (PARENS_TO_OPS ("(ab)*"), "xababx", 0, 0, -1, -1, -1, -1);
+
+ /* Per David A. Willcox. */
+ TEST_REGISTERS (PARENS_TO_OPS ("a(b*)c"), "ac", 0, 2, 1, 1, -1, -1);
+
+ test_fastmap (PARENS_TO_OPS ("(a)*b"), "ab", 0, 0);
+ test_match (PARENS_TO_OPS ("(a)*b"), "b");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a)*b"), "b", 0, 1, -1, -1, -1, -1);
+
+ test_match (PARENS_TO_OPS ("(a)*b"), "ab");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a)*b"), "ab", 0, 2, 0, 1, -1, -1);
+
+ test_match_2 (PARENS_TO_OPS ("(a)*b"), "a", "ab");
+ TEST_REGISTERS_2 (PARENS_TO_OPS ("(a)*b"), "a", "ab", 0, 3, 1, 2, -1, -1);
+
+ test_match (PARENS_TO_OPS ("(a)*b"), "aab");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a)*b"), "aab", 0, 3, 1, 2, -1, -1);
+
+ test_fastmap (PARENS_TO_OPS ("(a)*a"), "a", 0, 0);
+ test_match (PARENS_TO_OPS ("(a)*a"), "a");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a)*a"), "a", 0, 1, -1, -1, -1, -1);
+
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*)*"), "", 0, 0, 0, 0, 0, 0);
+
+ test_match (PARENS_TO_OPS ("((a*))*"), "");
+ TEST_REGISTERS (PARENS_TO_OPS ("((a*))*"), "", 0, 0, 0, 0, 0, 0);
+ test_match (PARENS_TO_OPS ("((a*))*"), "aa");
+
+ test_fastmap (PARENS_TO_OPS ("(a*)*b"), "ab", 0, 0);
+ test_match (PARENS_TO_OPS ("(a*)*b"), "b");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*)*b"), "b", 0, 1, 0, 0, -1, -1);
+
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*)*b"), "xbx", 1, 2, 1, 1, -1, -1);
+
+ test_match (PARENS_TO_OPS ("(a*)*b"), "ab"); /* Per rms. */
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*)*b"), "ab", 0, 2, 0, 1, -1, -1);
+
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*)*b"), "xabx", 1, 3, 1, 2, -1, -1);
+
+ /* Test register restores. */
+ test_match (PARENS_TO_OPS ("(a*)*b"), "aab");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*)*b"), "aab", 0, 3, 0, 2, -1, -1);
+
+ TEST_REGISTERS_2 (PARENS_TO_OPS ("(a*)*b"), "a", "ab", 0, 3, 0, 2, -1, -1);
+
+ /* We are matching the empty string, with backtracking. */
+ test_fastmap (PARENS_TO_OPS ("(a*)a"), "a", 0, 0);
+ test_match (PARENS_TO_OPS ("(a*)a"), "a");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*)a"), "a", 0, 1, 0, 0, -1, -1);
+
+ test_match (PARENS_TO_OPS ("(a*)a"), "aa");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*)a"), "aa", 0, 2, 0, 1, -1, -1);
+
+ /* We are matching the empty string, with backtracking. */
+/*fails test_match (PARENS_TO_OPS ("(a*)*a"), "a"); */
+ test_match (PARENS_TO_OPS ("(a*)*a"), "aa");
+ /* Match the empty string. */
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*)*a"), "a", 0, 1, 0, 0, -1, -1);
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*)*a"), "xax", 1, 2, 1, 1, -1, -1);
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*)*a"), "aa", 0, 2, 0, 1, -1, -1);
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*)*a"), "xaax", 1, 3, 1, 2, -1, -1);
+
+ test_fastmap (PARENS_TO_OPS ("(a)*ab"), "a", 0 , 0);
+ test_match (PARENS_TO_OPS ("(a)*ab"), "ab");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a)*ab"), "ab", 0, 2, -1, -1, -1, -1);
+
+ test_match (PARENS_TO_OPS ("(a)*ab"), "aab");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a)*ab"), "aab", 0, 3, 0, 1, -1, -1);
+
+ TEST_REGISTERS (PARENS_TO_OPS("(a)*ab"), "xaabx", 1, 4, 1, 2, -1, -1);
+
+ test_fastmap (PARENS_TO_OPS ("(a*)ab"), "a", 0 , 0);
+ test_match (PARENS_TO_OPS ("(a*)ab"), "ab");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*)ab"), "ab", 0, 2, 0, 0, -1, -1);
+
+ test_match (PARENS_TO_OPS ("(a*)ab"), "aab");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*)ab"), "aab", 0, 3, 0, 1, -1, -1);
+
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*)ab"), "xaabx", 1, 4, 1, 2, -1, -1);
+
+ test_fastmap (PARENS_TO_OPS ("(a*)*ab"), "a", 0 , 0);
+ test_match (PARENS_TO_OPS ("(a*)*ab"), "ab");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*)*ab"), "ab", 0, 2, 0, 0, -1, -1);
+
+ test_match (PARENS_TO_OPS ("(a*)*ab"), "aab");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*)*ab"), "aab", 0, 3, 0, 1, -1, -1);
+
+ TEST_REGISTERS (PARENS_TO_OPS("(a*)*ab"), "xaabx", 1, 4, 1, 2, -1, -1);
+
+ test_fastmap (PARENS_TO_OPS ("(a*)*b*c"), "abc", 0, 0);
+ test_match (PARENS_TO_OPS ("(a*)*b*c"), "c");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*)*b*c"), "c", 0, 1, 0, 0, -1, -1);
+
+ test_fastmap (PARENS_TO_OPS ("(a)*(ab)*"), "a", 0, 0);
+ test_match (PARENS_TO_OPS ("(a)*(ab)*"), "ab");
+ /* Register 1 doesn't match at all (vs. matching the empty string)
+ because of backtracking, hence -1's. */
+ TEST_REGISTERS (PARENS_TO_OPS ("(a)*(ab)*"), "ab", 0, 2, -1, -1, 0, 2);
+
+ test_match (PARENS_TO_OPS ("(a*)*(ab)*"), "ab");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*)*(ab)*"), "ab", 0, 2, 0, 0, 0, 2);
+
+ test_fastmap (PARENS_TO_OPS ("(a*b)*"), "ab", 0, 0);
+ test_match (PARENS_TO_OPS ("(a*b)*"), "");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*b)*"), "", 0, 0, -1, -1, -1, -1);
+
+ test_match (PARENS_TO_OPS ("(a*b)*"), "b");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*b)*"), "b", 0, 1, 0, 1, -1, -1);
+
+ test_match (PARENS_TO_OPS ("(a*b)*"), "baab");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*b)*"), "baab", 0, 4, 1, 4, -1, -1);
+
+ test_fastmap (PARENS_TO_OPS ("(a*b*)*"), "ab", 0, 0);
+ test_match (PARENS_TO_OPS ("(a*b*)*"), "");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*b*)*"), "", 0, 0, 0, 0, -1, -1);
+
+ test_match (PARENS_TO_OPS ("(a*b*)*"), "a");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*b*)*"), "a", 0, 1, 0, 1, -1, -1);
+
+ test_match (PARENS_TO_OPS ("(a*b*)*"), "ba");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*b*)*"), "ba", 0, 2, 1, 2, -1, -1);
+
+ test_match (PARENS_TO_OPS ("(a*b*)*"), "ab");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*b*)*"), "ab", 0, 2, 0, 2, -1, -1);
+
+ test_match (PARENS_TO_OPS ("(a*b*)*"), "aa");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*b*)*"), "aa", 0, 2, 0, 2, -1, -1);
+
+ test_match (PARENS_TO_OPS ("(a*b*)*"), "bb");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*b*)*"), "bb", 0, 2, 0, 2, -1, -1);
+
+ test_match (PARENS_TO_OPS ("(a*b*)*"), "aba");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*b*)*"), "aba", 0, 3, 2, 3, -1, -1);
+
+ test_match (PARENS_TO_OPS ("(a*b*)b"), "b");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*b*)b"), "b", 0, 1, 0, 0, -1, -1);
+
+ test_fastmap (PARENS_TO_OPS ("((a*)*(b*)*)*"), "ab", 0, 0);
+ test_match (PARENS_TO_OPS ("((a*)*(b*)*)*"), "");
+ test_all_registers (PARENS_TO_OPS ("((a*)*(b*)*)*"), "", "", 0, 0, 0, 0,
+ 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1);
+
+ test_match (PARENS_TO_OPS ("((a*)*(b*)*)*"), "aba");
+ /* Perhaps register 3 should be 3/3 here? Not sure if standard
+ specifies this. xx*/
+ test_all_registers (PARENS_TO_OPS ("((a*)*(b*)*)*"), "aba", "", 0, 3, 2, 3,
+ 2, 3, 1, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1);
+
+ test_fastmap (PARENS_TO_OPS ("((a*)(b*))*"), "ab", 0, 0);
+ test_match (PARENS_TO_OPS ("((a*)(b*))*"), "");
+
+ test_all_registers (PARENS_TO_OPS ("((a*)(b*))*"), "", "", 0, 0, 0, 0,
+ 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1);
+
+ test_match (PARENS_TO_OPS ("(c(c(a)*(b)*)*)*"), "");
+
+ test_match (PARENS_TO_OPS ("((a*)(b*))*"), "aba");
+ test_all_registers (PARENS_TO_OPS ("((a*)(b*))*"), "aba", "", 0, 3, 2, 3,
+ 2, 3, 3, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1);
+
+ test_fastmap (PARENS_TO_OPS ("((a)*(b)*)*"), "ab", 0, 0);
+ test_match (PARENS_TO_OPS ("((a)*(b)*)*"), "");
+ test_all_registers (PARENS_TO_OPS ("((a)*(b)*)*"), "", "", 0, 0, 0, 0,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1);
+
+ test_match (PARENS_TO_OPS ("((a)*(b)*)*"), "aba");
+
+ test_all_registers (PARENS_TO_OPS ("((a)*(b)*)*"), "aba", "", 0, 3, 2, 3,
+ 2, 3, 1, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1);
+
+ test_fastmap (PARENS_TO_OPS ("(c(a)*(b)*)*"), "c", 0, 0);
+ test_match (PARENS_TO_OPS ("(c(a)*(b)*)*"), "");
+ test_all_registers (PARENS_TO_OPS ("(c(a)*(b)*)*"), "", "", 0, 0, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1);
+
+ test_match (PARENS_TO_OPS ("(c(a)*(b)*)*"), "c");
+ test_all_registers (PARENS_TO_OPS ("(c(a)*(b)*)*"), "c", "", 0, 1, 0, 1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1);
+
+ test_fastmap (PARENS_TO_OPS ("c((a)*(b)*)*"), "c", 0, 0);
+ test_match (PARENS_TO_OPS ("c((a)*(b)*)*"), "c");
+ test_all_registers (PARENS_TO_OPS ("c((a)*(b)*)*"), "c", "", 0, 1, 1, 1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1);
+
+ test_fastmap (PARENS_TO_OPS ("(((a)*(b)*)*)*"), "ab", 0, 0);
+ test_match (PARENS_TO_OPS ("(((a)*(b)*)*)*"), "");
+ test_all_registers (PARENS_TO_OPS ("(((a)*(b)*)*)*"), "", "", 0, 0, 0, 0,
+ 0, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1);
+
+ test_match (PARENS_TO_OPS ("(c(c(a)*(b)*)*)*"), "");
+ test_fastmap (PARENS_TO_OPS ("(c(c(a)*(b)*)*)*"), "c", 0, 0);
+
+ test_all_registers (PARENS_TO_OPS ("(c(c(a)*(b)*)*)*"), "", "", 0, 0, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1);
+
+ test_fastmap (PARENS_TO_OPS ("((a)*b)*"), "ab", 0, 0);
+ test_match (PARENS_TO_OPS ("((a)*b)*"), "");
+
+ test_match (PARENS_TO_OPS ("((a)*b)*"), "");
+ TEST_REGISTERS (PARENS_TO_OPS ("((a)*b)*"), "", 0, 0, -1, -1, -1, -1);
+
+ test_match (PARENS_TO_OPS ("((a)*b)*"), "abb");
+ TEST_REGISTERS (PARENS_TO_OPS ("((a)*b)*"), "abb", 0, 3, 2, 3, 0, 1); /*zz*/
+
+ test_match (PARENS_TO_OPS ("((a)*b)*"), "abbab");
+ TEST_REGISTERS (PARENS_TO_OPS ("((a)*b)*"), "abbab", 0, 5, 3, 5, 3, 4);
+
+ /* We match the empty string here. */
+ TEST_REGISTERS (PARENS_TO_OPS ("((a)*b)*"), "xabbabx", 0, 0, -1, -1, -1, -1);
+
+ test_fastmap (PARENS_TO_OPS ("(a*)*"), "a", 0, 0);
+ test_match (PARENS_TO_OPS ("(a*)*"), "");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*)*"), "", 0, 0, 0, 0, -1, -1);
+
+ test_match (PARENS_TO_OPS ("(a*)*"), "aa");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*)*"), "aa", 0, 2, 0, 2, -1, -1);
+
+ test_fastmap (PARENS_TO_OPS ("((a*)*)*"), "a", 0, 0);
+ test_match (PARENS_TO_OPS ("((a*)*)*"), "");
+ TEST_REGISTERS (PARENS_TO_OPS ("((a*)*)*"), "", 0, 0, 0, 0, 0, 0);
+
+ test_match (PARENS_TO_OPS ("((a*)*)*"), "a");
+ TEST_REGISTERS (PARENS_TO_OPS ("((a*)*)*"), "a", 0, 1, 0, 1, 0, 1);
+
+ test_fastmap (PARENS_TO_OPS ("(ab*)*"), "a", 0, 0);
+ test_match (PARENS_TO_OPS ("(ab*)*"), "");
+ TEST_REGISTERS (PARENS_TO_OPS ("(ab*)*"), "", 0, 0, -1, -1, -1, -1);
+
+ test_match (PARENS_TO_OPS ("(ab*)*"), "aa");
+ TEST_REGISTERS (PARENS_TO_OPS ("(ab*)*"), "aa", 0, 2, 1, 2, -1, -1);
+
+ test_fastmap (PARENS_TO_OPS ("(ab*)*c"), "ac", 0, 0);
+ test_match (PARENS_TO_OPS ("(ab*)*c"), "c");
+ TEST_REGISTERS (PARENS_TO_OPS ("(ab*)*c"), "c", 0, 1, -1, -1, -1, -1);
+
+ test_match (PARENS_TO_OPS ("(ab*)*c"), "abbac");
+ TEST_REGISTERS (PARENS_TO_OPS ("(ab*)*c"), "abbac", 0, 5, 3, 4, -1, -1);
+
+ test_match (PARENS_TO_OPS ("(ab*)*c"), "abac");
+ TEST_REGISTERS (PARENS_TO_OPS ("(ab*)*c"), "abac", 0, 4, 2, 3, -1, -1);
+
+ test_fastmap (PARENS_TO_OPS ("(a*b)*c"), "abc", 0, 0);
+ test_match (PARENS_TO_OPS ("(a*b)*c"), "c");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*b)*c"), "c", 0, 1, -1, -1, -1, -1);
+
+ test_match (PARENS_TO_OPS ("(a*b)*c"), "bbc");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*b)*c"), "bbc", 0, 3, 1, 2, -1, -1);
+
+ test_match (PARENS_TO_OPS ("(a*b)*c"), "aababc");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*b)*c"), "aababc", 0, 6, 3, 5, -1, -1);
+
+ test_match (PARENS_TO_OPS ("(a*b)*c"), "aabaabc");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*b)*c"), "aabaabc", 0, 7, 3, 6, -1, -1);
+
+ test_fastmap (PARENS_TO_OPS ("((a*)b*)"), "ab", 0, 0);
+ test_match (PARENS_TO_OPS ("((a*)b*)"), "");
+ TEST_REGISTERS (PARENS_TO_OPS ("((a*)b*)"), "", 0, 0, 0, 0, 0, 0);
+
+ test_match (PARENS_TO_OPS ("((a*)b*)"), "a");
+ TEST_REGISTERS (PARENS_TO_OPS ("((a*)b*)"), "a", 0, 1, 0, 1, 0, 1);
+
+ test_match (PARENS_TO_OPS ("((a*)b*)"), "b");
+ TEST_REGISTERS (PARENS_TO_OPS ("((a*)b*)"), "b", 0, 1, 0, 1, 0, 0);
+
+ test_fastmap (PARENS_TO_OPS ("((a)*b*)"), "ab", 0, 0);
+ test_match (PARENS_TO_OPS ("((a)*b*)"), "");
+ TEST_REGISTERS (PARENS_TO_OPS ("((a)*b*)"), "", 0, 0, 0, 0, -1, -1);
+
+ test_match (PARENS_TO_OPS ("((a)*b*)"), "a");
+ TEST_REGISTERS (PARENS_TO_OPS ("((a)*b*)"), "a", 0, 1, 0, 1, 0, 1);
+
+ test_match (PARENS_TO_OPS ("((a)*b*)"), "b");
+ TEST_REGISTERS (PARENS_TO_OPS ("((a)*b*)"), "b", 0, 1, 0, 1, -1, -1);
+
+ test_match (PARENS_TO_OPS ("((a)*b*)"), "ab");
+ TEST_REGISTERS (PARENS_TO_OPS ("((a)*b*)"), "ab", 0, 2, 0, 2, 0, 1);
+
+ test_fastmap (PARENS_TO_OPS ("((a*)b*)c"), "abc", 0, 0);
+ test_match (PARENS_TO_OPS ("((a*)b*)c"), "c");
+ TEST_REGISTERS (PARENS_TO_OPS ("((a*)b*)c"), "c", 0, 1, 0, 0, 0, 0);
+
+ test_fastmap (PARENS_TO_OPS ("((a)*b*)c"), "abc", 0, 0);
+ test_match (PARENS_TO_OPS ("((a)*b*)c"), "c");
+ TEST_REGISTERS (PARENS_TO_OPS ("((a)*b*)c"), "c", 0, 1, 0, 0, -1, -1);
+
+ test_fastmap (PARENS_TO_OPS ("(a*b*)*"), "ab", 0, 0);
+ test_match (PARENS_TO_OPS ("(a*b*)*"), "");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*b*)*"), "", 0, 0, 0, 0, -1, -1);
+
+ test_fastmap (PARENS_TO_OPS ("(((a*))((b*)))*"), "ab", 0, 0);
+ test_match (PARENS_TO_OPS ("(((a*))((b*)))*"), "");
+ test_all_registers (PARENS_TO_OPS ("(((a*))((b*)))*"), "", "", 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1);
+
+ test_fastmap (PARENS_TO_OPS ("(c*((a*))d*((b*))e*)*"), "abcde", 0, 0);
+ test_match (PARENS_TO_OPS ("(c*((a*))d*((b*))e*)*"), "");
+ test_all_registers (PARENS_TO_OPS ("(c*((a*))d*((b*))e*)*"), "", "", 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1);
+
+ test_fastmap (PARENS_TO_OPS ("((a)*b)*c"), "abc", 0, 0);
+ test_match (PARENS_TO_OPS ("((a)*b)*c"), "c");
+ TEST_REGISTERS (PARENS_TO_OPS ("((a)*b)*c"), "c", 0, 1, -1, -1, -1, -1);
+
+ test_match (PARENS_TO_OPS ("(ab)*"), "");
+ test_match (PARENS_TO_OPS ("((ab)*)"), "");
+ test_match (PARENS_TO_OPS ("(((ab)*))"), "");
+ test_match (PARENS_TO_OPS ("((((ab)*)))"), "");
+ test_match (PARENS_TO_OPS ("(((((ab)*))))"), "");
+ test_match (PARENS_TO_OPS ("((((((ab)*)))))"), "");
+ test_match (PARENS_TO_OPS ("(((((((ab)*))))))"), "");
+ test_match (PARENS_TO_OPS ("((((((((ab)*)))))))"), "");
+ test_match (PARENS_TO_OPS ("(((((((((ab)*))))))))"), "");
+
+
+ test_fastmap (PARENS_TO_OPS ("(((((((((ab)*))))))))"), "a", 0, 0);
+ test_match (PARENS_TO_OPS ("((((((((((ab)*)))))))))"), "");
+ test_match (PARENS_TO_OPS ("(((((((((ab)*))))))))"), "");
+ test_all_registers (PARENS_TO_OPS ("(((((((((ab)*))))))))"), "", NULL,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1);
+
+ test_match (PARENS_TO_OPS ("(((((((((ab)*))))))))"), "abab");
+ test_all_registers (PARENS_TO_OPS ("(((((((((ab)*))))))))"), "abab", NULL,
+ 0, 4, 0, 4, 0, 4, 0, 4, 0, 4, 0, 4, 0, 4, 0, 4, 0, 4, 2, 4);
+
+
+ test_should_match = false;
+
+ invalid_pattern (REG_EPAREN, PARENS_TO_OPS ("(a"));
+
+ test_match (PARENS_TO_OPS ("(a)"), "");
+ test_match (PARENS_TO_OPS ("((a))"), "b");
+ test_match (PARENS_TO_OPS ("(a)(b)"), "ac");
+ test_match (PARENS_TO_OPS ("(ab)*"), "acab");
+ test_match (PARENS_TO_OPS ("(a*)*b"), "c");
+ test_match (PARENS_TO_OPS ("(a*b)*"), "baa");
+ test_match (PARENS_TO_OPS ("(a*b)*"), "baabc");
+ test_match (PARENS_TO_OPS ("(a*b*)*"), "c");
+ test_match (PARENS_TO_OPS ("((a*)*(b*)*)*"), "c");
+ test_match (PARENS_TO_OPS ("(a*)*"), "ab");
+ test_match (PARENS_TO_OPS ("((a*)*)*"), "ab");
+ test_match (PARENS_TO_OPS ("((a*)*)*"), "b");
+ test_match (PARENS_TO_OPS ("(ab*)*"), "abc");
+ test_match (PARENS_TO_OPS ("(ab*)*c"), "abbad");
+ test_match (PARENS_TO_OPS ("(a*c)*b"), "aacaacd");
+ test_match (PARENS_TO_OPS ("(a*)"), "b");
+ test_match (PARENS_TO_OPS ("((a*)b*)"), "c");
+
+ /* Expression anchoring. */
+ TEST_SEARCH (PARENS_TO_OPS ("(^b)"), "ab", 0, 2);
+ TEST_SEARCH (PARENS_TO_OPS ("(a$)"), "ab", 0, 2);
+
+ printf ("\nFinished POSIX grouping tests.\n");
+}
diff --git a/gnu/lib/libregex/test/psx-interf.c b/gnu/lib/libregex/test/psx-interf.c
new file mode 100644
index 000000000000..8312d5e7d74a
--- /dev/null
+++ b/gnu/lib/libregex/test/psx-interf.c
@@ -0,0 +1,624 @@
+/* psx-interf.c: test POSIX interface. */
+
+#include <string.h>
+#include <assert.h>
+
+#include "test.h"
+
+#define ERROR_CODE_LENGTH 20
+#define TEST_ERRBUF_SIZE 15
+
+
+void test_compile ();
+
+
+/* ANSWER should be at least ERROR_CODE_LENGTH long. */
+
+static char *
+get_error_string (error_code, answer)
+ int error_code;
+ char answer[];
+{
+ switch (error_code)
+ {
+ case 0: strcpy (answer, "No error"); break;
+ case REG_NOMATCH: strcpy (answer, "REG_NOMATCH"); break;
+ case REG_BADPAT: strcpy (answer, "REG_BADPAT"); break;
+ case REG_EPAREN: strcpy (answer, "REG_EPAREN"); break;
+ case REG_ESPACE: strcpy (answer, "REG_ESPACE"); break;
+ case REG_ECOLLATE: strcpy (answer, "REG_ECOLLATE"); break;
+ case REG_ECTYPE: strcpy (answer, "REG_ECTYPE"); break;
+ case REG_EESCAPE: strcpy (answer, "REG_EESCAPE"); break;
+ case REG_ESUBREG: strcpy (answer, "REG_ESUBREG"); break;
+ case REG_EBRACK: strcpy (answer, "REG_EBRACK"); break;
+ case REG_EBRACE: strcpy (answer, "REG_EBRACE"); break;
+ case REG_BADBR: strcpy (answer, "REG_BADBR"); break;
+ case REG_ERANGE: strcpy (answer, "REG_ERANGE"); break;
+ case REG_BADRPT: strcpy (answer, "REG_BADRPT"); break;
+ case REG_EEND: strcpy (answer, "REG_EEND"); break;
+ default: strcpy (answer, "Bad error code");
+ }
+ return answer;
+}
+
+
+/* I don't think we actually need to initialize all these things.
+ --karl */
+
+void
+init_pattern_buffer (pattern_buffer_ptr)
+ regex_t *pattern_buffer_ptr;
+{
+ pattern_buffer_ptr->buffer = NULL;
+ pattern_buffer_ptr->allocated = 0;
+ pattern_buffer_ptr->used = 0;
+ pattern_buffer_ptr->fastmap = NULL;
+ pattern_buffer_ptr->fastmap_accurate = 0;
+ pattern_buffer_ptr->translate = NULL;
+ pattern_buffer_ptr->can_be_null = 0;
+ pattern_buffer_ptr->re_nsub = 0;
+ pattern_buffer_ptr->no_sub = 0;
+ pattern_buffer_ptr->not_bol = 0;
+ pattern_buffer_ptr->not_eol = 0;
+}
+
+
+void
+test_compile (valid_pattern, error_code_expected, pattern,
+ pattern_buffer_ptr, cflags)
+ unsigned valid_pattern;
+ int error_code_expected;
+ const char *pattern;
+ regex_t *pattern_buffer_ptr;
+ int cflags;
+{
+ int error_code_returned;
+ boolean error = false;
+ char errbuf[TEST_ERRBUF_SIZE];
+
+ init_pattern_buffer (pattern_buffer_ptr);
+ error_code_returned = regcomp (pattern_buffer_ptr, pattern, cflags);
+
+ if (valid_pattern && error_code_returned)
+ {
+ printf ("\nShould have been a valid pattern but wasn't.\n");
+ regerror (error_code_returned, pattern_buffer_ptr, errbuf,
+ TEST_ERRBUF_SIZE);
+ printf ("%s", errbuf);
+ error = true;
+ }
+
+ if (!valid_pattern && !error_code_returned)
+ {
+ printf ("\n\nInvalid pattern compiled as valid:\n");
+ error = true;
+ }
+
+ if (error_code_returned != error_code_expected)
+ {
+ char expected_error_string[ERROR_CODE_LENGTH];
+ char returned_error_string[ERROR_CODE_LENGTH];
+
+ get_error_string (error_code_expected, expected_error_string),
+ get_error_string (error_code_returned, returned_error_string);
+
+ printf (" Expected error code %s but got `%s'.\n",
+ expected_error_string, returned_error_string);
+
+ error = true;
+ }
+
+ if (error)
+ print_pattern_info (pattern, pattern_buffer_ptr);
+}
+
+
+static void
+test_nsub (sub_count, pattern, cflags)
+ unsigned sub_count;
+ char *pattern;
+ int cflags;
+
+{
+ regex_t pattern_buffer;
+
+ test_compile (1, 0, pattern, &pattern_buffer, cflags);
+
+ if (pattern_buffer.re_nsub != sub_count)
+ {
+ printf ("\nShould have counted %d subexpressions but counted %d \
+instead.\n", sub_count, pattern_buffer.re_nsub);
+ }
+
+ regfree (&pattern_buffer);
+}
+
+
+static void
+test_regcomp ()
+{
+ regex_t pattern_buffer;
+ int cflags = 0;
+
+
+ printf ("\nStarting regcomp tests.\n");
+
+ cflags = 0;
+ test_compile (0, REG_ESUBREG, "\\(a\\)\\2", &pattern_buffer, cflags);
+ test_compile (0, REG_EBRACE, "a\\{", &pattern_buffer, cflags);
+ test_compile (0, REG_BADBR, "a\\{-1\\}", &pattern_buffer, cflags);
+ test_compile (0, REG_EBRACE, "a\\{", &pattern_buffer, cflags);
+ test_compile (0, REG_EBRACE, "a\\{1", &pattern_buffer, cflags);
+
+ cflags = REG_EXTENDED;
+ test_compile (0, REG_ECTYPE, "[[:alpo:]]", &pattern_buffer, cflags);
+ test_compile (0, REG_EESCAPE, "\\", &pattern_buffer, cflags);
+ test_compile (0, REG_EBRACK, "[a", &pattern_buffer, cflags);
+ test_compile (0, REG_EPAREN, "(", &pattern_buffer, cflags);
+ test_compile (0, REG_ERANGE, "[z-a]", &pattern_buffer, cflags);
+
+ test_nsub (1, "(a)", cflags);
+ test_nsub (2, "((a))", cflags);
+ test_nsub (2, "(a)(b)", cflags);
+
+ cflags = REG_EXTENDED | REG_NOSUB;
+ test_nsub (1, "(a)", cflags);
+
+ regfree (&pattern_buffer);
+
+ printf ("\nFinished regcomp tests.\n");
+}
+
+
+static void
+fill_pmatch (pmatch, start0, end0, start1, end1, start2, end2)
+ regmatch_t pmatch[];
+ regoff_t start0, end0, start1, end1, start2, end2;
+{
+ pmatch[0].rm_so = start0;
+ pmatch[0].rm_eo = end0;
+ pmatch[1].rm_so = start1;
+ pmatch[1].rm_eo = end1;
+ pmatch[2].rm_so = start2;
+ pmatch[2].rm_eo = end2;
+}
+
+
+static void
+test_pmatch (pattern, string, nmatch, pmatch, correct_pmatch, cflags)
+ char *pattern;
+ char *string;
+ unsigned nmatch;
+ regmatch_t pmatch[];
+ regmatch_t correct_pmatch[];
+ int cflags;
+{
+ regex_t pattern_buffer;
+ unsigned this_match;
+ int error_code_returned;
+ boolean found_nonmatch = false;
+
+ test_compile (1, 0, pattern, &pattern_buffer, cflags);
+ error_code_returned = regexec (&pattern_buffer, string, nmatch, pmatch, 0);
+
+ if (error_code_returned == REG_NOMATCH)
+ printf ("Matching failed in test_pmatch.\n");
+ else
+ {
+ for (this_match = 0; this_match < nmatch; this_match++)
+ {
+ if (pmatch[this_match].rm_so != correct_pmatch[this_match].rm_so)
+ {
+ if (found_nonmatch == false)
+ printf ("\n");
+
+ printf ("Pmatch start %d wrong: was %d when should have \
+been %d.\n", this_match, pmatch[this_match].rm_so,
+ correct_pmatch[this_match].rm_so);
+ found_nonmatch = true;
+ }
+ if (pmatch[this_match].rm_eo != correct_pmatch[this_match].rm_eo)
+ {
+ if (found_nonmatch == false)
+ printf ("\n");
+
+ printf ("Pmatch end %d wrong: was %d when should have been \
+%d.\n", this_match, pmatch[this_match].rm_eo,
+ correct_pmatch[this_match].rm_eo);
+ found_nonmatch = true;
+ }
+ }
+
+ if (found_nonmatch)
+ {
+ printf (" The number of pmatches requested was: %d.\n", nmatch);
+ printf (" The string to match was: `%s'.\n", string);
+ print_pattern_info (pattern, &pattern_buffer);
+ }
+ } /* error_code_returned == REG_NOMATCH */
+
+ regfree (&pattern_buffer);
+}
+
+
+static void
+test_eflags (must_match_bol, must_match_eol, pattern, string, cflags, eflags)
+ boolean must_match_bol;
+ boolean must_match_eol;
+ char *pattern;
+ char *string;
+ int cflags;
+ int eflags;
+{
+ regex_t pattern_buffer;
+ int error_code_returned;
+ boolean was_error = false;
+
+ test_compile (1, 0, pattern, &pattern_buffer, cflags);
+ error_code_returned = regexec (&pattern_buffer, string, 0, 0, eflags);
+
+ if (error_code_returned == REG_NOMATCH)
+ {
+ /* If wasn't true that both 1) the anchored part of the pattern
+ had to match this string and 2) this string was a proper
+ substring... */
+
+ if (!( (must_match_bol && (eflags & REG_NOTBOL))
+ || (must_match_eol && (eflags & REG_NOTEOL)) ))
+ {
+ printf ("\nEflags test failed: didn't match when should have.\n");
+ was_error = true;
+ }
+ }
+ else /* We got a match. */
+ {
+ /* If wasn't true that either 1) the anchored part of the pattern
+ didn't have to match this string or 2) this string wasn't a
+ proper substring... */
+
+ if ((must_match_bol == (eflags & REG_NOTBOL))
+ || (must_match_eol == (eflags & REG_NOTEOL)))
+ {
+ printf ("\nEflags test failed: matched when shouldn't have.\n");
+ was_error = true;
+ }
+ }
+
+ if (was_error)
+ {
+ printf (" The string to match was: `%s'.\n", string);
+ print_pattern_info (pattern, &pattern_buffer);
+
+ if (eflags & REG_NOTBOL)
+ printf (" The eflag REG_BOL was set.\n");
+ if (eflags & REG_NOTEOL)
+ printf (" The eflag REG_EOL was set.\n");
+ }
+
+ regfree (&pattern_buffer);
+}
+
+
+static void
+test_ignore_case (should_match, pattern, string, cflags)
+ boolean should_match;
+ char *pattern;
+ char *string;
+ int cflags;
+{
+ regex_t pattern_buffer;
+ int error_code_returned;
+
+ test_compile (1, 0, pattern, &pattern_buffer, cflags);
+ error_code_returned = regexec (&pattern_buffer, string, 0, 0, 0);
+
+ if (should_match && error_code_returned == REG_NOMATCH)
+ {
+ printf ("\nIgnore-case test failed:\n");
+ printf (" The string to match was: `%s'.\n", string);
+ print_pattern_info (pattern, &pattern_buffer);
+
+ if (cflags & REG_ICASE)
+ printf (" The cflag REG_ICASE was set.\n");
+ }
+
+ regfree (&pattern_buffer);
+}
+
+
+static void
+test_newline (should_match, pattern, string, cflags)
+ boolean should_match;
+ char *pattern;
+ char *string;
+ int cflags;
+{
+ regex_t pattern_buffer;
+ int error_code_returned;
+
+ test_compile (1, 0, pattern, &pattern_buffer, cflags);
+ error_code_returned = regexec (&pattern_buffer, string, 0, 0, 0);
+
+ if (should_match && error_code_returned == REG_NOMATCH)
+ {
+ printf ("\nNewline test failed:\n");
+ printf (" The string to match was: `%s'.\n", string);
+ print_pattern_info (pattern, &pattern_buffer);
+
+ if (cflags & REG_NEWLINE)
+ printf (" The cflag REG_NEWLINE was set.\n");
+ else
+ printf (" The cflag REG_NEWLINE wasn't set.\n");
+ }
+
+ regfree (&pattern_buffer);
+}
+
+
+static void
+test_posix_match (should_match, pattern, string, cflags)
+ boolean should_match;
+ char *pattern;
+ char *string;
+ int cflags;
+{
+ regex_t pattern_buffer;
+ int error_code_returned;
+ boolean was_error = false;
+
+ test_compile (1, 0, pattern, &pattern_buffer, cflags);
+ error_code_returned = regexec (&pattern_buffer, string, 0, 0, 0);
+
+ if (should_match && error_code_returned == REG_NOMATCH)
+ {
+ printf ("\nShould have matched but didn't:\n");
+ was_error = true;
+ }
+ else if (!should_match && error_code_returned != REG_NOMATCH)
+ {
+ printf ("\nShould not have matched but did:\n");
+ was_error = true;
+ }
+
+ if (was_error)
+ {
+ printf (" The string to match was: `%s'.\n", string);
+ print_pattern_info (pattern, &pattern_buffer);
+ }
+
+ regfree (&pattern_buffer);
+}
+
+
+static void
+test_regexec ()
+{
+ regmatch_t pmatch[3];
+ regmatch_t correct_pmatch[3];
+ int cflags = 0;
+ int eflags = 0;
+
+ printf ("\nStarting regexec tests.\n");
+
+ cflags = REG_NOSUB; /* shouldn't look at any of pmatch. */
+ test_pmatch ("a", "a", 0, pmatch, correct_pmatch, cflags);
+
+ /* Ask for less `pmatch'es than there are pattern subexpressions.
+ (Shouldn't look at pmatch[2]. */
+ cflags = REG_EXTENDED;
+ fill_pmatch (correct_pmatch, 0, 1, 0, 1, 100, 101);
+ test_pmatch ("((a))", "a", 2, pmatch, correct_pmatch, cflags);
+
+ /* Ask for same number of `pmatch'es as there are pattern subexpressions. */
+ cflags = REG_EXTENDED;
+ fill_pmatch(correct_pmatch, 0, 1, 0, 1, -1, -1);
+ test_pmatch ("(a)", "a", 2, pmatch, correct_pmatch, cflags);
+
+ /* Ask for more `pmatch'es than there are pattern subexpressions. */
+ cflags = REG_EXTENDED;
+ fill_pmatch (correct_pmatch, 0, 1, -1, -1, -1, -1);
+ test_pmatch ("a", "a", 2, pmatch, correct_pmatch, cflags);
+
+ eflags = REG_NOTBOL;
+ test_eflags (true, false, "^a", "a", cflags, eflags);
+ test_eflags (true, false, "(^a)", "a", cflags, eflags);
+ test_eflags (true, false, "a|^b", "b", cflags, eflags);
+ test_eflags (true, false, "^b|a", "b", cflags, eflags);
+
+ eflags = REG_NOTEOL;
+ test_eflags (false, true, "a$", "a", cflags, eflags);
+ test_eflags (false, true, "(a$)", "a", cflags, eflags);
+ test_eflags (false, true, "a|b$", "b", cflags, eflags);
+ test_eflags (false, true, "b$|a", "b", cflags, eflags);
+
+ eflags = REG_NOTBOL | REG_NOTEOL;
+ test_eflags (true, true, "^a$", "a", cflags, eflags);
+ test_eflags (true, true, "(^a$)", "a", cflags, eflags);
+ test_eflags (true, true, "a|(^b$)", "b", cflags, eflags);
+ test_eflags (true, true, "(^b$)|a", "b", cflags, eflags);
+
+ cflags = REG_ICASE;
+ test_ignore_case (true, "a", "a", cflags);
+ test_ignore_case (true, "A", "A", cflags);
+ test_ignore_case (true, "A", "a", cflags);
+ test_ignore_case (true, "a", "A", cflags);
+
+ test_ignore_case (true, "@", "@", cflags);
+ test_ignore_case (true, "\\[", "[", cflags);
+ test_ignore_case (true, "`", "`", cflags);
+ test_ignore_case (true, "{", "{", cflags);
+
+ test_ignore_case (true, "[!-`]", "A", cflags);
+ test_ignore_case (true, "[!-`]", "a", cflags);
+
+ cflags = 0;
+ test_ignore_case (false, "a", "a", cflags);
+ test_ignore_case (false, "A", "A", cflags);
+ test_ignore_case (false, "A", "a", cflags);
+ test_ignore_case (false, "a", "A", cflags);
+
+ test_ignore_case (true, "@", "@", cflags);
+ test_ignore_case (true, "\\[", "[", cflags);
+ test_ignore_case (true, "`", "`", cflags);
+ test_ignore_case (true, "{", "{", cflags);
+
+ test_ignore_case (true, "[!-`]", "A", cflags);
+ test_ignore_case (false, "[!-`]", "a", cflags);
+
+
+ /* Test newline stuff. */
+ cflags = REG_EXTENDED | REG_NEWLINE;
+ test_newline (true, "\n", "\n", cflags);
+ test_newline (true, "a\n", "a\n", cflags);
+ test_newline (true, "\nb", "\nb", cflags);
+ test_newline (true, "a\nb", "a\nb", cflags);
+
+ test_newline (false, ".", "\n", cflags);
+ test_newline (false, "[^a]", "\n", cflags);
+
+ test_newline (true, "\n^a", "\na", cflags);
+ test_newline (true, "\n(^a|b)", "\na", cflags);
+ test_newline (true, "a$\n", "a\n", cflags);
+ test_newline (true, "(a$|b)\n", "a\n", cflags);
+ test_newline (true, "(a$|b|c)\n", "a\n", cflags);
+ test_newline (true, "((a$|b|c)$)\n", "a\n", cflags);
+ test_newline (true, "((a$|b|c)$)\n", "b\n", cflags);
+ test_newline (true, "(a$|b)\n|a\n", "a\n", cflags);
+
+ test_newline (true, "^a", "\na", cflags);
+ test_newline (true, "a$", "a\n", cflags);
+
+ /* Now test normal behavior. */
+ cflags = REG_EXTENDED;
+ test_newline (true, "\n", "\n", cflags);
+ test_newline (true, "a\n", "a\n", cflags);
+ test_newline (true, "\nb", "\nb", cflags);
+ test_newline (true, "a\nb", "a\nb", cflags);
+
+ test_newline (true, ".", "\n", cflags);
+ test_newline (true, "[^a]", "\n", cflags);
+
+ test_newline (false, "\n^a", "\na", cflags);
+ test_newline (false, "a$\n", "a\n", cflags);
+
+ test_newline (false, "^a", "\na", cflags);
+ test_newline (false, "a$", "a\n", cflags);
+
+
+ /* Test that matches whole string only. */
+ cflags = 0;
+ test_posix_match (true, "a", "a", cflags);
+
+ /* Tests that match substrings. */
+ test_posix_match (true, "a", "ab", cflags);
+ test_posix_match (true, "b", "ab", cflags);
+
+ /* Test that doesn't match. */
+ test_posix_match (false, "a", "b", cflags);
+
+ printf ("\nFinished regexec tests.\n");
+}
+
+
+static void
+test_error_code_message (error_code, expected_error_message)
+ int error_code;
+ char *expected_error_message;
+{
+ char returned_error_message[TEST_ERRBUF_SIZE];
+ char error_code_string[ERROR_CODE_LENGTH];
+ size_t expected_error_message_length = strlen (expected_error_message) + 1;
+ size_t returned_error_message_length = regerror (error_code, 0,
+ returned_error_message,
+ TEST_ERRBUF_SIZE);
+
+ if (returned_error_message_length != expected_error_message_length)
+ {
+ printf ("\n\n Testing returned error codes, with expected error \
+message `%s':\n", expected_error_message);
+
+ printf ("\n\n and returned error message `%s':\n",
+ returned_error_message);
+ printf (" should have returned a length of %d but returned %d.\n",
+ expected_error_message_length, returned_error_message_length);
+ }
+
+ if (strncmp (expected_error_message, returned_error_message,
+ TEST_ERRBUF_SIZE - 1) != 0)
+ {
+
+ get_error_string (error_code, error_code_string),
+ printf ("\n\n With error code %s (%d), expected error message:\n",
+ error_code_string, error_code);
+
+ printf (" `%s'\n", expected_error_message);
+ printf (" but got:\n");
+ printf (" `%s'\n", returned_error_message);
+ }
+}
+
+
+static void
+test_error_code_allocation (error_code, expected_error_message)
+ int error_code;
+ char *expected_error_message;
+{
+ char *returned_error_message = NULL;
+ char error_code_string[ERROR_CODE_LENGTH];
+ size_t returned_error_message_length = regerror (error_code, 0,
+ returned_error_message,
+ (size_t)0);
+
+ returned_error_message = xmalloc (returned_error_message_length + 1);
+
+ regerror (error_code, 0, returned_error_message,
+ returned_error_message_length);
+
+ if (strcmp (expected_error_message, returned_error_message) != 0)
+ {
+ get_error_string (error_code, error_code_string),
+
+ printf ("\n\n Testing error code allocation,\n");
+ printf ("with error code %s (%d), expected error message:\n",
+ error_code_string, error_code);
+ printf (" `%s'\n", expected_error_message);
+ printf (" but got:\n");
+ printf (" `%s'\n", returned_error_message);
+ }
+}
+
+
+static void
+test_regerror ()
+{
+ test_error_code_message (REG_NOMATCH, "No match");
+ test_error_code_message (REG_BADPAT, "Invalid regular expression");
+ test_error_code_message (REG_ECOLLATE, "Invalid collation character");
+ test_error_code_message (REG_ECTYPE, "Invalid character class name");
+ test_error_code_message (REG_EESCAPE, "Trailing backslash");
+ test_error_code_message (REG_ESUBREG, "Invalid back reference");
+ test_error_code_message (REG_EBRACK, "Unmatched [ or [^");
+ test_error_code_message (REG_EPAREN, "Unmatched ( or \\(");
+ test_error_code_message (REG_EBRACE, "Unmatched \\{");
+ test_error_code_message (REG_BADBR, "Invalid content of \\{\\}");
+ test_error_code_message (REG_ERANGE, "Invalid range end");
+ test_error_code_message (REG_ESPACE, "Memory exhausted");
+ test_error_code_message (REG_BADRPT, "Invalid preceding regular expression");
+ test_error_code_message (REG_EEND, "Premature end of regular expression");
+ test_error_code_message (REG_ESIZE, "Regular expression too big");
+ test_error_code_allocation (REG_ERPAREN, "Unmatched ) or \\)");
+}
+
+
+void
+test_posix_interface ()
+{
+ printf ("\nStarting POSIX interface tests.\n");
+ t = posix_interface_test;
+
+ test_regcomp ();
+ test_regexec ();
+ test_regerror ();
+
+ printf ("\nFinished POSIX interface tests.\n");
+}
diff --git a/gnu/lib/libregex/test/psx-interv.c b/gnu/lib/libregex/test/psx-interv.c
new file mode 100644
index 000000000000..6725c38d00b8
--- /dev/null
+++ b/gnu/lib/libregex/test/psx-interv.c
@@ -0,0 +1,140 @@
+/* psx-interv.c: test POSIX intervals, both basic and extended. */
+
+#include "test.h"
+
+void
+test_intervals ()
+{
+ printf ("\nStarting POSIX interval tests.\n");
+
+ test_should_match = true;
+ /* Valid intervals. */
+ test_match (BRACES_TO_OPS (PARENS_TO_OPS ("(a{1,2}b)*")), "abaab");
+ test_fastmap (BRACES_TO_OPS (PARENS_TO_OPS ("(a{1,2}b)*")), "a", 0, 0);
+ TEST_REGISTERS (BRACES_TO_OPS (PARENS_TO_OPS ("(a{1,2}b)*")),
+ "abaab", 0, 5, 2, 5, -1, -1);
+
+ test_match (BRACES_TO_OPS ("a{0}"), "");
+ test_fastmap (BRACES_TO_OPS ("a{0}"), "", 0, 0);
+ TEST_REGISTERS (BRACES_TO_OPS ("a{0}"), "", 0, 0, -1, -1, -1, -1);
+ TEST_REGISTERS (BRACES_TO_OPS ("a{0}"), "x", 0, 0, -1, -1, -1, -1);
+
+ test_match (BRACES_TO_OPS ("a{0,}"), "");
+ test_match (BRACES_TO_OPS ("a{0,}"), "a");
+ test_fastmap (BRACES_TO_OPS ("a{0,}"), "a", 0, 0);
+ TEST_REGISTERS (BRACES_TO_OPS ("a{0,}"), "a", 0, 1, -1, -1, -1, -1);
+ TEST_REGISTERS (BRACES_TO_OPS ("a{0,}"), "xax", 0, 0, -1, -1, -1, -1);
+
+ test_match (BRACES_TO_OPS ("a{1}"), "a");
+ test_match (BRACES_TO_OPS ("a{1,}"), "a");
+ test_match (BRACES_TO_OPS ("a{1,}"), "aa");
+ test_match (BRACES_TO_OPS ("a{0,0}"), "");
+ test_match (BRACES_TO_OPS ("a{0,1}"), "");
+ test_match (BRACES_TO_OPS ("a{0,1}"), "a");
+ test_match (BRACES_TO_OPS ("a{1,3}"), "a");
+ test_match (BRACES_TO_OPS ("a{1,3}"), "aa");
+ test_match (BRACES_TO_OPS ("a{1,3}"), "aaa");
+ TEST_REGISTERS (BRACES_TO_OPS ("a{1,3}"), "aaa", 0, 3, -1, -1, -1, -1);
+ TEST_REGISTERS (BRACES_TO_OPS ("a{1,3}"), "xaaax", 1, 4, -1, -1, -1, -1);
+
+ test_match (BRACES_TO_OPS ("a{0,3}b"), "b");
+ test_match (BRACES_TO_OPS ("a{0,3}b"), "aaab");
+ test_fastmap (BRACES_TO_OPS ("a{0,3}b"), "ab", 0, 0);
+ TEST_REGISTERS (BRACES_TO_OPS ("a{0,3}b"), "b", 0, 1, -1, -1, -1, -1);
+ TEST_REGISTERS (BRACES_TO_OPS ("a{0,3}b"), "xbx", 1, 2, -1, -1, -1, -1);
+
+ test_match (BRACES_TO_OPS ("a{1,3}b"), "ab");
+ test_match (BRACES_TO_OPS ("a{1,3}b"), "aaab");
+ test_match (BRACES_TO_OPS ("ab{1,3}c"), "abbbc");
+
+ test_match (BRACES_TO_OPS (PARENS_TO_OPS ("(a){0,3}b")), "b");
+ test_fastmap (BRACES_TO_OPS (PARENS_TO_OPS ("(a){0,3}b")), "ab", 0, 0);
+ TEST_REGISTERS (BRACES_TO_OPS (PARENS_TO_OPS ("(a){0,3}b")), "b", 0, 1, -1, -1, -1, -1);
+ TEST_REGISTERS (BRACES_TO_OPS (PARENS_TO_OPS ("(a){0,3}b")), "ab", 0, 2, 0, 1, -1, -1);
+ TEST_REGISTERS (BRACES_TO_OPS (PARENS_TO_OPS ("(a){0,3}b")), "xabx", 1, 3, 1, 2, -1, -1);
+
+ test_match (BRACES_TO_OPS (PARENS_TO_OPS ("(a){1,3}b")), "ab");
+ test_match (BRACES_TO_OPS (PARENS_TO_OPS ("(a){1,3}b")), "aaab");
+ TEST_REGISTERS (BRACES_TO_OPS (PARENS_TO_OPS ("(a){1,3}b")), "aaab", 0, 4, 2, 3, -1, -1);
+ TEST_REGISTERS (BRACES_TO_OPS (PARENS_TO_OPS ("(a){1,3}b")), "xaaabx", 1, 5, 3, 4, -1, -1);
+
+ test_match (BRACES_TO_OPS (PARENS_TO_OPS ("(a*){0,3}b")), "aaaab");
+ test_fastmap (BRACES_TO_OPS (PARENS_TO_OPS ("(a*){0,3}b")), "ab", 0, 0);
+ TEST_REGISTERS (BRACES_TO_OPS (PARENS_TO_OPS ("(a*){0,3}b")), "aaaab", 0, 5, 4, 4, -1, -1);
+
+ test_match (BRACES_TO_OPS (PARENS_TO_OPS ("(a*){1,3}b")), "b");
+ test_match (BRACES_TO_OPS (PARENS_TO_OPS ("(a*){1,3}b")), "aaab");
+ test_fastmap (BRACES_TO_OPS (PARENS_TO_OPS ("(a*){1,3}b")), "ab", 0, 0);
+
+ test_match (BRACES_TO_OPS (PARENS_TO_OPS ("(a*){1,1}ab")), "aaaab");
+ TEST_REGISTERS (BRACES_TO_OPS (PARENS_TO_OPS ("(a*){1,1}ab")), "aaaab", 0, 5, 0, 3, -1, -1);
+
+ test_match (BRACES_TO_OPS (".{0,3}b"), "b");
+ test_match (BRACES_TO_OPS (".{0,3}b"), "ab");
+
+ test_match (BRACES_TO_OPS ("[a]{0,3}b"), "b");
+ test_match (BRACES_TO_OPS ("[a]{0,3}b"), "aaab");
+ test_fastmap (BRACES_TO_OPS ("[a]{0,3}b"), "ab", 0, 0);
+ test_match (BRACES_TO_OPS ("[^a]{0,3}b"), "bcdb");
+ test_match (BRACES_TO_OPS ("ab{0,3}c"), "abbbc");
+ test_match (BRACES_TO_OPS ("[[:digit:]]{0,3}d"), "123d");
+ test_fastmap (BRACES_TO_OPS ("[[:digit:]]{0,3}d"), "0123456789d", 0, 0);
+
+ test_match (BRACES_TO_OPS ("\\*{0,3}a"), "***a");
+ test_match (BRACES_TO_OPS (".{0,3}b"), "aaab");
+ test_match (BRACES_TO_OPS ("a{0,3}a"), "aaa");
+ /* Backtracking. */
+ test_fastmap (BRACES_TO_OPS (PARENS_TO_OPS ("(a{1,})*a")), "a", 0, 0);
+ test_match (BRACES_TO_OPS (PARENS_TO_OPS ("(a{1,})*a")), "a");
+ TEST_REGISTERS (BRACES_TO_OPS (PARENS_TO_OPS ("(a{1,})*a")), "a", 0, 1, -1, -1, -1, -1);
+
+ test_fastmap (BRACES_TO_OPS (PARENS_TO_OPS ("(a{2,})*aa")), "aa", 0, 0);
+ test_match (BRACES_TO_OPS (PARENS_TO_OPS ("(a{2,})*aa")), "aa");
+ TEST_REGISTERS (BRACES_TO_OPS (PARENS_TO_OPS ("(a{2,})*aa")), "aa", 0, 2, -1, -1, -1, -1);
+
+ test_match (BRACES_TO_OPS ("a{2}*"), "");
+ test_match (BRACES_TO_OPS ("a{2}*"), "aa");
+
+ test_match (BRACES_TO_OPS ("a{1}*"), "");
+ test_match (BRACES_TO_OPS ("a{1}*"), "a");
+ test_match (BRACES_TO_OPS ("a{1}*"), "aa");
+
+ test_match (BRACES_TO_OPS ("a{1}{1}"), "a");
+
+ test_match (BRACES_TO_OPS ("a{1}{1}{1}"), "a");
+ test_match (BRACES_TO_OPS ("a{1}{1}{2}"), "aa");
+
+ test_match (BRACES_TO_OPS ("a{1}{1}*"), "");
+ test_match (BRACES_TO_OPS ("a{1}{1}*"), "a");
+ test_match (BRACES_TO_OPS ("a{1}{1}*"), "aa");
+ test_match (BRACES_TO_OPS ("a{1}{1}*"), "aaa");
+
+ test_match (BRACES_TO_OPS ("a{1}{2}"), "aa");
+ test_match (BRACES_TO_OPS ("a{2}{1}"), "aa");
+
+
+ test_should_match = false;
+
+ test_match (BRACES_TO_OPS ("a{0}"), "a");
+ test_match (BRACES_TO_OPS ("a{0,}"), "b");
+ test_match (BRACES_TO_OPS ("a{1}"), "");
+ test_match (BRACES_TO_OPS ("a{1}"), "aa");
+ test_match (BRACES_TO_OPS ("a{1,}"), "");
+ test_match (BRACES_TO_OPS ("a{1,}"), "b");
+ test_match (BRACES_TO_OPS ("a{0,0}"), "a");
+ test_match (BRACES_TO_OPS ("a{0,1}"), "aa");
+ test_match (BRACES_TO_OPS ("a{0,1}"), "b");
+ test_match (BRACES_TO_OPS ("a{1,3}"), "");
+ test_match (BRACES_TO_OPS ("a{1,3}"), "aaaa");
+ test_match (BRACES_TO_OPS ("a{1,3}"), "b");
+ test_match (BRACES_TO_OPS (PARENS_TO_OPS ("(a){1,3}b")), "aaaab");
+ test_match (BRACES_TO_OPS (PARENS_TO_OPS ("(a*){1,3}b")), "bb");
+ test_match (BRACES_TO_OPS ("[a]{0,3}"), "aaaa");
+ test_match (BRACES_TO_OPS ("[^a]{0,3}b"), "ab");
+ test_match (BRACES_TO_OPS ("ab{0,3}c"), "abababc");
+ test_match (BRACES_TO_OPS ("[:alpha:]{0,3}d"), "123d");
+ test_match (BRACES_TO_OPS ("\\^{1,3}a"), "a");
+ test_match (BRACES_TO_OPS (".{0,3}b"), "aaaab");
+
+ printf ("\nFinished POSIX interval tests.\n");
+}
diff --git a/gnu/lib/libregex/test/regexcpp.sed b/gnu/lib/libregex/test/regexcpp.sed
new file mode 100644
index 000000000000..082c1360814f
--- /dev/null
+++ b/gnu/lib/libregex/test/regexcpp.sed
@@ -0,0 +1,8 @@
+/;..*$/s/;/;\
+/g
+/{ .*$/s/{/{\
+/g
+/ \?[^'] /s/?/?\
+/g
+/ : /s/:/:\
+/g
diff --git a/gnu/lib/libregex/test/syntax.skel b/gnu/lib/libregex/test/syntax.skel
new file mode 100644
index 000000000000..a3fbf64c5983
--- /dev/null
+++ b/gnu/lib/libregex/test/syntax.skel
@@ -0,0 +1,74 @@
+/* Print which syntax bits are set. */
+
+#include <sys/types.h>
+#include <stdio.h>
+#include "regex.h"
+
+/* It's coincidental that these two are currently the same. */
+#define LONGEST_BIT_NAME "RE_UNMATCHED_RIGHT_PAREN_ORD"
+#define LAST_BIT RE_UNMATCHED_RIGHT_PAREN_ORD
+
+/* Sum of above, when printed. Assigned in main. */
+static unsigned longest;
+
+
+static void
+test_bit (syntax, bit, name)
+ reg_syntax_t syntax;
+ unsigned bit;
+ char *name;
+{
+ char padding[100], test_str[100];
+ int padding_count;
+
+ sprintf (test_str, "%s (%d=0x%x)", name, bit, bit);
+ padding_count = longest - strlen (test_str);
+
+ padding[padding_count] = 0;
+ while (padding_count--)
+ {
+ padding[padding_count] = ' ';
+ }
+
+ printf ("%s%s (%d=0x%x): %c\n",
+ name, padding, bit, bit, syntax & bit ? 'y' : 'n');
+}
+
+
+/* Macro to abbreviate the constant arguments. */
+#define TEST_BIT(bit) test_bit (syntax, bit, #bit)
+
+int
+main (argc, argv)
+ int argc;
+ char *argv[];
+{
+ reg_syntax_t syntax;
+ char syntax_str[1000], test_str[100];
+
+ switch (argc)
+ {
+ case 1:
+ printf ("Syntax? ");
+ scanf ("%s", syntax_str);
+ break;
+
+ case 2:
+ strcpy (syntax_str, argv[1]);
+ break;
+
+ default:
+ fprintf (stderr, "Usage: syntax [syntax].\n");
+ exit (1);
+ }
+
+ sscanf (syntax_str, "%i", &syntax);
+
+ /* Figure out the longest name, so we can align the output nicely. */
+ sprintf (test_str, "%s (%d=0x%x)", LONGEST_BIT_NAME, LAST_BIT, LAST_BIT);
+ longest = strlen (test_str);
+
+ /* [[[replace with bit tests]]] */
+
+ return 0;
+}
diff --git a/gnu/lib/libregex/test/test.c b/gnu/lib/libregex/test/test.c
new file mode 100644
index 000000000000..a8de23ef7429
--- /dev/null
+++ b/gnu/lib/libregex/test/test.c
@@ -0,0 +1,782 @@
+/* test.c: testing routines for regex.c. */
+
+#include <assert.h>
+
+#ifdef STDC_HEADERS
+#include <stdlib.h>
+#else
+char *malloc ();
+char *realloc ();
+#endif
+
+/* Just to be complete, we make both the system V/ANSI and the BSD
+ versions of the string functions available. */
+#if USG || STDC_HEADERS
+#include <string.h>
+#define index strchr
+#define rindex strrchr
+#define bcmp(s1, s2, len) memcmp ((s1), (s2), (len))
+#define bcopy(from, to, len) memcpy ((to), (from), (len))
+#define bzero(s, len) memset ((s), 0, (len))
+#else
+#include <strings.h>
+#define strchr index
+#define strrchr rindex
+#ifndef NEED_MEMORY_H
+#define memcmp(s1, s2, n) bcmp ((s1), (s2), (n))
+#define memcpy(to, from, len) bcopy ((from), (to), (len))
+#endif
+extern char *strtok ();
+extern char *strstr ();
+#endif /* not USG or STDC_HEADERS */
+
+/* SunOS 4.1 declares memchr in <memory.h>, not <string.h>. I don't
+ understand why. */
+#if NEED_MEMORY_H
+#include <memory.h>
+#endif
+
+#include "test.h"
+
+#define BYTEWIDTH 8
+
+extern void print_partial_compiled_pattern ();
+extern void print_compiled_pattern ();
+extern void print_double_string ();
+
+/* If nonzero, the results of every test are displayed. */
+boolean verbose = false;
+
+/* If nonzero, don't do register testing. */
+boolean omit_register_tests = true;
+
+/* Says whether the current test should match or fail to match. */
+boolean test_should_match;
+
+
+static void
+set_all_registers (start0, end0, start1, end1,
+ start2, end2, start3, end3,
+ start4, end4, start5, end5,
+ start6, end6, start7, end7,
+ start8, end8, start9, end9, regs)
+
+ int start0; int end0; int start1; int end1;
+ int start2; int end2; int start3; int end3;
+ int start4; int end4; int start5; int end5;
+ int start6; int end6; int start7; int end7;
+ int start8; int end8; int start9; int end9;
+ struct re_registers *regs;
+
+ {
+ unsigned r;
+
+ regs->start[0] = start0; regs->end[0] = end0;
+ regs->start[1] = start1; regs->end[1] = end1;
+ regs->start[2] = start2; regs->end[2] = end2;
+ regs->start[3] = start3; regs->end[3] = end3;
+ regs->start[4] = start4; regs->end[4] = end4;
+ regs->start[5] = start5; regs->end[5] = end5;
+ regs->start[6] = start6; regs->end[6] = end6;
+ regs->start[7] = start7; regs->end[7] = end7;
+ regs->start[8] = start8; regs->end[8] = end8;
+ regs->start[9] = start9; regs->end[9] = end9;
+ for (r = 10; r < regs->num_regs; r++)
+ {
+ regs->start[r] = -1;
+ regs->end[r] = -1;
+ }
+ }
+
+
+
+/* Return the concatenation of S1 and S2. This would be a prime place
+ to use varargs. */
+
+char *
+concat (s1, s2)
+ char *s1;
+ char *s2;
+{
+ char *answer = xmalloc (strlen (s1) + strlen (s2) + 1);
+
+ strcpy (answer, s1);
+ strcat (answer, s2);
+
+ return answer;
+}
+
+
+#define OK_TO_SEARCH (nonconst_buf.fastmap_accurate && (str1 || str2))
+
+/* We ignore the `can_be_null' argument. Should just be removed. */
+
+void
+general_test (pattern_should_be_valid, match_whole_string,
+ pat, str1, str2, start, range, end, correct_fastmap,
+ correct_regs, can_be_null)
+ unsigned pattern_should_be_valid;
+ unsigned match_whole_string;
+ const char *pat;
+ char *str1, *str2;
+ int start, range, end;
+ char *correct_fastmap;
+ struct re_registers *correct_regs;
+ int can_be_null;
+{
+ struct re_pattern_buffer nonconst_buf;
+ struct re_pattern_buffer old_buf;
+ struct re_registers regs;
+ const char *r;
+ char fastmap[1 << BYTEWIDTH];
+ unsigned *regs_correct = NULL;
+ unsigned all_regs_correct = 1;
+ boolean fastmap_internal_error = false;
+ unsigned match = 0;
+ unsigned match_1 = 0;
+ unsigned match_2 = 0;
+ unsigned invalid_pattern = 0;
+ boolean internal_error_1 = false;
+ boolean internal_error_2 = false;
+
+
+ nonconst_buf.allocated = 8;
+ nonconst_buf.buffer = xmalloc (nonconst_buf.allocated);
+ nonconst_buf.fastmap = fastmap;
+ nonconst_buf.translate = 0;
+
+ assert (pat != NULL);
+ r = re_compile_pattern (pat, strlen (pat), &nonconst_buf);
+
+ /* Kludge: if we are doing POSIX testing, we really should have
+ called regcomp, not re_compile_pattern. As it happens, the only
+ way in which it matters is that re_compile_pattern sets the
+ newline/anchor field for matching (part of what happens when
+ REG_NEWLINE is given to regcomp). We have to undo that for POSIX
+ matching. */
+ if (t == posix_basic_test || t == posix_extended_test)
+ nonconst_buf.newline_anchor = 0;
+
+ invalid_pattern = r != NULL;
+
+ if (!r)
+ {
+ int r;
+
+ if (!pattern_should_be_valid)
+ printf ("\nShould have been an invalid pattern but wasn't:\n");
+ else
+ {
+ fastmap_internal_error = (re_compile_fastmap (&nonconst_buf) == -2);
+
+ if (correct_fastmap)
+ nonconst_buf.fastmap_accurate =
+ memcmp (nonconst_buf.fastmap, correct_fastmap, 1 << BYTEWIDTH)
+ == 0;
+
+ if (OK_TO_SEARCH)
+ {
+ old_buf = nonconst_buf;
+ old_buf.buffer = (unsigned char *) xmalloc (nonconst_buf.used);
+ memcpy (old_buf.buffer, nonconst_buf.buffer, nonconst_buf.used);
+
+ /* If only one string is null, call re_match or re_search,
+ which is what the user would probably do. */
+ if (str1 == NULL && str2 != NULL
+ || str2 == NULL && str1 != NULL)
+ {
+ char *the_str = str1 == NULL ? str2 : str1;
+
+ match_1
+ = match_whole_string
+ ? (r = re_match (&nonconst_buf, the_str,
+ strlen (the_str), start, &regs))
+ == strlen (the_str)
+ : (r = re_search (&nonconst_buf,
+ the_str, strlen (the_str),
+ start, range, &regs))
+ >= 0;
+
+ if (r == -2)
+ internal_error_1 = true;
+ }
+ else
+ match_1 = 1;
+
+ /* Also call with re_match_2 or re_search_2, as they might
+ do this. (Also can check calling with either string1
+ or string2 or both null.) */
+ if (match_whole_string)
+ {
+ r = re_match_2 (&nonconst_buf,
+ str1, SAFE_STRLEN (str1),
+ str2, SAFE_STRLEN (str2),
+ start, &regs, end);
+ match_2 = r == SAFE_STRLEN (str1) + SAFE_STRLEN (str2);
+ }
+ else
+ {
+ r = re_search_2 (&nonconst_buf,
+ str1, SAFE_STRLEN (str1),
+ str2, SAFE_STRLEN (str2),
+ start, range, &regs, end);
+ match_2 = r >= 0;
+ }
+
+ if (r == -2)
+ internal_error_2 = true;
+
+ match = match_1 & match_2;
+
+ if (correct_regs)
+ {
+ unsigned reg;
+ if (regs_correct != NULL)
+ free (regs_correct);
+
+ regs_correct
+ = (unsigned *) xmalloc (regs.num_regs * sizeof (unsigned));
+
+ for (reg = 0;
+ reg < regs.num_regs && reg < correct_regs->num_regs;
+ reg++)
+ {
+ regs_correct[reg]
+ = (regs.start[reg] == correct_regs->start[reg]
+ && regs.end[reg] == correct_regs->end[reg])
+#ifdef EMPTY_REGS_CONFUSED
+ /* There is confusion in the standard about
+ the registers in some patterns which can
+ match either the empty string or not match.
+ For example, in `((a*))*' against the empty
+ string, the two registers can either match
+ the empty string (be 0/0), or not match
+ (because of the outer *) (be -1/-1). (Or
+ one can do one and one can do the other.) */
+ || (regs.start[reg] == -1 && regs.end[reg] == -1
+ && correct_regs->start[reg]
+ == correct_regs->end[reg])
+#endif
+ ;
+
+ all_regs_correct &= regs_correct[reg];
+ }
+ }
+ } /* OK_TO_SEARCH */
+ }
+ }
+
+ if (fastmap_internal_error)
+ printf ("\n\nInternal error in re_compile_fastmap:");
+
+ if (internal_error_1)
+ {
+ if (!fastmap_internal_error)
+ printf ("\n");
+
+ printf ("\nInternal error in re_match or re_search:");
+ }
+
+ if (internal_error_2)
+ {
+ if (!internal_error_1)
+ printf ("\n");
+
+ printf ("\nInternal error in re_match_2 or re_search_2:");
+ }
+
+ if ((OK_TO_SEARCH && ((match && !test_should_match)
+ || (!match && test_should_match))
+ || (correct_regs && !all_regs_correct))
+ || !nonconst_buf.fastmap_accurate
+ || invalid_pattern
+ || !pattern_should_be_valid
+ || internal_error_1 || internal_error_2
+ || verbose)
+ {
+ if (OK_TO_SEARCH && match && !test_should_match)
+ {
+ printf ("\n\nMatched but shouldn't have:\n");
+ if (match_1)
+ printf ("The single match/search succeeded.\n");
+
+ if (match_2)
+ printf ("The double match/search succeeded.\n");
+ }
+ else if (OK_TO_SEARCH && !match && test_should_match)
+ {
+ printf ("\n\nDidn't match but should have:\n");
+ if (!match_1)
+ printf ("The single match/search failed.\n");
+
+ if (!match_2)
+ printf ("The double match/search failed.\n");
+ }
+ else if (invalid_pattern && pattern_should_be_valid)
+ printf ("\n\nInvalid pattern (%s):\n", r);
+ else if (!nonconst_buf.fastmap_accurate && pattern_should_be_valid)
+ printf ("\n\nIncorrect fastmap:\n");
+ else if (OK_TO_SEARCH && correct_regs && !all_regs_correct)
+ printf ("\n\nNot all registers were correct:\n");
+ else if (verbose)
+ printf ("\n\nTest was OK:\n");
+
+
+ if ((!(invalid_pattern && !pattern_should_be_valid)) || verbose)
+ printf (" Pattern: `%s'.\n", pat);
+
+ if (pattern_should_be_valid || verbose
+ || internal_error_1 || internal_error_2)
+ {
+ printf(" Strings: ");
+ printf ("`%s' and ", str1 == NULL ? "NULL" : str1);
+ printf ("`%s'.\n", str2 == NULL ? "NULL" : str2);
+
+ if ((OK_TO_SEARCH || verbose || internal_error_1 || internal_error_2)
+ && !invalid_pattern)
+ {
+ if (memcmp (old_buf.buffer, nonconst_buf.buffer,
+ nonconst_buf.used) != 0
+ && !invalid_pattern)
+ {
+ printf(" (%s)\n", r ? r : "Valid regular expression");
+ printf ("\n Compiled pattern before matching: ");
+ print_compiled_pattern (&old_buf);
+ printf ("\n Compiled pattern after matching: ");
+ }
+ else
+ printf ("\n Compiled pattern: ");
+
+ print_compiled_pattern (&nonconst_buf);
+ }
+
+ if (correct_fastmap && (!nonconst_buf.fastmap_accurate || verbose))
+ {
+ printf ("\n The fastmap should have been: ");
+ print_fastmap (correct_fastmap);
+
+ printf ("\n Fastmap: ");
+ print_fastmap (fastmap);
+
+ printf ("\n Compiled pattern before matching: ");
+ print_compiled_pattern (&nonconst_buf);
+ }
+
+ if ((!all_regs_correct || verbose) && correct_regs)
+ {
+ unsigned this_reg;
+ printf ("\n Incorrect registers:");
+
+ for (this_reg = 0; this_reg < regs.num_regs; this_reg++)
+ {
+ if (!regs_correct[this_reg])
+ {
+ printf ("\n Register %d's start was %2d. ", this_reg,
+ regs.start[this_reg]);
+ printf ("\tIt should have been %d.\n",
+ correct_regs->start[this_reg]);
+ printf (" Register %d's end was %2d. ", this_reg,
+ regs.end[this_reg]);
+ printf ("\tIt should have been %d.\n",
+ correct_regs->end[this_reg]);
+ }
+ }
+ }
+ }
+ }
+
+ if (nonconst_buf.buffer != NULL)
+ free (nonconst_buf.buffer);
+
+ if (OK_TO_SEARCH)
+ {
+ free (old_buf.buffer);
+
+ if (correct_regs)
+ free (regs_correct);
+
+ }
+
+ nonconst_buf.buffer = old_buf.buffer = NULL;
+ regs_correct = NULL;
+ regs.start = regs.end = NULL;
+
+} /* general_test */
+
+
+void
+test_search_return (match_start_wanted, pattern, string)
+ int match_start_wanted;
+ const char *pattern;
+ char *string;
+{
+ struct re_pattern_buffer buf;
+ char fastmap[1 << BYTEWIDTH];
+ const char *compile_return;
+ int match_start;
+ static num_times_called = 0;
+
+ num_times_called++;
+ buf.allocated = 1;
+ buf.buffer = xmalloc (buf.allocated);
+
+ assert (pattern != NULL);
+ buf.translate = 0;
+ compile_return = re_compile_pattern (pattern, strlen (pattern), &buf);
+
+ if (compile_return)
+ {
+ printf ("\n\nInvalid pattern in test_match_start:\n");
+ printf ("%s\n", compile_return);
+ }
+ else
+ {
+ buf.fastmap = fastmap;
+ match_start = re_search (&buf, string, strlen (string),
+ 0, strlen (string), 0);
+
+ if (match_start != match_start_wanted)
+ printf ("\nWanted search to start at %d but started at %d.\n",
+ match_start, match_start_wanted);
+ }
+ free (buf.buffer);
+ buf.buffer = NULL;
+}
+
+
+#define SET_FASTMAP() \
+ { \
+ unsigned this_char; \
+ \
+ memset (correct_fastmap, invert, (1 << BYTEWIDTH)); \
+ \
+ for (this_char = 0; this_char < strlen (fastmap_string); this_char++)\
+ correct_fastmap[fastmap_string[this_char]] = !invert; \
+ correct_fastmap['\n'] = match_newline; \
+ }
+
+
+void
+test_fastmap (pat, fastmap_string, invert, match_newline)
+ const char *pat;
+ char *fastmap_string;
+ unsigned invert;
+ unsigned match_newline;
+{
+ char correct_fastmap[(1 << BYTEWIDTH)];
+
+ SET_FASTMAP ();
+ general_test (1, 0, pat, NULL, NULL, -1, 0, -1, correct_fastmap, 0, -1);
+}
+
+
+void
+test_fastmap_search (pat, str, fastmap_string, invert, match_newline,
+ can_be_null, start0, end0)
+ const char *pat;
+ char *str;
+ char *fastmap_string;
+ unsigned invert;
+ unsigned match_newline;
+ int can_be_null;
+ int start0;
+ int end0;
+{
+ char correct_fastmap[(1 << BYTEWIDTH)];
+ struct re_registers correct_regs;
+
+ correct_regs.num_regs = RE_NREGS;
+ correct_regs.start = (int *) xmalloc (RE_NREGS * sizeof (int));
+ correct_regs.end = (int *) xmalloc (RE_NREGS * sizeof (int));
+
+ set_all_registers (start0, end0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, &correct_regs);
+ SET_FASTMAP ();
+ general_test (1, 0, pat, str, NULL, 0, SAFE_STRLEN (str), SAFE_STRLEN (str),
+ correct_fastmap, &correct_regs, can_be_null);
+
+ free (correct_regs.start);
+ free (correct_regs.end);
+}
+
+
+
+
+void
+test_all_registers (pat, str1, str2,
+ start0, end0, start1, end1,
+ start2, end2, start3, end3,
+ start4, end4, start5, end5,
+ start6, end6, start7, end7,
+ start8, end8, start9, end9)
+ char *pat; char *str1; char *str2;
+ int start0; int end0; int start1; int end1;
+ int start2; int end2; int start3; int end3;
+ int start4; int end4; int start5; int end5;
+ int start6; int end6; int start7; int end7;
+ int start8; int end8; int start9; int end9;
+{
+ struct re_registers correct_regs;
+
+ if (omit_register_tests) return;
+
+ correct_regs.num_regs = RE_NREGS;
+ correct_regs.start = (int *) xmalloc (RE_NREGS * sizeof (int));
+ correct_regs.end = (int *) xmalloc (RE_NREGS * sizeof (int));
+
+ set_all_registers (start0, end0, start1, end1, start2, end2, start3, end3,
+ start4, end4, start5, end5, start6, end6, start7, end7,
+ start8, end8, start9, end9, &correct_regs);
+
+ general_test (1, 0, pat, str1, str2, 0,
+ SAFE_STRLEN (str1) + SAFE_STRLEN (str2),
+ SAFE_STRLEN (str1) + SAFE_STRLEN (str2),
+ NULL, &correct_regs, -1);
+
+ free (correct_regs.start);
+ free (correct_regs.end);
+}
+
+
+void
+invalid_pattern (error_code_expected, pattern)
+ int error_code_expected;
+ char *pattern;
+{
+ regex_t pattern_buffer;
+ int cflags
+ = re_syntax_options == RE_SYNTAX_POSIX_EXTENDED
+ || re_syntax_options == RE_SYNTAX_POSIX_MINIMAL_EXTENDED
+ ? REG_EXTENDED : 0;
+
+ test_compile (0, error_code_expected, pattern, &pattern_buffer, cflags);
+}
+
+
+void
+valid_pattern (pattern)
+ char *pattern;
+{
+ regex_t pattern_buffer;
+ int cflags
+ = re_syntax_options == RE_SYNTAX_POSIX_EXTENDED
+ || re_syntax_options == RE_SYNTAX_POSIX_MINIMAL_EXTENDED
+ ? REG_EXTENDED : 0;
+
+ test_compile (1, 0, pattern, &pattern_buffer, cflags);
+}
+
+
+char *
+delimiters_to_ops (source, left_delimiter, right_delimiter)
+ char *source;
+ char left_delimiter;
+ char right_delimiter;
+{
+ static char *answer = NULL;
+ char *tmp = NULL;
+ boolean double_size = false;
+ unsigned source_char;
+ unsigned answer_char = 0;
+
+ assert (source != NULL);
+
+ switch (left_delimiter)
+ {
+ case '(': if (!(re_syntax_options & RE_NO_BK_PARENS))
+ double_size = true;
+ break;
+ case '{': if (!(re_syntax_options & RE_NO_BK_BRACES))
+ double_size = true;
+ break;
+ default: printf ("Found strange delimiter %c in delimiter_to_ops.\n",
+ left_delimiter);
+ printf ("The source was `%s'\n", source);
+ exit (0);
+ }
+
+ if (answer == source)
+ {
+ tmp = (char *) xmalloc (strlen (source) + 1);
+ strcpy (tmp, source);
+ source = tmp;
+ }
+
+ if (answer)
+ {
+ free (answer);
+ answer = NULL;
+ }
+
+ answer = (char *) xmalloc ((double_size
+ ? strlen (source) << 1
+ : strlen (source))
+ + 1);
+ if (!double_size)
+ strcpy (answer, source);
+ else
+ {
+ for (source_char = 0; source_char < strlen (source); source_char++)
+ {
+ if (source[source_char] == left_delimiter
+ || source[source_char] == right_delimiter)
+ answer[answer_char++] = '\\';
+
+ answer[answer_char++] = source[source_char];
+ }
+ answer[answer_char] = 0;
+ }
+
+ return answer;
+}
+
+
+void
+print_pattern_info (pattern, pattern_buffer_ptr)
+ const char *pattern;
+ regex_t *pattern_buffer_ptr;
+{
+ printf (" Pattern: `%s'.\n", pattern);
+ printf (" Compiled pattern: ");
+ print_compiled_pattern (pattern_buffer_ptr);
+}
+
+
+void
+valid_nonposix_pattern (pattern)
+ char *pattern;
+{
+ struct re_pattern_buffer nonconst_buf;
+
+ nonconst_buf.allocated = 0;
+ nonconst_buf.buffer = NULL;
+ nonconst_buf.translate = NULL;
+
+ assert (pattern != NULL);
+
+ if (re_compile_pattern (pattern, strlen (pattern), &nonconst_buf))
+ {
+ printf ("Couldn't compile the pattern.\n");
+ print_pattern_info (pattern, &nonconst_buf);
+ }
+}
+
+
+void
+compile_and_print_pattern (pattern)
+ char *pattern;
+{
+ struct re_pattern_buffer nonconst_buf;
+
+ nonconst_buf.allocated = 0;
+ nonconst_buf.buffer = NULL;
+
+ if (re_compile_pattern (pattern, strlen (pattern), &nonconst_buf))
+ printf ("Couldn't compile the pattern.\n");
+
+ print_pattern_info (pattern, &nonconst_buf);
+}
+
+
+void
+test_case_fold (pattern, string)
+ const char *pattern;
+ char* string;
+{
+ struct re_pattern_buffer nonconst_buf;
+ const char *ret;
+
+ init_pattern_buffer (&nonconst_buf);
+ nonconst_buf.translate = upcase;
+
+ assert (pattern != NULL);
+ ret = re_compile_pattern (pattern, strlen (pattern), &nonconst_buf);
+
+ if (ret)
+ {
+ printf ("\nShould have been a valid pattern but wasn't.\n");
+ print_pattern_info (pattern, &nonconst_buf);
+ }
+ else
+ {
+ if (test_should_match
+ && re_match (&nonconst_buf, string, strlen (string), 0, 0)
+ != strlen (string))
+ {
+ printf ("Match failed for case fold.\n");
+ printf (" Pattern: `%s'.\n", pattern);
+ printf (" String: `%s'.\n", string == NULL ? "NULL" : string);
+ }
+ }
+}
+
+
+void
+test_match_n_times (n, pattern, string)
+ unsigned n;
+ char* pattern;
+ char* string;
+{
+ struct re_pattern_buffer buf;
+ const char *r;
+ unsigned match = 0;
+ unsigned this_match;
+
+ buf.allocated = 0;
+ buf.buffer = NULL;
+ buf.translate = 0;
+
+ assert (pattern != NULL);
+
+ r = re_compile_pattern (pattern, strlen (pattern), &buf);
+ if (r)
+ {
+ printf ("Didn't compile.\n");
+ printf (" Pattern: %s.\n", pattern);
+ }
+ else
+ {
+ for (this_match = 1; this_match <= n; this_match++)
+ match = (re_match (&buf, string, strlen (string),
+ 0, 0)
+ == strlen (string));
+
+ if (match && !test_should_match)
+ printf ("\n\nMatched but shouldn't have:\n");
+ else if (!match && test_should_match)
+ printf ("\n\nDidn't match but should have:\n");
+
+ if ((match && !test_should_match) || (!match && test_should_match))
+ {
+ printf(" The string to match was: ");
+ if (string)
+ printf ("`%s' and ", string);
+ else
+ printf ("`'");
+
+ printf (" Pattern: %s.\n", pattern);
+ printf (" Compiled pattern: %s.\n", pattern);
+ print_compiled_pattern (&buf);
+ }
+ }
+}
+
+
+void
+test_match_2 (pat, str1, str2)
+ const char *pat;
+ char *str1;
+ char *str2;
+{
+ general_test (1, 1, pat, str1, str2, 0, 1,
+ SAFE_STRLEN (str1) + SAFE_STRLEN (str2), NULL, 0, -1);
+}
+
+void
+test_match (pat, str)
+ const char *pat;
+ char *str;
+{
+ test_match_2 (pat, str, NULL);
+ test_match_2 (pat, NULL, str);
+}
diff --git a/gnu/lib/libregex/test/test.h b/gnu/lib/libregex/test/test.h
new file mode 100644
index 000000000000..fb67126547cc
--- /dev/null
+++ b/gnu/lib/libregex/test/test.h
@@ -0,0 +1,141 @@
+/* test.h: for Regex testing. */
+
+#ifndef TEST_H
+#define TEST_H
+
+#include <stdio.h>
+#include <assert.h>
+
+#include <sys/types.h>
+#include "regex.h"
+
+
+/* A strlen that works even on a null pointer. */
+#define SAFE_STRLEN(s) (s == NULL ? 0 : strlen (s))
+
+typedef enum { false = 0, true = 1 } boolean;
+
+extern boolean test_should_match;
+extern boolean omit_register_tests;
+extern void *xmalloc ();
+
+/* Defined in upcase.c. */
+extern char upcase[];
+
+typedef enum
+{
+ all_test,
+ other_test,
+ posix_basic_test,
+ posix_extended_test,
+ posix_interface_test,
+ regress_test
+} test_type;
+
+extern test_type t;
+
+
+#if __STDC__
+
+extern char *concat (char *, char *);
+
+extern void general_test (unsigned pattern_should_be_valid,
+ unsigned match_whole_string,
+ const char *pat, char *str1, char *str2,
+ int start, int range, int end,
+ char *correct_fastmap,
+ struct re_registers *correct_regs, int can_be_null);
+
+
+extern void init_pattern_buffer (regex_t *pattern_buffer_ptr);
+
+extern void test_compile (unsigned valid_pattern, int error_code_expected,
+ const char *pattern, regex_t *pattern_buffer_ptr,
+ int cflags);
+
+extern char *delimiter_to_ops (char *source, char left_delimiter,
+ char right_delimiter);
+
+
+extern void test_search_return (int, const char *, char *);
+
+extern void test_berk_search (const char *pattern, char *string);
+
+extern void test_fastmap (const char *pat, char *fastmap_string, unsigned invert,
+ unsigned match_newline);
+
+extern void test_fastmap_search (const char *pat, char *str, char *fastmap_string,
+ unsigned invert, unsigned match_newline,
+ int can_be_null, int start0, int end0);
+
+extern void test_all_registers (char *pat, char *str1, char *str2,
+ int start0, int end0, int start1, int end1,
+ int start2, int end2, int start3, int end3,
+ int start4, int end4, int start5, int end5,
+ int start6, int end6, int start7, int end7,
+ int start8, int end8, int start9, int end9);
+
+extern void print_pattern_info (const char *pattern, regex_t *pattern_buffer_ptr);
+extern void compile_and_print_pattern (char *pattern);
+
+extern void test_case_fold (const char *pattern, char* string);
+
+extern void test_posix_generic ();
+
+extern void test_grouping ();
+
+extern void invalid_pattern (int error_code_expected, char *pattern);
+extern void valid_nonposix_pattern (char *pattern);
+extern void valid_pattern (char *pattern);
+
+extern void test_match_2 (const char *pat, char *str1, char *str2);
+extern void test_match (const char *pat, char *str);
+
+#endif /* __STDC__ */
+
+
+#define TEST_REGISTERS_2(pat, str1, str2, start0, end0, start1, end1, start2, end2)\
+ if (!omit_register_tests) \
+ test_all_registers (pat, str1, str2, start0, end0, start1, end1, \
+ start2, end2, -1, -1, -1, -1, -1, -1, -1, -1,\
+ -1, -1, -1, -1, -1, -1) \
+
+
+#define TEST_REGISTERS(pat, str, start0, end0, start1, end1, start2, end2) \
+ TEST_REGISTERS_2 (pat, str, NULL, start0, end0, start1, end1, start2, end2)\
+
+#define BRACES_TO_OPS(string) ((char *) delimiters_to_ops (string, '{', '}'))
+#define PARENS_TO_OPS(string) ((char *) delimiters_to_ops (string, '(', ')'))
+
+#define INVALID_PATTERN(pat) \
+ general_test (0, 0, pat, NULL, NULL, -1, 0, -1, NULL, 0, -1)
+
+
+#define MATCH_SELF(p) test_match (p, p)
+
+#define TEST_POSITIONED_MATCH(pat, str, start) \
+ general_test (1, 0, pat, str, NULL, start, 1, SAFE_STRLEN (str), \
+ NULL, 0, -1)
+
+#define TEST_TRUNCATED_MATCH(pat, str, end) \
+ general_test (1, 0, pat, str, NULL, 0, 1, end, NULL, 0, -1)
+
+#define TEST_SEARCH_2(pat, str1, str2, start, range, one_past_end) \
+ general_test (1, 0, pat, str1, str2, start, range, one_past_end, \
+ NULL, 0, -1)
+
+#define TEST_SEARCH(pat, str, start, range) \
+ { \
+ TEST_SEARCH_2 (pat, str, NULL, start, range, SAFE_STRLEN (str)); \
+ TEST_SEARCH_2 (pat, NULL, str, start, range, SAFE_STRLEN (str)); \
+ }
+
+#endif /* TEST_H */
+
+/*
+Local variables:
+make-backup-files: t
+version-control: t
+trim-versions-without-asking: nil
+End:
+*/
diff --git a/gnu/lib/libregex/test/tregress.c b/gnu/lib/libregex/test/tregress.c
new file mode 100644
index 000000000000..7858cac1502b
--- /dev/null
+++ b/gnu/lib/libregex/test/tregress.c
@@ -0,0 +1,464 @@
+/* tregress.c: reported bugs. The `t' just makes the filename not have
+ a common prefix with `regex.c', so completion works better. */
+
+#include "test.h"
+
+
+boolean pause_at_error = true;
+
+char *
+itoa (i)
+ int i;
+{
+ char *a = xmalloc (21); /* sign + 19 digits (enough for 64 bits) + null */
+
+ sprintf (a, "%d", i);
+ return a;
+}
+
+
+static void
+simple_fail (routine, pat, buf, str, ret)
+ const char *routine;
+ const char *pat;
+ struct re_pattern_buffer *buf;
+ const char *str;
+ char *ret;
+{
+ fprintf (stderr, "Failed %s (return = %s).\n", routine, ret);
+ if (str && *str) fprintf (stderr, " String = %s\n", str);
+ fprintf (stderr, " Pattern = %s\n", pat);
+ print_compiled_pattern (buf);
+
+ if (pause_at_error)
+ {
+ fprintf (stderr, "RET to continue: ");
+ (void) getchar ();
+ }
+}
+
+
+/* Abbreviate the most common calls. */
+
+static void
+simple_compile (pat, buf)
+ const char *pat;
+ struct re_pattern_buffer *buf;
+{
+ const char *ret = re_compile_pattern (pat, strlen (pat), buf);
+
+ if (ret != NULL) simple_fail ("compile", pat, buf, NULL, ret);
+}
+
+
+static void
+simple_fastmap (pat)
+ const char *pat;
+{
+ struct re_pattern_buffer buf;
+ char fastmap[256];
+ int ret;
+
+ buf.allocated = 0;
+ buf.buffer = buf.translate = NULL;
+ buf.fastmap = fastmap;
+
+ simple_compile (pat, &buf);
+
+ ret = re_compile_fastmap (&buf);
+
+ if (ret != 0) simple_fail ("fastmap compile", pat, &buf, NULL, itoa (ret));
+}
+
+
+#define SIMPLE_MATCH(pat, str) do_match (pat, str, strlen (str))
+#define SIMPLE_NONMATCH(pat, str) do_match (pat, str, -1)
+
+static void
+do_match (pat, str, expected)
+ const char *pat, *str;
+ int expected;
+{
+ int ret;
+ unsigned len;
+ struct re_pattern_buffer buf;
+
+ buf.allocated = 0;
+ buf.buffer = buf.translate = buf.fastmap = NULL;
+
+ simple_compile (pat, &buf);
+
+ len = strlen (str);
+
+ ret = re_match_2 (&buf, NULL, 0, str, len, 0, NULL, len);
+
+ if (ret != expected) simple_fail ("match", pat, &buf, str, itoa (ret));
+}
+
+
+static void
+simple_search (pat, str, correct_startpos)
+ const char *pat, *str;
+ int correct_startpos;
+{
+ int ret;
+ unsigned len;
+ struct re_pattern_buffer buf;
+
+ buf.allocated = 0;
+ buf.buffer = buf.translate = buf.fastmap = NULL;
+
+ simple_compile (pat, &buf);
+
+ len = strlen (str);
+
+ ret = re_search_2 (&buf, NULL, 0, str, len, 0, len, NULL, len);
+
+ if (ret != correct_startpos)
+ simple_fail ("match", pat, &buf, str, itoa (ret));
+}
+
+/* Past bugs people have reported. */
+
+void
+test_regress ()
+{
+ extern char upcase[];
+ struct re_pattern_buffer buf;
+ unsigned len;
+ struct re_registers regs;
+ int ret;
+ char *fastmap = xmalloc (256);
+
+ buf.translate = NULL;
+ buf.fastmap = NULL;
+ buf.allocated = 0;
+ buf.buffer = NULL;
+
+ printf ("\nStarting regression tests.\n");
+ t = regress_test;
+
+ test_should_match = true;
+ re_set_syntax (RE_SYNTAX_EMACS);
+
+ /* enami@sys.ptg.sony.co.jp 10 Nov 92 15:19:02 JST */
+ buf.translate = upcase;
+ SIMPLE_MATCH ("[A-[]", "A");
+ buf.translate = NULL;
+
+ /* meyering@cs.utexas.edu Nov 6 22:34:41 1992 */
+ simple_search ("\\w+", "a", 0);
+
+ /* jimb@occs.cs.oberlin.edu 10 Sep 92 00:42:33 */
+ buf.translate = upcase;
+ SIMPLE_MATCH ("[\001-\377]", "\001");
+ SIMPLE_MATCH ("[\001-\377]", "a");
+ SIMPLE_MATCH ("[\001-\377]", "\377");
+ buf.translate = NULL;
+
+ /* mike@skinner.cs.uoregon.edu 1 Sep 92 01:45:22 */
+ SIMPLE_MATCH ("^^$", "^");
+
+ /* pclink@qld.tne.oz.au Sep 7 22:42:36 1992 */
+ re_set_syntax (RE_INTERVALS);
+ SIMPLE_MATCH ("^a\\{3\\}$", "aaa");
+ SIMPLE_NONMATCH ("^a\\{3\\}$", "aa");
+ re_set_syntax (RE_SYNTAX_EMACS);
+
+ /* pclink@qld.tne.oz.au, 31 Aug 92. (conjecture) */
+ re_set_syntax (RE_INTERVALS);
+ simple_search ("a\\{1,3\\}b", "aaab", 0);
+ simple_search ("a\\{1,3\\}b", "aaaab", 1);
+ re_set_syntax (RE_SYNTAX_EMACS);
+
+ /* trq@dionysos.thphys.ox.ac.uk, 31 Aug 92. (simplified) */
+ simple_fastmap ("^.*\n[ ]*");
+
+ /* wind!greg@plains.NoDak.edu, 25 Aug 92. (simplified) */
+ re_set_syntax (RE_INTERVALS);
+ SIMPLE_MATCH ("[a-zA-Z]*.\\{5\\}", "xN0000");
+ SIMPLE_MATCH ("[a-zA-Z]*.\\{5\\}$", "systemxN0000");
+ SIMPLE_MATCH ("\\([a-zA-Z]*\\).\\{5\\}$", "systemxN0000");
+ re_set_syntax (RE_SYNTAX_EMACS);
+
+ /* jimb, 18 Aug 92. Don't use \000, so `strlen' (in our testing
+ routines) will work. (This still tickles the bug jimb reported.) */
+ SIMPLE_MATCH ("[\001-\377]", "\001");
+ SIMPLE_MATCH ("[\001-\377]", "a");
+ SIMPLE_MATCH ("[\001-\377]", "\377");
+
+ /* jimb, 13 Aug 92. */
+ SIMPLE_MATCH ("[\001-\177]", "\177");
+
+ /* Tests based on bwoelfel's below. */
+ SIMPLE_MATCH ("\\(a\\|ab\\)*", "aab");
+ SIMPLE_MATCH ("\\(a\\|ab\\)+", "aab");
+ SIMPLE_MATCH ("\\(a*\\|ab\\)+", "aab");
+ SIMPLE_MATCH ("\\(a+\\|ab\\)+", "aab");
+ SIMPLE_MATCH ("\\(a?\\|ab\\)+", "aab");
+
+ /* bwoelfel@widget.seas.upenn.edu, 25 Jul 92. */
+ SIMPLE_MATCH ("^\\([ab]+\\|bc\\)+", "abc");
+
+ /* jla, 3 Jul 92. Core dump in re_search_2. */
+ buf.fastmap = fastmap;
+ buf.translate = upcase;
+#define DATEDUMP_PATTERN " *[0-9]*:"
+ if (re_compile_pattern (DATEDUMP_PATTERN, strlen (DATEDUMP_PATTERN), &buf)
+ != NULL)
+ printf ("date dump compile failed.\n");
+ regs.num_regs = 0;
+ regs.start = regs.end = NULL;
+ if (re_search_2 (&buf, NULL, 0, "Thu Jul 2 18:34:18 1992",
+ 24, 3, 21, &regs, 24) != 10)
+ printf ("date dump search failed.\n");
+ buf.fastmap = 0;
+ buf.translate = 0;
+
+
+ /* rms, 4 Jul 1992. Pattern is much slower in Emacs 19. Fastmap
+ should be only a backslash. */
+#define BEGINEND_PATTERN "\\(\\\\begin\\s *{\\)\\|\\(\\\\end\\s *{\\)"
+ test_fastmap (BEGINEND_PATTERN, "\\", false, 0);
+
+
+ /* kaoru@is.s.u-tokyo.ac.jp, 27 Jun 1992. Code for [a-z] (in regex.c)
+ should translate the whole set. */
+ buf.translate = upcase;
+#define CASE_SET_PATTERN "[ -`]"
+ if (re_compile_pattern (CASE_SET_PATTERN, strlen (CASE_SET_PATTERN), &buf)
+ != NULL)
+ printf ("case set compile failed.\n");
+ if (re_match_2 (&buf, "K", 1, "", 0, 0, NULL, 1) != 1)
+ printf ("case set match failed.\n");
+
+#define CASE_SET_PATTERN2 "[`-|]"
+ if (re_compile_pattern (CASE_SET_PATTERN2, strlen (CASE_SET_PATTERN2), &buf)
+ != NULL)
+ printf ("case set2 compile failed.\n");
+ if (re_match_2 (&buf, "K", 1, "", 0, 0, NULL, 1) != 1)
+ printf ("case set2 match failed.\n");
+
+ buf.translate = NULL;
+
+
+ /* jimb, 27 Jun 92. Problems with gaps in the string. */
+#define GAP_PATTERN "x.*y.*z"
+ if (re_compile_pattern (GAP_PATTERN, strlen (GAP_PATTERN), &buf) != NULL)
+ printf ("gap didn't compile.\n");
+ if (re_match_2 (&buf, "x-", 2, "y-z-", 4, 0, NULL, 6) != 5)
+ printf ("gap match failed.\n");
+
+
+ /* jimb, 19 Jun 92. Since `beginning of word' matches at the
+ beginning of the string, then searching ought to find it there.
+ If `re_compile_fastmap' is not called, then it works ok. */
+ buf.fastmap = fastmap;
+#define BOW_BEG_PATTERN "\\<"
+ if (re_compile_pattern (BOW_BEG_PATTERN, strlen (BOW_BEG_PATTERN), &buf)
+ != NULL)
+ printf ("begword-begstring didn't compile.\n");
+ if (re_search (&buf, "foo", 3, 0, 3, NULL) != 0)
+ printf ("begword-begstring search failed.\n");
+
+ /* Same bug report, different null-matching pattern. */
+#define EMPTY_ANCHOR_PATTERN "^$"
+ if (re_compile_pattern (EMPTY_ANCHOR_PATTERN, strlen (EMPTY_ANCHOR_PATTERN),
+ &buf) != NULL)
+ printf ("empty anchor didn't compile.\n");
+ if (re_search (&buf, "foo\n\nbar", 8, 0, 8, NULL) != 4)
+ printf ("empty anchor search failed.\n");
+
+ /* jimb@occs.cs.oberlin.edu, 21 Apr 92. After we first allocate
+ registers for a particular re_pattern_buffer, we might have to
+ reallocate more registers on subsequent calls -- and we should be
+ reusing the same memory. */
+#define ALLOC_REG_PATTERN "\\(abc\\)"
+ free (buf.fastmap);
+ buf.fastmap = 0;
+ if (re_compile_pattern (ALLOC_REG_PATTERN, strlen (ALLOC_REG_PATTERN), &buf)
+ != NULL)
+ printf ("register allocation didn't compile.\n");
+ if (re_match (&buf, "abc", 3, 0, &regs) != 3)
+ printf ("register allocation didn't match.\n");
+ if (regs.start[1] != 0 || regs.end[1] != 3)
+ printf ("register allocation reg #1 wrong.\n");
+
+ {
+ int *old_regstart = regs.start;
+ int *old_regend = regs.end;
+
+ if (re_match (&buf, "abc", 3, 0, &regs) != 3)
+ printf ("register reallocation didn't match.\n");
+ if (regs.start[1] != 0 || regs.end[1] != 3
+ || old_regstart[1] != 0 || old_regend[1] != 3
+ || regs.start != old_regstart || regs.end != old_regend)
+ printf ("register reallocation registers wrong.\n");
+ }
+
+ /* jskudlarek@std.MENTORG.COM, 21 Apr 92 (string-match). */
+#define JSKUD_PATTERN "[^/]+\\(/[^/.]+\\)?/[0-9]+$"
+ if (re_compile_pattern (JSKUD_PATTERN, strlen (JSKUD_PATTERN), &buf) != NULL)
+ printf ("jskud test didn't compile.\n");
+ if (re_search (&buf, "a/1", 3, 0, 3, &regs) != 0)
+ printf ("jskud test didn't match.\n");
+ if (regs.start[1] != -1 || regs.end[1] != -1)
+ printf ("jskud test, reg #1 wrong.\n");
+
+ /* jla's bug (with string-match), 5 Feb 92. */
+ TEST_SEARCH ("\\`[ \t\n]*", "jla@challenger (Joseph Arceneaux)", 0, 100);
+
+ /* jwz@lucid.com, 8 March 1992 (re-search-forward). (His is the
+ second.) These are not supposed to match. */
+#if 0
+ /* This one fails quickly, because we can change the maybe_pop_jump
+ from the + to a pop_failure_pop, because of the c's. */
+ TEST_SEARCH ("^\\(To\\|CC\\):\\([^c]*\\)+co",
+"To: hbs%titanic@lucid.com (Harlan Sexton)\n\
+Cc: eb@thalidomide, jlm@thalidomide\n\
+Subject: Re: so is this really as horrible an idea as it seems to me?\n\
+In-Reply-To: Harlan Sexton's message of Sun 8-Mar-92 11:00:06 PST <9203081900.AA24794@titanic.lucid>\n\
+References: <9203080736.AA05869@thalidomide.lucid>\n\
+ <9203081900.AA24794@titanic.lucid>", 0, 5000);
+
+ /* This one takes a long, long time to complete, because we have to
+ keep the failure points around because we might backtrack. */
+ TEST_SEARCH ("^\\(To\\|CC\\):\\(.*\n.*\\)+co",
+ /* "X-Windows: The joke that kills.\n\
+FCC: /u/jwz/VM/inbox\n\
+From: Jamie Zawinski <jwz@lucid.com>\n\ */
+"To: hbs%titanic@lucid.com (Harlan Sexton)\n\
+Cc: eb@thalidomide, jlm@thalidomide\n\
+Subject: Re: so is this really as horrible an idea as it seems to me?\n\
+In-Reply-To: Harlan Sexton's message of Sun 8-Mar-92 11:00:06 PST <9203081900.AA24794@titanic.lucid>\n\
+References: <9203080736.AA05869@thalidomide.lucid>\n\
+ <9203081900.AA24794@titanic.lucid>", 0, 5000);
+#endif /* 0 [failed searches] */
+
+
+ /* macrakis' bugs. */
+ buf.translate = upcase; /* message of 24 Jan 91 */
+ if (re_compile_pattern ("[!-`]", 5, &buf) != NULL)
+ printf ("Range test didn't compile.\n");
+ if (re_match (&buf, "A", 1, 0, NULL) != 1)
+ printf ("Range test #1 didn't match.\n");
+ if (re_match (&buf, "a", 1, 0, NULL) != 1)
+ printf ("Range test #2 didn't match.\n");
+
+ buf.translate = 0;
+#define FAO_PATTERN "\\(f\\(.\\)o\\)+"
+ if (re_compile_pattern (FAO_PATTERN, strlen (FAO_PATTERN), &buf) != NULL)
+ printf ("faofdx test didn't compile.\n");
+ if (re_search (&buf, "faofdx", 6, 0, 6, &regs) != 0)
+ printf ("faofdx test didn't match.\n");
+ if (regs.start[1] != 0 || regs.end[1] != 3)
+ printf ("faofdx test, reg #1 wrong.\n");
+ if (regs.start[2] != 1 || regs.end[2] != 2)
+ printf ("faofdx test, reg #2 wrong.\n");
+
+ TEST_REGISTERS ("\\(a\\)*a", "aaa", 0, 3, 1, 2, -1, -1);
+ test_fastmap ("^\\([^ \n]+:\n\\)+\\([^ \n]+:\\)", " \n", 1, 0);
+
+ /* 40 lines, 48 a's in each line. */
+ test_match ("^\\([^ \n]+:\n\\)+\\([^ \n]+:\\)",
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:");
+
+ /* 640 a's followed by one b, twice. */
+ test_match ("\\(.*\\)\\1", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab");
+
+ /* 640 a's followed by two b's, twice. */
+ test_match ("\\(.*\\)\\1", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabb");
+
+
+ /* Dave G. bug: Reference to a subexpression which didn't match.
+ Should fail. */
+ re_set_syntax (RE_NO_BK_PARENS | RE_NO_BK_VBAR);
+ test_match ("(ooooooooooone())-annnnnnnnnnnd-(twooooooooooo\\2)",
+ "ooooooooooone-annnnnnnnnnnd-twooooooooooo");
+ test_match ("(o|t)", "o");
+ test_match ("(o()|t)", "o");
+ test_match ("(o|t)", "o");
+ test_match ("(ooooooooooooooo|tttttttttttttttt())", "ooooooooooooooo");
+ test_match ("(o|t())", "o");
+ test_match ("(o()|t())", "o");
+ test_match ("(ooooooooooooooooooooooooone()|twooooooooooooooooooooooooo())", "ooooooooooooooooooooooooone");
+ test_match ("(o()|t())-a-(t\\2|f\\3)", "o-a-t");
+ test_match ("(o()|t())-a-(t\\2|f\\3)", "t-a-f");
+
+ test_should_match = 0;
+ test_match ("(foo(bar)|second)\\2", "second");
+ test_match ("(o()|t())-a-(t\\2|f\\3)", "t-a-t");
+ test_match ("(o()|t())-a-(t\\2|f\\3)", "o-a-f");
+
+ re_set_syntax (RE_SYNTAX_EMACS);
+ test_match ("\\(foo\\(bar\\)\\|second\\)\\2", "secondbar");
+ test_match ("\\(one\\(\\)\\|two\\(\\)\\)-and-\\(three\\2\\|four\\3\\)",
+ "one-and-four");
+ test_match ("\\(one\\(\\)\\|two\\(\\)\\)-and-\\(three\\2\\|four\\3\\)",
+ "two-and-three");
+
+ test_should_match = 1;
+ re_set_syntax (RE_SYNTAX_EMACS);
+ test_match ("\\(one\\(\\)\\|two\\(\\)\\)-and-\\(three\\2\\|four\\3\\)",
+ "one-and-three");
+ test_match ("\\(one\\(\\)\\|two\\(\\)\\)-and-\\(three\\2\\|four\\3\\)",
+ "two-and-four");
+
+ TEST_REGISTERS (":\\(.*\\)", ":/", 0, 2, 1, 2, -1, -1);
+
+ /* Bug with `upcase' translation table, from Nico Josuttis
+ <nico@bredex.de> */
+ test_should_match = 1;
+ test_case_fold ("[a-a]", "a");
+
+ printf ("\nFinished regression tests.\n");
+}
+
+
+
+/*
+Local variables:
+make-backup-files: t
+version-control: t
+trim-versions-without-asking: nil
+End:
+*/
diff --git a/gnu/lib/libregex/test/upcase.c b/gnu/lib/libregex/test/upcase.c
new file mode 100644
index 000000000000..5147b812aaae
--- /dev/null
+++ b/gnu/lib/libregex/test/upcase.c
@@ -0,0 +1,39 @@
+/* Indexed by a character, gives the upper case equivalent of the
+ character. */
+
+char upcase[0400] =
+ { 000, 001, 002, 003, 004, 005, 006, 007,
+ 010, 011, 012, 013, 014, 015, 016, 017,
+ 020, 021, 022, 023, 024, 025, 026, 027,
+ 030, 031, 032, 033, 034, 035, 036, 037,
+ 040, 041, 042, 043, 044, 045, 046, 047,
+ 050, 051, 052, 053, 054, 055, 056, 057,
+ 060, 061, 062, 063, 064, 065, 066, 067,
+ 070, 071, 072, 073, 074, 075, 076, 077,
+ 0100, 0101, 0102, 0103, 0104, 0105, 0106, 0107,
+ 0110, 0111, 0112, 0113, 0114, 0115, 0116, 0117,
+ 0120, 0121, 0122, 0123, 0124, 0125, 0126, 0127,
+ 0130, 0131, 0132, 0133, 0134, 0135, 0136, 0137,
+ 0140, 0101, 0102, 0103, 0104, 0105, 0106, 0107,
+ 0110, 0111, 0112, 0113, 0114, 0115, 0116, 0117,
+ 0120, 0121, 0122, 0123, 0124, 0125, 0126, 0127,
+ 0130, 0131, 0132, 0173, 0174, 0175, 0176, 0177,
+ 0200, 0201, 0202, 0203, 0204, 0205, 0206, 0207,
+ 0210, 0211, 0212, 0213, 0214, 0215, 0216, 0217,
+ 0220, 0221, 0222, 0223, 0224, 0225, 0226, 0227,
+ 0230, 0231, 0232, 0233, 0234, 0235, 0236, 0237,
+ 0240, 0241, 0242, 0243, 0244, 0245, 0246, 0247,
+ 0250, 0251, 0252, 0253, 0254, 0255, 0256, 0257,
+ 0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267,
+ 0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277,
+ 0300, 0301, 0302, 0303, 0304, 0305, 0306, 0307,
+ 0310, 0311, 0312, 0313, 0314, 0315, 0316, 0317,
+ 0320, 0321, 0322, 0323, 0324, 0325, 0326, 0327,
+ 0330, 0331, 0332, 0333, 0334, 0335, 0336, 0337,
+ 0340, 0341, 0342, 0343, 0344, 0345, 0346, 0347,
+ 0350, 0351, 0352, 0353, 0354, 0355, 0356, 0357,
+ 0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367,
+ 0370, 0371, 0372, 0373, 0374, 0375, 0376, 0377
+ };
+
+
diff --git a/gnu/lib/libregex/test/xmalloc.c b/gnu/lib/libregex/test/xmalloc.c
new file mode 100644
index 000000000000..88be1a668bd3
--- /dev/null
+++ b/gnu/lib/libregex/test/xmalloc.c
@@ -0,0 +1,21 @@
+#include <stdio.h>
+extern char *malloc ();
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+void *
+xmalloc (size)
+ unsigned size;
+{
+ char *new_mem = malloc (size);
+
+ if (new_mem == NULL)
+ {
+ fprintf (stderr, "xmalloc: request for %u bytes failed.\n", size);
+ abort ();
+ }
+
+ return new_mem;
+}