1 /* Command line option handling.
2 Copyright (C) 2002, 2003 Free Software Foundation, Inc.
3 Contributed by Neil Booth.
5 This file is part of GCC.
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
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
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
24 #include "coretypes.h"
27 #include "langhooks.h"
30 static size_t find_opt (const char *, int);
32 /* Perform a binary search to find which option the command-line INPUT
33 matches. Returns its index in the option array, and N_OPTS on
36 Complications arise since some options can be suffixed with an
37 argument, and multiple complete matches can occur, e.g. -pedantic
38 and -pedantic-errors. Also, some options are only accepted by some
39 languages. If a switch matches for a different language and
40 doesn't match any alternatives for the true front end, the index of
41 the matched switch is returned anyway. The caller should check for
44 find_opt (const char *input, int lang_mask)
48 size_t result = cl_options_count;
52 mx = cl_options_count;
58 opt_len = cl_options[md].opt_len;
59 comp = strncmp (input, cl_options[md].opt_text, opt_len);
67 /* The switch matches. It it an exact match? */
68 if (input[opt_len] == '\0')
74 /* If the switch takes no arguments this is not a proper
75 match, so we continue the search (e.g. input="stdc++"
77 if (!(cl_options[md].flags & CL_JOINED))
80 /* Is this switch valid for this front end? */
81 if (!(cl_options[md].flags & lang_mask))
83 /* If subsequently we don't find a better match,
84 return this and let the caller report it as a bad
90 /* Two scenarios remain: we have the switch's argument,
91 or we match a longer option. This can happen with
92 -iwithprefix and -withprefixbefore. The longest
93 possible option match succeeds.
95 Scan forwards, and return an exact match. Otherwise
96 return the longest valid option-accepting match (mx).
97 This loops at most twice with current options. */
99 for (md = md + 1; md < cl_options_count; md++)
101 opt_len = cl_options[md].opt_len;
102 if (strncmp (input, cl_options[md].opt_text, opt_len))
104 if (input[opt_len] == '\0')
106 if (cl_options[md].flags & lang_mask
107 && cl_options[md].flags & CL_JOINED)
119 /* Handle the switch beginning at ARGV, with ARGC remaining. */
121 handle_option (int argc, char **argv, int lang_mask)
124 const char *opt, *arg = 0;
127 int result = 0, temp;
128 const struct cl_option *option;
130 /* If the front end isn't yet converted, use the old hook. */
131 if (!lang_hooks.handle_option)
132 return (*lang_hooks.decode_option) (argc, argv);
136 /* Interpret "-" or a non-switch as a file name. */
137 if (opt[0] != '-' || opt[1] == '\0')
139 opt_index = cl_options_count;
145 /* Drop the "no-" from negative switches. */
146 if ((opt[1] == 'W' || opt[1] == 'f')
147 && opt[2] == 'n' && opt[3] == 'o' && opt[4] == '-')
149 size_t len = strlen (opt) - 3;
151 dup = xmalloc (len + 1);
154 memcpy (dup + 2, opt + 5, len - 2 + 1);
160 opt_index = find_opt (opt + 1, lang_mask);
161 if (opt_index == cl_options_count)
164 option = &cl_options[opt_index];
166 /* Reject negative form of switches that don't take negatives. */
167 if (!on && (option->flags & CL_REJECT_NEGATIVE))
170 /* We've recognised this switch. */
173 /* Sort out any argument the switch takes. */
174 if (option->flags & (CL_JOINED | CL_SEPARATE))
176 if (option->flags & CL_JOINED)
178 /* Have arg point to the original switch. This is because
179 some code, such as disable_builtin_function, expects its
180 argument to be persistent until the program exits. */
181 arg = argv[0] + cl_options[opt_index].opt_len + 1;
183 arg += strlen ("no-");
186 /* If we don't have an argument, and CL_SEPARATE, try the next
187 argument in the vector. */
188 if (!arg || (*arg == '\0' && option->flags & CL_SEPARATE))
194 /* Canonicalize missing arguments as NULL for the handler. */
200 temp = (*lang_hooks.handle_option) (opt_index, arg, on);