* sh.c (prepare_move_operand): Check if operand 0 is an invalid
[official-gcc.git] / gcc / opts.c
blob32620576f9aff789011c10802d75e2c0edabc845
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
10 version.
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.
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. */
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "tree.h"
27 #include "langhooks.h"
28 #include "opts.h"
29 #include "options.h"
30 #include "flags.h"
31 #include "toplev.h"
33 /* Value of the -G xx switch, and whether it was passed or not. */
34 unsigned HOST_WIDE_INT g_switch_value;
35 bool g_switch_set;
37 /* True if we should exit after parsing options. */
38 bool exit_after_options;
40 /* If -version. */
41 bool version_flag;
43 static size_t find_opt (const char *, int);
44 static int common_handle_option (size_t scode, const char *arg, int value);
46 /* Perform a binary search to find which option the command-line INPUT
47 matches. Returns its index in the option array, and N_OPTS on
48 failure.
50 Complications arise since some options can be suffixed with an
51 argument, and multiple complete matches can occur, e.g. -pedantic
52 and -pedantic-errors. Also, some options are only accepted by some
53 languages. If a switch matches for a different language and
54 doesn't match any alternatives for the true front end, the index of
55 the matched switch is returned anyway. The caller should check for
56 this case. */
57 static size_t
58 find_opt (const char *input, int lang_mask)
60 size_t md, mn, mx;
61 size_t opt_len;
62 size_t result = cl_options_count;
63 int comp;
65 mn = 0;
66 mx = cl_options_count;
68 while (mx > mn)
70 md = (mn + mx) / 2;
72 opt_len = cl_options[md].opt_len;
73 comp = strncmp (input, cl_options[md].opt_text, opt_len);
75 if (comp < 0)
76 mx = md;
77 else if (comp > 0)
78 mn = md + 1;
79 else
81 /* The switch matches. It it an exact match? */
82 if (input[opt_len] == '\0')
83 return md;
84 else
86 mn = md + 1;
88 /* If the switch takes no arguments this is not a proper
89 match, so we continue the search (e.g. input="stdc++"
90 match was "stdc"). */
91 if (!(cl_options[md].flags & CL_JOINED))
92 continue;
94 /* Is this switch valid for this front end? */
95 if (!(cl_options[md].flags & lang_mask))
97 /* If subsequently we don't find a better match,
98 return this and let the caller report it as a bad
99 match. */
100 result = md;
101 continue;
104 /* Two scenarios remain: we have the switch's argument,
105 or we match a longer option. This can happen with
106 -iwithprefix and -withprefixbefore. The longest
107 possible option match succeeds.
109 Scan forwards, and return an exact match. Otherwise
110 return the longest valid option-accepting match (mx).
111 This loops at most twice with current options. */
112 mx = md;
113 for (md = md + 1; md < cl_options_count; md++)
115 opt_len = cl_options[md].opt_len;
116 if (strncmp (input, cl_options[md].opt_text, opt_len))
117 break;
118 if (input[opt_len] == '\0')
119 return md;
120 if (cl_options[md].flags & lang_mask
121 && cl_options[md].flags & CL_JOINED)
122 mx = md;
125 return mx;
130 return result;
133 /* If ARG is a postive integer made up solely of digits, return its
134 value, otherwise return -1. */
135 static int
136 integral_argument (const char *arg)
138 const char *p = arg;
140 while (*p && ISDIGIT (*p))
141 p++;
143 if (*p == '\0')
144 return atoi (arg);
146 return -1;
149 /* Handle the switch beginning at ARGV, with ARGC remaining. */
151 handle_option (int argc ATTRIBUTE_UNUSED, char **argv, int lang_mask)
153 size_t opt_index;
154 const char *opt, *arg = 0;
155 char *dup = 0;
156 int value = 1;
157 int result = 0, temp;
158 const struct cl_option *option;
160 opt = argv[0];
162 /* Interpret "-" or a non-switch as a file name. */
163 if (opt[0] != '-' || opt[1] == '\0')
165 opt_index = cl_options_count;
166 arg = opt;
167 main_input_filename = opt;
168 result = (*lang_hooks.handle_option) (opt_index, arg, value);
170 else
172 /* Drop the "no-" from negative switches. */
173 if ((opt[1] == 'W' || opt[1] == 'f')
174 && opt[2] == 'n' && opt[3] == 'o' && opt[4] == '-')
176 size_t len = strlen (opt) - 3;
178 dup = xmalloc (len + 1);
179 dup[0] = '-';
180 dup[1] = opt[1];
181 memcpy (dup + 2, opt + 5, len - 2 + 1);
182 opt = dup;
183 value = 0;
186 opt_index = find_opt (opt + 1, lang_mask | CL_COMMON);
187 if (opt_index == cl_options_count)
188 goto done;
190 option = &cl_options[opt_index];
192 /* Reject negative form of switches that don't take negatives. */
193 if (!value && (option->flags & CL_REJECT_NEGATIVE))
194 goto done;
196 /* We've recognized this switch. */
197 result = 1;
199 /* Sort out any argument the switch takes. */
200 if (option->flags & CL_JOINED)
202 /* Have arg point to the original switch. This is because
203 some code, such as disable_builtin_function, expects its
204 argument to be persistent until the program exits. */
205 arg = argv[0] + cl_options[opt_index].opt_len + 1;
206 if (!value)
207 arg += strlen ("no-");
209 if (*arg == '\0' && !(option->flags & CL_MISSING_OK))
211 if (option->flags & CL_SEPARATE)
213 arg = argv[1];
214 result = 2;
216 else
217 /* Missing argument. */
218 arg = NULL;
221 else if (option->flags & CL_SEPARATE)
223 arg = argv[1];
224 result = 2;
227 /* If the switch takes an integer, convert it. */
228 if (arg && (option->flags & CL_UINTEGER))
230 value = integral_argument (arg);
231 if (value == -1)
233 error ("argument to \"-%s\" should be a non-negative integer",
234 option->opt_text);
235 goto done;
239 if (option->flags & lang_mask)
241 temp = (*lang_hooks.handle_option) (opt_index, arg, value);
242 if (temp <= 0)
243 result = temp;
246 if (result > 0 && (option->flags & CL_COMMON))
248 if (common_handle_option (opt_index, arg, value) == 0)
249 result = 0;
253 done:
254 if (dup)
255 free (dup);
256 return result;
259 /* Handle target- and language-independent options. Return zero to
260 generate an "unknown option" message. */
261 static int
262 common_handle_option (size_t scode, const char *arg,
263 int value ATTRIBUTE_UNUSED)
265 const struct cl_option *option = &cl_options[scode];
266 enum opt_code code = (enum opt_code) scode;
268 if (arg == NULL && (option->flags & (CL_JOINED | CL_SEPARATE)))
270 error ("missing argument to \"-%s\"", option->opt_text);
271 return 1;
274 switch (code)
276 default:
277 abort ();
279 case OPT__help:
280 display_help ();
281 exit_after_options = true;
282 break;
284 case OPT__target_help:
285 display_target_options ();
286 exit_after_options = true;
287 break;
289 case OPT__version:
290 print_version (stderr, "");
291 exit_after_options = true;
292 break;
294 case OPT_G:
295 g_switch_value = value;
296 g_switch_set = true;
297 break;
299 case OPT_aux_info:
300 case OPT_aux_info_:
301 aux_info_file_name = arg;
302 flag_gen_aux_info = 1;
303 break;
305 case OPT_auxbase:
306 aux_base_name = arg;
307 break;
309 case OPT_auxbase_strip:
311 char *tmp = xstrdup (arg);
312 strip_off_ending (tmp, strlen (tmp));
313 if (tmp[0])
314 aux_base_name = tmp;
316 break;
318 case OPT_d:
319 decode_d_option (arg);
320 break;
322 case OPT_dumpbase:
323 dump_base_name = arg;
324 break;
326 case OPT_o:
327 asm_file_name = arg;
328 break;
330 case OPT_p:
331 profile_flag = 1;
332 break;
334 case OPT_pedantic:
335 pedantic = 1;
336 break;
338 case OPT_pedantic_errors:
339 flag_pedantic_errors = pedantic = 1;
340 break;
342 case OPT_quiet:
343 quiet_flag = 1;
344 break;
346 case OPT_version:
347 version_flag = 1;
348 break;
350 case OPT_w:
351 inhibit_warnings = 1;
352 break;
355 return 1;