From 7e12f0f085e8a0a29f7a70bca3dddbca09349e50 Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Mon, 3 Sep 2007 06:30:00 +0000 Subject: [PATCH] Commit new fnmatch.c/h git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@5439 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/src/lib/fnmatch.c | 337 ++++++++++++++++++--------------------- bacula/src/lib/fnmatch.h | 42 +++-- 2 files changed, 177 insertions(+), 202 deletions(-) diff --git a/bacula/src/lib/fnmatch.c b/bacula/src/lib/fnmatch.c index 4a9c4d3f9f..ddb00ab30d 100644 --- a/bacula/src/lib/fnmatch.c +++ b/bacula/src/lib/fnmatch.c @@ -1,6 +1,6 @@ /* * Copyright (c) 1989, 1993, 1994 - * The Regents of the University of California. All rights reserved. + * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Guido van Rossum. @@ -30,199 +30,176 @@ * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char rcsid[] = "$OpenBSD: fnmatch.c,v 1.6 1998/03/19 00:29:59 millert Exp $"; -#endif /* LIBC_SCCS and not lint */ +/* OpenBSD: fnmatch.c,v 1.6 1998/03/19 00:29:59 millert */ /* * Function fnmatch() as specified in POSIX 1003.2-1992, section B.6. * Compares a filename or pathname to a pattern. */ -#include "config.h" +/* Version: $Id$ */ -#include -#include -#ifdef HAVE_STRING_H -# include -#else -# ifdef HAVE_STRINGS_H -# include -# endif -#endif /* HAVE_STRING_H */ -#include "compat.h" -#include "emul/fnmatch.h" +#include "bacula.h" +#include "fnmatch.h" -#undef EOS -#define EOS '\0' +#undef EOS +#define EOS '\0' -#define RANGE_MATCH 1 -#define RANGE_NOMATCH 0 -#define RANGE_ERROR (-1) +#define RANGE_MATCH 1 +#define RANGE_NOMATCH 0 +#define RANGE_ERROR (-1) -static int rangematch __P((const char *, char, int, char **)); +#define ISSET(x, y) ((x) & (y)) +#define FOLD(c) ((flags & FNM_CASEFOLD) && B_ISUPPER(c) ? tolower(c) : (c)) -int -fnmatch(pattern, string, flags) - const char *pattern, *string; - int flags; +static int rangematch(const char *, char, int, char **); + +int fnmatch(const char *pattern, const char *string, int flags) { - const char *stringstart; - char *newp; - char c, test; - - for (stringstart = string;;) - switch (c = *pattern++) { - case EOS: - if (ISSET(flags, FNM_LEADING_DIR) && *string == '/') - return (0); - return (*string == EOS ? 0 : FNM_NOMATCH); - case '?': - if (*string == EOS) - return (FNM_NOMATCH); - if (*string == '/' && ISSET(flags, FNM_PATHNAME)) - return (FNM_NOMATCH); - if (*string == '.' && ISSET(flags, FNM_PERIOD) && - (string == stringstart || - (ISSET(flags, FNM_PATHNAME) && *(string - 1) == '/'))) - return (FNM_NOMATCH); - ++string; - break; - case '*': - c = *pattern; - /* Collapse multiple stars. */ - while (c == '*') - c = *++pattern; - - if (*string == '.' && ISSET(flags, FNM_PERIOD) && - (string == stringstart || - (ISSET(flags, FNM_PATHNAME) && *(string - 1) == '/'))) - return (FNM_NOMATCH); - - /* Optimize for pattern with * at end or before /. */ - if (c == EOS) { - if (ISSET(flags, FNM_PATHNAME)) - return (ISSET(flags, FNM_LEADING_DIR) || - strchr(string, '/') == NULL ? - 0 : FNM_NOMATCH); - else - return (0); - } else if (c == '/' && ISSET(flags, FNM_PATHNAME)) { - if ((string = strchr(string, '/')) == NULL) - return (FNM_NOMATCH); - break; - } - - /* General case, use recursion. */ - while ((test = *string) != EOS) { - if (!fnmatch(pattern, string, flags & ~FNM_PERIOD)) - return (0); - if (test == '/' && ISSET(flags, FNM_PATHNAME)) - break; - ++string; - } - return (FNM_NOMATCH); - case '[': - if (*string == EOS) - return (FNM_NOMATCH); - if (*string == '/' && ISSET(flags, FNM_PATHNAME)) - return (FNM_NOMATCH); - if (*string == '.' && ISSET(flags, FNM_PERIOD) && - (string == stringstart || - (ISSET(flags, FNM_PATHNAME) && *(string - 1) == '/'))) - return (FNM_NOMATCH); - - switch (rangematch(pattern, *string, flags, &newp)) { - case RANGE_ERROR: - /* not a good range, treat as normal text */ - goto normal; - case RANGE_MATCH: - pattern = newp; - break; - case RANGE_NOMATCH: - return (FNM_NOMATCH); - } - ++string; - break; - case '\\': - if (!ISSET(flags, FNM_NOESCAPE)) { - if ((c = *pattern++) == EOS) { - c = '\\'; - --pattern; - } - } - /* FALLTHROUGH */ - default: - normal: - if (c != *string && !(ISSET(flags, FNM_CASEFOLD) && - (tolower((unsigned char)c) == - tolower((unsigned char)*string)))) - return (FNM_NOMATCH); - ++string; - break; - } - /* NOTREACHED */ + const char *stringstart; + char *newp; + char c, test; + + stringstart = string; + for ( ;; ) { + switch (c = *pattern++) { + case EOS: + if (ISSET(flags, FNM_LEADING_DIR) && IsPathSeparator(*string)) + return (0); + return (*string == EOS ? 0 : FNM_NOMATCH); + case '?': + if (*string == EOS) + return (FNM_NOMATCH); + if (*string == '/' && ISSET(flags, FNM_PATHNAME)) + return (FNM_NOMATCH); + if (*string == '.' && ISSET(flags, FNM_PERIOD) && + (string == stringstart || + (ISSET(flags, FNM_PATHNAME) && IsPathSeparator(*(string - 1))))) + return (FNM_NOMATCH); + ++string; + break; + case '*': + c = *pattern; + /* Collapse multiple stars. */ + while (c == '*') + c = *++pattern; + + if (*string == '.' && ISSET(flags, FNM_PERIOD) && + (string == stringstart || + (ISSET(flags, FNM_PATHNAME) && IsPathSeparator(*(string - 1))))) + return (FNM_NOMATCH); + + /* Optimize for pattern with * at end or before /. */ + if (c == EOS) { + if (ISSET(flags, FNM_PATHNAME)) + return (ISSET(flags, FNM_LEADING_DIR) || + strchr(string, '/') == NULL ? 0 : FNM_NOMATCH); + else + return (0); + } else if (c == '/' && ISSET(flags, FNM_PATHNAME)) { + if ((string = strchr(string, '/')) == NULL) + return (FNM_NOMATCH); + break; + } + + /* General case, use recursion. */ + while ((test = *string) != EOS) { + if (!fnmatch(pattern, string, flags & ~FNM_PERIOD)) + return (0); + if (test == '/' && ISSET(flags, FNM_PATHNAME)) + break; + ++string; + } + return (FNM_NOMATCH); + case '[': + if (*string == EOS) + return (FNM_NOMATCH); + if (IsPathSeparator(*string) && ISSET(flags, FNM_PATHNAME)) + return (FNM_NOMATCH); + if (*string == '.' && ISSET(flags, FNM_PERIOD) && + (string == stringstart || + (ISSET(flags, FNM_PATHNAME) && IsPathSeparator(*(string - 1))))) + return (FNM_NOMATCH); + + switch (rangematch(pattern, *string, flags, &newp)) { + case RANGE_ERROR: + /* not a good range, treat as normal text */ + goto normal; + case RANGE_MATCH: + pattern = newp; + break; + case RANGE_NOMATCH: + return (FNM_NOMATCH); + } + ++string; + break; + case '\\': + if (!ISSET(flags, FNM_NOESCAPE)) { + if ((c = *pattern++) == EOS) { + c = '\\'; + --pattern; + } + } + /* FALLTHROUGH */ + default: + normal: + if (FOLD(c) != FOLD(*string)) { + return (FNM_NOMATCH); + } + ++string; + break; + } + } + /* NOTREACHED */ } -static int -#ifdef __STDC__ -rangematch(const char *pattern, char test, int flags, char **newp) -#else -rangematch(pattern, test, flags, newp) - const char *pattern; - char test; - int flags; - char **newp; -#endif +static int rangematch(const char *pattern, char test, int flags, + char **newp) { - int negate, ok; - char c, c2; - - /* - * A bracket expression starting with an unquoted circumflex - * character produces unspecified results (IEEE 1003.2-1992, - * 3.13.2). This implementation treats it like '!', for - * consistency with the regular expression syntax. - * J.T. Conklin (conklin@ngai.kaleida.com) - */ - if ((negate = (*pattern == '!' || *pattern == '^'))) - ++pattern; - - if (ISSET(flags, FNM_CASEFOLD)) - test = tolower((unsigned char)test); - - /* - * A right bracket shall lose its special meaning and represent - * itself in a bracket expression if it occurs first in the list. - * -- POSIX.2 2.8.3.2 - */ - ok = 0; - c = *pattern++; - do { - if (c == '\\' && !ISSET(flags, FNM_NOESCAPE)) - c = *pattern++; - if (c == EOS) - return (RANGE_ERROR); - if (c == '/' && ISSET(flags, FNM_PATHNAME)) - return (RANGE_NOMATCH); - if (ISSET(flags, FNM_CASEFOLD)) - c = tolower((unsigned char)c); - if (*pattern == '-' - && (c2 = *(pattern+1)) != EOS && c2 != ']') { - pattern += 2; - if (c2 == '\\' && !ISSET(flags, FNM_NOESCAPE)) - c2 = *pattern++; - if (c2 == EOS) - return (RANGE_ERROR); - if (ISSET(flags, FNM_CASEFOLD)) - c2 = tolower((unsigned char)c2); - if (c <= test && test <= c2) - ok = 1; - } else if (c == test) - ok = 1; - } while ((c = *pattern++) != ']'); - - *newp = (char *)pattern; - return (ok == negate ? RANGE_NOMATCH : RANGE_MATCH); + int negate, ok; + char c, c2; + + /* + * A bracket expression starting with an unquoted circumflex + * character produces unspecified results (IEEE 1003.2-1992, + * 3.13.2). This implementation treats it like '!', for + * consistency with the regular expression syntax. + * J.T. Conklin (conklin@ngai.kaleida.com) + */ + if ((negate = (*pattern == '!' || *pattern == '^'))) + ++pattern; + + test = FOLD(test); + + /* + * A right bracket shall lose its special meaning and represent + * itself in a bracket expression if it occurs first in the list. + * -- POSIX.2 2.8.3.2 + */ + ok = 0; + c = *pattern++; + do { + if (c == '\\' && !ISSET(flags, FNM_NOESCAPE)) + c = *pattern++; + if (c == EOS) + return (RANGE_ERROR); + if (c == '/' && ISSET(flags, FNM_PATHNAME)) + return (RANGE_NOMATCH); + c = FOLD(c); + if (*pattern == '-' && (c2 = *(pattern + 1)) != EOS && c2 != ']') { + pattern += 2; + if (c2 == '\\' && !ISSET(flags, FNM_NOESCAPE)) + c2 = *pattern++; + if (c2 == EOS) + return (RANGE_ERROR); + c2 = FOLD(c2); + if (c <= test && test <= c2) + ok = 1; + } else if (c == test) + ok = 1; + } while ((c = *pattern++) != ']'); + + *newp = (char *) pattern; + return (ok == negate ? RANGE_NOMATCH : RANGE_MATCH); } diff --git a/bacula/src/lib/fnmatch.h b/bacula/src/lib/fnmatch.h index 4b27d06c3d..278410d122 100644 --- a/bacula/src/lib/fnmatch.h +++ b/bacula/src/lib/fnmatch.h @@ -1,9 +1,8 @@ -/* $OpenBSD: fnmatch.h,v 1.8 2005/12/13 00:35:22 millert Exp $ */ -/* $NetBSD: fnmatch.h,v 1.5 1994/10/26 00:55:53 cgd Exp $ */ +/* $OpenBSD: fnmatch.h,v 1.8 2005/12/13 00:35:22 millert Exp $ */ /*- * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. + * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -29,29 +28,28 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)fnmatch.h 8.1 (Berkeley) 6/2/93 + * @(#)fnmatch.h 8.1 (Berkeley) 6/2/93 */ +/* Version: $Id$ */ -#ifndef _FNMATCH_H_ -#define _FNMATCH_H_ +#ifndef _FNMATCH_H_ +#define _FNMATCH_H_ -#include +#undef FNM_PATHNAME +#undef FNM_NOESCAPE +#undef FNM_PERIOD -#define FNM_NOMATCH 1 /* Match failed. */ -#define FNM_NOSYS 2 /* Function not supported (unused). */ +#define FNM_NOMATCH 1 /* Match failed. */ -#define FNM_NOESCAPE 0x01 /* Disable backslash escaping. */ -#define FNM_PATHNAME 0x02 /* Slash must be matched by slash. */ -#define FNM_PERIOD 0x04 /* Period must be matched by period. */ -#if __BSD_VISIBLE -#define FNM_LEADING_DIR 0x08 /* Ignore / after Imatch. */ -#define FNM_CASEFOLD 0x10 /* Case insensitive search. */ -#define FNM_IGNORECASE FNM_CASEFOLD -#define FNM_FILE_NAME FNM_PATHNAME -#endif +#define FNM_PATHNAME 0x01 /* Slash must be matched by slash. */ +#define FNM_NOESCAPE 0x02 /* Disable backslash escaping. */ +#define FNM_PERIOD 0x04 /* Period must be matched by period. */ +#define FNM_LEADING_DIR 0x08 /* Ignore / after Imatch. */ +#define FNM_CASEFOLD 0x10 /* Case insensitive search. */ -__BEGIN_DECLS -int fnmatch(const char *, const char *, int); -__END_DECLS +#define FNM_IGNORECASE FNM_CASEFOLD +#define FNM_FILE_NAME FNM_PATHNAME -#endif /* !_FNMATCH_H_ */ +extern "C" int fnmatch(const char *, const char *, int); + +#endif /* !_FNMATCH_H_ */ -- 2.39.5