From 73a4362713b8fb624ec70a5d86d4e5d87fba2b7b Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Fri, 22 Feb 2002 17:28:04 +0000 Subject: 16620, 16697: add a and n parameter expansion flags --- Src/subst.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 96 insertions(+), 10 deletions(-) (limited to 'Src/subst.c') diff --git a/Src/subst.c b/Src/subst.c index 607e9b979..7a0a8b16b 100644 --- a/Src/subst.c +++ b/Src/subst.c @@ -539,6 +539,72 @@ invcstrpcmp(const void *a, const void *b) #endif } +/**/ +int +nstrpcmp(const void *a, const void *b) +{ + char *c = *(char **)a, *d = *(char **)b; + int cmp; + +#ifdef HAVE_STRCOLL + cmp = strcoll(c, d); +#endif + for (; *c == *d && *c; c++, d++); +#ifndef HAVE_STRCOLL + cmp = (int)STOUC(*c) - (int)STOUC(*d); +#endif + if (idigit(*c) || idigit(*d)) { + for (; c > *(char **)b && idigit(c[-1]); c--, d--); + if (idigit(*c) && idigit(*d)) { + while (*c == '0') + c++; + while (*d == '0') + d++; + for (; idigit(*c) && *c == *d; c++, d++); + if (idigit(*c) || idigit(*d)) { + cmp = (int)STOUC(*c) - (int)STOUC(*d); + while (idigit(*c) && idigit(*d)) + c++, d++; + if (idigit(*c) && !idigit(*d)) + return 1; + if (idigit(*d) && !idigit(*c)) + return -1; + } + } + } + return cmp; +} + +/**/ +int +invnstrpcmp(const void *a, const void *b) +{ + return -nstrpcmp(a, b); +} + +/**/ +int +instrpcmp(const void *a, const void *b) +{ + VARARR(char, c, strlen(*(char **) a) + 1); + VARARR(char, d, strlen(*(char **) b) + 1); + char **e = (char **)&c; + char **f = (char **)&d; + char *s, *t; + + for (s = *(char **) a, t = c; (*t++ = tulower(*s++));); + for (s = *(char **) b, t = d; (*t++ = tulower(*s++));); + + return nstrpcmp(&e, &f); +} + +/**/ +int +invinstrpcmp(const void *a, const void *b) +{ + return -instrpcmp(a, b); +} + /**/ static char * dopadding(char *str, int prenum, int postnum, char *preone, char *postone, char *premul, char *postmul) @@ -773,7 +839,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub) Value v = NULL; int flags = 0; int flnum = 0; - int sortit = 0, casind = 0; + int sortit = 0, casind = 0, numord = 0, indord = 0; int unique = 0; int casmod = 0; int quotemod = 0, quotetype = 0, quoteerr = 0; @@ -881,6 +947,12 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub) case 'i': casind = 1; break; + case 'n': + numord = 1; + break; + case 'a': + indord = 1; + break; case 'V': visiblemod++; @@ -1018,7 +1090,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub) } } if (sortit) - sortit += (casind << 1); + sortit += (casind << 1) + (numord << 2); if (!premul) premul = " "; @@ -1894,16 +1966,30 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub) zhuniqarray(aval); } if (sortit) { - static CompareFn sortfn[] = { - strpcmp, invstrpcmp, cstrpcmp, invcstrpcmp - }; - if (!copied) aval = arrdup(aval); - - i = arrlen(aval); - if (i && (*aval[i-1] || --i)) - qsort(aval, i, sizeof(char *), sortfn[sortit-1]); + if (indord) { + if (sortit & 2) { + char *copy; + char **end = aval + arrlen(aval) - 1, **start = aval; + + /* reverse the array */ + while (start < end) { + copy = *end; + *end-- = *start; + *start++ = copy; + } + } + } else { + static CompareFn sortfn[] = { + strpcmp, invstrpcmp, cstrpcmp, invcstrpcmp, + nstrpcmp, invnstrpcmp, instrpcmp, invinstrpcmp + }; + + i = arrlen(aval); + if (i && (*aval[i-1] || --i)) + qsort(aval, i, sizeof(char *), sortfn[sortit-1]); + } } if (plan9) { LinkNode tn; -- cgit 1.4.1