1 /* Tests for fnmatch function.
2 Copyright (C) 2000-2017 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, see
17 <http://www.gnu.org/licenses/>. */
26 #include <sys/types.h>
30 static char *next_input (char **line
, int first
, int last
);
31 static int convert_flags (const char *str
);
32 static char *flag_output (int flags
);
33 static char *escape (const char *str
, size_t *reslenp
, char **resbuf
);
40 size_t linebuflen
= 0;
43 char *escinput
= NULL
;
44 size_t escinputlen
= 0;
45 char *escpattern
= NULL
;
46 size_t escpatternlen
= 0;
51 /* Read lines from stdin with the following format:
53 locale input-string match-string flags result
55 where `result' is either 0 or 1. If the first character of a
56 string is '"' we read until the next '"' and handled escaped '"'. */
57 while (! feof (stdin
))
59 ssize_t n
= getline (&linebuf
, &linebuflen
, stdin
);
64 const char *result_str
;
75 /* Maybe an empty line. */
78 /* Skip over all leading white spaces. */
81 locale
= next_input (&cp
, 1, 0);
85 input
= next_input (&cp
, 0, 0);
89 pattern
= next_input (&cp
, 0, 0);
93 result_str
= next_input (&cp
, 0, 0);
94 if (result_str
== NULL
)
97 if (strcmp (result_str
, "0") == 0)
99 else if (strcasecmp (result_str
, "NOMATCH") == 0)
100 result
= FNM_NOMATCH
;
104 result
= strtol (result_str
, &endp
, 0);
109 flags
= next_input (&cp
, 0, 1);
111 /* We allow the flags missing. */
114 /* Convert the text describing the flags in a numeric value. */
115 flags_val
= convert_flags (flags
);
117 /* Something went wrong. */
120 /* Now run the actual test. */
123 if (setlocale (LC_COLLATE
, locale
) == NULL
124 || setlocale (LC_CTYPE
, locale
) == NULL
)
126 puts ("*** Cannot set locale");
131 fnmres
= fnmatch (pattern
, input
, flags_val
);
133 printf ("%3d: fnmatch (\"%s\", \"%s\", %s) = %s%c",
135 escape (pattern
, &escpatternlen
, &escpattern
),
136 escape (input
, &escinputlen
, &escinput
),
137 flag_output (flags_val
),
139 ? "0" : (fnmres
== FNM_NOMATCH
141 : (sprintf (numbuf
, "%d", fnmres
), numbuf
))),
142 (fnmres
!= 0) != (result
!= 0) ? ' ' : '\n');
144 if ((fnmres
!= 0) != (result
!= 0))
146 printf ("(FAIL, expected %s) ***\n",
148 ? "0" : (result
== FNM_NOMATCH
150 : (sprintf (numbuf
, "%d", result
), numbuf
)));
155 printf ("=====================\n%3d tests, %3d failed\n", ntests
, nfailed
);
166 next_input (char **line
, int first
, int last
)
171 while (*cp
== ' ' || *cp
== '\t')
174 /* We allow comment lines starting with '#'. */
175 if (first
&& *cp
== '#')
185 while (*cp
!= '"' && *cp
!= '\0' && *cp
!= '\n')
188 if (cp
[1] == '\n' || cp
[1] == '\0')
213 while (*cp
!= '\0' && *cp
!= '\n' && *cp
!= ' ' && *cp
!= '\t')
216 if (cp
== result
&& ! last
)
217 /* Premature end of line. */
221 /* Terminate and skip over the next white spaces. */
230 convert_flags (const char *str
)
238 if (strncasecmp (str
, "PATHNAME", 8) == 0
239 && (str
[8] == '|' || str
[8] == '\0'))
241 result
|= FNM_PATHNAME
;
244 else if (strncasecmp (str
, "NOESCAPE", 8) == 0
245 && (str
[8] == '|' || str
[8] == '\0'))
247 result
|= FNM_NOESCAPE
;
250 else if (strncasecmp (str
, "PERIOD", 6) == 0
251 && (str
[6] == '|' || str
[6] == '\0'))
253 result
|= FNM_PERIOD
;
256 else if (strncasecmp (str
, "LEADING_DIR", 11) == 0
257 && (str
[11] == '|' || str
[11] == '\0'))
259 result
|= FNM_LEADING_DIR
;
262 else if (strncasecmp (str
, "CASEFOLD", 8) == 0
263 && (str
[8] == '|' || str
[8] == '\0'))
265 result
|= FNM_CASEFOLD
;
268 else if (strncasecmp (str
, "EXTMATCH", 8) == 0
269 && (str
[8] == '|' || str
[8] == '\0'))
271 result
|= FNM_EXTMATCH
;
287 flag_output (int flags
)
289 static char buf
[100];
293 if (flags
& FNM_PATHNAME
)
295 cp
= stpcpy (cp
, "FNM_PATHNAME");
298 if (flags
& FNM_NOESCAPE
)
302 cp
= stpcpy (cp
, "FNM_NOESCAPE");
305 if (flags
& FNM_PERIOD
)
309 cp
= stpcpy (cp
, "FNM_PERIOD");
312 if (flags
& FNM_LEADING_DIR
)
316 cp
= stpcpy (cp
, "FNM_LEADING_DIR");
319 if (flags
& FNM_CASEFOLD
)
323 cp
= stpcpy (cp
, "FNM_CASEFOLD");
326 if (flags
& FNM_EXTMATCH
)
330 cp
= stpcpy (cp
, "FNM_EXTMATCH");
342 escape (const char *str
, size_t *reslenp
, char **resbufp
)
344 size_t reslen
= *reslenp
;
345 char *resbuf
= *resbufp
;
346 size_t len
= strlen (str
);
349 if (2 * len
+ 1 > reslen
)
351 resbuf
= (char *) realloc (resbuf
, 2 * len
+ 1);
353 error (EXIT_FAILURE
, errno
, "while allocating buffer for printing");
354 *reslenp
= 2 * len
+ 1;
366 else if (*str
== '\n')
372 else if (*str
== '"')
378 else if (*str
== '\\')
392 #define TEST_FUNCTION do_test ()
393 #include "../test-skeleton.c"