mirror of
git://slackware.nl/current.git
synced 2025-02-16 09:34:21 +01:00
446 lines
8.9 KiB
Diff
446 lines
8.9 KiB
Diff
![]() |
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 <pwd.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <stdio.h>
|
||
|
+#if defined(__GLIBC__) && !defined(GLOB_BROKEN)
|
||
|
+#include <fnmatch.h>
|
||
|
+#include <glob.h>
|
||
|
+#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 *));
|
||
|
|