lib: remove librte_ prefix from directory names
[dpdk.git] / lib / eal / windows / fnmatch.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright (c) 1989, 1993, 1994
3  *      The Regents of the University of California.  All rights reserved.
4  *
5  * This code is derived from software contributed to Berkeley by
6  * Guido van Rossum.
7  */
8
9 #if defined(LIBC_SCCS) && !defined(lint)
10 static const char sccsid[] = "@(#)fnmatch.c     8.2 (Berkeley) 4/16/94";
11 #endif /* LIBC_SCCS and not lint */
12
13 /*
14  * Function fnmatch() as specified in POSIX 1003.2-1992, section B.6.
15  * Compares a filename or pathname to a pattern.
16  */
17
18 #include <ctype.h>
19 #include <string.h>
20 #include <stdio.h>
21
22 #include "fnmatch.h"
23
24 #define EOS     '\0'
25
26 static const char *rangematch(const char *, char, int);
27
28 int
29 fnmatch(const char *pattern, const char *string, int flags)
30 {
31         const char *stringstart;
32         char c, test;
33
34         for (stringstart = string;;)
35                 switch (c = *pattern++) {
36                 case EOS:
37                         if ((flags & FNM_LEADING_DIR) && *string == '/')
38                                 return (0);
39                         return (*string == EOS ? 0 : FNM_NOMATCH);
40                 case '?':
41                         if (*string == EOS)
42                                 return (FNM_NOMATCH);
43                         if (*string == '/' && (flags & FNM_PATHNAME))
44                                 return (FNM_NOMATCH);
45                         if (*string == '.' && (flags & FNM_PERIOD) &&
46                             (string == stringstart ||
47                             ((flags & FNM_PATHNAME) && *(string - 1) == '/')))
48                                 return (FNM_NOMATCH);
49                         ++string;
50                         break;
51                 case '*':
52                         c = *pattern;
53                         /* Collapse multiple stars. */
54                         while (c == '*')
55                                 c = *++pattern;
56
57                         if (*string == '.' && (flags & FNM_PERIOD) &&
58                             (string == stringstart ||
59                             ((flags & FNM_PATHNAME) && *(string - 1) == '/')))
60                                 return (FNM_NOMATCH);
61
62                         /* Optimize for pattern with * at end or before /. */
63                         if (c == EOS)
64                                 if (flags & FNM_PATHNAME)
65                                         return ((flags & FNM_LEADING_DIR) ||
66                                             strchr(string, '/') == NULL ?
67                                             0 : FNM_NOMATCH);
68                                 else
69                                         return (0);
70                         else if (c == '/' && flags & FNM_PATHNAME) {
71                                 string = strchr(string, '/');
72                                 if (string == NULL)
73                                         return (FNM_NOMATCH);
74                                 break;
75                         }
76
77                         /* General case, use recursion. */
78                         while ((test = *string) != EOS) {
79                                 if (!fnmatch(pattern, string,
80                                         flags & ~FNM_PERIOD))
81                                         return (0);
82                                 if (test == '/' && flags & FNM_PATHNAME)
83                                         break;
84                                 ++string;
85                         }
86                         return (FNM_NOMATCH);
87                 case '[':
88                         if (*string == EOS)
89                                 return (FNM_NOMATCH);
90                         if (*string == '/' && flags & FNM_PATHNAME)
91                                 return (FNM_NOMATCH);
92                         pattern = rangematch(pattern, *string, flags);
93                         if (pattern == NULL)
94                                 return (FNM_NOMATCH);
95                         ++string;
96                         break;
97                 case '\\':
98                         if (!(flags & FNM_NOESCAPE)) {
99                                 c = *pattern++;
100                                 if (c == EOS) {
101                                         c = '\\';
102                                         --pattern;
103                                 }
104                         }
105                         /* FALLTHROUGH */
106                 default:
107                         if (c == *string)
108                                 ;
109                         else if ((flags & FNM_CASEFOLD) &&
110                                  (tolower((unsigned char)c) ==
111                                   tolower((unsigned char)*string)))
112                                 ;
113                         else if ((flags & FNM_PREFIX_DIRS) && *string == EOS &&
114                              ((c == '/' && string != stringstart) ||
115                              (string == stringstart+1 && *stringstart == '/')))
116                                 return (0);
117                         else
118                                 return (FNM_NOMATCH);
119                         string++;
120                         break;
121                 }
122         /* NOTREACHED */
123 }
124
125 static const char *
126 rangematch(const char *pattern, char test, int flags)
127 {
128         int negate, ok;
129         char c, c2;
130
131         /*
132          * A bracket expression starting with an unquoted circumflex
133          * character produces unspecified results (IEEE 1003.2-1992,
134          * 3.13.2).  This implementation treats it like '!', for
135          * consistency with the regular expression syntax.
136          * J.T. Conklin (conklin@ngai.kaleida.com)
137          */
138         negate = (*pattern == '!' || *pattern == '^');
139         if (negate)
140                 ++pattern;
141
142         if (flags & FNM_CASEFOLD)
143                 test = tolower((unsigned char)test);
144
145         for (ok = 0; (c = *pattern++) != ']';) {
146                 if (c == '\\' && !(flags & FNM_NOESCAPE))
147                         c = *pattern++;
148                 if (c == EOS)
149                         return (NULL);
150
151                 if (flags & FNM_CASEFOLD)
152                         c = tolower((unsigned char)c);
153
154                 c2 = *(pattern + 1);
155                 if (*pattern == '-' && c2 != EOS && c2 != ']') {
156                         pattern += 2;
157                         if (c2 == '\\' && !(flags & FNM_NOESCAPE))
158                                 c2 = *pattern++;
159                         if (c2 == EOS)
160                                 return (NULL);
161
162                         if (flags & FNM_CASEFOLD)
163                                 c2 = tolower((unsigned char)c2);
164
165                         if ((unsigned char)c <= (unsigned char)test &&
166                             (unsigned char)test <= (unsigned char)c2)
167                                 ok = 1;
168                 } else if (c == test)
169                         ok = 1;
170         }
171         return (ok == negate ? NULL : pattern);
172 }