aboutsummaryrefslogtreecommitdiff
path: root/src/pcre2posix_test.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/pcre2posix_test.c')
-rw-r--r--src/pcre2posix_test.c209
1 files changed, 209 insertions, 0 deletions
diff --git a/src/pcre2posix_test.c b/src/pcre2posix_test.c
new file mode 100644
index 00000000..e85e72bc
--- /dev/null
+++ b/src/pcre2posix_test.c
@@ -0,0 +1,209 @@
+/*************************************************
+* PCRE2 POSIX interface test program *
+*************************************************/
+
+/*
+Written by Philip Hazel, December 2022
+Copyright (c) 2022
+File last edited: December 2022
+
+This program tests the POSIX wrapper to the PCRE2 regular expression library.
+The main PCRE2 test program is pcre2test, which also tests these function
+calls. This little program is needed to test the case where the client includes
+pcre2posix.h but not pcre2.h, mainly to make sure that it builds successfully.
+However, the code is written as a flexible test program to which extra tests
+can be added.
+
+Compile with -lpcre2-posix -lpcre2-8
+
+If run with no options, there is no output on success, and the return code is
+zero. If any test fails there is output to stderr, and the return code is 1.
+
+For testing purposes, the "-v" option causes verification output to be written
+to stdout. */
+
+#include <stdio.h>
+#include <string.h>
+#include <pcre2posix.h>
+
+#define CAPCOUNT 5 /* Number of captures supported */
+#define PRINTF if (v) printf /* Shorthand for testing output */
+
+/* This vector contains compiler flags for each pattern that is tested. */
+
+static int cflags[] = {
+ 0, /* Test 0 */
+ REG_ICASE, /* Test 1 */
+ 0, /* Test 2 */
+ REG_NEWLINE, /* Test 3 */
+ 0 /* Test 4 */
+};
+
+/* This vector contains match flags for each pattern that is tested. */
+
+static int mflags[] = {
+ 0, /* Test 0 */
+ 0, /* Test 1 */
+ 0, /* Test 2 */
+ REG_NOTBOL, /* Test 3 */
+ 0 /* Test 4 */
+};
+
+/* Automate the number of patterns */
+
+#define count (int)(sizeof(cflags)/sizeof(int))
+
+/* The data for each pattern consists of a pattern string, followed by any
+number of subject strings, terminated by NULL. Some tests share data, but use
+different flags. */
+
+static const char *data0_1[] = { "posix", "lower posix", "upper POSIX", NULL };
+static const char *data2_3[] = { "^(cat|dog)", "catastrophic\ncataclysm",
+ "dogfight", "no animals", NULL };
+static const char *data4[] = { "*badpattern", NULL };
+
+/* Index the data strings */
+
+static char **data[] = {
+ (char **)(&data0_1),
+ (char **)(&data0_1),
+ (char **)(&data2_3),
+ (char **)(&data2_3),
+ (char **)(&data4)
+};
+
+/* The expected results for each pattern consist of a compiler return code,
+optionally followed, for each subject string, by a match return code and, for a
+successful match, up to CAPCOUNT pairs of returned match data. */
+
+static int results0[] = {
+ 0, /* Compiler rc */
+ 0, 6, 11, /* 1st match */
+ REG_NOMATCH /* 2nd match */
+};
+
+static int results1[] = {
+ 0, /* Compiler rc */
+ 0, 6, 11, /* 1st match */
+ 0, 6, 11 /* 2nd match */
+};
+
+static int results2[] = {
+ 0, /* Compiler rc */
+ 0, 0, 3, 0, 3, /* 1st match */
+ 0, 0, 3, 0, 3, /* 2nd match */
+ REG_NOMATCH /* 3rd match */
+};
+
+static int results3[] = {
+ 0, /* Compiler rc */
+ 0, 13, 16, 13, 16, /* 1st match */
+ REG_NOMATCH, /* 2nd match */
+ REG_NOMATCH /* 3rd match */
+};
+
+static int results4[] = {
+ REG_BADRPT /* Compiler rc */
+};
+
+/* Index the result vectors */
+
+static int *results[] = {
+ (int *)(&results0),
+ (int *)(&results1),
+ (int *)(&results2),
+ (int *)(&results3),
+ (int *)(&results4)
+};
+
+/* And here is the program */
+
+int main(int argc, char **argv)
+{
+regex_t re;
+regmatch_t match[CAPCOUNT];
+int v = argc > 1 && strcmp(argv[1], "-v") == 0;
+
+PRINTF("Test of pcre2posix.h without pcre2.h\n");
+
+for (int i = 0; i < count; i++)
+ {
+ char *pattern = data[i][0];
+ char **subjects = data[i] + 1;
+ int *rd = results[i];
+ int rc = regcomp(&re, pattern, cflags[i]);
+
+ PRINTF("Pattern: %s flags=0x%02x\n", pattern, cflags[i]);
+
+ if (rc != *rd)
+ {
+ fprintf(stderr, "Unexpected compile error %d (expected %d)\n", rc, *rd);
+ fprintf(stderr, "Pattern is: %s\n", pattern);
+ return 1;
+ }
+
+ if (rc != 0)
+ {
+ if (v)
+ {
+ char buffer[256];
+ (void)regerror(rc, &re, buffer, sizeof(buffer));
+ PRINTF("Compile error %d: %s (expected)\n", rc, buffer);
+ }
+ continue;
+ }
+
+ for (; *subjects != NULL; subjects++)
+ {
+ rc = regexec(&re, *subjects, CAPCOUNT, match, mflags[i]);
+
+ PRINTF("Subject: %s\n", *subjects);
+ PRINTF("Return: %d", rc);
+
+ if (rc != *(++rd))
+ {
+ PRINTF("\n");
+ fprintf(stderr, "Unexpected match error %d (expected %d)\n", rc, *rd);
+ fprintf(stderr, "Pattern is: %s\n", pattern);
+ fprintf(stderr, "Subject is: %s\n", *subjects);
+ return 1;
+ }
+
+ if (rc == 0)
+ {
+ for (int j = 0; j < CAPCOUNT; j++)
+ {
+ regmatch_t *m = match + j;
+ if (m->rm_so < 0) continue;
+ if (m->rm_so != *(++rd) || m->rm_eo != *(++rd))
+ {
+ PRINTF("\n");
+ fprintf(stderr, "Mismatched results for successful match\n");
+ fprintf(stderr, "Pattern is: %s\n", pattern);
+ fprintf(stderr, "Subject is: %s\n", *subjects);
+ fprintf(stderr, "Result %d: expected %d %d received %d %d\n",
+ j, rd[-1], rd[0], m->rm_so, m->rm_eo);
+ return 1;
+ }
+ PRINTF(" (%d %d %d)", j, m->rm_so, m->rm_eo);
+ }
+ }
+
+ else if (v)
+ {
+ char buffer[256];
+ (void)regerror(rc, &re, buffer, sizeof(buffer));
+ PRINTF(": %s (expected)", buffer);
+ }
+
+ PRINTF("\n");
+ }
+
+ regfree(&re);
+ }
+
+PRINTF("End of test\n");
+return 0;
+}
+
+/* End of pcre2posix_test.c */