/* The argp from which this option came. */
const struct argp *argp;
+
+ /* Position in the array */
+ unsigned ord;
};
/* A cluster of entries to reflect the argp tree structure. */
}
\f
/* Iterator that returns true for the first short option. */
-static inline int
+static int
until_short (const struct argp_option *opt, const struct argp_option *real,
const char *domain, void *cookie)
{
hol_cluster_cmp (const struct hol_cluster *cl1, const struct hol_cluster *cl2)
{
/* If one cluster is deeper than the other, use its ancestor at the same
- level, so that finding the common ancestor is straightforward. */
- while (cl1->depth < cl2->depth)
+ level, so that finding the common ancestor is straightforward.
+
+ clN->depth > 0 means that clN->parent != NULL (see hol_add_cluster) */
+ while (cl1->depth > cl2->depth)
cl1 = cl1->parent;
- while (cl2->depth < cl1->depth)
+ while (cl2->depth > cl1->depth)
cl2 = cl2->parent;
/* Now reduce both clusters to their ancestors at the point where both have
return non_opt;
}
+#define HOL_ENTRY_PTRCMP(a,b) ((a)->ord < (b)->ord ? -1 : 1)
+
/* Order ENTRY1 & ENTRY2 by the order which they should appear in a help
listing. */
static int
/* 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)
{
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
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
#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. */
hol_sort (struct hol *hol)
{
if (hol->num_entries > 0)
- qsort (hol->entries, hol->num_entries, sizeof (struct hol_entry),
- hol_entry_qcmp);
+ {
+ unsigned i;
+ struct hol_entry *e;
+ for (i = 0, e = hol->entries; i < hol->num_entries; i++, e++)
+ e->ord = i;
+ qsort (hol->entries, hol->num_entries, sizeof (struct hol_entry),
+ hol_entry_qcmp);
+ }
}
\f
/* Append MORE to HOL, destroying MORE in the process. Options in HOL shadow