Date: Tue, 2 Oct 2007 13:30:55 GMT From: Roy Marples <uberlord@gentoo.org> To: freebsd-gnats-submit@FreeBSD.org Subject: standards/116826: [PATCH] sh support for POSIX character classes Message-ID: <200710021330.l92DUt2Y001701@www.freebsd.org> Resent-Message-ID: <200710021340.l92De3hE061456@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 116826 >Category: standards >Synopsis: [PATCH] sh support for POSIX character classes >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-standards >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Tue Oct 02 13:40:03 GMT 2007 >Closed-Date: >Last-Modified: >Originator: Roy Marples >Release: FreeBSD-6.2 >Organization: Gentoo >Environment: FreeBSD uberlaptop 6.2-RELEASE FreeBSD Gentoo 6.2-r3 #0: Thu Sep 13 17:44:37 BST 2007 root@uberlaptop:/usr/src/sys-6.2-r3/i386/compile/UBERKERNEL i386 >Description: sh does not support POSIX character classes http://www.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_13 http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap09.html#tag_09_03_05 >How-To-Repeat: $ sh -c 'case foo in [[:alpha:]]*) echo "alpha";; *) echo "not alpha";; esac' not alpha I would expect it to echo alpha. >Fix: Patch attached with submission follows: diff -u a/sh/expand.c b/sh/expand.c --- a/sh/expand.c 2005-11-06 20:39:47 +0000 +++ b/sh/expand.c 2007-10-02 13:46:28 +0100 @@ -1320,6 +1320,42 @@ } +STATIC int ccmatch(char *p, int chr, char **r) +{ + static const struct class { + char name[10]; + int (*fn)(int); + } classes[] = { + { .name = ":alnum:]", .fn = isalnum }, + { .name = ":cntrl:]", .fn = iscntrl }, + { .name = ":lower:]", .fn = islower }, + { .name = ":space:]", .fn = isspace }, + { .name = ":alpha:]", .fn = isalpha }, + { .name = ":digit:]", .fn = isdigit }, + { .name = ":print:]", .fn = isprint }, + { .name = ":upper:]", .fn = isupper }, + { .name = ":blank:]", .fn = isblank }, + { .name = ":graph:]", .fn = isgraph }, + { .name = ":punct:]", .fn = ispunct }, + { .name = ":xdigit:]", .fn = isxdigit }, + }; + const struct class *class, *end; + char *q; + + end = classes + sizeof(classes) / sizeof(classes[0]); + for (class = classes; class < end; class++) { + q = prefix(class->name, p); + if (!q) + continue; + *r = q; + return class->fn(chr); + } + + *r = 0; + return 0; +} + + STATIC int pmatch(char *pattern, char *string, int squoted) { @@ -1405,6 +1441,15 @@ continue; if (c == CTLESC) c = *p++; + else if (c == '[') { + char *r; + + found |= ccmatch(p, chr, &r); + if (r) { + p = r; + continue; + } + } if (*p == '-' && p[1] != ']') { p++; while (*p == CTLQUOTEMARK) diff -u a/sh/mystring.c b/sh/mystring.c --- a/sh/mystring.c 2004-04-06 21:06:51 +0100 +++ b/sh/mystring.c 2007-10-02 13:45:31 +0100 @@ -88,14 +88,14 @@ * prefix -- see if pfx is a prefix of string. */ -int +char * prefix(const char *pfx, const char *string) { while (*pfx) { if (*pfx++ != *string++) return 0; } - return 1; + return (char *)string; } diff -u a/sh/mystring.h b/sh/mystring.h --- a/sh/mystring.h 2004-04-06 21:06:51 +0100 +++ b/sh/mystring.h 2007-10-02 13:45:35 +0100 @@ -36,7 +36,7 @@ #include <string.h> void scopyn(const char *, char *, int); -int prefix(const char *, const char *); +char *prefix(const char *, const char *); int number(const char *); int is_number(const char *); >Release-Note: >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200710021330.l92DUt2Y001701>