bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: recent argp changes


From: Sergey Poznyakoff
Subject: Re: recent argp changes
Date: Mon, 30 Apr 2007 11:43:57 +0300

Hello,

The option sorting in argp-help was based on the stability
of sort algorithm, therefore the test failed on systems with
quicksort qsort implementations.  It went unnoticed on glibc,
because its qsort uses adaptive algorithm, defaulting to
insertion sort if the number of partitions is smaller than a
predefined value, which happens to be true for the argp tests.

I have installed the following changes.

2007-04-30  Sergey Poznyakoff  <address@hidden>

        * lib/argp-help.c (hol_entry_cmp): Option sorting algorithm
        assumes the sorting is stable, while most qsort
        implementations are not.  Use argument addresses to ensure they
        never compare as equal.  

        * tests/test-argp-2.sh (usage-indent test): Fix output
        (func_compare): Restore diff options
        * tests/test-argp.c: Restore #include "progname.h"
                                
Index: lib/argp-help.c
===================================================================
RCS file: /cvsroot/gnulib/gnulib/lib/argp-help.c,v
retrieving revision 1.27
retrieving revision 1.28
diff -p -u -r1.27 -r1.28
--- lib/argp-help.c     29 Apr 2007 12:02:27 -0000      1.27
+++ lib/argp-help.c     30 Apr 2007 08:25:46 -0000      1.28
@@ -733,6 +733,8 @@ canon_doc_option (const char **name)
   return non_opt;
 }
 
+#define HOL_ENTRY_PTRCMP(a,b) ((a) < (b) ? -1 : 1)
+
 /* Order ENTRY1 & ENTRY2 by the order which they should appear in a help
    listing.  */
 static int
@@ -742,6 +744,7 @@ hol_entry_cmp (const struct hol_entry *e
   /* The group numbers by which the entries should be ordered; if either is
      in a cluster, then this is just the group within the cluster.  */
   int group1 = entry1->group, group2 = entry2->group;
+  int rc;
 
   if (entry1->cluster != entry2->cluster)
     {
@@ -758,7 +761,8 @@ hol_entry_cmp (const struct hol_entry *e
        return group_cmp (hol_cluster_base (entry1->cluster)->group, group2, 1);
       else
        /* Both entries are in clusters, we can just compare the clusters.  */
-       return hol_cluster_cmp (entry1->cluster, entry2->cluster);
+       return (rc = hol_cluster_cmp (entry1->cluster, entry2->cluster)) ?
+               rc : HOL_ENTRY_PTRCMP(entry1, entry2);
     }
   else if (group1 == group2)
     /* The entries are both in the same cluster and group, so compare them
@@ -782,7 +786,8 @@ hol_entry_cmp (const struct hol_entry *e
        return doc1 - doc2;
       else if (!short1 && !short2 && long1 && long2)
        /* Only long options.  */
-       return __strcasecmp (long1, long2);
+       return (rc = __strcasecmp (long1, long2)) ?
+                 rc : HOL_ENTRY_PTRCMP(entry1, entry2);
       else
        /* Compare short/short, long/short, short/long, using the first
           character of long options.  Entries without *any* valid
@@ -799,13 +804,15 @@ hol_entry_cmp (const struct hol_entry *e
 #endif
          /* Compare ignoring case, except when the options are both the
             same letter, in which case lower-case always comes first.  */
-         return lower_cmp ? lower_cmp : first2 - first1;
+         return lower_cmp ? lower_cmp : 
+                    (rc = first2 - first1) ?
+                    rc : HOL_ENTRY_PTRCMP(entry1, entry2);
        }
     }
   else
     /* Within the same cluster, but not the same group, so just compare
        groups.  */
-    return group_cmp (group1, group2, 0);
+    return group_cmp (group1, group2, HOL_ENTRY_PTRCMP(entry1, entry2));
 }
 
 /* Version of hol_entry_cmp with correct signature for qsort.  */
Index: tests/test-argp.c
===================================================================
RCS file: /cvsroot/gnulib/gnulib/tests/test-argp.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -p -u -r1.3 -r1.4
--- tests/test-argp.c   29 Apr 2007 12:02:45 -0000      1.3
+++ tests/test-argp.c   30 Apr 2007 08:26:26 -0000      1.4
@@ -30,6 +30,7 @@
 #if HAVE_STRINGS_H
 # include <strings.h>
 #endif
+#include "progname.h"
 
 struct test_args
 {
Index: tests/test-argp-2.sh
===================================================================
RCS file: /cvsroot/gnulib/gnulib/tests/test-argp-2.sh,v
retrieving revision 1.4
retrieving revision 1.5
diff -p -u -r1.4 -r1.5
--- tests/test-argp-2.sh        29 Apr 2007 12:04:15 -0000      1.4
+++ tests/test-argp-2.sh        30 Apr 2007 08:26:11 -0000      1.5
@@ -26,7 +26,7 @@ func_compare() {
 # If argp was compiled without base_name, it will display full program name
   sed '1{
          s,: [^ ]*/test-argp,: test-argp,
-        }' | diff -pu $TMP -
+        }' | diff -c $TMP -
 }  
 
 ####
@@ -44,9 +44,9 @@ EOT
 # Test working usage-indent format
 
 cat > $TMP <<EOT
-Usage: test-argp [-tvO?V] [-f FILE] [-o[ARG]] [--test] [--file=FILE]
-[--input=FILE] [--verbose] [--option] [--optional[=ARG]] [--help] [--usage]
-[--version] ARGS...
+Usage: test-argp [-tvCSOlp?V] [-f FILE] [-o[ARG]] [--test] [--file=FILE]
+[--input=FILE] [--verbose] [--cantiga] [--sonet] [--option] [--optional[=ARG]]
+[--limerick] [--poem] [--help] [--usage] [--version] ARGS...
 EOT
 
 ARGP_HELP_FMT='usage-indent=0' ./test-argp --usage | func_compare || ERR=1


Regards,
Sergey
 




reply via email to

[Prev in Thread] Current Thread [Next in Thread]