summaryrefslogtreecommitdiff
path: root/src/regress/lib/libc
diff options
context:
space:
mode:
Diffstat (limited to 'src/regress/lib/libc')
-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/README68
-rw-r--r--src/regress/lib/libc/db/dbtest.c759
-rw-r--r--src/regress/lib/libc/db/run.test706
-rw-r--r--src/regress/lib/libc/ieeefp/Makefile9
-rw-r--r--src/regress/lib/libc/ieeefp/except/Makefile12
-rw-r--r--src/regress/lib/libc/ieeefp/except/except.c88
-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.c515
-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.c135
-rw-r--r--src/regress/lib/libc/sigsetjmp/Makefile17
26 files changed, 3874 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..d42dc96315
--- /dev/null
+++ b/src/regress/lib/libc/db/Makefile
@@ -0,0 +1,17 @@
1# $NetBSD: Makefile,v 1.11 1995/12/12 01:54:15 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..fddf5c3d5a
--- /dev/null
+++ b/src/regress/lib/libc/db/README
@@ -0,0 +1,68 @@
1# $NetBSD: README,v 1.5 1996/05/03 21:54:19 cgd Exp $
2# @(#)README 8.8 (Berkeley) 7/31/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 an initial character which is
13the command for that line, or an initial character indicating a key
14or data entry for a previous command.
15
16Legal command characters are as follows:
17
18c: compare a record
19 + must be followed by [kK][dD]; the data value in the database
20 associated with the specified key is compared to the specified
21 data value.
22e: echo a string
23 + writes out the rest of the line into the output file; if the
24 last character is not a carriage-return, a newline is appended.
25f: set the flags for the next command
26 + no value zero's the flags
27g: do a get command
28 + must be followed by [kK]
29 + writes out the retrieved data DBT.
30o [r]: dump [reverse]
31 + dump the database out, if 'r' is set, in reverse order.
32p: do a put command
33 + must be followed by [kK][dD]
34r: do a del command
35 + must be followed by [kK] unless R_CURSOR flag set.
36S: sync the database
37s: do a seq command
38 + must be followed by [kK] if R_CURSOR flag set.
39 + writes out the retrieved data DBT.
40
41Legal key/data characters are as follows:
42
43D [file]: data file
44 + set the current data value to the contents of the file
45d [data]:
46 + set the current key value to the contents of the line.
47K [file]: key file
48 + set the current key value to the contents of the file
49k [data]:
50 + set the current key value to the contents of the line.
51
52Blank lines, lines with leading white space, and lines with leading
53hash marks (#) are ignored.
54
55Options to dbtest are as follows:
56
57 -d: Set the DB_LOCK flag.
58 -f: Use the file argument as the database file.
59 -i: Use the rest of the argument to set elements in the info
60 structure. If the type is btree, then "-i cachesize=10240"
61 will set BTREEINFO.cachesize to 10240.
62 -o: The rest of the argument is the output file instead of
63 using stdout.
64 -s: Don't delete the database file before opening it, i.e.
65 use the database file from a previous run.
66
67Dbtest requires two arguments, the type of access "hash", "recno"
68or "btree", and the script name or "-" to indicate stdin.
diff --git a/src/regress/lib/libc/db/dbtest.c b/src/regress/lib/libc/db/dbtest.c
new file mode 100644
index 0000000000..6ccfba5011
--- /dev/null
+++ b/src/regress/lib/libc/db/dbtest.c
@@ -0,0 +1,759 @@
1/* $NetBSD: dbtest.c,v 1.8 1996/05/03 21:57:48 cgd Exp $ */
2
3/*-
4 * Copyright (c) 1992, 1993, 1994
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, 1994\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.17 (Berkeley) 9/1/94";
45#else
46static char rcsid[] = "$NetBSD: dbtest.c,v 1.8 1996/05/03 21:57:48 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 *));
74char *sflags __P((int));
75void synk __P((DB *));
76void *rfile __P((char *, size_t *));
77void seq __P((DB *, DBT *));
78u_int setflags __P((char *));
79void *setinfo __P((DBTYPE, char *));
80void usage __P((void));
81void *xmalloc __P((char *, size_t));
82
83DBTYPE type; /* Database type. */
84void *infop; /* Iflags. */
85u_long lineno; /* Current line in test script. */
86u_int flags; /* Current DB flags. */
87int ofd = STDOUT_FILENO; /* Standard output fd. */
88
89DB *XXdbp; /* Global for gdb. */
90int XXlineno; /* Fast breakpoint for gdb. */
91
92int
93main(argc, argv)
94 int argc;
95 char *argv[];
96{
97 extern int optind;
98 extern char *optarg;
99 enum S command, state;
100 DB *dbp;
101 DBT data, key, keydata;
102 size_t len;
103 int ch, oflags, sflag;
104 char *fname, *infoarg, *p, *t, buf[8 * 1024];
105
106 infoarg = NULL;
107 fname = NULL;
108 oflags = O_CREAT | O_RDWR;
109 sflag = 0;
110 while ((ch = getopt(argc, argv, "f:i:lo:s")) != -1)
111 switch (ch) {
112 case 'f':
113 fname = optarg;
114 break;
115 case 'i':
116 infoarg = optarg;
117 break;
118 case 'l':
119 oflags |= DB_LOCK;
120 break;
121 case 'o':
122 if ((ofd = open(optarg,
123 O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0)
124 err("%s: %s", optarg, strerror(errno));
125 break;
126 case 's':
127 sflag = 1;
128 break;
129 case '?':
130 default:
131 usage();
132 }
133 argc -= optind;
134 argv += optind;
135
136 if (argc != 2)
137 usage();
138
139 /* Set the type. */
140 type = dbtype(*argv++);
141
142 /* Open the descriptor file. */
143 if (strcmp(*argv, "-") && freopen(*argv, "r", stdin) == NULL)
144 err("%s: %s", *argv, strerror(errno));
145
146 /* Set up the db structure as necessary. */
147 if (infoarg == NULL)
148 infop = NULL;
149 else
150 for (p = strtok(infoarg, ",\t "); p != NULL;
151 p = strtok(0, ",\t "))
152 if (*p != '\0')
153 infop = setinfo(type, p);
154
155 /*
156 * Open the DB. Delete any preexisting copy, you almost never
157 * want it around, and it often screws up tests.
158 */
159 if (fname == NULL) {
160 p = getenv("TMPDIR");
161 if (p == NULL)
162 p = "/var/tmp";
163 (void)sprintf(buf, "%s/__dbtest", p);
164 fname = buf;
165 (void)unlink(buf);
166 } else if (!sflag)
167 (void)unlink(fname);
168
169 if ((dbp = dbopen(fname,
170 oflags, S_IRUSR | S_IWUSR, type, infop)) == NULL)
171 err("dbopen: %s", strerror(errno));
172 XXdbp = dbp;
173
174 state = COMMAND;
175 for (lineno = 1;
176 (p = fgets(buf, sizeof(buf), stdin)) != NULL; ++lineno) {
177 /* Delete the newline, displaying the key/data is easier. */
178 if (ofd == STDOUT_FILENO && (t = strchr(p, '\n')) != NULL)
179 *t = '\0';
180 if ((len = strlen(buf)) == 0 || isspace(*p) || *p == '#')
181 continue;
182
183 /* Convenient gdb break point. */
184 if (XXlineno == lineno)
185 XXlineno = 1;
186 switch (*p) {
187 case 'c': /* compare */
188 if (state != COMMAND)
189 err("line %lu: not expecting command", lineno);
190 state = KEY;
191 command = COMPARE;
192 break;
193 case 'e': /* echo */
194 if (state != COMMAND)
195 err("line %lu: not expecting command", lineno);
196 /* Don't display the newline, if CR at EOL. */
197 if (p[len - 2] == '\r')
198 --len;
199 if (write(ofd, p + 1, len - 1) != len - 1 ||
200 write(ofd, "\n", 1) != 1)
201 err("write: %s", strerror(errno));
202 break;
203 case 'g': /* get */
204 if (state != COMMAND)
205 err("line %lu: not expecting command", lineno);
206 state = KEY;
207 command = GET;
208 break;
209 case 'p': /* put */
210 if (state != COMMAND)
211 err("line %lu: not expecting command", lineno);
212 state = KEY;
213 command = PUT;
214 break;
215 case 'r': /* remove */
216 if (state != COMMAND)
217 err("line %lu: not expecting command", lineno);
218 if (flags == R_CURSOR) {
219 rem(dbp, &key);
220 state = COMMAND;
221 } else {
222 state = KEY;
223 command = REMOVE;
224 }
225 break;
226 case 'S': /* sync */
227 if (state != COMMAND)
228 err("line %lu: not expecting command", lineno);
229 synk(dbp);
230 state = COMMAND;
231 break;
232 case 's': /* seq */
233 if (state != COMMAND)
234 err("line %lu: not expecting command", lineno);
235 if (flags == R_CURSOR) {
236 state = KEY;
237 command = SEQ;
238 } else
239 seq(dbp, &key);
240 break;
241 case 'f':
242 flags = setflags(p + 1);
243 break;
244 case 'D': /* data file */
245 if (state != DATA)
246 err("line %lu: not expecting data", lineno);
247 data.data = rfile(p + 1, &data.size);
248 goto ldata;
249 case 'd': /* data */
250 if (state != DATA)
251 err("line %lu: not expecting data", lineno);
252 data.data = xmalloc(p + 1, len - 1);
253 data.size = len - 1;
254ldata: switch (command) {
255 case COMPARE:
256 compare(&keydata, &data);
257 break;
258 case PUT:
259 put(dbp, &key, &data);
260 break;
261 default:
262 err("line %lu: command doesn't take data",
263 lineno);
264 }
265 if (type != DB_RECNO)
266 free(key.data);
267 free(data.data);
268 state = COMMAND;
269 break;
270 case 'K': /* key file */
271 if (state != KEY)
272 err("line %lu: not expecting a key", lineno);
273 if (type == DB_RECNO)
274 err("line %lu: 'K' not available for recno",
275 lineno);
276 key.data = rfile(p + 1, &key.size);
277 goto lkey;
278 case 'k': /* key */
279 if (state != KEY)
280 err("line %lu: not expecting a key", lineno);
281 if (type == DB_RECNO) {
282 static recno_t recno;
283 recno = atoi(p + 1);
284 key.data = &recno;
285 key.size = sizeof(recno);
286 } else {
287 key.data = xmalloc(p + 1, len - 1);
288 key.size = len - 1;
289 }
290lkey: switch (command) {
291 case COMPARE:
292 getdata(dbp, &key, &keydata);
293 state = DATA;
294 break;
295 case GET:
296 get(dbp, &key);
297 if (type != DB_RECNO)
298 free(key.data);
299 state = COMMAND;
300 break;
301 case PUT:
302 state = DATA;
303 break;
304 case REMOVE:
305 rem(dbp, &key);
306 if ((type != DB_RECNO) && (flags != R_CURSOR))
307 free(key.data);
308 state = COMMAND;
309 break;
310 case SEQ:
311 seq(dbp, &key);
312 if ((type != DB_RECNO) && (flags != R_CURSOR))
313 free(key.data);
314 state = COMMAND;
315 break;
316 default:
317 err("line %lu: command doesn't take a key",
318 lineno);
319 }
320 break;
321 case 'o':
322 dump(dbp, p[1] == 'r');
323 break;
324 default:
325 err("line %lu: %s: unknown command character",
326 lineno, p);
327 }
328 }
329#ifdef STATISTICS
330 /*
331 * -l must be used (DB_LOCK must be set) for this to be
332 * used, otherwise a page will be locked and it will fail.
333 */
334 if (type == DB_BTREE && oflags & DB_LOCK)
335 __bt_stat(dbp);
336#endif
337 if (dbp->close(dbp))
338 err("db->close: %s", strerror(errno));
339 (void)close(ofd);
340 exit(0);
341}
342
343#define NOOVERWRITE "put failed, would overwrite key\n"
344
345void
346compare(db1, db2)
347 DBT *db1, *db2;
348{
349 register size_t len;
350 register u_char *p1, *p2;
351
352 if (db1->size != db2->size)
353 printf("compare failed: key->data len %lu != data len %lu\n",
354 db1->size, db2->size);
355
356 len = MIN(db1->size, db2->size);
357 for (p1 = db1->data, p2 = db2->data; len--;)
358 if (*p1++ != *p2++) {
359 printf("compare failed at offset %d\n",
360 p1 - (u_char *)db1->data);
361 break;
362 }
363}
364
365void
366get(dbp, kp)
367 DB *dbp;
368 DBT *kp;
369{
370 DBT data;
371
372 switch (dbp->get(dbp, kp, &data, flags)) {
373 case 0:
374 (void)write(ofd, data.data, data.size);
375 if (ofd == STDOUT_FILENO)
376 (void)write(ofd, "\n", 1);
377 break;
378 case -1:
379 err("line %lu: get: %s", lineno, strerror(errno));
380 /* NOTREACHED */
381 case 1:
382#define NOSUCHKEY "get failed, no such key\n"
383 if (ofd != STDOUT_FILENO)
384 (void)write(ofd, NOSUCHKEY, sizeof(NOSUCHKEY) - 1);
385 else
386 (void)fprintf(stderr, "%d: %.*s: %s",
387 lineno, MIN(kp->size, 20), kp->data, NOSUCHKEY);
388#undef NOSUCHKEY
389 break;
390 }
391}
392
393void
394getdata(dbp, kp, dp)
395 DB *dbp;
396 DBT *kp, *dp;
397{
398 switch (dbp->get(dbp, kp, dp, flags)) {
399 case 0:
400 return;
401 case -1:
402 err("line %lu: getdata: %s", lineno, strerror(errno));
403 /* NOTREACHED */
404 case 1:
405 err("line %lu: getdata failed, no such key", lineno);
406 /* NOTREACHED */
407 }
408}
409
410void
411put(dbp, kp, dp)
412 DB *dbp;
413 DBT *kp, *dp;
414{
415 switch (dbp->put(dbp, kp, dp, flags)) {
416 case 0:
417 break;
418 case -1:
419 err("line %lu: put: %s", lineno, strerror(errno));
420 /* NOTREACHED */
421 case 1:
422 (void)write(ofd, NOOVERWRITE, sizeof(NOOVERWRITE) - 1);
423 break;
424 }
425}
426
427void
428rem(dbp, kp)
429 DB *dbp;
430 DBT *kp;
431{
432 switch (dbp->del(dbp, kp, flags)) {
433 case 0:
434 break;
435 case -1:
436 err("line %lu: rem: %s", lineno, strerror(errno));
437 /* NOTREACHED */
438 case 1:
439#define NOSUCHKEY "rem failed, no such key\n"
440 if (ofd != STDOUT_FILENO)
441 (void)write(ofd, NOSUCHKEY, sizeof(NOSUCHKEY) - 1);
442 else if (flags != R_CURSOR)
443 (void)fprintf(stderr, "%d: %.*s: %s",
444 lineno, MIN(kp->size, 20), kp->data, NOSUCHKEY);
445 else
446 (void)fprintf(stderr,
447 "%d: rem of cursor failed\n", lineno);
448#undef NOSUCHKEY
449 break;
450 }
451}
452
453void
454synk(dbp)
455 DB *dbp;
456{
457 switch (dbp->sync(dbp, flags)) {
458 case 0:
459 break;
460 case -1:
461 err("line %lu: synk: %s", lineno, strerror(errno));
462 /* NOTREACHED */
463 }
464}
465
466void
467seq(dbp, kp)
468 DB *dbp;
469 DBT *kp;
470{
471 DBT data;
472
473 switch (dbp->seq(dbp, kp, &data, flags)) {
474 case 0:
475 (void)write(ofd, data.data, data.size);
476 if (ofd == STDOUT_FILENO)
477 (void)write(ofd, "\n", 1);
478 break;
479 case -1:
480 err("line %lu: seq: %s", lineno, strerror(errno));
481 /* NOTREACHED */
482 case 1:
483#define NOSUCHKEY "seq failed, no such key\n"
484 if (ofd != STDOUT_FILENO)
485 (void)write(ofd, NOSUCHKEY, sizeof(NOSUCHKEY) - 1);
486 else if (flags == R_CURSOR)
487 (void)fprintf(stderr, "%d: %.*s: %s",
488 lineno, MIN(kp->size, 20), kp->data, NOSUCHKEY);
489 else
490 (void)fprintf(stderr,
491 "%d: seq (%s) failed\n", lineno, sflags(flags));
492#undef NOSUCHKEY
493 break;
494 }
495}
496
497void
498dump(dbp, rev)
499 DB *dbp;
500 int rev;
501{
502 DBT key, data;
503 int flags, nflags;
504
505 if (rev) {
506 flags = R_LAST;
507 nflags = R_PREV;
508 } else {
509 flags = R_FIRST;
510 nflags = R_NEXT;
511 }
512 for (;; flags = nflags)
513 switch (dbp->seq(dbp, &key, &data, flags)) {
514 case 0:
515 (void)write(ofd, data.data, data.size);
516 if (ofd == STDOUT_FILENO)
517 (void)write(ofd, "\n", 1);
518 break;
519 case 1:
520 goto done;
521 case -1:
522 err("line %lu: (dump) seq: %s",
523 lineno, strerror(errno));
524 /* NOTREACHED */
525 }
526done: return;
527}
528
529u_int
530setflags(s)
531 char *s;
532{
533 char *p;
534
535 for (; isspace(*s); ++s);
536 if (*s == '\n' || *s == '\0')
537 return (0);
538 if ((p = strchr(s, '\n')) != NULL)
539 *p = '\0';
540 if (!strcmp(s, "R_CURSOR")) return (R_CURSOR);
541 if (!strcmp(s, "R_FIRST")) return (R_FIRST);
542 if (!strcmp(s, "R_IAFTER")) return (R_IAFTER);
543 if (!strcmp(s, "R_IBEFORE")) return (R_IBEFORE);
544 if (!strcmp(s, "R_LAST")) return (R_LAST);
545 if (!strcmp(s, "R_NEXT")) return (R_NEXT);
546 if (!strcmp(s, "R_NOOVERWRITE")) return (R_NOOVERWRITE);
547 if (!strcmp(s, "R_PREV")) return (R_PREV);
548 if (!strcmp(s, "R_SETCURSOR")) return (R_SETCURSOR);
549
550 err("line %lu: %s: unknown flag", lineno, s);
551 /* NOTREACHED */
552}
553
554char *
555sflags(flags)
556 int flags;
557{
558 switch (flags) {
559 case R_CURSOR: return ("R_CURSOR");
560 case R_FIRST: return ("R_FIRST");
561 case R_IAFTER: return ("R_IAFTER");
562 case R_IBEFORE: return ("R_IBEFORE");
563 case R_LAST: return ("R_LAST");
564 case R_NEXT: return ("R_NEXT");
565 case R_NOOVERWRITE: return ("R_NOOVERWRITE");
566 case R_PREV: return ("R_PREV");
567 case R_SETCURSOR: return ("R_SETCURSOR");
568 }
569
570 return ("UNKNOWN!");
571}
572
573DBTYPE
574dbtype(s)
575 char *s;
576{
577 if (!strcmp(s, "btree"))
578 return (DB_BTREE);
579 if (!strcmp(s, "hash"))
580 return (DB_HASH);
581 if (!strcmp(s, "recno"))
582 return (DB_RECNO);
583 err("%s: unknown type (use btree, hash or recno)", s);
584 /* NOTREACHED */
585}
586
587void *
588setinfo(type, s)
589 DBTYPE type;
590 char *s;
591{
592 static BTREEINFO ib;
593 static HASHINFO ih;
594 static RECNOINFO rh;
595 char *eq;
596
597 if ((eq = strchr(s, '=')) == NULL)
598 err("%s: illegal structure set statement", s);
599 *eq++ = '\0';
600 if (!isdigit(*eq))
601 err("%s: structure set statement must be a number", s);
602
603 switch (type) {
604 case DB_BTREE:
605 if (!strcmp("flags", s)) {
606 ib.flags = atoi(eq);
607 return (&ib);
608 }
609 if (!strcmp("cachesize", s)) {
610 ib.cachesize = atoi(eq);
611 return (&ib);
612 }
613 if (!strcmp("maxkeypage", s)) {
614 ib.maxkeypage = atoi(eq);
615 return (&ib);
616 }
617 if (!strcmp("minkeypage", s)) {
618 ib.minkeypage = atoi(eq);
619 return (&ib);
620 }
621 if (!strcmp("lorder", s)) {
622 ib.lorder = atoi(eq);
623 return (&ib);
624 }
625 if (!strcmp("psize", s)) {
626 ib.psize = atoi(eq);
627 return (&ib);
628 }
629 break;
630 case DB_HASH:
631 if (!strcmp("bsize", s)) {
632 ih.bsize = atoi(eq);
633 return (&ih);
634 }
635 if (!strcmp("ffactor", s)) {
636 ih.ffactor = atoi(eq);
637 return (&ih);
638 }
639 if (!strcmp("nelem", s)) {
640 ih.nelem = atoi(eq);
641 return (&ih);
642 }
643 if (!strcmp("cachesize", s)) {
644 ih.cachesize = atoi(eq);
645 return (&ih);
646 }
647 if (!strcmp("lorder", s)) {
648 ih.lorder = atoi(eq);
649 return (&ih);
650 }
651 break;
652 case DB_RECNO:
653 if (!strcmp("flags", s)) {
654 rh.flags = atoi(eq);
655 return (&rh);
656 }
657 if (!strcmp("cachesize", s)) {
658 rh.cachesize = atoi(eq);
659 return (&rh);
660 }
661 if (!strcmp("lorder", s)) {
662 rh.lorder = atoi(eq);
663 return (&rh);
664 }
665 if (!strcmp("reclen", s)) {
666 rh.reclen = atoi(eq);
667 return (&rh);
668 }
669 if (!strcmp("bval", s)) {
670 rh.bval = atoi(eq);
671 return (&rh);
672 }
673 if (!strcmp("psize", s)) {
674 rh.psize = atoi(eq);
675 return (&rh);
676 }
677 break;
678 }
679 err("%s: unknown structure value", s);
680 /* NOTREACHED */
681}
682
683void *
684rfile(name, lenp)
685 char *name;
686 size_t *lenp;
687{
688 struct stat sb;
689 void *p;
690 int fd;
691 char *np;
692
693 for (; isspace(*name); ++name);
694 if ((np = strchr(name, '\n')) != NULL)
695 *np = '\0';
696 if ((fd = open(name, O_RDONLY, 0)) < 0 ||
697 fstat(fd, &sb))
698 err("%s: %s\n", name, strerror(errno));
699#ifdef NOT_PORTABLE
700 if (sb.st_size > (off_t)SIZE_T_MAX)
701 err("%s: %s\n", name, strerror(E2BIG));
702#endif
703 if ((p = (void *)malloc((u_int)sb.st_size)) == NULL)
704 err("%s", strerror(errno));
705 (void)read(fd, p, (int)sb.st_size);
706 *lenp = sb.st_size;
707 (void)close(fd);
708 return (p);
709}
710
711void *
712xmalloc(text, len)
713 char *text;
714 size_t len;
715{
716 void *p;
717
718 if ((p = (void *)malloc(len)) == NULL)
719 err("%s", strerror(errno));
720 memmove(p, text, len);
721 return (p);
722}
723
724void
725usage()
726{
727 (void)fprintf(stderr,
728 "usage: dbtest [-l] [-f file] [-i info] [-o file] type script\n");
729 exit(1);
730}
731
732#ifdef __STDC__
733#include <stdarg.h>
734#else
735#include <varargs.h>
736#endif
737
738void
739#ifdef __STDC__
740err(const char *fmt, ...)
741#else
742err(fmt, va_alist)
743 char *fmt;
744 va_dcl
745#endif
746{
747 va_list ap;
748#ifdef __STDC__
749 va_start(ap, fmt);
750#else
751 va_start(ap);
752#endif
753 (void)fprintf(stderr, "dbtest: ");
754 (void)vfprintf(stderr, fmt, ap);
755 va_end(ap);
756 (void)fprintf(stderr, "\n");
757 exit(1);
758 /* NOTREACHED */
759}
diff --git a/src/regress/lib/libc/db/run.test b/src/regress/lib/libc/db/run.test
new file mode 100644
index 0000000000..acbd3f49e1
--- /dev/null
+++ b/src/regress/lib/libc/db/run.test
@@ -0,0 +1,706 @@
1#!/bin/sh -
2#
3# $NetBSD: run.test,v 1.8 1996/05/03 21:57:51 cgd Exp $
4# @(#)run.test 8.10 (Berkeley) 7/26/94
5#
6
7# db regression tests
8main()
9{
10
11 PROG=./dbtest
12 TMP1=t1
13 TMP2=t2
14 TMP3=t3
15
16 if [ -f /usr/share/dict/words ]; then
17 DICT=/usr/share/dict/words
18 elif [ -f /usr/dict/words ]; then
19 DICT=/usr/dict/words
20 else
21 echo 'run.test: no dictionary'
22 exit 1
23 fi
24
25 if [ $# -eq 0 ]; then
26 for t in 1 2 3 4 5 6 7 8 9 10 11 12 13 20; do
27 test$t
28 done
29 else
30 while [ $# -gt 0 ]
31 do case "$1" in
32 test*)
33 $1;;
34 [0-9]*)
35 test$1;;
36 btree)
37 for t in 1 2 3 7 8 9 10 12 13; do
38 test$t
39 done;;
40 hash)
41 for t in 1 2 3 8 13 20; do
42 test$t
43 done;;
44 recno)
45 for t in 1 2 3 4 5 6 7 10 11; do
46 test$t
47 done;;
48 *)
49 echo "run.test: unknown test $1"
50 echo "usage: run.test test# | type"
51 exit 1
52 esac
53 shift
54 done
55 fi
56 rm -f $TMP1 $TMP2 $TMP3
57 exit 0
58}
59
60# Take the first hundred entries in the dictionary, and make them
61# be key/data pairs.
62test1()
63{
64 echo "Test 1: btree, hash: small key, small data pairs"
65 sed 200q $DICT > $TMP1
66 for type in btree hash; do
67 rm -f $TMP2 $TMP3
68 for i in `sed 200q $DICT`; do
69 echo p
70 echo k$i
71 echo d$i
72 echo g
73 echo k$i
74 done > $TMP2
75 $PROG -o $TMP3 $type $TMP2
76 if (cmp -s $TMP1 $TMP3) ; then :
77 else
78 echo "test1: type $type: failed"
79 exit 1
80 fi
81 done
82 echo "Test 1: recno: small key, small data pairs"
83 rm -f $TMP2 $TMP3
84 sed 200q $DICT |
85 awk '{
86 ++i;
87 printf("p\nk%d\nd%s\ng\nk%d\n", i, $0, i);
88 }' > $TMP2
89 $PROG -o $TMP3 recno $TMP2
90 if (cmp -s $TMP1 $TMP3) ; then :
91 else
92 echo "test1: type recno: failed"
93 exit 1
94 fi
95}
96
97# Take the first 200 entries in the dictionary, and give them
98# each a medium size data entry.
99test2()
100{
101 echo "Test 2: btree, hash: small key, medium data pairs"
102 mdata=abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz
103 echo $mdata |
104 awk '{ for (i = 1; i < 201; ++i) print $0 }' > $TMP1
105 for type in hash btree; do
106 rm -f $TMP2 $TMP3
107 for i in `sed 200q $DICT`; do
108 echo p
109 echo k$i
110 echo d$mdata
111 echo g
112 echo k$i
113 done > $TMP2
114 $PROG -o $TMP3 $type $TMP2
115 if (cmp -s $TMP1 $TMP3) ; then :
116 else
117 echo "test2: type $type: failed"
118 exit 1
119 fi
120 done
121 echo "Test 2: recno: small key, medium data pairs"
122 rm -f $TMP2 $TMP3
123 echo $mdata |
124 awk '{ for (i = 1; i < 201; ++i)
125 printf("p\nk%d\nd%s\ng\nk%d\n", i, $0, i);
126 }' > $TMP2
127 $PROG -o $TMP3 recno $TMP2
128 if (cmp -s $TMP1 $TMP3) ; then :
129 else
130 echo "test2: type recno: failed"
131 exit 1
132 fi
133}
134
135# Insert the programs in /bin with their paths as their keys.
136test3()
137{
138 echo "Test 3: hash: small key, big data pairs"
139 rm -f $TMP1
140 (find /bin -type f -print | xargs cat) > $TMP1
141 for type in hash; do
142 rm -f $TMP2 $TMP3
143 for i in `find /bin -type f -print`; do
144 echo p
145 echo k$i
146 echo D$i
147 echo g
148 echo k$i
149 done > $TMP2
150 $PROG -o $TMP3 $type $TMP2
151 if (cmp -s $TMP1 $TMP3) ; then :
152 else
153 echo "test3: $type: failed"
154 exit 1
155 fi
156 done
157 echo "Test 3: btree: small key, big data pairs"
158 for psize in 512 16384 65536; do
159 echo " page size $psize"
160 for type in btree; do
161 rm -f $TMP2 $TMP3
162 for i in `find /bin -type f -print`; do
163 echo p
164 echo k$i
165 echo D$i
166 echo g
167 echo k$i
168 done > $TMP2
169 $PROG -i psize=$psize -o $TMP3 $type $TMP2
170 if (cmp -s $TMP1 $TMP3) ; then :
171 else
172 echo "test3: $type: page size $psize: failed"
173 exit 1
174 fi
175 done
176 done
177 echo "Test 3: recno: big data pairs"
178 rm -f $TMP2 $TMP3
179 find /bin -type f -print |
180 awk '{
181 ++i;
182 printf("p\nk%d\nD%s\ng\nk%d\n", i, $0, i);
183 }' > $TMP2
184 for psize in 512 16384 65536; do
185 echo " page size $psize"
186 $PROG -i psize=$psize -o $TMP3 recno $TMP2
187 if (cmp -s $TMP1 $TMP3) ; then :
188 else
189 echo "test3: recno: page size $psize: failed"
190 exit 1
191 fi
192 done
193}
194
195# Do random recno entries.
196test4()
197{
198 echo "Test 4: recno: random entries"
199 echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" |
200 awk '{
201 for (i = 37; i <= 37 + 88 * 17; i += 17) {
202 if (i % 41)
203 s = substr($0, 1, i % 41);
204 else
205 s = substr($0, 1);
206 printf("input key %d: %s\n", i, s);
207 }
208 for (i = 1; i <= 15; ++i) {
209 if (i % 41)
210 s = substr($0, 1, i % 41);
211 else
212 s = substr($0, 1);
213 printf("input key %d: %s\n", i, s);
214 }
215 for (i = 19234; i <= 19234 + 61 * 27; i += 27) {
216 if (i % 41)
217 s = substr($0, 1, i % 41);
218 else
219 s = substr($0, 1);
220 printf("input key %d: %s\n", i, s);
221 }
222 exit
223 }' > $TMP1
224 rm -f $TMP2 $TMP3
225 cat $TMP1 |
226 awk 'BEGIN {
227 i = 37;
228 incr = 17;
229 }
230 {
231 printf("p\nk%d\nd%s\n", i, $0);
232 if (i == 19234 + 61 * 27)
233 exit;
234 if (i == 37 + 88 * 17) {
235 i = 1;
236 incr = 1;
237 } else if (i == 15) {
238 i = 19234;
239 incr = 27;
240 } else
241 i += incr;
242 }
243 END {
244 for (i = 37; i <= 37 + 88 * 17; i += 17)
245 printf("g\nk%d\n", i);
246 for (i = 1; i <= 15; ++i)
247 printf("g\nk%d\n", i);
248 for (i = 19234; i <= 19234 + 61 * 27; i += 27)
249 printf("g\nk%d\n", i);
250 }' > $TMP2
251 $PROG -o $TMP3 recno $TMP2
252 if (cmp -s $TMP1 $TMP3) ; then :
253 else
254 echo "test4: type recno: failed"
255 exit 1
256 fi
257}
258
259# Do reverse order recno entries.
260test5()
261{
262 echo "Test 5: recno: reverse order entries"
263 echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" |
264 awk ' {
265 for (i = 1500; i; --i) {
266 if (i % 34)
267 s = substr($0, 1, i % 34);
268 else
269 s = substr($0, 1);
270 printf("input key %d: %s\n", i, s);
271 }
272 exit;
273 }' > $TMP1
274 rm -f $TMP2 $TMP3
275 cat $TMP1 |
276 awk 'BEGIN {
277 i = 1500;
278 }
279 {
280 printf("p\nk%d\nd%s\n", i, $0);
281 --i;
282 }
283 END {
284 for (i = 1500; i; --i)
285 printf("g\nk%d\n", i);
286 }' > $TMP2
287 $PROG -o $TMP3 recno $TMP2
288 if (cmp -s $TMP1 $TMP3) ; then :
289 else
290 echo "test5: type recno: failed"
291 exit 1
292 fi
293}
294
295# Do alternating order recno entries.
296test6()
297{
298 echo "Test 6: recno: alternating order entries"
299 echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" |
300 awk ' {
301 for (i = 1; i < 1200; i += 2) {
302 if (i % 34)
303 s = substr($0, 1, i % 34);
304 else
305 s = substr($0, 1);
306 printf("input key %d: %s\n", i, s);
307 }
308 for (i = 2; i < 1200; i += 2) {
309 if (i % 34)
310 s = substr($0, 1, i % 34);
311 else
312 s = substr($0, 1);
313 printf("input key %d: %s\n", i, s);
314 }
315 exit;
316 }' > $TMP1
317 rm -f $TMP2 $TMP3
318 cat $TMP1 |
319 awk 'BEGIN {
320 i = 1;
321 even = 0;
322 }
323 {
324 printf("p\nk%d\nd%s\n", i, $0);
325 i += 2;
326 if (i >= 1200) {
327 if (even == 1)
328 exit;
329 even = 1;
330 i = 2;
331 }
332 }
333 END {
334 for (i = 1; i < 1200; ++i)
335 printf("g\nk%d\n", i);
336 }' > $TMP2
337 $PROG -o $TMP3 recno $TMP2
338 sort -o $TMP1 $TMP1
339 sort -o $TMP3 $TMP3
340 if (cmp -s $TMP1 $TMP3) ; then :
341 else
342 echo "test6: type recno: failed"
343 exit 1
344 fi
345}
346
347# Delete cursor record
348test7()
349{
350 echo "Test 7: btree, recno: delete cursor record"
351 echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" |
352 awk '{
353 for (i = 1; i <= 120; ++i)
354 printf("%05d: input key %d: %s\n", i, i, $0);
355 printf("%05d: input key %d: %s\n", 120, 120, $0);
356 printf("seq failed, no such key\n");
357 printf("%05d: input key %d: %s\n", 1, 1, $0);
358 printf("%05d: input key %d: %s\n", 2, 2, $0);
359 exit;
360 }' > $TMP1
361 rm -f $TMP2 $TMP3
362
363 for type in btree recno; do
364 cat $TMP1 |
365 awk '{
366 if (i == 120)
367 exit;
368 printf("p\nk%d\nd%s\n", ++i, $0);
369 }
370 END {
371 printf("fR_NEXT\n");
372 for (i = 1; i <= 120; ++i)
373 printf("s\n");
374 printf("fR_CURSOR\ns\nk120\n");
375 printf("r\n");
376 printf("fR_NEXT\ns\n");
377 printf("fR_CURSOR\ns\nk1\n");
378 printf("r\n");
379 printf("fR_FIRST\ns\n");
380 }' > $TMP2
381 $PROG -o $TMP3 recno $TMP2
382 if (cmp -s $TMP1 $TMP3) ; then :
383 else
384 echo "test7: type $type: failed"
385 exit 1
386 fi
387 done
388}
389
390# Make sure that overflow pages are reused.
391test8()
392{
393 echo "Test 8: btree, hash: repeated small key, big data pairs"
394 rm -f $TMP1
395 echo "" |
396 awk 'BEGIN {
397 for (i = 1; i <= 10; ++i) {
398 printf("p\nkkey1\nD/bin/sh\n");
399 printf("p\nkkey2\nD/bin/csh\n");
400 if (i % 8 == 0) {
401 printf("c\nkkey2\nD/bin/csh\n");
402 printf("c\nkkey1\nD/bin/sh\n");
403 printf("e\t%d of 10 (comparison)\n", i);
404 } else
405 printf("e\t%d of 10 \n", i);
406 printf("r\nkkey1\nr\nkkey2\n");
407 }
408 }' > $TMP1
409 $PROG btree $TMP1
410# $PROG hash $TMP1
411 # No explicit test for success.
412}
413
414# Test btree duplicate keys
415test9()
416{
417 echo "Test 9: btree: duplicate keys"
418 echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" |
419 awk '{
420 for (i = 1; i <= 543; ++i)
421 printf("%05d: input key %d: %s\n", i, i, $0);
422 exit;
423 }' > $TMP1
424 rm -f $TMP2 $TMP3
425
426 for type in btree; do
427 cat $TMP1 |
428 awk '{
429 if (i++ % 2)
430 printf("p\nkduplicatekey\nd%s\n", $0);
431 else
432 printf("p\nkunique%dkey\nd%s\n", i, $0);
433 }
434 END {
435 printf("o\n");
436 }' > $TMP2
437 $PROG -iflags=1 -o $TMP3 $type $TMP2
438 sort -o $TMP3 $TMP3
439 if (cmp -s $TMP1 $TMP3) ; then :
440 else
441 echo "test9: type $type: failed"
442 exit 1
443 fi
444 done
445}
446
447# Test use of cursor flags without initialization
448test10()
449{
450 echo "Test 10: btree, recno: test cursor flag use"
451 echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" |
452 awk '{
453 for (i = 1; i <= 20; ++i)
454 printf("%05d: input key %d: %s\n", i, i, $0);
455 exit;
456 }' > $TMP1
457 rm -f $TMP2 $TMP3
458
459 # Test that R_CURSOR doesn't succeed before cursor initialized
460 for type in btree recno; do
461 cat $TMP1 |
462 awk '{
463 if (i == 10)
464 exit;
465 printf("p\nk%d\nd%s\n", ++i, $0);
466 }
467 END {
468 printf("fR_CURSOR\nr\n");
469 printf("eR_CURSOR SHOULD HAVE FAILED\n");
470 }' > $TMP2
471 $PROG -o $TMP3 $type $TMP2 > /dev/null 2>&1
472 if [ -s $TMP3 ] ; then
473 echo "Test 10: delete: R_CURSOR SHOULD HAVE FAILED"
474 exit 1
475 fi
476 done
477 for type in btree recno; do
478 cat $TMP1 |
479 awk '{
480 if (i == 10)
481 exit;
482 printf("p\nk%d\nd%s\n", ++i, $0);
483 }
484 END {
485 printf("fR_CURSOR\np\nk1\ndsome data\n");
486 printf("eR_CURSOR SHOULD HAVE FAILED\n");
487 }' > $TMP2
488 $PROG -o $TMP3 $type $TMP2 > /dev/null 2>&1
489 if [ -s $TMP3 ] ; then
490 echo "Test 10: put: R_CURSOR SHOULD HAVE FAILED"
491 exit 1
492 fi
493 done
494}
495
496# Test insert in reverse order.
497test11()
498{
499 echo "Test 11: recno: reverse order insert"
500 echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" |
501 awk '{
502 for (i = 1; i <= 779; ++i)
503 printf("%05d: input key %d: %s\n", i, i, $0);
504 exit;
505 }' > $TMP1
506 rm -f $TMP2 $TMP3
507
508 for type in recno; do
509 cat $TMP1 |
510 awk '{
511 if (i == 0) {
512 i = 1;
513 printf("p\nk1\nd%s\n", $0);
514 printf("%s\n", "fR_IBEFORE");
515 } else
516 printf("p\nk1\nd%s\n", $0);
517 }
518 END {
519 printf("or\n");
520 }' > $TMP2
521 $PROG -o $TMP3 $type $TMP2
522 if (cmp -s $TMP1 $TMP3) ; then :
523 else
524 echo "test11: type $type: failed"
525 exit 1
526 fi
527 done
528}
529
530# Take the first 20000 entries in the dictionary, reverse them, and give
531# them each a small size data entry. Use a small page size to make sure
532# the btree split code gets hammered.
533test12()
534{
535 echo "Test 12: btree: lots of keys, small page size"
536 mdata=abcdefghijklmnopqrstuvwxy
537 echo $mdata |
538 awk '{ for (i = 1; i < 20001; ++i) print $0 }' > $TMP1
539 for type in btree; do
540 rm -f $TMP2 $TMP3
541 for i in `sed 20000q $DICT | rev`; do
542 echo p
543 echo k$i
544 echo d$mdata
545 echo g
546 echo k$i
547 done > $TMP2
548 $PROG -i psize=512 -o $TMP3 $type $TMP2
549 if (cmp -s $TMP1 $TMP3) ; then :
550 else
551 echo "test12: type $type: failed"
552 exit 1
553 fi
554 done
555}
556
557# Test different byte orders.
558test13()
559{
560 echo "Test 13: btree, hash: differing byte orders"
561 sed 50q $DICT > $TMP1
562 for order in 1234 4321; do
563 for type in btree hash; do
564 rm -f byte.file $TMP2 $TMP3
565 for i in `sed 50q $DICT`; do
566 echo p
567 echo k$i
568 echo d$i
569 echo g
570 echo k$i
571 done > $TMP2
572 $PROG -ilorder=$order -f byte.file -o $TMP3 $type $TMP2
573 if (cmp -s $TMP1 $TMP3) ; then :
574 else
575 echo "test13: $type/$order put failed"
576 exit 1
577 fi
578 for i in `sed 50q $DICT`; do
579 echo g
580 echo k$i
581 done > $TMP2
582 $PROG -s \
583 -ilorder=$order -f byte.file -o $TMP3 $type $TMP2
584 if (cmp -s $TMP1 $TMP3) ; then :
585 else
586 echo "test13: $type/$order get failed"
587 exit 1
588 fi
589 done
590 done
591 rm -f byte.file
592}
593
594# Try a variety of bucketsizes and fill factors for hashing
595test20()
596{
597 echo\
598 "Test 20: hash: bucketsize, fill factor; nelem 25000 cachesize 65536"
599 echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" |
600 awk '{
601 for (i = 1; i <= 10000; ++i) {
602 if (i % 34)
603 s = substr($0, 1, i % 34);
604 else
605 s = substr($0, 1);
606 printf("%s\n", s);
607 }
608 exit;
609 }' > $TMP1
610 sed 10000q $DICT |
611 awk 'BEGIN {
612 ds="abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg"
613 }
614 {
615 if (++i % 34)
616 s = substr(ds, 1, i % 34);
617 else
618 s = substr(ds, 1);
619 printf("p\nk%s\nd%s\n", $0, s);
620 }' > $TMP2
621 sed 10000q $DICT |
622 awk '{
623 ++i;
624 printf("g\nk%s\n", $0);
625 }' >> $TMP2
626 bsize=256
627 for ffactor in 11 14 21; do
628 echo " bucketsize $bsize, fill factor $ffactor"
629 $PROG -o$TMP3 \
630 -ibsize=$bsize,ffactor=$ffactor,nelem=25000,cachesize=65536\
631 hash $TMP2
632 if (cmp -s $TMP1 $TMP3) ; then :
633 else
634 echo "test20: type hash:\
635bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed"
636 exit 1
637 fi
638 done
639 bsize=512
640 for ffactor in 21 28 43; do
641 echo " bucketsize $bsize, fill factor $ffactor"
642 $PROG -o$TMP3 \
643 -ibsize=$bsize,ffactor=$ffactor,nelem=25000,cachesize=65536\
644 hash $TMP2
645 if (cmp -s $TMP1 $TMP3) ; then :
646 else
647 echo "test20: type hash:\
648bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed"
649 exit 1
650 fi
651 done
652 bsize=1024
653 for ffactor in 43 57 85; do
654 echo " bucketsize $bsize, fill factor $ffactor"
655 $PROG -o$TMP3 \
656 -ibsize=$bsize,ffactor=$ffactor,nelem=25000,cachesize=65536\
657 hash $TMP2
658 if (cmp -s $TMP1 $TMP3) ; then :
659 else
660 echo "test20: type hash:\
661bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed"
662 exit 1
663 fi
664 done
665 bsize=2048
666 for ffactor in 85 114 171; do
667 echo " bucketsize $bsize, fill factor $ffactor"
668 $PROG -o$TMP3 \
669 -ibsize=$bsize,ffactor=$ffactor,nelem=25000,cachesize=65536\
670 hash $TMP2
671 if (cmp -s $TMP1 $TMP3) ; then :
672 else
673 echo "test20: type hash:\
674bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed"
675 exit 1
676 fi
677 done
678 bsize=4096
679 for ffactor in 171 228 341; do
680 echo " bucketsize $bsize, fill factor $ffactor"
681 $PROG -o$TMP3 \
682 -ibsize=$bsize,ffactor=$ffactor,nelem=25000,cachesize=65536\
683 hash $TMP2
684 if (cmp -s $TMP1 $TMP3) ; then :
685 else
686 echo "test20: type hash:\
687bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed"
688 exit 1
689 fi
690 done
691 bsize=8192
692 for ffactor in 341 455 683; do
693 echo " bucketsize $bsize, fill factor $ffactor"
694 $PROG -o$TMP3 \
695 -ibsize=$bsize,ffactor=$ffactor,nelem=25000,cachesize=65536\
696 hash $TMP2
697 if (cmp -s $TMP1 $TMP3) ; then :
698 else
699 echo "test20: type hash:\
700bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed"
701 exit 1
702 fi
703 done
704}
705
706main $*
diff --git a/src/regress/lib/libc/ieeefp/Makefile b/src/regress/lib/libc/ieeefp/Makefile
new file mode 100644
index 0000000000..0f453a31e9
--- /dev/null
+++ b/src/regress/lib/libc/ieeefp/Makefile
@@ -0,0 +1,9 @@
1# $NetBSD: Makefile,v 1.5 1996/04/09 16:54:18 phil Exp $
2
3SUBDIR+= except round
4
5regress: _SUBDIRUSE
6
7install:
8
9.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..a2a107a788
--- /dev/null
+++ b/src/regress/lib/libc/ieeefp/except/except.c
@@ -0,0 +1,88 @@
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
15int
16main()
17{
18 volatile double x;
19
20 /*
21 * check to make sure that all exceptions are masked and
22 * that the accumulated exception status is clear.
23 */
24 assert(fpgetmask() == 0);
25 assert(fpgetsticky() == 0);
26
27 /* set up signal handler */
28 signal (SIGFPE, sigfpe);
29 signal_cought = 0;
30
31 /* trip divide by zero */
32 x = one / zero;
33 assert (fpgetsticky() & FP_X_DZ);
34 assert (signal_cought == 0);
35 fpsetsticky(0);
36
37 /* trip invalid operation */
38 x = zero / zero;
39 assert (fpgetsticky() & FP_X_INV);
40 assert (signal_cought == 0);
41 fpsetsticky(0);
42
43 /* trip overflow */
44 x = huge * huge;
45 assert (fpgetsticky() & FP_X_OFL);
46 assert (signal_cought == 0);
47 fpsetsticky(0);
48
49 /* trip underflow */
50 x = tiny * tiny;
51 assert (fpgetsticky() & FP_X_UFL);
52 assert (signal_cought == 0);
53 fpsetsticky(0);
54
55#if 0
56 /* unmask and then trip divide by zero */
57 fpsetmask(FP_X_DZ);
58 x = one / zero;
59 assert (signal_cought == 1);
60 signal_cought = 0;
61
62 /* unmask and then trip invalid operation */
63 fpsetmask(FP_X_INV);
64 x = zero / zero;
65 assert (signal_cought == 1);
66 signal_cought = 0;
67
68 /* unmask and then trip overflow */
69 fpsetmask(FP_X_OFL);
70 x = huge * huge;
71 assert (signal_cought == 1);
72 signal_cought = 0;
73
74 /* unmask and then trip underflow */
75 fpsetmask(FP_X_UFL);
76 x = tiny * tiny;
77 assert (signal_cought == 1);
78 signal_cought = 0;
79#endif
80
81 exit(0);
82}
83
84void
85sigfpe()
86{
87 signal_cought = 1;
88}
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..41cd4a557d
--- /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, "!%ld(%ld)!", (long)OP(*s), (long)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..6e63ffc235
--- /dev/null
+++ b/src/regress/lib/libc/regex/main.c
@@ -0,0 +1,515 @@
1/* $OpenBSD: main.c,v 1.3 1997/01/15 23:41:07 millert Exp $ */
2/* $NetBSD: main.c,v 1.2 1995/04/20 22:39:51 cgd Exp $ */
3
4#include <stdio.h>
5#include <stdlib.h>
6#include <string.h>
7#include <sys/types.h>
8#include <regex.h>
9#include <assert.h>
10#include <unistd.h>
11
12#include "main.ih"
13
14char *progname;
15int debug = 0;
16int line = 0;
17int status = 0;
18
19int copts = REG_EXTENDED;
20int eopts = 0;
21regoff_t startoff = 0;
22regoff_t endoff = 0;
23
24
25extern int split();
26extern void regprint();
27
28/*
29 - main - do the simple case, hand off to regress() for regression
30 */
31int
32main(argc, argv)
33int argc;
34char *argv[];
35{
36 regex_t re;
37# define NS 10
38 regmatch_t subs[NS];
39 char erbuf[100];
40 int err;
41 size_t len;
42 int c;
43 int errflg = 0;
44 register int i;
45 extern int optind;
46 extern char *optarg;
47
48 progname = argv[0];
49
50 while ((c = getopt(argc, argv, "c:e:S:E:x")) != -1)
51 switch (c) {
52 case 'c': /* compile options */
53 copts = options('c', optarg);
54 break;
55 case 'e': /* execute options */
56 eopts = options('e', optarg);
57 break;
58 case 'S': /* start offset */
59 startoff = (regoff_t)atoi(optarg);
60 break;
61 case 'E': /* end offset */
62 endoff = (regoff_t)atoi(optarg);
63 break;
64 case 'x': /* Debugging. */
65 debug++;
66 break;
67 case '?':
68 default:
69 errflg++;
70 break;
71 }
72 if (errflg) {
73 fprintf(stderr, "usage: %s ", progname);
74 fprintf(stderr, "[-c copt][-C][-d] [re]\n");
75 exit(2);
76 }
77
78 if (optind >= argc) {
79 regress(stdin);
80 exit(status);
81 }
82
83 err = regcomp(&re, argv[optind++], copts);
84 if (err) {
85 len = regerror(err, &re, erbuf, sizeof(erbuf));
86 fprintf(stderr, "error %s, %d/%d `%s'\n",
87 eprint(err), len, sizeof(erbuf), erbuf);
88 exit(status);
89 }
90 regprint(&re, stdout);
91
92 if (optind >= argc) {
93 regfree(&re);
94 exit(status);
95 }
96
97 if (eopts&REG_STARTEND) {
98 subs[0].rm_so = startoff;
99 subs[0].rm_eo = strlen(argv[optind]) - endoff;
100 }
101 err = regexec(&re, argv[optind], (size_t)NS, subs, eopts);
102 if (err) {
103 len = regerror(err, &re, erbuf, sizeof(erbuf));
104 fprintf(stderr, "error %s, %d/%d `%s'\n",
105 eprint(err), len, sizeof(erbuf), erbuf);
106 exit(status);
107 }
108 if (!(copts&REG_NOSUB)) {
109 len = (size_t)(subs[0].rm_eo - subs[0].rm_so);
110 if (subs[0].rm_so != -1) {
111 if (len != 0)
112 printf("match `%.*s'\n", (int)len,
113 argv[optind] + subs[0].rm_so);
114 else
115 printf("match `'@%.1s\n",
116 argv[optind] + subs[0].rm_so);
117 }
118 for (i = 1; i < NS; i++)
119 if (subs[i].rm_so != -1)
120 printf("(%d) `%.*s'\n", i,
121 (int)(subs[i].rm_eo - subs[i].rm_so),
122 argv[optind] + subs[i].rm_so);
123 }
124 exit(status);
125}
126
127/*
128 - regress - main loop of regression test
129 == void regress(FILE *in);
130 */
131void
132regress(in)
133FILE *in;
134{
135 char inbuf[1000];
136# define MAXF 10
137 char *f[MAXF];
138 int nf;
139 int i;
140 char erbuf[100];
141 size_t ne;
142 char *badpat = "invalid regular expression";
143# define SHORT 10
144 char *bpname = "REG_BADPAT";
145 regex_t re;
146
147 while (fgets(inbuf, sizeof(inbuf), in) != NULL) {
148 line++;
149 if (inbuf[0] == '#' || inbuf[0] == '\n')
150 continue; /* NOTE CONTINUE */
151 inbuf[strlen(inbuf)-1] = '\0'; /* get rid of stupid \n */
152 if (debug)
153 fprintf(stdout, "%d:\n", line);
154 nf = split(inbuf, f, MAXF, "\t\t");
155 if (nf < 3) {
156 fprintf(stderr, "bad input, line %d\n", line);
157 exit(1);
158 }
159 for (i = 0; i < nf; i++)
160 if (strcmp(f[i], "\"\"") == 0)
161 f[i] = "";
162 if (nf <= 3)
163 f[3] = NULL;
164 if (nf <= 4)
165 f[4] = NULL;
166 try(f[0], f[1], f[2], f[3], f[4], options('c', f[1]));
167 if (opt('&', f[1])) /* try with either type of RE */
168 try(f[0], f[1], f[2], f[3], f[4],
169 options('c', f[1]) &~ REG_EXTENDED);
170 }
171
172 ne = regerror(REG_BADPAT, (regex_t *)NULL, erbuf, sizeof(erbuf));
173 if (strcmp(erbuf, badpat) != 0 || ne != strlen(badpat)+1) {
174 fprintf(stderr, "end: regerror() test gave `%s' not `%s'\n",
175 erbuf, badpat);
176 status = 1;
177 }
178 ne = regerror(REG_BADPAT, (regex_t *)NULL, erbuf, (size_t)SHORT);
179 if (strncmp(erbuf, badpat, SHORT-1) != 0 || erbuf[SHORT-1] != '\0' ||
180 ne != strlen(badpat)+1) {
181 fprintf(stderr, "end: regerror() short test gave `%s' not `%.*s'\n",
182 erbuf, SHORT-1, badpat);
183 status = 1;
184 }
185 ne = regerror(REG_ITOA|REG_BADPAT, (regex_t *)NULL, erbuf, sizeof(erbuf));
186 if (strcmp(erbuf, bpname) != 0 || ne != strlen(bpname)+1) {
187 fprintf(stderr, "end: regerror() ITOA test gave `%s' not `%s'\n",
188 erbuf, bpname);
189 status = 1;
190 }
191 re.re_endp = bpname;
192 ne = regerror(REG_ATOI, &re, erbuf, sizeof(erbuf));
193 if (atoi(erbuf) != (int)REG_BADPAT) {
194 fprintf(stderr, "end: regerror() ATOI test gave `%s' not `%ld'\n",
195 erbuf, (long)REG_BADPAT);
196 status = 1;
197 } else if (ne != strlen(erbuf)+1) {
198 fprintf(stderr, "end: regerror() ATOI test len(`%s') = %ld\n",
199 erbuf, (long)REG_BADPAT);
200 status = 1;
201 }
202}
203
204/*
205 - try - try it, and report on problems
206 == void try(char *f0, char *f1, char *f2, char *f3, char *f4, int opts);
207 */
208void
209try(f0, f1, f2, f3, f4, opts)
210char *f0;
211char *f1;
212char *f2;
213char *f3;
214char *f4;
215int opts; /* may not match f1 */
216{
217 regex_t re;
218# define NSUBS 10
219 regmatch_t subs[NSUBS];
220# define NSHOULD 15
221 char *should[NSHOULD];
222 int nshould;
223 char erbuf[100];
224 int err;
225 int len;
226 char *type = (opts & REG_EXTENDED) ? "ERE" : "BRE";
227 register int i;
228 char *grump;
229 char f0copy[1000];
230 char f2copy[1000];
231
232 strcpy(f0copy, f0);
233 re.re_endp = (opts&REG_PEND) ? f0copy + strlen(f0copy) : NULL;
234 fixstr(f0copy);
235 err = regcomp(&re, f0copy, opts);
236 if (err != 0 && (!opt('C', f1) || err != efind(f2))) {
237 /* unexpected error or wrong error */
238 len = regerror(err, &re, erbuf, sizeof(erbuf));
239 fprintf(stderr, "%d: %s error %s, %d/%d `%s'\n",
240 line, type, eprint(err), len,
241 sizeof(erbuf), erbuf);
242 status = 1;
243 } else if (err == 0 && opt('C', f1)) {
244 /* unexpected success */
245 fprintf(stderr, "%d: %s should have given REG_%s\n",
246 line, type, f2);
247 status = 1;
248 err = 1; /* so we won't try regexec */
249 }
250
251 if (err != 0) {
252 regfree(&re);
253 return;
254 }
255
256 strcpy(f2copy, f2);
257 fixstr(f2copy);
258
259 if (options('e', f1)&REG_STARTEND) {
260 if (strchr(f2, '(') == NULL || strchr(f2, ')') == NULL)
261 fprintf(stderr, "%d: bad STARTEND syntax\n", line);
262 subs[0].rm_so = strchr(f2, '(') - f2 + 1;
263 subs[0].rm_eo = strchr(f2, ')') - f2;
264 }
265 err = regexec(&re, f2copy, NSUBS, subs, options('e', f1));
266
267 if (err != 0 && (f3 != NULL || err != REG_NOMATCH)) {
268 /* unexpected error or wrong error */
269 len = regerror(err, &re, erbuf, sizeof(erbuf));
270 fprintf(stderr, "%d: %s exec error %s, %d/%d `%s'\n",
271 line, type, eprint(err), len,
272 sizeof(erbuf), erbuf);
273 status = 1;
274 } else if (err != 0) {
275 /* nothing more to check */
276 } else if (f3 == NULL) {
277 /* unexpected success */
278 fprintf(stderr, "%d: %s exec should have failed\n",
279 line, type);
280 status = 1;
281 err = 1; /* just on principle */
282 } else if (opts&REG_NOSUB) {
283 /* nothing more to check */
284 } else if ((grump = check(f2, subs[0], f3)) != NULL) {
285 fprintf(stderr, "%d: %s %s\n", line, type, grump);
286 status = 1;
287 err = 1;
288 }
289
290 if (err != 0 || f4 == NULL) {
291 regfree(&re);
292 return;
293 }
294
295 for (i = 1; i < NSHOULD; i++)
296 should[i] = NULL;
297 nshould = split(f4, should+1, NSHOULD-1, ",");
298 if (nshould == 0) {
299 nshould = 1;
300 should[1] = "";
301 }
302 for (i = 1; i < NSUBS; i++) {
303 grump = check(f2, subs[i], should[i]);
304 if (grump != NULL) {
305 fprintf(stderr, "%d: %s $%d %s\n", line,
306 type, i, grump);
307 status = 1;
308 err = 1;
309 }
310 }
311
312 regfree(&re);
313}
314
315/*
316 - options - pick options out of a regression-test string
317 == int options(int type, char *s);
318 */
319int
320options(type, s)
321int type; /* 'c' compile, 'e' exec */
322char *s;
323{
324 register char *p;
325 register int o = (type == 'c') ? copts : eopts;
326 register char *legal = (type == 'c') ? "bisnmp" : "^$#tl";
327
328 for (p = s; *p != '\0'; p++)
329 if (strchr(legal, *p) != NULL)
330 switch (*p) {
331 case 'b':
332 o &= ~REG_EXTENDED;
333 break;
334 case 'i':
335 o |= REG_ICASE;
336 break;
337 case 's':
338 o |= REG_NOSUB;
339 break;
340 case 'n':
341 o |= REG_NEWLINE;
342 break;
343 case 'm':
344 o &= ~REG_EXTENDED;
345 o |= REG_NOSPEC;
346 break;
347 case 'p':
348 o |= REG_PEND;
349 break;
350 case '^':
351 o |= REG_NOTBOL;
352 break;
353 case '$':
354 o |= REG_NOTEOL;
355 break;
356 case '#':
357 o |= REG_STARTEND;
358 break;
359 case 't': /* trace */
360 o |= REG_TRACE;
361 break;
362 case 'l': /* force long representation */
363 o |= REG_LARGE;
364 break;
365 case 'r': /* force backref use */
366 o |= REG_BACKR;
367 break;
368 }
369 return(o);
370}
371
372/*
373 - opt - is a particular option in a regression string?
374 == int opt(int c, char *s);
375 */
376int /* predicate */
377opt(c, s)
378int c;
379char *s;
380{
381 return(strchr(s, c) != NULL);
382}
383
384/*
385 - fixstr - transform magic characters in strings
386 == void fixstr(register char *p);
387 */
388void
389fixstr(p)
390register char *p;
391{
392 if (p == NULL)
393 return;
394
395 for (; *p != '\0'; p++)
396 if (*p == 'N')
397 *p = '\n';
398 else if (*p == 'T')
399 *p = '\t';
400 else if (*p == 'S')
401 *p = ' ';
402 else if (*p == 'Z')
403 *p = '\0';
404}
405
406/*
407 - check - check a substring match
408 == char *check(char *str, regmatch_t sub, char *should);
409 */
410char * /* NULL or complaint */
411check(str, sub, should)
412char *str;
413regmatch_t sub;
414char *should;
415{
416 register int len;
417 register int shlen;
418 register char *p;
419 static char grump[500];
420 register char *at = NULL;
421
422 if (should != NULL && strcmp(should, "-") == 0)
423 should = NULL;
424 if (should != NULL && should[0] == '@') {
425 at = should + 1;
426 should = "";
427 }
428
429 /* check rm_so and rm_eo for consistency */
430 if (sub.rm_so > sub.rm_eo || (sub.rm_so == -1 && sub.rm_eo != -1) ||
431 (sub.rm_so != -1 && sub.rm_eo == -1) ||
432 (sub.rm_so != -1 && sub.rm_so < 0) ||
433 (sub.rm_eo != -1 && sub.rm_eo < 0) ) {
434 sprintf(grump, "start %ld end %ld", (long)sub.rm_so,
435 (long)sub.rm_eo);
436 return(grump);
437 }
438
439 /* check for no match */
440 if (sub.rm_so == -1 && should == NULL)
441 return(NULL);
442 if (sub.rm_so == -1)
443 return("did not match");
444
445 /* check for in range */
446 if (sub.rm_eo > strlen(str)) {
447 sprintf(grump, "start %ld end %ld, past end of string",
448 (long)sub.rm_so, (long)sub.rm_eo);
449 return(grump);
450 }
451
452 len = (int)(sub.rm_eo - sub.rm_so);
453 shlen = (int)strlen(should);
454 p = str + sub.rm_so;
455
456 /* check for not supposed to match */
457 if (should == NULL) {
458 sprintf(grump, "matched `%.*s'", len, p);
459 return(grump);
460 }
461
462 /* check for wrong match */
463 if (len != shlen || strncmp(p, should, (size_t)shlen) != 0) {
464 sprintf(grump, "matched `%.*s' instead", len, p);
465 return(grump);
466 }
467 if (shlen > 0)
468 return(NULL);
469
470 /* check null match in right place */
471 if (at == NULL)
472 return(NULL);
473 shlen = strlen(at);
474 if (shlen == 0)
475 shlen = 1; /* force check for end-of-string */
476 if (strncmp(p, at, shlen) != 0) {
477 sprintf(grump, "matched null at `%.20s'", p);
478 return(grump);
479 }
480 return(NULL);
481}
482
483/*
484 - eprint - convert error number to name
485 == static char *eprint(int err);
486 */
487static char *
488eprint(err)
489int err;
490{
491 static char epbuf[100];
492 size_t len;
493
494 len = regerror(REG_ITOA|err, (regex_t *)NULL, epbuf, sizeof(epbuf));
495 assert(len <= sizeof(epbuf));
496 return(epbuf);
497}
498
499/*
500 - efind - convert error name to number
501 == static int efind(char *name);
502 */
503static int
504efind(name)
505char *name;
506{
507 static char efbuf[100];
508 regex_t re;
509
510 sprintf(efbuf, "REG_%s", name);
511 assert(strlen(efbuf) < sizeof(efbuf));
512 re.re_endp = efbuf;
513 (void) regerror(REG_ATOI, &re, efbuf, sizeof(efbuf));
514 return(atoi(efbuf));
515}
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..16a482640a
--- /dev/null
+++ b/src/regress/lib/libc/setjmp/jmptest.c
@@ -0,0 +1,135 @@
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 <err.h>
36#include <setjmp.h>
37#include <signal.h>
38#include <stdio.h>
39#include <stdlib.h>
40#include <unistd.h>
41
42#if (TEST_SETJMP + TEST_U_SETJMP + TEST_SIGSETJMP) != 1
43#error one of TEST_SETJMP, TEST_U_SETJMP, or TEST_SIGSETJMP must be defined
44#endif
45
46#ifdef TEST_SETJMP
47#define BUF jmp_buf
48#define SET(b, m) setjmp(b)
49#define JMP(b, v) longjmp(b, v)
50#endif
51
52#ifdef TEST_U_SETJMP
53#define BUF jmp_buf
54#define SET(b, m) _setjmp(b)
55#define JMP(b, v) _longjmp(b, v)
56#endif
57
58#ifdef TEST_SIGSETJMP
59#define BUF sigjmp_buf
60#define SET(b, m) sigsetjmp(b, m)
61#define JMP(b, v) siglongjmp(b, v)
62#endif
63
64int expectsignal;
65
66void
67aborthandler(signo)
68 int signo;
69{
70
71 if (expectsignal)
72 exit(0);
73 else
74 errx(1, "kill(SIGABRT) succeeded");
75}
76
77int
78main(argc, argv)
79 int argc;
80 char *argv[];
81{
82 struct sigaction sa;
83 BUF jb;
84 sigset_t ss;
85 int i, x;
86
87 i = getpid();
88
89#ifdef TEST_SETJMP
90 expectsignal = 0;
91#endif
92#ifdef TEST_U_SETJMP
93 expectsignal = 1;
94#endif
95#ifdef TEST_SIGSETJMP
96 if (argc != 2 ||
97 (strcmp(argv[1], "save") && strcmp(argv[1], "nosave"))) {
98 fprintf(stderr, "usage: %s [save|nosave]\n", argv[0]);
99 exit(1);
100 }
101 expectsignal = (strcmp(argv[1], "save") != 0);
102#endif
103
104 sa.sa_handler = aborthandler;
105 sigemptyset(&sa.sa_mask);
106 sa.sa_flags = 0;
107 if (sigaction(SIGABRT, &sa, NULL) == -1)
108 err(1, "sigaction failed");
109
110 if (sigemptyset(&ss) == -1)
111 err(1, "sigemptyset failed");
112 if (sigaddset(&ss, SIGABRT) == -1)
113 err(1, "sigaddset failed");
114 if (sigprocmask(SIG_BLOCK, &ss, NULL) == -1)
115 err(1, "sigprocmask (1) failed");
116
117 x = SET(jb, !expectsignal);
118 if (x != 0) {
119 if (x != i)
120 errx(1, "setjmp returned wrong value");
121
122 kill(i, SIGABRT);
123 if (expectsignal)
124 errx(1, "kill(SIGABRT) failed");
125 else
126 exit(0);
127 }
128
129 if (sigprocmask(SIG_UNBLOCK, &ss, NULL) == -1)
130 err(1, "sigprocmask (2) failed");
131
132 JMP(jb, i);
133
134 errx(1, "jmp failed");
135}
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>