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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gcc-4.2.2/] [gcc/] [opts-common.c] - Blame information for rev 304

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

Line No. Rev Author Line
1 38 julius
/* Command line option handling.
2
   Copyright (C) 2006, 2007 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, opts.sh 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 = xmalloc (argc * sizeof (*options));
135
  char **argv = xmalloc (argc * sizeof (char *));
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
}

powered by: WebSVN 2.1.0

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