OILS / demo / glibc_fnmatch.c View on Github | oilshell.org

71 lines, 43 significant
1#define _GNU_SOURCE 1
2#include <fnmatch.h>
3#include <stdio.h>
4
5/*
6 * BUG: When FNM_EXTMATCH is passed, you should be able to escape | as \|
7 * just like you can escape * as \*.
8 *
9 * (Remember that \| is written "\\|" in C syntax)
10 */
11
12void test(char* pattern, char* str, int flags) {
13 int ret = fnmatch(pattern, str, flags);
14
15 char* prefix = (flags == FNM_EXTMATCH) ? "[ext]" : " ";
16
17 switch (ret) {
18 case 0:
19 printf("%s %-10s matches %-10s\n", prefix, str, pattern);
20 break;
21 case FNM_NOMATCH:
22 printf("%s %-10s doesn't match %-10s\n", prefix, str, pattern);
23 break;
24 default:
25 printf("other error: %s\n", str);
26 break;
27 }
28}
29
30int main() {
31 char* pattern = 0;
32
33 // Demonstrate that \| and \* are valid patterns, whether or not FNM_EXTMATCH
34 // is set
35 pattern = "\\*";
36 test(pattern, "*", FNM_EXTMATCH);
37 test(pattern, "x", FNM_EXTMATCH);
38 printf("\n");
39
40 pattern = "\\|";
41 test(pattern, "|", 0);
42 test(pattern, "x", 0);
43 test(pattern, "|", FNM_EXTMATCH);
44 test(pattern, "x", FNM_EXTMATCH);
45 printf("\n");
46
47 // Wrap in @() works for \*
48 pattern = "@(\\*)";
49 test(pattern, "*", FNM_EXTMATCH);
50 test(pattern, "x", FNM_EXTMATCH);
51 printf("\n");
52
53 // Wrap in @() doesn't work for \|
54 pattern = "@(\\|)";
55 test(pattern, "|", FNM_EXTMATCH); // BUG: doesn't match
56 test(pattern, "x", FNM_EXTMATCH);
57 printf("\n");
58
59 // More realistic example
60 pattern = "@(spam|foo\\||bar\\*)";
61
62 // Demonstrate that \* escaping works
63 test(pattern, "bar*", FNM_EXTMATCH);
64 test(pattern, "bar\\", FNM_EXTMATCH);
65
66 test(pattern, "foo|",
67 FNM_EXTMATCH); // BUG: this should match, but it doesn't
68 test(pattern, "foo\\|", FNM_EXTMATCH); // shouldn't match and doesn't match
69
70 return 0;
71}