0
|
1 /* Command line option handling.
|
|
2 Copyright (C) 2006, 2007, 2008 Free Software Foundation, Inc.
|
|
3
|
|
4 This file is part of GCC.
|
|
5
|
|
6 GCC is free software; you can redistribute it and/or modify it under
|
|
7 the terms of the GNU General Public License as published by the Free
|
|
8 Software Foundation; either version 3, or (at your option) any later
|
|
9 version.
|
|
10
|
|
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
14 for more details.
|
|
15
|
|
16 You should have received a copy of the GNU General Public License
|
|
17 along with GCC; see the file COPYING3. If not see
|
|
18 <http://www.gnu.org/licenses/>. */
|
|
19
|
|
20 #include "config.h"
|
|
21 #include "system.h"
|
|
22 #include "intl.h"
|
|
23 #include "coretypes.h"
|
|
24 #include "opts.h"
|
|
25
|
|
26 /* Perform a binary search to find which option the command-line INPUT
|
|
27 matches. Returns its index in the option array, and N_OPTS
|
|
28 (cl_options_count) on failure.
|
|
29
|
|
30 This routine is quite subtle. A normal binary search is not good
|
|
31 enough because some options can be suffixed with an argument, and
|
|
32 multiple sub-matches can occur, e.g. input of "-pedantic" matching
|
|
33 the initial substring of "-pedantic-errors".
|
|
34
|
|
35 A more complicated example is -gstabs. It should match "-g" with
|
|
36 an argument of "stabs". Suppose, however, that the number and list
|
|
37 of switches are such that the binary search tests "-gen-decls"
|
|
38 before having tested "-g". This doesn't match, and as "-gen-decls"
|
|
39 is less than "-gstabs", it will become the lower bound of the
|
|
40 binary search range, and "-g" will never be seen. To resolve this
|
|
41 issue, 'optc-gen.awk' makes "-gen-decls" point, via the back_chain member,
|
|
42 to "-g" so that failed searches that end between "-gen-decls" and
|
|
43 the lexicographically subsequent switch know to go back and see if
|
|
44 "-g" causes a match (which it does in this example).
|
|
45
|
|
46 This search is done in such a way that the longest match for the
|
|
47 front end in question wins. If there is no match for the current
|
|
48 front end, the longest match for a different front end is returned
|
|
49 (or N_OPTS if none) and the caller emits an error message. */
|
|
50 size_t
|
|
51 find_opt (const char *input, int lang_mask)
|
|
52 {
|
|
53 size_t mn, mx, md, opt_len;
|
|
54 size_t match_wrong_lang;
|
|
55 int comp;
|
|
56
|
|
57 mn = 0;
|
|
58 mx = cl_options_count;
|
|
59
|
|
60 /* Find mn such this lexicographical inequality holds:
|
|
61 cl_options[mn] <= input < cl_options[mn + 1]. */
|
|
62 while (mx - mn > 1)
|
|
63 {
|
|
64 md = (mn + mx) / 2;
|
|
65 opt_len = cl_options[md].opt_len;
|
|
66 comp = strncmp (input, cl_options[md].opt_text + 1, opt_len);
|
|
67
|
|
68 if (comp < 0)
|
|
69 mx = md;
|
|
70 else
|
|
71 mn = md;
|
|
72 }
|
|
73
|
|
74 /* This is the switch that is the best match but for a different
|
|
75 front end, or cl_options_count if there is no match at all. */
|
|
76 match_wrong_lang = cl_options_count;
|
|
77
|
|
78 /* Backtrace the chain of possible matches, returning the longest
|
|
79 one, if any, that fits best. With current GCC switches, this
|
|
80 loop executes at most twice. */
|
|
81 do
|
|
82 {
|
|
83 const struct cl_option *opt = &cl_options[mn];
|
|
84
|
|
85 /* Is the input either an exact match or a prefix that takes a
|
|
86 joined argument? */
|
|
87 if (!strncmp (input, opt->opt_text + 1, opt->opt_len)
|
|
88 && (input[opt->opt_len] == '\0' || (opt->flags & CL_JOINED)))
|
|
89 {
|
|
90 /* If language is OK, return it. */
|
|
91 if (opt->flags & lang_mask)
|
|
92 return mn;
|
|
93
|
|
94 /* If we haven't remembered a prior match, remember this
|
|
95 one. Any prior match is necessarily better. */
|
|
96 if (match_wrong_lang == cl_options_count)
|
|
97 match_wrong_lang = mn;
|
|
98 }
|
|
99
|
|
100 /* Try the next possibility. This is cl_options_count if there
|
|
101 are no more. */
|
|
102 mn = opt->back_chain;
|
|
103 }
|
|
104 while (mn != cl_options_count);
|
|
105
|
|
106 /* Return the best wrong match, or cl_options_count if none. */
|
|
107 return match_wrong_lang;
|
|
108 }
|
|
109
|
|
110 /* Return true if NEXT_OPT_IDX cancels OPT_IDX. Return false if the
|
|
111 next one is the same as ORIG_NEXT_OPT_IDX. */
|
|
112
|
|
113 static bool
|
|
114 cancel_option (int opt_idx, int next_opt_idx, int orig_next_opt_idx)
|
|
115 {
|
|
116 /* An option can be canceled by the same option or an option with
|
|
117 Negative. */
|
|
118 if (cl_options [next_opt_idx].neg_index == opt_idx)
|
|
119 return true;
|
|
120
|
|
121 if (cl_options [next_opt_idx].neg_index != orig_next_opt_idx)
|
|
122 return cancel_option (opt_idx, cl_options [next_opt_idx].neg_index,
|
|
123 orig_next_opt_idx);
|
|
124
|
|
125 return false;
|
|
126 }
|
|
127
|
|
128 /* Filter out options canceled by the ones after them. */
|
|
129
|
|
130 void
|
|
131 prune_options (int *argcp, char ***argvp)
|
|
132 {
|
|
133 int argc = *argcp;
|
|
134 int *options = XNEWVEC (int, argc);
|
|
135 char **argv = XNEWVEC (char *, argc);
|
|
136 int i, arg_count, need_prune = 0;
|
|
137 const struct cl_option *option;
|
|
138 size_t opt_index;
|
|
139
|
|
140 /* Scan all arguments. */
|
|
141 for (i = 1; i < argc; i++)
|
|
142 {
|
|
143 int value = 1;
|
|
144 const char *opt = (*argvp) [i];
|
|
145
|
|
146 opt_index = find_opt (opt + 1, -1);
|
|
147 if (opt_index == cl_options_count
|
|
148 && (opt[1] == 'W' || opt[1] == 'f' || opt[1] == 'm')
|
|
149 && opt[2] == 'n' && opt[3] == 'o' && opt[4] == '-')
|
|
150 {
|
|
151 char *dup;
|
|
152
|
|
153 /* Drop the "no-" from negative switches. */
|
|
154 size_t len = strlen (opt) - 3;
|
|
155
|
|
156 dup = XNEWVEC (char, len + 1);
|
|
157 dup[0] = '-';
|
|
158 dup[1] = opt[1];
|
|
159 memcpy (dup + 2, opt + 5, len - 2 + 1);
|
|
160 opt = dup;
|
|
161 value = 0;
|
|
162 opt_index = find_opt (opt + 1, -1);
|
|
163 free (dup);
|
|
164 }
|
|
165
|
|
166 if (opt_index == cl_options_count)
|
|
167 {
|
|
168 cont:
|
|
169 options [i] = 0;
|
|
170 continue;
|
|
171 }
|
|
172
|
|
173 option = &cl_options[opt_index];
|
|
174 if (option->neg_index < 0)
|
|
175 goto cont;
|
|
176
|
|
177 /* Skip joined switches. */
|
|
178 if ((option->flags & CL_JOINED))
|
|
179 goto cont;
|
|
180
|
|
181 /* Reject negative form of switches that don't take negatives as
|
|
182 unrecognized. */
|
|
183 if (!value && (option->flags & CL_REJECT_NEGATIVE))
|
|
184 goto cont;
|
|
185
|
|
186 options [i] = (int) opt_index;
|
|
187 need_prune |= options [i];
|
|
188 }
|
|
189
|
|
190 if (!need_prune)
|
|
191 goto done;
|
|
192
|
|
193 /* Remove arguments which are negated by others after them. */
|
|
194 argv [0] = (*argvp) [0];
|
|
195 arg_count = 1;
|
|
196 for (i = 1; i < argc; i++)
|
|
197 {
|
|
198 int j, opt_idx;
|
|
199
|
|
200 opt_idx = options [i];
|
|
201 if (opt_idx)
|
|
202 {
|
|
203 int next_opt_idx;
|
|
204 for (j = i + 1; j < argc; j++)
|
|
205 {
|
|
206 next_opt_idx = options [j];
|
|
207 if (next_opt_idx
|
|
208 && cancel_option (opt_idx, next_opt_idx,
|
|
209 next_opt_idx))
|
|
210 break;
|
|
211 }
|
|
212 }
|
|
213 else
|
|
214 goto keep;
|
|
215
|
|
216 if (j == argc)
|
|
217 {
|
|
218 keep:
|
|
219 argv [arg_count] = (*argvp) [i];
|
|
220 arg_count++;
|
|
221 }
|
|
222 }
|
|
223
|
|
224 if (arg_count != argc)
|
|
225 {
|
|
226 *argcp = arg_count;
|
|
227 *argvp = argv;
|
|
228 }
|
|
229 else
|
|
230 {
|
|
231 done:
|
|
232 free (argv);
|
|
233 }
|
|
234
|
|
235 free (options);
|
|
236 }
|