zsh-workers
 help / color / mirror / code / Atom feed
From: "Oliver Kiddle" <okiddle@yahoo.co.uk>
To: Bart Schaefer <schaefer@brasslantern.com>, zsh-workers@sunsite.dk
Subject: Re: Reverse the order of an array?
Date: Fri, 22 Feb 2002 09:20:37 +0000 (GMT)	[thread overview]
Message-ID: <20020222092037.3619.qmail@web9305.mail.yahoo.com> (raw)
In-Reply-To: <1020215171627.ZM24466@candle.brasslantern.com>

 --- Bart Schaefer <schaefer@brasslantern.com> wrote:

> There are already a number of inconsistencies between glob qualifiers
> and parameter flags in this regard.  Order matters in glob
> qualifiers;
> e.g. (n) by itself is numeric sorting (which we don't yet do in
> arrays),
> (no) is an error, and (on) means sort by name.  In parameter flags
> (i)
> by itself is meaningless, but both (io) and (oi) mean to sort case-
> independently (an option that we don't have in the glob qualifiers).
> 
> Also, directory order is not likely to have been carefully crafted by
> the user the way array ordering is.  The main use of pure directory
> order would be to avoid sorting when there are a large number of
> files.

I'll not worry about about directory order then. Is there any demand
for case insensitive glob sorting? (i) is free.

Seeing as you mentioned it I've added the numeric ordering. It'll save
you having to rescue (n) from being used for something else again (as
you did in 16350). This also means that `(oin)' should result in
case-insensitive numeric ordering.

Could someone better at C and perhaps more awake than me please take a
look at instrpcmp(). Is there a cleaner way I can get a pointer to a
pointer of the VARARRs to pass on to nstrpcmp()? I can avoid the cast
with `char (*e)[] = &c;' but the SGI compiler prints a warning for
that. I was hoping to avoid the e and f variables.

I've swiped notstrcmp() out of glob.c for this so the patch is longer
than it really is. I hope nobody minds about that function's move and
rename? Patch includes documentation for this and the new (a) flag.

Oliver

--- Src/subst.c.before	Wed Feb 20 19:34:54 2002
+++ Src/subst.c	Thu Feb 21 23:44:14 2002
@@ -540,6 +540,72 @@
 }
 
 /**/
+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 @@
     Value v = NULL;
     int flags = 0;
     int flnum = 0;
-    int sortit = 0, casind = 0, indord = 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,9 @@
 		case 'i':
 		    casind = 1;
 		    break;
+		case 'n':
+		    numord = 1;
+		    break;
 		case 'a':
 		    indord = 1;
 		    break;
@@ -1021,7 +1090,7 @@
 	}
     }
     if (sortit)
-	sortit += (casind << 1);
+	sortit += (casind << 1) + (numord << 2);
 
     if (!premul)
 	premul = " ";
@@ -1913,7 +1982,8 @@
 		}
 	    } else {
 		static CompareFn sortfn[] = {
-		    strpcmp, invstrpcmp, cstrpcmp, invcstrpcmp
+		    strpcmp, invstrpcmp, cstrpcmp, invcstrpcmp,
+		    nstrpcmp, invnstrpcmp, instrpcmp, invinstrpcmp
 		};
 
 		i = arrlen(aval);
--- Src/glob.c.before	Thu Feb 21 23:25:39 2002
+++ Src/glob.c	Thu Feb 21 23:44:14 2002
@@ -854,7 +854,10 @@
     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:
 	    {
@@ -1609,46 +1612,6 @@
     free(matchbuf);
 
     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 */
--- Doc/Zsh/expn.yo.before      Thu Feb 21 23:44:08 2002
+++ Doc/Zsh/expn.yo     Thu Feb 21 23:44:14 2002
@@ -620,6 +620,11 @@
 example by using `tt(${(AA)=)var(name)tt(=)...tt(})' to activate
 field splitting, when creating an associative array.
 )
+item(tt(a))(
+With tt(o) or tt(O), sort in array index order. Note that `tt(oa)' is
+therefore equivalent to the default but `tt(Oa)' is useful for
+obtaining an array's elements in reverse order.
+)
 item(tt(c))(
 With tt(${#)var(name)tt(}), count the total number of characters in an
array,
 as if the elements were concatenated with spaces between them.
@@ -660,6 +665,9 @@
 )
 item(tt(O))(
 Sort the resulting words in descending order.
+)
+item(tt(n))(
+With tt(o) or tt(O), sort numerically.
 )
 item(tt(P))(
 This forces the value of the parameter var(name) to be interpreted as
a


__________________________________________________
Do You Yahoo!?
Everything you'll ever need on one web page
from News and Sport to Email and Music Charts
http://uk.my.yahoo.com


  reply	other threads:[~2002-02-22  9:20 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <Pine.BSF.4.40.0202082359000.90676-100000@brasslantern.com>
     [not found] ` <20020211132620.27729.qmail@web9302.mail.yahoo.com>
2002-02-12 13:15   ` Derek Peschel
2002-02-13 16:36     ` Oliver Kiddle
2002-02-15 17:16       ` Bart Schaefer
2002-02-22  9:20         ` Oliver Kiddle [this message]
2002-02-25 17:54           ` Bart Schaefer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20020222092037.3619.qmail@web9305.mail.yahoo.com \
    --to=okiddle@yahoo.co.uk \
    --cc=schaefer@brasslantern.com \
    --cc=zsh-workers@sunsite.dk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).