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"
33 /* Value of the -G xx switch, and whether it was passed or not. */
34 unsigned HOST_WIDE_INT g_switch_value
;
37 /* True if we should exit after parsing options. */
38 bool exit_after_options
;
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
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
58 find_opt (const char *input
, int lang_mask
)
62 size_t result
= cl_options_count
;
66 mx
= cl_options_count
;
72 opt_len
= cl_options
[md
].opt_len
;
73 comp
= strncmp (input
, cl_options
[md
].opt_text
, opt_len
);
81 /* The switch matches. It it an exact match? */
82 if (input
[opt_len
] == '\0')
88 /* If the switch takes no arguments this is not a proper
89 match, so we continue the search (e.g. input="stdc++"
91 if (!(cl_options
[md
].flags
& CL_JOINED
))
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
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. */
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
))
118 if (input
[opt_len
] == '\0')
120 if (cl_options
[md
].flags
& lang_mask
121 && cl_options
[md
].flags
& CL_JOINED
)
133 /* If ARG is a postive integer made up solely of digits, return its
134 value, otherwise return -1. */
136 integral_argument (const char *arg
)
140 while (*p
&& ISDIGIT (*p
))
149 /* Handle the switch beginning at ARGV, with ARGC remaining. */
151 handle_option (int argc ATTRIBUTE_UNUSED
, char **argv
, int lang_mask
)
154 const char *opt
, *arg
= 0;
157 int result
= 0, temp
;
158 const struct cl_option
*option
;
162 /* Interpret "-" or a non-switch as a file name. */
163 if (opt
[0] != '-' || opt
[1] == '\0')
165 opt_index
= cl_options_count
;
167 main_input_filename
= opt
;
168 result
= (*lang_hooks
.handle_option
) (opt_index
, arg
, value
);
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);
181 memcpy (dup
+ 2, opt
+ 5, len
- 2 + 1);
186 opt_index
= find_opt (opt
+ 1, lang_mask
| CL_COMMON
);
187 if (opt_index
== cl_options_count
)
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
))
196 /* We've recognized this switch. */
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;
207 arg
+= strlen ("no-");
209 if (*arg
== '\0' && !(option
->flags
& CL_MISSING_OK
))
211 if (option
->flags
& CL_SEPARATE
)
217 /* Missing argument. */
221 else if (option
->flags
& CL_SEPARATE
)
227 /* If the switch takes an integer, convert it. */
228 if (arg
&& (option
->flags
& CL_UINTEGER
))
230 value
= integral_argument (arg
);
233 error ("argument to \"-%s\" should be a non-negative integer",
239 if (option
->flags
& lang_mask
)
241 temp
= (*lang_hooks
.handle_option
) (opt_index
, arg
, value
);
246 if (result
> 0 && (option
->flags
& CL_COMMON
))
248 if (common_handle_option (opt_index
, arg
, value
) == 0)
259 /* Handle target- and language-independent options. Return zero to
260 generate an "unknown option" message. */
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
);
281 exit_after_options
= true;
284 case OPT__target_help
:
285 display_target_options ();
286 exit_after_options
= true;
290 print_version (stderr
, "");
291 exit_after_options
= true;
295 g_switch_value
= value
;
301 aux_info_file_name
= arg
;
302 flag_gen_aux_info
= 1;
309 case OPT_auxbase_strip
:
311 char *tmp
= xstrdup (arg
);
312 strip_off_ending (tmp
, strlen (tmp
));
319 decode_d_option (arg
);
323 dump_base_name
= arg
;
338 case OPT_pedantic_errors
:
339 flag_pedantic_errors
= pedantic
= 1;
351 inhibit_warnings
= 1;