Fixup fromcvs/togit conversion
[minix-pkgsrc.git] / lang / gcc / patches / patch-ag
blobf300b0d432e8196f604feca855d94c8d0d791308
1 $NetBSD$
3 --- ../gcc-2.95.3/gcc/gcc.c.orig
4 +++ ../gcc-2.95.3/gcc/gcc.c
5 @@ -189,9 +189,13 @@
6  static void clear_failure_queue PROTO((void));
7  static int check_live_switch   PROTO((int, int));
8  static const char *handle_braces PROTO((const char *));
9 +static const struct spec_function *lookup_spec_function PROTO((const char *));
10 +static const char *eval_spec_function PROTO((const char *, const char *));
11 +static const char *handle_spec_function PROTO((const char *));
12  static char *save_string       PROTO((const char *, int));
13  extern int do_spec             PROTO((const char *));
14  static int do_spec_1           PROTO((const char *, int, const char *));
15 +static int do_spec_2           PROTO((const char *));
16  static const char *find_file   PROTO((const char *));
17  static int is_directory                PROTO((const char *, const char *, int));
18  static void validate_switches  PROTO((const char *));
19 @@ -216,6 +220,7 @@
20  static void process_command            PROTO ((int, char **));
21  static int execute                     PROTO ((void));
22  static void unused_prefix_warnings     PROTO ((struct path_prefix *));
23 +static void alloc_args                 PROTO ((void));
24  static void clear_args                 PROTO ((void));
25  static void fatal_error                        PROTO ((int));
27 @@ -231,6 +236,8 @@
28  /* Number of extra output files that lang_specific_pre_link may generate. */
29  extern int lang_specific_extra_outfiles;
30  \f
31 +static const char *if_exists_spec_function PROTO ((int, const char **));
32 +\f
33  /* Specs are strings containing lines, each of which (if not blank)
34  is made up of a program name, and arguments separated by spaces.
35  The program name must be exact and start from root, since no path
36 @@ -335,6 +342,12 @@
37   %*    substitute the variable part of a matched option.  (See below.)
38         Note that each comma in the substituted string is replaced by
39         a single space.
40 + %:function(args)
41 +       Call the named function FUNCTION, passing it ARGS.  ARGS is
42 +       first processed as a nested spec string, then split into an
43 +       argument vector in the usual fashion.  The function returns
44 +       a string which is processed as if it had appeared literally
45 +       as part of the current spec.
46   %{S}   substitutes the -S switch, if that switch was given to CC.
47         If that switch was not specified, this substitutes nothing.
48         Here S is a metasyntactic variable.
49 @@ -1162,6 +1175,24 @@
50  static struct spec_list *specs = (struct spec_list *)0;
52  \f
53 +/* The mapping of a spec function name to the C function that
54 +   implements it.  */
55 +struct spec_function
57 +  const char *name;
58 +  const char *(*func) PROTO ((int, const char **));
59 +};
61 +/* List of static spec functions.  */
63 +static const struct spec_function static_spec_functions[] =
65 +  { "if-exists",               if_exists_spec_function },
66 +  { 0, 0 }
67 +};
69 +static int processing_spec_function;
70 +\f
71  /* Initialize the specs lookup routines.  */
73  static void
74 @@ -1404,6 +1435,15 @@
76  static const char *multilib_dir;
78 +/* Allocate the argument vector.  */
80 +static void
81 +alloc_args ()
83 +  argbuf_length = 10;
84 +  argbuf = (char **) xmalloc (argbuf_length * sizeof (char *));
87  /* Clear out the vector of arguments (after a command is executed).  */
89  static void
90 @@ -2211,6 +2251,9 @@
92    struct command *commands;    /* each command buffer with above info.  */
94 +  if (processing_spec_function)
95 +    abort ();
97    /* Count # of piped commands.  */
98    for (n_commands = 1, i = 0; i < argbuf_index; i++)
99      if (strcmp (argbuf[i], "|") == 0)
100 @@ -3360,14 +3403,7 @@
102    int value;
104 -  clear_args ();
105 -  arg_going = 0;
106 -  delete_this_arg = 0;
107 -  this_is_output_file = 0;
108 -  this_is_library_file = 0;
109 -  input_from_pipe = 0;
111 -  value = do_spec_1 (spec, 0, NULL_PTR);
112 +  value = do_spec_2 (spec);
114    /* Force out any unfinished command.
115       If -pipe, this forces out the last command if it ended in `|'.  */
116 @@ -3383,6 +3419,20 @@
117    return value;
120 +static int
121 +do_spec_2 (spec)
122 +     const char *spec;
124 +  clear_args ();
125 +  arg_going = 0;
126 +  delete_this_arg = 0;
127 +  this_is_output_file = 0;
128 +  this_is_library_file = 0;
129 +  input_from_pipe = 0;
131 +  return do_spec_1 (spec, 0, NULL_PTR);
134  /* Process the sub-spec SPEC as a portion of a larger spec.
135     This is like processing a whole spec except that we do
136     not initialize at the beginning and we do not supply a
137 @@ -4068,6 +4118,12 @@
138               return -1;
139             break;
141 +         case ':':
142 +           p = handle_spec_function (p);
143 +           if (p == 0)
144 +             return -1;
145 +           break;
147           case '%':
148             obstack_1grow (&obstack, '%');
149             break;
150 @@ -4222,7 +4278,173 @@
151         arg_going = 1;
152        }
154 -  return 0;            /* End of string */
155 +  /* End of string.  If we are processing a spec function, we need to
156 +     end any pending argument.  */
157 +  if (processing_spec_function && arg_going)
158 +    {
159 +      obstack_1grow (&obstack, 0);
160 +      string = obstack_finish (&obstack);
161 +      if (this_is_library_file)
162 +       string = find_file (string);
163 +      store_arg (string, delete_this_arg, this_is_output_file);
164 +      if (this_is_output_file)
165 +       outfiles[input_file_number] = string;
166 +      arg_going = 0;
167 +    }
169 +  return 0;
172 +/* Look up a spec function.  */
174 +static const struct spec_function *
175 +lookup_spec_function (name)
176 +     const char *name;
178 +  static const struct spec_function * const spec_function_tables[] =
179 +  {
180 +    static_spec_functions,
181 +  };
182 +  const struct spec_function *sf;
183 +  unsigned int i;
185 +  for (i = 0; i < ARRAY_SIZE (spec_function_tables); i++)
186 +    {
187 +      for (sf = spec_function_tables[i]; sf->name != NULL; sf++)
188 +       if (strcmp (sf->name, name) == 0)
189 +         return sf;
190 +    }
192 +  return NULL;
195 +/* Evaluate a spec function.  */
197 +static const char *
198 +eval_spec_function (func, args)
199 +     const char *func, *args;
201 +  const struct spec_function *sf;
202 +  const char *funcval;
204 +  /* Saved spec processing context.  */
205 +  int save_argbuf_index;
206 +  int save_argbuf_length;
207 +  char **save_argbuf;
209 +  int save_arg_going;
210 +  int save_delete_this_arg;
211 +  int save_this_is_output_file;
212 +  int save_this_is_library_file;
213 +  int save_input_from_pipe;
216 +  sf = lookup_spec_function (func);
217 +  if (sf == NULL)
218 +    fatal ("unknown spec function `%s'", func);
220 +  /* Push the spec processing context.  */
221 +  save_argbuf_index = argbuf_index;
222 +  save_argbuf_length = argbuf_length;
223 +  save_argbuf = argbuf;
225 +  save_arg_going = arg_going;
226 +  save_delete_this_arg = delete_this_arg;
227 +  save_this_is_output_file = this_is_output_file;
228 +  save_this_is_library_file = this_is_library_file;
229 +  save_input_from_pipe = input_from_pipe;
231 +  /* Create a new spec processing context, and build the function
232 +     arguments.  */
234 +  alloc_args ();
235 +  if (do_spec_2 (args) < 0)
236 +    fatal ("error in args to spec function `%s'", func);
238 +  /* argbuf_index is an index for the next argument to be inserted, and
239 +     so contains the count of the args already inserted.  */
241 +  funcval = (*sf->func) (argbuf_index, (const char **) argbuf);
243 +  /* Pop the spec processing context.  */
244 +  argbuf_index = save_argbuf_index;
245 +  argbuf_length = save_argbuf_length;
246 +  free (argbuf);
247 +  argbuf = save_argbuf;
249 +  arg_going = save_arg_going;
250 +  delete_this_arg = save_delete_this_arg;
251 +  this_is_output_file = save_this_is_output_file;
252 +  this_is_library_file = save_this_is_library_file;
253 +  input_from_pipe = save_input_from_pipe;
255 +  return funcval;
258 +/* Handle a spec function call of the form:
260 +   %:function(args)
262 +   ARGS is processed as a spec in a separate context and split into an
263 +   argument vector in the normal fashion.  The function returns a string
264 +   containing a spec which we then process in the caller's context, or
265 +   NULL if no processing is required.  */
267 +static const char *
268 +handle_spec_function (p)
269 +     const char *p;
271 +  char *func, *args;
272 +  const char *endp, *funcval;
273 +  int count;
275 +  processing_spec_function++;
277 +  /* Get the function name.  */
278 +  for (endp = p; *endp != '\0'; endp++)
279 +    {
280 +      if (*endp == '(')                /* ) */
281 +       break;
282 +      /* Only allow [A-Za-z0-9], -, and _ in function names.  */
283 +      if (!ISALNUM (*endp) && !(*endp == '-' || *endp == '_'))
284 +       fatal ("malformed spec function name");
285 +    }
286 +  if (*endp != '(')            /* ) */
287 +    fatal ("no arguments for spec function");
288 +  func = save_string (p, endp - p);
289 +  p = ++endp;
291 +  /* Get the arguments.  */
292 +  for (count = 0; *endp != '\0'; endp++)
293 +    {
294 +      /* ( */
295 +      if (*endp == ')')
296 +       {
297 +         if (count == 0)
298 +           break;
299 +         count--;
300 +       }
301 +      else if (*endp == '(')   /* ) */
302 +       count++;
303 +    }
304 +  /* ( */
305 +  if (*endp != ')')
306 +    fatal ("malformed spec function arguments");
307 +  args = save_string (p, endp - p);
308 +  p = ++endp;
310 +  /* p now points to just past the end of the spec function expression.  */
312 +  funcval = eval_spec_function (func, args);
313 +  if (funcval != NULL && do_spec_1 (funcval, 0, NULL) < 0)
314 +    p = NULL;
316 +  free (func);
317 +  free (args);
319 +  processing_spec_function--;
321 +  return p;
324  /* Return 0 if we call do_spec_1 and that returns -1.  */
325 @@ -4674,8 +4896,8 @@
326      signal (SIGPIPE, fatal_error);
327  #endif
329 -  argbuf_length = 10;
330 -  argbuf = (char **) xmalloc (argbuf_length * sizeof (char *));
331 +  /* Allocate the argument vector.  */
332 +  alloc_args ();
334    obstack_init (&obstack);
336 @@ -5846,3 +6068,25 @@
337        ++p;
338      }
341 +/* if-exists built-in spec function.
343 +   Checks to see if the file specified by the absolute pathname in
344 +   ARGS exists.  Returns that pathname if found.
346 +   The usual use for this function is to check for a library file
347 +   (whose name has been expanded with %s).  */
349 +#define IS_ABSOLUTE_PATHNAME(cp)       ((cp)[0] == '/')
351 +static const char *
352 +if_exists_spec_function (argc, argv)
353 +     int argc;
354 +     const char **argv;
356 +  /* Must have only one argument.  */
357 +  if (argc == 1 && IS_ABSOLUTE_PATHNAME (argv[0]) && ! access (argv[0], R_OK))
358 +    return argv[0];
360 +  return NULL;