📄 fnmatch.c
字号:
/* @(#)fnmatch.c 1.3 99/03/02 eric */#ifndef lintstatic char sccsid[] = "@(#)fnmatch.c 1.3 99/03/02 eric";#endif/* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc.NOTE: The canonical source of this file is maintained with the GNU C Library.Bugs can be reported to bug-glibc@prep.ai.mit.edu.This program is free software; you can redistribute it and/or modify itunder the terms of the GNU General Public License as published by theFree Software Foundation; either version 2, or (at your option) anylater version.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, 675 Mass Ave, Cambridge, MA 02139, USA. */#ifdef HAVE_CONFIG_H#include <config.h>#endif#include <errno.h>#include <fnmatch.h>#ifndef __STDC__#define const#endif#ifndef FNM_FILE_NAME#define FNM_FILE_NAME FNM_PATHNAME /* Preferred GNU name. */#endif#ifndef FNM_LEADING_DIR#define FNM_LEADING_DIR (1 << 3) /* Ignore `/...' after a match. */#endif#ifndef FNM_CASEFOLD#define FNM_CASEFOLD (1 << 4) /* Compare without regard to case. */#endif#include <ctype.h>#if defined (STDC_HEADERS) || !defined (isascii)#define ISASCII(c) 1#else#define ISASCII(c) isascii(c)#endif#define ISUPPER(c) (ISASCII (c) && isupper (c))/* Comment out all this code if we are using the GNU C Library, and are not actually compiling the library itself. This code is part of the GNU C Library, but also included in many other GNU distributions. Compiling and linking in this code is a waste when using the GNU C library (especially if it is a shared library). Rather than having every GNU program understand `configure --with-gnu-libc' and omit the object files, it is simpler to just do this in the source for each such file. */#if defined (_LIBC) || !defined (__GNU_LIBRARY__)#if !defined(__GNU_LIBRARY__) && !defined(STDC_HEADERS)extern int errno;#endif/* Match STRING against the filename pattern PATTERN, returning zero if it matches, nonzero if not. */intfnmatch (pattern, string, flags) const char *pattern; const char *string; int flags;{ register const char *p = pattern, *n = string; register char c;/* Note that this evalutes C many times. */#define FOLD(c) ((flags & FNM_CASEFOLD) && ISUPPER (c) ? tolower (c) : (c)) while ((c = *p++) != '\0') { c = FOLD ((unsigned char)c); switch (c) { case '?': if (*n == '\0') return FNM_NOMATCH; else if ((flags & FNM_FILE_NAME) && *n == '/') return FNM_NOMATCH; else if ((flags & FNM_PERIOD) && *n == '.' && (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/'))) return FNM_NOMATCH; break; case '\\': if (!(flags & FNM_NOESCAPE)) { c = *p++; c = FOLD ((unsigned char )c); } if (FOLD ((unsigned char )*n) != c) return FNM_NOMATCH; break; case '*': if ((flags & FNM_PERIOD) && *n == '.' && (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/'))) return FNM_NOMATCH; for (c = *p++; c == '?' || c == '*'; c = *p++, ++n) if (((flags & FNM_FILE_NAME) && *n == '/') || (c == '?' && *n == '\0')) return FNM_NOMATCH; if (c == '\0') return 0; { char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c; c1 = FOLD ((unsigned char )c1); for (--p; *n != '\0'; ++n) if ((c == '[' || FOLD ((unsigned char )*n) == c1) && fnmatch (p, n, flags & ~FNM_PERIOD) == 0) return 0; return FNM_NOMATCH; } case '[': { /* Nonzero if the sense of the character class is inverted. */ register int not; if (*n == '\0') return FNM_NOMATCH; if ((flags & FNM_PERIOD) && *n == '.' && (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/'))) return FNM_NOMATCH; not = (*p == '!' || *p == '^'); if (not) ++p; c = *p++; for (;;) { register char cstart = c, cend = c; if (!(flags & FNM_NOESCAPE) && c == '\\') cstart = cend = *p++; cstart = cend = FOLD ((unsigned char)cstart); if (c == '\0') /* [ (unterminated) loses. */ return FNM_NOMATCH; c = *p++; c = FOLD ((unsigned char)c); if ((flags & FNM_FILE_NAME) && c == '/') /* [/] can never match. */ return FNM_NOMATCH; if (c == '-' && *p != ']') { cend = *p++; if (!(flags & FNM_NOESCAPE) && cend == '\\') cend = *p++; if (cend == '\0') return FNM_NOMATCH; cend = FOLD ((unsigned char)cend); c = *p++; } if (FOLD ((unsigned char)*n) >= cstart && FOLD ((unsigned char)*n) <= cend) goto matched; if (c == ']') break; } if (!not) return FNM_NOMATCH; break; matched:; /* Skip the rest of the [...] that already matched. */ while (c != ']') { if (c == '\0') /* [... (unterminated) loses. */ return FNM_NOMATCH; c = *p++; if (!(flags & FNM_NOESCAPE) && c == '\\') /* XXX 1003.2d11 is unclear if this is right. */ ++p; } if (not) return FNM_NOMATCH; } break; default: if (c != FOLD ((unsigned char)*n)) return FNM_NOMATCH; } ++n; } if (*n == '\0') return 0; if ((flags & FNM_LEADING_DIR) && *n == '/') /* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz". */ return 0; return FNM_NOMATCH;}#endif /* _LIBC or not __GNU_LIBRARY__. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -