diff options
author | Oliver Kiddle <opk@users.sourceforge.net> | 2002-02-22 17:28:04 +0000 |
---|---|---|
committer | Oliver Kiddle <opk@users.sourceforge.net> | 2002-02-22 17:28:04 +0000 |
commit | 73a4362713b8fb624ec70a5d86d4e5d87fba2b7b (patch) | |
tree | de3a8e80a0823da8c1ce6313f0f5ba674184ff4f /Src | |
parent | e3b5e1356c601cf894b06311814060b66cb30f78 (diff) | |
download | zsh-73a4362713b8fb624ec70a5d86d4e5d87fba2b7b.tar.gz zsh-73a4362713b8fb624ec70a5d86d4e5d87fba2b7b.tar.xz zsh-73a4362713b8fb624ec70a5d86d4e5d87fba2b7b.zip |
16620, 16697: add a and n parameter expansion flags
Diffstat (limited to 'Src')
-rw-r--r-- | Src/glob.c | 45 | ||||
-rw-r--r-- | Src/subst.c | 106 |
2 files changed, 100 insertions, 51 deletions
diff --git a/Src/glob.c b/Src/glob.c index aa82b91c1..75509fee5 100644 --- a/Src/glob.c +++ b/Src/glob.c @@ -854,7 +854,10 @@ gmatchcmp(Gmatch a, Gmatch b) for (i = gf_nsorts, s = gf_sortlist; i; i--, s++) { switch (*s & ~GS_DESC) { case GS_NAME: - r = notstrcmp(&a->name, &b->name); + if (gf_numsort) + r = nstrpcmp(&b->name, &a->name); + else + r = strpcmp(&b->name, &a->name); break; case GS_DEPTH: { @@ -1611,46 +1614,6 @@ zglob(LinkList list, LinkNode np, int nountok) restore_globstate(saved); } -/* Return the order of two strings, taking into account * - * possible numeric order if NUMERICGLOBSORT is set. * - * The comparison here is reversed. */ - -/**/ -static int -notstrcmp(char **a, char **b) -{ - char *c = *b, *d = *a; - 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 (gf_numsort && (idigit(*c) || idigit(*d))) { - for (; c > *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; -} - /* Return the trailing character for marking file types */ /**/ diff --git a/Src/subst.c b/Src/subst.c index 607e9b979..7a0a8b16b 100644 --- a/Src/subst.c +++ b/Src/subst.c @@ -540,6 +540,72 @@ invcstrpcmp(const void *a, const void *b) } /**/ +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; |