This source file includes following definitions.
- validate_uparams
 
- fill_in_uparams
 
- find_char
 
- make_hol
 
- hol_add_cluster
 
- hol_free
 
- hol_entry_short_iterate
 
- hol_entry_long_iterate
 
- until_short
 
- hol_entry_first_short
 
- hol_entry_first_long
 
- hol_find_entry
 
- hol_set_group
 
- group_cmp
 
- hol_sibling_cluster_cmp
 
- hol_cousin_cluster_cmp
 
- hol_cluster_cmp
 
- hol_cluster_base
 
- canon_doc_option
 
- hol_entry_cmp
 
- hol_entry_qcmp
 
- hol_sort
 
- hol_append
 
- argp_hol
 
- indent_to
 
- space
 
- arg
 
- filter_doc
 
- print_header
 
- hol_cluster_is_child
 
- comma
 
- hol_entry_help
 
- hol_help
 
- add_argless_short_opt
 
- usage_argful_short_opt
 
- usage_long_opt
 
- hol_usage
 
- argp_args_levels
 
- argp_args_usage
 
- argp_doc
 
- _help
 
- __argp_help
 
- weak_alias
 
- __argp_state_help
 
- weak_alias
 
- weak_alias
 
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 
  10 
  11 
  12 
  13 
  14 
  15 
  16 
  17 
  18 
  19 #ifndef _GNU_SOURCE
  20 # define _GNU_SOURCE    1
  21 #endif
  22 
  23 #ifdef HAVE_CONFIG_H
  24 # include <config.h>
  25 #endif
  26 
  27 #include <alloca.h>
  28 #include <errno.h>
  29 #include <stdbool.h>
  30 #include <stddef.h>
  31 #include <stdlib.h>
  32 #include <string.h>
  33 #include <strings.h>
  34 #include <assert.h>
  35 #include <stdarg.h>
  36 #include <ctype.h>
  37 #include <limits.h>
  38 #ifdef _LIBC
  39 # include <../libio/libioP.h>
  40 # include <wchar.h>
  41 #endif
  42 
  43 #ifdef _LIBC
  44 # include <libintl.h>
  45 # undef dgettext
  46 # define dgettext(domain, msgid) \
  47    __dcgettext (domain, msgid, LC_MESSAGES)
  48 #else
  49 # include "gettext.h"
  50 #endif
  51 
  52 #include "argp.h"
  53 #include "argp-fmtstream.h"
  54 #include "argp-namefrob.h"
  55 
  56 #ifndef SIZE_MAX
  57 # define SIZE_MAX ((size_t) -1)
  58 #endif
  59 
  60 
  61 
  62 
  63 
  64 
  65 
  66 
  67 
  68 
  69 
  70 #define DUP_ARGS      0         
  71 #define DUP_ARGS_NOTE 1         
  72 #define SHORT_OPT_COL 2         
  73 #define LONG_OPT_COL  6         
  74 #define DOC_OPT_COL   2         
  75 #define OPT_DOC_COL  29         
  76 #define HEADER_COL    1         
  77 #define USAGE_INDENT 12         
  78 #define RMARGIN      79         
  79 
  80 
  81 
  82 struct uparams
  83 {
  84   
  85 
  86 
  87 
  88 
  89   int dup_args;
  90 
  91   
  92 
  93   int dup_args_note;
  94 
  95   
  96   int short_opt_col;      
  97   int long_opt_col;       
  98   int doc_opt_col;        
  99   int opt_doc_col;        
 100   int header_col;         
 101   int usage_indent;       
 102   int rmargin;            
 103 
 104   int valid;              
 105 };
 106 
 107 
 108 static struct uparams uparams = {
 109   DUP_ARGS, DUP_ARGS_NOTE,
 110   SHORT_OPT_COL, LONG_OPT_COL, DOC_OPT_COL, OPT_DOC_COL, HEADER_COL,
 111   USAGE_INDENT, RMARGIN
 112 };
 113 
 114 
 115 struct uparam_name
 116 {
 117   const char name[14];          
 118   bool is_bool;                 
 119   unsigned char uparams_offs;   
 120 };
 121 
 122 
 123 static const struct uparam_name uparam_names[] =
 124 {
 125   { "dup-args",       true, offsetof (struct uparams, dup_args) },
 126   { "dup-args-note",  true, offsetof (struct uparams, dup_args_note) },
 127   { "short-opt-col",  false, offsetof (struct uparams, short_opt_col) },
 128   { "long-opt-col",   false, offsetof (struct uparams, long_opt_col) },
 129   { "doc-opt-col",    false, offsetof (struct uparams, doc_opt_col) },
 130   { "opt-doc-col",    false, offsetof (struct uparams, opt_doc_col) },
 131   { "header-col",     false, offsetof (struct uparams, header_col) },
 132   { "usage-indent",   false, offsetof (struct uparams, usage_indent) },
 133   { "rmargin",        false, offsetof (struct uparams, rmargin) }
 134 };
 135 #define nuparam_names (sizeof (uparam_names) / sizeof (uparam_names[0]))
 136 
 137 static void
 138 validate_uparams (const struct argp_state *state, struct uparams *upptr)
     
 139 {
 140   const struct uparam_name *up;
 141 
 142   for (up = uparam_names; up < uparam_names + nuparam_names; up++)
 143     {
 144       if (up->is_bool
 145           || up->uparams_offs == offsetof (struct uparams, rmargin))
 146         continue;
 147       if (*(int *)((char *)upptr + up->uparams_offs) >= upptr->rmargin)
 148         {
 149           __argp_failure (state, 0, 0,
 150                           dgettext (state == NULL ? NULL
 151                                     : state->root_argp->argp_domain,
 152                                     "\
 153 ARGP_HELP_FMT: %s value is less than or equal to %s"),
 154                           "rmargin", up->name);
 155           return;
 156         }
 157     }
 158   uparams = *upptr;
 159   uparams.valid = 1;
 160 }
 161 
 162 
 163 static void
 164 fill_in_uparams (const struct argp_state *state)
     
 165 {
 166   const char *var = getenv ("ARGP_HELP_FMT");
 167   struct uparams new_params = uparams;
 168 
 169 #define SKIPWS(p) do { while (isspace ((unsigned char) *p)) p++; } while (0);
 170 
 171   if (var)
 172     {
 173       
 174       while (*var)
 175         {
 176           SKIPWS (var);
 177 
 178           if (isalpha ((unsigned char) *var))
 179             {
 180               size_t var_len;
 181               const struct uparam_name *un;
 182               int unspec = 0, val = 0;
 183               const char *arg = var;
 184 
 185               while (isalnum ((unsigned char) *arg) || *arg == '-' || *arg == '_')
 186                 arg++;
 187               var_len = arg - var;
 188 
 189               SKIPWS (arg);
 190 
 191               if (*arg == '\0' || *arg == ',')
 192                 unspec = 1;
 193               else if (*arg == '=')
 194                 {
 195                   arg++;
 196                   SKIPWS (arg);
 197                 }
 198 
 199               if (unspec)
 200                 {
 201                   if (var[0] == 'n' && var[1] == 'o' && var[2] == '-')
 202                     {
 203                       val = 0;
 204                       var += 3;
 205                       var_len -= 3;
 206                     }
 207                   else
 208                     val = 1;
 209                 }
 210               else if (isdigit ((unsigned char) *arg))
 211                 {
 212                   val = atoi (arg);
 213                   while (isdigit ((unsigned char) *arg))
 214                     arg++;
 215                   SKIPWS (arg);
 216                 }
 217 
 218               for (un = uparam_names;
 219                    un < uparam_names + nuparam_names;
 220                    un++)
 221                 if (strlen (un->name) == var_len
 222                     && strncmp (var, un->name, var_len) == 0)
 223                   {
 224                     if (unspec && !un->is_bool)
 225                       __argp_failure (state, 0, 0,
 226                                       dgettext (state == NULL ? NULL
 227                                                 : state->root_argp->argp_domain,
 228                                                 "\
 229 %.*s: ARGP_HELP_FMT parameter requires a value"),
 230                                       (int) var_len, var);
 231                     else
 232                       *(int *)((char *)&new_params + un->uparams_offs) = val;
 233                     break;
 234                   }
 235               if (un == uparam_names + nuparam_names)
 236                 __argp_failure (state, 0, 0,
 237                                 dgettext (state == NULL ? NULL
 238                                           : state->root_argp->argp_domain, "\
 239 %.*s: Unknown ARGP_HELP_FMT parameter"),
 240                                 (int) var_len, var);
 241 
 242               var = arg;
 243               if (*var == ',')
 244                 var++;
 245             }
 246           else if (*var)
 247             {
 248               __argp_failure (state, 0, 0,
 249                               dgettext (state == NULL ? NULL
 250                                         : state->root_argp->argp_domain,
 251                                         "Garbage in ARGP_HELP_FMT: %s"), var);
 252               break;
 253             }
 254         }
 255       validate_uparams (state, &new_params);
 256     }
 257 }
 258 
 259 
 260 
 261 
 262 
 263 #define ovisible(opt) (! ((opt)->flags & OPTION_HIDDEN))
 264 
 265 
 266 #define oalias(opt) ((opt)->flags & OPTION_ALIAS)
 267 
 268 
 269 #define odoc(opt) ((opt)->flags & OPTION_DOC)
 270 
 271 
 272 #define onotrans(opt) ((opt)->flags & OPTION_NO_TRANS)
 273 
 274 
 275 #define oend(opt) __option_is_end (opt)
 276 
 277 
 278 #define oshort(opt) __option_is_short (opt)
 279 
 280 
 281 
 282 
 283 
 284 
 285 
 286 
 287 
 288 
 289 
 290 
 291 
 292 
 293 
 294 
 295 
 296 
 297 
 298 
 299 
 300 
 301 
 302 
 303 
 304 
 305 
 306 
 307 
 308 
 309 
 310 
 311 
 312 
 313 
 314 
 315 
 316 
 317 
 318 
 319 
 320 
 321 
 322 
 323 
 324 
 325 
 326 
 327 
 328 
 329 
 330 
 331 
 332 
 333 
 334 
 335 
 336 
 337 
 338 
 339 
 340 
 341 
 342 
 343 
 344 
 345 static int
 346 find_char (char ch, char *beg, char *end)
     
 347 {
 348   while (beg < end)
 349     if (*beg == ch)
 350       return 1;
 351     else
 352       beg++;
 353   return 0;
 354 }
 355 
 356 
 357 
 358 
 359 struct hol_cluster;             
 360 
 361 struct hol_entry
 362 {
 363   
 364   const struct argp_option *opt;
 365   
 366   unsigned num;
 367 
 368   
 369 
 370 
 371 
 372 
 373 
 374   char *short_options;
 375 
 376   
 377 
 378 
 379   int group;
 380 
 381   
 382   struct hol_cluster *cluster;
 383 
 384   
 385   const struct argp *argp;
 386 
 387   
 388   unsigned ord;
 389 };
 390 
 391 
 392 struct hol_cluster
 393 {
 394   
 395   const char *header;
 396 
 397   
 398 
 399 
 400   int index;
 401 
 402   
 403 
 404   int group;
 405 
 406   
 407 
 408   struct hol_cluster *parent;
 409 
 410   
 411   const struct argp *argp;
 412 
 413   
 414   int depth;
 415 
 416   
 417 
 418   struct hol_cluster *next;
 419 };
 420 
 421 
 422 struct hol
 423 {
 424   
 425   struct hol_entry *entries;
 426   
 427 
 428   unsigned num_entries;
 429 
 430   
 431 
 432   char *short_options;
 433 
 434   
 435   struct hol_cluster *clusters;
 436 };
 437 
 438 
 439 
 440 static struct hol *
 441 make_hol (const struct argp *argp, struct hol_cluster *cluster)
     
 442 {
 443   char *so;
 444   const struct argp_option *o;
 445   const struct argp_option *opts = argp->options;
 446   struct hol_entry *entry;
 447   unsigned num_short_options = 0;
 448   struct hol *hol = malloc (sizeof (struct hol));
 449 
 450   assert (hol);
 451 
 452   hol->num_entries = 0;
 453   hol->clusters = 0;
 454 
 455   if (opts)
 456     {
 457       int cur_group = 0;
 458 
 459       
 460       assert (! oalias (opts));
 461 
 462       
 463       for (o = opts; ! oend (o); o++)
 464         {
 465           if (! oalias (o))
 466             hol->num_entries++;
 467           if (oshort (o))
 468             num_short_options++;        
 469         }
 470 
 471       hol->entries = malloc (sizeof (struct hol_entry) * hol->num_entries);
 472       hol->short_options = malloc (num_short_options + 1);
 473 
 474       assert (hol->entries && hol->short_options);
 475       if (SIZE_MAX <= UINT_MAX)
 476         assert (hol->num_entries <= SIZE_MAX / sizeof (struct hol_entry));
 477 
 478       
 479       so = hol->short_options;
 480       for (o = opts, entry = hol->entries; ! oend (o); entry++)
 481         {
 482           entry->opt = o;
 483           entry->num = 0;
 484           entry->short_options = so;
 485           entry->group = cur_group =
 486             o->group
 487             ? o->group
 488             : ((!o->name && !o->key)
 489                ? cur_group + 1
 490                : cur_group);
 491           entry->cluster = cluster;
 492           entry->argp = argp;
 493 
 494           do
 495             {
 496               entry->num++;
 497               if (oshort (o) && ! find_char (o->key, hol->short_options, so))
 498                 
 499                 *so++ = o->key;
 500               o++;
 501             }
 502           while (! oend (o) && oalias (o));
 503         }
 504       *so = '\0';               
 505     }
 506 
 507   return hol;
 508 }
 509 
 510 
 511 
 512 
 513 static struct hol_cluster *
 514 hol_add_cluster (struct hol *hol, int group, const char *header, int index,
     
 515                  struct hol_cluster *parent, const struct argp *argp)
 516 {
 517   struct hol_cluster *cl = malloc (sizeof (struct hol_cluster));
 518   if (cl)
 519     {
 520       cl->group = group;
 521       cl->header = header;
 522 
 523       cl->index = index;
 524       cl->parent = parent;
 525       cl->argp = argp;
 526       cl->depth = parent ? parent->depth + 1 : 0;
 527 
 528       cl->next = hol->clusters;
 529       hol->clusters = cl;
 530     }
 531   return cl;
 532 }
 533 
 534 
 535 static void
 536 hol_free (struct hol *hol)
     
 537 {
 538   struct hol_cluster *cl = hol->clusters;
 539 
 540   while (cl)
 541     {
 542       struct hol_cluster *next = cl->next;
 543       free (cl);
 544       cl = next;
 545     }
 546 
 547   if (hol->num_entries > 0)
 548     {
 549       free (hol->entries);
 550       free (hol->short_options);
 551     }
 552 
 553   free (hol);
 554 }
 555 
 556 
 557 
 558 
 559 static int
 560 hol_entry_short_iterate (const struct hol_entry *entry,
     
 561                          int (*func)(const struct argp_option *opt,
 562                                      const struct argp_option *real,
 563                                      const char *domain, void *cookie),
 564                          const char *domain, void *cookie)
 565 {
 566   unsigned nopts;
 567   int val = 0;
 568   const struct argp_option *opt, *real = entry->opt;
 569   char *so = entry->short_options;
 570 
 571   for (opt = real, nopts = entry->num; nopts > 0 && !val; opt++, nopts--)
 572     if (oshort (opt) && *so == opt->key)
 573       {
 574         if (!oalias (opt))
 575           real = opt;
 576         if (ovisible (opt))
 577           val = (*func)(opt, real, domain, cookie);
 578         so++;
 579       }
 580 
 581   return val;
 582 }
 583 
 584 
 585 
 586 
 587 static inline int
 588 #if (__GNUC__ >= 3) || (__clang_major__ >= 4)
 589 __attribute__ ((always_inline))
 590 #endif
 591 hol_entry_long_iterate (const struct hol_entry *entry,
     
 592                         int (*func)(const struct argp_option *opt,
 593                                     const struct argp_option *real,
 594                                     const char *domain, void *cookie),
 595                         const char *domain, void *cookie)
 596 {
 597   unsigned nopts;
 598   int val = 0;
 599   const struct argp_option *opt, *real = entry->opt;
 600 
 601   for (opt = real, nopts = entry->num; nopts > 0 && !val; opt++, nopts--)
 602     if (opt->name)
 603       {
 604         if (!oalias (opt))
 605           real = opt;
 606         if (ovisible (opt))
 607           val = (*func)(opt, real, domain, cookie);
 608       }
 609 
 610   return val;
 611 }
 612 
 613 
 614 static int
 615 until_short (const struct argp_option *opt, const struct argp_option *real,
     
 616              const char *domain, void *cookie)
 617 {
 618   return oshort (opt) ? opt->key : 0;
 619 }
 620 
 621 
 622 static char
 623 hol_entry_first_short (const struct hol_entry *entry)
     
 624 {
 625   return hol_entry_short_iterate (entry, until_short,
 626                                   entry->argp->argp_domain, 0);
 627 }
 628 
 629 
 630 static const char *
 631 hol_entry_first_long (const struct hol_entry *entry)
     
 632 {
 633   const struct argp_option *opt;
 634   unsigned num;
 635   for (opt = entry->opt, num = entry->num; num > 0; opt++, num--)
 636     if (opt->name && ovisible (opt))
 637       return opt->name;
 638   return 0;
 639 }
 640 
 641 
 642 
 643 static struct hol_entry *
 644 hol_find_entry (struct hol *hol, const char *name)
     
 645 {
 646   struct hol_entry *entry = hol->entries;
 647   unsigned num_entries = hol->num_entries;
 648 
 649   while (num_entries-- > 0)
 650     {
 651       const struct argp_option *opt = entry->opt;
 652       unsigned num_opts = entry->num;
 653 
 654       while (num_opts-- > 0)
 655         if (opt->name && ovisible (opt) && strcmp (opt->name, name) == 0)
 656           return entry;
 657         else
 658           opt++;
 659 
 660       entry++;
 661     }
 662 
 663   return 0;
 664 }
 665 
 666 
 667 
 668 static void
 669 hol_set_group (struct hol *hol, const char *name, int group)
     
 670 {
 671   struct hol_entry *entry = hol_find_entry (hol, name);
 672   if (entry)
 673     entry->group = group;
 674 }
 675 
 676 
 677 
 678 
 679 
 680 static int
 681 group_cmp (int group1, int group2)
     
 682 {
 683   if ((group1 < 0 && group2 < 0) || (group1 >= 0 && group2 >= 0))
 684     return group1 - group2;
 685   else
 686     
 687 
 688     return group2 - group1;
 689 }
 690 
 691 
 692 
 693 static int
 694 hol_sibling_cluster_cmp (const struct hol_cluster *cl1,
     
 695                          const struct hol_cluster *cl2)
 696 {
 697   
 698   int cmp = group_cmp (cl1->group, cl2->group);
 699   if (cmp != 0)
 700     return cmp;
 701 
 702   
 703   return cl2->index - cl1->index;
 704 }
 705 
 706 
 707 
 708 static int
 709 hol_cousin_cluster_cmp (const struct hol_cluster *cl1,
     
 710                         const struct hol_cluster *cl2)
 711 {
 712   if (cl1->parent == cl2->parent)
 713     return hol_sibling_cluster_cmp (cl1, cl2);
 714   else
 715     {
 716       
 717       int cmp = hol_cousin_cluster_cmp (cl1->parent, cl2->parent);
 718       if (cmp != 0)
 719         return cmp;
 720 
 721       
 722       cmp = group_cmp (cl1->group, cl2->group);
 723       if (cmp != 0)
 724         return cmp;
 725 
 726       
 727       return cl2->index - cl1->index;
 728     }
 729 }
 730 
 731 
 732 
 733 static int
 734 hol_cluster_cmp (const struct hol_cluster *cl1, const struct hol_cluster *cl2)
     
 735 {
 736   
 737 
 738 
 739   if (cl1->depth > cl2->depth)
 740     {
 741       do
 742         cl1 = cl1->parent;
 743       while (cl1->depth > cl2->depth);
 744       int cmp = hol_cousin_cluster_cmp (cl1, cl2);
 745       if (cmp != 0)
 746         return cmp;
 747 
 748       return 1;
 749     }
 750   else if (cl1->depth < cl2->depth)
 751     {
 752       do
 753         cl2 = cl2->parent;
 754       while (cl1->depth < cl2->depth);
 755       int cmp = hol_cousin_cluster_cmp (cl1, cl2);
 756       if (cmp != 0)
 757         return cmp;
 758 
 759       return -1;
 760     }
 761   else
 762     return hol_cousin_cluster_cmp (cl1, cl2);
 763 }
 764 
 765 
 766 
 767 static struct hol_cluster *
 768 hol_cluster_base (struct hol_cluster *cl)
     
 769 {
 770   while (cl->parent)
 771     cl = cl->parent;
 772   return cl;
 773 }
 774 
 775 
 776 
 777 
 778 static int
 779 canon_doc_option (const char **name)
     
 780 {
 781   int non_opt;
 782   
 783   while (isspace ((unsigned char) **name))
 784     (*name)++;
 785   
 786   non_opt = (**name != '-');
 787   
 788   while (**name && !isalnum ((unsigned char) **name))
 789     (*name)++;
 790   return non_opt;
 791 }
 792 
 793 
 794 
 795 
 796 
 797 
 798 
 799 
 800 
 801 
 802 
 803 
 804 static int
 805 hol_entry_cmp (const struct hol_entry *entry1,
     
 806                const struct hol_entry *entry2)
 807 {
 808   
 809 
 810 
 811   int group1 = (entry1->cluster
 812                 ? hol_cluster_base (entry1->cluster)->group
 813                 : entry1->group);
 814   int group2 = (entry2->cluster
 815                 ? hol_cluster_base (entry2->cluster)->group
 816                 : entry2->group);
 817   int cmp = group_cmp (group1, group2);
 818   if (cmp != 0)
 819     return cmp;
 820 
 821   
 822 
 823   
 824   cmp = (entry1->cluster != NULL) - (entry2->cluster != NULL);
 825   if (cmp != 0)
 826     return cmp;
 827 
 828   
 829   if (entry1->cluster != NULL)
 830     {
 831       cmp = hol_cluster_cmp (entry1->cluster, entry2->cluster);
 832       if (cmp != 0)
 833         return cmp;
 834     }
 835 
 836   
 837 
 838   cmp = group_cmp (entry1->group, entry2->group);
 839   if (cmp != 0)
 840     return cmp;
 841 
 842   
 843 
 844   
 845 
 846   const char *long1 = hol_entry_first_long (entry1);
 847   const char *long2 = hol_entry_first_long (entry2);
 848   int doc1 =
 849     (odoc (entry1->opt) ? long1 != NULL && canon_doc_option (&long1) : 0);
 850   int doc2 =
 851     (odoc (entry2->opt) ? long2 != NULL && canon_doc_option (&long2) : 0);
 852   cmp = doc1 - doc2;
 853   if (cmp != 0)
 854     return cmp;
 855 
 856   
 857 
 858   
 859 
 860 
 861 
 862   int short1 = hol_entry_first_short (entry1);
 863   int short2 = hol_entry_first_short (entry2);
 864   unsigned char first1 = short1 ? short1 : long1 != NULL ? *long1 : 0;
 865   unsigned char first2 = short2 ? short2 : long2 != NULL ? *long2 : 0;
 866   
 867   
 868 
 869   cmp = tolower (first1) - tolower (first2);
 870   if (cmp != 0)
 871     return cmp;
 872   
 873 
 874   cmp = first2 - first1;
 875   if (cmp != 0)
 876     return cmp;
 877 
 878   
 879 
 880   
 881   cmp = (short1 != 0) - (short2 != 0);
 882   if (cmp != 0)
 883     return cmp;
 884 
 885   
 886   if (short1 == 0)
 887     {
 888       cmp = (long1 != NULL) - (long2 != NULL);
 889       if (cmp != 0)
 890         return cmp;
 891 
 892       if (long1 != NULL)
 893         {
 894           cmp = __strcasecmp (long1, long2);
 895           if (cmp != 0)
 896             return cmp;
 897         }
 898     }
 899 
 900   
 901 
 902   return 0;
 903 }
 904 
 905 
 906 static int
 907 hol_entry_qcmp (const void *entry1_v, const void *entry2_v)
     
 908 {
 909   return hol_entry_cmp (entry1_v, entry2_v);
 910 }
 911 
 912 
 913 
 914 
 915 static void
 916 hol_sort (struct hol *hol)
     
 917 {
 918   if (hol->num_entries > 0)
 919     {
 920       unsigned i;
 921       struct hol_entry *e;
 922       for (i = 0, e = hol->entries; i < hol->num_entries; i++, e++)
 923         e->ord = i;
 924 
 925       qsort (hol->entries, hol->num_entries, sizeof (struct hol_entry),
 926              hol_entry_qcmp);
 927     }
 928 }
 929 
 930 
 931 
 932 
 933 
 934 
 935 static void
 936 hol_append (struct hol *hol, struct hol *more)
     
 937 {
 938   struct hol_cluster **cl_end = &hol->clusters;
 939 
 940   
 941   while (*cl_end)
 942     cl_end = &(*cl_end)->next;
 943   *cl_end = more->clusters;
 944   more->clusters = 0;
 945 
 946   
 947   if (more->num_entries > 0)
 948     {
 949       if (hol->num_entries == 0)
 950         {
 951           hol->num_entries = more->num_entries;
 952           hol->entries = more->entries;
 953           hol->short_options = more->short_options;
 954           more->num_entries = 0;        
 955         }
 956       else
 957         
 958 
 959         {
 960           unsigned left;
 961           char *so, *more_so;
 962           struct hol_entry *e;
 963           unsigned num_entries = hol->num_entries + more->num_entries;
 964           struct hol_entry *entries =
 965             malloc (num_entries * sizeof (struct hol_entry));
 966           unsigned hol_so_len = strlen (hol->short_options);
 967           char *short_options =
 968             malloc (hol_so_len + strlen (more->short_options) + 1);
 969 
 970           assert (entries && short_options);
 971           if (SIZE_MAX <= UINT_MAX)
 972             assert (num_entries <= SIZE_MAX / sizeof (struct hol_entry));
 973 
 974           __mempcpy (__mempcpy (entries, hol->entries,
 975                                 hol->num_entries * sizeof (struct hol_entry)),
 976                      more->entries,
 977                      more->num_entries * sizeof (struct hol_entry));
 978 
 979           __mempcpy (short_options, hol->short_options, hol_so_len);
 980 
 981           
 982           for (e = entries, left = hol->num_entries; left > 0; e++, left--)
 983             e->short_options
 984               = short_options + (e->short_options - hol->short_options);
 985 
 986           
 987 
 988           so = short_options + hol_so_len;
 989           more_so = more->short_options;
 990           for (left = more->num_entries; left > 0; e++, left--)
 991             {
 992               int opts_left;
 993               const struct argp_option *opt;
 994 
 995               e->short_options = so;
 996 
 997               for (opts_left = e->num, opt = e->opt; opts_left; opt++, opts_left--)
 998                 {
 999                   int ch = *more_so;
1000                   if (oshort (opt) && ch == opt->key)
1001                     
1002                     {
1003                       if (! find_char (ch, short_options,
1004                                        short_options + hol_so_len))
1005                         
1006 
1007                         *so++ = ch;
1008                       more_so++;
1009                     }
1010                 }
1011             }
1012 
1013           *so = '\0';
1014 
1015           free (hol->entries);
1016           free (hol->short_options);
1017 
1018           hol->entries = entries;
1019           hol->num_entries = num_entries;
1020           hol->short_options = short_options;
1021         }
1022     }
1023 
1024   hol_free (more);
1025 }
1026 
1027 
1028 
1029 static struct hol *
1030 argp_hol (const struct argp *argp, struct hol_cluster *cluster)
     
1031 {
1032   const struct argp_child *child = argp->children;
1033   struct hol *hol = make_hol (argp, cluster);
1034   if (child)
1035     while (child->argp)
1036       {
1037         struct hol_cluster *child_cluster =
1038           ((child->group || child->header)
1039            
1040            ? hol_add_cluster (hol, child->group, child->header,
1041                               child - argp->children, cluster, argp)
1042            
1043            : cluster);
1044         hol_append (hol, argp_hol (child->argp, child_cluster)) ;
1045         child++;
1046       }
1047   return hol;
1048 }
1049 
1050 
1051 
1052 
1053 
1054 static void
1055 indent_to (argp_fmtstream_t stream, unsigned col)
     
1056 {
1057   int needed = col - __argp_fmtstream_point (stream);
1058   while (needed-- > 0)
1059     __argp_fmtstream_putc (stream, ' ');
1060 }
1061 
1062 
1063 
1064 static void
1065 space (argp_fmtstream_t stream, size_t ensure)
     
1066 {
1067   if (__argp_fmtstream_point (stream) + ensure
1068       >= __argp_fmtstream_rmargin (stream))
1069     __argp_fmtstream_putc (stream, '\n');
1070   else
1071     __argp_fmtstream_putc (stream, ' ');
1072 }
1073 
1074 
1075 
1076 
1077 static void
1078 arg (const struct argp_option *real, const char *req_fmt, const char *opt_fmt,
     
1079      const char *domain, argp_fmtstream_t stream)
1080 {
1081   if (real->arg)
1082     {
1083       if (real->flags & OPTION_ARG_OPTIONAL)
1084         __argp_fmtstream_printf (stream, opt_fmt,
1085                                  dgettext (domain, real->arg));
1086       else
1087         __argp_fmtstream_printf (stream, req_fmt,
1088                                  dgettext (domain, real->arg));
1089     }
1090 }
1091 
1092 
1093 
1094 
1095 struct hol_help_state
1096 {
1097   
1098   struct hol_entry *prev_entry;
1099 
1100   
1101 
1102   int sep_groups;
1103 
1104   
1105 
1106   int suppressed_dup_arg;
1107 };
1108 
1109 
1110 
1111 
1112 struct pentry_state
1113 {
1114   const struct hol_entry *entry;
1115   argp_fmtstream_t stream;
1116   struct hol_help_state *hhstate;
1117 
1118   
1119   int first;
1120 
1121   
1122   const struct argp_state *state;
1123 };
1124 
1125 
1126 static const char *
1127 filter_doc (const char *doc, int key, const struct argp *argp,
     
1128             const struct argp_state *state)
1129 {
1130   if (argp && argp->help_filter)
1131     
1132     {
1133       void *input = __argp_input (argp, state);
1134       return (*argp->help_filter) (key, doc, input);
1135     }
1136   else
1137     
1138     return doc;
1139 }
1140 
1141 
1142 
1143 
1144 
1145 
1146 static void
1147 print_header (const char *str, const struct argp *argp,
     
1148               struct pentry_state *pest)
1149 {
1150   const char *tstr = str ? dgettext (argp->argp_domain, str) : NULL;
1151   const char *fstr = filter_doc (tstr, ARGP_KEY_HELP_HEADER, argp, pest->state);
1152 
1153   if (fstr)
1154     {
1155       if (*fstr)
1156         {
1157           if (pest->hhstate->prev_entry)
1158             
1159             __argp_fmtstream_putc (pest->stream, '\n');
1160           indent_to (pest->stream, uparams.header_col);
1161           __argp_fmtstream_set_lmargin (pest->stream, uparams.header_col);
1162           __argp_fmtstream_set_wmargin (pest->stream, uparams.header_col);
1163           __argp_fmtstream_puts (pest->stream, fstr);
1164           __argp_fmtstream_set_lmargin (pest->stream, 0);
1165           __argp_fmtstream_putc (pest->stream, '\n');
1166         }
1167 
1168       pest->hhstate->sep_groups = 1; 
1169     }
1170 
1171   if (fstr != tstr)
1172     free ((char *) fstr);
1173 }
1174 
1175 
1176 static int
1177 hol_cluster_is_child (const struct hol_cluster *cl1,
     
1178                       const struct hol_cluster *cl2)
1179 {
1180   while (cl1 && cl1 != cl2)
1181     cl1 = cl1->parent;
1182   return cl1 == cl2;
1183 }
1184 
1185 
1186 
1187 
1188 
1189 static void
1190 comma (unsigned col, struct pentry_state *pest)
     
1191 {
1192   if (pest->first)
1193     {
1194       const struct hol_entry *pe = pest->hhstate->prev_entry;
1195       const struct hol_cluster *cl = pest->entry->cluster;
1196 
1197       if (pest->hhstate->sep_groups && pe && pest->entry->group != pe->group)
1198         __argp_fmtstream_putc (pest->stream, '\n');
1199 
1200       if (cl && cl->header && *cl->header
1201           && (!pe
1202               || (pe->cluster != cl
1203                   && !hol_cluster_is_child (pe->cluster, cl))))
1204         
1205 
1206 
1207 
1208         {
1209           int old_wm = __argp_fmtstream_wmargin (pest->stream);
1210           print_header (cl->header, cl->argp, pest);
1211           __argp_fmtstream_set_wmargin (pest->stream, old_wm);
1212         }
1213 
1214       pest->first = 0;
1215     }
1216   else
1217     __argp_fmtstream_puts (pest->stream, ", ");
1218 
1219   indent_to (pest->stream, col);
1220 }
1221 
1222 
1223 static void
1224 hol_entry_help (struct hol_entry *entry, const struct argp_state *state,
     
1225                 argp_fmtstream_t stream, struct hol_help_state *hhstate)
1226 {
1227   unsigned num;
1228   const struct argp_option *real = entry->opt, *opt;
1229   char *so = entry->short_options;
1230   int have_long_opt = 0;        
1231   
1232   int old_lm = __argp_fmtstream_set_lmargin (stream, 0);
1233   int old_wm = __argp_fmtstream_wmargin (stream);
1234   
1235 
1236   struct pentry_state pest = { entry, stream, hhstate, 1, state };
1237 
1238   if (! odoc (real))
1239     for (opt = real, num = entry->num; num > 0; opt++, num--)
1240       if (opt->name && ovisible (opt))
1241         {
1242           have_long_opt = 1;
1243           break;
1244         }
1245 
1246   
1247   __argp_fmtstream_set_wmargin (stream, uparams.short_opt_col); 
1248   for (opt = real, num = entry->num; num > 0; opt++, num--)
1249     if (oshort (opt) && opt->key == *so)
1250       
1251       {
1252         if (ovisible (opt))
1253           {
1254             comma (uparams.short_opt_col, &pest);
1255             __argp_fmtstream_putc (stream, '-');
1256             __argp_fmtstream_putc (stream, *so);
1257             if (!have_long_opt || uparams.dup_args)
1258               arg (real, " %s", "[%s]",
1259                    state == NULL ? NULL : state->root_argp->argp_domain,
1260                    stream);
1261             else if (real->arg)
1262               hhstate->suppressed_dup_arg = 1;
1263           }
1264         so++;
1265       }
1266 
1267   
1268   if (odoc (real))
1269     
1270     {
1271       __argp_fmtstream_set_wmargin (stream, uparams.doc_opt_col);
1272       for (opt = real, num = entry->num; num > 0; opt++, num--)
1273         if (opt->name && ovisible (opt))
1274           {
1275             comma (uparams.doc_opt_col, &pest);
1276             
1277 
1278 
1279             __argp_fmtstream_puts (stream,
1280                                    dgettext (state == NULL ? NULL
1281                                              : state->root_argp->argp_domain,
1282                                              opt->name));
1283           }
1284     }
1285   else
1286     
1287     {
1288       __argp_fmtstream_set_wmargin (stream, uparams.long_opt_col);
1289       for (opt = real, num = entry->num; num > 0; opt++, num--)
1290         if (opt->name && ovisible (opt))
1291           {
1292             comma (uparams.long_opt_col, &pest);
1293             __argp_fmtstream_printf (stream, "--%s", opt->name);
1294             arg (real, "=%s", "[=%s]",
1295                  state == NULL ? NULL : state->root_argp->argp_domain, stream);
1296           }
1297     }
1298 
1299   
1300   __argp_fmtstream_set_lmargin (stream, 0);
1301 
1302   if (pest.first)
1303     {
1304       
1305       if (!oshort (real) && !real->name)
1306         
1307         print_header (real->doc, entry->argp, &pest);
1308       else
1309         
1310         goto cleanup;           
1311     }
1312   else
1313     {
1314       const char *tstr = real->doc ? dgettext (state == NULL ? NULL
1315                                                : state->root_argp->argp_domain,
1316                                                real->doc) : 0;
1317       const char *fstr = filter_doc (tstr, real->key, entry->argp, state);
1318       if (fstr && *fstr)
1319         {
1320           unsigned int col = __argp_fmtstream_point (stream);
1321 
1322           __argp_fmtstream_set_lmargin (stream, uparams.opt_doc_col);
1323           __argp_fmtstream_set_wmargin (stream, uparams.opt_doc_col);
1324 
1325           if (col > (unsigned int) (uparams.opt_doc_col + 3))
1326             __argp_fmtstream_putc (stream, '\n');
1327           else if (col >= (unsigned int) uparams.opt_doc_col)
1328             __argp_fmtstream_puts (stream, "   ");
1329           else
1330             indent_to (stream, uparams.opt_doc_col);
1331 
1332           __argp_fmtstream_puts (stream, fstr);
1333         }
1334       if (fstr && fstr != tstr)
1335         free ((char *) fstr);
1336 
1337       
1338       __argp_fmtstream_set_lmargin (stream, 0);
1339       __argp_fmtstream_putc (stream, '\n');
1340     }
1341 
1342   hhstate->prev_entry = entry;
1343 
1344 cleanup:
1345   __argp_fmtstream_set_lmargin (stream, old_lm);
1346   __argp_fmtstream_set_wmargin (stream, old_wm);
1347 }
1348 
1349 
1350 static void
1351 hol_help (struct hol *hol, const struct argp_state *state,
     
1352           argp_fmtstream_t stream)
1353 {
1354   unsigned num;
1355   struct hol_entry *entry;
1356   struct hol_help_state hhstate = { 0, 0, 0 };
1357 
1358   for (entry = hol->entries, num = hol->num_entries; num > 0; entry++, num--)
1359     hol_entry_help (entry, state, stream, &hhstate);
1360 
1361   if (hhstate.suppressed_dup_arg && uparams.dup_args_note)
1362     {
1363       const char *tstr = dgettext (state == NULL ? NULL
1364                                    : state->root_argp->argp_domain, "\
1365 Mandatory or optional arguments to long options are also mandatory or \
1366 optional for any corresponding short options.");
1367       const char *fstr = filter_doc (tstr, ARGP_KEY_HELP_DUP_ARGS_NOTE,
1368                                      state ? state->root_argp : 0, state);
1369       if (fstr && *fstr)
1370         {
1371           __argp_fmtstream_putc (stream, '\n');
1372           __argp_fmtstream_puts (stream, fstr);
1373           __argp_fmtstream_putc (stream, '\n');
1374         }
1375       if (fstr && fstr != tstr)
1376         free ((char *) fstr);
1377     }
1378 }
1379 
1380 
1381 
1382 
1383 
1384 static int
1385 add_argless_short_opt (const struct argp_option *opt,
     
1386                        const struct argp_option *real,
1387                        const char *domain, void *cookie)
1388 {
1389   char **snao_end = cookie;
1390   if (!(opt->arg || real->arg)
1391       && !((opt->flags | real->flags) & OPTION_NO_USAGE))
1392     *(*snao_end)++ = opt->key;
1393   return 0;
1394 }
1395 
1396 
1397 
1398 static int
1399 usage_argful_short_opt (const struct argp_option *opt,
     
1400                         const struct argp_option *real,
1401                         const char *domain, void *cookie)
1402 {
1403   argp_fmtstream_t stream = cookie;
1404   const char *arg = opt->arg;
1405   int flags = opt->flags | real->flags;
1406 
1407   if (! arg)
1408     arg = real->arg;
1409 
1410   if (arg && !(flags & OPTION_NO_USAGE))
1411     {
1412       arg = dgettext (domain, arg);
1413 
1414       if (flags & OPTION_ARG_OPTIONAL)
1415         __argp_fmtstream_printf (stream, " [-%c[%s]]", opt->key, arg);
1416       else
1417         {
1418           
1419 
1420           space (stream, 6 + strlen (arg));
1421           __argp_fmtstream_printf (stream, "[-%c %s]", opt->key, arg);
1422         }
1423     }
1424 
1425   return 0;
1426 }
1427 
1428 
1429 
1430 static int
1431 usage_long_opt (const struct argp_option *opt,
     
1432                 const struct argp_option *real,
1433                 const char *domain, void *cookie)
1434 {
1435   argp_fmtstream_t stream = cookie;
1436   const char *arg = opt->arg;
1437   int flags = opt->flags | real->flags;
1438 
1439   if (! arg)
1440     arg = real->arg;
1441 
1442   if (! (flags & OPTION_NO_USAGE))
1443     {
1444       if (arg)
1445         {
1446           arg = dgettext (domain, arg);
1447           if (flags & OPTION_ARG_OPTIONAL)
1448             __argp_fmtstream_printf (stream, " [--%s[=%s]]", opt->name, arg);
1449           else
1450             __argp_fmtstream_printf (stream, " [--%s=%s]", opt->name, arg);
1451         }
1452       else
1453         __argp_fmtstream_printf (stream, " [--%s]", opt->name);
1454     }
1455 
1456   return 0;
1457 }
1458 
1459 
1460 static void
1461 hol_usage (struct hol *hol, argp_fmtstream_t stream)
     
1462 {
1463   if (hol->num_entries > 0)
1464     {
1465       unsigned nentries;
1466       struct hol_entry *entry;
1467       char *short_no_arg_opts = alloca (strlen (hol->short_options) + 1);
1468       char *snao_end = short_no_arg_opts;
1469 
1470       
1471       for (entry = hol->entries, nentries = hol->num_entries
1472            ; nentries > 0
1473            ; entry++, nentries--)
1474         hol_entry_short_iterate (entry, add_argless_short_opt,
1475                                  entry->argp->argp_domain, &snao_end);
1476       if (snao_end > short_no_arg_opts)
1477         {
1478           *snao_end++ = 0;
1479           __argp_fmtstream_printf (stream, " [-%s]", short_no_arg_opts);
1480         }
1481 
1482       
1483       for (entry = hol->entries, nentries = hol->num_entries
1484            ; nentries > 0
1485            ; entry++, nentries--)
1486         hol_entry_short_iterate (entry, usage_argful_short_opt,
1487                                  entry->argp->argp_domain, stream);
1488 
1489       
1490       for (entry = hol->entries, nentries = hol->num_entries
1491            ; nentries > 0
1492            ; entry++, nentries--)
1493         hol_entry_long_iterate (entry, usage_long_opt,
1494                                 entry->argp->argp_domain, stream);
1495     }
1496 }
1497 
1498 
1499 
1500 static size_t
1501 argp_args_levels (const struct argp *argp)
     
1502 {
1503   size_t levels = 0;
1504   const struct argp_child *child = argp->children;
1505 
1506   if (argp->args_doc && strchr (argp->args_doc, '\n'))
1507     levels++;
1508 
1509   if (child)
1510     while (child->argp)
1511       levels += argp_args_levels ((child++)->argp);
1512 
1513   return levels;
1514 }
1515 
1516 
1517 
1518 
1519 
1520 
1521 static int
1522 argp_args_usage (const struct argp *argp, const struct argp_state *state,
     
1523                  char **levels, int advance, argp_fmtstream_t stream)
1524 {
1525   char *our_level = *levels;
1526   int multiple = 0;
1527   const struct argp_child *child = argp->children;
1528   const char *tdoc =
1529     argp->args_doc ? dgettext (argp->argp_domain, argp->args_doc) : NULL;
1530   const char *fdoc = filter_doc (tdoc, ARGP_KEY_HELP_ARGS_DOC, argp, state);
1531   const char *nl = NULL;
1532 
1533   if (fdoc)
1534     {
1535       const char *cp = fdoc;
1536       nl = __strchrnul (cp, '\n');
1537       if (*nl != '\0')
1538         
1539 
1540         {
1541           int i;
1542           multiple = 1;
1543           for (i = 0; i < *our_level; i++)
1544             cp = nl + 1, nl = __strchrnul (cp, '\n');
1545           (*levels)++;
1546         }
1547 
1548       
1549 
1550       space (stream, 1 + nl - cp);
1551 
1552       __argp_fmtstream_write (stream, cp, nl - cp);
1553     }
1554   if (fdoc && fdoc != tdoc)
1555     free ((char *)fdoc);        
1556 
1557   if (child)
1558     while (child->argp)
1559       advance = !argp_args_usage ((child++)->argp, state, levels, advance, stream);
1560 
1561   if (advance && multiple)
1562     {
1563       
1564       if (*nl)
1565         
1566         {
1567           (*our_level)++;
1568           advance = 0;          
1569         }
1570       else if (*our_level > 0)
1571         
1572         *our_level = 0;
1573     }
1574 
1575   return !advance;
1576 }
1577 
1578 
1579 
1580 
1581 
1582 
1583 
1584 
1585 static int
1586 argp_doc (const struct argp *argp, const struct argp_state *state,
     
1587           int post, int pre_blank, int first_only,
1588           argp_fmtstream_t stream)
1589 {
1590   const char *text;
1591   const char *inp_text;
1592   void *input = 0;
1593   int anything = 0;
1594   size_t inp_text_limit = 0;
1595   const char *doc = argp->doc ? dgettext (argp->argp_domain, argp->doc) : NULL;
1596   const struct argp_child *child = argp->children;
1597 
1598   if (doc)
1599     {
1600       char *vt = strchr (doc, '\v');
1601       inp_text = post ? (vt ? vt + 1 : 0) : doc;
1602       inp_text_limit = (!post && vt) ? (vt - doc) : 0;
1603     }
1604   else
1605     inp_text = 0;
1606 
1607   if (argp->help_filter)
1608     
1609     {
1610       if (inp_text_limit)
1611         
1612         inp_text = __strndup (inp_text, inp_text_limit);
1613       input = __argp_input (argp, state);
1614       text =
1615         (*argp->help_filter) (post
1616                               ? ARGP_KEY_HELP_POST_DOC
1617                               : ARGP_KEY_HELP_PRE_DOC,
1618                               inp_text, input);
1619     }
1620   else
1621     text = (const char *) inp_text;
1622 
1623   if (text)
1624     {
1625       if (pre_blank)
1626         __argp_fmtstream_putc (stream, '\n');
1627 
1628       if (text == inp_text && inp_text_limit)
1629         __argp_fmtstream_write (stream, inp_text, inp_text_limit);
1630       else
1631         __argp_fmtstream_puts (stream, text);
1632 
1633       if (__argp_fmtstream_point (stream) > __argp_fmtstream_lmargin (stream))
1634         __argp_fmtstream_putc (stream, '\n');
1635 
1636       anything = 1;
1637     }
1638 
1639   if (text && text != inp_text)
1640     free ((char *) text);       
1641   if (inp_text && inp_text_limit && argp->help_filter)
1642     free ((char *) inp_text);   
1643 
1644   if (post && argp->help_filter)
1645     
1646     {
1647       text = (*argp->help_filter) (ARGP_KEY_HELP_EXTRA, 0, input);
1648       if (text)
1649         {
1650           if (anything || pre_blank)
1651             __argp_fmtstream_putc (stream, '\n');
1652           __argp_fmtstream_puts (stream, text);
1653           free ((char *) text);
1654           if (__argp_fmtstream_point (stream)
1655               > __argp_fmtstream_lmargin (stream))
1656             __argp_fmtstream_putc (stream, '\n');
1657           anything = 1;
1658         }
1659     }
1660 
1661   if (child)
1662     while (child->argp && !(first_only && anything))
1663       anything |=
1664         argp_doc ((child++)->argp, state,
1665                   post, anything || pre_blank, first_only,
1666                   stream);
1667 
1668   return anything;
1669 }
1670 
1671 
1672 
1673 
1674 
1675 static void
1676 _help (const struct argp *argp, const struct argp_state *state, FILE *stream,
     
1677        unsigned flags, char *name)
1678 {
1679   int anything = 0;             
1680   struct hol *hol = 0;
1681   argp_fmtstream_t fs;
1682 
1683   if (! stream)
1684     return;
1685 
1686 #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
1687   __flockfile (stream);
1688 #endif
1689 
1690   if (! uparams.valid)
1691     fill_in_uparams (state);
1692 
1693   fs = __argp_make_fmtstream (stream, 0, uparams.rmargin, 0);
1694   if (! fs)
1695     {
1696 #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
1697       __funlockfile (stream);
1698 #endif
1699       return;
1700     }
1701 
1702   if (flags & (ARGP_HELP_USAGE | ARGP_HELP_SHORT_USAGE | ARGP_HELP_LONG))
1703     {
1704       hol = argp_hol (argp, 0);
1705 
1706       
1707       hol_set_group (hol, "help", -1);
1708       hol_set_group (hol, "version", -1);
1709 
1710       hol_sort (hol);
1711     }
1712 
1713   if (flags & (ARGP_HELP_USAGE | ARGP_HELP_SHORT_USAGE))
1714     
1715     {
1716       int first_pattern = 1, more_patterns;
1717       size_t num_pattern_levels = argp_args_levels (argp);
1718       char *pattern_levels = alloca (num_pattern_levels);
1719 
1720       memset (pattern_levels, 0, num_pattern_levels);
1721 
1722       do
1723         {
1724           int old_lm;
1725           int old_wm = __argp_fmtstream_set_wmargin (fs, uparams.usage_indent);
1726           char *levels = pattern_levels;
1727 
1728           if (first_pattern)
1729             __argp_fmtstream_printf (fs, "%s %s",
1730                                      dgettext (argp->argp_domain, "Usage:"),
1731                                      name);
1732           else
1733             __argp_fmtstream_printf (fs, "%s %s",
1734                                      dgettext (argp->argp_domain, "  or: "),
1735                                      name);
1736 
1737           
1738 
1739           old_lm = __argp_fmtstream_set_lmargin (fs, uparams.usage_indent);
1740 
1741           if (flags & ARGP_HELP_SHORT_USAGE)
1742             
1743             {
1744               if (hol->num_entries > 0)
1745                 __argp_fmtstream_puts (fs, dgettext (argp->argp_domain,
1746                                                      " [OPTION...]"));
1747             }
1748           else
1749             
1750             {
1751               hol_usage (hol, fs);
1752               flags |= ARGP_HELP_SHORT_USAGE; 
1753             }
1754 
1755           more_patterns = argp_args_usage (argp, state, &levels, 1, fs);
1756 
1757           __argp_fmtstream_set_wmargin (fs, old_wm);
1758           __argp_fmtstream_set_lmargin (fs, old_lm);
1759 
1760           __argp_fmtstream_putc (fs, '\n');
1761           anything = 1;
1762 
1763           first_pattern = 0;
1764         }
1765       while (more_patterns);
1766     }
1767 
1768   if (flags & ARGP_HELP_PRE_DOC)
1769     anything |= argp_doc (argp, state, 0, 0, 1, fs);
1770 
1771   if (flags & ARGP_HELP_SEE)
1772     {
1773       __argp_fmtstream_printf (fs, dgettext (argp->argp_domain, "\
1774 Try '%s --help' or '%s --usage' for more information.\n"),
1775                                name, name);
1776       anything = 1;
1777     }
1778 
1779   if (flags & ARGP_HELP_LONG)
1780     
1781     {
1782       
1783       if (hol->num_entries > 0)
1784         {
1785           if (anything)
1786             __argp_fmtstream_putc (fs, '\n');
1787           hol_help (hol, state, fs);
1788           anything = 1;
1789         }
1790     }
1791 
1792   if (flags & ARGP_HELP_POST_DOC)
1793     
1794     anything |= argp_doc (argp, state, 1, anything, 0, fs);
1795 
1796   if ((flags & ARGP_HELP_BUG_ADDR) && argp_program_bug_address)
1797     {
1798       if (anything)
1799         __argp_fmtstream_putc (fs, '\n');
1800       __argp_fmtstream_printf (fs, dgettext (argp->argp_domain,
1801                                              "Report bugs to %s.\n"),
1802                                argp_program_bug_address);
1803       anything = 1;
1804     }
1805 
1806 #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
1807   __funlockfile (stream);
1808 #endif
1809 
1810   if (hol)
1811     hol_free (hol);
1812 
1813   __argp_fmtstream_free (fs);
1814 }
1815 
1816 
1817 
1818 void __argp_help (const struct argp *argp, FILE *stream,
     
1819                   unsigned flags, char *name)
1820 {
1821   _help (argp, 0, stream, flags, name);
1822 }
1823 #ifdef weak_alias
1824 weak_alias (__argp_help, argp_help)
     
1825 #endif
1826 
1827 #if ! (defined _LIBC || HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME)
1828 char *
1829 __argp_short_program_name (void)
1830 {
1831 # if HAVE_DECL_PROGRAM_INVOCATION_NAME
1832   char *name = strrchr (program_invocation_name, '/');
1833   return name ? name + 1 : program_invocation_name;
1834 # else
1835   
1836 
1837 
1838 # if __GNUC__ || (__clang_major__ >= 4)
1839 #  warning No reasonable value to return
1840 # endif 
1841   return "";
1842 # endif
1843 }
1844 #endif
1845 
1846 
1847 
1848 void
1849 __argp_state_help (const struct argp_state *state, FILE *stream, unsigned flags)
     
1850 {
1851   if ((!state || ! (state->flags & ARGP_NO_ERRS)) && stream)
1852     {
1853       if (state && (state->flags & ARGP_LONG_ONLY))
1854         flags |= ARGP_HELP_LONG_ONLY;
1855 
1856       _help (state ? state->root_argp : 0, state, stream, flags,
1857              state ? state->name : __argp_short_program_name ());
1858 
1859       if (!state || ! (state->flags & ARGP_NO_EXIT))
1860         {
1861           if (flags & ARGP_HELP_EXIT_ERR)
1862             exit (argp_err_exit_status);
1863           if (flags & ARGP_HELP_EXIT_OK)
1864             exit (0);
1865         }
1866   }
1867 }
1868 #ifdef weak_alias
1869 weak_alias (__argp_state_help, argp_state_help)
     
1870 #endif
1871 
1872 
1873 
1874 
1875 void
1876 __argp_error (const struct argp_state *state, const char *fmt, ...)
1877 {
1878   if (!state || !(state->flags & ARGP_NO_ERRS))
1879     {
1880       FILE *stream = state ? state->err_stream : stderr;
1881 
1882       if (stream)
1883         {
1884           va_list ap;
1885 
1886 #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
1887           __flockfile (stream);
1888 #endif
1889 
1890           va_start (ap, fmt);
1891 
1892 #ifdef _LIBC
1893           char *buf;
1894 
1895           if (_IO_vasprintf (&buf, fmt, ap) < 0)
1896             buf = NULL;
1897 
1898           __fxprintf (stream, "%s: %s\n",
1899                       state ? state->name : __argp_short_program_name (), buf);
1900 
1901           free (buf);
1902 #else
1903           fputs_unlocked (state ? state->name : __argp_short_program_name (),
1904                           stream);
1905           putc_unlocked (':', stream);
1906           putc_unlocked (' ', stream);
1907 
1908           vfprintf (stream, fmt, ap);
1909 
1910           putc_unlocked ('\n', stream);
1911 #endif
1912 
1913           __argp_state_help (state, stream, ARGP_HELP_STD_ERR);
1914 
1915           va_end (ap);
1916 
1917 #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
1918           __funlockfile (stream);
1919 #endif
1920         }
1921     }
1922 }
1923 #ifdef weak_alias
1924 weak_alias (__argp_error, argp_error)
     
1925 #endif
1926 
1927 
1928 
1929 
1930 
1931 
1932 
1933 
1934 
1935 void
1936 __argp_failure (const struct argp_state *state, int status, int errnum,
1937                 const char *fmt, ...)
1938 {
1939   if (!state || !(state->flags & ARGP_NO_ERRS))
1940     {
1941       FILE *stream = state ? state->err_stream : stderr;
1942 
1943       if (stream)
1944         {
1945 #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
1946           __flockfile (stream);
1947 #endif
1948 
1949 #ifdef _LIBC
1950           __fxprintf (stream, "%s",
1951                       state ? state->name : __argp_short_program_name ());
1952 #else
1953           fputs_unlocked (state ? state->name : __argp_short_program_name (),
1954                           stream);
1955 #endif
1956 
1957           if (fmt)
1958             {
1959               va_list ap;
1960 
1961               va_start (ap, fmt);
1962 #ifdef _LIBC
1963               char *buf;
1964 
1965               if (_IO_vasprintf (&buf, fmt, ap) < 0)
1966                 buf = NULL;
1967 
1968               __fxprintf (stream, ": %s", buf);
1969 
1970               free (buf);
1971 #else
1972               putc_unlocked (':', stream);
1973               putc_unlocked (' ', stream);
1974 
1975               vfprintf (stream, fmt, ap);
1976 #endif
1977 
1978               va_end (ap);
1979             }
1980 
1981           if (errnum)
1982             {
1983               char buf[200];
1984 
1985 #ifdef _LIBC
1986               __fxprintf (stream, ": %s",
1987                           __strerror_r (errnum, buf, sizeof (buf)));
1988 #else
1989               char const *s = NULL;
1990               putc_unlocked (':', stream);
1991               putc_unlocked (' ', stream);
1992 # if GNULIB_STRERROR_R_POSIX || HAVE_DECL_STRERROR_R
1993 #  if !GNULIB_STRERROR_R_POSIX && STRERROR_R_CHAR_P
1994               s = __strerror_r (errnum, buf, sizeof buf);
1995 #  else
1996               if (__strerror_r (errnum, buf, sizeof buf) == 0)
1997                 s = buf;
1998 #  endif
1999 # endif
2000               if (! s && ! (s = strerror (errnum)))
2001                 s = dgettext (state->root_argp->argp_domain,
2002                               "Unknown system error");
2003               fputs_unlocked (s, stream);
2004 #endif
2005             }
2006 
2007 #if _LIBC
2008           if (_IO_fwide (stream, 0) > 0)
2009             putwc_unlocked (L'\n', stream);
2010           else
2011 #endif
2012             putc_unlocked ('\n', stream);
2013 
2014 #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
2015           __funlockfile (stream);
2016 #endif
2017 
2018           if (status && (!state || !(state->flags & ARGP_NO_EXIT)))
2019             exit (status);
2020         }
2021     }
2022 }
2023 #ifdef weak_alias
2024 weak_alias (__argp_failure, argp_failure)
2025 #endif