X-Git-Url: https://erislabs.net/gitweb/?a=blobdiff_plain;ds=sidebyside;f=lib%2Fargp-help.c;h=150a0ad28f37e681c739653eb2e32e61676d3f5e;hb=298d8b4a29e66da0b046b64b822f97d1c8fef74b;hp=8f5c73adc5fca6beba918ea97c3f316d29b6eafb;hpb=1beff1e41eb41ce276d25d5eba9f5b46f201b7c3;p=gnulib.git diff --git a/lib/argp-help.c b/lib/argp-help.c index 8f5c73adc..150a0ad28 100644 --- a/lib/argp-help.c +++ b/lib/argp-help.c @@ -1,21 +1,20 @@ /* Hierarchial argument parsing help output - Copyright (C) 1995-2003, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 1995-2005, 2007, 2009 Free Software Foundation, Inc. This file is part of the GNU C Library. Written by Miles Bader . - This program is free software; you can redistribute it and/or modify + This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ #ifndef _GNU_SOURCE # define _GNU_SOURCE 1 @@ -89,11 +88,11 @@ struct uparams int dup_args_note; /* Various output columns. */ - int short_opt_col; /* column in which short options start */ - int long_opt_col; /* column in which long options start */ + int short_opt_col; /* column in which short options start */ + int long_opt_col; /* column in which long options start */ int doc_opt_col; /* column in which doc options start */ int opt_doc_col; /* column in which option text starts */ - int header_col; /* column in which group headers are printed */ + int header_col; /* column in which group headers are printed */ int usage_indent; /* indentation of wrapped usage lines */ int rmargin; /* right margin used for wrapping */ @@ -161,8 +160,8 @@ fill_in_uparams (const struct argp_state *state) { const char *var = getenv ("ARGP_HELP_FMT"); struct uparams new_params = uparams; - -#define SKIPWS(p) do { while (isspace (*p)) p++; } while (0); + +#define SKIPWS(p) do { while (isspace ((unsigned char) *p)) p++; } while (0); if (var) { @@ -170,20 +169,20 @@ fill_in_uparams (const struct argp_state *state) while (*var) { SKIPWS (var); - - if (isalpha (*var)) + + if (isalpha ((unsigned char) *var)) { size_t var_len; const struct uparam_name *un; int unspec = 0, val = 0; const char *arg = var; - while (isalnum (*arg) || *arg == '-' || *arg == '_') + while (isalnum ((unsigned char) *arg) || *arg == '-' || *arg == '_') arg++; var_len = arg - var; - + SKIPWS (arg); - + if (*arg == '\0' || *arg == ',') unspec = 1; else if (*arg == '=') @@ -191,7 +190,7 @@ fill_in_uparams (const struct argp_state *state) arg++; SKIPWS (arg); } - + if (unspec) { if (var[0] == 'n' && var[1] == 'o' && var[2] == '-') @@ -203,14 +202,14 @@ fill_in_uparams (const struct argp_state *state) else val = 1; } - else if (isdigit (*arg)) + else if (isdigit ((unsigned char) *arg)) { val = atoi (arg); - while (isdigit (*arg)) + while (isdigit ((unsigned char) *arg)) arg++; SKIPWS (arg); } - + for (un = uparam_names; un->name; un++) if (strlen (un->name) == var_len && strncmp (var, un->name, var_len) == 0) @@ -375,6 +374,9 @@ struct hol_entry /* 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. */ @@ -592,7 +594,7 @@ hol_entry_long_iterate (const struct hol_entry *entry, } /* 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) { @@ -673,10 +675,12 @@ static int 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 @@ -720,17 +724,19 @@ canon_doc_option (const char **name) else { /* Skip initial whitespace. */ - while (isspace (**name)) + while (isspace ((unsigned char) **name)) (*name)++; /* Decide whether this looks like an option (leading `-') or not. */ non_opt = (**name != '-'); /* Skip until part of name used for sorting. */ - while (**name && !isalnum (**name)) + while (**name && !isalnum ((unsigned char) **name)) (*name)++; } 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 @@ -740,6 +746,7 @@ hol_entry_cmp (const struct hol_entry *entry1, /* 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) { @@ -756,7 +763,8 @@ hol_entry_cmp (const struct hol_entry *entry1, 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 @@ -780,7 +788,8 @@ hol_entry_cmp (const struct hol_entry *entry1, 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 @@ -788,22 +797,22 @@ hol_entry_cmp (const struct hol_entry *entry1, first, but as they're not displayed, it doesn't matter where they are. */ { - char first1 = short1 ? short1 : long1 ? *long1 : 0; - char first2 = short2 ? short2 : long2 ? *long2 : 0; -#ifdef _tolower - int lower_cmp = _tolower (first1) - _tolower (first2); -#else + unsigned char first1 = short1 ? short1 : long1 ? *long1 : 0; + unsigned char first2 = short2 ? short2 : long2 ? *long2 : 0; + /* Use tolower, not _tolower, since only the former is + guaranteed to work on something already lower case. */ int lower_cmp = tolower (first1) - tolower (first2); -#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. */ @@ -820,8 +829,14 @@ static void 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); + } } /* Append MORE to HOL, destroying MORE in the process. Options in HOL shadow @@ -1496,7 +1511,7 @@ argp_doc (const struct argp *argp, const struct argp_state *state, } else inp_text = post ? 0 : argp->doc; - trans_text = dgettext (argp->argp_domain, inp_text); + trans_text = inp_text ? dgettext (argp->argp_domain, inp_text) : NULL; } else trans_text = inp_text = 0;