Don't run tests checking xecutable stack when SELinux is enforcing.
[glibc.git] / posix / tst-fnmatch.c
blob7e1f73a975f8944351d7b8ca901c8f5237a5f7a1
1 /* Tests for fnmatch function.
2 Copyright (C) 2000, 2001, 2010 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, write to the Free
17 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18 02111-1307 USA. */
20 #include <errno.h>
21 #include <error.h>
22 #include <fnmatch.h>
23 #include <locale.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <sys/types.h>
28 #include <mcheck.h>
31 static char *next_input (char **line, int first, int last);
32 static int convert_flags (const char *str);
33 static char *flag_output (int flags);
34 static char *escape (const char *str, size_t *reslenp, char **resbuf);
37 int
38 main (void)
40 char *linebuf = NULL;
41 size_t linebuflen = 0;
42 int ntests = 0;
43 int nfailed = 0;
44 char *escinput = NULL;
45 size_t escinputlen = 0;
46 char *escpattern = NULL;
47 size_t escpatternlen = 0;
48 int nr = 0;
50 mtrace ();
52 /* Read lines from stdin with the following format:
54 locale input-string match-string flags result
56 where `result' is either 0 or 1. If the first character of a
57 string is '"' we read until the next '"' and handled escaped '"'. */
58 while (! feof (stdin))
60 ssize_t n = getline (&linebuf, &linebuflen, stdin);
61 char *cp;
62 const char *locale;
63 const char *input;
64 const char *pattern;
65 const char *result_str;
66 int result;
67 const char *flags;
68 int flags_val;
69 int fnmres;
70 char numbuf[24];
72 if (n == -1)
73 break;
75 if (n == 0)
76 /* Maybe an empty line. */
77 continue;
79 /* Skip over all leading white spaces. */
80 cp = linebuf;
82 locale = next_input (&cp, 1, 0);
83 if (locale == NULL)
84 continue;
86 input = next_input (&cp, 0, 0);
87 if (input == NULL)
88 continue;
90 pattern = next_input (&cp, 0, 0);
91 if (pattern == NULL)
92 continue;
94 result_str = next_input (&cp, 0, 0);
95 if (result_str == NULL)
96 continue;
98 if (strcmp (result_str, "0") == 0)
99 result = 0;
100 else if (strcasecmp (result_str, "NOMATCH") == 0)
101 result = FNM_NOMATCH;
102 else
104 char *endp;
105 result = strtol (result_str, &endp, 0);
106 if (*endp != '\0')
107 continue;
110 flags = next_input (&cp, 0, 1);
111 if (flags == NULL)
112 /* We allow the flags missing. */
113 flags = "";
115 /* Convert the text describing the flags in a numeric value. */
116 flags_val = convert_flags (flags);
117 if (flags_val == -1)
118 /* Something went wrong. */
119 continue;
121 /* Now run the actual test. */
122 ++ntests;
124 if (setlocale (LC_COLLATE, locale) == NULL
125 || setlocale (LC_CTYPE, locale) == NULL)
127 puts ("*** Cannot set locale");
128 ++nfailed;
129 continue;
132 fnmres = fnmatch (pattern, input, flags_val);
134 printf ("%3d: fnmatch (\"%s\", \"%s\", %s) = %s%c",
135 ++nr,
136 escape (pattern, &escpatternlen, &escpattern),
137 escape (input, &escinputlen, &escinput),
138 flag_output (flags_val),
139 (fnmres == 0
140 ? "0" : (fnmres == FNM_NOMATCH
141 ? "FNM_NOMATCH"
142 : (sprintf (numbuf, "%d", fnmres), numbuf))),
143 (fnmres != 0) != (result != 0) ? ' ' : '\n');
145 if ((fnmres != 0) != (result != 0))
147 printf ("(FAIL, expected %s) ***\n",
148 result == 0
149 ? "0" : (result == FNM_NOMATCH
150 ? "FNM_NOMATCH"
151 : (sprintf (numbuf, "%d", result), numbuf)));
152 ++nfailed;
156 printf ("=====================\n%3d tests, %3d failed\n", ntests, nfailed);
158 free (escpattern);
159 free (escinput);
160 free (linebuf);
162 return nfailed != 0;
166 static char *
167 next_input (char **line, int first, int last)
169 char *cp = *line;
170 char *result;
172 while (*cp == ' ' || *cp == '\t')
173 ++cp;
175 /* We allow comment lines starting with '#'. */
176 if (first && *cp == '#')
177 return NULL;
179 if (*cp == '"')
181 char *wp;
183 result = ++cp;
184 wp = cp;
186 while (*cp != '"' && *cp != '\0' && *cp != '\n')
187 if (*cp == '\\')
189 if (cp[1] == '\n' || cp[1] == '\0')
190 return NULL;
192 ++cp;
193 if (*cp == 't')
194 *wp++ = '\t';
195 else if (*cp == 'n')
196 *wp++ = '\n';
197 else
198 *wp++ = *cp;
200 ++cp;
202 else
203 *wp++ = *cp++;
205 if (*cp != '"')
206 return NULL;
208 if (wp != cp)
209 *wp = '\0';
211 else
213 result = cp;
214 while (*cp != '\0' && *cp != '\n' && *cp != ' ' && *cp != '\t')
215 ++cp;
217 if (cp == result && ! last)
218 /* Premature end of line. */
219 return NULL;
222 /* Terminate and skip over the next white spaces. */
223 *cp++ = '\0';
225 *line = cp;
226 return result;
230 static int
231 convert_flags (const char *str)
233 int result = 0;
235 while (*str != '\0')
237 int len;
239 if (strncasecmp (str, "PATHNAME", 8) == 0
240 && (str[8] == '|' || str[8] == '\0'))
242 result |= FNM_PATHNAME;
243 len = 8;
245 else if (strncasecmp (str, "NOESCAPE", 8) == 0
246 && (str[8] == '|' || str[8] == '\0'))
248 result |= FNM_NOESCAPE;
249 len = 8;
251 else if (strncasecmp (str, "PERIOD", 6) == 0
252 && (str[6] == '|' || str[6] == '\0'))
254 result |= FNM_PERIOD;
255 len = 6;
257 else if (strncasecmp (str, "LEADING_DIR", 11) == 0
258 && (str[11] == '|' || str[11] == '\0'))
260 result |= FNM_LEADING_DIR;
261 len = 11;
263 else if (strncasecmp (str, "CASEFOLD", 8) == 0
264 && (str[8] == '|' || str[8] == '\0'))
266 result |= FNM_CASEFOLD;
267 len = 8;
269 else if (strncasecmp (str, "EXTMATCH", 8) == 0
270 && (str[8] == '|' || str[8] == '\0'))
272 result |= FNM_EXTMATCH;
273 len = 8;
275 else
276 return -1;
278 str += len;
279 if (*str != '\0')
280 ++str;
283 return result;
287 static char *
288 flag_output (int flags)
290 static char buf[100];
291 int first = 1;
292 char *cp = buf;
294 if (flags & FNM_PATHNAME)
296 cp = stpcpy (cp, "FNM_PATHNAME");
297 first = 0;
299 if (flags & FNM_NOESCAPE)
301 if (! first)
302 *cp++ = '|';
303 cp = stpcpy (cp, "FNM_NOESCAPE");
304 first = 0;
306 if (flags & FNM_PERIOD)
308 if (! first)
309 *cp++ = '|';
310 cp = stpcpy (cp, "FNM_PERIOD");
311 first = 0;
313 if (flags & FNM_LEADING_DIR)
315 if (! first)
316 *cp++ = '|';
317 cp = stpcpy (cp, "FNM_LEADING_DIR");
318 first = 0;
320 if (flags & FNM_CASEFOLD)
322 if (! first)
323 *cp++ = '|';
324 cp = stpcpy (cp, "FNM_CASEFOLD");
325 first = 0;
327 if (flags & FNM_EXTMATCH)
329 if (! first)
330 *cp++ = '|';
331 cp = stpcpy (cp, "FNM_EXTMATCH");
332 first = 0;
334 if (cp == buf)
335 *cp++ = '0';
336 *cp = '\0';
338 return buf;
342 static char *
343 escape (const char *str, size_t *reslenp, char **resbufp)
345 size_t reslen = *reslenp;
346 char *resbuf = *resbufp;
347 size_t len = strlen (str);
348 char *wp;
350 if (2 * len + 1 > reslen)
352 resbuf = (char *) realloc (resbuf, 2 * len + 1);
353 if (resbuf == NULL)
354 error (EXIT_FAILURE, errno, "while allocating buffer for printing");
355 *reslenp = 2 * len + 1;
356 *resbufp = resbuf;
359 wp = resbuf;
360 while (*str != '\0')
361 if (*str == '\t')
363 *wp++ = '\\';
364 *wp++ = 't';
365 ++str;
367 else if (*str == '\n')
369 *wp++ = '\\';
370 *wp++ = 'n';
371 ++str;
373 else if (*str == '"')
375 *wp++ = '\\';
376 *wp++ = '"';
377 ++str;
379 else if (*str == '\\')
381 *wp++ = '\\';
382 *wp++ = '\\';
383 ++str;
385 else
386 *wp++ = *str++;
388 *wp = '\0';
390 return resbuf;