summaryrefslogtreecommitdiff
path: root/bin/ksh/misc.c
diff options
context:
space:
mode:
authorTodd C. Miller <millert@cvs.openbsd.org>2009-03-03 20:01:02 +0000
committerTodd C. Miller <millert@cvs.openbsd.org>2009-03-03 20:01:02 +0000
commit7e32d8837264f3c4f2103da7b0027e3dad040339 (patch)
tree0983193b780f264a45378129918c3fb7c1d28f2b /bin/ksh/misc.c
parent377d2887ff99ee8607be820565642c8b512fde48 (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.c53
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++;