summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorderaadt <>1995-10-18 08:49:34 +0000
committerderaadt <>1995-10-18 08:49:34 +0000
commita4f79641824cbf9f60ca9d1168d1fcc46717a82a (patch)
tree3a9a60a6831189695ecfa7eb6904bce69aec0bcb /src
parent0527d29da443886d92e9a418180c5b25a5f8d270 (diff)
downloadopenbsd-a4f79641824cbf9f60ca9d1168d1fcc46717a82a.tar.gz
openbsd-a4f79641824cbf9f60ca9d1168d1fcc46717a82a.tar.bz2
openbsd-a4f79641824cbf9f60ca9d1168d1fcc46717a82a.zip
initial import of NetBSD tree
Diffstat (limited to 'src')
-rw-r--r--src/regress/lib/libc/Makefile16
-rw-r--r--src/regress/lib/libc/_setjmp/Makefile16
-rw-r--r--src/regress/lib/libc/arch/alpha/Makefile10
-rw-r--r--src/regress/lib/libc/arch/alpha/divremtest/Makefile29
-rw-r--r--src/regress/lib/libc/arch/alpha/divremtest/divremtest.c183
-rw-r--r--src/regress/lib/libc/arch/alpha/divremtest/mkcases.c63
-rw-r--r--src/regress/lib/libc/arch/alpha/divremtest/mktestcases.c67
-rw-r--r--src/regress/lib/libc/db/Makefile17
-rw-r--r--src/regress/lib/libc/db/README54
-rw-r--r--src/regress/lib/libc/db/dbtest.c672
-rw-r--r--src/regress/lib/libc/db/run.test699
-rw-r--r--src/regress/lib/libc/ieeefp/Makefile13
-rw-r--r--src/regress/lib/libc/ieeefp/except/Makefile12
-rw-r--r--src/regress/lib/libc/ieeefp/except/except.c87
-rw-r--r--src/regress/lib/libc/ieeefp/round/Makefile12
-rw-r--r--src/regress/lib/libc/ieeefp/round/round.c44
-rw-r--r--src/regress/lib/libc/regex/Makefile16
-rw-r--r--src/regress/lib/libc/regex/debug.c244
-rw-r--r--src/regress/lib/libc/regex/debug.ih16
-rw-r--r--src/regress/lib/libc/regex/main.c512
-rw-r--r--src/regress/lib/libc/regex/main.ih21
-rw-r--r--src/regress/lib/libc/regex/split.c318
-rw-r--r--src/regress/lib/libc/regex/tests477
-rw-r--r--src/regress/lib/libc/setjmp/Makefile16
-rw-r--r--src/regress/lib/libc/setjmp/jmptest.c134
-rw-r--r--src/regress/lib/libc/sigsetjmp/Makefile17
26 files changed, 3765 insertions, 0 deletions
diff --git a/src/regress/lib/libc/Makefile b/src/regress/lib/libc/Makefile
new file mode 100644
index 0000000000..7b65e2c1c5
--- /dev/null
+++ b/src/regress/lib/libc/Makefile
@@ -0,0 +1,16 @@
1# $NetBSD: Makefile,v 1.6 1995/04/24 05:52:15 cgd Exp $
2
3SUBDIR+= _setjmp db regex setjmp sigsetjmp
4.if (${MACHINE_ARCH} != "vax")
5SUBDIR+= ieeefp
6.endif
7
8.if exists(arch/${MACHINE_ARCH})
9SUBDIR+= arch/${MACHINE_ARCH}
10.endif
11
12regress: _SUBDIRUSE
13
14install:
15
16.include <bsd.subdir.mk>
diff --git a/src/regress/lib/libc/_setjmp/Makefile b/src/regress/lib/libc/_setjmp/Makefile
new file mode 100644
index 0000000000..c2b9dc1aae
--- /dev/null
+++ b/src/regress/lib/libc/_setjmp/Makefile
@@ -0,0 +1,16 @@
1# $NetBSD: Makefile,v 1.2 1995/04/20 22:38:44 cgd Exp $
2
3PROG= _setjmptest
4SRCS= jmptest.c
5NOMAN= noman, no way, man
6
7CFLAGS+= -DTEST_U_SETJMP
8
9.PATH: ${.CURDIR}/../setjmp
10
11install:
12
13regress: ${PROG}
14 ./${PROG}
15
16.include <bsd.prog.mk>
diff --git a/src/regress/lib/libc/arch/alpha/Makefile b/src/regress/lib/libc/arch/alpha/Makefile
new file mode 100644
index 0000000000..b79a82b0e2
--- /dev/null
+++ b/src/regress/lib/libc/arch/alpha/Makefile
@@ -0,0 +1,10 @@
1# $NetBSD: Makefile,v 1.1 1995/04/24 05:53:31 cgd Exp $
2
3# do nothing here; none of the tests here can be run automatically
4SUBDIR=
5
6regress: _SUBDIRUSE
7
8install:
9
10.include <bsd.subdir.mk>
diff --git a/src/regress/lib/libc/arch/alpha/divremtest/Makefile b/src/regress/lib/libc/arch/alpha/divremtest/Makefile
new file mode 100644
index 0000000000..bd3b12f537
--- /dev/null
+++ b/src/regress/lib/libc/arch/alpha/divremtest/Makefile
@@ -0,0 +1,29 @@
1# $NetBSD: Makefile,v 1.1 1995/04/24 05:53:34 cgd Exp $
2
3PROG= divremtest
4NOMAN=
5
6CLEANFILES+= mkcases cases.c mktestcases testcases
7
8divremtest.c: cases.c
9
10cases.c: mkcases
11 /bin/rm -f cases.c
12 mkcases > cases.c
13
14# a typical strategy to use this:
15# compile a NetBSD divremtest binary, an OSF/1 divremtest binary, and an
16# OSF/1 mktestcases binary. You then run mktestecases | divremtest -g
17# on an OSF/1 machine, and pipe the output to an rsh to a NetBSD machine
18# which then runs divremtest. You can test an infinite number of random
19# values that way; I like to put a 'dd' in, so I can see how much I've done.
20
21testcases: mktestcases divremtest
22 /bin/rm -f testcases
23 mktestcases | divremtest -g > testcases
24
25regress:
26 @echo THIS TEST CANNOT BE RUN AUTOMATICALLY.
27 @false
28
29.include <bsd.prog.mk>
diff --git a/src/regress/lib/libc/arch/alpha/divremtest/divremtest.c b/src/regress/lib/libc/arch/alpha/divremtest/divremtest.c
new file mode 100644
index 0000000000..fcf64c9384
--- /dev/null
+++ b/src/regress/lib/libc/arch/alpha/divremtest/divremtest.c
@@ -0,0 +1,183 @@
1/* $NetBSD: divremtest.c,v 1.1 1995/04/24 05:53:35 cgd Exp $ */
2
3/*
4 * Copyright (c) 1995 Christopher G. Demetriou
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by Christopher G. Demetriou
18 * for the NetBSD Project.
19 * 4. The name of the author may not be used to endorse or promote products
20 * derived from this software without specific prior written permission
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34#include <stdio.h>
35#include <unistd.h>
36#include <signal.h>
37
38void testfile();
39void usage();
40
41int generate;
42
43int
44main(argc, argv)
45 int argc;
46 char **argv;
47{
48 int c;
49
50 signal(SIGFPE, SIG_IGN);
51
52 while ((c = getopt(argc, argv, "g")) != -1)
53 switch (c) {
54 case 'g':
55 generate = 1;
56 break;
57
58 default:
59 usage();
60 break;
61 }
62
63 argc -= optind;
64 argv += optind;
65
66 if (argc == 0)
67 testfile();
68 else
69 for (; argc != 0; argc--, argv++) {
70 if (freopen(argv[0], "r", stdin) == NULL) {
71 fprintf(stderr,
72 "divremtest: couldn't open %s\n",
73 argv[0]);
74 exit(1);
75 }
76
77 testfile();
78 }
79
80 exit(0);
81}
82
83void
84testfile()
85{
86 union operand {
87 unsigned long input;
88 int op_int;
89 unsigned int op_u_int;
90 long op_long;
91 unsigned long op_u_long;
92 } op1, op2, divres, modres, divwant, modwant;
93 char opspec[6];
94 int encoded, i;
95
96 while (scanf("%6c %lx %lx %lx %lx\n", opspec, &op1.input,
97 &op2.input, &divwant.input, &modwant.input) != EOF) {
98
99 encoded = 0;
100
101 for (i = 0; i < 6; i += 2) {
102 int posval;
103
104 switch (opspec[i]) {
105 case '.':
106 posval = 0;
107 break;
108 case '-':
109 posval = 1;
110 break;
111 default:
112 fprintf(stderr,
113 "unknown signedness spec %c\n",
114 opspec[i]);
115 exit(1);
116 }
117 encoded |= posval << ((5 - i) * 4);
118 }
119
120 for (i = 1; i < 6; i += 2) {
121 int posval;
122
123 switch (opspec[i]) {
124 case 'i':
125 posval = 0;
126 break;
127 case 'l':
128 posval = 1;
129 break;
130 default:
131 fprintf(stderr, "unknown length spec %c\n",
132 opspec[i]);
133 exit(1);
134 }
135 encoded |= posval << ((5 - i) * 4);
136 }
137
138 /* KILL ME!!! */
139 switch (encoded) {
140
141#define TRY_IT(a, b, c) \
142 divres.a = op1.b / op2.c; \
143 modres.a = op1.b % op2.c; \
144 if (generate) { \
145 printf("%6s 0x%016lx 0x%016lx 0x%016lx 0x%016lx\n", \
146 opspec, op1.input, op2.input, \
147 divres.a, modres.a); \
148 } else { \
149 if ((divres.a != divwant.a) || \
150 (modres.a != modwant.a)) { \
151 fprintf(stderr, "%6s 0x%016lx 0x%016lx\n", \
152 opspec, op1.input, op2.input); \
153 fprintf(stderr, "FAILED:\n"); \
154 fprintf(stderr, \
155 "div:\twanted 0x%16lx, got 0x%16lx\n", \
156 divwant.a, divres.a); \
157 fprintf(stderr, \
158 "mod:\twanted 0x%16lx, got 0x%16lx\n", \
159 modwant.a, modres.a); \
160 \
161 exit(1); \
162 } \
163 }
164
165#include "cases.c"
166
167#undef TRY_IT
168
169 default:
170 fprintf(stderr,
171 "INTERNAL ERROR: unknown encoding %x\n", encoded);
172 exit(1);
173 }
174 }
175}
176
177void
178usage()
179{
180
181 fprintf(stderr, "usage: divremtest [-v] [testfile ...]\n");
182 exit(1);
183}
diff --git a/src/regress/lib/libc/arch/alpha/divremtest/mkcases.c b/src/regress/lib/libc/arch/alpha/divremtest/mkcases.c
new file mode 100644
index 0000000000..65ca17af4c
--- /dev/null
+++ b/src/regress/lib/libc/arch/alpha/divremtest/mkcases.c
@@ -0,0 +1,63 @@
1/* $NetBSD: mkcases.c,v 1.1 1995/04/24 05:53:36 cgd Exp $ */
2
3/*
4 * Copyright (c) 1995 Christopher G. Demetriou
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by Christopher G. Demetriou
18 * for the NetBSD Project.
19 * 4. The name of the author may not be used to endorse or promote products
20 * derived from this software without specific prior written permission
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34char *tab[4] = { "u_int", "int", "u_long", "long" };
35
36int
37main()
38{
39 int i;
40
41 for (i = 0; i < 64; i++) {
42 printf(
43" case 0x%d%d%d%d%d%d: /* %s <= %s op %s */\n",
44 (i >> 5) & 1,
45 (i >> 4) & 1,
46 (i >> 3) & 1,
47 (i >> 2) & 1,
48 (i >> 1) & 1,
49 (i >> 0) & 1,
50 tab[(i >> 4) & 0x3],
51 tab[(i >> 2) & 0x3],
52 tab[(i >> 0) & 0x3]);
53 printf(
54" TRY_IT(op_%s, op_%s, op_%s);\n",
55 tab[(i >> 4) & 0x3],
56 tab[(i >> 2) & 0x3],
57 tab[(i >> 0) & 0x3]);
58 printf(
59" break;\n\n");
60 }
61
62 exit(0);
63}
diff --git a/src/regress/lib/libc/arch/alpha/divremtest/mktestcases.c b/src/regress/lib/libc/arch/alpha/divremtest/mktestcases.c
new file mode 100644
index 0000000000..ef02d61d70
--- /dev/null
+++ b/src/regress/lib/libc/arch/alpha/divremtest/mktestcases.c
@@ -0,0 +1,67 @@
1/* $NetBSD: mktestcases.c,v 1.1 1995/04/24 05:53:37 cgd Exp $ */
2
3/*
4 * Copyright (c) 1995 Christopher G. Demetriou
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by Christopher G. Demetriou
18 * for the NetBSD Project.
19 * 4. The name of the author may not be used to endorse or promote products
20 * derived from this software without specific prior written permission
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34#include <stdio.h>
35
36int
37main()
38{
39 int i, j;
40 unsigned long n1, n2;
41
42 srandom(time(NULL));
43
44 for (i = 1; /* i < 10240 */ 1; i++) {
45 n1 = (unsigned)
46 (random() & ((random() & random()) | 0x80000000));
47 n1 <<= 32;
48 n1 |= (unsigned)(random() & random() & random());
49
50 n2 = (unsigned)
51 (random() & ((random() & random()) | 0x80000000));
52 n2 <<= 32;
53 n2 |= (unsigned)(random() & random() & random());
54
55 for (j = 0; j < 64; j++) {
56 char *tab[] = { ".i", ".l", "-i", "-l" };
57
58 printf("%s%s%s 0x%lx 0x%lx 0 0\n",
59 tab[(j >> 4) & 0x3],
60 tab[(j >> 2) & 0x3],
61 tab[(j >> 0) & 0x3],
62 n1, n2);
63 }
64 }
65
66 exit(0);
67}
diff --git a/src/regress/lib/libc/db/Makefile b/src/regress/lib/libc/db/Makefile
new file mode 100644
index 0000000000..5bf343bf64
--- /dev/null
+++ b/src/regress/lib/libc/db/Makefile
@@ -0,0 +1,17 @@
1# $NetBSD: Makefile,v 1.10 1995/04/20 22:39:11 cgd Exp $
2# @(#)Makefile 8.1 (Berkeley) 6/4/93
3
4PROG= dbtest
5
6# add -DSTATISTICS to CFLAGS to get usage statistics. Note that
7# for this to work, libc must be compiled with -DSTATISTICS as well
8CFLAGS= -g -D__DBINTERFACE_PRIVATE -DDEBUG
9NOMAN= noman
10CLEANFILES+= t1 t2 t3
11
12install:
13
14regress:
15 sh ${.CURDIR}/run.test
16
17.include <bsd.prog.mk>
diff --git a/src/regress/lib/libc/db/README b/src/regress/lib/libc/db/README
new file mode 100644
index 0000000000..3b290b09d8
--- /dev/null
+++ b/src/regress/lib/libc/db/README
@@ -0,0 +1,54 @@
1# $NetBSD: README,v 1.4 1995/04/20 22:39:18 cgd Exp $
2# @(#)README 8.4 (Berkeley) 6/20/94
3
4To run the tests, enter "make regress".
5
6Fairly large files (the command files) are built in this directory during
7the test runs, and even larger files (the database files) are created in
8"/var/tmp". If the latter directory doesn't exist, set the environmental
9variable TMPDIR to a directory where the files can be built.
10
11=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
12The script file consists of lines with a initial character which is
13the "command" for that line. Legal characters are as follows:
14
15c: compare a record
16 + must be followed by [kK][dD]; the data value in the database
17 associated with the specified key is compared to the specified
18 data value.
19e: echo a string
20 + writes out the rest of the line into the output file; if the
21 last character is not a carriage-return, a newline is appended.
22g: do a get command
23 + must be followed by [kK]
24 + writes out the retrieved data DBT.
25p: do a put command
26 + must be followed by [kK][dD]
27r: do a del command
28 + must be followed by [kK]
29s: do a seq command
30 + writes out the retrieved data DBT.
31f: set the flags for the next command
32 + no value zero's the flags
33D [file]: data file
34 + set the current data value to the contents of the file
35d [data]:
36 + set the current key value to the contents of the line.
37K [file]: key file
38 + set the current key value to the contents of the file
39k [data]:
40 + set the current key value to the contents of the line.
41o [r]: dump [reverse]
42 + dump the database out, if 'r' is set, in reverse order.
43
44Options to dbtest are as follows:
45
46 -f: Use the file argument as the database file.
47 -i: Use the rest of the argument to set elements in the info
48 structure. If the type is btree, then "-i cachesize=10240"
49 will set BTREEINFO.cachesize to 10240.
50 -o: The rest of the argument is the output file instead of
51 using stdout.
52
53Dbtest requires two arguments, the type of access "hash", "recno" or
54"btree", and the script name.
diff --git a/src/regress/lib/libc/db/dbtest.c b/src/regress/lib/libc/db/dbtest.c
new file mode 100644
index 0000000000..1fcf09af97
--- /dev/null
+++ b/src/regress/lib/libc/db/dbtest.c
@@ -0,0 +1,672 @@
1/* $NetBSD: dbtest.c,v 1.7 1995/04/20 22:39:22 cgd Exp $ */
2
3/*-
4 * Copyright (c) 1992, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by the University of
18 * California, Berkeley and its contributors.
19 * 4. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35
36#ifndef lint
37static char copyright[] =
38"@(#) Copyright (c) 1992, 1993\n\
39 The Regents of the University of California. All rights reserved.\n";
40#endif /* not lint */
41
42#ifndef lint
43#if 0
44static char sccsid[] = "@(#)dbtest.c 8.8 (Berkeley) 2/21/94";
45#else
46static char rcsid[] = "$NetBSD: dbtest.c,v 1.7 1995/04/20 22:39:22 cgd Exp $";
47#endif
48#endif /* not lint */
49
50#include <sys/param.h>
51#include <sys/stat.h>
52
53#include <ctype.h>
54#include <errno.h>
55#include <fcntl.h>
56#include <limits.h>
57#include <stdio.h>
58#include <stdlib.h>
59#include <string.h>
60#include <unistd.h>
61
62#include <db.h>
63
64enum S { COMMAND, COMPARE, GET, PUT, REMOVE, SEQ, SEQFLAG, KEY, DATA };
65
66void compare __P((DBT *, DBT *));
67DBTYPE dbtype __P((char *));
68void dump __P((DB *, int));
69void err __P((const char *, ...));
70void get __P((DB *, DBT *));
71void getdata __P((DB *, DBT *, DBT *));
72void put __P((DB *, DBT *, DBT *));
73void rem __P((DB *, DBT *));
74void *rfile __P((char *, size_t *));
75void seq __P((DB *, DBT *));
76u_int setflags __P((char *));
77void *setinfo __P((DBTYPE, char *));
78void usage __P((void));
79void *xmalloc __P((char *, size_t));
80
81DBTYPE type;
82void *infop;
83u_long lineno;
84u_int flags;
85int ofd = STDOUT_FILENO;
86
87DB *XXdbp; /* Global for gdb. */
88
89int
90main(argc, argv)
91 int argc;
92 char *argv[];
93{
94 extern int optind;
95 extern char *optarg;
96 enum S command, state;
97 DB *dbp;
98 DBT data, key, keydata;
99 size_t len;
100 int ch, oflags;
101 char *fname, *infoarg, *p, buf[8 * 1024];
102
103 infoarg = NULL;
104 fname = NULL;
105 oflags = O_CREAT | O_RDWR;
106 while ((ch = getopt(argc, argv, "f:i:lo:")) != EOF)
107 switch(ch) {
108 case 'f':
109 fname = optarg;
110 break;
111 case 'i':
112 infoarg = optarg;
113 break;
114 case 'l':
115 oflags |= DB_LOCK;
116 break;
117 case 'o':
118 if ((ofd = open(optarg,
119 O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0)
120 err("%s: %s", optarg, strerror(errno));
121 break;
122 case '?':
123 default:
124 usage();
125 }
126 argc -= optind;
127 argv += optind;
128
129 if (argc != 2)
130 usage();
131
132 /* Set the type. */
133 type = dbtype(*argv++);
134
135 /* Open the descriptor file. */
136 if (freopen(*argv, "r", stdin) == NULL)
137 err("%s: %s", *argv, strerror(errno));
138
139 /* Set up the db structure as necessary. */
140 if (infoarg == NULL)
141 infop = NULL;
142 else
143 for (p = strtok(infoarg, ",\t "); p != NULL;
144 p = strtok(0, ",\t "))
145 if (*p != '\0')
146 infop = setinfo(type, p);
147
148 /* Open the DB. */
149 if (fname == NULL) {
150 p = getenv("TMPDIR");
151 if (p == NULL)
152 p = "/var/tmp";
153 (void)sprintf(buf, "%s/__dbtest", p);
154 fname = buf;
155 (void)unlink(buf);
156 }
157 if ((dbp = dbopen(fname,
158 oflags, S_IRUSR | S_IWUSR, type, infop)) == NULL)
159 err("dbopen: %s", strerror(errno));
160 XXdbp = dbp;
161
162 state = COMMAND;
163 for (lineno = 1;
164 (p = fgets(buf, sizeof(buf), stdin)) != NULL; ++lineno) {
165 len = strlen(buf);
166 switch(*p) {
167 case 'c': /* compare */
168 if (state != COMMAND)
169 err("line %lu: not expecting command", lineno);
170 state = KEY;
171 command = COMPARE;
172 break;
173 case 'e': /* echo */
174 if (state != COMMAND)
175 err("line %lu: not expecting command", lineno);
176 /* Don't display the newline, if CR at EOL. */
177 if (p[len - 2] == '\r')
178 --len;
179 if (write(ofd, p + 1, len - 1) != len - 1)
180 err("write: %s", strerror(errno));
181 break;
182 case 'g': /* get */
183 if (state != COMMAND)
184 err("line %lu: not expecting command", lineno);
185 state = KEY;
186 command = GET;
187 break;
188 case 'p': /* put */
189 if (state != COMMAND)
190 err("line %lu: not expecting command", lineno);
191 state = KEY;
192 command = PUT;
193 break;
194 case 'r': /* remove */
195 if (state != COMMAND)
196 err("line %lu: not expecting command", lineno);
197 state = KEY;
198 command = REMOVE;
199 break;
200 case 's': /* seq */
201 if (state != COMMAND)
202 err("line %lu: not expecting command", lineno);
203 if (flags == R_CURSOR) {
204 state = KEY;
205 command = SEQ;
206 } else
207 seq(dbp, &key);
208 break;
209 case 'f':
210 flags = setflags(p + 1);
211 break;
212 case 'D': /* data file */
213 if (state != DATA)
214 err("line %lu: not expecting data", lineno);
215 data.data = rfile(p + 1, &data.size);
216 goto ldata;
217 case 'd': /* data */
218 if (state != DATA)
219 err("line %lu: not expecting data", lineno);
220 data.data = xmalloc(p + 1, len - 1);
221 data.size = len - 1;
222ldata: switch(command) {
223 case COMPARE:
224 compare(&keydata, &data);
225 break;
226 case PUT:
227 put(dbp, &key, &data);
228 break;
229 default:
230 err("line %lu: command doesn't take data",
231 lineno);
232 }
233 if (type != DB_RECNO)
234 free(key.data);
235 free(data.data);
236 state = COMMAND;
237 break;
238 case 'K': /* key file */
239 if (state != KEY)
240 err("line %lu: not expecting a key", lineno);
241 if (type == DB_RECNO)
242 err("line %lu: 'K' not available for recno",
243 lineno);
244 key.data = rfile(p + 1, &key.size);
245 goto lkey;
246 case 'k': /* key */
247 if (state != KEY)
248 err("line %lu: not expecting a key", lineno);
249 if (type == DB_RECNO) {
250 static recno_t recno;
251 recno = atoi(p + 1);
252 key.data = &recno;
253 key.size = sizeof(recno);
254 } else {
255 key.data = xmalloc(p + 1, len - 1);
256 key.size = len - 1;
257 }
258lkey: switch(command) {
259 case COMPARE:
260 getdata(dbp, &key, &keydata);
261 state = DATA;
262 break;
263 case GET:
264 get(dbp, &key);
265 if (type != DB_RECNO)
266 free(key.data);
267 state = COMMAND;
268 break;
269 case PUT:
270 state = DATA;
271 break;
272 case REMOVE:
273 rem(dbp, &key);
274 if (type != DB_RECNO)
275 free(key.data);
276 state = COMMAND;
277 break;
278 case SEQ:
279 seq(dbp, &key);
280 if (type != DB_RECNO)
281 free(key.data);
282 state = COMMAND;
283 break;
284 default:
285 err("line %lu: command doesn't take a key",
286 lineno);
287 }
288 break;
289 case 'o':
290 dump(dbp, p[1] == 'r');
291 break;
292 default:
293 err("line %lu: %s: unknown command character",
294 p, lineno);
295 }
296 }
297#ifdef STATISTICS
298 if (type == DB_BTREE)
299 __bt_stat(dbp);
300#endif
301 if (dbp->close(dbp))
302 err("db->close: %s", strerror(errno));
303 (void)close(ofd);
304 exit(0);
305}
306
307#define NOOVERWRITE "put failed, would overwrite key\n"
308#define NOSUCHKEY "get failed, no such key\n"
309
310void
311compare(db1, db2)
312 DBT *db1, *db2;
313{
314 register size_t len;
315 register u_char *p1, *p2;
316
317 if (db1->size != db2->size)
318 printf("compare failed: key->data len %lu != data len %lu\n",
319 db1->size, db2->size);
320
321 len = MIN(db1->size, db2->size);
322 for (p1 = db1->data, p2 = db2->data; len--;)
323 if (*p1++ != *p2++) {
324 printf("compare failed at offset %d\n",
325 p1 - (u_char *)db1->data);
326 break;
327 }
328}
329
330void
331get(dbp, kp)
332 DB *dbp;
333 DBT *kp;
334{
335 DBT data;
336
337 switch(dbp->get(dbp, kp, &data, flags)) {
338 case 0:
339 (void)write(ofd, data.data, data.size);
340 break;
341 case -1:
342 err("line %lu: get: %s", lineno, strerror(errno));
343 /* NOTREACHED */
344 case 1:
345 (void)write(ofd, NOSUCHKEY, sizeof(NOSUCHKEY) - 1);
346 (void)fprintf(stderr, "%d: %.*s: %s\n",
347 lineno, kp->size, kp->data, NOSUCHKEY);
348 break;
349 }
350}
351
352void
353getdata(dbp, kp, dp)
354 DB *dbp;
355 DBT *kp, *dp;
356{
357 switch(dbp->get(dbp, kp, dp, flags)) {
358 case 0:
359 return;
360 case -1:
361 err("line %lu: getdata: %s", lineno, strerror(errno));
362 /* NOTREACHED */
363 case 1:
364 err("line %lu: get failed, no such key", lineno);
365 /* NOTREACHED */
366 }
367}
368
369void
370put(dbp, kp, dp)
371 DB *dbp;
372 DBT *kp, *dp;
373{
374 switch(dbp->put(dbp, kp, dp, flags)) {
375 case 0:
376 break;
377 case -1:
378 err("line %lu: put: %s", lineno, strerror(errno));
379 /* NOTREACHED */
380 case 1:
381 (void)write(ofd, NOOVERWRITE, sizeof(NOOVERWRITE) - 1);
382 break;
383 }
384}
385
386void
387rem(dbp, kp)
388 DB *dbp;
389 DBT *kp;
390{
391 switch(dbp->del(dbp, kp, flags)) {
392 case 0:
393 break;
394 case -1:
395 err("line %lu: get: %s", lineno, strerror(errno));
396 /* NOTREACHED */
397 case 1:
398 (void)write(ofd, NOSUCHKEY, sizeof(NOSUCHKEY) - 1);
399 break;
400 }
401}
402
403void
404seq(dbp, kp)
405 DB *dbp;
406 DBT *kp;
407{
408 DBT data;
409
410 switch(dbp->seq(dbp, kp, &data, flags)) {
411 case 0:
412 (void)write(ofd, data.data, data.size);
413 break;
414 case -1:
415 err("line %lu: seq: %s", lineno, strerror(errno));
416 /* NOTREACHED */
417 case 1:
418 (void)write(ofd, NOSUCHKEY, sizeof(NOSUCHKEY) - 1);
419 break;
420 }
421}
422
423void
424dump(dbp, rev)
425 DB *dbp;
426 int rev;
427{
428 DBT key, data;
429 int flags, nflags;
430
431 if (rev) {
432 flags = R_LAST;
433 nflags = R_PREV;
434 } else {
435 flags = R_FIRST;
436 nflags = R_NEXT;
437 }
438 for (;; flags = nflags)
439 switch(dbp->seq(dbp, &key, &data, flags)) {
440 case 0:
441 (void)write(ofd, data.data, data.size);
442 break;
443 case 1:
444 goto done;
445 case -1:
446 err("line %lu: (dump) seq: %s",
447 lineno, strerror(errno));
448 /* NOTREACHED */
449 }
450done: return;
451}
452
453u_int
454setflags(s)
455 char *s;
456{
457 char *p, *index();
458
459 for (; isspace(*s); ++s);
460 if (*s == '\n')
461 return (0);
462 if ((p = index(s, '\n')) != NULL)
463 *p = '\0';
464 if (!strcmp(s, "R_CURSOR"))
465 return (R_CURSOR);
466 if (!strcmp(s, "R_FIRST"))
467 return (R_FIRST);
468 if (!strcmp(s, "R_IAFTER"))
469 return (R_IAFTER);
470 if (!strcmp(s, "R_IBEFORE"))
471 return (R_IBEFORE);
472 if (!strcmp(s, "R_LAST"))
473 return (R_LAST);
474 if (!strcmp(s, "R_NEXT"))
475 return (R_NEXT);
476 if (!strcmp(s, "R_NOOVERWRITE"))
477 return (R_NOOVERWRITE);
478 if (!strcmp(s, "R_PREV"))
479 return (R_PREV);
480 if (!strcmp(s, "R_SETCURSOR"))
481 return (R_SETCURSOR);
482 err("line %lu: %s: unknown flag", lineno, s);
483 /* NOTREACHED */
484}
485
486DBTYPE
487dbtype(s)
488 char *s;
489{
490 if (!strcmp(s, "btree"))
491 return (DB_BTREE);
492 if (!strcmp(s, "hash"))
493 return (DB_HASH);
494 if (!strcmp(s, "recno"))
495 return (DB_RECNO);
496 err("%s: unknown type (use btree, hash or recno)", s);
497 /* NOTREACHED */
498}
499
500void *
501setinfo(type, s)
502 DBTYPE type;
503 char *s;
504{
505 static BTREEINFO ib;
506 static HASHINFO ih;
507 static RECNOINFO rh;
508 char *eq, *index();
509
510 if ((eq = index(s, '=')) == NULL)
511 err("%s: illegal structure set statement", s);
512 *eq++ = '\0';
513 if (!isdigit(*eq))
514 err("%s: structure set statement must be a number", s);
515
516 switch(type) {
517 case DB_BTREE:
518 if (!strcmp("flags", s)) {
519 ib.flags = atoi(eq);
520 return (&ib);
521 }
522 if (!strcmp("cachesize", s)) {
523 ib.cachesize = atoi(eq);
524 return (&ib);
525 }
526 if (!strcmp("maxkeypage", s)) {
527 ib.maxkeypage = atoi(eq);
528 return (&ib);
529 }
530 if (!strcmp("minkeypage", s)) {
531 ib.minkeypage = atoi(eq);
532 return (&ib);
533 }
534 if (!strcmp("lorder", s)) {
535 ib.lorder = atoi(eq);
536 return (&ib);
537 }
538 if (!strcmp("psize", s)) {
539 ib.psize = atoi(eq);
540 return (&ib);
541 }
542 break;
543 case DB_HASH:
544 if (!strcmp("bsize", s)) {
545 ih.bsize = atoi(eq);
546 return (&ih);
547 }
548 if (!strcmp("ffactor", s)) {
549 ih.ffactor = atoi(eq);
550 return (&ih);
551 }
552 if (!strcmp("nelem", s)) {
553 ih.nelem = atoi(eq);
554 return (&ih);
555 }
556 if (!strcmp("cachesize", s)) {
557 ih.cachesize = atoi(eq);
558 return (&ih);
559 }
560 if (!strcmp("lorder", s)) {
561 ih.lorder = atoi(eq);
562 return (&ih);
563 }
564 break;
565 case DB_RECNO:
566 if (!strcmp("flags", s)) {
567 rh.flags = atoi(eq);
568 return (&rh);
569 }
570 if (!strcmp("cachesize", s)) {
571 rh.cachesize = atoi(eq);
572 return (&rh);
573 }
574 if (!strcmp("lorder", s)) {
575 rh.lorder = atoi(eq);
576 return (&rh);
577 }
578 if (!strcmp("reclen", s)) {
579 rh.reclen = atoi(eq);
580 return (&rh);
581 }
582 if (!strcmp("bval", s)) {
583 rh.bval = atoi(eq);
584 return (&rh);
585 }
586 if (!strcmp("psize", s)) {
587 rh.psize = atoi(eq);
588 return (&rh);
589 }
590 break;
591 }
592 err("%s: unknown structure value", s);
593 /* NOTREACHED */
594}
595
596void *
597rfile(name, lenp)
598 char *name;
599 size_t *lenp;
600{
601 struct stat sb;
602 void *p;
603 int fd;
604 char *np, *index();
605
606 for (; isspace(*name); ++name);
607 if ((np = index(name, '\n')) != NULL)
608 *np = '\0';
609 if ((fd = open(name, O_RDONLY, 0)) < 0 ||
610 fstat(fd, &sb))
611 err("%s: %s\n", name, strerror(errno));
612#ifdef NOT_PORTABLE
613 if (sb.st_size > (off_t)SIZE_T_MAX)
614 err("%s: %s\n", name, strerror(E2BIG));
615#endif
616 if ((p = (void *)malloc((u_int)sb.st_size)) == NULL)
617 err("%s", strerror(errno));
618 (void)read(fd, p, (int)sb.st_size);
619 *lenp = sb.st_size;
620 (void)close(fd);
621 return (p);
622}
623
624void *
625xmalloc(text, len)
626 char *text;
627 size_t len;
628{
629 void *p;
630
631 if ((p = (void *)malloc(len)) == NULL)
632 err("%s", strerror(errno));
633 memmove(p, text, len);
634 return (p);
635}
636
637void
638usage()
639{
640 (void)fprintf(stderr,
641 "usage: dbtest [-l] [-f file] [-i info] [-o file] type script\n");
642 exit(1);
643}
644
645#if __STDC__
646#include <stdarg.h>
647#else
648#include <varargs.h>
649#endif
650
651void
652#if __STDC__
653err(const char *fmt, ...)
654#else
655err(fmt, va_alist)
656 char *fmt;
657 va_dcl
658#endif
659{
660 va_list ap;
661#if __STDC__
662 va_start(ap, fmt);
663#else
664 va_start(ap);
665#endif
666 (void)fprintf(stderr, "dbtest: ");
667 (void)vfprintf(stderr, fmt, ap);
668 va_end(ap);
669 (void)fprintf(stderr, "\n");
670 exit(1);
671 /* NOTREACHED */
672}
diff --git a/src/regress/lib/libc/db/run.test b/src/regress/lib/libc/db/run.test
new file mode 100644
index 0000000000..4073310a31
--- /dev/null
+++ b/src/regress/lib/libc/db/run.test
@@ -0,0 +1,699 @@
1#!/bin/sh -
2# $NetBSD: run.test,v 1.7 1995/04/20 22:39:27 cgd Exp $
3#
4# @(#)run.test 8.8 (Berkeley) 6/16/94
5#
6
7# db regression tests
8main()
9{
10
11DICT=/usr/share/dict/web2
12PROG=./dbtest
13TMP1=t1
14TMP2=t2
15TMP3=t3
16
17 if [ $# -eq 0 ]; then
18 for t in 1 2 3 4 5 6 7 8 9 10 11 12 13 20; do
19 test$t
20 done
21 else
22 while [ $# -gt 0 ]
23 do case "$1" in
24 test*)
25 $1;;
26 [0-9]*)
27 test$1;;
28 btree)
29 for t in 1 2 3 7 8 9 10 12 13; do
30 test$t
31 done;;
32 hash)
33 for t in 1 2 3 8 13 20; do
34 test$t
35 done;;
36 recno)
37 for t in 1 2 3 4 5 6 7 10 11; do
38 test$t
39 done;;
40 *)
41 echo "run.test: unknown test $1"
42 echo "usage: run.test test# | type"
43 exit 1
44 esac
45 shift
46 done
47 fi
48 rm -f $TMP1 $TMP2 $TMP3
49 exit 0
50}
51
52# Take the first hundred entries in the dictionary, and make them
53# be key/data pairs.
54test1()
55{
56 echo "Test 1: btree, hash: small key, small data pairs"
57 sed 200q $DICT > $TMP1
58 for type in btree hash; do
59 rm -f $TMP2 $TMP3
60 for i in `sed 200q $DICT`; do
61 echo p
62 echo k$i
63 echo d$i
64 echo g
65 echo k$i
66 done > $TMP2
67 $PROG -o $TMP3 $type $TMP2
68 if (cmp -s $TMP1 $TMP3) ; then :
69 else
70 echo "test1: type $type: failed"
71 exit 1
72 fi
73 done
74 echo "Test 1: recno: small key, small data pairs"
75 rm -f $TMP2 $TMP3
76 sed 200q $DICT |
77 awk '{
78 ++i;
79 printf("p\nk%d\nd%s\ng\nk%d\n", i, $0, i);
80 }' > $TMP2
81 $PROG -o $TMP3 recno $TMP2
82 if (cmp -s $TMP1 $TMP3) ; then :
83 else
84 echo "test1: type recno: failed"
85 exit 1
86 fi
87}
88
89# Take the first 200 entries in the dictionary, and give them
90# each a medium size data entry.
91test2()
92{
93 echo "Test 2: btree, hash: small key, medium data pairs"
94 mdata=abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz
95 echo $mdata |
96 awk '{ for (i = 1; i < 201; ++i) print $0 }' > $TMP1
97 for type in hash btree; do
98 rm -f $TMP2 $TMP3
99 for i in `sed 200q $DICT`; do
100 echo p
101 echo k$i
102 echo d$mdata
103 echo g
104 echo k$i
105 done > $TMP2
106 $PROG -o $TMP3 $type $TMP2
107 if (cmp -s $TMP1 $TMP3) ; then :
108 else
109 echo "test2: type $type: failed"
110 exit 1
111 fi
112 done
113 echo "Test 2: recno: small key, medium data pairs"
114 rm -f $TMP2 $TMP3
115 echo $mdata |
116 awk '{ for (i = 1; i < 201; ++i)
117 printf("p\nk%d\nd%s\ng\nk%d\n", i, $0, i);
118 }' > $TMP2
119 $PROG -o $TMP3 recno $TMP2
120 if (cmp -s $TMP1 $TMP3) ; then :
121 else
122 echo "test2: type recno: failed"
123 exit 1
124 fi
125}
126
127# Insert the programs in /bin with their paths as their keys.
128test3()
129{
130 echo "Test 3: hash: small key, big data pairs"
131 rm -f $TMP1
132 (find /bin -type f -print | xargs cat) > $TMP1
133 for type in hash; do
134 rm -f $TMP2 $TMP3
135 for i in `find /bin -type f -print`; do
136 echo p
137 echo k$i
138 echo D$i
139 echo g
140 echo k$i
141 done > $TMP2
142 $PROG -o $TMP3 $type $TMP2
143 if (cmp -s $TMP1 $TMP3) ; then :
144 else
145 echo "test3: $type: failed"
146 exit 1
147 fi
148 done
149 echo "Test 3: btree: small key, big data pairs"
150 for psize in 512 16384 65536; do
151 echo " page size $psize"
152 for type in btree; do
153 rm -f $TMP2 $TMP3
154 for i in `find /bin -type f -print`; do
155 echo p
156 echo k$i
157 echo D$i
158 echo g
159 echo k$i
160 done > $TMP2
161 $PROG -i psize=$psize -o $TMP3 $type $TMP2
162 if (cmp -s $TMP1 $TMP3) ; then :
163 else
164 echo "test3: $type: page size $psize: failed"
165 exit 1
166 fi
167 done
168 done
169 echo "Test 3: recno: big data pairs"
170 rm -f $TMP2 $TMP3
171 find /bin -type f -print |
172 awk '{
173 ++i;
174 printf("p\nk%d\nD%s\ng\nk%d\n", i, $0, i);
175 }' > $TMP2
176 for psize in 512 16384 65536; do
177 echo " page size $psize"
178 $PROG -i psize=$psize -o $TMP3 recno $TMP2
179 if (cmp -s $TMP1 $TMP3) ; then :
180 else
181 echo "test3: recno: page size $psize: failed"
182 exit 1
183 fi
184 done
185}
186
187# Do random recno entries.
188test4()
189{
190 echo "Test 4: recno: random entries"
191 echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" |
192 awk '{
193 for (i = 37; i <= 37 + 88 * 17; i += 17) {
194 if (i % 41)
195 s = substr($0, 1, i % 41);
196 else
197 s = substr($0, 1);
198 printf("input key %d: %s\n", i, s);
199 }
200 for (i = 1; i <= 15; ++i) {
201 if (i % 41)
202 s = substr($0, 1, i % 41);
203 else
204 s = substr($0, 1);
205 printf("input key %d: %s\n", i, s);
206 }
207 for (i = 19234; i <= 19234 + 61 * 27; i += 27) {
208 if (i % 41)
209 s = substr($0, 1, i % 41);
210 else
211 s = substr($0, 1);
212 printf("input key %d: %s\n", i, s);
213 }
214 exit
215 }' > $TMP1
216 rm -f $TMP2 $TMP3
217 cat $TMP1 |
218 awk 'BEGIN {
219 i = 37;
220 incr = 17;
221 }
222 {
223 printf("p\nk%d\nd%s\n", i, $0);
224 if (i == 19234 + 61 * 27)
225 exit;
226 if (i == 37 + 88 * 17) {
227 i = 1;
228 incr = 1;
229 } else if (i == 15) {
230 i = 19234;
231 incr = 27;
232 } else
233 i += incr;
234 }
235 END {
236 for (i = 37; i <= 37 + 88 * 17; i += 17)
237 printf("g\nk%d\n", i);
238 for (i = 1; i <= 15; ++i)
239 printf("g\nk%d\n", i);
240 for (i = 19234; i <= 19234 + 61 * 27; i += 27)
241 printf("g\nk%d\n", i);
242 }' > $TMP2
243 $PROG -o $TMP3 recno $TMP2
244 if (cmp -s $TMP1 $TMP3) ; then :
245 else
246 echo "test4: type recno: failed"
247 exit 1
248 fi
249}
250
251# Do reverse order recno entries.
252test5()
253{
254 echo "Test 5: recno: reverse order entries"
255 echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" |
256 awk ' {
257 for (i = 1500; i; --i) {
258 if (i % 34)
259 s = substr($0, 1, i % 34);
260 else
261 s = substr($0, 1);
262 printf("input key %d: %s\n", i, s);
263 }
264 exit;
265 }' > $TMP1
266 rm -f $TMP2 $TMP3
267 cat $TMP1 |
268 awk 'BEGIN {
269 i = 1500;
270 }
271 {
272 printf("p\nk%d\nd%s\n", i, $0);
273 --i;
274 }
275 END {
276 for (i = 1500; i; --i)
277 printf("g\nk%d\n", i);
278 }' > $TMP2
279 $PROG -o $TMP3 recno $TMP2
280 if (cmp -s $TMP1 $TMP3) ; then :
281 else
282 echo "test5: type recno: failed"
283 exit 1
284 fi
285}
286
287# Do alternating order recno entries.
288test6()
289{
290 echo "Test 6: recno: alternating order entries"
291 echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" |
292 awk ' {
293 for (i = 1; i < 1200; i += 2) {
294 if (i % 34)
295 s = substr($0, 1, i % 34);
296 else
297 s = substr($0, 1);
298 printf("input key %d: %s\n", i, s);
299 }
300 for (i = 2; i < 1200; i += 2) {
301 if (i % 34)
302 s = substr($0, 1, i % 34);
303 else
304 s = substr($0, 1);
305 printf("input key %d: %s\n", i, s);
306 }
307 exit;
308 }' > $TMP1
309 rm -f $TMP2 $TMP3
310 cat $TMP1 |
311 awk 'BEGIN {
312 i = 1;
313 even = 0;
314 }
315 {
316 printf("p\nk%d\nd%s\n", i, $0);
317 i += 2;
318 if (i >= 1200) {
319 if (even == 1)
320 exit;
321 even = 1;
322 i = 2;
323 }
324 }
325 END {
326 for (i = 1; i < 1200; ++i)
327 printf("g\nk%d\n", i);
328 }' > $TMP2
329 $PROG -o $TMP3 recno $TMP2
330 sort -o $TMP1 $TMP1
331 sort -o $TMP3 $TMP3
332 if (cmp -s $TMP1 $TMP3) ; then :
333 else
334 echo "test6: type recno: failed"
335 exit 1
336 fi
337}
338
339# Delete cursor record
340test7()
341{
342 echo "Test 7: btree, recno: delete cursor record"
343 echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" |
344 awk '{
345 for (i = 1; i <= 120; ++i)
346 printf("%05d: input key %d: %s\n", i, i, $0);
347 printf("%05d: input key %d: %s\n", 120, 120, $0);
348 printf("get failed, no such key\n");
349 printf("%05d: input key %d: %s\n", 1, 1, $0);
350 printf("%05d: input key %d: %s\n", 2, 2, $0);
351 exit;
352 }' > $TMP1
353 rm -f $TMP2 $TMP3
354
355 for type in btree recno; do
356 cat $TMP1 |
357 awk '{
358 if (i == 120)
359 exit;
360 printf("p\nk%d\nd%s\n", ++i, $0);
361 }
362 END {
363 printf("fR_NEXT\n");
364 for (i = 1; i <= 120; ++i)
365 printf("s\n");
366 printf("fR_CURSOR\ns\nk120\n");
367 printf("r\nk120\n");
368 printf("fR_NEXT\ns\n");
369 printf("fR_CURSOR\ns\nk1\n");
370 printf("r\nk1\n");
371 printf("fR_FIRST\ns\n");
372 }' > $TMP2
373 $PROG -o $TMP3 recno $TMP2
374 if (cmp -s $TMP1 $TMP3) ; then :
375 else
376 echo "test7: type $type: failed"
377 exit 1
378 fi
379 done
380}
381
382# Make sure that overflow pages are reused.
383test8()
384{
385 echo "Test 8: btree, hash: repeated small key, big data pairs"
386 rm -f $TMP1
387 echo "" |
388 awk 'BEGIN {
389 for (i = 1; i <= 10; ++i) {
390 printf("p\nkkey1\nD/bin/sh\n");
391 printf("p\nkkey2\nD/bin/csh\n");
392 if (i % 8 == 0) {
393 printf("c\nkkey2\nD/bin/csh\n");
394 printf("c\nkkey1\nD/bin/sh\n");
395 printf("e\t%d of 10 (comparison)\n", i);
396 } else
397 printf("e\t%d of 10 \n", i);
398 printf("r\nkkey1\nr\nkkey2\n");
399 }
400 printf("e\n");
401 printf("eend of test8 run\n");
402 }' > $TMP1
403 $PROG btree $TMP1
404# $PROG hash $TMP1
405 # No explicit test for success.
406}
407
408# Test btree duplicate keys
409test9()
410{
411 echo "Test 9: btree: duplicate keys"
412 echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" |
413 awk '{
414 for (i = 1; i <= 543; ++i)
415 printf("%05d: input key %d: %s\n", i, i, $0);
416 exit;
417 }' > $TMP1
418 rm -f $TMP2 $TMP3
419
420 for type in btree; do
421 cat $TMP1 |
422 awk '{
423 if (i++ % 2)
424 printf("p\nkduplicatekey\nd%s\n", $0);
425 else
426 printf("p\nkunique%dkey\nd%s\n", i, $0);
427 }
428 END {
429 printf("o\n");
430 }' > $TMP2
431 $PROG -iflags=1 -o $TMP3 $type $TMP2
432 sort -o $TMP3 $TMP3
433 if (cmp -s $TMP1 $TMP3) ; then :
434 else
435 echo "test9: type $type: failed"
436 exit 1
437 fi
438 done
439}
440
441# Test use of cursor flags without initialization
442test10()
443{
444 echo "Test 10: btree, recno: test cursor flag use"
445 echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" |
446 awk '{
447 for (i = 1; i <= 20; ++i)
448 printf("%05d: input key %d: %s\n", i, i, $0);
449 exit;
450 }' > $TMP1
451 rm -f $TMP2 $TMP3
452
453 # Test that R_CURSOR doesn't succeed before cursor initialized
454 for type in btree recno; do
455 cat $TMP1 |
456 awk '{
457 if (i == 10)
458 exit;
459 printf("p\nk%d\nd%s\n", ++i, $0);
460 }
461 END {
462 printf("fR_CURSOR\nr\nk1\n");
463 printf("eR_CURSOR SHOULD HAVE FAILED\n");
464 }' > $TMP2
465 $PROG -o $TMP3 $type $TMP2 > /dev/null 2>&1
466 if [ -s $TMP3 ] ; then
467 echo "Test 10: delete: R_CURSOR SHOULD HAVE FAILED"
468 exit 1
469 fi
470 done
471 for type in btree recno; do
472 cat $TMP1 |
473 awk '{
474 if (i == 10)
475 exit;
476 printf("p\nk%d\nd%s\n", ++i, $0);
477 }
478 END {
479 printf("fR_CURSOR\np\nk1\ndsome data\n");
480 printf("eR_CURSOR SHOULD HAVE FAILED\n");
481 }' > $TMP2
482 $PROG -o $TMP3 $type $TMP2 > /dev/null 2>&1
483 if [ -s $TMP3 ] ; then
484 echo "Test 10: put: R_CURSOR SHOULD HAVE FAILED"
485 exit 1
486 fi
487 done
488}
489
490# Test insert in reverse order.
491test11()
492{
493 echo "Test 11: recno: reverse order insert"
494 echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" |
495 awk '{
496 for (i = 1; i <= 779; ++i)
497 printf("%05d: input key %d: %s\n", i, i, $0);
498 exit;
499 }' > $TMP1
500 rm -f $TMP2 $TMP3
501
502 for type in recno; do
503 cat $TMP1 |
504 awk '{
505 if (i == 0) {
506 i = 1;
507 printf("p\nk1\nd%s\n", $0);
508 printf("%s\n", "fR_IBEFORE");
509 } else
510 printf("p\nk1\nd%s\n", $0);
511 }
512 END {
513 printf("or\n");
514 }' > $TMP2
515 $PROG -o $TMP3 $type $TMP2
516 if (cmp -s $TMP1 $TMP3) ; then :
517 else
518 echo "test11: type $type: failed"
519 exit 1
520 fi
521 done
522}
523
524# Take the first 20000 entries in the dictionary, reverse them, and give
525# them each a small size data entry. Use a small page size to make sure
526# the btree split code gets hammered.
527test12()
528{
529 echo "Test 12: btree: lots of keys, small page size"
530 mdata=abcdefghijklmnopqrstuvwxy
531 echo $mdata |
532 awk '{ for (i = 1; i < 20001; ++i) print $0 }' > $TMP1
533 for type in btree; do
534 rm -f $TMP2 $TMP3
535 for i in `sed 20000q $DICT | rev`; do
536 echo p
537 echo k$i
538 echo d$mdata
539 echo g
540 echo k$i
541 done > $TMP2
542 $PROG -i psize=512 -o $TMP3 $type $TMP2
543 if (cmp -s $TMP1 $TMP3) ; then :
544 else
545 echo "test12: type $type: failed"
546 exit 1
547 fi
548 done
549}
550
551# Test different byte orders.
552test13()
553{
554 echo "Test 13: btree, hash: differing byte orders"
555 sed 50q $DICT > $TMP1
556 for order in 1234 4321; do
557 for type in btree hash; do
558 rm -f byte.file $TMP2 $TMP3
559 for i in `sed 50q $DICT`; do
560 echo p
561 echo k$i
562 echo d$i
563 echo g
564 echo k$i
565 done > $TMP2
566 $PROG -ilorder=$order -f byte.file -o $TMP3 $type $TMP2
567 if (cmp -s $TMP1 $TMP3) ; then :
568 else
569 echo "test13: $type/$order put failed"
570 exit 1
571 fi
572 for i in `sed 50q $DICT`; do
573 echo g
574 echo k$i
575 done > $TMP2
576 $PROG -ilorder=$order -f byte.file -o $TMP3 $type $TMP2
577 if (cmp -s $TMP1 $TMP3) ; then :
578 else
579 echo "test13: $type/$order get failed"
580 exit 1
581 fi
582 done
583 done
584 rm -f byte.file
585}
586
587# Try a variety of bucketsizes and fill factors for hashing
588test20()
589{
590 echo\
591 "Test 20: hash: bucketsize, fill factor; nelem 25000 cachesize 65536"
592 echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" |
593 awk '{
594 for (i = 1; i <= 10000; ++i) {
595 if (i % 34)
596 s = substr($0, 1, i % 34);
597 else
598 s = substr($0, 1);
599 printf("%s\n", s);
600 }
601 exit;
602 }' > $TMP1
603 sed 10000q $DICT |
604 awk 'BEGIN {
605 ds="abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg"
606 }
607 {
608 if (++i % 34)
609 s = substr(ds, 1, i % 34);
610 else
611 s = substr(ds, 1);
612 printf("p\nk%s\nd%s\n", $0, s);
613 }' > $TMP2
614 sed 10000q $DICT |
615 awk '{
616 ++i;
617 printf("g\nk%s\n", $0);
618 }' >> $TMP2
619 bsize=256
620 for ffactor in 11 14 21; do
621 echo " bucketsize $bsize, fill factor $ffactor"
622 $PROG -o$TMP3 \
623 -ibsize=$bsize,ffactor=$ffactor,nelem=25000,cachesize=65536\
624 hash $TMP2
625 if (cmp -s $TMP1 $TMP3) ; then :
626 else
627 echo "test20: type hash:\
628bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed"
629 exit 1
630 fi
631 done
632 bsize=512
633 for ffactor in 21 28 43; do
634 echo " bucketsize $bsize, fill factor $ffactor"
635 $PROG -o$TMP3 \
636 -ibsize=$bsize,ffactor=$ffactor,nelem=25000,cachesize=65536\
637 hash $TMP2
638 if (cmp -s $TMP1 $TMP3) ; then :
639 else
640 echo "test20: type hash:\
641bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed"
642 exit 1
643 fi
644 done
645 bsize=1024
646 for ffactor in 43 57 85; do
647 echo " bucketsize $bsize, fill factor $ffactor"
648 $PROG -o$TMP3 \
649 -ibsize=$bsize,ffactor=$ffactor,nelem=25000,cachesize=65536\
650 hash $TMP2
651 if (cmp -s $TMP1 $TMP3) ; then :
652 else
653 echo "test20: type hash:\
654bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed"
655 exit 1
656 fi
657 done
658 bsize=2048
659 for ffactor in 85 114 171; do
660 echo " bucketsize $bsize, fill factor $ffactor"
661 $PROG -o$TMP3 \
662 -ibsize=$bsize,ffactor=$ffactor,nelem=25000,cachesize=65536\
663 hash $TMP2
664 if (cmp -s $TMP1 $TMP3) ; then :
665 else
666 echo "test20: type hash:\
667bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed"
668 exit 1
669 fi
670 done
671 bsize=4096
672 for ffactor in 171 228 341; do
673 echo " bucketsize $bsize, fill factor $ffactor"
674 $PROG -o$TMP3 \
675 -ibsize=$bsize,ffactor=$ffactor,nelem=25000,cachesize=65536\
676 hash $TMP2
677 if (cmp -s $TMP1 $TMP3) ; then :
678 else
679 echo "test20: type hash:\
680bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed"
681 exit 1
682 fi
683 done
684 bsize=8192
685 for ffactor in 341 455 683; do
686 echo " bucketsize $bsize, fill factor $ffactor"
687 $PROG -o$TMP3 \
688 -ibsize=$bsize,ffactor=$ffactor,nelem=25000,cachesize=65536\
689 hash $TMP2
690 if (cmp -s $TMP1 $TMP3) ; then :
691 else
692 echo "test20: type hash:\
693bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed"
694 exit 1
695 fi
696 done
697}
698
699main $*
diff --git a/src/regress/lib/libc/ieeefp/Makefile b/src/regress/lib/libc/ieeefp/Makefile
new file mode 100644
index 0000000000..4e2e517b03
--- /dev/null
+++ b/src/regress/lib/libc/ieeefp/Makefile
@@ -0,0 +1,13 @@
1# $NetBSD: Makefile,v 1.4 1995/10/03 21:59:36 phil Exp $
2
3.if ${MACHINE} == "pc532"
4SUBDIR+= round
5.else
6SUBDIR+= except round
7.endif
8
9regress: _SUBDIRUSE
10
11install:
12
13.include <bsd.subdir.mk>
diff --git a/src/regress/lib/libc/ieeefp/except/Makefile b/src/regress/lib/libc/ieeefp/except/Makefile
new file mode 100644
index 0000000000..91f24f15f6
--- /dev/null
+++ b/src/regress/lib/libc/ieeefp/except/Makefile
@@ -0,0 +1,12 @@
1# $NetBSD: Makefile,v 1.1 1995/04/26 00:27:25 jtc Exp $
2
3PROG= except
4SRCS= except.c
5NOMAN=
6
7install:
8
9regress: ${PROG}
10 ./${PROG}
11
12.include <bsd.prog.mk>
diff --git a/src/regress/lib/libc/ieeefp/except/except.c b/src/regress/lib/libc/ieeefp/except/except.c
new file mode 100644
index 0000000000..0ffdcdd468
--- /dev/null
+++ b/src/regress/lib/libc/ieeefp/except/except.c
@@ -0,0 +1,87 @@
1#include <stdio.h>
2#include <signal.h>
3#include <assert.h>
4#include <ieeefp.h>
5#include <float.h>
6
7void sigfpe();
8volatile sig_atomic_t signal_cought;
9
10static volatile const double one = 1.0;
11static volatile const double zero = 0.0;
12static volatile const double huge = DBL_MAX;
13static volatile const double tiny = DBL_MIN;
14
15main()
16{
17 volatile double x;
18
19 /*
20 * check to make sure that all exceptions are masked and
21 * that the accumulated exception status is clear.
22 */
23 assert(fpgetmask() == 0);
24 assert(fpgetsticky() == 0);
25
26 /* set up signal handler */
27 signal (SIGFPE, sigfpe);
28 signal_cought = 0;
29
30 /* trip divide by zero */
31 x = one / zero;
32 assert (fpgetsticky() & FP_X_DZ);
33 assert (signal_cought == 0);
34 fpsetsticky(0);
35
36 /* trip invalid operation */
37 x = zero / zero;
38 assert (fpgetsticky() & FP_X_INV);
39 assert (signal_cought == 0);
40 fpsetsticky(0);
41
42 /* trip overflow */
43 x = huge * huge;
44 assert (fpgetsticky() & FP_X_OFL);
45 assert (signal_cought == 0);
46 fpsetsticky(0);
47
48 /* trip underflow */
49 x = tiny * tiny;
50 assert (fpgetsticky() & FP_X_UFL);
51 assert (signal_cought == 0);
52 fpsetsticky(0);
53
54#if 0
55 /* unmask and then trip divide by zero */
56 fpsetmask(FP_X_DZ);
57 x = one / zero;
58 assert (signal_cought == 1);
59 signal_cought = 0;
60
61 /* unmask and then trip invalid operation */
62 fpsetmask(FP_X_INV);
63 x = zero / zero;
64 assert (signal_cought == 1);
65 signal_cought = 0;
66
67 /* unmask and then trip overflow */
68 fpsetmask(FP_X_OFL);
69 x = huge * huge;
70 assert (signal_cought == 1);
71 signal_cought = 0;
72
73 /* unmask and then trip underflow */
74 fpsetmask(FP_X_UFL);
75 x = tiny * tiny;
76 assert (signal_cought == 1);
77 signal_cought = 0;
78#endif
79
80 exit(0);
81}
82
83void
84sigfpe()
85{
86 signal_cought = 1;
87}
diff --git a/src/regress/lib/libc/ieeefp/round/Makefile b/src/regress/lib/libc/ieeefp/round/Makefile
new file mode 100644
index 0000000000..571133436c
--- /dev/null
+++ b/src/regress/lib/libc/ieeefp/round/Makefile
@@ -0,0 +1,12 @@
1# $NetBSD: Makefile,v 1.1 1995/04/26 00:27:27 jtc Exp $
2
3PROG= round
4SRCS= round.c
5NOMAN=
6
7install:
8
9regress: ${PROG}
10 ./${PROG}
11
12.include <bsd.prog.mk>
diff --git a/src/regress/lib/libc/ieeefp/round/round.c b/src/regress/lib/libc/ieeefp/round/round.c
new file mode 100644
index 0000000000..b9fcd9771e
--- /dev/null
+++ b/src/regress/lib/libc/ieeefp/round/round.c
@@ -0,0 +1,44 @@
1/* $NetBSD: round.c,v 1.1 1995/04/26 00:27:28 jtc Exp $ */
2
3/*
4 * Written by J.T. Conklin, Apr 18, 1995
5 * Public domain.
6 */
7
8#include <assert.h>
9#include <stdlib.h>
10#include <ieeefp.h>
11#include <float.h>
12
13int
14main()
15{
16 /*
17 * This test would be better if it actually performed some
18 * calculations to verify the selected rounding mode. But
19 * this is probably acceptable since the fp{get,set}round
20 * functions usually just get or set the processors fpu
21 * control word.
22 */
23
24 assert(fpgetround() == FP_RN);
25 assert(FLT_ROUNDS == 1);
26
27 assert(fpsetround(FP_RP) == FP_RN);
28 assert(fpgetround() == FP_RP);
29 assert(FLT_ROUNDS == 2);
30
31 assert(fpsetround(FP_RM) == FP_RP);
32 assert(fpgetround() == FP_RM);
33 assert(FLT_ROUNDS == 3);
34
35 assert(fpsetround(FP_RZ) == FP_RM);
36 assert(fpgetround() == FP_RZ);
37 assert(FLT_ROUNDS == 0);
38
39 assert(fpsetround(FP_RN) == FP_RZ);
40 assert(fpgetround() == FP_RN);
41 assert(FLT_ROUNDS == 1);
42
43 exit(0);
44}
diff --git a/src/regress/lib/libc/regex/Makefile b/src/regress/lib/libc/regex/Makefile
new file mode 100644
index 0000000000..93b7bb9052
--- /dev/null
+++ b/src/regress/lib/libc/regex/Makefile
@@ -0,0 +1,16 @@
1# $NetBSD: Makefile,v 1.2 1995/02/16 19:38:45 cgd Exp $
2
3PROG= re
4SRCS= main.c split.c debug.c
5NOMAN=
6
7CFLAGS+= -I${.CURDIR}/../../../../lib/libc/regex
8
9TESTS= ${.CURDIR}/tests
10
11regress:
12 ./re < ${TESTS}
13 ./re -el < ${TESTS}
14 ./re -er < ${TESTS}
15
16.include <bsd.prog.mk>
diff --git a/src/regress/lib/libc/regex/debug.c b/src/regress/lib/libc/regex/debug.c
new file mode 100644
index 0000000000..861f550611
--- /dev/null
+++ b/src/regress/lib/libc/regex/debug.c
@@ -0,0 +1,244 @@
1/* $NetBSD: debug.c,v 1.2 1995/04/20 22:39:42 cgd Exp $ */
2
3#include <stdio.h>
4#include <string.h>
5#include <ctype.h>
6#include <limits.h>
7#include <stdlib.h>
8#include <sys/types.h>
9#include <regex.h>
10
11#include "utils.h"
12#include "regex2.h"
13#include "debug.ih"
14
15/*
16 - regprint - print a regexp for debugging
17 == void regprint(regex_t *r, FILE *d);
18 */
19void
20regprint(r, d)
21regex_t *r;
22FILE *d;
23{
24 register struct re_guts *g = r->re_g;
25 register int i;
26 register int c;
27 register int last;
28 int nincat[NC];
29
30 fprintf(d, "%ld states, %d categories", (long)g->nstates,
31 g->ncategories);
32 fprintf(d, ", first %ld last %ld", (long)g->firststate,
33 (long)g->laststate);
34 if (g->iflags&USEBOL)
35 fprintf(d, ", USEBOL");
36 if (g->iflags&USEEOL)
37 fprintf(d, ", USEEOL");
38 if (g->iflags&BAD)
39 fprintf(d, ", BAD");
40 if (g->nsub > 0)
41 fprintf(d, ", nsub=%ld", (long)g->nsub);
42 if (g->must != NULL)
43 fprintf(d, ", must(%ld) `%*s'", (long)g->mlen, (int)g->mlen,
44 g->must);
45 if (g->backrefs)
46 fprintf(d, ", backrefs");
47 if (g->nplus > 0)
48 fprintf(d, ", nplus %ld", (long)g->nplus);
49 fprintf(d, "\n");
50 s_print(g, d);
51 for (i = 0; i < g->ncategories; i++) {
52 nincat[i] = 0;
53 for (c = CHAR_MIN; c <= CHAR_MAX; c++)
54 if (g->categories[c] == i)
55 nincat[i]++;
56 }
57 fprintf(d, "cc0#%d", nincat[0]);
58 for (i = 1; i < g->ncategories; i++)
59 if (nincat[i] == 1) {
60 for (c = CHAR_MIN; c <= CHAR_MAX; c++)
61 if (g->categories[c] == i)
62 break;
63 fprintf(d, ", %d=%s", i, regchar(c));
64 }
65 fprintf(d, "\n");
66 for (i = 1; i < g->ncategories; i++)
67 if (nincat[i] != 1) {
68 fprintf(d, "cc%d\t", i);
69 last = -1;
70 for (c = CHAR_MIN; c <= CHAR_MAX+1; c++) /* +1 does flush */
71 if (c <= CHAR_MAX && g->categories[c] == i) {
72 if (last < 0) {
73 fprintf(d, "%s", regchar(c));
74 last = c;
75 }
76 } else {
77 if (last >= 0) {
78 if (last != c-1)
79 fprintf(d, "-%s",
80 regchar(c-1));
81 last = -1;
82 }
83 }
84 fprintf(d, "\n");
85 }
86}
87
88/*
89 - s_print - print the strip for debugging
90 == static void s_print(register struct re_guts *g, FILE *d);
91 */
92static void
93s_print(g, d)
94register struct re_guts *g;
95FILE *d;
96{
97 register sop *s;
98 register cset *cs;
99 register int i;
100 register int done = 0;
101 register sop opnd;
102 register int col = 0;
103 register int last;
104 register sopno offset = 2;
105# define GAP() { if (offset % 5 == 0) { \
106 if (col > 40) { \
107 fprintf(d, "\n\t"); \
108 col = 0; \
109 } else { \
110 fprintf(d, " "); \
111 col++; \
112 } \
113 } else \
114 col++; \
115 offset++; \
116 }
117
118 if (OP(g->strip[0]) != OEND)
119 fprintf(d, "missing initial OEND!\n");
120 for (s = &g->strip[1]; !done; s++) {
121 opnd = OPND(*s);
122 switch (OP(*s)) {
123 case OEND:
124 fprintf(d, "\n");
125 done = 1;
126 break;
127 case OCHAR:
128 if (strchr("\\|()^$.[+*?{}!<> ", (char)opnd) != NULL)
129 fprintf(d, "\\%c", (char)opnd);
130 else
131 fprintf(d, "%s", regchar((char)opnd));
132 break;
133 case OBOL:
134 fprintf(d, "^");
135 break;
136 case OEOL:
137 fprintf(d, "$");
138 break;
139 case OBOW:
140 fprintf(d, "\\{");
141 break;
142 case OEOW:
143 fprintf(d, "\\}");
144 break;
145 case OANY:
146 fprintf(d, ".");
147 break;
148 case OANYOF:
149 fprintf(d, "[(%ld)", (long)opnd);
150 cs = &g->sets[opnd];
151 last = -1;
152 for (i = 0; i < g->csetsize+1; i++) /* +1 flushes */
153 if (CHIN(cs, i) && i < g->csetsize) {
154 if (last < 0) {
155 fprintf(d, "%s", regchar(i));
156 last = i;
157 }
158 } else {
159 if (last >= 0) {
160 if (last != i-1)
161 fprintf(d, "-%s",
162 regchar(i-1));
163 last = -1;
164 }
165 }
166 fprintf(d, "]");
167 break;
168 case OBACK_:
169 fprintf(d, "(\\<%ld>", (long)opnd);
170 break;
171 case O_BACK:
172 fprintf(d, "<%ld>\\)", (long)opnd);
173 break;
174 case OPLUS_:
175 fprintf(d, "(+");
176 if (OP(*(s+opnd)) != O_PLUS)
177 fprintf(d, "<%ld>", (long)opnd);
178 break;
179 case O_PLUS:
180 if (OP(*(s-opnd)) != OPLUS_)
181 fprintf(d, "<%ld>", (long)opnd);
182 fprintf(d, "+)");
183 break;
184 case OQUEST_:
185 fprintf(d, "(?");
186 if (OP(*(s+opnd)) != O_QUEST)
187 fprintf(d, "<%ld>", (long)opnd);
188 break;
189 case O_QUEST:
190 if (OP(*(s-opnd)) != OQUEST_)
191 fprintf(d, "<%ld>", (long)opnd);
192 fprintf(d, "?)");
193 break;
194 case OLPAREN:
195 fprintf(d, "((<%ld>", (long)opnd);
196 break;
197 case ORPAREN:
198 fprintf(d, "<%ld>))", (long)opnd);
199 break;
200 case OCH_:
201 fprintf(d, "<");
202 if (OP(*(s+opnd)) != OOR2)
203 fprintf(d, "<%ld>", (long)opnd);
204 break;
205 case OOR1:
206 if (OP(*(s-opnd)) != OOR1 && OP(*(s-opnd)) != OCH_)
207 fprintf(d, "<%ld>", (long)opnd);
208 fprintf(d, "|");
209 break;
210 case OOR2:
211 fprintf(d, "|");
212 if (OP(*(s+opnd)) != OOR2 && OP(*(s+opnd)) != O_CH)
213 fprintf(d, "<%ld>", (long)opnd);
214 break;
215 case O_CH:
216 if (OP(*(s-opnd)) != OOR1)
217 fprintf(d, "<%ld>", (long)opnd);
218 fprintf(d, ">");
219 break;
220 default:
221 fprintf(d, "!%d(%d)!", OP(*s), opnd);
222 break;
223 }
224 if (!done)
225 GAP();
226 }
227}
228
229/*
230 - regchar - make a character printable
231 == static char *regchar(int ch);
232 */
233static char * /* -> representation */
234regchar(ch)
235int ch;
236{
237 static char buf[10];
238
239 if (isprint(ch) || ch == ' ')
240 sprintf(buf, "%c", ch);
241 else
242 sprintf(buf, "\\%o", ch);
243 return(buf);
244}
diff --git a/src/regress/lib/libc/regex/debug.ih b/src/regress/lib/libc/regex/debug.ih
new file mode 100644
index 0000000000..fb9bac0c75
--- /dev/null
+++ b/src/regress/lib/libc/regex/debug.ih
@@ -0,0 +1,16 @@
1/* $NetBSD: debug.ih,v 1.2 1995/04/20 22:39:47 cgd Exp $ */
2
3/* ========= begin header generated by ./mkh ========= */
4#ifdef __cplusplus
5extern "C" {
6#endif
7
8/* === debug.c === */
9void regprint __P((regex_t *r, FILE *d));
10static void s_print __P((register struct re_guts *g, FILE *d));
11static char *regchar __P((int ch));
12
13#ifdef __cplusplus
14}
15#endif
16/* ========= end header generated by ./mkh ========= */
diff --git a/src/regress/lib/libc/regex/main.c b/src/regress/lib/libc/regex/main.c
new file mode 100644
index 0000000000..8d88a8b9b8
--- /dev/null
+++ b/src/regress/lib/libc/regex/main.c
@@ -0,0 +1,512 @@
1/* $NetBSD: main.c,v 1.2 1995/04/20 22:39:51 cgd Exp $ */
2
3#include <stdio.h>
4#include <string.h>
5#include <sys/types.h>
6#include <regex.h>
7#include <assert.h>
8
9#include "main.ih"
10
11char *progname;
12int debug = 0;
13int line = 0;
14int status = 0;
15
16int copts = REG_EXTENDED;
17int eopts = 0;
18regoff_t startoff = 0;
19regoff_t endoff = 0;
20
21
22extern int split();
23extern void regprint();
24
25/*
26 - main - do the simple case, hand off to regress() for regression
27 */
28main(argc, argv)
29int argc;
30char *argv[];
31{
32 regex_t re;
33# define NS 10
34 regmatch_t subs[NS];
35 char erbuf[100];
36 int err;
37 size_t len;
38 int c;
39 int errflg = 0;
40 register int i;
41 extern int optind;
42 extern char *optarg;
43
44 progname = argv[0];
45
46 while ((c = getopt(argc, argv, "c:e:S:E:x")) != EOF)
47 switch (c) {
48 case 'c': /* compile options */
49 copts = options('c', optarg);
50 break;
51 case 'e': /* execute options */
52 eopts = options('e', optarg);
53 break;
54 case 'S': /* start offset */
55 startoff = (regoff_t)atoi(optarg);
56 break;
57 case 'E': /* end offset */
58 endoff = (regoff_t)atoi(optarg);
59 break;
60 case 'x': /* Debugging. */
61 debug++;
62 break;
63 case '?':
64 default:
65 errflg++;
66 break;
67 }
68 if (errflg) {
69 fprintf(stderr, "usage: %s ", progname);
70 fprintf(stderr, "[-c copt][-C][-d] [re]\n");
71 exit(2);
72 }
73
74 if (optind >= argc) {
75 regress(stdin);
76 exit(status);
77 }
78
79 err = regcomp(&re, argv[optind++], copts);
80 if (err) {
81 len = regerror(err, &re, erbuf, sizeof(erbuf));
82 fprintf(stderr, "error %s, %d/%d `%s'\n",
83 eprint(err), len, sizeof(erbuf), erbuf);
84 exit(status);
85 }
86 regprint(&re, stdout);
87
88 if (optind >= argc) {
89 regfree(&re);
90 exit(status);
91 }
92
93 if (eopts&REG_STARTEND) {
94 subs[0].rm_so = startoff;
95 subs[0].rm_eo = strlen(argv[optind]) - endoff;
96 }
97 err = regexec(&re, argv[optind], (size_t)NS, subs, eopts);
98 if (err) {
99 len = regerror(err, &re, erbuf, sizeof(erbuf));
100 fprintf(stderr, "error %s, %d/%d `%s'\n",
101 eprint(err), len, sizeof(erbuf), erbuf);
102 exit(status);
103 }
104 if (!(copts&REG_NOSUB)) {
105 len = (int)(subs[0].rm_eo - subs[0].rm_so);
106 if (subs[0].rm_so != -1) {
107 if (len != 0)
108 printf("match `%.*s'\n", len,
109 argv[optind] + subs[0].rm_so);
110 else
111 printf("match `'@%.1s\n",
112 argv[optind] + subs[0].rm_so);
113 }
114 for (i = 1; i < NS; i++)
115 if (subs[i].rm_so != -1)
116 printf("(%d) `%.*s'\n", i,
117 (int)(subs[i].rm_eo - subs[i].rm_so),
118 argv[optind] + subs[i].rm_so);
119 }
120 exit(status);
121}
122
123/*
124 - regress - main loop of regression test
125 == void regress(FILE *in);
126 */
127void
128regress(in)
129FILE *in;
130{
131 char inbuf[1000];
132# define MAXF 10
133 char *f[MAXF];
134 int nf;
135 int i;
136 char erbuf[100];
137 size_t ne;
138 char *badpat = "invalid regular expression";
139# define SHORT 10
140 char *bpname = "REG_BADPAT";
141 regex_t re;
142
143 while (fgets(inbuf, sizeof(inbuf), in) != NULL) {
144 line++;
145 if (inbuf[0] == '#' || inbuf[0] == '\n')
146 continue; /* NOTE CONTINUE */
147 inbuf[strlen(inbuf)-1] = '\0'; /* get rid of stupid \n */
148 if (debug)
149 fprintf(stdout, "%d:\n", line);
150 nf = split(inbuf, f, MAXF, "\t\t");
151 if (nf < 3) {
152 fprintf(stderr, "bad input, line %d\n", line);
153 exit(1);
154 }
155 for (i = 0; i < nf; i++)
156 if (strcmp(f[i], "\"\"") == 0)
157 f[i] = "";
158 if (nf <= 3)
159 f[3] = NULL;
160 if (nf <= 4)
161 f[4] = NULL;
162 try(f[0], f[1], f[2], f[3], f[4], options('c', f[1]));
163 if (opt('&', f[1])) /* try with either type of RE */
164 try(f[0], f[1], f[2], f[3], f[4],
165 options('c', f[1]) &~ REG_EXTENDED);
166 }
167
168 ne = regerror(REG_BADPAT, (regex_t *)NULL, erbuf, sizeof(erbuf));
169 if (strcmp(erbuf, badpat) != 0 || ne != strlen(badpat)+1) {
170 fprintf(stderr, "end: regerror() test gave `%s' not `%s'\n",
171 erbuf, badpat);
172 status = 1;
173 }
174 ne = regerror(REG_BADPAT, (regex_t *)NULL, erbuf, (size_t)SHORT);
175 if (strncmp(erbuf, badpat, SHORT-1) != 0 || erbuf[SHORT-1] != '\0' ||
176 ne != strlen(badpat)+1) {
177 fprintf(stderr, "end: regerror() short test gave `%s' not `%.*s'\n",
178 erbuf, SHORT-1, badpat);
179 status = 1;
180 }
181 ne = regerror(REG_ITOA|REG_BADPAT, (regex_t *)NULL, erbuf, sizeof(erbuf));
182 if (strcmp(erbuf, bpname) != 0 || ne != strlen(bpname)+1) {
183 fprintf(stderr, "end: regerror() ITOA test gave `%s' not `%s'\n",
184 erbuf, bpname);
185 status = 1;
186 }
187 re.re_endp = bpname;
188 ne = regerror(REG_ATOI, &re, erbuf, sizeof(erbuf));
189 if (atoi(erbuf) != (int)REG_BADPAT) {
190 fprintf(stderr, "end: regerror() ATOI test gave `%s' not `%ld'\n",
191 erbuf, (long)REG_BADPAT);
192 status = 1;
193 } else if (ne != strlen(erbuf)+1) {
194 fprintf(stderr, "end: regerror() ATOI test len(`%s') = %ld\n",
195 erbuf, (long)REG_BADPAT);
196 status = 1;
197 }
198}
199
200/*
201 - try - try it, and report on problems
202 == void try(char *f0, char *f1, char *f2, char *f3, char *f4, int opts);
203 */
204void
205try(f0, f1, f2, f3, f4, opts)
206char *f0;
207char *f1;
208char *f2;
209char *f3;
210char *f4;
211int opts; /* may not match f1 */
212{
213 regex_t re;
214# define NSUBS 10
215 regmatch_t subs[NSUBS];
216# define NSHOULD 15
217 char *should[NSHOULD];
218 int nshould;
219 char erbuf[100];
220 int err;
221 int len;
222 char *type = (opts & REG_EXTENDED) ? "ERE" : "BRE";
223 register int i;
224 char *grump;
225 char f0copy[1000];
226 char f2copy[1000];
227
228 strcpy(f0copy, f0);
229 re.re_endp = (opts&REG_PEND) ? f0copy + strlen(f0copy) : NULL;
230 fixstr(f0copy);
231 err = regcomp(&re, f0copy, opts);
232 if (err != 0 && (!opt('C', f1) || err != efind(f2))) {
233 /* unexpected error or wrong error */
234 len = regerror(err, &re, erbuf, sizeof(erbuf));
235 fprintf(stderr, "%d: %s error %s, %d/%d `%s'\n",
236 line, type, eprint(err), len,
237 sizeof(erbuf), erbuf);
238 status = 1;
239 } else if (err == 0 && opt('C', f1)) {
240 /* unexpected success */
241 fprintf(stderr, "%d: %s should have given REG_%s\n",
242 line, type, f2);
243 status = 1;
244 err = 1; /* so we won't try regexec */
245 }
246
247 if (err != 0) {
248 regfree(&re);
249 return;
250 }
251
252 strcpy(f2copy, f2);
253 fixstr(f2copy);
254
255 if (options('e', f1)&REG_STARTEND) {
256 if (strchr(f2, '(') == NULL || strchr(f2, ')') == NULL)
257 fprintf(stderr, "%d: bad STARTEND syntax\n", line);
258 subs[0].rm_so = strchr(f2, '(') - f2 + 1;
259 subs[0].rm_eo = strchr(f2, ')') - f2;
260 }
261 err = regexec(&re, f2copy, NSUBS, subs, options('e', f1));
262
263 if (err != 0 && (f3 != NULL || err != REG_NOMATCH)) {
264 /* unexpected error or wrong error */
265 len = regerror(err, &re, erbuf, sizeof(erbuf));
266 fprintf(stderr, "%d: %s exec error %s, %d/%d `%s'\n",
267 line, type, eprint(err), len,
268 sizeof(erbuf), erbuf);
269 status = 1;
270 } else if (err != 0) {
271 /* nothing more to check */
272 } else if (f3 == NULL) {
273 /* unexpected success */
274 fprintf(stderr, "%d: %s exec should have failed\n",
275 line, type);
276 status = 1;
277 err = 1; /* just on principle */
278 } else if (opts&REG_NOSUB) {
279 /* nothing more to check */
280 } else if ((grump = check(f2, subs[0], f3)) != NULL) {
281 fprintf(stderr, "%d: %s %s\n", line, type, grump);
282 status = 1;
283 err = 1;
284 }
285
286 if (err != 0 || f4 == NULL) {
287 regfree(&re);
288 return;
289 }
290
291 for (i = 1; i < NSHOULD; i++)
292 should[i] = NULL;
293 nshould = split(f4, should+1, NSHOULD-1, ",");
294 if (nshould == 0) {
295 nshould = 1;
296 should[1] = "";
297 }
298 for (i = 1; i < NSUBS; i++) {
299 grump = check(f2, subs[i], should[i]);
300 if (grump != NULL) {
301 fprintf(stderr, "%d: %s $%d %s\n", line,
302 type, i, grump);
303 status = 1;
304 err = 1;
305 }
306 }
307
308 regfree(&re);
309}
310
311/*
312 - options - pick options out of a regression-test string
313 == int options(int type, char *s);
314 */
315int
316options(type, s)
317int type; /* 'c' compile, 'e' exec */
318char *s;
319{
320 register char *p;
321 register int o = (type == 'c') ? copts : eopts;
322 register char *legal = (type == 'c') ? "bisnmp" : "^$#tl";
323
324 for (p = s; *p != '\0'; p++)
325 if (strchr(legal, *p) != NULL)
326 switch (*p) {
327 case 'b':
328 o &= ~REG_EXTENDED;
329 break;
330 case 'i':
331 o |= REG_ICASE;
332 break;
333 case 's':
334 o |= REG_NOSUB;
335 break;
336 case 'n':
337 o |= REG_NEWLINE;
338 break;
339 case 'm':
340 o &= ~REG_EXTENDED;
341 o |= REG_NOSPEC;
342 break;
343 case 'p':
344 o |= REG_PEND;
345 break;
346 case '^':
347 o |= REG_NOTBOL;
348 break;
349 case '$':
350 o |= REG_NOTEOL;
351 break;
352 case '#':
353 o |= REG_STARTEND;
354 break;
355 case 't': /* trace */
356 o |= REG_TRACE;
357 break;
358 case 'l': /* force long representation */
359 o |= REG_LARGE;
360 break;
361 case 'r': /* force backref use */
362 o |= REG_BACKR;
363 break;
364 }
365 return(o);
366}
367
368/*
369 - opt - is a particular option in a regression string?
370 == int opt(int c, char *s);
371 */
372int /* predicate */
373opt(c, s)
374int c;
375char *s;
376{
377 return(strchr(s, c) != NULL);
378}
379
380/*
381 - fixstr - transform magic characters in strings
382 == void fixstr(register char *p);
383 */
384void
385fixstr(p)
386register char *p;
387{
388 if (p == NULL)
389 return;
390
391 for (; *p != '\0'; p++)
392 if (*p == 'N')
393 *p = '\n';
394 else if (*p == 'T')
395 *p = '\t';
396 else if (*p == 'S')
397 *p = ' ';
398 else if (*p == 'Z')
399 *p = '\0';
400}
401
402/*
403 - check - check a substring match
404 == char *check(char *str, regmatch_t sub, char *should);
405 */
406char * /* NULL or complaint */
407check(str, sub, should)
408char *str;
409regmatch_t sub;
410char *should;
411{
412 register int len;
413 register int shlen;
414 register char *p;
415 static char grump[500];
416 register char *at = NULL;
417
418 if (should != NULL && strcmp(should, "-") == 0)
419 should = NULL;
420 if (should != NULL && should[0] == '@') {
421 at = should + 1;
422 should = "";
423 }
424
425 /* check rm_so and rm_eo for consistency */
426 if (sub.rm_so > sub.rm_eo || (sub.rm_so == -1 && sub.rm_eo != -1) ||
427 (sub.rm_so != -1 && sub.rm_eo == -1) ||
428 (sub.rm_so != -1 && sub.rm_so < 0) ||
429 (sub.rm_eo != -1 && sub.rm_eo < 0) ) {
430 sprintf(grump, "start %ld end %ld", (long)sub.rm_so,
431 (long)sub.rm_eo);
432 return(grump);
433 }
434
435 /* check for no match */
436 if (sub.rm_so == -1 && should == NULL)
437 return(NULL);
438 if (sub.rm_so == -1)
439 return("did not match");
440
441 /* check for in range */
442 if (sub.rm_eo > strlen(str)) {
443 sprintf(grump, "start %ld end %ld, past end of string",
444 (long)sub.rm_so, (long)sub.rm_eo);
445 return(grump);
446 }
447
448 len = (int)(sub.rm_eo - sub.rm_so);
449 shlen = (int)strlen(should);
450 p = str + sub.rm_so;
451
452 /* check for not supposed to match */
453 if (should == NULL) {
454 sprintf(grump, "matched `%.*s'", len, p);
455 return(grump);
456 }
457
458 /* check for wrong match */
459 if (len != shlen || strncmp(p, should, (size_t)shlen) != 0) {
460 sprintf(grump, "matched `%.*s' instead", len, p);
461 return(grump);
462 }
463 if (shlen > 0)
464 return(NULL);
465
466 /* check null match in right place */
467 if (at == NULL)
468 return(NULL);
469 shlen = strlen(at);
470 if (shlen == 0)
471 shlen = 1; /* force check for end-of-string */
472 if (strncmp(p, at, shlen) != 0) {
473 sprintf(grump, "matched null at `%.20s'", p);
474 return(grump);
475 }
476 return(NULL);
477}
478
479/*
480 - eprint - convert error number to name
481 == static char *eprint(int err);
482 */
483static char *
484eprint(err)
485int err;
486{
487 static char epbuf[100];
488 size_t len;
489
490 len = regerror(REG_ITOA|err, (regex_t *)NULL, epbuf, sizeof(epbuf));
491 assert(len <= sizeof(epbuf));
492 return(epbuf);
493}
494
495/*
496 - efind - convert error name to number
497 == static int efind(char *name);
498 */
499static int
500efind(name)
501char *name;
502{
503 static char efbuf[100];
504 size_t n;
505 regex_t re;
506
507 sprintf(efbuf, "REG_%s", name);
508 assert(strlen(efbuf) < sizeof(efbuf));
509 re.re_endp = efbuf;
510 (void) regerror(REG_ATOI, &re, efbuf, sizeof(efbuf));
511 return(atoi(efbuf));
512}
diff --git a/src/regress/lib/libc/regex/main.ih b/src/regress/lib/libc/regex/main.ih
new file mode 100644
index 0000000000..135e3e792d
--- /dev/null
+++ b/src/regress/lib/libc/regex/main.ih
@@ -0,0 +1,21 @@
1/* $NetBSD: main.ih,v 1.2 1995/04/20 22:39:55 cgd Exp $ */
2
3/* ========= begin header generated by ./mkh ========= */
4#ifdef __cplusplus
5extern "C" {
6#endif
7
8/* === main.c === */
9void regress __P((FILE *in));
10void try __P((char *f0, char *f1, char *f2, char *f3, char *f4, int opts));
11int options __P((int type, char *s));
12int opt __P((int c, char *s));
13void fixstr __P((register char *p));
14char *check __P((char *str, regmatch_t sub, char *should));
15static char *eprint __P((int err));
16static int efind __P((char *name));
17
18#ifdef __cplusplus
19}
20#endif
21/* ========= end header generated by ./mkh ========= */
diff --git a/src/regress/lib/libc/regex/split.c b/src/regress/lib/libc/regex/split.c
new file mode 100644
index 0000000000..dd1ca14480
--- /dev/null
+++ b/src/regress/lib/libc/regex/split.c
@@ -0,0 +1,318 @@
1/* $NetBSD: split.c,v 1.2 1995/04/20 22:39:57 cgd Exp $ */
2
3#include <stdio.h>
4#include <string.h>
5
6/*
7 - split - divide a string into fields, like awk split()
8 = int split(char *string, char *fields[], int nfields, char *sep);
9 */
10int /* number of fields, including overflow */
11split(string, fields, nfields, sep)
12char *string;
13char *fields[]; /* list is not NULL-terminated */
14int nfields; /* number of entries available in fields[] */
15char *sep; /* "" white, "c" single char, "ab" [ab]+ */
16{
17 register char *p = string;
18 register char c; /* latest character */
19 register char sepc = sep[0];
20 register char sepc2;
21 register int fn;
22 register char **fp = fields;
23 register char *sepp;
24 register int trimtrail;
25
26 /* white space */
27 if (sepc == '\0') {
28 while ((c = *p++) == ' ' || c == '\t')
29 continue;
30 p--;
31 trimtrail = 1;
32 sep = " \t"; /* note, code below knows this is 2 long */
33 sepc = ' ';
34 } else
35 trimtrail = 0;
36 sepc2 = sep[1]; /* now we can safely pick this up */
37
38 /* catch empties */
39 if (*p == '\0')
40 return(0);
41
42 /* single separator */
43 if (sepc2 == '\0') {
44 fn = nfields;
45 for (;;) {
46 *fp++ = p;
47 fn--;
48 if (fn == 0)
49 break;
50 while ((c = *p++) != sepc)
51 if (c == '\0')
52 return(nfields - fn);
53 *(p-1) = '\0';
54 }
55 /* we have overflowed the fields vector -- just count them */
56 fn = nfields;
57 for (;;) {
58 while ((c = *p++) != sepc)
59 if (c == '\0')
60 return(fn);
61 fn++;
62 }
63 /* not reached */
64 }
65
66 /* two separators */
67 if (sep[2] == '\0') {
68 fn = nfields;
69 for (;;) {
70 *fp++ = p;
71 fn--;
72 while ((c = *p++) != sepc && c != sepc2)
73 if (c == '\0') {
74 if (trimtrail && **(fp-1) == '\0')
75 fn++;
76 return(nfields - fn);
77 }
78 if (fn == 0)
79 break;
80 *(p-1) = '\0';
81 while ((c = *p++) == sepc || c == sepc2)
82 continue;
83 p--;
84 }
85 /* we have overflowed the fields vector -- just count them */
86 fn = nfields;
87 while (c != '\0') {
88 while ((c = *p++) == sepc || c == sepc2)
89 continue;
90 p--;
91 fn++;
92 while ((c = *p++) != '\0' && c != sepc && c != sepc2)
93 continue;
94 }
95 /* might have to trim trailing white space */
96 if (trimtrail) {
97 p--;
98 while ((c = *--p) == sepc || c == sepc2)
99 continue;
100 p++;
101 if (*p != '\0') {
102 if (fn == nfields+1)
103 *p = '\0';
104 fn--;
105 }
106 }
107 return(fn);
108 }
109
110 /* n separators */
111 fn = 0;
112 for (;;) {
113 if (fn < nfields)
114 *fp++ = p;
115 fn++;
116 for (;;) {
117 c = *p++;
118 if (c == '\0')
119 return(fn);
120 sepp = sep;
121 while ((sepc = *sepp++) != '\0' && sepc != c)
122 continue;
123 if (sepc != '\0') /* it was a separator */
124 break;
125 }
126 if (fn < nfields)
127 *(p-1) = '\0';
128 for (;;) {
129 c = *p++;
130 sepp = sep;
131 while ((sepc = *sepp++) != '\0' && sepc != c)
132 continue;
133 if (sepc == '\0') /* it wasn't a separator */
134 break;
135 }
136 p--;
137 }
138
139 /* not reached */
140}
141
142#ifdef TEST_SPLIT
143
144
145/*
146 * test program
147 * pgm runs regression
148 * pgm sep splits stdin lines by sep
149 * pgm str sep splits str by sep
150 * pgm str sep n splits str by sep n times
151 */
152int
153main(argc, argv)
154int argc;
155char *argv[];
156{
157 char buf[512];
158 register int n;
159# define MNF 10
160 char *fields[MNF];
161
162 if (argc > 4)
163 for (n = atoi(argv[3]); n > 0; n--) {
164 (void) strcpy(buf, argv[1]);
165 }
166 else if (argc > 3)
167 for (n = atoi(argv[3]); n > 0; n--) {
168 (void) strcpy(buf, argv[1]);
169 (void) split(buf, fields, MNF, argv[2]);
170 }
171 else if (argc > 2)
172 dosplit(argv[1], argv[2]);
173 else if (argc > 1)
174 while (fgets(buf, sizeof(buf), stdin) != NULL) {
175 buf[strlen(buf)-1] = '\0'; /* stomp newline */
176 dosplit(buf, argv[1]);
177 }
178 else
179 regress();
180
181 exit(0);
182}
183
184dosplit(string, seps)
185char *string;
186char *seps;
187{
188# define NF 5
189 char *fields[NF];
190 register int nf;
191
192 nf = split(string, fields, NF, seps);
193 print(nf, NF, fields);
194}
195
196print(nf, nfp, fields)
197int nf;
198int nfp;
199char *fields[];
200{
201 register int fn;
202 register int bound;
203
204 bound = (nf > nfp) ? nfp : nf;
205 printf("%d:\t", nf);
206 for (fn = 0; fn < bound; fn++)
207 printf("\"%s\"%s", fields[fn], (fn+1 < nf) ? ", " : "\n");
208}
209
210#define RNF 5 /* some table entries know this */
211struct {
212 char *str;
213 char *seps;
214 int nf;
215 char *fi[RNF];
216} tests[] = {
217 "", " ", 0, { "" },
218 " ", " ", 2, { "", "" },
219 "x", " ", 1, { "x" },
220 "xy", " ", 1, { "xy" },
221 "x y", " ", 2, { "x", "y" },
222 "abc def g ", " ", 5, { "abc", "def", "", "g", "" },
223 " a bcd", " ", 4, { "", "", "a", "bcd" },
224 "a b c d e f", " ", 6, { "a", "b", "c", "d", "e f" },
225 " a b c d ", " ", 6, { "", "a", "b", "c", "d " },
226
227 "", " _", 0, { "" },
228 " ", " _", 2, { "", "" },
229 "x", " _", 1, { "x" },
230 "x y", " _", 2, { "x", "y" },
231 "ab _ cd", " _", 2, { "ab", "cd" },
232 " a_b c ", " _", 5, { "", "a", "b", "c", "" },
233 "a b c_d e f", " _", 6, { "a", "b", "c", "d", "e f" },
234 " a b c d ", " _", 6, { "", "a", "b", "c", "d " },
235
236 "", " _~", 0, { "" },
237 " ", " _~", 2, { "", "" },
238 "x", " _~", 1, { "x" },
239 "x y", " _~", 2, { "x", "y" },
240 "ab _~ cd", " _~", 2, { "ab", "cd" },
241 " a_b c~", " _~", 5, { "", "a", "b", "c", "" },
242 "a b_c d~e f", " _~", 6, { "a", "b", "c", "d", "e f" },
243 "~a b c d ", " _~", 6, { "", "a", "b", "c", "d " },
244
245 "", " _~-", 0, { "" },
246 " ", " _~-", 2, { "", "" },
247 "x", " _~-", 1, { "x" },
248 "x y", " _~-", 2, { "x", "y" },
249 "ab _~- cd", " _~-", 2, { "ab", "cd" },
250 " a_b c~", " _~-", 5, { "", "a", "b", "c", "" },
251 "a b_c-d~e f", " _~-", 6, { "a", "b", "c", "d", "e f" },
252 "~a-b c d ", " _~-", 6, { "", "a", "b", "c", "d " },
253
254 "", " ", 0, { "" },
255 " ", " ", 2, { "", "" },
256 "x", " ", 1, { "x" },
257 "xy", " ", 1, { "xy" },
258 "x y", " ", 2, { "x", "y" },
259 "abc def g ", " ", 4, { "abc", "def", "g", "" },
260 " a bcd", " ", 3, { "", "a", "bcd" },
261 "a b c d e f", " ", 6, { "a", "b", "c", "d", "e f" },
262 " a b c d ", " ", 6, { "", "a", "b", "c", "d " },
263
264 "", "", 0, { "" },
265 " ", "", 0, { "" },
266 "x", "", 1, { "x" },
267 "xy", "", 1, { "xy" },
268 "x y", "", 2, { "x", "y" },
269 "abc def g ", "", 3, { "abc", "def", "g" },
270 "\t a bcd", "", 2, { "a", "bcd" },
271 " a \tb\t c ", "", 3, { "a", "b", "c" },
272 "a b c d e ", "", 5, { "a", "b", "c", "d", "e" },
273 "a b\tc d e f", "", 6, { "a", "b", "c", "d", "e f" },
274 " a b c d e f ", "", 6, { "a", "b", "c", "d", "e f " },
275
276 NULL, NULL, 0, { NULL },
277};
278
279regress()
280{
281 char buf[512];
282 register int n;
283 char *fields[RNF+1];
284 register int nf;
285 register int i;
286 register int printit;
287 register char *f;
288
289 for (n = 0; tests[n].str != NULL; n++) {
290 (void) strcpy(buf, tests[n].str);
291 fields[RNF] = NULL;
292 nf = split(buf, fields, RNF, tests[n].seps);
293 printit = 0;
294 if (nf != tests[n].nf) {
295 printf("split `%s' by `%s' gave %d fields, not %d\n",
296 tests[n].str, tests[n].seps, nf, tests[n].nf);
297 printit = 1;
298 } else if (fields[RNF] != NULL) {
299 printf("split() went beyond array end\n");
300 printit = 1;
301 } else {
302 for (i = 0; i < nf && i < RNF; i++) {
303 f = fields[i];
304 if (f == NULL)
305 f = "(NULL)";
306 if (strcmp(f, tests[n].fi[i]) != 0) {
307 printf("split `%s' by `%s', field %d is `%s', not `%s'\n",
308 tests[n].str, tests[n].seps,
309 i, fields[i], tests[n].fi[i]);
310 printit = 1;
311 }
312 }
313 }
314 if (printit)
315 print(nf, RNF, fields);
316 }
317}
318#endif
diff --git a/src/regress/lib/libc/regex/tests b/src/regress/lib/libc/regex/tests
new file mode 100644
index 0000000000..8e89f161b1
--- /dev/null
+++ b/src/regress/lib/libc/regex/tests
@@ -0,0 +1,477 @@
1# $NetBSD: tests,v 1.5 1995/04/20 22:40:00 cgd Exp $
2
3# regular expression test set
4# Lines are at least three fields, separated by one or more tabs. "" stands
5# for an empty field. First field is an RE. Second field is flags. If
6# C flag given, regcomp() is expected to fail, and the third field is the
7# error name (minus the leading REG_).
8#
9# Otherwise it is expected to succeed, and the third field is the string to
10# try matching it against. If there is no fourth field, the match is
11# expected to fail. If there is a fourth field, it is the substring that
12# the RE is expected to match. If there is a fifth field, it is a comma-
13# separated list of what the subexpressions should match, with - indicating
14# no match for that one. In both the fourth and fifth fields, a (sub)field
15# starting with @ indicates that the (sub)expression is expected to match
16# a null string followed by the stuff after the @; this provides a way to
17# test where null strings match. The character `N' in REs and strings
18# is newline, `S' is space, `T' is tab, `Z' is NUL.
19#
20# The full list of flags:
21# - placeholder, does nothing
22# b RE is a BRE, not an ERE
23# & try it as both an ERE and a BRE
24# C regcomp() error expected, third field is error name
25# i REG_ICASE
26# m ("mundane") REG_NOSPEC
27# s REG_NOSUB (not really testable)
28# n REG_NEWLINE
29# ^ REG_NOTBOL
30# $ REG_NOTEOL
31# # REG_STARTEND (see below)
32# p REG_PEND
33#
34# For REG_STARTEND, the start/end offsets are those of the substring
35# enclosed in ().
36
37# basics
38a & a a
39abc & abc abc
40abc|de - abc abc
41a|b|c - abc a
42
43# parentheses and perversions thereof
44a(b)c - abc abc
45a\(b\)c b abc abc
46a( C EPAREN
47a( b a( a(
48a\( - a( a(
49a\( bC EPAREN
50a\(b bC EPAREN
51a(b C EPAREN
52a(b b a(b a(b
53# gag me with a right parenthesis -- 1003.2 goofed here (my fault, partly)
54a) - a) a)
55) - ) )
56# end gagging (in a just world, those *should* give EPAREN)
57a) b a) a)
58a\) bC EPAREN
59\) bC EPAREN
60a()b - ab ab
61a\(\)b b ab ab
62
63# anchoring and REG_NEWLINE
64^abc$ & abc abc
65a^b - a^b
66a^b b a^b a^b
67a$b - a$b
68a$b b a$b a$b
69^ & abc @abc
70$ & abc @
71^$ & "" @
72$^ - "" @
73\($\)\(^\) b "" @
74# stop retching, those are legitimate (although disgusting)
75^^ - "" @
76$$ - "" @
77b$ & abNc
78b$ &n abNc b
79^b$ & aNbNc
80^b$ &n aNbNc b
81^$ &n aNNb @Nb
82^$ n abc
83^$ n abcN @
84$^ n aNNb @Nb
85\($\)\(^\) bn aNNb @Nb
86^^ n^ aNNb @Nb
87$$ n aNNb @NN
88^a ^ a
89a$ $ a
90^a ^n aNb
91^b ^n aNb b
92a$ $n bNa
93b$ $n bNa b
94a*(^b$)c* - b b
95a*\(^b$\)c* b b b
96
97# certain syntax errors and non-errors
98| C EMPTY
99| b | |
100* C BADRPT
101* b * *
102+ C BADRPT
103? C BADRPT
104"" &C EMPTY
105() - abc @abc
106\(\) b abc @abc
107a||b C EMPTY
108|ab C EMPTY
109ab| C EMPTY
110(|a)b C EMPTY
111(a|)b C EMPTY
112(*a) C BADRPT
113(+a) C BADRPT
114(?a) C BADRPT
115({1}a) C BADRPT
116\(\{1\}a\) bC BADRPT
117(a|*b) C BADRPT
118(a|+b) C BADRPT
119(a|?b) C BADRPT
120(a|{1}b) C BADRPT
121^* C BADRPT
122^* b * *
123^+ C BADRPT
124^? C BADRPT
125^{1} C BADRPT
126^\{1\} bC BADRPT
127
128# metacharacters, backslashes
129a.c & abc abc
130a[bc]d & abd abd
131a\*c & a*c a*c
132a\\b & a\b a\b
133a\\\*b & a\*b a\*b
134a\bc & abc abc
135a\ &C EESCAPE
136a\\bc & a\bc a\bc
137\{ bC BADRPT
138a\[b & a[b a[b
139a[b &C EBRACK
140# trailing $ is a peculiar special case for the BRE code
141a$ & a a
142a$ & a$
143a\$ & a
144a\$ & a$ a$
145a\\$ & a
146a\\$ & a$
147a\\$ & a\$
148a\\$ & a\ a\
149
150# back references, ugh
151a\(b\)\2c bC ESUBREG
152a\(b\1\)c bC ESUBREG
153a\(b*\)c\1d b abbcbbd abbcbbd bb
154a\(b*\)c\1d b abbcbd
155a\(b*\)c\1d b abbcbbbd
156^\(.\)\1 b abc
157a\([bc]\)\1d b abcdabbd abbd b
158a\(\([bc]\)\2\)*d b abbccd abbccd
159a\(\([bc]\)\2\)*d b abbcbd
160# actually, this next one probably ought to fail, but the spec is unclear
161a\(\(b\)*\2\)*d b abbbd abbbd
162# here is a case that no NFA implementation does right
163\(ab*\)[ab]*\1 b ababaaa ababaaa a
164# check out normal matching in the presence of back refs
165\(a\)\1bcd b aabcd aabcd
166\(a\)\1bc*d b aabcd aabcd
167\(a\)\1bc*d b aabd aabd
168\(a\)\1bc*d b aabcccd aabcccd
169\(a\)\1bc*[ce]d b aabcccd aabcccd
170^\(a\)\1b\(c\)*cd$ b aabcccd aabcccd
171
172# ordinary repetitions
173ab*c & abc abc
174ab+c - abc abc
175ab?c - abc abc
176a\(*\)b b a*b a*b
177a\(**\)b b ab ab
178a\(***\)b bC BADRPT
179*a b *a *a
180**a b a a
181***a bC BADRPT
182
183# the dreaded bounded repetitions
184{ & { {
185{abc & {abc {abc
186{1 C BADRPT
187{1} C BADRPT
188a{b & a{b a{b
189a{1}b - ab ab
190a\{1\}b b ab ab
191a{1,}b - ab ab
192a\{1,\}b b ab ab
193a{1,2}b - aab aab
194a\{1,2\}b b aab aab
195a{1 C EBRACE
196a\{1 bC EBRACE
197a{1a C EBRACE
198a\{1a bC EBRACE
199a{1a} C BADBR
200a\{1a\} bC BADBR
201a{,2} - a{,2} a{,2}
202a\{,2\} bC BADBR
203a{,} - a{,} a{,}
204a\{,\} bC BADBR
205a{1,x} C BADBR
206a\{1,x\} bC BADBR
207a{1,x C EBRACE
208a\{1,x bC EBRACE
209a{300} C BADBR
210a\{300\} bC BADBR
211a{1,0} C BADBR
212a\{1,0\} bC BADBR
213ab{0,0}c - abcac ac
214ab\{0,0\}c b abcac ac
215ab{0,1}c - abcac abc
216ab\{0,1\}c b abcac abc
217ab{0,3}c - abbcac abbc
218ab\{0,3\}c b abbcac abbc
219ab{1,1}c - acabc abc
220ab\{1,1\}c b acabc abc
221ab{1,3}c - acabc abc
222ab\{1,3\}c b acabc abc
223ab{2,2}c - abcabbc abbc
224ab\{2,2\}c b abcabbc abbc
225ab{2,4}c - abcabbc abbc
226ab\{2,4\}c b abcabbc abbc
227((a{1,10}){1,10}){1,10} - a a a,a
228
229# multiple repetitions
230a** &C BADRPT
231a++ C BADRPT
232a?? C BADRPT
233a*+ C BADRPT
234a*? C BADRPT
235a+* C BADRPT
236a+? C BADRPT
237a?* C BADRPT
238a?+ C BADRPT
239a{1}{1} C BADRPT
240a*{1} C BADRPT
241a+{1} C BADRPT
242a?{1} C BADRPT
243a{1}* C BADRPT
244a{1}+ C BADRPT
245a{1}? C BADRPT
246a*{b} - a{b} a{b}
247a\{1\}\{1\} bC BADRPT
248a*\{1\} bC BADRPT
249a\{1\}* bC BADRPT
250
251# brackets, and numerous perversions thereof
252a[b]c & abc abc
253a[ab]c & abc abc
254a[^ab]c & adc adc
255a[]b]c & a]c a]c
256a[[b]c & a[c a[c
257a[-b]c & a-c a-c
258a[^]b]c & adc adc
259a[^-b]c & adc adc
260a[b-]c & a-c a-c
261a[b &C EBRACK
262a[] &C EBRACK
263a[1-3]c & a2c a2c
264a[3-1]c &C ERANGE
265a[1-3-5]c &C ERANGE
266a[[.-.]--]c & a-c a-c
267a[1- &C ERANGE
268a[[. &C EBRACK
269a[[.x &C EBRACK
270a[[.x. &C EBRACK
271a[[.x.] &C EBRACK
272a[[.x.]] & ax ax
273a[[.x,.]] &C ECOLLATE
274a[[.one.]]b & a1b a1b
275a[[.notdef.]]b &C ECOLLATE
276a[[.].]]b & a]b a]b
277a[[:alpha:]]c & abc abc
278a[[:notdef:]]c &C ECTYPE
279a[[: &C EBRACK
280a[[:alpha &C EBRACK
281a[[:alpha:] &C EBRACK
282a[[:alpha,:] &C ECTYPE
283a[[:]:]]b &C ECTYPE
284a[[:-:]]b &C ECTYPE
285a[[:alph:]] &C ECTYPE
286a[[:alphabet:]] &C ECTYPE
287[[:alnum:]]+ - -%@a0X- a0X
288[[:alpha:]]+ - -%@aX0- aX
289[[:blank:]]+ - aSSTb SST
290[[:cntrl:]]+ - aNTb NT
291[[:digit:]]+ - a019b 019
292[[:graph:]]+ - Sa%bS a%b
293[[:lower:]]+ - AabC ab
294[[:print:]]+ - NaSbN aSb
295[[:punct:]]+ - S%-&T %-&
296[[:space:]]+ - aSNTb SNT
297[[:upper:]]+ - aBCd BC
298[[:xdigit:]]+ - p0f3Cq 0f3C
299a[[=b=]]c & abc abc
300a[[= &C EBRACK
301a[[=b &C EBRACK
302a[[=b= &C EBRACK
303a[[=b=] &C EBRACK
304a[[=b,=]] &C ECOLLATE
305a[[=one=]]b & a1b a1b
306
307# complexities
308a(((b)))c - abc abc
309a(b|(c))d - abd abd
310a(b*|c)d - abbd abbd
311# just gotta have one DFA-buster, of course
312a[ab]{20} - aaaaabaaaabaaaabaaaab aaaaabaaaabaaaabaaaab
313# and an inline expansion in case somebody gets tricky
314a[ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab] - aaaaabaaaabaaaabaaaab aaaaabaaaabaaaabaaaab
315# and in case somebody just slips in an NFA...
316a[ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab](wee|week)(knights|night) - aaaaabaaaabaaaabaaaabweeknights aaaaabaaaabaaaabaaaabweeknights
317# fish for anomalies as the number of states passes 32
31812345678901234567890123456789 - a12345678901234567890123456789b 12345678901234567890123456789
319123456789012345678901234567890 - a123456789012345678901234567890b 123456789012345678901234567890
3201234567890123456789012345678901 - a1234567890123456789012345678901b 1234567890123456789012345678901
32112345678901234567890123456789012 - a12345678901234567890123456789012b 12345678901234567890123456789012
322123456789012345678901234567890123 - a123456789012345678901234567890123b 123456789012345678901234567890123
323# and one really big one, beyond any plausible word width
3241234567890123456789012345678901234567890123456789012345678901234567890 - a1234567890123456789012345678901234567890123456789012345678901234567890b 1234567890123456789012345678901234567890123456789012345678901234567890
325# fish for problems as brackets go past 8
326[ab][cd][ef][gh][ij][kl][mn] - xacegikmoq acegikm
327[ab][cd][ef][gh][ij][kl][mn][op] - xacegikmoq acegikmo
328[ab][cd][ef][gh][ij][kl][mn][op][qr] - xacegikmoqy acegikmoq
329[ab][cd][ef][gh][ij][kl][mn][op][q] - xacegikmoqy acegikmoq
330
331# subtleties of matching
332abc & xabcy abc
333a\(b\)?c\1d b acd
334aBc i Abc Abc
335a[Bc]*d i abBCcd abBCcd
3360[[:upper:]]1 &i 0a1 0a1
3370[[:lower:]]1 &i 0A1 0A1
338a[^b]c &i abc
339a[^b]c &i aBc
340a[^b]c &i adc adc
341[a]b[c] - abc abc
342[a]b[a] - aba aba
343[abc]b[abc] - abc abc
344[abc]b[abd] - abd abd
345a(b?c)+d - accd accd
346(wee|week)(knights|night) - weeknights weeknights
347(we|wee|week|frob)(knights|night|day) - weeknights weeknights
348a[bc]d - xyzaaabcaababdacd abd
349a[ab]c - aaabc abc
350abc s abc abc
351a* & b @b
352
353# Let's have some fun -- try to match a C comment.
354# first the obvious, which looks okay at first glance...
355/\*.*\*/ - /*x*/ /*x*/
356# but...
357/\*.*\*/ - /*x*/y/*z*/ /*x*/y/*z*/
358# okay, we must not match */ inside; try to do that...
359/\*([^*]|\*[^/])*\*/ - /*x*/ /*x*/
360/\*([^*]|\*[^/])*\*/ - /*x*/y/*z*/ /*x*/
361# but...
362/\*([^*]|\*[^/])*\*/ - /*x**/y/*z*/ /*x**/y/*z*/
363# and a still fancier version, which does it right (I think)...
364/\*([^*]|\*+[^*/])*\*+/ - /*x*/ /*x*/
365/\*([^*]|\*+[^*/])*\*+/ - /*x*/y/*z*/ /*x*/
366/\*([^*]|\*+[^*/])*\*+/ - /*x**/y/*z*/ /*x**/
367/\*([^*]|\*+[^*/])*\*+/ - /*x****/y/*z*/ /*x****/
368/\*([^*]|\*+[^*/])*\*+/ - /*x**x*/y/*z*/ /*x**x*/
369/\*([^*]|\*+[^*/])*\*+/ - /*x***x/y/*z*/ /*x***x/y/*z*/
370
371# subexpressions
372a(b)(c)d - abcd abcd b,c
373a(((b)))c - abc abc b,b,b
374a(b|(c))d - abd abd b,-
375a(b*|c|e)d - abbd abbd bb
376a(b*|c|e)d - acd acd c
377a(b*|c|e)d - ad ad @d
378a(b?)c - abc abc b
379a(b?)c - ac ac @c
380a(b+)c - abc abc b
381a(b+)c - abbbc abbbc bbb
382a(b*)c - ac ac @c
383(a|ab)(bc([de]+)f|cde) - abcdef abcdef a,bcdef,de
384# the regression tester only asks for 9 subexpressions
385a(b)(c)(d)(e)(f)(g)(h)(i)(j)k - abcdefghijk abcdefghijk b,c,d,e,f,g,h,i,j
386a(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)l - abcdefghijkl abcdefghijkl b,c,d,e,f,g,h,i,j,k
387a([bc]?)c - abc abc b
388a([bc]?)c - ac ac @c
389a([bc]+)c - abc abc b
390a([bc]+)c - abcc abcc bc
391a([bc]+)bc - abcbc abcbc bc
392a(bb+|b)b - abb abb b
393a(bbb+|bb+|b)b - abb abb b
394a(bbb+|bb+|b)b - abbb abbb bb
395a(bbb+|bb+|b)bb - abbb abbb b
396(.*).* - abcdef abcdef abcdef
397(a*)* - bc @b @b
398
399# do we get the right subexpression when it is used more than once?
400a(b|c)*d - ad ad -
401a(b|c)*d - abcd abcd c
402a(b|c)+d - abd abd b
403a(b|c)+d - abcd abcd c
404a(b|c?)+d - ad ad @d
405a(b|c?)+d - abcd abcd @d
406a(b|c){0,0}d - ad ad -
407a(b|c){0,1}d - ad ad -
408a(b|c){0,1}d - abd abd b
409a(b|c){0,2}d - ad ad -
410a(b|c){0,2}d - abcd abcd c
411a(b|c){0,}d - ad ad -
412a(b|c){0,}d - abcd abcd c
413a(b|c){1,1}d - abd abd b
414a(b|c){1,1}d - acd acd c
415a(b|c){1,2}d - abd abd b
416a(b|c){1,2}d - abcd abcd c
417a(b|c){1,}d - abd abd b
418a(b|c){1,}d - abcd abcd c
419a(b|c){2,2}d - acbd acbd b
420a(b|c){2,2}d - abcd abcd c
421a(b|c){2,4}d - abcd abcd c
422a(b|c){2,4}d - abcbd abcbd b
423a(b|c){2,4}d - abcbcd abcbcd c
424a(b|c){2,}d - abcd abcd c
425a(b|c){2,}d - abcbd abcbd b
426a(b+|((c)*))+d - abd abd @d,@d,-
427a(b+|((c)*))+d - abcd abcd @d,@d,-
428
429# check out the STARTEND option
430[abc] &# a(b)c b
431[abc] &# a(d)c
432[abc] &# a(bc)d b
433[abc] &# a(dc)d c
434. &# a()c
435b.*c &# b(bc)c bc
436b.* &# b(bc)c bc
437.*c &# b(bc)c bc
438
439# plain strings, with the NOSPEC flag
440abc m abc abc
441abc m xabcy abc
442abc m xyz
443a*b m aba*b a*b
444a*b m ab
445"" mC EMPTY
446
447# cases involving NULs
448aZb & a a
449aZb &p a
450aZb &p# (aZb) aZb
451aZ*b &p# (ab) ab
452a.b &# (aZb) aZb
453a.* &# (aZb)c aZb
454
455# word boundaries (ick)
456[[:<:]]a & a a
457[[:<:]]a & ba
458[[:<:]]a & -a a
459a[[:>:]] & a a
460a[[:>:]] & ab
461a[[:>:]] & a- a
462[[:<:]]a.c[[:>:]] & axcd-dayc-dazce-abc abc
463[[:<:]]a.c[[:>:]] & axcd-dayc-dazce-abc-q abc
464[[:<:]]a.c[[:>:]] & axc-dayc-dazce-abc axc
465[[:<:]]b.c[[:>:]] & a_bxc-byc_d-bzc-q bzc
466[[:<:]].x..[[:>:]] & y_xa_-_xb_y-_xc_-axdc _xc_
467[[:<:]]a_b[[:>:]] & x_a_b
468
469# past problems, and suspected problems
470(A[1])|(A[2])|(A[3])|(A[4])|(A[5])|(A[6])|(A[7])|(A[8])|(A[9])|(A[A]) - A1 A1
471abcdefghijklmnop i abcdefghijklmnop abcdefghijklmnop
472abcdefghijklmnopqrstuv i abcdefghijklmnopqrstuv abcdefghijklmnopqrstuv
473(ALAK)|(ALT[AB])|(CC[123]1)|(CM[123]1)|(GAMC)|(LC[23][EO ])|(SEM[1234])|(SL[ES][12])|(SLWW)|(SLF )|(SLDT)|(VWH[12])|(WH[34][EW])|(WP1[ESN]) - CC11 CC11
474CC[13]1|a{21}[23][EO][123][Es][12]a{15}aa[34][EW]aaaaaaa[X]a - CC11 CC11
475Char \([a-z0-9_]*\)\[.* b Char xyz[k Char xyz[k xyz
476a?b - ab ab
477-\{0,1\}[0-9]*$ b -5 -5
diff --git a/src/regress/lib/libc/setjmp/Makefile b/src/regress/lib/libc/setjmp/Makefile
new file mode 100644
index 0000000000..25bf99d4cb
--- /dev/null
+++ b/src/regress/lib/libc/setjmp/Makefile
@@ -0,0 +1,16 @@
1# $NetBSD: Makefile,v 1.2 1995/04/20 22:40:13 cgd Exp $
2
3PROG= setjmptest
4SRCS= jmptest.c
5NOMAN= noman, no way, man
6
7CFLAGS+= -DTEST_SETJMP
8
9.PATH: ${.CURDIR}/../setjmp
10
11install:
12
13regress: ${PROG}
14 ./${PROG}
15
16.include <bsd.prog.mk>
diff --git a/src/regress/lib/libc/setjmp/jmptest.c b/src/regress/lib/libc/setjmp/jmptest.c
new file mode 100644
index 0000000000..f2cecc9178
--- /dev/null
+++ b/src/regress/lib/libc/setjmp/jmptest.c
@@ -0,0 +1,134 @@
1/* $NetBSD: jmptest.c,v 1.2 1995/01/01 20:55:35 jtc Exp $ */
2
3/*
4 * Copyright (c) 1994 Christopher G. Demetriou
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by Christopher G. Demetriou
18 * for the NetBSD Project.
19 * 4. The name of the author may not be used to endorse or promote products
20 * derived from this software without specific prior written permission
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34#include <sys/types.h>
35#include <setjmp.h>
36#include <signal.h>
37#include <stdio.h>
38#include <stdlib.h>
39#include <unistd.h>
40
41#if (TEST_SETJMP + TEST_U_SETJMP + TEST_SIGSETJMP) != 1
42#error one of TEST_SETJMP, TEST_U_SETJMP, or TEST_SIGSETJMP must be defined
43#endif
44
45#ifdef TEST_SETJMP
46#define BUF jmp_buf
47#define SET(b, m) setjmp(b)
48#define JMP(b, v) longjmp(b, v)
49#endif
50
51#ifdef TEST_U_SETJMP
52#define BUF jmp_buf
53#define SET(b, m) _setjmp(b)
54#define JMP(b, v) _longjmp(b, v)
55#endif
56
57#ifdef TEST_SIGSETJMP
58#define BUF sigjmp_buf
59#define SET(b, m) sigsetjmp(b, m)
60#define JMP(b, v) siglongjmp(b, v)
61#endif
62
63int expectsignal;
64
65void
66aborthandler(signo)
67 int signo;
68{
69
70 if (expectsignal)
71 exit(0);
72 else
73 errx(1, "kill(SIGABRT) succeeded");
74}
75
76int
77main(argc, argv)
78 int argc;
79 char *argv[];
80{
81 struct sigaction sa;
82 BUF jb;
83 sigset_t ss;
84 int i, x;
85
86 i = getpid();
87
88#ifdef TEST_SETJMP
89 expectsignal = 0;
90#endif
91#ifdef TEST_U_SETJMP
92 expectsignal = 1;
93#endif
94#ifdef TEST_SIGSETJMP
95 if (argc != 2 ||
96 (strcmp(argv[1], "save") && strcmp(argv[1], "nosave"))) {
97 fprintf(stderr, "usage: %s [save|nosave]\n", argv[0]);
98 exit(1);
99 }
100 expectsignal = (strcmp(argv[1], "save") != 0);
101#endif
102
103 sa.sa_handler = aborthandler;
104 sa.sa_mask = 0;
105 sa.sa_flags = 0;
106 if (sigaction(SIGABRT, &sa, NULL) == -1)
107 err(1, "sigaction failed");
108
109 if (sigemptyset(&ss) == -1)
110 err(1, "sigemptyset failed");
111 if (sigaddset(&ss, SIGABRT) == -1)
112 err(1, "sigaddset failed");
113 if (sigprocmask(SIG_BLOCK, &ss, NULL) == -1)
114 err(1, "sigprocmask (1) failed");
115
116 x = SET(jb, !expectsignal);
117 if (x != 0) {
118 if (x != i)
119 errx(1, "setjmp returned wrong value");
120
121 kill(i, SIGABRT);
122 if (expectsignal)
123 errx(1, "kill(SIGABRT) failed");
124 else
125 exit(0);
126 }
127
128 if (sigprocmask(SIG_UNBLOCK, &ss, NULL) == -1)
129 err(1, "sigprocmask (2) failed");
130
131 JMP(jb, i);
132
133 errx(1, "jmp failed");
134}
diff --git a/src/regress/lib/libc/sigsetjmp/Makefile b/src/regress/lib/libc/sigsetjmp/Makefile
new file mode 100644
index 0000000000..41682fcb66
--- /dev/null
+++ b/src/regress/lib/libc/sigsetjmp/Makefile
@@ -0,0 +1,17 @@
1# $NetBSD: Makefile,v 1.2 1995/04/20 22:40:40 cgd Exp $
2
3PROG= sigsetjmptest
4SRCS= jmptest.c
5NOMAN= noman, no way, man
6
7CFLAGS+= -DTEST_SIGSETJMP
8
9.PATH: ${.CURDIR}/../setjmp
10
11install:
12
13regress: ${PROG}
14 ./${PROG} save
15 ./${PROG} nosave
16
17.include <bsd.prog.mk>