Makefile.in: Rename options.c and options.h to c-options.c and c-options.h.
[platform/upstream/gcc.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, 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   /* If the front end isn't yet converted, use the old hook.  */
131   if (!lang_hooks.handle_option)
132     return (*lang_hooks.decode_option) (argc, argv);
133
134   opt = argv[0];
135
136   /* Interpret "-" or a non-switch as a file name.  */
137   if (opt[0] != '-' || opt[1] == '\0')
138     {
139       opt_index = cl_options_count;
140       arg = opt;
141       result = 1;
142     }
143   else
144     {
145       /* Drop the "no-" from negative switches.  */
146       if ((opt[1] == 'W' || opt[1] == 'f')
147           && opt[2] == 'n' && opt[3] == 'o' && opt[4] == '-')
148         {
149           size_t len = strlen (opt) - 3;
150
151           dup = xmalloc (len + 1);
152           dup[0] = '-';
153           dup[1] = opt[1];
154           memcpy (dup + 2, opt + 5, len - 2 + 1);
155           opt = dup;
156           on = false;
157         }
158
159       /* Skip over '-'.  */
160       opt_index = find_opt (opt + 1, lang_mask);
161       if (opt_index == cl_options_count)
162         goto done;
163
164       option = &cl_options[opt_index];
165
166       /* Reject negative form of switches that don't take negatives.  */
167       if (!on && (option->flags & CL_REJECT_NEGATIVE))
168         goto done;
169
170       /* We've recognised this switch.  */
171       result = 1;
172
173       /* Sort out any argument the switch takes.  */
174       if (option->flags & (CL_JOINED | CL_SEPARATE))
175         {
176           if (option->flags & CL_JOINED)
177             {
178               /* Have arg point to the original switch.  This is because
179                  some code, such as disable_builtin_function, expects its
180                  argument to be persistent until the program exits.  */
181               arg = argv[0] + cl_options[opt_index].opt_len + 1;
182               if (!on)
183                 arg += strlen ("no-");
184             }
185
186           /* If we don't have an argument, and CL_SEPARATE, try the next
187              argument in the vector.  */
188           if (!arg || (*arg == '\0' && option->flags & CL_SEPARATE))
189             {
190               arg = argv[1];
191               result = 2;
192             }
193
194           /* Canonicalize missing arguments as NULL for the handler.  */
195           if (*arg == '\0')
196             arg = NULL;
197         }
198     }
199
200   temp = (*lang_hooks.handle_option) (opt_index, arg, on);
201   if (temp <= 0)
202     result = temp;
203
204  done:
205   if (dup)
206     free (dup);
207   return result;
208 }