diff -urN netbsd-sh/expand.c ash-0.3.7.orig/expand.c --- netbsd-sh/expand.c Tue Mar 14 13:03:45 2000 +++ ash-0.3.7.orig/expand.c Mon Apr 23 22:16:46 2001 @@ -54,6 +54,10 @@ #include #include #include +#if defined(__GLIBC__) && !defined(GLOB_BROKEN) +#include +#include +#endif /* * Routines to expand arguments to commands. We have to deal with @@ -102,17 +106,30 @@ STATIC int subevalvar __P((char *, char *, int, int, int, int)); STATIC char *evalvar __P((char *, int)); STATIC int varisset __P((char *, int)); +STATIC char *strtodest __P((char *, int, int)); STATIC void varvalue __P((char *, int, int)); STATIC void recordregion __P((int, int, int)); STATIC void removerecordregions __P((int)); STATIC void ifsbreakup __P((char *, struct arglist *)); STATIC void ifsfree __P((void)); STATIC void expandmeta __P((struct strlist *, int)); +#if defined(__GLIBC__) && !defined(GLOB_BROKEN) +STATIC const char *preglob __P((const char *)); +STATIC void addglob __P((const glob_t *)); +#else STATIC void expmeta __P((char *, char *)); +#endif STATIC void addfname __P((char *)); +#if defined(__GLIBC__) && !defined(GLOB_BROKEN) +STATIC int patmatch __P((char *, char *, int)); +STATIC int patmatch2 __P((char *, char *, int)); +STATIC char * _rmescapes __P((char *, int)); +#else STATIC struct strlist *expsort __P((struct strlist *)); STATIC struct strlist *msort __P((struct strlist *, int)); STATIC int pmatch __P((char *, char *, int)); +#define patmatch2 patmatch +#endif STATIC char *cvtnum __P((int, char *)); /* @@ -371,7 +388,7 @@ * have to rescan starting from the beginning since CTLESC * characters have to be processed left to right. */ - CHECKSTRSPACE(8, expdest); + CHECKSTRSPACE(10, expdest); USTPUTC('\0', expdest); start = stackblock(); p = expdest - 1; @@ -393,7 +410,7 @@ if (quotes) rmescapes(p+2); result = arith(p+2); - fmtstr(p, 10, "%d", result); + fmtstr(p, 12, "%d", result); while (*p++) ; @@ -503,7 +520,7 @@ int amount; herefd = -1; - argstr(p, 0); + argstr(p, subtype != VSASSIGN && subtype != VSQUESTION ? EXP_CASE : 0); STACKSTRNUL(expdest); herefd = saveherefd; argbackq = saveargbackq; @@ -535,7 +552,7 @@ for (loc = startp; loc < str; loc++) { c = *loc; *loc = '\0'; - if (patmatch(str, startp, varflags & VSQUOTE)) + if (patmatch2(str, startp, varflags & VSQUOTE)) goto recordleft; *loc = c; if ((varflags & VSQUOTE) && *loc == CTLESC) @@ -547,7 +564,7 @@ for (loc = str - 1; loc >= startp;) { c = *loc; *loc = '\0'; - if (patmatch(str, startp, varflags & VSQUOTE)) + if (patmatch2(str, startp, varflags & VSQUOTE)) goto recordleft; *loc = c; loc--; @@ -564,7 +581,7 @@ case VSTRIMRIGHT: for (loc = str - 1; loc >= startp;) { - if (patmatch(str, loc, varflags & VSQUOTE)) + if (patmatch2(str, loc, varflags & VSQUOTE)) goto recordright; loc--; if ((varflags & VSQUOTE) && loc > startp && @@ -580,7 +597,7 @@ case VSTRIMRIGHTMAX: for (loc = startp; loc < str - 1; loc++) { - if (patmatch(str, loc, varflags & VSQUOTE)) + if (patmatch2(str, loc, varflags & VSQUOTE)) goto recordright; if ((varflags & VSQUOTE) && *loc == CTLESC) loc++; @@ -819,6 +836,34 @@ /* + * Put a string on the stack. + */ + +STATIC char * +strtodest(p, quoted, allow_split) + char *p; + int quoted; + int allow_split; +{ + char const *syntax; + + if (allow_split) { + syntax = quoted ? DQSYNTAX : BASESYNTAX; + while (*p) { + if (syntax[(int) *p] == CCTL) + STPUTC(CTLESC, expdest); + STPUTC(*p++, expdest); + } + } else + while (*p) + STPUTC(*p++, expdest); + + return p; +} + + + +/* * Add the value of a specialized variable to the stack string. */ @@ -834,22 +879,6 @@ extern int oexitstatus; char sep; char **ap; - char const *syntax; - -#define STRTODEST(p) \ - do {\ - if (allow_split) { \ - syntax = quoted? DQSYNTAX : BASESYNTAX; \ - while (*p) { \ - if (syntax[(int)*p] == CCTL) \ - STPUTC(CTLESC, expdest); \ - STPUTC(*p++, expdest); \ - } \ - } else \ - while (*p) \ - STPUTC(*p++, expdest); \ - } while (0) - switch (*name) { case '$': @@ -875,7 +904,7 @@ case '@': if (allow_split && quoted) { for (ap = shellparam.p ; (p = *ap++) != NULL ; ) { - STRTODEST(p); + p = strtodest(p, quoted, allow_split); if (*ap) STPUTC('\0', expdest); } @@ -888,21 +917,20 @@ else sep = ' '; for (ap = shellparam.p ; (p = *ap++) != NULL ; ) { - STRTODEST(p); + p = strtodest(p, quoted, allow_split); if (*ap && sep) STPUTC(sep, expdest); } break; case '0': - p = arg0; - STRTODEST(p); + p = strtodest(arg0, quoted, allow_split); break; default: if (is_digit(*name)) { num = atoi(name); if (num > 0 && num <= shellparam.nparam) { - p = shellparam.p[num - 1]; - STRTODEST(p); + p = strtodest(shellparam.p[num - 1], quoted, + allow_split); } } break; @@ -1054,6 +1082,98 @@ * should be escapes. The results are stored in the list exparg. */ +#if defined(__GLIBC__) && !defined(GLOB_BROKEN) +STATIC void +expandmeta(str, flag) + struct strlist *str; + int flag; +{ + const char *p; + glob_t pglob; + /* TODO - EXP_REDIR */ + + while (str) { + if (fflag) + goto nometa; + p = preglob(str->text); + INTOFF; + switch (glob(p, GLOB_NOMAGIC, 0, &pglob)) { + case 0: + if (!(pglob.gl_flags & GLOB_MAGCHAR)) + goto nometa2; + addglob(&pglob); + globfree(&pglob); + INTON; + break; + case GLOB_NOMATCH: +nometa2: + globfree(&pglob); + INTON; +nometa: + *exparg.lastp = str; + rmescapes(str->text); + exparg.lastp = &str->next; + break; + default: /* GLOB_NOSPACE */ + error("Out of space"); + } + str = str->next; + } +} + + +/* + * Prepare the string for glob(3). + */ + +STATIC const char * +preglob(str) + const char *str; +{ + const char *p; + char *q, *r; + size_t len; + + p = str; + while (*p != CTLQUOTEMARK && *p != CTLESC) { + if (*p++ == '\0') + return str; + } + len = p - str; + q = r = stalloc(strlen(str) + 1); + if (len > 0) { + memcpy(q, str, len); + q += len; + } + do { + if (*p == CTLQUOTEMARK) + continue; + if (*p == CTLESC) { + if (*++p != '/') + *q++ = '\\'; + } + *q++ = *p; + } while (*++p); + *q = '\0'; + return r; +} + + +/* + * Add the result of glob(3) to the list. + */ + +STATIC void +addglob(pglob) + const glob_t *pglob; +{ + char **p = pglob->gl_pathv; + + do { + addfname(*p); + } while (*++p); +} +#else char *expdir; @@ -1238,6 +1358,7 @@ if (! atend) endname[-1] = '/'; } +#endif /* @@ -1260,6 +1381,7 @@ } +#if !(defined(__GLIBC__) && !defined(GLOB_BROKEN)) /* * Sort the results of file name expansion. It calculates the number of * strings to sort and then calls msort (short for merge sort) to do the @@ -1321,6 +1443,7 @@ } return list; } +#endif @@ -1328,6 +1451,39 @@ * Returns true if the pattern matches the string. */ +#if defined(__GLIBC__) && !defined(GLOB_BROKEN) +STATIC int +patmatch(pattern, string, squoted) + char *pattern; + char *string; + int squoted; /* string might have quote chars */ + { + const char *p; + char *q; + + p = preglob(pattern); + q = squoted ? _rmescapes(string, 1) : string; + + return !fnmatch(p, q, 0); +} + + +STATIC int +patmatch2(pattern, string, squoted) + char *pattern; + char *string; + int squoted; /* string might have quote chars */ + { + char *p; + int res; + + sstrnleft--; + p = grabstackstr(expdest); + res = patmatch(pattern, string, squoted); + ungrabstackstr(p, expdest); + return res; +} +#else int patmatch(pattern, string, squoted) char *pattern; @@ -1462,6 +1618,7 @@ return 0; return 1; } +#endif @@ -1469,6 +1626,50 @@ * Remove any CTLESC characters from a string. */ +#if defined(__GLIBC__) && !defined(GLOB_BROKEN) +void +rmescapes(str) + char *str; +{ + _rmescapes(str, 0); +} + + +STATIC char * +_rmescapes(str, flag) + char *str; + int flag; +{ + char *p, *q, *r; + + p = str; + while (*p != CTLESC && *p != CTLQUOTEMARK) { + if (*p++ == '\0') + return str; + } + q = p; + r = str; + if (flag) { + size_t len = p - str; + q = r = stalloc(strlen(p) + len + 1); + if (len > 0) { + memcpy(q, str, len); + q += len; + } + } + while (*p) { + if (*p == CTLQUOTEMARK) { + p++; + continue; + } + if (*p == CTLESC) + p++; + *q++ = *p++; + } + *q = '\0'; + return r; +} +#else void rmescapes(str) char *str; @@ -1492,6 +1693,7 @@ } *q = '\0'; } +#endif diff -urN netbsd-sh/expand.h ash-0.3.7.orig/expand.h --- netbsd-sh/expand.h Fri Jul 9 13:02:06 1999 +++ ash-0.3.7.orig/expand.h Mon Apr 23 22:16:46 2001 @@ -64,7 +64,9 @@ void expandhere __P((union node *, int)); void expandarg __P((union node *, struct arglist *, int)); void expari __P((int)); +#if !(defined(__GLIBC__) && !defined(GLOB_BROKEN)) int patmatch __P((char *, char *, int)); +#endif void rmescapes __P((char *)); int casematch __P((union node *, char *));