1*22dc650dSSadaf Ebrahimi /*************************************************
2*22dc650dSSadaf Ebrahimi * PCRE2 POSIX interface test program *
3*22dc650dSSadaf Ebrahimi *************************************************/
4*22dc650dSSadaf Ebrahimi
5*22dc650dSSadaf Ebrahimi /*
6*22dc650dSSadaf Ebrahimi Written by Philip Hazel, December 2022
7*22dc650dSSadaf Ebrahimi Copyright (c) 2022
8*22dc650dSSadaf Ebrahimi File last edited: December 2022
9*22dc650dSSadaf Ebrahimi
10*22dc650dSSadaf Ebrahimi This program tests the POSIX wrapper to the PCRE2 regular expression library.
11*22dc650dSSadaf Ebrahimi The main PCRE2 test program is pcre2test, which also tests these function
12*22dc650dSSadaf Ebrahimi calls. This little program is needed to test the case where the client includes
13*22dc650dSSadaf Ebrahimi pcre2posix.h but not pcre2.h, mainly to make sure that it builds successfully.
14*22dc650dSSadaf Ebrahimi However, the code is written as a flexible test program to which extra tests
15*22dc650dSSadaf Ebrahimi can be added.
16*22dc650dSSadaf Ebrahimi
17*22dc650dSSadaf Ebrahimi Compile with -lpcre2-posix -lpcre2-8
18*22dc650dSSadaf Ebrahimi
19*22dc650dSSadaf Ebrahimi If run with no options, there is no output on success, and the return code is
20*22dc650dSSadaf Ebrahimi zero. If any test fails there is output to stderr, and the return code is 1.
21*22dc650dSSadaf Ebrahimi
22*22dc650dSSadaf Ebrahimi For testing purposes, the "-v" option causes verification output to be written
23*22dc650dSSadaf Ebrahimi to stdout. */
24*22dc650dSSadaf Ebrahimi
25*22dc650dSSadaf Ebrahimi #include <stdio.h>
26*22dc650dSSadaf Ebrahimi #include <string.h>
27*22dc650dSSadaf Ebrahimi #include <pcre2posix.h>
28*22dc650dSSadaf Ebrahimi
29*22dc650dSSadaf Ebrahimi #define CAPCOUNT 5 /* Number of captures supported */
30*22dc650dSSadaf Ebrahimi #define PRINTF if (v) printf /* Shorthand for testing output */
31*22dc650dSSadaf Ebrahimi
32*22dc650dSSadaf Ebrahimi /* This vector contains compiler flags for each pattern that is tested. */
33*22dc650dSSadaf Ebrahimi
34*22dc650dSSadaf Ebrahimi static int cflags[] = {
35*22dc650dSSadaf Ebrahimi 0, /* Test 0 */
36*22dc650dSSadaf Ebrahimi REG_ICASE, /* Test 1 */
37*22dc650dSSadaf Ebrahimi 0, /* Test 2 */
38*22dc650dSSadaf Ebrahimi REG_NEWLINE, /* Test 3 */
39*22dc650dSSadaf Ebrahimi 0 /* Test 4 */
40*22dc650dSSadaf Ebrahimi };
41*22dc650dSSadaf Ebrahimi
42*22dc650dSSadaf Ebrahimi /* This vector contains match flags for each pattern that is tested. */
43*22dc650dSSadaf Ebrahimi
44*22dc650dSSadaf Ebrahimi static int mflags[] = {
45*22dc650dSSadaf Ebrahimi 0, /* Test 0 */
46*22dc650dSSadaf Ebrahimi 0, /* Test 1 */
47*22dc650dSSadaf Ebrahimi 0, /* Test 2 */
48*22dc650dSSadaf Ebrahimi REG_NOTBOL, /* Test 3 */
49*22dc650dSSadaf Ebrahimi 0 /* Test 4 */
50*22dc650dSSadaf Ebrahimi };
51*22dc650dSSadaf Ebrahimi
52*22dc650dSSadaf Ebrahimi /* Automate the number of patterns */
53*22dc650dSSadaf Ebrahimi
54*22dc650dSSadaf Ebrahimi #define count (int)(sizeof(cflags)/sizeof(int))
55*22dc650dSSadaf Ebrahimi
56*22dc650dSSadaf Ebrahimi /* The data for each pattern consists of a pattern string, followed by any
57*22dc650dSSadaf Ebrahimi number of subject strings, terminated by NULL. Some tests share data, but use
58*22dc650dSSadaf Ebrahimi different flags. */
59*22dc650dSSadaf Ebrahimi
60*22dc650dSSadaf Ebrahimi static const char *data0_1[] = { "posix", "lower posix", "upper POSIX", NULL };
61*22dc650dSSadaf Ebrahimi static const char *data2_3[] = { "(*LF)^(cat|dog)", "catastrophic\ncataclysm",
62*22dc650dSSadaf Ebrahimi "dogfight", "no animals", NULL };
63*22dc650dSSadaf Ebrahimi static const char *data4[] = { "*badpattern", NULL };
64*22dc650dSSadaf Ebrahimi
65*22dc650dSSadaf Ebrahimi /* Index the data strings */
66*22dc650dSSadaf Ebrahimi
67*22dc650dSSadaf Ebrahimi static char **data[] = {
68*22dc650dSSadaf Ebrahimi (char **)(&data0_1),
69*22dc650dSSadaf Ebrahimi (char **)(&data0_1),
70*22dc650dSSadaf Ebrahimi (char **)(&data2_3),
71*22dc650dSSadaf Ebrahimi (char **)(&data2_3),
72*22dc650dSSadaf Ebrahimi (char **)(&data4)
73*22dc650dSSadaf Ebrahimi };
74*22dc650dSSadaf Ebrahimi
75*22dc650dSSadaf Ebrahimi /* The expected results for each pattern consist of a compiler return code,
76*22dc650dSSadaf Ebrahimi optionally followed, for each subject string, by a match return code and, for a
77*22dc650dSSadaf Ebrahimi successful match, up to CAPCOUNT pairs of returned match data. */
78*22dc650dSSadaf Ebrahimi
79*22dc650dSSadaf Ebrahimi static int results0[] = {
80*22dc650dSSadaf Ebrahimi 0, /* Compiler rc */
81*22dc650dSSadaf Ebrahimi 0, 6, 11, /* 1st match */
82*22dc650dSSadaf Ebrahimi REG_NOMATCH /* 2nd match */
83*22dc650dSSadaf Ebrahimi };
84*22dc650dSSadaf Ebrahimi
85*22dc650dSSadaf Ebrahimi static int results1[] = {
86*22dc650dSSadaf Ebrahimi 0, /* Compiler rc */
87*22dc650dSSadaf Ebrahimi 0, 6, 11, /* 1st match */
88*22dc650dSSadaf Ebrahimi 0, 6, 11 /* 2nd match */
89*22dc650dSSadaf Ebrahimi };
90*22dc650dSSadaf Ebrahimi
91*22dc650dSSadaf Ebrahimi static int results2[] = {
92*22dc650dSSadaf Ebrahimi 0, /* Compiler rc */
93*22dc650dSSadaf Ebrahimi 0, 0, 3, 0, 3, /* 1st match */
94*22dc650dSSadaf Ebrahimi 0, 0, 3, 0, 3, /* 2nd match */
95*22dc650dSSadaf Ebrahimi REG_NOMATCH /* 3rd match */
96*22dc650dSSadaf Ebrahimi };
97*22dc650dSSadaf Ebrahimi
98*22dc650dSSadaf Ebrahimi static int results3[] = {
99*22dc650dSSadaf Ebrahimi 0, /* Compiler rc */
100*22dc650dSSadaf Ebrahimi 0, 13, 16, 13, 16, /* 1st match */
101*22dc650dSSadaf Ebrahimi REG_NOMATCH, /* 2nd match */
102*22dc650dSSadaf Ebrahimi REG_NOMATCH /* 3rd match */
103*22dc650dSSadaf Ebrahimi };
104*22dc650dSSadaf Ebrahimi
105*22dc650dSSadaf Ebrahimi static int results4[] = {
106*22dc650dSSadaf Ebrahimi REG_BADRPT /* Compiler rc */
107*22dc650dSSadaf Ebrahimi };
108*22dc650dSSadaf Ebrahimi
109*22dc650dSSadaf Ebrahimi /* Index the result vectors */
110*22dc650dSSadaf Ebrahimi
111*22dc650dSSadaf Ebrahimi static int *results[] = {
112*22dc650dSSadaf Ebrahimi (int *)(&results0),
113*22dc650dSSadaf Ebrahimi (int *)(&results1),
114*22dc650dSSadaf Ebrahimi (int *)(&results2),
115*22dc650dSSadaf Ebrahimi (int *)(&results3),
116*22dc650dSSadaf Ebrahimi (int *)(&results4)
117*22dc650dSSadaf Ebrahimi };
118*22dc650dSSadaf Ebrahimi
119*22dc650dSSadaf Ebrahimi /* And here is the program */
120*22dc650dSSadaf Ebrahimi
main(int argc,char ** argv)121*22dc650dSSadaf Ebrahimi int main(int argc, char **argv)
122*22dc650dSSadaf Ebrahimi {
123*22dc650dSSadaf Ebrahimi regex_t re;
124*22dc650dSSadaf Ebrahimi regmatch_t match[CAPCOUNT];
125*22dc650dSSadaf Ebrahimi int v = argc > 1 && strcmp(argv[1], "-v") == 0;
126*22dc650dSSadaf Ebrahimi
127*22dc650dSSadaf Ebrahimi PRINTF("Test of pcre2posix.h without pcre2.h\n");
128*22dc650dSSadaf Ebrahimi
129*22dc650dSSadaf Ebrahimi for (int i = 0; i < count; i++)
130*22dc650dSSadaf Ebrahimi {
131*22dc650dSSadaf Ebrahimi char *pattern = data[i][0];
132*22dc650dSSadaf Ebrahimi char **subjects = data[i] + 1;
133*22dc650dSSadaf Ebrahimi int *rd = results[i];
134*22dc650dSSadaf Ebrahimi int rc = regcomp(&re, pattern, cflags[i]);
135*22dc650dSSadaf Ebrahimi
136*22dc650dSSadaf Ebrahimi PRINTF("Pattern: %s flags=0x%02x\n", pattern, cflags[i]);
137*22dc650dSSadaf Ebrahimi
138*22dc650dSSadaf Ebrahimi if (rc != *rd)
139*22dc650dSSadaf Ebrahimi {
140*22dc650dSSadaf Ebrahimi fprintf(stderr, "Unexpected compile error %d (expected %d)\n", rc, *rd);
141*22dc650dSSadaf Ebrahimi fprintf(stderr, "Pattern is: %s\n", pattern);
142*22dc650dSSadaf Ebrahimi return 1;
143*22dc650dSSadaf Ebrahimi }
144*22dc650dSSadaf Ebrahimi
145*22dc650dSSadaf Ebrahimi if (rc != 0)
146*22dc650dSSadaf Ebrahimi {
147*22dc650dSSadaf Ebrahimi if (v)
148*22dc650dSSadaf Ebrahimi {
149*22dc650dSSadaf Ebrahimi char buffer[256];
150*22dc650dSSadaf Ebrahimi (void)regerror(rc, &re, buffer, sizeof(buffer));
151*22dc650dSSadaf Ebrahimi PRINTF("Compile error %d: %s (expected)\n", rc, buffer);
152*22dc650dSSadaf Ebrahimi }
153*22dc650dSSadaf Ebrahimi continue;
154*22dc650dSSadaf Ebrahimi }
155*22dc650dSSadaf Ebrahimi
156*22dc650dSSadaf Ebrahimi for (; *subjects != NULL; subjects++)
157*22dc650dSSadaf Ebrahimi {
158*22dc650dSSadaf Ebrahimi rc = regexec(&re, *subjects, CAPCOUNT, match, mflags[i]);
159*22dc650dSSadaf Ebrahimi
160*22dc650dSSadaf Ebrahimi PRINTF("Subject: %s\n", *subjects);
161*22dc650dSSadaf Ebrahimi PRINTF("Return: %d", rc);
162*22dc650dSSadaf Ebrahimi
163*22dc650dSSadaf Ebrahimi if (rc != *(++rd))
164*22dc650dSSadaf Ebrahimi {
165*22dc650dSSadaf Ebrahimi PRINTF("\n");
166*22dc650dSSadaf Ebrahimi fprintf(stderr, "Unexpected match error %d (expected %d)\n", rc, *rd);
167*22dc650dSSadaf Ebrahimi fprintf(stderr, "Pattern is: %s\n", pattern);
168*22dc650dSSadaf Ebrahimi fprintf(stderr, "Subject is: %s\n", *subjects);
169*22dc650dSSadaf Ebrahimi return 1;
170*22dc650dSSadaf Ebrahimi }
171*22dc650dSSadaf Ebrahimi
172*22dc650dSSadaf Ebrahimi if (rc == 0)
173*22dc650dSSadaf Ebrahimi {
174*22dc650dSSadaf Ebrahimi for (int j = 0; j < CAPCOUNT; j++)
175*22dc650dSSadaf Ebrahimi {
176*22dc650dSSadaf Ebrahimi regmatch_t *m = match + j;
177*22dc650dSSadaf Ebrahimi if (m->rm_so < 0) continue;
178*22dc650dSSadaf Ebrahimi if (m->rm_so != *(++rd) || m->rm_eo != *(++rd))
179*22dc650dSSadaf Ebrahimi {
180*22dc650dSSadaf Ebrahimi PRINTF("\n");
181*22dc650dSSadaf Ebrahimi fprintf(stderr, "Mismatched results for successful match\n");
182*22dc650dSSadaf Ebrahimi fprintf(stderr, "Pattern is: %s\n", pattern);
183*22dc650dSSadaf Ebrahimi fprintf(stderr, "Subject is: %s\n", *subjects);
184*22dc650dSSadaf Ebrahimi fprintf(stderr, "Result %d: expected %d %d received %d %d\n",
185*22dc650dSSadaf Ebrahimi j, rd[-1], rd[0], m->rm_so, m->rm_eo);
186*22dc650dSSadaf Ebrahimi return 1;
187*22dc650dSSadaf Ebrahimi }
188*22dc650dSSadaf Ebrahimi PRINTF(" (%d %d %d)", j, m->rm_so, m->rm_eo);
189*22dc650dSSadaf Ebrahimi }
190*22dc650dSSadaf Ebrahimi }
191*22dc650dSSadaf Ebrahimi
192*22dc650dSSadaf Ebrahimi else if (v)
193*22dc650dSSadaf Ebrahimi {
194*22dc650dSSadaf Ebrahimi char buffer[256];
195*22dc650dSSadaf Ebrahimi (void)regerror(rc, &re, buffer, sizeof(buffer));
196*22dc650dSSadaf Ebrahimi PRINTF(": %s (expected)", buffer);
197*22dc650dSSadaf Ebrahimi }
198*22dc650dSSadaf Ebrahimi
199*22dc650dSSadaf Ebrahimi PRINTF("\n");
200*22dc650dSSadaf Ebrahimi }
201*22dc650dSSadaf Ebrahimi
202*22dc650dSSadaf Ebrahimi regfree(&re);
203*22dc650dSSadaf Ebrahimi }
204*22dc650dSSadaf Ebrahimi
205*22dc650dSSadaf Ebrahimi PRINTF("End of test\n");
206*22dc650dSSadaf Ebrahimi return 0;
207*22dc650dSSadaf Ebrahimi }
208*22dc650dSSadaf Ebrahimi
209*22dc650dSSadaf Ebrahimi /* End of pcre2posix_test.c */
210