1169689Skan/* Command line option handling.
2169689Skan   Copyright (C) 2006 Free Software Foundation, Inc.
3169689Skan
4169689SkanThis file is part of GCC.
5169689Skan
6169689SkanGCC is free software; you can redistribute it and/or modify it under
7169689Skanthe terms of the GNU General Public License as published by the Free
8169689SkanSoftware Foundation; either version 2, or (at your option) any later
9169689Skanversion.
10169689Skan
11169689SkanGCC is distributed in the hope that it will be useful, but WITHOUT ANY
12169689SkanWARRANTY; without even the implied warranty of MERCHANTABILITY or
13169689SkanFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14169689Skanfor more details.
15169689Skan
16169689SkanYou should have received a copy of the GNU General Public License
17169689Skanalong with GCC; see the file COPYING.  If not, write to the Free
18169689SkanSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
19169689Skan02110-1301, USA.  */
20169689Skan
21169689Skan#include "config.h"
22169689Skan#include "system.h"
23169689Skan#include "intl.h"
24169689Skan#include "coretypes.h"
25169689Skan#include "opts.h"
26169689Skan
27169689Skan/* Perform a binary search to find which option the command-line INPUT
28169689Skan   matches.  Returns its index in the option array, and N_OPTS
29169689Skan   (cl_options_count) on failure.
30169689Skan
31169689Skan   This routine is quite subtle.  A normal binary search is not good
32169689Skan   enough because some options can be suffixed with an argument, and
33169689Skan   multiple sub-matches can occur, e.g. input of "-pedantic" matching
34169689Skan   the initial substring of "-pedantic-errors".
35169689Skan
36169689Skan   A more complicated example is -gstabs.  It should match "-g" with
37169689Skan   an argument of "stabs".  Suppose, however, that the number and list
38169689Skan   of switches are such that the binary search tests "-gen-decls"
39169689Skan   before having tested "-g".  This doesn't match, and as "-gen-decls"
40169689Skan   is less than "-gstabs", it will become the lower bound of the
41169689Skan   binary search range, and "-g" will never be seen.  To resolve this
42169689Skan   issue, opts.sh makes "-gen-decls" point, via the back_chain member,
43169689Skan   to "-g" so that failed searches that end between "-gen-decls" and
44169689Skan   the lexicographically subsequent switch know to go back and see if
45169689Skan   "-g" causes a match (which it does in this example).
46169689Skan
47169689Skan   This search is done in such a way that the longest match for the
48169689Skan   front end in question wins.  If there is no match for the current
49169689Skan   front end, the longest match for a different front end is returned
50169689Skan   (or N_OPTS if none) and the caller emits an error message.  */
51169689Skansize_t
52169689Skanfind_opt (const char *input, int lang_mask)
53169689Skan{
54169689Skan  size_t mn, mx, md, opt_len;
55169689Skan  size_t match_wrong_lang;
56169689Skan  int comp;
57169689Skan
58169689Skan  mn = 0;
59169689Skan  mx = cl_options_count;
60169689Skan
61169689Skan  /* Find mn such this lexicographical inequality holds:
62169689Skan     cl_options[mn] <= input < cl_options[mn + 1].  */
63169689Skan  while (mx - mn > 1)
64169689Skan    {
65169689Skan      md = (mn + mx) / 2;
66169689Skan      opt_len = cl_options[md].opt_len;
67169689Skan      comp = strncmp (input, cl_options[md].opt_text + 1, opt_len);
68169689Skan
69169689Skan      if (comp < 0)
70169689Skan	mx = md;
71169689Skan      else
72169689Skan	mn = md;
73169689Skan    }
74169689Skan
75169689Skan  /* This is the switch that is the best match but for a different
76169689Skan     front end, or cl_options_count if there is no match at all.  */
77169689Skan  match_wrong_lang = cl_options_count;
78169689Skan
79169689Skan  /* Backtrace the chain of possible matches, returning the longest
80169689Skan     one, if any, that fits best.  With current GCC switches, this
81169689Skan     loop executes at most twice.  */
82169689Skan  do
83169689Skan    {
84169689Skan      const struct cl_option *opt = &cl_options[mn];
85169689Skan
86169689Skan      /* Is the input either an exact match or a prefix that takes a
87169689Skan	 joined argument?  */
88169689Skan      if (!strncmp (input, opt->opt_text + 1, opt->opt_len)
89169689Skan	  && (input[opt->opt_len] == '\0' || (opt->flags & CL_JOINED)))
90169689Skan	{
91169689Skan	  /* If language is OK, return it.  */
92169689Skan	  if (opt->flags & lang_mask)
93169689Skan	    return mn;
94169689Skan
95169689Skan	  /* If we haven't remembered a prior match, remember this
96169689Skan	     one.  Any prior match is necessarily better.  */
97169689Skan	  if (match_wrong_lang == cl_options_count)
98169689Skan	    match_wrong_lang = mn;
99169689Skan	}
100169689Skan
101169689Skan      /* Try the next possibility.  This is cl_options_count if there
102169689Skan	 are no more.  */
103169689Skan      mn = opt->back_chain;
104169689Skan    }
105169689Skan  while (mn != cl_options_count);
106169689Skan
107169689Skan  /* Return the best wrong match, or cl_options_count if none.  */
108169689Skan  return match_wrong_lang;
109169689Skan}
110169689Skan
111169689Skan/* Return true if NEXT_OPT_IDX cancels OPT_IDX.  Return false if the
112169689Skan   next one is the same as ORIG_NEXT_OPT_IDX.  */
113169689Skan
114169689Skanstatic bool
115169689Skancancel_option (int opt_idx, int next_opt_idx, int orig_next_opt_idx)
116169689Skan{
117169689Skan  /* An option can be canceled by the same option or an option with
118169689Skan     Negative.  */
119169689Skan  if (cl_options [next_opt_idx].neg_index == opt_idx)
120169689Skan    return true;
121169689Skan
122169689Skan  if (cl_options [next_opt_idx].neg_index != orig_next_opt_idx)
123169689Skan    return cancel_option (opt_idx, cl_options [next_opt_idx].neg_index,
124169689Skan			  orig_next_opt_idx);
125169689Skan
126169689Skan  return false;
127169689Skan}
128169689Skan
129169689Skan/* Filter out options canceled by the ones after them.  */
130169689Skan
131169689Skanvoid
132169689Skanprune_options (int *argcp, char ***argvp)
133169689Skan{
134169689Skan  int argc = *argcp;
135169689Skan  int *options = xmalloc (argc * sizeof (*options));
136169689Skan  char **argv = xmalloc (argc * sizeof (char *));
137169689Skan  int i, arg_count, need_prune = 0;
138169689Skan  const struct cl_option *option;
139169689Skan  size_t opt_index;
140169689Skan
141169689Skan  /* Scan all arguments.  */
142169689Skan  for (i = 1; i < argc; i++)
143169689Skan    {
144169689Skan      int value = 1;
145169689Skan      const char *opt = (*argvp) [i];
146169689Skan
147169689Skan      opt_index = find_opt (opt + 1, -1);
148169689Skan      if (opt_index == cl_options_count
149169689Skan	  && (opt[1] == 'W' || opt[1] == 'f' || opt[1] == 'm')
150169689Skan	  && opt[2] == 'n' && opt[3] == 'o' && opt[4] == '-')
151169689Skan	{
152169689Skan	  char *dup;
153169689Skan
154169689Skan	  /* Drop the "no-" from negative switches.  */
155169689Skan	  size_t len = strlen (opt) - 3;
156169689Skan
157169689Skan	  dup = XNEWVEC (char, len + 1);
158169689Skan	  dup[0] = '-';
159169689Skan	  dup[1] = opt[1];
160169689Skan	  memcpy (dup + 2, opt + 5, len - 2 + 1);
161169689Skan	  opt = dup;
162169689Skan	  value = 0;
163169689Skan	  opt_index = find_opt (opt + 1, -1);
164169689Skan	  free (dup);
165169689Skan	}
166169689Skan
167169689Skan      if (opt_index == cl_options_count)
168169689Skan	{
169169689Skancont:
170169689Skan	  options [i] = 0;
171169689Skan	  continue;
172169689Skan	}
173169689Skan
174169689Skan      option = &cl_options[opt_index];
175169689Skan      if (option->neg_index < 0)
176169689Skan	goto cont;
177169689Skan
178169689Skan      /* Skip joined switches.  */
179169689Skan      if ((option->flags & CL_JOINED))
180169689Skan	goto cont;
181169689Skan
182169689Skan      /* Reject negative form of switches that don't take negatives as
183169689Skan	 unrecognized.  */
184169689Skan      if (!value && (option->flags & CL_REJECT_NEGATIVE))
185169689Skan	goto cont;
186169689Skan
187169689Skan      options [i] = (int) opt_index;
188169689Skan      need_prune |= options [i];
189169689Skan    }
190169689Skan
191169689Skan  if (!need_prune)
192169689Skan    goto done;
193169689Skan
194169689Skan  /* Remove arguments which are negated by others after them.  */
195169689Skan  argv [0] = (*argvp) [0];
196169689Skan  arg_count = 1;
197169689Skan  for (i = 1; i < argc; i++)
198169689Skan    {
199169689Skan      int j, opt_idx;
200169689Skan
201169689Skan      opt_idx = options [i];
202169689Skan      if (opt_idx)
203169689Skan	{
204169689Skan	  int next_opt_idx;
205169689Skan	  for (j = i + 1; j < argc; j++)
206169689Skan	    {
207169689Skan	      next_opt_idx = options [j];
208169689Skan	      if (next_opt_idx
209169689Skan		  && cancel_option (opt_idx, next_opt_idx,
210169689Skan				    next_opt_idx))
211169689Skan		break;
212169689Skan	    }
213169689Skan	}
214169689Skan      else
215169689Skan	goto keep;
216169689Skan
217169689Skan      if (j == argc)
218169689Skan	{
219169689Skankeep:
220169689Skan	  argv [arg_count] = (*argvp) [i];
221169689Skan	  arg_count++;
222169689Skan	}
223169689Skan    }
224169689Skan
225169689Skan  if (arg_count != argc)
226169689Skan    {
227169689Skan      *argcp = arg_count;
228169689Skan      *argvp = argv;
229169689Skan    }
230169689Skan  else
231169689Skan    {
232169689Skandone:
233169689Skan      free (argv);
234169689Skan    }
235169689Skan
236169689Skan  free (options);
237169689Skan}
238