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
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
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
24 #include "coretypes.h"
27 #include "langhooks.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
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
44 find_opt (const char *input
, int lang_mask
)
48 size_t result
= cl_options_count
;
52 mx
= cl_options_count
;
58 opt_len
= cl_options
[md
].opt_len
;
59 comp
= strncmp (input
, cl_options
[md
].opt_text
, opt_len
);
67 /* The switch matches. It it an exact match? */
68 if (input
[opt_len
] == '\0')
74 /* If the switch takes no arguments this is not a proper
75 match, so we continue the search (e.g. input="stdc++"
77 if (!(cl_options
[md
].flags
& CL_JOINED
))
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
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. */
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
))
104 if (input
[opt_len
] == '\0')
106 if (cl_options
[md
].flags
& lang_mask
107 && cl_options
[md
].flags
& CL_JOINED
)
119 /* Handle the switch beginning at ARGV, with ARGC remaining. */
121 handle_option (int argc
, char **argv
, int lang_mask
)
124 const char *opt
, *arg
= 0;
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
);
136 /* Interpret "-" or a non-switch as a file name. */
137 if (opt
[0] != '-' || opt
[1] == '\0')
139 opt_index
= cl_options_count
;
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);
154 memcpy (dup
+ 2, opt
+ 5, len
- 2 + 1);
160 opt_index
= find_opt (opt
+ 1, lang_mask
);
161 if (opt_index
== cl_options_count
)
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
))
170 /* We've recognised this switch. */
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;
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
))
194 /* Canonicalize missing arguments as NULL for the handler. */
200 temp
= (*lang_hooks
.handle_option
) (opt_index
, arg
, on
);