OSDN Git Service

* sh.md (adddi3_compact, subdi3_compact): Add earlyclobber
[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
30 static size_t find_opt (const char *, int);
31
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
34    failure.
35
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
42    this case.  */
43 static size_t
44 find_opt (const char *input, int lang_mask)
45 {
46   size_t md, mn, mx;
47   size_t opt_len;
48   size_t result = cl_options_count;
49   int comp;
50
51   mn = 0;
52   mx = cl_options_count;
53
54   while (mx > mn)
55     {
56       md = (mn + mx) / 2;
57
58       opt_len = cl_options[md].opt_len;
59       comp = strncmp (input, cl_options[md].opt_text, opt_len);
60
61       if (comp < 0)
62         mx = md;
63       else if (comp > 0)
64         mn = md + 1;
65       else
66         {
67           /* The switch matches.  It it an exact match?  */
68           if (input[opt_len] == '\0')
69             return md;
70           else
71             {
72               mn = md + 1;
73
74               /* If the switch takes no arguments this is not a proper
75                  match, so we continue the search (e.g. input="stdc++"
76                  match was "stdc").  */
77               if (!(cl_options[md].flags & CL_JOINED))
78                 continue;
79
80               /* Is this switch valid for this front end?  */
81               if (!(cl_options[md].flags & lang_mask))
82                 {
83                   /* If subsequently we don't find a better match,
84                      return this and let the caller report it as a bad
85                      match.  */
86                   result = md;
87                   continue;
88                 }
89
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.
94
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.  */
98               mx = md;
99               for (md = md + 1; md < cl_options_count; md++)
100                 {
101                   opt_len = cl_options[md].opt_len;
102                   if (strncmp (input, cl_options[md].opt_text, opt_len))
103                     break;
104                   if (input[opt_len] == '\0')
105                     return md;
106                   if (cl_options[md].flags & lang_mask
107                       && cl_options[md].flags & CL_JOINED)
108                     mx = md;
109                 }
110
111               return mx;
112             }
113         }
114     }
115
116   return result;
117 }
118
119 /* Handle the switch beginning at ARGV, with ARGC remaining.  */
120 int
121 handle_option (int argc ATTRIBUTE_UNUSED, char **argv, int lang_mask)
122 {
123   size_t opt_index;
124   const char *opt, *arg = 0;
125   char *dup = 0;
126   bool on = true;
127   int result = 0, temp;
128   const struct cl_option *option;
129
130   opt = argv[0];
131
132   /* Interpret "-" or a non-switch as a file name.  */
133   if (opt[0] != '-' || opt[1] == '\0')
134     {
135       opt_index = cl_options_count;
136       arg = opt;
137       result = 1;
138     }
139   else
140     {
141       /* Drop the "no-" from negative switches.  */
142       if ((opt[1] == 'W' || opt[1] == 'f')
143           && opt[2] == 'n' && opt[3] == 'o' && opt[4] == '-')
144         {
145           size_t len = strlen (opt) - 3;
146
147           dup = xmalloc (len + 1);
148           dup[0] = '-';
149           dup[1] = opt[1];
150           memcpy (dup + 2, opt + 5, len - 2 + 1);
151           opt = dup;
152           on = false;
153         }
154
155       /* Skip over '-'.  */
156       opt_index = find_opt (opt + 1, lang_mask);
157       if (opt_index == cl_options_count)
158         goto done;
159
160       option = &cl_options[opt_index];
161
162       /* Reject negative form of switches that don't take negatives.  */
163       if (!on && (option->flags & CL_REJECT_NEGATIVE))
164         goto done;
165
166       /* We've recognised this switch.  */
167       result = 1;
168
169       /* Sort out any argument the switch takes.  */
170       if (option->flags & (CL_JOINED | CL_SEPARATE))
171         {
172           if (option->flags & CL_JOINED)
173             {
174               /* Have arg point to the original switch.  This is because
175                  some code, such as disable_builtin_function, expects its
176                  argument to be persistent until the program exits.  */
177               arg = argv[0] + cl_options[opt_index].opt_len + 1;
178               if (!on)
179                 arg += strlen ("no-");
180             }
181
182           /* If we don't have an argument, and CL_SEPARATE, try the next
183              argument in the vector.  */
184           if (!arg || (*arg == '\0' && option->flags & CL_SEPARATE))
185             {
186               arg = argv[1];
187               result = 2;
188             }
189
190           /* Canonicalize missing arguments as NULL for the handler.  */
191           if (*arg == '\0')
192             arg = NULL;
193         }
194     }
195
196   temp = (*lang_hooks.handle_option) (opt_index, arg, on);
197   if (temp <= 0)
198     result = temp;
199
200  done:
201   if (dup)
202     free (dup);
203   return result;
204 }