OSDN Git Service

* c-pch.c (asm_file_name): Remove.
[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 "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"
32
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;
36
37 /* True if we should exit after parsing options.  */
38 bool exit_after_options;
39
40 /* If -version.  */
41 bool version_flag;
42
43 static size_t find_opt (const char *, int);
44 static int common_handle_option (size_t scode, const char *arg, int value);
45
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.
49
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)
59 {
60   size_t md, mn, mx;
61   size_t opt_len;
62   size_t result = cl_options_count;
63   int comp;
64
65   mn = 0;
66   mx = cl_options_count;
67
68   while (mx > mn)
69     {
70       md = (mn + mx) / 2;
71
72       opt_len = cl_options[md].opt_len;
73       comp = strncmp (input, cl_options[md].opt_text, opt_len);
74
75       if (comp < 0)
76         mx = md;
77       else if (comp > 0)
78         mn = md + 1;
79       else
80         {
81           /* The switch matches.  It it an exact match?  */
82           if (input[opt_len] == '\0')
83             return md;
84           else
85             {
86               mn = md + 1;
87
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;
93
94               /* Is this switch valid for this front end?  */
95               if (!(cl_options[md].flags & lang_mask))
96                 {
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;
102                 }
103
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.
108
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++)
114                 {
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;
123                 }
124
125               return mx;
126             }
127         }
128     }
129
130   return result;
131 }
132
133 /* Handle the switch beginning at ARGV, with ARGC remaining.  */
134 int
135 handle_option (int argc ATTRIBUTE_UNUSED, char **argv, int lang_mask)
136 {
137   size_t opt_index;
138   const char *opt, *arg = 0;
139   char *dup = 0;
140   bool on = true;
141   int result = 0, temp;
142   const struct cl_option *option;
143
144   opt = argv[0];
145
146   /* Interpret "-" or a non-switch as a file name.  */
147   if (opt[0] != '-' || opt[1] == '\0')
148     {
149       opt_index = cl_options_count;
150       arg = opt;
151       main_input_filename = opt;
152       result = (*lang_hooks.handle_option) (opt_index, arg, on);
153     }
154   else
155     {
156       /* Drop the "no-" from negative switches.  */
157       if ((opt[1] == 'W' || opt[1] == 'f')
158           && opt[2] == 'n' && opt[3] == 'o' && opt[4] == '-')
159         {
160           size_t len = strlen (opt) - 3;
161
162           dup = xmalloc (len + 1);
163           dup[0] = '-';
164           dup[1] = opt[1];
165           memcpy (dup + 2, opt + 5, len - 2 + 1);
166           opt = dup;
167           on = false;
168         }
169
170       opt_index = find_opt (opt + 1, lang_mask | CL_COMMON);
171       if (opt_index == cl_options_count)
172         goto done;
173
174       option = &cl_options[opt_index];
175
176       /* Reject negative form of switches that don't take negatives.  */
177       if (!on && (option->flags & CL_REJECT_NEGATIVE))
178         goto done;
179
180       /* We've recognized this switch.  */
181       result = 1;
182
183       /* Sort out any argument the switch takes.  */
184       if (option->flags & (CL_JOINED | CL_SEPARATE))
185         {
186           if (option->flags & CL_JOINED)
187             {
188               /* Have arg point to the original switch.  This is because
189                  some code, such as disable_builtin_function, expects its
190                  argument to be persistent until the program exits.  */
191               arg = argv[0] + cl_options[opt_index].opt_len + 1;
192               if (!on)
193                 arg += strlen ("no-");
194             }
195
196           /* If we don't have an argument, and CL_SEPARATE, try the next
197              argument in the vector.  */
198           if (!arg || (*arg == '\0' && option->flags & CL_SEPARATE))
199             {
200               arg = argv[1];
201               result = 2;
202             }
203
204           /* Canonicalize missing arguments as NULL for the handler.  */
205           if (*arg == '\0')
206             arg = NULL;
207         }
208
209       if (option->flags & lang_mask)
210         {
211           temp = (*lang_hooks.handle_option) (opt_index, arg, on);
212           if (temp <= 0)
213             result = temp;
214         }
215
216       if (result > 0 && (option->flags & CL_COMMON))
217         {
218           if (common_handle_option (opt_index, arg, on) == 0)
219             result = 0;
220         }
221     }
222
223  done:
224   if (dup)
225     free (dup);
226   return result;
227 }
228
229 /* Handle target- and language-independent options.  Return zero to
230    generate an "unknown option" message.  */
231 static int
232 common_handle_option (size_t scode, const char *arg,
233                       int value ATTRIBUTE_UNUSED)
234 {
235   const struct cl_option *option = &cl_options[scode];
236   enum opt_code code = (enum opt_code) scode;
237
238   if (arg == NULL && (option->flags & (CL_JOINED | CL_SEPARATE)))
239     {
240       error ("missing argument to \"-%s\"", option->opt_text);
241       return 1;
242     }
243
244   switch (code)
245     {
246     default:
247       abort ();
248
249     case OPT__help:
250       display_help ();
251       exit_after_options = true;
252       break;
253
254     case OPT__target_help:
255       display_target_options ();
256       exit_after_options = true;
257       break;
258
259     case OPT__version:
260       print_version (stderr, "");
261       exit_after_options = true;
262       break;
263
264     case OPT_G:
265       g_switch_value = read_integral_parameter (arg, 0, -1);
266       if (g_switch_value == (unsigned HOST_WIDE_INT) -1)
267         return 0;
268       g_switch_set = true;
269       break;
270
271     case OPT_aux_info:
272     case OPT_aux_info_:
273       aux_info_file_name = arg;
274       flag_gen_aux_info = 1;
275       break;
276
277     case OPT_auxbase:
278       aux_base_name = arg;
279       break;
280
281     case OPT_auxbase_strip:
282       {
283         char *tmp = xstrdup (arg);
284         strip_off_ending (tmp, strlen (tmp));
285         if (tmp[0])
286           aux_base_name = tmp;
287       }
288       break;
289
290     case OPT_d:
291       decode_d_option (arg);
292       break;
293
294     case OPT_dumpbase:
295       dump_base_name = arg;
296       break;
297
298     case OPT_o:
299       asm_file_name = arg;
300       break;
301
302     case OPT_p:
303       profile_flag = 1;
304       break;
305
306     case OPT_pedantic:
307       pedantic = 1;
308       break;
309
310     case OPT_pedantic_errors:
311       flag_pedantic_errors = pedantic = 1;
312       break;
313
314     case OPT_quiet:
315       quiet_flag = 1;
316       break;
317
318     case OPT_version:
319       version_flag = 1;
320       break;
321
322     case OPT_w:
323       inhibit_warnings = 1;
324       break;      
325     }
326
327   return 1;
328 }