Module Name: src Committed By: roy Date: Mon Jan 20 14:05:52 UTC 2014
Modified Files: src/bin/sh: expand.c sh.1 Log Message: Add wctype(3) support to Shell Patterns. Obtained from FreeBSD. To generate a diff of this commit: cvs rdiff -u -r1.90 -r1.91 src/bin/sh/expand.c cvs rdiff -u -r1.111 -r1.112 src/bin/sh/sh.1 Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/bin/sh/expand.c diff -u src/bin/sh/expand.c:1.90 src/bin/sh/expand.c:1.91 --- src/bin/sh/expand.c:1.90 Sun Oct 6 21:05:50 2013 +++ src/bin/sh/expand.c Mon Jan 20 14:05:51 2014 @@ -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/1 #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, in 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 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] != ']') { Index: src/bin/sh/sh.1 diff -u src/bin/sh/sh.1:1.111 src/bin/sh/sh.1:1.112 --- src/bin/sh/sh.1:1.111 Wed Oct 2 20:42:56 2013 +++ src/bin/sh/sh.1 Mon Jan 20 14:05:51 2014 @@ -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