mirror of https://github.com/postgres/postgres
This uses the function fnmatch() which is not available on all platforms (notably Windows), so import the implementation from NetBSD into src/port.REL8_5_ALPHA1_BRANCH
parent
a378555501
commit
cb10467d30
@ -0,0 +1,27 @@ |
|||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
* |
||||||
|
* fnmatchstub.h |
||||||
|
* Stubs for fnmatch() in port/fnmatch.c |
||||||
|
* |
||||||
|
* |
||||||
|
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group |
||||||
|
* Portions Copyright (c) 1994, Regents of the University of California |
||||||
|
* |
||||||
|
* $PostgreSQL: pgsql/src/include/fnmatchstub.h,v 1.1 2008/11/24 09:15:16 mha Exp $ |
||||||
|
* |
||||||
|
*------------------------------------------------------------------------- |
||||||
|
*/ |
||||||
|
#ifndef FNMATCHSTUB_H |
||||||
|
#define FNMATCHSTUB_H |
||||||
|
|
||||||
|
extern int fnmatch(const char *, const char *, int); |
||||||
|
#define FNM_NOMATCH 1 /* Match failed. */ |
||||||
|
#define FNM_NOSYS 2 /* Function not implemented. */ |
||||||
|
#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. */ |
||||||
|
#define FNM_CASEFOLD 0x08 /* Pattern is matched case-insensitive */ |
||||||
|
#define FNM_LEADING_DIR 0x10 /* Ignore /<tail> after Imatch. */ |
||||||
|
|
||||||
|
|
||||||
|
#endif |
@ -0,0 +1,198 @@ |
|||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
* |
||||||
|
* fnmatch.c |
||||||
|
* fnmatch() - wildcard matching function |
||||||
|
* |
||||||
|
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group |
||||||
|
* |
||||||
|
* |
||||||
|
* IDENTIFICATION |
||||||
|
* $PostgreSQL: pgsql/src/port/fnmatch.c,v 1.1 2008/11/24 09:15:16 mha Exp $ |
||||||
|
* |
||||||
|
* This file was taken from NetBSD and is used on platforms that don't |
||||||
|
* provide fnmatch(). The NetBSD copyright terms follow. |
||||||
|
*------------------------------------------------------------------------- |
||||||
|
*/ |
||||||
|
|
||||||
|
/* $NetBSD: fnmatch.c,v 1.21 2005/12/24 21:11:16 perry Exp $ */ |
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 1989, 1993, 1994 |
||||||
|
* The Regents of the University of California. All rights reserved. |
||||||
|
* |
||||||
|
* This code is derived from software contributed to Berkeley by |
||||||
|
* Guido van Rossum. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions |
||||||
|
* are met: |
||||||
|
* 1. Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer in the |
||||||
|
* documentation and/or other materials provided with the distribution. |
||||||
|
* 3. Neither the name of the University nor the names of its contributors |
||||||
|
* may be used to endorse or promote products derived from this software |
||||||
|
* without specific prior written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
||||||
|
* SUCH DAMAGE. |
||||||
|
*/ |
||||||
|
|
||||||
|
/*
|
||||||
|
* Function fnmatch() as specified in POSIX 1003.2-1992, section B.6. |
||||||
|
* Compares a filename or pathname to a pattern. |
||||||
|
*/ |
||||||
|
|
||||||
|
#include "c.h" |
||||||
|
#include "fnmatchstub.h" |
||||||
|
|
||||||
|
#define EOS '\0' |
||||||
|
|
||||||
|
static const char *rangematch (const char *, int, int); |
||||||
|
|
||||||
|
static inline int |
||||||
|
foldcase(int ch, int flags) |
||||||
|
{ |
||||||
|
|
||||||
|
if ((flags & FNM_CASEFOLD) != 0 && isupper(ch)) |
||||||
|
return (tolower(ch)); |
||||||
|
return (ch); |
||||||
|
} |
||||||
|
|
||||||
|
#define FOLDCASE(ch, flags) foldcase((unsigned char)(ch), (flags)) |
||||||
|
|
||||||
|
int |
||||||
|
fnmatch(pattern, string, flags) |
||||||
|
const char *pattern, *string; |
||||||
|
int flags; |
||||||
|
{ |
||||||
|
const char *stringstart; |
||||||
|
char c, test; |
||||||
|
|
||||||
|
for (stringstart = string;;) |
||||||
|
switch (c = FOLDCASE(*pattern++, flags)) { |
||||||
|
case EOS: |
||||||
|
if ((flags & FNM_LEADING_DIR) && *string == '/') |
||||||
|
return (0); |
||||||
|
return (*string == EOS ? 0 : FNM_NOMATCH); |
||||||
|
case '?': |
||||||
|
if (*string == EOS) |
||||||
|
return (FNM_NOMATCH); |
||||||
|
if (*string == '/' && (flags & FNM_PATHNAME)) |
||||||
|
return (FNM_NOMATCH); |
||||||
|
if (*string == '.' && (flags & FNM_PERIOD) && |
||||||
|
(string == stringstart || |
||||||
|
((flags & FNM_PATHNAME) && *(string - 1) == '/'))) |
||||||
|
return (FNM_NOMATCH); |
||||||
|
++string; |
||||||
|
break; |
||||||
|
case '*': |
||||||
|
c = FOLDCASE(*pattern, flags); |
||||||
|
/* Collapse multiple stars. */ |
||||||
|
while (c == '*') |
||||||
|
c = FOLDCASE(*++pattern, flags); |
||||||
|
|
||||||
|
if (*string == '.' && (flags & FNM_PERIOD) && |
||||||
|
(string == stringstart || |
||||||
|
((flags & FNM_PATHNAME) && *(string - 1) == '/'))) |
||||||
|
return (FNM_NOMATCH); |
||||||
|
|
||||||
|
/* Optimize for pattern with * at end or before /. */ |
||||||
|
if (c == EOS) { |
||||||
|
if (flags & FNM_PATHNAME) |
||||||
|
return ((flags & FNM_LEADING_DIR) || |
||||||
|
strchr(string, '/') == NULL ? |
||||||
|
0 : FNM_NOMATCH); |
||||||
|
else |
||||||
|
return (0); |
||||||
|
} else if (c == '/' && flags & FNM_PATHNAME) { |
||||||
|
if ((string = strchr(string, '/')) == NULL) |
||||||
|
return (FNM_NOMATCH); |
||||||
|
break; |
||||||
|
} |
||||||
|
|
||||||
|
/* General case, use recursion. */ |
||||||
|
while ((test = FOLDCASE(*string, flags)) != EOS) { |
||||||
|
if (!fnmatch(pattern, string, |
||||||
|
flags & ~FNM_PERIOD)) |
||||||
|
return (0); |
||||||
|
if (test == '/' && flags & FNM_PATHNAME) |
||||||
|
break; |
||||||
|
++string; |
||||||
|
} |
||||||
|
return (FNM_NOMATCH); |
||||||
|
case '[': |
||||||
|
if (*string == EOS) |
||||||
|
return (FNM_NOMATCH); |
||||||
|
if (*string == '/' && flags & FNM_PATHNAME) |
||||||
|
return (FNM_NOMATCH); |
||||||
|
if ((pattern = |
||||||
|
rangematch(pattern, FOLDCASE(*string, flags), |
||||||
|
flags)) == NULL) |
||||||
|
return (FNM_NOMATCH); |
||||||
|
++string; |
||||||
|
break; |
||||||
|
case '\\': |
||||||
|
if (!(flags & FNM_NOESCAPE)) { |
||||||
|
if ((c = FOLDCASE(*pattern++, flags)) == EOS) { |
||||||
|
c = '\\'; |
||||||
|
--pattern; |
||||||
|
} |
||||||
|
} |
||||||
|
/* FALLTHROUGH */ |
||||||
|
default: |
||||||
|
if (c != FOLDCASE(*string++, flags)) |
||||||
|
return (FNM_NOMATCH); |
||||||
|
break; |
||||||
|
} |
||||||
|
/* NOTREACHED */ |
||||||
|
} |
||||||
|
|
||||||
|
static const char * |
||||||
|
rangematch(pattern, test, flags) |
||||||
|
const char *pattern; |
||||||
|
int test, flags; |
||||||
|
{ |
||||||
|
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 == '^')) != 0) |
||||||
|
++pattern; |
||||||
|
|
||||||
|
for (ok = 0; (c = FOLDCASE(*pattern++, flags)) != ']';) { |
||||||
|
if (c == '\\' && !(flags & FNM_NOESCAPE)) |
||||||
|
c = FOLDCASE(*pattern++, flags); |
||||||
|
if (c == EOS) |
||||||
|
return (NULL); |
||||||
|
if (*pattern == '-'
|
||||||
|
&& (c2 = FOLDCASE(*(pattern+1), flags)) != EOS && |
||||||
|
c2 != ']') { |
||||||
|
pattern += 2; |
||||||
|
if (c2 == '\\' && !(flags & FNM_NOESCAPE)) |
||||||
|
c2 = FOLDCASE(*pattern++, flags); |
||||||
|
if (c2 == EOS) |
||||||
|
return (NULL); |
||||||
|
if (c <= test && test <= c2) |
||||||
|
ok = 1; |
||||||
|
} else if (c == test) |
||||||
|
ok = 1; |
||||||
|
} |
||||||
|
return (ok == negate ? NULL : pattern); |
||||||
|
} |
Loading…
Reference in new issue