OSDN Git Service

2003-06-16 Aldy Hernandez <aldyh@redhat.com>
[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 /* 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)
137 {
138   const char *p = arg;
139
140   while (*p && ISDIGIT (*p))
141     p++;
142
143   if (*p == '\0')
144     return atoi (arg);
145
146   return -1;
147 }
148
149 /* Handle the switch beginning at ARGV, with ARGC remaining.  */
150 int
151 handle_option (int argc ATTRIBUTE_UNUSED, char **argv, int lang_mask)
152 {
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;
159
160   opt = argv[0];
161
162   /* Interpret "-" or a non-switch as a file name.  */
163   if (opt[0] != '-' || opt[1] == '\0')
164     {
165       opt_index = cl_options_count;
166       arg = opt;
167       main_input_filename = opt;
168       result = (*lang_hooks.handle_option) (opt_index, arg, value);
169     }
170   else
171     {
172       /* Drop the "no-" from negative switches.  */
173       if ((opt[1] == 'W' || opt[1] == 'f')
174           && opt[2] == 'n' && opt[3] == 'o' && opt[4] == '-')
175         {
176           size_t len = strlen (opt) - 3;
177
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;
184         }
185
186       opt_index = find_opt (opt + 1, lang_mask | CL_COMMON);
187       if (opt_index == cl_options_count)
188         goto done;
189
190       option = &cl_options[opt_index];
191
192       /* Reject negative form of switches that don't take negatives.  */
193       if (!value && (option->flags & CL_REJECT_NEGATIVE))
194         goto done;
195
196       /* We've recognized this switch.  */
197       result = 1;
198
199       /* Sort out any argument the switch takes.  */
200       if (option->flags & CL_JOINED)
201         {
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-");
208
209           if (*arg == '\0' && !(option->flags & CL_MISSING_OK))
210             {
211               if (option->flags & CL_SEPARATE)
212                 {
213                   arg = argv[1];
214                   result = 2;
215                 }
216               else
217                 /* Missing argument.  */
218                 arg = NULL;
219             }
220         }
221       else if (option->flags & CL_SEPARATE)
222         {
223           arg = argv[1];
224           result = 2;
225         }
226
227       /* If the switch takes an integer, convert it.  */
228       if (arg && (option->flags & CL_UINTEGER))
229         {
230           value = integral_argument (arg);
231           if (value == -1)
232             {
233               error ("argument to \"-%s\" should be a non-negative integer",
234                      option->opt_text);
235               goto done;
236             }
237         }
238
239       if (option->flags & lang_mask)
240         {
241           temp = (*lang_hooks.handle_option) (opt_index, arg, value);
242           if (temp <= 0)
243             result = temp;
244         }
245
246       if (result > 0 && (option->flags & CL_COMMON))
247         {
248           if (common_handle_option (opt_index, arg, value) == 0)
249             result = 0;
250         }
251     }
252
253  done:
254   if (dup)
255     free (dup);
256   return result;
257 }
258
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)
264 {
265   const struct cl_option *option = &cl_options[scode];
266   enum opt_code code = (enum opt_code) scode;
267
268   if (arg == NULL && (option->flags & (CL_JOINED | CL_SEPARATE)))
269     {
270       error ("missing argument to \"-%s\"", option->opt_text);
271       return 1;
272     }
273
274   switch (code)
275     {
276     default:
277       abort ();
278
279     case OPT__help:
280       display_help ();
281       exit_after_options = true;
282       break;
283
284     case OPT__target_help:
285       display_target_options ();
286       exit_after_options = true;
287       break;
288
289     case OPT__version:
290       print_version (stderr, "");
291       exit_after_options = true;
292       break;
293
294     case OPT_G:
295       g_switch_value = value;
296       g_switch_set = true;
297       break;
298
299     case OPT_aux_info:
300     case OPT_aux_info_:
301       aux_info_file_name = arg;
302       flag_gen_aux_info = 1;
303       break;
304
305     case OPT_auxbase:
306       aux_base_name = arg;
307       break;
308
309     case OPT_auxbase_strip:
310       {
311         char *tmp = xstrdup (arg);
312         strip_off_ending (tmp, strlen (tmp));
313         if (tmp[0])
314           aux_base_name = tmp;
315       }
316       break;
317
318     case OPT_d:
319       decode_d_option (arg);
320       break;
321
322     case OPT_dumpbase:
323       dump_base_name = arg;
324       break;
325
326     case OPT_o:
327       asm_file_name = arg;
328       break;
329
330     case OPT_p:
331       profile_flag = 1;
332       break;
333
334     case OPT_pedantic:
335       pedantic = 1;
336       break;
337
338     case OPT_pedantic_errors:
339       flag_pedantic_errors = pedantic = 1;
340       break;
341
342     case OPT_quiet:
343       quiet_flag = 1;
344       break;
345
346     case OPT_version:
347       version_flag = 1;
348       break;
349
350     case OPT_w:
351       inhibit_warnings = 1;
352       break;      
353     }
354
355   return 1;
356 }