2003-12-26 Guilhem Lavaux <guilhem@kaffe.org>
[official-gcc.git] / gcc / f / g77spec.c
blobb5404994c2d72e3946fae2a53b195f38b44d3b3c
1 /* Specific flags and argument handling of the Fortran front-end.
2 Copyright (C) 1997, 1999, 2000, 2001, 2002, 2003
3 Free Software Foundation, Inc.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
12 GCC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
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
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
22 /* This file contains a filter for the main `gcc' driver, which is
23 replicated for the `g77' driver by adding this filter. The purpose
24 of this filter is to be basically identical to gcc (in that
25 it faithfully passes all of the original arguments to gcc) but,
26 unless explicitly overridden by the user in certain ways, ensure
27 that the needs of the language supported by this wrapper are met.
29 For GNU Fortran (g77), we do the following to the argument list
30 before passing it to `gcc':
32 1. Make sure `-lg2c -lm' is at the end of the list.
34 2. Make sure each time `-lg2c' or `-lm' is seen, it forms
35 part of the series `-lg2c -lm'.
37 #1 and #2 are not done if `-nostdlib' or any option that disables
38 the linking phase is present, or if `-xfoo' is in effect. Note that
39 a lack of source files or -l options disables linking.
41 This program was originally made out of gcc/cp/g++spec.c, but the
42 way it builds the new argument list was rewritten so it is much
43 easier to maintain, improve the way it decides to add or not add
44 extra arguments, etc. And several improvements were made in the
45 handling of arguments, primarily to make it more consistent with
46 `gcc' itself. */
48 #include "config.h"
49 #include "system.h"
50 #include "coretypes.h"
51 #include "tm.h"
52 #include "gcc.h"
54 #ifndef MATH_LIBRARY
55 #define MATH_LIBRARY "-lm"
56 #endif
58 #ifndef FORTRAN_INIT
59 #define FORTRAN_INIT "-lfrtbegin"
60 #endif
62 #ifndef FORTRAN_LIBRARY
63 #define FORTRAN_LIBRARY "-lg2c"
64 #endif
66 /* Options this driver needs to recognize, not just know how to
67 skip over. */
68 typedef enum
70 OPTION_b, /* Aka --prefix. */
71 OPTION_B, /* Aka --target. */
72 OPTION_c, /* Aka --compile. */
73 OPTION_driver, /* Wrapper-specific option. */
74 OPTION_E, /* Aka --preprocess. */
75 OPTION_help, /* --help. */
76 OPTION_i, /* -imacros, -include, -include-*. */
77 OPTION_l,
78 OPTION_L, /* Aka --library-directory. */
79 OPTION_M, /* Aka --dependencies. */
80 OPTION_MM, /* Aka --user-dependencies. */
81 OPTION_nostdlib, /* Aka --no-standard-libraries, or
82 -nodefaultlibs. */
83 OPTION_o, /* Aka --output. */
84 OPTION_S, /* Aka --assemble. */
85 OPTION_syntax_only, /* -fsyntax-only. */
86 OPTION_v, /* Aka --verbose. */
87 OPTION_version, /* --version. */
88 OPTION_V, /* Aka --use-version. */
89 OPTION_x, /* Aka --language. */
90 OPTION_ /* Unrecognized or unimportant. */
91 } Option;
93 /* The original argument list and related info is copied here. */
94 static int g77_xargc;
95 static const char *const *g77_xargv;
96 static void lookup_option (Option *, int *, const char **, const char *);
97 static void append_arg (const char *);
99 /* The new argument list will be built here. */
100 static int g77_newargc;
101 static const char **g77_newargv;
103 #ifndef SWITCH_TAKES_ARG
104 #define SWITCH_TAKES_ARG(CHAR) DEFAULT_SWITCH_TAKES_ARG(CHAR)
105 #endif
107 #ifndef WORD_SWITCH_TAKES_ARG
108 #define WORD_SWITCH_TAKES_ARG(STR) DEFAULT_WORD_SWITCH_TAKES_ARG (STR)
109 #endif
111 /* Assumes text[0] == '-'. Returns number of argv items that belong to
112 (and follow) this one, an option id for options important to the
113 caller, and a pointer to the first char of the arg, if embedded (else
114 returns NULL, meaning no arg or it's the next argv).
116 Note that this also assumes gcc.c's pass converting long options
117 to short ones, where available, has already been run. */
119 static void
120 lookup_option (Option *xopt, int *xskip, const char **xarg, const char *text)
122 Option opt = OPTION_;
123 int skip;
124 const char *arg = NULL;
126 if ((skip = SWITCH_TAKES_ARG (text[1])))
127 skip -= (text[2] != '\0'); /* See gcc.c. */
129 if (text[1] == 'B')
130 opt = OPTION_B, skip = (text[2] == '\0'), arg = text + 2;
131 else if (text[1] == 'b')
132 opt = OPTION_b, skip = (text[2] == '\0'), arg = text + 2;
133 else if ((text[1] == 'c') && (text[2] == '\0'))
134 opt = OPTION_c, skip = 0;
135 else if ((text[1] == 'E') && (text[2] == '\0'))
136 opt = OPTION_E, skip = 0;
137 else if (text[1] == 'i')
138 opt = OPTION_i, skip = 0;
139 else if (text[1] == 'l')
140 opt = OPTION_l;
141 else if (text[1] == 'L')
142 opt = OPTION_L, arg = text + 2;
143 else if (text[1] == 'o')
144 opt = OPTION_o;
145 else if ((text[1] == 'S') && (text[2] == '\0'))
146 opt = OPTION_S, skip = 0;
147 else if (text[1] == 'V')
148 opt = OPTION_V, skip = (text[2] == '\0');
149 else if ((text[1] == 'v') && (text[2] == '\0'))
150 opt = OPTION_v, skip = 0;
151 else if (text[1] == 'x')
152 opt = OPTION_x, arg = text + 2;
153 else
155 if ((skip = WORD_SWITCH_TAKES_ARG (text + 1)) != 0) /* See gcc.c. */
157 else if (! strncmp (text, "-fdriver", 8)) /* Really --driver!! */
158 opt = OPTION_driver; /* Never mind arg, this is unsupported. */
159 else if (! strcmp (text, "-fhelp")) /* Really --help!! */
160 opt = OPTION_help;
161 else if (! strcmp (text, "-M"))
162 opt = OPTION_M;
163 else if (! strcmp (text, "-MM"))
164 opt = OPTION_MM;
165 else if (! strcmp (text, "-nostdlib")
166 || ! strcmp (text, "-nodefaultlibs"))
167 opt = OPTION_nostdlib;
168 else if (! strcmp (text, "-fsyntax-only"))
169 opt = OPTION_syntax_only;
170 else if (! strcmp (text, "-dumpversion"))
171 opt = OPTION_version;
172 else if (! strcmp (text, "-fversion")) /* Really --version!! */
173 opt = OPTION_version;
174 else if (! strcmp (text, "-Xlinker")
175 || ! strcmp (text, "-specs"))
176 skip = 1;
177 else
178 skip = 0;
181 if (xopt != NULL)
182 *xopt = opt;
183 if (xskip != NULL)
184 *xskip = skip;
185 if (xarg != NULL)
187 if ((arg != NULL)
188 && (arg[0] == '\0'))
189 *xarg = NULL;
190 else
191 *xarg = arg;
195 /* Append another argument to the list being built. As long as it is
196 identical to the corresponding arg in the original list, just increment
197 the new arg count. Otherwise allocate a new list, etc. */
199 static void
200 append_arg (const char *arg)
202 static int newargsize;
204 #if 0
205 fprintf (stderr, "`%s'\n", arg);
206 #endif
208 if (g77_newargv == g77_xargv
209 && g77_newargc < g77_xargc
210 && (arg == g77_xargv[g77_newargc]
211 || ! strcmp (arg, g77_xargv[g77_newargc])))
213 ++g77_newargc;
214 return; /* Nothing new here. */
217 if (g77_newargv == g77_xargv)
218 { /* Make new arglist. */
219 int i;
221 newargsize = (g77_xargc << 2) + 20; /* This should handle all. */
222 g77_newargv = xmalloc (newargsize * sizeof (char *));
224 /* Copy what has been done so far. */
225 for (i = 0; i < g77_newargc; ++i)
226 g77_newargv[i] = g77_xargv[i];
229 if (g77_newargc == newargsize)
230 fatal ("overflowed output arg list for `%s'", arg);
232 g77_newargv[g77_newargc++] = arg;
235 void
236 lang_specific_driver (int *in_argc, const char *const **in_argv,
237 int *in_added_libraries ATTRIBUTE_UNUSED)
239 int argc = *in_argc;
240 const char *const *argv = *in_argv;
241 int i;
242 int verbose = 0;
243 Option opt;
244 int skip;
245 const char *arg;
247 /* This will be NULL if we encounter a situation where we should not
248 link in libf2c. */
249 const char *library = FORTRAN_LIBRARY;
251 /* 0 => -xnone in effect.
252 1 => -xfoo in effect. */
253 int saw_speclang = 0;
255 /* 0 => initial/reset state
256 1 => last arg was -l<library>
257 2 => last two args were -l<library> -lm. */
258 int saw_library = 0;
260 /* 0 => initial/reset state
261 1 => FORTRAN_INIT linked in */
262 int use_init = 0;
263 /* By default, we throw on the math library if we have one. */
264 int need_math = (MATH_LIBRARY[0] != '\0');
266 /* The number of input and output files in the incoming arg list. */
267 int n_infiles = 0;
268 int n_outfiles = 0;
270 #if 0
271 fprintf (stderr, "Incoming:");
272 for (i = 0; i < argc; i++)
273 fprintf (stderr, " %s", argv[i]);
274 fprintf (stderr, "\n");
275 #endif
277 g77_xargc = argc;
278 g77_xargv = argv;
279 g77_newargc = 0;
280 g77_newargv = (const char **) argv;
282 /* First pass through arglist.
284 If -nostdlib or a "turn-off-linking" option is anywhere in the
285 command line, don't do any library-option processing (except
286 relating to -x). Also, if -v is specified, but no other options
287 that do anything special (allowing -V version, etc.), remember
288 to add special stuff to make gcc command actually invoke all
289 the different phases of the compilation process so all the version
290 numbers can be seen.
292 Also, here is where all problems with missing arguments to options
293 are caught. If this loop is exited normally, it means all options
294 have the appropriate number of arguments as far as the rest of this
295 program is concerned. */
297 for (i = 1; i < argc; ++i)
299 if ((argv[i][0] == '+') && (argv[i][1] == 'e'))
301 continue;
304 if ((argv[i][0] != '-') || (argv[i][1] == '\0'))
306 ++n_infiles;
307 continue;
310 lookup_option (&opt, &skip, NULL, argv[i]);
312 switch (opt)
314 case OPTION_nostdlib:
315 case OPTION_c:
316 case OPTION_S:
317 case OPTION_syntax_only:
318 case OPTION_E:
319 case OPTION_M:
320 case OPTION_MM:
321 /* These options disable linking entirely or linking of the
322 standard libraries. */
323 library = 0;
324 break;
326 case OPTION_l:
327 ++n_infiles;
328 break;
330 case OPTION_o:
331 ++n_outfiles;
332 break;
334 case OPTION_v:
335 verbose = 1;
336 break;
338 case OPTION_b:
339 case OPTION_B:
340 case OPTION_L:
341 case OPTION_i:
342 case OPTION_V:
343 /* These options are useful in conjunction with -v to get
344 appropriate version info. */
345 break;
347 case OPTION_version:
348 printf ("\
349 GNU Fortran (GCC) %s\n\
350 Copyright (C) 2002 Free Software Foundation, Inc.\n\
352 GNU Fortran comes with NO WARRANTY, to the extent permitted by law.\n\
353 You may redistribute copies of GNU Fortran\n\
354 under the terms of the GNU General Public License.\n\
355 For more information about these matters, see the file named COPYING\n\
356 or type the command `info -f g77 Copying'.\n\
357 ", version_string);
358 exit (0);
359 break;
361 case OPTION_help:
362 /* Let gcc.c handle this, as it has a really
363 cool facility for handling --help and --verbose --help. */
364 return;
366 case OPTION_driver:
367 fatal ("--driver no longer supported");
368 break;
370 default:
371 break;
374 /* This is the one place we check for missing arguments in the
375 program. */
377 if (i + skip < argc)
378 i += skip;
379 else
380 fatal ("argument to `%s' missing", argv[i]);
383 if ((n_outfiles != 0) && (n_infiles == 0))
384 fatal ("no input files; unwilling to write output files");
386 /* If there are no input files, no need for the library. */
387 if (n_infiles == 0)
388 library = 0;
390 /* Second pass through arglist, transforming arguments as appropriate. */
392 append_arg (argv[0]); /* Start with command name, of course. */
394 for (i = 1; i < argc; ++i)
396 if (argv[i][0] == '\0')
398 append_arg (argv[i]); /* Interesting. Just append as is. */
399 continue;
402 if ((argv[i][0] == '-') && (argv[i][1] != 'l'))
404 /* Not a filename or library. */
406 if (saw_library == 1 && need_math) /* -l<library>. */
407 append_arg (MATH_LIBRARY);
409 saw_library = 0;
411 lookup_option (&opt, &skip, &arg, argv[i]);
413 if (argv[i][1] == '\0')
415 append_arg (argv[i]); /* "-" == Standard input. */
416 continue;
419 if (opt == OPTION_x)
421 /* Track input language. */
422 const char *lang;
424 if (arg == NULL)
425 lang = argv[i+1];
426 else
427 lang = arg;
429 saw_speclang = (strcmp (lang, "none") != 0);
432 append_arg (argv[i]);
434 for (; skip != 0; --skip)
435 append_arg (argv[++i]);
437 continue;
440 /* A filename/library, not an option. */
442 if (saw_speclang)
443 saw_library = 0; /* -xfoo currently active. */
444 else
445 { /* -lfoo or filename. */
446 if (strcmp (argv[i], MATH_LIBRARY) == 0)
448 if (saw_library == 1)
449 saw_library = 2; /* -l<library> -lm. */
450 else
452 if (0 == use_init)
454 append_arg (FORTRAN_INIT);
455 use_init = 1;
457 append_arg (FORTRAN_LIBRARY);
460 else if (strcmp (argv[i], FORTRAN_LIBRARY) == 0)
461 saw_library = 1; /* -l<library>. */
462 else
463 { /* Other library, or filename. */
464 if (saw_library == 1 && need_math)
465 append_arg (MATH_LIBRARY);
466 saw_library = 0;
469 append_arg (argv[i]);
472 /* Append `-lg2c -lm' as necessary. */
474 if (library)
475 { /* Doing a link and no -nostdlib. */
476 if (saw_speclang)
477 append_arg ("-xnone");
479 switch (saw_library)
481 case 0:
482 if (0 == use_init)
484 append_arg (FORTRAN_INIT);
485 use_init = 1;
487 append_arg (library);
488 case 1:
489 if (need_math)
490 append_arg (MATH_LIBRARY);
491 default:
492 break;
496 #ifdef ENABLE_SHARED_LIBGCC
497 if (library)
499 int i;
501 for (i = 1; i < g77_newargc; i++)
502 if (g77_newargv[i][0] == '-')
503 if (strcmp (g77_newargv[i], "-static-libgcc") == 0
504 || strcmp (g77_newargv[i], "-static") == 0)
505 break;
507 if (i == g77_newargc)
508 append_arg ("-shared-libgcc");
511 #endif
513 if (verbose
514 && g77_newargv != g77_xargv)
516 fprintf (stderr, "Driving:");
517 for (i = 0; i < g77_newargc; i++)
518 fprintf (stderr, " %s", g77_newargv[i]);
519 fprintf (stderr, "\n");
522 *in_argc = g77_newargc;
523 *in_argv = g77_newargv;
526 /* Called before linking. Returns 0 on success and -1 on failure. */
527 int lang_specific_pre_link (void) /* Not used for F77. */
529 return 0;
532 /* Number of extra output files that lang_specific_pre_link may generate. */
533 int lang_specific_extra_outfiles = 0; /* Not used for F77. */
535 /* Table of language-specific spec functions. */
536 const struct spec_function lang_specific_spec_functions[] =
538 { 0, 0 }