2 * ircd_match_t.c - test cases for irc glob matching
8 #include <errno.h> /* errno */
9 #include <fcntl.h> /* O_RDONLY */
12 #include <sys/mman.h> /* mmap(), munmap() */
13 #include <unistd.h> /* sysconf() */
15 #if !defined(MAP_ANONYMOUS)
16 # if defined(MAP_ANON)
17 # define MAP_ANONYMOUS MAP_ANON
19 # error I do not know how to request an anonymous mmap from your OS.
23 #if !defined(_SC_PAGE_SIZE)
24 # if defined(_SC_PAGESIZE)
25 # define _SC_PAGE_SIZE _SC_PAGESIZE
27 # error I do not know how to request the page size from your OS.
33 const char *should_match;
34 const char *shouldnt_match;
37 const struct match_test match_tests[] = {
42 "a\0pizza\0abe\0brack\0",
46 "*PeacefuL*\0pizza\0???\0" },
51 "abc\0fooabc\0ababc\0",
58 "dark\\s|de!pimp\0joe\\[mama\0" },
62 int test_match(const char glob[], const char name[])
64 static unsigned int page_size;
71 /* If we have not yet set up our test mappings, do so. */
76 page_size = sysconf(_SC_PAGE_SIZE);
77 if (page_size == 0 || page_size == (unsigned int)-1)
79 fprintf(stderr, "sysconf(_SC_PAGE_SIZE) failed: %s\n", strerror(errno));
82 dev_zero_fd = open("/dev/zero", O_RDONLY);
83 /* If dev_zero_fd == -1 (failed), we may still be able to mmap anonymously. */
84 pages = mmap(NULL, 4 * page_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, dev_zero_fd, 0);
85 if (pages == MAP_FAILED)
87 /* Try using fd == -1 for MAP_ANONYMOUS, which BSD systems require. */
88 pages = mmap(NULL, 4 * page_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
90 if (pages == MAP_FAILED)
92 fprintf(stderr, "Unable to map pages: %s\n", strerror(errno));
100 res = munmap(pages + page_size * 1, page_size);
103 fprintf(stderr, "Unable to unmap page 2/4: %s\n", strerror(errno));
104 /* Dysfunctional OSes */
106 munmap(pages + page_size * 3, page_size);
109 fprintf(stderr, "Unable to unmap page 4/4: %s\n", strerror(errno));
113 /* Copy the strings to the end of their respective pages. */
114 length = strlen(glob) + 1;
115 test_glob = pages + page_size * 1 - length;
116 memcpy(test_glob, glob, length);
117 length = strlen(name) + 1;
118 test_name = pages + page_size * 3 - length;
119 memcpy(test_name, name, length);
121 /* Perform the test. */
122 return match(test_glob, test_name);
125 void do_match_test(const struct match_test *test)
127 const char *candidate;
128 unsigned int matched, not_matched;
131 for (candidate = test->should_match, matched = 0;
133 candidate += strlen(candidate) + 1, ++matched) {
134 res = test_match(test->glob, candidate);
136 fprintf(stderr, "\"%s\" failed to match \"%s\".\n", test->glob, candidate);
141 for (candidate = test->shouldnt_match, not_matched = 0;
143 candidate += strlen(candidate) + 1, ++not_matched) {
144 res = test_match(test->glob, candidate);
146 fprintf(stderr, "\"%s\" incorrectly matched \"%s\".\n", test->glob, candidate);
151 printf("Passed: %s (%u matches, %u non-matches)\n",
152 test->glob, matched, not_matched);
155 int main(int argc, char *argv[])
157 const struct match_test *match;
158 for (match = match_tests; match->glob; ++match)
159 do_match_test(match);