diff options
author | Todd C. Miller <millert@cvs.openbsd.org> | 2009-03-03 20:01:02 +0000 |
---|---|---|
committer | Todd C. Miller <millert@cvs.openbsd.org> | 2009-03-03 20:01:02 +0000 |
commit | 7e32d8837264f3c4f2103da7b0027e3dad040339 (patch) | |
tree | 0983193b780f264a45378129918c3fb7c1d28f2b /bin/ksh/misc.c | |
parent | 377d2887ff99ee8607be820565642c8b512fde48 (diff) |
Add POSIX character class support ([:alpha:] and friends) to ksh globbing.
OK deraadt@ krw@ jmc@ sobrado@
Diffstat (limited to 'bin/ksh/misc.c')
-rw-r--r-- | bin/ksh/misc.c | 53 |
1 files changed, 50 insertions, 3 deletions
diff --git a/bin/ksh/misc.c b/bin/ksh/misc.c index 874a88e89ff..76b0cec98df 100644 --- a/bin/ksh/misc.c +++ b/bin/ksh/misc.c @@ -1,12 +1,13 @@ -/* $OpenBSD: misc.c,v 1.35 2009/01/17 22:06:44 millert Exp $ */ +/* $OpenBSD: misc.c,v 1.36 2009/03/03 20:01:01 millert Exp $ */ /* * Miscellaneous functions */ #include "sh.h" -#include <ctype.h> /* ??? Removing this changes generated code! */ +#include <ctype.h> #include <sys/param.h> /* for MAXPATHLEN */ +#include "charclass.h" short ctypes [UCHAR_MAX+1]; /* type bits for unsigned char */ @@ -703,15 +704,61 @@ do_gmatch(const unsigned char *s, const unsigned char *se, return s == se; } +static int +posix_cclass(const unsigned char *pattern, int test, const unsigned char **ep) +{ + struct cclass *cc; + const unsigned char *colon; + size_t len; + int rval = 0; + + if ((colon = strchr(pattern, ':')) == NULL || colon[1] != MAGIC) { + *ep = pattern - 2; + return -1; + } + *ep = colon + 3; /* skip MAGIC */ + len = (size_t)(colon - pattern); + + for (cc = cclasses; cc->name != NULL; cc++) { + if (!strncmp(pattern, cc->name, len) && cc->name[len] == '\0') { + if (cc->isctype(test)) + rval = 1; + break; + } + } + if (cc->name == NULL) { + rval = -2; /* invalid character class */ + } + return rval; +} + static const unsigned char * cclass(const unsigned char *p, int sub) { - int c, d, not, found = 0; + int c, d, rv, not, found = 0; const unsigned char *orig_p = p; if ((not = (ISMAGIC(*p) && *++p == NOT))) p++; do { + /* check for POSIX character class (e.g. [[:alpha:]]) */ + if ((p[0] == MAGIC && p[1] == '[' && p[2] == ':') || + (p[0] == '[' && p[1] == ':')) { + do { + const char *pp = p + (*p == MAGIC) + 2; + rv = posix_cclass(pp, sub, &p); + switch (rv) { + case 1: + found = 1; + break; + case -2: + return NULL; + } + } while (rv != -1 && p[0] == MAGIC && p[1] == '[' && p[2] == ':'); + if (p[0] == MAGIC && p[1] == ']') + break; + } + c = *p++; if (ISMAGIC(c)) { c = *p++; |