1 /* Tests for fnmatch function.
2 Copyright (C) 2000, 2001 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
28 #include <sys/types.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 str_isalpha(const char *str)
39 size_t i = strlen(str);
41 if (isascii(str[i]) == 0)
45 int str_has_funk(const char *str, const char x)
47 size_t i, max = strlen(str);
48 for (i=0; i+1<max; ++i)
49 if (str[i] == '[' && str[i+1] == x)
59 size_t linebuflen = 0;
63 char *escinput = NULL;
64 size_t escinputlen = 0;
65 char *escpattern = NULL;
66 size_t escpatternlen = 0;
69 /* Read lines from stdin with the following format:
71 locale input-string match-string flags result
73 where `result' is either 0 or 1. If the first character of a
74 string is '"' we read until the next '"' and handled escaped '"'. */
75 while (! feof (stdin))
77 ssize_t n = getline (&linebuf, &linebuflen, stdin);
82 const char *result_str;
93 /* Maybe an empty line. */
96 /* Skip over all leading white spaces. */
99 locale = next_input (&cp, 1, 0);
103 input = next_input (&cp, 0, 0);
107 pattern = next_input (&cp, 0, 0);
111 result_str = next_input (&cp, 0, 0);
112 if (result_str == NULL)
115 if (strcmp (result_str, "0") == 0)
117 else if (strcasecmp (result_str, "NOMATCH") == 0)
118 result = FNM_NOMATCH;
122 result = strtol (result_str, &endp, 0);
127 flags = next_input (&cp, 0, 1);
129 /* We allow the flags missing. */
132 /* Convert the text describing the flags in a numeric value. */
133 flags_val = convert_flags (flags);
135 /* Something went wrong. */
138 /* Now run the actual test. */
141 #ifdef __UCLIBC_HAS_XLOCALE__
142 if (setlocale (LC_COLLATE, locale) == NULL
143 || setlocale (LC_CTYPE, locale) == NULL)
145 puts ("*** Cannot set locale");
150 /* skip non-ascii strings */
151 if (!str_isalpha(pattern) || !str_isalpha(input))
154 printf("%3d: fnmatch (\"%s\", \"%s\"): SKIP multibyte test (requires locale support)\n", ++nr, pattern, input);
157 /* skip collating symbols */
158 if (str_has_funk(pattern, '.') || str_has_funk(input, '.'))
161 printf("%3d: fnmatch (\"%s\", \"%s\"): SKIP collating symbol test (requires locale support)\n", ++nr, pattern, input);
164 /* skip equivalence class expressions */
165 if (str_has_funk(pattern, '=') || str_has_funk(input, '='))
168 printf("%3d: fnmatch (\"%s\", \"%s\"): SKIP equivalence class test (requires locale support)\n", ++nr, pattern, input);
173 fnmres = fnmatch (pattern, input, flags_val);
175 printf ("%3d: fnmatch (\"%s\", \"%s\", %s) = %s%c",
177 escape (pattern, &escpatternlen, &escpattern),
178 escape (input, &escinputlen, &escinput),
179 flag_output (flags_val),
181 ? "0" : (fnmres == FNM_NOMATCH
183 : (sprintf (numbuf, "%d", fnmres), numbuf))),
184 (fnmres != 0) != (result != 0) ? ' ' : '\n');
186 if ((fnmres != 0) != (result != 0))
188 printf ("(FAIL, expected %s) ***\n",
190 ? "0" : (result == FNM_NOMATCH
192 : (sprintf (numbuf, "%d", result), numbuf)));
197 printf ("=====================\n%3d tests, %3d failed, %3d skipped\n", ntests, nfailed, nskipped);
208 next_input (char **line, int first, int last)
213 while (*cp == ' ' || *cp == '\t')
216 /* We allow comment lines starting with '#'. */
217 if (first && *cp == '#')
227 while (*cp != '"' && *cp != '\0' && *cp != '\n')
230 if (cp[1] == '\n' || cp[1] == '\0')
255 while (*cp != '\0' && *cp != '\n' && *cp != ' ' && *cp != '\t')
258 if (cp == result && ! last)
259 /* Premature end of line. */
263 /* Terminate and skip over the next white spaces. */
272 convert_flags (const char *str)
280 if (strncasecmp (str, "PATHNAME", 8) == 0
281 && (str[8] == '|' || str[8] == '\0'))
283 result |= FNM_PATHNAME;
286 else if (strncasecmp (str, "NOESCAPE", 8) == 0
287 && (str[8] == '|' || str[8] == '\0'))
289 result |= FNM_NOESCAPE;
292 else if (strncasecmp (str, "PERIOD", 6) == 0
293 && (str[6] == '|' || str[6] == '\0'))
295 result |= FNM_PERIOD;
298 #ifdef FNM_LEADING_DIR
299 else if (strncasecmp (str, "LEADING_DIR", 11) == 0
300 && (str[11] == '|' || str[11] == '\0'))
302 result |= FNM_LEADING_DIR;
307 else if (strncasecmp (str, "CASEFOLD", 8) == 0
308 && (str[8] == '|' || str[8] == '\0'))
310 result |= FNM_CASEFOLD;
315 else if (strncasecmp (str, "EXTMATCH", 8) == 0
316 && (str[8] == '|' || str[8] == '\0'))
318 result |= FNM_EXTMATCH;
335 flag_output (int flags)
337 static char buf[100];
341 if (flags & FNM_PATHNAME)
343 cp = stpcpy (cp, "FNM_PATHNAME");
346 if (flags & FNM_NOESCAPE)
350 cp = stpcpy (cp, "FNM_NOESCAPE");
353 if (flags & FNM_PERIOD)
357 cp = stpcpy (cp, "FNM_PERIOD");
360 #ifdef FNM_LEADING_DIR
361 if (flags & FNM_LEADING_DIR)
365 cp = stpcpy (cp, "FNM_LEADING_DIR");
370 if (flags & FNM_CASEFOLD)
374 cp = stpcpy (cp, "FNM_CASEFOLD");
379 if (flags & FNM_EXTMATCH)
383 cp = stpcpy (cp, "FNM_EXTMATCH");
396 escape (const char *str, size_t *reslenp, char **resbufp)
398 size_t reslen = *reslenp;
399 char *resbuf = *resbufp;
400 size_t len = strlen (str);
403 if (2 * len + 1 > reslen)
405 resbuf = (char *) realloc (resbuf, 2 * len + 1);
407 error (EXIT_FAILURE, errno, "while allocating buffer for printing");
408 *reslenp = 2 * len + 1;
420 else if (*str == '\n')
426 else if (*str == '"')
432 else if (*str == '\\')