Improve support for arm-wince-pe target:
[official-gcc.git] / gcc / opts.c
blob0911d388ff81243b1af2aa2e781c7945d5122622
1 /* Command line option handling.
2 Copyright (C) 2002, 2003 Free Software Foundation, Inc.
3 Contributed by Neil Booth.
5 This file is part of GCC.
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.
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.
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. */
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"
30 static size_t find_opt (const char *, int);
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.
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)
46 size_t md, mn, mx;
47 size_t opt_len;
48 size_t result = cl_options_count;
49 int comp;
51 mn = 0;
52 mx = cl_options_count;
54 while (mx > mn)
56 md = (mn + mx) / 2;
58 opt_len = cl_options[md].opt_len;
59 comp = strncmp (input, cl_options[md].opt_text, opt_len);
61 if (comp < 0)
62 mx = md;
63 else if (comp > 0)
64 mn = md + 1;
65 else
67 /* The switch matches. It it an exact match? */
68 if (input[opt_len] == '\0')
69 return md;
70 else
72 mn = md + 1;
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;
80 /* Is this switch valid for this front end? */
81 if (!(cl_options[md].flags & lang_mask))
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;
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.
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++)
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;
111 return mx;
116 return result;
119 /* Handle the switch beginning at ARGV, with ARGC remaining. */
121 handle_option (int argc, char **argv, int lang_mask)
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;
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);
134 opt = argv[0];
136 /* Interpret "-" or a non-switch as a file name. */
137 if (opt[0] != '-' || opt[1] == '\0')
139 opt_index = cl_options_count;
140 arg = opt;
141 result = 1;
143 else
145 /* Drop the "no-" from negative switches. */
146 if ((opt[1] == 'W' || opt[1] == 'f')
147 && opt[2] == 'n' && opt[3] == 'o' && opt[4] == '-')
149 size_t len = strlen (opt) - 3;
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;
159 /* Skip over '-'. */
160 opt_index = find_opt (opt + 1, lang_mask);
161 if (opt_index == cl_options_count)
162 goto done;
164 option = &cl_options[opt_index];
166 /* Reject negative form of switches that don't take negatives. */
167 if (!on && (option->flags & CL_REJECT_NEGATIVE))
168 goto done;
170 /* We've recognised this switch. */
171 result = 1;
173 /* Sort out any argument the switch takes. */
174 if (option->flags & (CL_JOINED | CL_SEPARATE))
176 if (option->flags & CL_JOINED)
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-");
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))
190 arg = argv[1];
191 result = 2;
194 /* Canonicalize missing arguments as NULL for the handler. */
195 if (*arg == '\0')
196 arg = NULL;
200 temp = (*lang_hooks.handle_option) (opt_index, arg, on);
201 if (temp <= 0)
202 result = temp;
204 done:
205 if (dup)
206 free (dup);
207 return result;