Add wctype(3) support to Shell Patterns.

Obtained from FreeBSD.
This commit is contained in:
roy 2014-01-20 14:05:51 +00:00
parent 07e9f21310
commit 7969ec4d55
2 changed files with 51 additions and 5 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: expand.c,v 1.90 2013/10/06 21:05:50 ast Exp $ */
/* $NetBSD: expand.c,v 1.91 2014/01/20 14:05:51 roy Exp $ */
/*-
* Copyright (c) 1991, 1993
@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)expand.c 8.5 (Berkeley) 5/15/95";
#else
__RCSID("$NetBSD: expand.c,v 1.90 2013/10/06 21:05:50 ast Exp $");
__RCSID("$NetBSD: expand.c,v 1.91 2014/01/20 14:05:51 roy Exp $");
#endif
#endif /* not lint */
@ -51,6 +51,7 @@ __RCSID("$NetBSD: expand.c,v 1.90 2013/10/06 21:05:50 ast Exp $");
#include <limits.h>
#include <stdlib.h>
#include <stdio.h>
#include <wctype.h>
/*
* Routines to expand arguments to commands. We have to deal with
@ -1365,6 +1366,37 @@ msort(struct strlist *list, int len)
}
/*
* See if a character matches a character class, starting at the first colon
* of "[:class:]".
* If a valid character class is recognized, a pointer to the next character
* after the final closing bracket is stored into *end, otherwise a null
* pointer is stored into *end.
*/
static int
match_charclass(char *p, wchar_t chr, char **end)
{
char name[20];
char *nameend;
wctype_t cclass;
*end = NULL;
p++;
nameend = strstr(p, ":]");
if (nameend == NULL || (size_t)(nameend - p) >= sizeof(name) ||
nameend == p)
return 0;
memcpy(name, p, nameend - p);
name[nameend - p] = '\0';
*end = nameend + 2;
cclass = wctype(name);
/* An unknown class matches nothing but is valid nevertheless. */
if (cclass == 0)
return 0;
return iswctype(chr, cclass);
}
/*
* Returns true if the pattern matches the string.
@ -1385,7 +1417,7 @@ patmatch(char *pattern, char *string, int squoted)
STATIC int
pmatch(char *pattern, char *string, int squoted)
{
char *p, *q;
char *p, *q, *end;
char c;
p = pattern;
@ -1465,6 +1497,11 @@ pmatch(char *pattern, char *string, int squoted)
do {
if (c == CTLQUOTEMARK)
continue;
if (c == '[' && *p == ':') {
found |= match_charclass(p, chr, &end);
if (end != NULL)
p = end;
}
if (c == CTLESC)
c = *p++;
if (*p == '-' && p[1] != ']') {

View File

@ -1,4 +1,4 @@
.\" $NetBSD: sh.1,v 1.111 2013/10/02 20:42:56 christos Exp $
.\" $NetBSD: sh.1,v 1.112 2014/01/20 14:05:51 roy Exp $
.\" Copyright (c) 1991, 1993
.\" The Regents of the University of California. All rights reserved.
.\"
@ -31,7 +31,7 @@
.\"
.\" @(#)sh.1 8.6 (Berkeley) 5/4/95
.\"
.Dd October 2, 2013
.Dd January 20, 2014
.Dt SH 1
.Os
.Sh NAME
@ -1157,6 +1157,15 @@ matches a
.Dq \&[
rather than introducing a character class.
A character class matches any of the characters between the square brackets.
A named class of characters (see
.Xr wctype 3 )
may be specified by surrounding the name with
.Pq Dq [:
and
.Pq Dq :] .
For example,
.Pq Dq [[:alpha:]]
is a shell pattern that matches a single letter.
A range of characters may be specified using a minus sign
.Pq Dq - .
The character class may be complemented