1 /* Command line option handling.
2 Copyright (C) 2006, 2007, 2008, 2010 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
23 #include "coretypes.h"
26 #include "diagnostic.h"
27 #include "tm.h" /* For WORD_SWITCH_TAKES_ARG and
28 TARGET_OPTION_TRANSLATE_TABLE. */
30 static void prune_options (struct cl_decoded_option **, unsigned int *);
32 /* Perform a binary search to find which option the command-line INPUT
33 matches. Returns its index in the option array, and
34 OPT_SPECIAL_unknown on failure.
36 This routine is quite subtle. A normal binary search is not good
37 enough because some options can be suffixed with an argument, and
38 multiple sub-matches can occur, e.g. input of "-pedantic" matching
39 the initial substring of "-pedantic-errors".
41 A more complicated example is -gstabs. It should match "-g" with
42 an argument of "stabs". Suppose, however, that the number and list
43 of switches are such that the binary search tests "-gen-decls"
44 before having tested "-g". This doesn't match, and as "-gen-decls"
45 is less than "-gstabs", it will become the lower bound of the
46 binary search range, and "-g" will never be seen. To resolve this
47 issue, 'optc-gen.awk' makes "-gen-decls" point, via the back_chain member,
48 to "-g" so that failed searches that end between "-gen-decls" and
49 the lexicographically subsequent switch know to go back and see if
50 "-g" causes a match (which it does in this example).
52 This search is done in such a way that the longest match for the
53 front end in question wins. If there is no match for the current
54 front end, the longest match for a different front end is returned
55 (or N_OPTS if none) and the caller emits an error message. */
57 find_opt (const char *input, int lang_mask)
59 size_t mn, mn_orig, mx, md, opt_len;
60 size_t match_wrong_lang;
64 mx = cl_options_count;
66 /* Find mn such this lexicographical inequality holds:
67 cl_options[mn] <= input < cl_options[mn + 1]. */
71 opt_len = cl_options[md].opt_len;
72 comp = strncmp (input, cl_options[md].opt_text + 1, opt_len);
82 /* This is the switch that is the best match but for a different
83 front end, or OPT_SPECIAL_unknown if there is no match at all. */
84 match_wrong_lang = OPT_SPECIAL_unknown;
86 /* Backtrace the chain of possible matches, returning the longest
87 one, if any, that fits best. With current GCC switches, this
88 loop executes at most twice. */
91 const struct cl_option *opt = &cl_options[mn];
93 /* Is the input either an exact match or a prefix that takes a
95 if (!strncmp (input, opt->opt_text + 1, opt->opt_len)
96 && (input[opt->opt_len] == '\0' || (opt->flags & CL_JOINED)))
98 /* If language is OK, return it. */
99 if (opt->flags & lang_mask)
102 /* If we haven't remembered a prior match, remember this
103 one. Any prior match is necessarily better. */
104 if (match_wrong_lang == OPT_SPECIAL_unknown)
105 match_wrong_lang = mn;
108 /* Try the next possibility. This is cl_options_count if there
110 mn = opt->back_chain;
112 while (mn != cl_options_count);
114 if (match_wrong_lang == OPT_SPECIAL_unknown && input[0] == '-')
116 /* Long options, starting "--", may be abbreviated if the
117 abbreviation is unambiguous. This only applies to options
118 not taking a joined argument, and abbreviations of "--option"
119 are permitted even if there is a variant "--option=". */
120 size_t mnc = mn_orig + 1;
121 size_t cmp_len = strlen (input);
122 while (mnc < cl_options_count
123 && strncmp (input, cl_options[mnc].opt_text + 1, cmp_len) == 0)
125 /* Option matching this abbreviation. OK if it is the first
126 match and that does not take a joined argument, or the
127 second match, taking a joined argument and with only '='
128 added to the first match; otherwise considered
130 if (mnc == mn_orig + 1
131 && !(cl_options[mnc].flags & CL_JOINED))
132 match_wrong_lang = mnc;
133 else if (mnc == mn_orig + 2
134 && match_wrong_lang == mn_orig + 1
135 && (cl_options[mnc].flags & CL_JOINED)
136 && (cl_options[mnc].opt_len
137 == cl_options[mn_orig + 1].opt_len + 1)
138 && strncmp (cl_options[mnc].opt_text + 1,
139 cl_options[mn_orig + 1].opt_text + 1,
140 cl_options[mn_orig + 1].opt_len) == 0)
141 ; /* OK, as long as there are no more matches. */
143 return OPT_SPECIAL_unknown;
148 /* Return the best wrong match, or OPT_SPECIAL_unknown if none. */
149 return match_wrong_lang;
152 /* If ARG is a non-negative integer made up solely of digits, return its
153 value, otherwise return -1. */
156 integral_argument (const char *arg)
160 while (*p && ISDIGIT (*p))
169 /* Return whether OPTION is OK for the language given by
172 option_ok_for_language (const struct cl_option *option,
173 unsigned int lang_mask)
175 if (!(option->flags & lang_mask))
177 else if ((option->flags & CL_TARGET)
178 && (option->flags & (CL_LANG_ALL | CL_DRIVER))
179 && !(option->flags & (lang_mask & ~CL_COMMON & ~CL_TARGET)))
180 /* Complain for target flag language mismatches if any languages
187 /* Fill in the canonical option part of *DECODED with an option
188 described by OPT_INDEX, ARG and VALUE. */
191 generate_canonical_option (size_t opt_index, const char *arg, int value,
192 struct cl_decoded_option *decoded)
194 const struct cl_option *option = &cl_options[opt_index];
195 const char *opt_text = option->opt_text;
198 && !(option->flags & CL_REJECT_NEGATIVE)
199 && (opt_text[1] == 'W' || opt_text[1] == 'f' || opt_text[1] == 'm'))
201 char *t = XNEWVEC (char, option->opt_len + 5);
207 memcpy (t + 5, opt_text + 2, option->opt_len);
211 decoded->canonical_option[2] = NULL;
212 decoded->canonical_option[3] = NULL;
216 if ((option->flags & CL_SEPARATE)
217 && !(option->flags & CL_SEPARATE_ALIAS))
219 decoded->canonical_option[0] = opt_text;
220 decoded->canonical_option[1] = arg;
221 decoded->canonical_option_num_elements = 2;
225 gcc_assert (option->flags & CL_JOINED);
226 decoded->canonical_option[0] = concat (opt_text, arg, NULL);
227 decoded->canonical_option[1] = NULL;
228 decoded->canonical_option_num_elements = 1;
233 decoded->canonical_option[0] = opt_text;
234 decoded->canonical_option[1] = NULL;
235 decoded->canonical_option_num_elements = 1;
239 /* Structure describing mappings from options on the command line to
240 options to look up with find_opt. */
243 /* Prefix of the option on the command line. */
245 /* If two argv elements are considered to be merged into one option,
246 prefix for the second element, otherwise NULL. */
248 /* The new prefix to map to. */
249 const char *new_prefix;
250 /* Whether at least one character is needed following opt1 or opt0
251 for this mapping to be used. (--optimize= is valid for -O, but
252 --warn- is not valid for -W.) */
253 bool another_char_needed;
254 /* Whether the original option is a negated form of the option
255 resulting from this map. */
258 static const struct option_map option_map[] =
260 { "-Wno-", NULL, "-W", false, true },
261 { "-fno-", NULL, "-f", false, true },
262 { "-mno-", NULL, "-m", false, true },
263 { "--debug=", NULL, "-g", false, false },
264 { "--machine-", NULL, "-m", true, false },
265 { "--machine-no-", NULL, "-m", false, true },
266 { "--machine=", NULL, "-m", false, false },
267 { "--machine=no-", NULL, "-m", false, true },
268 { "--machine", "", "-m", false, false },
269 { "--machine", "no-", "-m", false, true },
270 { "--optimize=", NULL, "-O", false, false },
271 { "--std=", NULL, "-std=", false, false },
272 { "--std", "", "-std=", false, false },
273 { "--warn-", NULL, "-W", true, false },
274 { "--warn-no-", NULL, "-W", false, true },
275 { "--", NULL, "-f", true, false },
276 { "--no-", NULL, "-f", false, true }
279 /* Decode the switch beginning at ARGV for the language indicated by
280 LANG_MASK (including CL_COMMON and CL_TARGET if applicable), into
281 the structure *DECODED. Returns the number of switches
285 decode_cmdline_option (const char **argv, unsigned int lang_mask,
286 struct cl_decoded_option *decoded)
291 unsigned int result = 1, i, extra_args;
295 const struct cl_option *option;
297 const char *warn_message = NULL;
298 bool separate_arg_flag;
299 bool joined_arg_flag;
300 bool have_separate_arg = false;
304 opt_index = find_opt (argv[0] + 1, lang_mask);
306 while (opt_index == OPT_SPECIAL_unknown
307 && i < ARRAY_SIZE (option_map))
309 const char *opt0 = option_map[i].opt0;
310 const char *opt1 = option_map[i].opt1;
311 const char *new_prefix = option_map[i].new_prefix;
312 bool another_char_needed = option_map[i].another_char_needed;
313 size_t opt0_len = strlen (opt0);
314 size_t opt1_len = (opt1 == NULL ? 0 : strlen (opt1));
315 size_t optn_len = (opt1 == NULL ? opt0_len : opt1_len);
316 size_t new_prefix_len = strlen (new_prefix);
318 extra_args = (opt1 == NULL ? 0 : 1);
319 value = !option_map[i].negated;
321 if (strncmp (argv[0], opt0, opt0_len) == 0
323 || (argv[1] != NULL && strncmp (argv[1], opt1, opt1_len) == 0))
324 && (!another_char_needed
325 || argv[extra_args][optn_len] != 0))
327 size_t arglen = strlen (argv[extra_args]);
330 adjust_len = (int) optn_len - (int) new_prefix_len;
331 dup = XNEWVEC (char, arglen + 1 - adjust_len);
332 memcpy (dup, new_prefix, new_prefix_len);
333 memcpy (dup + new_prefix_len, argv[extra_args] + optn_len,
334 arglen - optn_len + 1);
335 opt_index = find_opt (dup + 1, lang_mask);
341 if (opt_index == OPT_SPECIAL_unknown)
349 option = &cl_options[opt_index];
351 /* Reject negative form of switches that don't take negatives as
353 if (!value && (option->flags & CL_REJECT_NEGATIVE))
355 opt_index = OPT_SPECIAL_unknown;
356 errors |= CL_ERR_NEGATIVE;
361 result = extra_args + 1;
362 warn_message = option->warn_message;
364 /* Check to see if the option is disabled for this configuration. */
365 if (option->flags & CL_DISABLED)
366 errors |= CL_ERR_DISABLED;
368 /* Determine whether there may be a separate argument based on
369 whether this option is being processed for the driver. */
370 separate_arg_flag = ((option->flags & CL_SEPARATE)
371 && !((option->flags & CL_NO_DRIVER_ARG)
372 && (lang_mask & CL_DRIVER)));
373 joined_arg_flag = (option->flags & CL_JOINED) != 0;
375 /* Sort out any argument the switch takes. */
378 /* Have arg point to the original switch. This is because
379 some code, such as disable_builtin_function, expects its
380 argument to be persistent until the program exits. */
381 arg = argv[extra_args] + cl_options[opt_index].opt_len + 1 + adjust_len;
383 if (*arg == '\0' && !(option->flags & CL_MISSING_OK))
385 if (separate_arg_flag)
387 arg = argv[extra_args + 1];
388 result = extra_args + 2;
390 result = extra_args + 1;
392 have_separate_arg = true;
395 /* Missing argument. */
399 else if (separate_arg_flag)
401 arg = argv[extra_args + 1];
402 result = extra_args + 2;
404 result = extra_args + 1;
406 have_separate_arg = true;
409 if (arg == NULL && (separate_arg_flag || joined_arg_flag))
410 errors |= CL_ERR_MISSING_ARG;
412 /* Is this option an alias (or an ignored option, marked as an alias
413 of OPT_SPECIAL_ignore)? */
414 if (option->alias_target != N_OPTS
415 && (!(option->flags & CL_SEPARATE_ALIAS) || have_separate_arg))
417 size_t new_opt_index = option->alias_target;
419 if (new_opt_index == OPT_SPECIAL_ignore)
421 gcc_assert (option->alias_arg == NULL);
422 gcc_assert (option->neg_alias_arg == NULL);
423 opt_index = new_opt_index;
429 const struct cl_option *new_option = &cl_options[new_opt_index];
431 /* The new option must not be an alias itself. */
432 gcc_assert (new_option->alias_target == N_OPTS
433 || (new_option->flags & CL_SEPARATE_ALIAS));
435 if (option->neg_alias_arg)
437 gcc_assert (option->alias_arg != NULL);
438 gcc_assert (arg == NULL);
440 arg = option->alias_arg;
442 arg = option->neg_alias_arg;
445 else if (option->alias_arg)
447 gcc_assert (value == 1);
448 gcc_assert (arg == NULL);
449 arg = option->alias_arg;
452 opt_index = new_opt_index;
456 gcc_assert (!(option->flags & CL_REJECT_NEGATIVE));
458 /* Recompute what arguments are allowed. */
459 separate_arg_flag = ((option->flags & CL_SEPARATE)
460 && !((option->flags & CL_NO_DRIVER_ARG)
461 && (lang_mask & CL_DRIVER)));
462 joined_arg_flag = (option->flags & CL_JOINED) != 0;
464 if (!(errors & CL_ERR_MISSING_ARG))
466 if (separate_arg_flag || joined_arg_flag)
468 if ((option->flags & CL_MISSING_OK) && arg == NULL)
470 gcc_assert (arg != NULL);
473 gcc_assert (arg == NULL);
476 /* Recheck for warnings and disabled options. */
477 if (option->warn_message)
479 gcc_assert (warn_message == NULL);
480 warn_message = option->warn_message;
482 if (option->flags & CL_DISABLED)
483 errors |= CL_ERR_DISABLED;
487 /* Check if this is a switch for a different front end. */
488 if (!option_ok_for_language (option, lang_mask))
489 errors |= CL_ERR_WRONG_LANG;
491 /* If the switch takes an integer, convert it. */
492 if (arg && (option->flags & CL_UINTEGER))
494 value = integral_argument (arg);
496 errors |= CL_ERR_UINT_ARG;
500 decoded->opt_index = opt_index;
502 decoded->value = value;
503 decoded->errors = errors;
504 decoded->warn_message = warn_message;
506 if (opt_index == OPT_SPECIAL_unknown)
508 /* Skip the correct number of arguments for options handled
510 const char *popt ATTRIBUTE_UNUSED = argv[0] + 1;
512 gcc_assert (result == 1);
513 if (WORD_SWITCH_TAKES_ARG (popt))
514 result += WORD_SWITCH_TAKES_ARG (popt);
516 for (i = 1; i < result; i++)
524 gcc_assert (result >= 1 && result <= ARRAY_SIZE (decoded->canonical_option));
525 decoded->canonical_option_num_elements = result;
527 for (i = 0; i < ARRAY_SIZE (decoded->canonical_option); i++)
531 if (opt_index == OPT_SPECIAL_unknown)
532 decoded->canonical_option[i] = argv[i];
534 decoded->canonical_option[i] = NULL;
535 total_len += strlen (argv[i]) + 1;
538 decoded->canonical_option[i] = NULL;
540 if (opt_index != OPT_SPECIAL_unknown && opt_index != OPT_SPECIAL_ignore)
541 generate_canonical_option (opt_index, arg, value, decoded);
542 decoded->orig_option_with_args_text = p = XNEWVEC (char, total_len);
543 for (i = 0; i < result; i++)
545 size_t len = strlen (argv[i]);
547 memcpy (p, argv[i], len);
558 #ifdef TARGET_OPTION_TRANSLATE_TABLE
559 static const struct {
560 const char *const option_found;
561 const char *const replacements;
562 } target_option_translations[] =
564 TARGET_OPTION_TRANSLATE_TABLE,
569 /* Decode command-line options (ARGC and ARGV being the arguments of
570 main) into an array, setting *DECODED_OPTIONS to a pointer to that
571 array and *DECODED_OPTIONS_COUNT to the number of entries in the
572 array. The first entry in the array is always one for the program
573 name (OPT_SPECIAL_program_name). LANG_MASK indicates the language
574 flags applicable for decoding (including CL_COMMON and CL_TARGET if
575 those options should be considered applicable). Do not produce any
576 diagnostics or set state outside of these variables. */
579 decode_cmdline_options_to_array (unsigned int argc, const char **argv,
580 unsigned int lang_mask,
581 struct cl_decoded_option **decoded_options,
582 unsigned int *decoded_options_count)
584 unsigned int n, i, target_translate_from;
585 struct cl_decoded_option *opt_array;
586 unsigned int num_decoded_options;
587 bool argv_copied = false;
589 opt_array = XNEWVEC (struct cl_decoded_option, argc);
591 opt_array[0].opt_index = OPT_SPECIAL_program_name;
592 opt_array[0].warn_message = NULL;
593 opt_array[0].arg = argv[0];
594 opt_array[0].orig_option_with_args_text = argv[0];
595 opt_array[0].canonical_option_num_elements = 1;
596 opt_array[0].canonical_option[0] = argv[0];
597 opt_array[0].canonical_option[1] = NULL;
598 opt_array[0].canonical_option[2] = NULL;
599 opt_array[0].canonical_option[3] = NULL;
600 opt_array[0].value = 1;
601 opt_array[0].errors = 0;
602 num_decoded_options = 1;
604 target_translate_from = 1;
605 for (i = 1; i < argc; i += n)
607 const char *opt = argv[i];
609 /* Interpret "-" or a non-switch as a file name. */
610 if (opt[0] != '-' || opt[1] == '\0')
612 generate_option_input_file (opt, &opt_array[num_decoded_options]);
613 num_decoded_options++;
618 if (i >= target_translate_from && (lang_mask & CL_DRIVER))
620 #ifdef TARGET_OPTION_TRANSLATE_TABLE
624 target_option_translations[tott_idx].option_found;
627 if (strcmp (target_option_translations[tott_idx].option_found,
630 unsigned int spaces = 0;
635 for (sp = target_option_translations[tott_idx].replacements;
649 int new_argc = argc + spaces;
651 argv = XRESIZEVEC (const char *, argv, new_argc + 1);
654 const char **new_argv = XNEWVEC (const char *,
656 memcpy (new_argv, argv,
657 (argc + 1) * sizeof (const char *));
661 memmove (&argv[i] + spaces, &argv[i],
662 (argc + 1 - i) * sizeof (const char *));
664 opt_array = XRESIZEVEC (struct cl_decoded_option,
668 sp = target_option_translations[tott_idx].replacements;
678 while (*np != ' ' && *np)
685 target_translate_from = i + m;
686 gcc_assert (m == spaces + 1);
693 n = decode_cmdline_option (argv + i, lang_mask,
694 &opt_array[num_decoded_options]);
695 num_decoded_options++;
700 *decoded_options = opt_array;
701 *decoded_options_count = num_decoded_options;
702 prune_options (decoded_options, decoded_options_count);
705 /* Return true if NEXT_OPT_IDX cancels OPT_IDX. Return false if the
706 next one is the same as ORIG_NEXT_OPT_IDX. */
709 cancel_option (int opt_idx, int next_opt_idx, int orig_next_opt_idx)
711 /* An option can be canceled by the same option or an option with
713 if (cl_options [next_opt_idx].neg_index == opt_idx)
716 if (cl_options [next_opt_idx].neg_index != orig_next_opt_idx)
717 return cancel_option (opt_idx, cl_options [next_opt_idx].neg_index,
723 /* Filter out options canceled by the ones after them. */
726 prune_options (struct cl_decoded_option **decoded_options,
727 unsigned int *decoded_options_count)
729 unsigned int old_decoded_options_count = *decoded_options_count;
730 struct cl_decoded_option *old_decoded_options = *decoded_options;
731 unsigned int new_decoded_options_count;
732 struct cl_decoded_option *new_decoded_options
733 = XNEWVEC (struct cl_decoded_option, old_decoded_options_count);
735 const struct cl_option *option;
737 /* Remove arguments which are negated by others after them. */
738 new_decoded_options_count = 0;
739 for (i = 0; i < old_decoded_options_count; i++)
741 unsigned int j, opt_idx, next_opt_idx;
743 if (old_decoded_options[i].errors & ~CL_ERR_WRONG_LANG)
746 opt_idx = old_decoded_options[i].opt_index;
749 case OPT_SPECIAL_unknown:
750 case OPT_SPECIAL_ignore:
751 case OPT_SPECIAL_program_name:
752 case OPT_SPECIAL_input_file:
756 gcc_assert (opt_idx < cl_options_count);
757 option = &cl_options[opt_idx];
758 if (option->neg_index < 0)
761 /* Skip joined switches. */
762 if ((option->flags & CL_JOINED))
765 for (j = i + 1; j < old_decoded_options_count; j++)
767 if (old_decoded_options[j].errors & ~CL_ERR_WRONG_LANG)
769 next_opt_idx = old_decoded_options[j].opt_index;
770 if (next_opt_idx >= cl_options_count)
772 if (cl_options[next_opt_idx].neg_index < 0)
774 if ((cl_options[next_opt_idx].flags & CL_JOINED))
776 if (cancel_option (opt_idx, next_opt_idx, next_opt_idx))
779 if (j == old_decoded_options_count)
782 new_decoded_options[new_decoded_options_count]
783 = old_decoded_options[i];
784 new_decoded_options_count++;
790 free (old_decoded_options);
791 new_decoded_options = XRESIZEVEC (struct cl_decoded_option,
793 new_decoded_options_count);
794 *decoded_options = new_decoded_options;
795 *decoded_options_count = new_decoded_options_count;
798 /* Handle option DECODED for the language indicated by LANG_MASK,
799 using the handlers in HANDLERS and setting fields in OPTS and
800 OPTS_SET. KIND is the diagnostic_t if this is a diagnostics
801 option, DK_UNSPECIFIED otherwise. GENERATED_P is true for an
802 option generated as part of processing another option or otherwise
803 generated internally, false for one explicitly passed by the user.
804 Returns false if the switch was invalid. DC is the diagnostic
805 context for options affecting diagnostics state, or NULL. */
808 handle_option (struct gcc_options *opts,
809 struct gcc_options *opts_set,
810 const struct cl_decoded_option *decoded,
811 unsigned int lang_mask, int kind,
812 const struct cl_option_handlers *handlers,
813 bool generated_p, diagnostic_context *dc)
815 size_t opt_index = decoded->opt_index;
816 const char *arg = decoded->arg;
817 int value = decoded->value;
818 const struct cl_option *option = &cl_options[opt_index];
819 void *flag_var = option_flag_var (opt_index, opts);
823 set_option (opts, (generated_p ? NULL : opts_set),
824 opt_index, value, arg, kind, dc);
826 for (i = 0; i < handlers->num_handlers; i++)
827 if (option->flags & handlers->handlers[i].mask)
829 if (!handlers->handlers[i].handler (opts, opts_set, decoded,
830 lang_mask, kind, handlers))
833 handlers->post_handling_callback (decoded,
834 handlers->handlers[i].mask);
840 /* Like handle_option, but OPT_INDEX, ARG and VALUE describe the
841 option instead of DECODED. This is used for callbacks when one
842 option implies another instead of an option being decoded from the
846 handle_generated_option (struct gcc_options *opts,
847 struct gcc_options *opts_set,
848 size_t opt_index, const char *arg, int value,
849 unsigned int lang_mask, int kind,
850 const struct cl_option_handlers *handlers,
851 diagnostic_context *dc)
853 struct cl_decoded_option decoded;
855 generate_option (opt_index, arg, value, lang_mask, &decoded);
856 return handle_option (opts, opts_set, &decoded, lang_mask, kind, handlers,
860 /* Fill in *DECODED with an option described by OPT_INDEX, ARG and
861 VALUE for a front end using LANG_MASK. This is used when the
862 compiler generates options internally. */
865 generate_option (size_t opt_index, const char *arg, int value,
866 unsigned int lang_mask, struct cl_decoded_option *decoded)
868 const struct cl_option *option = &cl_options[opt_index];
870 decoded->opt_index = opt_index;
871 decoded->warn_message = NULL;
873 decoded->value = value;
874 decoded->errors = (option_ok_for_language (option, lang_mask)
876 : CL_ERR_WRONG_LANG);
878 generate_canonical_option (opt_index, arg, value, decoded);
879 switch (decoded->canonical_option_num_elements)
882 decoded->orig_option_with_args_text = decoded->canonical_option[0];
886 decoded->orig_option_with_args_text
887 = concat (decoded->canonical_option[0], " ",
888 decoded->canonical_option[1], NULL);
896 /* Fill in *DECODED with an option for input file FILE. */
899 generate_option_input_file (const char *file,
900 struct cl_decoded_option *decoded)
902 decoded->opt_index = OPT_SPECIAL_input_file;
903 decoded->warn_message = NULL;
905 decoded->orig_option_with_args_text = file;
906 decoded->canonical_option_num_elements = 1;
907 decoded->canonical_option[0] = file;
908 decoded->canonical_option[1] = NULL;
909 decoded->canonical_option[2] = NULL;
910 decoded->canonical_option[3] = NULL;
915 /* Handle the switch DECODED for the language indicated by LANG_MASK,
916 using the handlers in *HANDLERS and setting fields in OPTS and
917 OPTS_SET and using diagnostic context DC (if not NULL) for
918 diagnostic options. */
921 read_cmdline_option (struct gcc_options *opts,
922 struct gcc_options *opts_set,
923 struct cl_decoded_option *decoded,
924 unsigned int lang_mask,
925 const struct cl_option_handlers *handlers,
926 diagnostic_context *dc)
928 const struct cl_option *option;
929 const char *opt = decoded->orig_option_with_args_text;
931 if (decoded->warn_message)
932 warning (0, decoded->warn_message, opt);
934 if (decoded->opt_index == OPT_SPECIAL_unknown)
936 if (handlers->unknown_option_callback (decoded))
937 error ("unrecognized command line option %qs", decoded->arg);
941 if (decoded->opt_index == OPT_SPECIAL_ignore)
944 option = &cl_options[decoded->opt_index];
946 if (decoded->errors & CL_ERR_DISABLED)
948 error ("command line option %qs"
949 " is not supported by this configuration", opt);
953 if (decoded->errors & CL_ERR_WRONG_LANG)
955 handlers->wrong_lang_callback (decoded, lang_mask);
959 if (decoded->errors & CL_ERR_MISSING_ARG)
961 if (option->missing_argument_error)
962 error (option->missing_argument_error, opt);
964 error ("missing argument to %qs", opt);
968 if (decoded->errors & CL_ERR_UINT_ARG)
970 error ("argument to %qs should be a non-negative integer",
975 gcc_assert (!decoded->errors);
977 if (!handle_option (opts, opts_set, decoded, lang_mask, DK_UNSPECIFIED,
978 handlers, false, dc))
979 error ("unrecognized command line option %qs", opt);
982 /* Set any field in OPTS, and OPTS_SET if not NULL, for option
983 OPT_INDEX according to VALUE and ARG, diagnostic kind KIND, using
984 diagnostic context DC if not NULL for diagnostic
988 set_option (struct gcc_options *opts, struct gcc_options *opts_set,
989 int opt_index, int value, const char *arg, int kind,
990 diagnostic_context *dc)
992 const struct cl_option *option = &cl_options[opt_index];
993 void *flag_var = option_flag_var (opt_index, opts);
994 void *set_flag_var = NULL;
999 if (opts_set != NULL)
1000 set_flag_var = option_flag_var (opt_index, opts_set);
1002 switch (option->var_type)
1005 *(int *) flag_var = value;
1007 *(int *) set_flag_var = 1;
1011 *(int *) flag_var = (value
1013 : !option->var_value);
1015 *(int *) set_flag_var = 1;
1018 case CLVC_BIT_CLEAR:
1020 if ((value != 0) == (option->var_type == CLVC_BIT_SET))
1021 *(int *) flag_var |= option->var_value;
1023 *(int *) flag_var &= ~option->var_value;
1025 *(int *) set_flag_var |= option->var_value;
1029 *(const char **) flag_var = arg;
1031 *(const char **) set_flag_var = "";
1035 if ((diagnostic_t) kind != DK_UNSPECIFIED
1037 diagnostic_classify_diagnostic (dc, opt_index, (diagnostic_t) kind,
1041 /* Return the address of the flag variable for option OPT_INDEX in
1042 options structure OPTS, or NULL if there is no flag variable. */
1045 option_flag_var (int opt_index, struct gcc_options *opts)
1047 const struct cl_option *option = &cl_options[opt_index];
1049 if (option->flag_var_offset == (unsigned short) -1)
1051 return (void *)(((char *) opts) + option->flag_var_offset);