OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gcc-4.5.1/] [gcc/] [opts-common.c] - Blame information for rev 859

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 280 jeremybenn
/* 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
  /* We will only return this replacement argv if we remove at least
136
     one argument, so it does not need to be size (argc + 1) to
137
     make room for the terminating NULL because we will always have
138
     freed up at least one slot when we end up using it at all.  */
139
  char **argv = XNEWVEC (char *, argc);
140
  int i, arg_count, need_prune = 0;
141
  const struct cl_option *option;
142
  size_t opt_index;
143
 
144
  /* Scan all arguments.  */
145
  for (i = 1; i < argc; i++)
146
    {
147
      int value = 1;
148
      const char *opt = (*argvp) [i];
149
 
150
      opt_index = find_opt (opt + 1, -1);
151
      if (opt_index == cl_options_count
152
          && (opt[1] == 'W' || opt[1] == 'f' || opt[1] == 'm')
153
          && opt[2] == 'n' && opt[3] == 'o' && opt[4] == '-')
154
        {
155
          char *dup;
156
 
157
          /* Drop the "no-" from negative switches.  */
158
          size_t len = strlen (opt) - 3;
159
 
160
          dup = XNEWVEC (char, len + 1);
161
          dup[0] = '-';
162
          dup[1] = opt[1];
163
          memcpy (dup + 2, opt + 5, len - 2 + 1);
164
          opt = dup;
165
          value = 0;
166
          opt_index = find_opt (opt + 1, -1);
167
          free (dup);
168
        }
169
 
170
      if (opt_index == cl_options_count)
171
        {
172
cont:
173
          options [i] = 0;
174
          continue;
175
        }
176
 
177
      option = &cl_options[opt_index];
178
      if (option->neg_index < 0)
179
        goto cont;
180
 
181
      /* Skip joined switches.  */
182
      if ((option->flags & CL_JOINED))
183
        goto cont;
184
 
185
      /* Reject negative form of switches that don't take negatives as
186
         unrecognized.  */
187
      if (!value && (option->flags & CL_REJECT_NEGATIVE))
188
        goto cont;
189
 
190
      options [i] = (int) opt_index;
191
      need_prune |= options [i];
192
    }
193
 
194
  if (!need_prune)
195
    goto done;
196
 
197
  /* Remove arguments which are negated by others after them.  */
198
  argv [0] = (*argvp) [0];
199
  arg_count = 1;
200
  for (i = 1; i < argc; i++)
201
    {
202
      int j, opt_idx;
203
 
204
      opt_idx = options [i];
205
      if (opt_idx)
206
        {
207
          int next_opt_idx;
208
          for (j = i + 1; j < argc; j++)
209
            {
210
              next_opt_idx = options [j];
211
              if (next_opt_idx
212
                  && cancel_option (opt_idx, next_opt_idx,
213
                                    next_opt_idx))
214
                break;
215
            }
216
        }
217
      else
218
        goto keep;
219
 
220
      if (j == argc)
221
        {
222
keep:
223
          argv [arg_count] = (*argvp) [i];
224
          arg_count++;
225
        }
226
    }
227
 
228
  if (arg_count != argc)
229
    {
230
      *argcp = arg_count;
231
      *argvp = argv;
232
      /* Add NULL-termination.  Guaranteed not to overflow because
233
         arg_count here can only be less than argc.  */
234
      argv[arg_count] = 0;
235
    }
236
  else
237
    {
238
done:
239
      free (argv);
240
    }
241
 
242
  free (options);
243
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.