OSDN Git Service

* c-common.c: Fix comment formatting.
[pf3gnuchains/gcc-fork.git] / gcc / opts.c
1 /* Command line option handling.
2    Copyright (C) 2002, 2003 Free Software Foundation, Inc.
3    Contributed by Neil Booth.
4
5 This file is part of GCC.
6
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
11
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING.  If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA.  */
21
22 #include "config.h"
23 #include "system.h"
24 #include "intl.h"
25 #include "coretypes.h"
26 #include "tm.h"
27 #include "tree.h"
28 #include "rtl.h"
29 #include "ggc.h"
30 #include "output.h"
31 #include "langhooks.h"
32 #include "opts.h"
33 #include "options.h"
34 #include "flags.h"
35 #include "toplev.h"
36 #include "params.h"
37 #include "diagnostic.h"
38 #include "tm_p.h"               /* For OPTIMIZATION_OPTIONS.  */
39 #include "insn-attr.h"          /* For INSN_SCHEDULING.  */
40
41 /* Value of the -G xx switch, and whether it was passed or not.  */
42 unsigned HOST_WIDE_INT g_switch_value;
43 bool g_switch_set;
44
45 /* True if we should exit after parsing options.  */
46 bool exit_after_options;
47
48 /* If -version.  */
49 bool version_flag;
50
51 /* Print various extra warnings.  -W/-Wextra.  */
52 bool extra_warnings;
53
54 /* Don't print warning messages.  -w.  */
55 bool inhibit_warnings;
56
57 /* Treat warnings as errors.  -Werror.  */
58 bool warnings_are_errors;
59
60 /* Warn if a function returns an aggregate, since there are often
61    incompatible calling conventions for doing this.  */
62 bool warn_aggregate_return;
63
64 /* Nonzero means warn about pointer casts that increase the required
65    alignment of the target type (and might therefore lead to a crash
66    due to a misaligned access).  */
67 bool warn_cast_align;
68
69 /* Nonzero means warn about uses of __attribute__((deprecated))
70    declarations.  */
71 bool warn_deprecated_decl = true;
72
73 /* Warn when an optimization pass is disabled.  */
74 bool warn_disabled_optimization;
75
76 /* Nonzero means warn if inline function is too large.  */
77 bool warn_inline;
78
79 /* True to warn about any objects definitions whose size is larger
80    than N bytes.  Also want about function definitions whose returned
81    values are larger than N bytes, where N is `larger_than_size'.  */
82 bool warn_larger_than;
83 HOST_WIDE_INT larger_than_size;
84
85 /* Warn about functions which might be candidates for attribute noreturn.  */
86 bool warn_missing_noreturn;
87
88 /* True to warn about code which is never reached.  */
89 bool warn_notreached;
90
91 /* Warn if packed attribute on struct is unnecessary and inefficient.  */
92 bool warn_packed;
93
94 /* Warn when gcc pads a structure to an alignment boundary.  */
95 bool warn_padded;
96
97 /* True means warn about all declarations which shadow others.  */
98 bool warn_shadow;
99
100 /* Nonzero means warn about constructs which might not be
101    strict-aliasing safe.  */
102 bool warn_strict_aliasing;
103
104 /* True to warn if a switch on an enum, that does not have a default
105    case, fails to have a case for every enum value.  */
106 bool warn_switch;
107
108 /* Warn if a switch does not have a default case.  */
109 bool warn_switch_default;
110
111 /* Warn if a switch on an enum fails to have a case for every enum
112    value (regardless of the presence or otherwise of a default case).  */
113 bool warn_switch_enum;
114
115 /* Don't suppress warnings from system headers.  -Wsystem-headers.  */
116 bool warn_system_headers;
117
118 /* True to warn about variables used before they are initialized.  */
119 int warn_uninitialized;
120
121 /* True to warn about unused variables, functions et.al.  */
122 bool warn_unused_function;
123 bool warn_unused_label;
124 bool warn_unused_parameter;
125 bool warn_unused_variable;
126 bool warn_unused_value;
127
128 /* Hack for cooperation between set_Wunused and set_Wextra.  */
129 static bool maybe_warn_unused_parameter;
130
131 /* Type(s) of debugging information we are producing (if any).  See
132    flags.h for the definitions of the different possible types of
133    debugging information.  */
134 enum debug_info_type write_symbols = NO_DEBUG;
135
136 /* Level of debugging information we are producing.  See flags.h for
137    the definitions of the different possible levels.  */
138 enum debug_info_level debug_info_level = DINFO_LEVEL_NONE;
139
140 /* Nonzero means use GNU-only extensions in the generated symbolic
141    debugging information.  Currently, this only has an effect when
142    write_symbols is set to DBX_DEBUG, XCOFF_DEBUG, or DWARF_DEBUG.  */
143 bool use_gnu_debug_info_extensions;
144
145 /* Columns of --help display.  */
146 static unsigned int columns = 80;
147
148 /* What to print when a switch has no documentation.  */
149 static const char undocumented_msg[] = N_("This switch lacks documentation");
150
151 /* Input file names.  */
152 const char **in_fnames;
153 unsigned num_in_fnames;
154
155 static size_t find_opt (const char *, int);
156 static int common_handle_option (size_t scode, const char *arg, int value);
157 static void handle_param (const char *);
158 static void set_Wextra (int);
159 static unsigned int handle_option (const char **argv, unsigned int lang_mask);
160 static char *write_langs (unsigned int lang_mask);
161 static void complain_wrong_lang (const char *, const struct cl_option *,
162                                  unsigned int lang_mask);
163 static void handle_options (unsigned int, const char **, unsigned int);
164 static void wrap_help (const char *help, const char *item, unsigned int);
165 static void print_help (void);
166 static void print_param_help (void);
167 static void print_filtered_help (unsigned int flag);
168 static unsigned int print_switch (const char *text, unsigned int indent);
169 static void set_debug_level (enum debug_info_type type, int extended,
170                              const char *arg);
171
172 /* Perform a binary search to find which option the command-line INPUT
173    matches.  Returns its index in the option array, and N_OPTS
174    (cl_options_count) on failure.
175
176    This routine is quite subtle.  A normal binary search is not good
177    enough because some options can be suffixed with an argument, and
178    multiple sub-matches can occur, e.g. input of "-pedantic" matching
179    the initial substring of "-pedantic-errors".
180
181    A more complicated example is -gstabs.  It should match "-g" with
182    an argument of "stabs".  Suppose, however, that the number and list
183    of switches are such that the binary search tests "-gen-decls"
184    before having tested "-g".  This doesn't match, and as "-gen-decls"
185    is less than "-gstabs", it will become the lower bound of the
186    binary search range, and "-g" will never be seen.  To resolve this
187    issue, opts.sh makes "-gen-decls" point, via the back_chain member,
188    to "-g" so that failed searches that end between "-gen-decls" and
189    the lexicographically subsequent switch know to go back and see if
190    "-g" causes a match (which it does in this example).
191
192    This search is done in such a way that the longest match for the
193    front end in question wins.  If there is no match for the current
194    front end, the longest match for a different front end is returned
195    (or N_OPTS if none) and the caller emits an error message.  */
196 static size_t
197 find_opt (const char *input, int lang_mask)
198 {
199   size_t mn, mx, md, opt_len;
200   size_t match_wrong_lang;
201   int comp;
202
203   mn = 0;
204   mx = cl_options_count;
205
206   /* Find mn such this lexicographical inequality holds:
207      cl_options[mn] <= input < cl_options[mn + 1].  */
208   while (mx - mn > 1)
209     {
210       md = (mn + mx) / 2;
211       opt_len = cl_options[md].opt_len;
212       comp = strncmp (input, cl_options[md].opt_text + 1, opt_len);
213
214       if (comp < 0)
215         mx = md;
216       else
217         mn = md;
218     }
219
220   /* This is the switch that is the best match but for a different
221      front end, or cl_options_count if there is no match at all.  */
222   match_wrong_lang = cl_options_count;
223
224   /* Backtrace the chain of possible matches, returning the longest
225      one, if any, that fits best.  With current GCC switches, this
226      loop executes at most twice.  */
227   do
228     {
229       const struct cl_option *opt = &cl_options[mn];
230
231       /* Is this switch a prefix of the input?  */
232       if (!strncmp (input, opt->opt_text + 1, opt->opt_len))
233         {
234           /* If language is OK, and the match is exact or the switch
235              takes a joined argument, return it.  */
236           if ((opt->flags & lang_mask)
237               && (input[opt->opt_len] == '\0' || (opt->flags & CL_JOINED)))
238             return mn;
239
240           /* If we haven't remembered a prior match, remember this
241              one.  Any prior match is necessarily better.  */
242           if (match_wrong_lang == cl_options_count)
243             match_wrong_lang = mn;
244         }
245
246       /* Try the next possibility.  This is cl_options_count if there
247          are no more.  */
248       mn = opt->back_chain;
249     }
250   while (mn != cl_options_count);
251
252   /* Return the best wrong match, or cl_options_count if none.  */
253   return match_wrong_lang;
254 }
255
256 /* If ARG is a non-negative integer made up solely of digits, return its
257    value, otherwise return -1.  */
258 static int
259 integral_argument (const char *arg)
260 {
261   const char *p = arg;
262
263   while (*p && ISDIGIT (*p))
264     p++;
265
266   if (*p == '\0')
267     return atoi (arg);
268
269   return -1;
270 }
271
272 /* Return a malloced slash-separated list of languages in MASK.  */
273 static char *
274 write_langs (unsigned int mask)
275 {
276   unsigned int n = 0, len = 0;
277   const char *lang_name;
278   char *result;
279
280   for (n = 0; (lang_name = lang_names[n]) != 0; n++)
281     if (mask & (1U << n))
282       len += strlen (lang_name) + 1;
283
284   result = xmalloc (len);
285   len = 0;
286   for (n = 0; (lang_name = lang_names[n]) != 0; n++)
287     if (mask & (1U << n))
288       {
289         if (len)
290           result[len++] = '/';
291         strcpy (result + len, lang_name);
292         len += strlen (lang_name);
293       }
294
295   result[len] = 0;
296
297   return result;
298 }
299
300 /* Complain that switch OPT_INDEX does not apply to this front end.  */
301 static void
302 complain_wrong_lang (const char *text, const struct cl_option *option,
303                      unsigned int lang_mask)
304 {
305   char *ok_langs, *bad_lang;
306
307   ok_langs = write_langs (option->flags);
308   bad_lang = write_langs (lang_mask);
309
310   /* Eventually this should become a hard error IMO.  */
311   warning ("command line option \"%s\" is valid for %s but not for %s",
312            text, ok_langs, bad_lang);
313
314   free (ok_langs);
315   free (bad_lang);
316 }
317
318 /* Handle the switch beginning at ARGV for the language indicated by
319    LANG_MASK.  Returns the number of switches consumed.  */
320 static unsigned int
321 handle_option (const char **argv, unsigned int lang_mask)
322 {
323   size_t opt_index;
324   const char *opt, *arg = 0;
325   char *dup = 0;
326   int value = 1;
327   unsigned int result = 0;
328   const struct cl_option *option;
329
330   opt = argv[0];
331
332   /* Drop the "no-" from negative switches.  */
333   if ((opt[1] == 'W' || opt[1] == 'f')
334       && opt[2] == 'n' && opt[3] == 'o' && opt[4] == '-')
335     {
336       size_t len = strlen (opt) - 3;
337
338       dup = xmalloc (len + 1);
339       dup[0] = '-';
340       dup[1] = opt[1];
341       memcpy (dup + 2, opt + 5, len - 2 + 1);
342       opt = dup;
343       value = 0;
344     }
345
346   opt_index = find_opt (opt + 1, lang_mask | CL_COMMON);
347   if (opt_index == cl_options_count)
348     goto done;
349
350   option = &cl_options[opt_index];
351
352   /* Reject negative form of switches that don't take negatives as
353      unrecognized.  */
354   if (!value && (option->flags & CL_REJECT_NEGATIVE))
355     goto done;
356
357   /* We've recognized this switch.  */
358   result = 1;
359
360   /* Sort out any argument the switch takes.  */
361   if (option->flags & CL_JOINED)
362     {
363       /* Have arg point to the original switch.  This is because
364          some code, such as disable_builtin_function, expects its
365          argument to be persistent until the program exits.  */
366       arg = argv[0] + cl_options[opt_index].opt_len + 1;
367       if (!value)
368         arg += strlen ("no-");
369
370       if (*arg == '\0' && !(option->flags & CL_MISSING_OK))
371         {
372           if (option->flags & CL_SEPARATE)
373             {
374               arg = argv[1];
375               result = 2;
376             }
377           else
378             /* Missing argument.  */
379             arg = NULL;
380         }
381     }
382   else if (option->flags & CL_SEPARATE)
383     {
384       arg = argv[1];
385       result = 2;
386     }
387
388   /* Now we've swallowed any potential argument, complain if this
389      is a switch for a different front end.  */
390   if (!(option->flags & (lang_mask | CL_COMMON)))
391     {
392       complain_wrong_lang (argv[0], option, lang_mask);
393       goto done;
394     }
395
396   if (arg == NULL && (option->flags & (CL_JOINED | CL_SEPARATE)))
397     {
398       if (!(*lang_hooks.missing_argument) (opt, opt_index))
399         error ("missing argument to \"%s\"", opt);
400       goto done;
401     }
402
403   /* If the switch takes an integer, convert it.  */
404   if (arg && (option->flags & CL_UINTEGER))
405     {
406       value = integral_argument (arg);
407       if (value == -1)
408         {
409           error ("argument to \"%s\" should be a non-negative integer",
410                  option->opt_text);
411           goto done;
412         }
413     }
414
415   if (option->flags & lang_mask)
416     if ((*lang_hooks.handle_option) (opt_index, arg, value) == 0)
417       result = 0;
418
419   if (result && (option->flags & CL_COMMON))
420     if (common_handle_option (opt_index, arg, value) == 0)
421       result = 0;
422
423  done:
424   if (dup)
425     free (dup);
426   return result;
427 }
428
429 /* Decode and handle the vector of command line options.  LANG_MASK
430    contains has a single bit set representing the current
431    language.  */
432 static void
433 handle_options (unsigned int argc, const char **argv, unsigned int lang_mask)
434 {
435   unsigned int n, i;
436
437   for (i = 1; i < argc; i += n)
438     {
439       const char *opt = argv[i];
440
441       /* Interpret "-" or a non-switch as a file name.  */
442       if (opt[0] != '-' || opt[1] == '\0')
443         {
444           main_input_filename = opt;
445           add_input_filename (opt);
446           n = 1;
447           continue;
448         }
449
450       n = handle_option (argv + i, lang_mask);
451
452       if (!n)
453         {
454           n = 1;
455           error ("unrecognized command line option \"%s\"", opt);
456         }
457     }
458 }
459
460 /* Handle FILENAME from the command line.  */
461 void
462 add_input_filename (const char *filename)
463 {
464   num_in_fnames++;
465   in_fnames = xrealloc (in_fnames, num_in_fnames * sizeof (in_fnames[0]));
466   in_fnames[num_in_fnames - 1] = filename;
467 }
468
469 /* Parse command line options and set default flag values.  Do minimal
470    options processing.  */
471 void
472 decode_options (unsigned int argc, const char **argv)
473 {
474   unsigned int i, lang_mask;
475
476   /* Perform language-specific options initialization.  */
477   lang_mask = (*lang_hooks.init_options) (argc, argv);
478
479   lang_hooks.initialize_diagnostics (global_dc);
480
481   /* Scan to see what optimization level has been specified.  That will
482      determine the default value of many flags.  */
483   for (i = 1; i < argc; i++)
484     {
485       if (!strcmp (argv[i], "-O"))
486         {
487           optimize = 1;
488           optimize_size = 0;
489         }
490       else if (argv[i][0] == '-' && argv[i][1] == 'O')
491         {
492           /* Handle -Os, -O2, -O3, -O69, ...  */
493           const char *p = &argv[i][2];
494
495           if ((p[0] == 's') && (p[1] == 0))
496             {
497               optimize_size = 1;
498
499               /* Optimizing for size forces optimize to be 2.  */
500               optimize = 2;
501             }
502           else
503             {
504               const int optimize_val = read_integral_parameter (p, p - 2, -1);
505               if (optimize_val != -1)
506                 {
507                   optimize = optimize_val;
508                   optimize_size = 0;
509                 }
510             }
511         }
512     }
513
514   if (!optimize)
515     {
516       flag_merge_constants = 0;
517     }
518
519   if (optimize >= 1)
520     {
521       flag_defer_pop = 1;
522       flag_thread_jumps = 1;
523 #ifdef DELAY_SLOTS
524       flag_delayed_branch = 1;
525 #endif
526 #ifdef CAN_DEBUG_WITHOUT_FP
527       flag_omit_frame_pointer = 1;
528 #endif
529       flag_guess_branch_prob = 1;
530       flag_cprop_registers = 1;
531       flag_loop_optimize = 1;
532       flag_crossjumping = 1;
533       flag_if_conversion = 1;
534       flag_if_conversion2 = 1;
535     }
536
537   if (optimize >= 2)
538     {
539       flag_optimize_sibling_calls = 1;
540       flag_cse_follow_jumps = 1;
541       flag_cse_skip_blocks = 1;
542       flag_gcse = 1;
543       flag_expensive_optimizations = 1;
544       flag_strength_reduce = 1;
545       flag_rerun_cse_after_loop = 1;
546       flag_rerun_loop_opt = 1;
547       flag_caller_saves = 1;
548       flag_force_mem = 1;
549       flag_peephole2 = 1;
550 #ifdef INSN_SCHEDULING
551       flag_schedule_insns = 1;
552       flag_schedule_insns_after_reload = 1;
553 #endif
554       flag_regmove = 1;
555       flag_strict_aliasing = 1;
556       flag_delete_null_pointer_checks = 1;
557       flag_reorder_blocks = 1;
558       flag_reorder_functions = 1;
559     }
560
561   if (optimize >= 3)
562     {
563       flag_inline_functions = 1;
564       flag_rename_registers = 1;
565       flag_unswitch_loops = 1;
566       flag_unit_at_a_time = 1;
567     }
568
569   if (optimize < 2 || optimize_size)
570     {
571       align_loops = 1;
572       align_jumps = 1;
573       align_labels = 1;
574       align_functions = 1;
575
576       /* Don't reorder blocks when optimizing for size because extra
577          jump insns may be created; also barrier may create extra padding.
578
579          More correctly we should have a block reordering mode that tried
580          to minimize the combined size of all the jumps.  This would more
581          or less automatically remove extra jumps, but would also try to
582          use more short jumps instead of long jumps.  */
583       flag_reorder_blocks = 0;
584     }
585
586   /* Initialize whether `char' is signed.  */
587   flag_signed_char = DEFAULT_SIGNED_CHAR;
588 #ifdef DEFAULT_SHORT_ENUMS
589   /* Initialize how much space enums occupy, by default.  */
590   flag_short_enums = DEFAULT_SHORT_ENUMS;
591 #endif
592
593   /* Initialize target_flags before OPTIMIZATION_OPTIONS so the latter can
594      modify it.  */
595   target_flags = 0;
596   set_target_switch ("");
597
598   /* Unwind tables are always present in an ABI-conformant IA-64
599      object file, so the default should be ON.  */
600 #ifdef IA64_UNWIND_INFO
601   flag_unwind_tables = IA64_UNWIND_INFO;
602 #endif
603
604 #ifdef OPTIMIZATION_OPTIONS
605   /* Allow default optimizations to be specified on a per-machine basis.  */
606   OPTIMIZATION_OPTIONS (optimize, optimize_size);
607 #endif
608
609   handle_options (argc, argv, lang_mask);
610
611   if (flag_pie)
612     flag_pic = flag_pie;
613   if (flag_pic && !flag_pie)
614     flag_shlib = 1;
615
616   if (flag_no_inline == 2)
617     flag_no_inline = 0;
618   else
619     flag_really_no_inline = flag_no_inline;
620
621   /* Set flag_no_inline before the post_options () hook.  The C front
622      ends use it to determine tree inlining defaults.  FIXME: such
623      code should be lang-independent when all front ends use tree
624      inlining, in which case it, and this condition, should be moved
625      to the top of process_options() instead.  */
626   if (optimize == 0)
627     {
628       /* Inlining does not work if not optimizing,
629          so force it not to be done.  */
630       flag_no_inline = 1;
631       warn_inline = 0;
632
633       /* The c_decode_option function and decode_option hook set
634          this to `2' if -Wall is used, so we can avoid giving out
635          lots of errors for people who don't realize what -Wall does.  */
636       if (warn_uninitialized == 1)
637         warning ("-Wuninitialized is not supported without -O");
638     }
639
640   if (flag_really_no_inline == 2)
641     flag_really_no_inline = flag_no_inline;
642 }
643
644 /* Handle target- and language-independent options.  Return zero to
645    generate an "unknown option" message.  */
646 static int
647 common_handle_option (size_t scode, const char *arg,
648                       int value ATTRIBUTE_UNUSED)
649 {
650   enum opt_code code = (enum opt_code) scode;
651
652   switch (code)
653     {
654     default:
655       abort ();
656
657     case OPT__help:
658       print_help ();
659       exit_after_options = true;
660       break;
661
662     case OPT__param:
663       handle_param (arg);
664       break;
665
666     case OPT__target_help:
667       display_target_options ();
668       exit_after_options = true;
669       break;
670
671     case OPT__version:
672       print_version (stderr, "");
673       exit_after_options = true;
674       break;
675
676     case OPT_G:
677       g_switch_value = value;
678       g_switch_set = true;
679       break;
680
681     case OPT_O:
682     case OPT_Os:
683       /* Currently handled in a prescan.  */
684       break;
685
686     case OPT_W:
687       /* For backward compatibility, -W is the same as -Wextra.  */
688       set_Wextra (value);
689       break;
690
691     case OPT_Waggregate_return:
692       warn_aggregate_return = value;
693       break;
694
695     case OPT_Wcast_align:
696       warn_cast_align = value;
697       break;
698
699     case OPT_Wdeprecated_declarations:
700       warn_deprecated_decl = value;
701       break;
702
703     case OPT_Wdisabled_optimization:
704       warn_disabled_optimization = value;
705       break;
706
707     case OPT_Werror:
708       warnings_are_errors = value;
709       break;
710
711     case OPT_Wextra:
712       set_Wextra (value);
713       break;
714
715     case OPT_Winline:
716       warn_inline = value;
717       break;
718
719     case OPT_Wlarger_than_:
720       larger_than_size = value;
721       warn_larger_than = value != -1;
722       break;
723
724     case OPT_Wmissing_noreturn:
725       warn_missing_noreturn = value;
726       break;
727
728     case OPT_Wpacked:
729       warn_packed = value;
730       break;
731
732     case OPT_Wpadded:
733       warn_padded = value;
734       break;
735
736     case OPT_Wshadow:
737       warn_shadow = value;
738       break;
739
740     case OPT_Wstrict_aliasing:
741       warn_strict_aliasing = value;
742       break;
743
744     case OPT_Wswitch:
745       warn_switch = value;
746       break;
747
748     case OPT_Wswitch_default:
749       warn_switch_default = value;
750       break;
751
752     case OPT_Wswitch_enum:
753       warn_switch_enum = value;
754       break;
755
756     case OPT_Wsystem_headers:
757       warn_system_headers = value;
758       break;
759
760     case OPT_Wuninitialized:
761       warn_uninitialized = value;
762       break;
763
764     case OPT_Wunreachable_code:
765       warn_notreached = value;
766       break;
767
768     case OPT_Wunused:
769       set_Wunused (value);
770       break;
771
772     case OPT_Wunused_function:
773       warn_unused_function = value;
774       break;
775
776     case OPT_Wunused_label:
777       warn_unused_label = value;
778       break;
779
780     case OPT_Wunused_parameter:
781       warn_unused_parameter = value;
782       break;
783
784     case OPT_Wunused_value:
785       warn_unused_value = value;
786       break;
787
788     case OPT_Wunused_variable:
789       warn_unused_variable = value;
790       break;
791
792     case OPT_aux_info:
793     case OPT_aux_info_:
794       aux_info_file_name = arg;
795       flag_gen_aux_info = 1;
796       break;
797
798     case OPT_auxbase:
799       aux_base_name = arg;
800       break;
801
802     case OPT_auxbase_strip:
803       {
804         char *tmp = xstrdup (arg);
805         strip_off_ending (tmp, strlen (tmp));
806         if (tmp[0])
807           aux_base_name = tmp;
808       }
809       break;
810
811     case OPT_d:
812       decode_d_option (arg);
813       break;
814
815     case OPT_dumpbase:
816       dump_base_name = arg;
817       break;
818
819     case OPT_fPIC:
820       flag_pic = value + value;
821       break;
822
823     case OPT_fPIE:
824       flag_pie = value + value;
825       break;
826
827     case OPT_falign_functions:
828       align_functions = !value;
829       break;
830
831     case OPT_falign_functions_:
832       align_functions = value;
833       break;
834
835     case OPT_falign_jumps:
836       align_jumps = !value;
837       break;
838
839     case OPT_falign_jumps_:
840       align_jumps = value;
841       break;
842
843     case OPT_falign_labels:
844       align_labels = !value;
845       break;
846
847     case OPT_falign_labels_:
848       align_labels = value;
849       break;
850
851     case OPT_falign_loops:
852       align_loops = !value;
853       break;
854
855     case OPT_falign_loops_:
856       align_loops = value;
857       break;
858
859     case OPT_fargument_alias:
860       flag_argument_noalias = !value;
861       break;
862
863     case OPT_fargument_noalias:
864       flag_argument_noalias = value;
865       break;
866
867     case OPT_fargument_noalias_global:
868       flag_argument_noalias = value + value;
869       break;
870
871     case OPT_fasynchronous_unwind_tables:
872       flag_asynchronous_unwind_tables = value;
873       break;
874
875     case OPT_fbounds_check:
876       flag_bounds_check = value;
877       break;
878
879     case OPT_fbranch_count_reg:
880       flag_branch_on_count_reg = value;
881       break;
882
883     case OPT_fbranch_probabilities:
884       flag_branch_probabilities = value;
885       break;
886
887     case OPT_fbranch_target_load_optimize:
888       flag_branch_target_load_optimize = value;
889       break;
890
891     case OPT_fbranch_target_load_optimize2:
892       flag_branch_target_load_optimize2 = value;
893       break;
894
895     case OPT_fcall_used_:
896       fix_register (arg, 0, 1);
897       break;
898
899     case OPT_fcall_saved_:
900       fix_register (arg, 0, 0);
901       break;
902
903     case OPT_fcaller_saves:
904       flag_caller_saves = value;
905       break;
906
907     case OPT_fcommon:
908       flag_no_common = !value;
909       break;
910
911     case OPT_fcprop_registers:
912       flag_cprop_registers = value;
913       break;
914
915     case OPT_fcrossjumping:
916       flag_crossjumping = value;
917       break;
918
919     case OPT_fcse_follow_jumps:
920       flag_cse_follow_jumps = value;
921       break;
922
923     case OPT_fcse_skip_blocks:
924       flag_cse_skip_blocks = value;
925       break;
926
927     case OPT_fdata_sections:
928       flag_data_sections = value;
929       break;
930
931     case OPT_fdefer_pop:
932       flag_defer_pop = value;
933       break;
934
935     case OPT_fdelayed_branch:
936       flag_delayed_branch = value;
937       break;
938
939     case OPT_fdelete_null_pointer_checks:
940       flag_delete_null_pointer_checks = value;
941       break;
942
943     case OPT_fdiagnostics_show_location_:
944       if (!strcmp (arg, "once"))
945         diagnostic_prefixing_rule (global_dc) = DIAGNOSTICS_SHOW_PREFIX_ONCE;
946       else if (!strcmp (arg, "every-line"))
947         diagnostic_prefixing_rule (global_dc)
948           = DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE;
949       else
950         return 0;
951       break;
952
953     case OPT_fdump_unnumbered:
954       flag_dump_unnumbered = value;
955       break;
956
957     case OPT_feliminate_dwarf2_dups:
958       flag_eliminate_dwarf2_dups = value;
959       break;
960
961     case OPT_feliminate_unused_debug_types:
962       flag_eliminate_unused_debug_types = value;
963       break;
964
965     case OPT_feliminate_unused_debug_symbols:
966       flag_debug_only_used_symbols = value;
967       break;
968
969     case OPT_fexceptions:
970       flag_exceptions = value;
971       break;
972
973     case OPT_fexpensive_optimizations:
974       flag_expensive_optimizations = value;
975       break;
976
977     case OPT_ffast_math:
978       set_fast_math_flags (value);
979       break;
980
981     case OPT_ffinite_math_only:
982       flag_finite_math_only = value;
983       break;
984
985     case OPT_ffixed_:
986       fix_register (arg, 1, 1);
987       break;
988
989     case OPT_ffunction_cse:
990       flag_no_function_cse = !value;
991       break;
992
993     case OPT_ffloat_store:
994       flag_float_store = value;
995       break;
996
997     case OPT_fforce_addr:
998       flag_force_addr = value;
999       break;
1000
1001     case OPT_fforce_mem:
1002       flag_force_mem = value;
1003       break;
1004
1005     case OPT_ffunction_sections:
1006       flag_function_sections = value;
1007       break;
1008
1009     case OPT_fgcse:
1010       flag_gcse = value;
1011       break;
1012
1013     case OPT_fgcse_lm:
1014       flag_gcse_lm = value;
1015       break;
1016
1017     case OPT_fgcse_sm:
1018       flag_gcse_sm = value;
1019       break;
1020
1021     case OPT_fgnu_linker:
1022       flag_gnu_linker = value;
1023       break;
1024
1025     case OPT_fguess_branch_probability:
1026       flag_guess_branch_prob = value;
1027       break;
1028
1029     case OPT_fident:
1030       flag_no_ident = !value;
1031       break;
1032
1033     case OPT_fif_conversion:
1034       flag_if_conversion = value;
1035       break;
1036
1037     case OPT_fif_conversion2:
1038       flag_if_conversion2 = value;
1039       break;
1040
1041     case OPT_finhibit_size_directive:
1042       flag_inhibit_size_directive = value;
1043       break;
1044
1045     case OPT_finline:
1046       flag_no_inline = !value;
1047       break;
1048
1049     case OPT_finline_functions:
1050       flag_inline_functions = value;
1051       break;
1052
1053     case OPT_finline_limit_:
1054     case OPT_finline_limit_eq:
1055       set_param_value ("max-inline-insns", value);
1056       set_param_value ("max-inline-insns-single", value / 2);
1057       set_param_value ("max-inline-insns-auto", value / 2);
1058       set_param_value ("max-inline-insns-rtl", value);
1059       if (value / 4 < MIN_INLINE_INSNS)
1060         {
1061           if (value / 4 > 10)
1062             set_param_value ("min-inline-insns", value / 4);
1063           else
1064             set_param_value ("min-inline-insns", 10);
1065         }
1066       break;
1067
1068     case OPT_finstrument_functions:
1069       flag_instrument_function_entry_exit = value;
1070       break;
1071
1072     case OPT_fkeep_inline_functions:
1073       flag_keep_inline_functions =value;
1074       break;
1075
1076     case OPT_fkeep_static_consts:
1077       flag_keep_static_consts = value;
1078       break;
1079
1080     case OPT_fleading_underscore:
1081       flag_leading_underscore = value;
1082       break;
1083
1084     case OPT_floop_optimize:
1085       flag_loop_optimize = value;
1086       break;
1087
1088     case OPT_fmath_errno:
1089       flag_errno_math = value;
1090       break;
1091
1092     case OPT_fmem_report:
1093       mem_report = value;
1094       break;
1095
1096     case OPT_fmerge_all_constants:
1097       flag_merge_constants = value + value;
1098       break;
1099
1100     case OPT_fmerge_constants:
1101       flag_merge_constants = value;
1102       break;
1103
1104     case OPT_fmessage_length_:
1105       pp_set_line_maximum_length (global_dc->printer, value);
1106       break;
1107
1108     case OPT_fmove_all_movables:
1109       flag_move_all_movables = value;
1110       break;
1111
1112     case OPT_fnew_ra:
1113       flag_new_regalloc = value;
1114       break;
1115
1116     case OPT_fnon_call_exceptions:
1117       flag_non_call_exceptions = value;
1118       break;
1119
1120     case OPT_fold_unroll_all_loops:
1121       flag_old_unroll_all_loops = value;
1122       break;
1123
1124     case OPT_fold_unroll_loops:
1125       flag_old_unroll_loops = value;
1126       break;
1127
1128     case OPT_fomit_frame_pointer:
1129       flag_omit_frame_pointer = value;
1130       break;
1131
1132     case OPT_foptimize_register_move:
1133       flag_regmove = value;
1134       break;
1135
1136     case OPT_foptimize_sibling_calls:
1137       flag_optimize_sibling_calls = value;
1138       break;
1139
1140     case OPT_fpack_struct:
1141       flag_pack_struct = value;
1142       break;
1143
1144     case OPT_fpeel_loops:
1145       flag_peel_loops = value;
1146       break;
1147
1148     case OPT_fpcc_struct_return:
1149       flag_pcc_struct_return = value;
1150       break;
1151
1152     case OPT_fpeephole:
1153       flag_no_peephole = !value;
1154       break;
1155
1156     case OPT_fpeephole2:
1157       flag_peephole2 = value;
1158       break;
1159
1160     case OPT_fpic:
1161       flag_pic = value;
1162       break;
1163
1164     case OPT_fpie:
1165       flag_pie = value;
1166       break;
1167
1168     case OPT_fprefetch_loop_arrays:
1169       flag_prefetch_loop_arrays = value;
1170       break;
1171
1172     case OPT_fprofile:
1173       profile_flag = value;
1174       break;
1175
1176     case OPT_fprofile_arcs:
1177       profile_arc_flag = value;
1178       break;
1179
1180     case OPT_frandom_seed:
1181       /* The real switch is -fno-random-seed.  */
1182       if (value)
1183         return 0;
1184       flag_random_seed = NULL;
1185       break;
1186
1187     case OPT_frandom_seed_:
1188       flag_random_seed = arg;
1189       break;
1190
1191     case OPT_freduce_all_givs:
1192       flag_reduce_all_givs = value;
1193       break;
1194
1195     case OPT_freg_struct_return:
1196       flag_pcc_struct_return = !value;
1197       break;
1198
1199     case OPT_fregmove:
1200       flag_regmove = value;
1201       break;
1202
1203     case OPT_frename_registers:
1204       flag_rename_registers = value;
1205       break;
1206
1207     case OPT_freorder_blocks:
1208       flag_reorder_blocks = value;
1209       break;
1210
1211     case OPT_freorder_functions:
1212       flag_reorder_functions = value;
1213       break;
1214
1215     case OPT_frerun_cse_after_loop:
1216       flag_rerun_cse_after_loop = value;
1217       break;
1218
1219     case OPT_frerun_loop_opt:
1220       flag_rerun_loop_opt = value;
1221       break;
1222
1223     case OPT_fsched_interblock:
1224       flag_schedule_interblock= value;
1225       break;
1226
1227     case OPT_fsched_spec:
1228       flag_schedule_speculative = value;
1229       break;
1230
1231     case OPT_fsched_spec_load:
1232       flag_schedule_speculative_load = value;
1233       break;
1234
1235     case OPT_fsched_spec_load_dangerous:
1236       flag_schedule_speculative_load_dangerous = value;
1237       break;
1238
1239     case OPT_fsched_verbose_:
1240 #ifdef INSN_SCHEDULING
1241       fix_sched_param ("verbose", arg);
1242       break;
1243 #else
1244       return 0;
1245 #endif
1246
1247     case OPT_fsched2_use_superblocks:
1248       flag_sched2_use_superblocks = value;
1249       break;
1250
1251     case OPT_fsched2_use_traces:
1252       flag_sched2_use_traces = value;
1253       break;
1254
1255     case OPT_fschedule_insns:
1256       flag_schedule_insns = value;
1257       break;
1258
1259     case OPT_fschedule_insns2:
1260       flag_schedule_insns_after_reload = value;
1261       break;
1262
1263     case OPT_fshared_data:
1264       flag_shared_data = value;
1265       break;
1266
1267     case OPT_fsignaling_nans:
1268       flag_signaling_nans = value;
1269       break;
1270
1271     case OPT_fsingle_precision_constant:
1272       flag_single_precision_constant = value;
1273       break;
1274
1275     case OPT_fssa:
1276       flag_ssa = value;
1277       break;
1278
1279     case OPT_fssa_ccp:
1280       flag_ssa_ccp = value;
1281       break;
1282
1283     case OPT_fssa_dce:
1284       flag_ssa_dce = value;
1285       break;
1286
1287     case OPT_fstack_check:
1288       flag_stack_check = value;
1289       break;
1290
1291     case OPT_fstack_limit:
1292       /* The real switch is -fno-stack-limit.  */
1293       if (value)
1294         return 0;
1295       stack_limit_rtx = NULL_RTX;
1296       break;
1297
1298     case OPT_fstack_limit_register_:
1299       {
1300         int reg = decode_reg_name (arg);
1301         if (reg < 0)
1302           error ("unrecognized register name \"%s\"", arg);
1303         else
1304           stack_limit_rtx = gen_rtx_REG (Pmode, reg);
1305       }
1306       break;
1307
1308     case OPT_fstack_limit_symbol_:
1309       stack_limit_rtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (arg));
1310       break;
1311
1312     case OPT_fstrength_reduce:
1313       flag_strength_reduce = value;
1314       break;
1315
1316     case OPT_fstrict_aliasing:
1317       flag_strict_aliasing = value;
1318       break;
1319
1320     case OPT_fsyntax_only:
1321       flag_syntax_only = value;
1322       break;
1323
1324     case OPT_ftest_coverage:
1325       flag_test_coverage = value;
1326       break;
1327
1328     case OPT_fthread_jumps:
1329       flag_thread_jumps = value;
1330       break;
1331
1332     case OPT_ftime_report:
1333       time_report = value;
1334       break;
1335
1336     case OPT_ftls_model_:
1337       if (!strcmp (arg, "global-dynamic"))
1338         flag_tls_default = TLS_MODEL_GLOBAL_DYNAMIC;
1339       else if (!strcmp (arg, "local-dynamic"))
1340         flag_tls_default = TLS_MODEL_LOCAL_DYNAMIC;
1341       else if (!strcmp (arg, "initial-exec"))
1342         flag_tls_default = TLS_MODEL_INITIAL_EXEC;
1343       else if (!strcmp (arg, "local-exec"))
1344         flag_tls_default = TLS_MODEL_LOCAL_EXEC;
1345       else
1346         warning ("unknown tls-model \"%s\"", arg);
1347       break;
1348
1349     case OPT_ftracer:
1350       flag_tracer = value;
1351       break;
1352
1353     case OPT_ftrapping_math:
1354       flag_trapping_math = value;
1355       break;
1356
1357     case OPT_ftrapv:
1358       flag_trapv = value;
1359       break;
1360
1361     case OPT_funit_at_a_time:
1362       flag_unit_at_a_time = value;
1363       break;
1364
1365     case OPT_funroll_all_loops:
1366       flag_unroll_all_loops = value;
1367       break;
1368
1369     case OPT_funroll_loops:
1370       flag_unroll_loops = value;
1371       break;
1372
1373     case OPT_funsafe_math_optimizations:
1374       flag_unsafe_math_optimizations = value;
1375       break;
1376
1377     case OPT_funswitch_loops:
1378       flag_unswitch_loops = value;
1379       break;
1380
1381     case OPT_funwind_tables:
1382       flag_unwind_tables = value;
1383       break;
1384
1385     case OPT_fverbose_asm:
1386       flag_verbose_asm = value;
1387       break;
1388       
1389     case OPT_fwrapv:
1390       flag_wrapv = value;
1391       break;
1392
1393     case OPT_fwritable_strings:
1394       flag_writable_strings = value;
1395       break;
1396
1397     case OPT_fzero_initialized_in_bss:
1398       flag_zero_initialized_in_bss = value;
1399       break;
1400
1401     case OPT_g:
1402       set_debug_level (NO_DEBUG, DEFAULT_GDB_EXTENSIONS, arg);
1403       break;
1404
1405     case OPT_gcoff:
1406       set_debug_level (SDB_DEBUG, false, arg);
1407       break;
1408
1409     case OPT_gdwarf:
1410       if (*arg)
1411         {
1412           error ("use -gdwarf -gN for DWARF v1 level N, "
1413                  "and -gdwarf-2 for DWARF v2" );
1414           break;
1415         }
1416
1417       /* Fall through.  */
1418     case OPT_gdwarf_:
1419       set_debug_level (DWARF_DEBUG, code == OPT_gdwarf_, arg);
1420       break;
1421
1422     case OPT_gdwarf_2:
1423       set_debug_level (DWARF2_DEBUG, false, arg);
1424       break;
1425
1426     case OPT_ggdb:
1427       set_debug_level (NO_DEBUG, 2, arg);
1428       break;
1429
1430     case OPT_gstabs:
1431     case OPT_gstabs_:
1432       set_debug_level (DBX_DEBUG, code == OPT_gstabs_, arg);
1433       break;
1434
1435     case OPT_gvms:
1436       set_debug_level (VMS_DEBUG, false, arg);
1437       break;
1438
1439     case OPT_gxcoff:
1440     case OPT_gxcoff_:
1441       set_debug_level (XCOFF_DEBUG, code == OPT_gxcoff_, arg);
1442       break;
1443
1444     case OPT_m:
1445       set_target_switch (arg);
1446       break;
1447
1448     case OPT_o:
1449       asm_file_name = arg;
1450       break;
1451
1452     case OPT_p:
1453       profile_flag = 1;
1454       break;
1455
1456     case OPT_pedantic:
1457       pedantic = 1;
1458       break;
1459
1460     case OPT_pedantic_errors:
1461       flag_pedantic_errors = pedantic = 1;
1462       break;
1463
1464     case OPT_quiet:
1465       quiet_flag = 1;
1466       break;
1467
1468     case OPT_version:
1469       version_flag = 1;
1470       break;
1471
1472     case OPT_w:
1473       inhibit_warnings = true;
1474       break;      
1475     }
1476
1477   return 1;
1478 }
1479
1480 /* Handle --param NAME=VALUE.  */
1481 static void
1482 handle_param (const char *carg)
1483 {
1484   char *equal, *arg;
1485   int value;
1486
1487   arg = xstrdup (carg);
1488   equal = strchr (arg, '=');
1489   if (!equal)
1490     error ("%s: --param arguments should be of the form NAME=VALUE", arg);
1491   else
1492     {
1493       value = integral_argument (equal + 1);
1494       if (value == -1)
1495         error ("invalid --param value `%s'", equal + 1);
1496       else
1497         {
1498           *equal = '\0';
1499           set_param_value (arg, value);
1500         }
1501     }
1502
1503   free (arg);
1504 }
1505
1506 /* Handle -W and -Wextra.  */
1507 static void
1508 set_Wextra (int setting)
1509 {
1510   extra_warnings = setting;
1511   warn_unused_value = setting;
1512   warn_unused_parameter = (setting && maybe_warn_unused_parameter);
1513
1514   /* We save the value of warn_uninitialized, since if they put
1515      -Wuninitialized on the command line, we need to generate a
1516      warning about not using it without also specifying -O.  */
1517   if (setting == 0)
1518     warn_uninitialized = 0;
1519   else if (warn_uninitialized != 1)
1520     warn_uninitialized = 2;
1521 }
1522
1523 /* Initialize unused warning flags.  */
1524 void
1525 set_Wunused (int setting)
1526 {
1527   warn_unused_function = setting;
1528   warn_unused_label = setting;
1529   /* Unused function parameter warnings are reported when either
1530      ``-Wextra -Wunused'' or ``-Wunused-parameter'' is specified.
1531      Thus, if -Wextra has already been seen, set warn_unused_parameter;
1532      otherwise set maybe_warn_extra_parameter, which will be picked up
1533      by set_Wextra.  */
1534   maybe_warn_unused_parameter = setting;
1535   warn_unused_parameter = (setting && extra_warnings);
1536   warn_unused_variable = setting;
1537   warn_unused_value = setting;
1538 }
1539
1540 /* The following routines are useful in setting all the flags that
1541    -ffast-math and -fno-fast-math imply.  */
1542 void
1543 set_fast_math_flags (int set)
1544 {
1545   flag_trapping_math = !set;
1546   flag_unsafe_math_optimizations = set;
1547   flag_finite_math_only = set;
1548   flag_errno_math = !set;
1549   if (set)
1550     flag_signaling_nans = 0;
1551 }
1552
1553 /* Return true iff flags are set as if -ffast-math.  */
1554 bool
1555 fast_math_flags_set_p (void)
1556 {
1557   return (!flag_trapping_math
1558           && flag_unsafe_math_optimizations
1559           && flag_finite_math_only
1560           && !flag_errno_math);
1561 }
1562
1563 /* Handle a debug output -g switch.  EXTENDED is true or false to support
1564    extended output (2 is special and means "-ggdb" was given).  */
1565 static void
1566 set_debug_level (enum debug_info_type type, int extended, const char *arg)
1567 {
1568   static bool type_explicit;
1569
1570   use_gnu_debug_info_extensions = extended;
1571
1572   if (type == NO_DEBUG)
1573     {
1574       if (write_symbols == NO_DEBUG)
1575         {
1576           write_symbols = PREFERRED_DEBUGGING_TYPE;
1577
1578           if (extended == 2)
1579             {
1580 #ifdef DWARF2_DEBUGGING_INFO
1581               write_symbols = DWARF2_DEBUG;
1582 #elif defined DBX_DEBUGGING_INFO
1583               write_symbols = DBX_DEBUG;
1584 #endif
1585             }
1586
1587           if (write_symbols == NO_DEBUG)
1588             warning ("target system does not support debug output");
1589         }
1590     }
1591   else
1592     {
1593       /* Does it conflict with an already selected type?  */
1594       if (type_explicit && write_symbols != NO_DEBUG && type != write_symbols)
1595         error ("debug format \"%s\" conflicts with prior selection",
1596                debug_type_names[type]);
1597       write_symbols = type;
1598       type_explicit = true;
1599     }
1600
1601   /* A debug flag without a level defaults to level 2.  */
1602   if (*arg == '\0')
1603     {
1604       if (!debug_info_level)
1605         debug_info_level = 2;
1606     }
1607   else
1608     {
1609       debug_info_level = integral_argument (arg);
1610       if (debug_info_level == (unsigned int) -1)
1611         error ("unrecognised debug output level \"%s\"", arg);
1612       else if (debug_info_level > 3)
1613         error ("debug output level %s is too high", arg);
1614     }
1615 }
1616
1617 /* Output --help text.  */
1618 static void
1619 print_help (void)
1620 {
1621   size_t i;
1622   const char *p;
1623
1624   GET_ENVIRONMENT (p, "COLUMNS");
1625   if (p)
1626     {
1627       int value = atoi (p);
1628       if (value > 0)
1629         columns = value;
1630     }
1631
1632   puts (_("The following options are language-independent:\n"));
1633
1634   print_filtered_help (CL_COMMON);
1635   print_param_help ();
1636
1637   for (i = 0; lang_names[i]; i++)
1638     {
1639       printf (_("The %s front end recognizes the following options:\n\n"),
1640               lang_names[i]);
1641       print_filtered_help (1U << i);
1642     }
1643
1644   display_target_options ();
1645 }
1646
1647 /* Print the help for --param.  */
1648 static void
1649 print_param_help (void)
1650 {
1651   size_t i;
1652
1653   puts (_("The --param option recognizes the following as parameters:\n"));
1654
1655   for (i = 0; i < LAST_PARAM; i++)
1656     {
1657       const char *help = compiler_params[i].help;
1658       const char *param = compiler_params[i].option;
1659
1660       if (help == NULL || *help == '\0')
1661         help = undocumented_msg;
1662
1663       /* Get the translation.  */
1664       help = _(help);
1665
1666       wrap_help (help, param, strlen (param));
1667     }
1668
1669   putchar ('\n');
1670 }
1671
1672 /* Print help for a specific front-end, etc.  */
1673 static void
1674 print_filtered_help (unsigned int flag)
1675 {
1676   unsigned int i, len, filter, indent = 0;
1677   bool duplicates = false;
1678   const char *help, *opt, *tab;
1679   static char *printed;
1680
1681   if (flag == CL_COMMON)
1682     {
1683       filter = flag;
1684       if (!printed)
1685         printed = xmalloc (cl_options_count);
1686       memset (printed, 0, cl_options_count);
1687     }
1688   else
1689     {
1690       /* Don't print COMMON options twice.  */
1691       filter = flag | CL_COMMON;
1692
1693       for (i = 0; i < cl_options_count; i++)
1694         {
1695           if ((cl_options[i].flags & filter) != flag)
1696             continue;
1697
1698           /* Skip help for internal switches.  */
1699           if (cl_options[i].flags & CL_UNDOCUMENTED)
1700             continue;
1701
1702           /* Skip switches that have already been printed, mark them to be
1703              listed later.  */
1704           if (printed[i])
1705             {
1706               duplicates = true;
1707               indent = print_switch (cl_options[i].opt_text, indent);
1708             }
1709         }
1710
1711       if (duplicates)
1712         {
1713           putchar ('\n');
1714           putchar ('\n');
1715         }
1716     }
1717
1718   for (i = 0; i < cl_options_count; i++)
1719     {
1720       if ((cl_options[i].flags & filter) != flag)
1721         continue;
1722
1723       /* Skip help for internal switches.  */
1724       if (cl_options[i].flags & CL_UNDOCUMENTED)
1725         continue;
1726
1727       /* Skip switches that have already been printed.  */
1728       if (printed[i])
1729         continue;
1730
1731       printed[i] = true;
1732
1733       help = cl_options[i].help;
1734       if (!help)
1735         help = undocumented_msg;
1736
1737       /* Get the translation.  */
1738       help = _(help);
1739
1740       tab = strchr (help, '\t');
1741       if (tab)
1742         {
1743           len = tab - help;
1744           opt = help;
1745           help = tab + 1;
1746         }
1747       else
1748         {
1749           opt = cl_options[i].opt_text;
1750           len = strlen (opt);
1751         }
1752
1753       wrap_help (help, opt, len);
1754     }
1755
1756   putchar ('\n');
1757 }
1758
1759 /* Output ITEM, of length ITEM_WIDTH, in the left column, followed by
1760    word-wrapped HELP in a second column.  */
1761 static unsigned int
1762 print_switch (const char *text, unsigned int indent)
1763 {
1764   unsigned int len = strlen (text) + 1; /* trailing comma */
1765
1766   if (indent)
1767     {
1768       putchar (',');
1769       if (indent + len > columns)
1770         {
1771           putchar ('\n');
1772           putchar (' ');
1773           indent = 1;
1774         }
1775     }
1776   else
1777     putchar (' ');
1778
1779   putchar (' ');
1780   fputs (text, stdout);
1781
1782   return indent + len + 1;
1783 }
1784
1785 /* Output ITEM, of length ITEM_WIDTH, in the left column, followed by
1786    word-wrapped HELP in a second column.  */
1787 static void
1788 wrap_help (const char *help, const char *item, unsigned int item_width)
1789 {
1790   unsigned int col_width = 27;
1791   unsigned int remaining, room, len;
1792
1793   remaining = strlen (help);
1794
1795   do
1796     {
1797       room = columns - 3 - MAX (col_width, item_width);
1798       if (room > columns)
1799         room = 0;
1800       len = remaining;
1801
1802       if (room < len)
1803         {
1804           unsigned int i;
1805
1806           for (i = 0; help[i]; i++)
1807             {
1808               if (i >= room && len != remaining)
1809                 break;
1810               if (help[i] == ' ')
1811                 len = i;
1812               else if ((help[i] == '-' || help[i] == '/')
1813                        && help[i + 1] != ' '
1814                        && ISALPHA (help[i - 1]))
1815                 len = i + 1;
1816             }
1817         }
1818
1819       printf( "  %-*.*s %.*s\n", col_width, item_width, item, len, help);
1820       item_width = 0;
1821       while (help[len] == ' ')
1822         len++;
1823       help += len;
1824       remaining -= len;
1825     }
1826   while (remaining);
1827 }