]> gcc.gnu.org Git - gcc.git/blame - gcc/opts.c
alpha.md: Follow spelling conventions.
[gcc.git] / gcc / opts.c
CommitLineData
2772ef3e
NB
1/* Command line option handling.
2 Copyright (C) 2002, 2003 Free Software Foundation, Inc.
3 Contributed by Neil Booth.
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
9Software Foundation; either version 2, or (at your option) any later
10version.
11
12GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15for more details.
16
17You should have received a copy of the GNU General Public License
18along with GCC; see the file COPYING. If not, write to the Free
19Software Foundation, 59 Temple Place - Suite 330, Boston, MA
2002111-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"
d7b42618
NB
29#include "options.h"
30#include "flags.h"
31#include "toplev.h"
2772ef3e 32
35399bdc 33static size_t find_opt (const char *, int);
d7b42618 34static int common_handle_option (size_t scode, const char *arg, int value);
2772ef3e
NB
35
36/* Perform a binary search to find which option the command-line INPUT
37 matches. Returns its index in the option array, and N_OPTS on
38 failure.
39
40 Complications arise since some options can be suffixed with an
41 argument, and multiple complete matches can occur, e.g. -pedantic
42 and -pedantic-errors. Also, some options are only accepted by some
43 languages. If a switch matches for a different language and
44 doesn't match any alternatives for the true front end, the index of
45 the matched switch is returned anyway. The caller should check for
46 this case. */
35399bdc 47static size_t
2772ef3e
NB
48find_opt (const char *input, int lang_mask)
49{
50 size_t md, mn, mx;
51 size_t opt_len;
35399bdc 52 size_t result = cl_options_count;
2772ef3e
NB
53 int comp;
54
55 mn = 0;
35399bdc 56 mx = cl_options_count;
2772ef3e
NB
57
58 while (mx > mn)
59 {
60 md = (mn + mx) / 2;
61
62 opt_len = cl_options[md].opt_len;
63 comp = strncmp (input, cl_options[md].opt_text, opt_len);
64
65 if (comp < 0)
66 mx = md;
67 else if (comp > 0)
68 mn = md + 1;
69 else
70 {
71 /* The switch matches. It it an exact match? */
72 if (input[opt_len] == '\0')
73 return md;
74 else
75 {
76 mn = md + 1;
77
78 /* If the switch takes no arguments this is not a proper
79 match, so we continue the search (e.g. input="stdc++"
80 match was "stdc"). */
81 if (!(cl_options[md].flags & CL_JOINED))
82 continue;
83
84 /* Is this switch valid for this front end? */
85 if (!(cl_options[md].flags & lang_mask))
86 {
87 /* If subsequently we don't find a better match,
88 return this and let the caller report it as a bad
89 match. */
35399bdc 90 result = md;
2772ef3e
NB
91 continue;
92 }
93
94 /* Two scenarios remain: we have the switch's argument,
95 or we match a longer option. This can happen with
96 -iwithprefix and -withprefixbefore. The longest
97 possible option match succeeds.
98
99 Scan forwards, and return an exact match. Otherwise
100 return the longest valid option-accepting match (mx).
101 This loops at most twice with current options. */
102 mx = md;
35399bdc 103 for (md = md + 1; md < cl_options_count; md++)
2772ef3e
NB
104 {
105 opt_len = cl_options[md].opt_len;
106 if (strncmp (input, cl_options[md].opt_text, opt_len))
107 break;
108 if (input[opt_len] == '\0')
109 return md;
110 if (cl_options[md].flags & lang_mask
111 && cl_options[md].flags & CL_JOINED)
112 mx = md;
113 }
114
115 return mx;
116 }
117 }
118 }
119
120 return result;
121}
122
123/* Handle the switch beginning at ARGV, with ARGC remaining. */
124int
7fb26bb0 125handle_option (int argc ATTRIBUTE_UNUSED, char **argv, int lang_mask)
2772ef3e
NB
126{
127 size_t opt_index;
128 const char *opt, *arg = 0;
129 char *dup = 0;
130 bool on = true;
131 int result = 0, temp;
132 const struct cl_option *option;
133
2772ef3e
NB
134 opt = argv[0];
135
136 /* Interpret "-" or a non-switch as a file name. */
137 if (opt[0] != '-' || opt[1] == '\0')
138 {
35399bdc 139 opt_index = cl_options_count;
2772ef3e 140 arg = opt;
d7b42618
NB
141 main_input_filename = opt;
142 result = (*lang_hooks.handle_option) (opt_index, arg, on);
2772ef3e
NB
143 }
144 else
145 {
146 /* Drop the "no-" from negative switches. */
147 if ((opt[1] == 'W' || opt[1] == 'f')
148 && opt[2] == 'n' && opt[3] == 'o' && opt[4] == '-')
149 {
150 size_t len = strlen (opt) - 3;
151
152 dup = xmalloc (len + 1);
153 dup[0] = '-';
154 dup[1] = opt[1];
155 memcpy (dup + 2, opt + 5, len - 2 + 1);
156 opt = dup;
157 on = false;
158 }
159
d7b42618 160 opt_index = find_opt (opt + 1, lang_mask | CL_COMMON);
35399bdc 161 if (opt_index == cl_options_count)
2772ef3e
NB
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
6356f892 170 /* We've recognized this switch. */
2772ef3e
NB
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 }
2772ef3e 198
d7b42618
NB
199 if (option->flags & lang_mask)
200 {
201 temp = (*lang_hooks.handle_option) (opt_index, arg, on);
202 if (temp <= 0)
203 result = temp;
204 }
205
206 if (result > 0 && (option->flags & CL_COMMON))
207 {
208 if (common_handle_option (opt_index, arg, on) == 0)
209 result = 0;
210 }
211 }
2772ef3e
NB
212
213 done:
214 if (dup)
215 free (dup);
216 return result;
217}
d7b42618
NB
218
219/* Handle target- and language-independent options. Return zero to
220 generate an "unknown option" message. */
221static int
222common_handle_option (size_t scode, const char *arg,
223 int value ATTRIBUTE_UNUSED)
224{
225 const struct cl_option *option = &cl_options[scode];
226 enum opt_code code = (enum opt_code) scode;
227
228 if (arg == NULL && (option->flags & (CL_JOINED | CL_SEPARATE)))
229 {
230 error ("missing argument to \"-%s\"", option->opt_text);
231 return 1;
232 }
233
234 switch (code)
235 {
236 default:
237 abort ();
238
239 case OPT_quiet:
240 quiet_flag = 1;
241 break;
242 }
243
244 return 1;
245}
This page took 0.074274 seconds and 5 git commands to generate.