Implement FNM_CASEFOLD, for matching the pattern in a case-insensitive

way.  Flag name taken from glibc.
This commit is contained in:
thorpej 2000-06-28 01:13:35 +00:00
parent 3c173d4927
commit 445d18ed28
3 changed files with 43 additions and 16 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: fnmatch.h,v 1.6 1998/01/13 12:45:02 kleink Exp $ */
/* $NetBSD: fnmatch.h,v 1.7 2000/06/28 01:13:35 thorpej Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -38,12 +38,17 @@
#ifndef _FNMATCH_H_
#define _FNMATCH_H_
#include <sys/featuretest.h>
#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. */
#if !defined(_POSIX_C_SOURCE)
#define FNM_CASEFOLD 0x08 /* Pattern is matched case-insensitive */
#endif
#include <sys/cdefs.h>

View File

@ -1,4 +1,4 @@
.\" $NetBSD: fnmatch.3,v 1.13 1998/02/05 18:46:17 perry Exp $
.\" $NetBSD: fnmatch.3,v 1.14 2000/06/28 01:13:36 thorpej Exp $
.\"
.\" Copyright (c) 1989, 1991, 1993
.\" The Regents of the University of California. All rights reserved.
@ -98,6 +98,8 @@ Additionally, if
.Dv FNM_PATHNAME
is set,
a period is ``leading'' if it immediately follows a slash.
.It Dv FNM_CASEFOLD
The pattern is matched in a case-insensitive fashion.
.El
.Sh RETURN VALUES
The
@ -117,6 +119,11 @@ The
.Fn fnmatch
function conforms to
.St -p1003.2-92 .
The
.Dv FNM_CASEFOLD
flag is a
.Nx
extension.
.Sh HISTORY
The
.Fn fnmatch

View File

@ -1,4 +1,4 @@
/* $NetBSD: fnmatch.c,v 1.17 2000/01/22 22:19:10 mycroft Exp $ */
/* $NetBSD: fnmatch.c,v 1.18 2000/06/28 01:13:36 thorpej Exp $ */
/*
* Copyright (c) 1989, 1993, 1994
@ -41,7 +41,7 @@
#if 0
static char sccsid[] = "@(#)fnmatch.c 8.2 (Berkeley) 4/16/94";
#else
__RCSID("$NetBSD: fnmatch.c,v 1.17 2000/01/22 22:19:10 mycroft Exp $");
__RCSID("$NetBSD: fnmatch.c,v 1.18 2000/06/28 01:13:36 thorpej Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
@ -53,6 +53,7 @@ __RCSID("$NetBSD: fnmatch.c,v 1.17 2000/01/22 22:19:10 mycroft Exp $");
#include "namespace.h"
#include <assert.h>
#include <ctype.h>
#include <fnmatch.h>
#include <string.h>
@ -64,6 +65,17 @@ __weak_alias(fnmatch,_fnmatch)
static const char *rangematch __P((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;
@ -76,7 +88,7 @@ fnmatch(pattern, string, flags)
_DIAGASSERT(string != NULL);
for (stringstart = string;;)
switch (c = *pattern++) {
switch (c = FOLDCASE(*pattern++, flags)) {
case EOS:
return (*string == EOS ? 0 : FNM_NOMATCH);
case '?':
@ -91,10 +103,10 @@ fnmatch(pattern, string, flags)
++string;
break;
case '*':
c = *pattern;
c = FOLDCASE(*pattern, flags);
/* Collapse multiple stars. */
while (c == '*')
c = *++pattern;
c = FOLDCASE(*++pattern, flags);
if (*string == '.' && (flags & FNM_PERIOD) &&
(string == stringstart ||
@ -115,8 +127,9 @@ fnmatch(pattern, string, flags)
}
/* General case, use recursion. */
while ((test = *string) != EOS) {
if (!fnmatch(pattern, string, flags & ~FNM_PERIOD))
while ((test = FOLDCASE(*string, flags)) != EOS) {
if (!fnmatch(pattern, string,
flags & ~FNM_PERIOD))
return (0);
if (test == '/' && flags & FNM_PATHNAME)
break;
@ -129,20 +142,21 @@ fnmatch(pattern, string, flags)
if (*string == '/' && flags & FNM_PATHNAME)
return (FNM_NOMATCH);
if ((pattern =
rangematch(pattern, *string, flags)) == NULL)
rangematch(pattern, FOLDCASE(*string, flags),
flags)) == NULL)
return (FNM_NOMATCH);
++string;
break;
case '\\':
if (!(flags & FNM_NOESCAPE)) {
if ((c = *pattern++) == EOS) {
if ((c = FOLDCASE(*pattern++, flags)) == EOS) {
c = '\\';
--pattern;
}
}
/* FALLTHROUGH */
default:
if (c != *string++)
if (c != FOLDCASE(*string++, flags))
return (FNM_NOMATCH);
break;
}
@ -169,16 +183,17 @@ rangematch(pattern, test, flags)
if ((negate = (*pattern == '!' || *pattern == '^')) != 0)
++pattern;
for (ok = 0; (c = *pattern++) != ']';) {
for (ok = 0; (c = FOLDCASE(*pattern++, flags)) != ']';) {
if (c == '\\' && !(flags & FNM_NOESCAPE))
c = *pattern++;
c = FOLDCASE(*pattern++, flags);
if (c == EOS)
return (NULL);
if (*pattern == '-'
&& (c2 = *(pattern+1)) != EOS && c2 != ']') {
&& (c2 = FOLDCASE(*(pattern+1), flags)) != EOS &&
c2 != ']') {
pattern += 2;
if (c2 == '\\' && !(flags & FNM_NOESCAPE))
c2 = *pattern++;
c2 = FOLDCASE(*pattern++, flags);
if (c2 == EOS)
return (NULL);
if (c <= test && test <= c2)