]> gcc.gnu.org Git - gcc.git/blame - gcc/fortran/gfortranspec.c
Update FSF address.
[gcc.git] / gcc / fortran / gfortranspec.c
CommitLineData
6de9cd9a 1/* Specific flags and argument handling of the Fortran front-end.
12d3e34b
TS
2 Copyright (C) 1997, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free
3 Software Foundation, Inc.
6de9cd9a 4
882f2b8e 5This file is part of GCC.
6de9cd9a
DN
6
7GNU CC is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2, or (at your option)
10any later version.
11
12GNU CC is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU CC; see the file COPYING. If not, write to
ab57747b
KC
19the Free Software Foundation, 51 Franklin Street, Fifth Floor,
20Boston, MA 02110-1301, USA. */
6de9cd9a
DN
21/* This file is copied more or less verbatim from g77. */
22/* This file contains a filter for the main `gcc' driver, which is
23 replicated for the `gfortran' 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.
28
29 For GNU Fortran 95(gfortran), we do the following to the argument list
30 before passing it to `gcc':
31
32 1. Make sure `-lgfortran -lm' is at the end of the list.
33
34 2. Make sure each time `-lgfortran' or `-lm' is seen, it forms
35 part of the series `-lgfortran -lm'.
36
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.
40
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. */
47
48#include "config.h"
49#include "system.h"
50#include "gcc.h"
51
52#include "coretypes.h"
53#include "tm.h"
54
55#ifndef MATH_LIBRARY
56#define MATH_LIBRARY "-lm"
57#endif
58
59#ifndef FORTRAN_INIT
60#define FORTRAN_INIT "-lgfortranbegin"
61#endif
62
63#ifndef FORTRAN_LIBRARY
64#define FORTRAN_LIBRARY "-lgfortran"
65#endif
66
67/* Options this driver needs to recognize, not just know how to
68 skip over. */
69typedef enum
70{
f7b529fa
KH
71 OPTION_b, /* Aka --prefix. */
72 OPTION_B, /* Aka --target. */
73 OPTION_c, /* Aka --compile. */
74 OPTION_E, /* Aka --preprocess. */
75 OPTION_help, /* --help. */
76 OPTION_i, /* -imacros, -include, -include-*. */
6de9cd9a 77 OPTION_l,
f7b529fa 78 OPTION_L, /* Aka --library-directory. */
6de9cd9a 79 OPTION_nostdlib, /* Aka --no-standard-libraries, or
f7b529fa
KH
80 -nodefaultlibs. */
81 OPTION_o, /* Aka --output. */
82 OPTION_S, /* Aka --assemble. */
83 OPTION_syntax_only, /* -fsyntax-only. */
84 OPTION_v, /* Aka --verbose. */
85 OPTION_version, /* --version. */
86 OPTION_V, /* Aka --use-version. */
87 OPTION_x, /* Aka --language. */
88 OPTION_ /* Unrecognized or unimportant. */
6de9cd9a
DN
89}
90Option;
91
92/* The original argument list and related info is copied here. */
93static int g77_xargc;
94static const char *const *g77_xargv;
95static void lookup_option (Option *, int *, const char **, const char *);
96static void append_arg (const char *);
97
98/* The new argument list will be built here. */
99static int g77_newargc;
100static const char **g77_newargv;
101
102const struct spec_function lang_specific_spec_functions[] = {{0,0}};
103
104/* --- This comes from gcc.c (2.8.1) verbatim: */
105
106/* This defines which switch letters take arguments. */
107
108#ifndef SWITCH_TAKES_ARG
109#define SWITCH_TAKES_ARG(CHAR) DEFAULT_SWITCH_TAKES_ARG(CHAR)
110#endif
111
112/* This defines which multi-letter switches take arguments. */
113
114#ifndef WORD_SWITCH_TAKES_ARG
115#define WORD_SWITCH_TAKES_ARG(STR) DEFAULT_WORD_SWITCH_TAKES_ARG (STR)
116#endif
117
118/* --- End of verbatim. */
119
120/* Assumes text[0] == '-'. Returns number of argv items that belong to
121 (and follow) this one, an option id for options important to the
122 caller, and a pointer to the first char of the arg, if embedded (else
123 returns NULL, meaning no arg or it's the next argv).
124
125 Note that this also assumes gcc.c's pass converting long options
126 to short ones, where available, has already been run. */
127
128static void
129lookup_option (Option *xopt, int *xskip, const char **xarg, const char *text)
130{
131 Option opt = OPTION_;
132 int skip;
133 const char *arg = NULL;
134
135 if ((skip = SWITCH_TAKES_ARG (text[1])))
f7b529fa 136 skip -= (text[2] != '\0'); /* See gcc.c. */
6de9cd9a
DN
137
138 if (text[1] == 'B')
139 opt = OPTION_B, skip = (text[2] == '\0'), arg = text + 2;
140 else if (text[1] == 'b')
141 opt = OPTION_b, skip = (text[2] == '\0'), arg = text + 2;
142 else if ((text[1] == 'c') && (text[2] == '\0'))
143 opt = OPTION_c, skip = 0;
144 else if ((text[1] == 'E') && (text[2] == '\0'))
145 opt = OPTION_E, skip = 0;
146 else if (text[1] == 'i')
147 opt = OPTION_i, skip = 0;
148 else if (text[1] == 'l')
149 opt = OPTION_l;
150 else if (text[1] == 'L')
151 opt = OPTION_L, arg = text + 2;
152 else if (text[1] == 'o')
153 opt = OPTION_o;
154 else if ((text[1] == 'S') && (text[2] == '\0'))
155 opt = OPTION_S, skip = 0;
156 else if (text[1] == 'V')
157 opt = OPTION_V, skip = (text[2] == '\0');
158 else if ((text[1] == 'v') && (text[2] == '\0'))
159 opt = OPTION_v, skip = 0;
160 else if (text[1] == 'x')
161 opt = OPTION_x, arg = text + 2;
162 else
163 {
f7b529fa 164 if ((skip = WORD_SWITCH_TAKES_ARG (text + 1)) != 0) /* See gcc.c. */
6de9cd9a
DN
165 ;
166 else if (!strcmp (text, "-fhelp")) /* Really --help!! */
167 opt = OPTION_help;
168 else if (!strcmp (text, "-nostdlib")
169 || !strcmp (text, "-nodefaultlibs"))
170 opt = OPTION_nostdlib;
171 else if (!strcmp (text, "-fsyntax-only"))
172 opt = OPTION_syntax_only;
173 else if (!strcmp (text, "-dumpversion"))
174 opt = OPTION_version;
175 else if (!strcmp (text, "-fversion")) /* Really --version!! */
176 opt = OPTION_version;
177 else if (!strcmp (text, "-Xlinker") || !strcmp (text, "-specs"))
178 skip = 1;
179 else
180 skip = 0;
181 }
182
183 if (xopt != NULL)
184 *xopt = opt;
185 if (xskip != NULL)
186 *xskip = skip;
187 if (xarg != NULL)
188 {
189 if ((arg != NULL) && (arg[0] == '\0'))
190 *xarg = NULL;
191 else
192 *xarg = arg;
193 }
194}
195
196/* Append another argument to the list being built. As long as it is
197 identical to the corresponding arg in the original list, just increment
198 the new arg count. Otherwise allocate a new list, etc. */
199
200static void
201append_arg (const char *arg)
202{
203 static int newargsize;
204
205#if 0
206 fprintf (stderr, "`%s'\n", arg);
207#endif
208
209 if (g77_newargv == g77_xargv
210 && g77_newargc < g77_xargc
211 && (arg == g77_xargv[g77_newargc]
212 || !strcmp (arg, g77_xargv[g77_newargc])))
213 {
214 ++g77_newargc;
f7b529fa 215 return; /* Nothing new here. */
6de9cd9a
DN
216 }
217
218 if (g77_newargv == g77_xargv)
f7b529fa 219 { /* Make new arglist. */
6de9cd9a
DN
220 int i;
221
f7b529fa 222 newargsize = (g77_xargc << 2) + 20; /* This should handle all. */
6de9cd9a
DN
223 g77_newargv = (const char **) xmalloc (newargsize * sizeof (char *));
224
225 /* Copy what has been done so far. */
226 for (i = 0; i < g77_newargc; ++i)
227 g77_newargv[i] = g77_xargv[i];
228 }
229
230 if (g77_newargc == newargsize)
597cdf4f 231 fatal ("overflowed output arg list for '%s'", arg);
6de9cd9a
DN
232
233 g77_newargv[g77_newargc++] = arg;
234}
235
236void
237lang_specific_driver (int *in_argc, const char *const **in_argv,
238 int *in_added_libraries ATTRIBUTE_UNUSED)
239{
240 int argc = *in_argc;
241 const char *const *argv = *in_argv;
242 int i;
243 int verbose = 0;
244 Option opt;
245 int skip;
246 const char *arg;
247
248 /* This will be NULL if we encounter a situation where we should not
249 link in libf2c. */
250 const char *library = FORTRAN_LIBRARY;
251
252 /* 0 => -xnone in effect.
253 1 => -xfoo in effect. */
254 int saw_speclang = 0;
255
256 /* 0 => initial/reset state
257 1 => last arg was -l<library>
258 2 => last two args were -l<library> -lm. */
259 int saw_library = 0;
260
261 /* 0 => initial/reset state
262 1 => FORTRAN_INIT linked in */
263 int use_init = 0;
264
265 /* By default, we throw on the math library if we have one. */
266 int need_math = (MATH_LIBRARY[0] != '\0');
267
268 /* The number of input and output files in the incoming arg list. */
269 int n_infiles = 0;
270 int n_outfiles = 0;
271
272#if 0
273 fprintf (stderr, "Incoming:");
274 for (i = 0; i < argc; i++)
275 fprintf (stderr, " %s", argv[i]);
276 fprintf (stderr, "\n");
277#endif
278
279 g77_xargc = argc;
280 g77_xargv = argv;
281 g77_newargc = 0;
282 g77_newargv = (const char **) argv;
283
284 /* First pass through arglist.
285
286 If -nostdlib or a "turn-off-linking" option is anywhere in the
287 command line, don't do any library-option processing (except
288 relating to -x). Also, if -v is specified, but no other options
289 that do anything special (allowing -V version, etc.), remember
290 to add special stuff to make gcc command actually invoke all
291 the different phases of the compilation process so all the version
292 numbers can be seen.
293
294 Also, here is where all problems with missing arguments to options
295 are caught. If this loop is exited normally, it means all options
296 have the appropriate number of arguments as far as the rest of this
297 program is concerned. */
298
299 for (i = 1; i < argc; ++i)
300 {
301 if ((argv[i][0] == '+') && (argv[i][1] == 'e'))
302 {
303 continue;
304 }
305
306 if ((argv[i][0] != '-') || (argv[i][1] == '\0'))
307 {
308 ++n_infiles;
309 continue;
310 }
311
312 lookup_option (&opt, &skip, NULL, argv[i]);
313
314 switch (opt)
315 {
316 case OPTION_nostdlib:
317 case OPTION_c:
318 case OPTION_S:
319 case OPTION_syntax_only:
320 case OPTION_E:
321 /* These options disable linking entirely or linking of the
322 standard libraries. */
323 library = 0;
324 break;
325
326 case OPTION_l:
327 ++n_infiles;
328 break;
329
330 case OPTION_o:
331 ++n_outfiles;
332 break;
333
334 case OPTION_v:
335 verbose = 1;
336 break;
337
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;
346
347 case OPTION_version:
348 printf ("\
349GNU Fortran 95 (GCC %s)\n\
12d3e34b 350Copyright (C) 2005 Free Software Foundation, Inc.\n\
6de9cd9a
DN
351\n\
352GNU Fortran comes with NO WARRANTY, to the extent permitted by law.\n\
353You may redistribute copies of GNU Fortran\n\
354under the terms of the GNU General Public License.\n\
355For more information about these matters, see the file named COPYING\n\
356", version_string);
357 exit (0);
358 break;
359
360 case OPTION_help:
361 /* Let gcc.c handle this, as it has a really
362 cool facility for handling --help and --verbose --help. */
363 return;
364
365 default:
366 break;
367 }
368
369 /* This is the one place we check for missing arguments in the
370 program. */
371
372 if (i + skip < argc)
373 i += skip;
374 else
597cdf4f 375 fatal ("argument to '%s' missing", argv[i]);
6de9cd9a
DN
376 }
377
378 if ((n_outfiles != 0) && (n_infiles == 0))
379 fatal ("no input files; unwilling to write output files");
380
381 /* If there are no input files, no need for the library. */
382 if (n_infiles == 0)
383 library = 0;
384
385 /* Second pass through arglist, transforming arguments as appropriate. */
386
f7b529fa 387 append_arg (argv[0]); /* Start with command name, of course. */
6de9cd9a
DN
388
389 for (i = 1; i < argc; ++i)
390 {
391 if (argv[i][0] == '\0')
392 {
f7b529fa 393 append_arg (argv[i]); /* Interesting. Just append as is. */
6de9cd9a
DN
394 continue;
395 }
396
397 if ((argv[i][0] == '-') && (argv[i][1] == 'M'))
398 {
399 char *p;
400
401 if (argv[i][2] == '\0')
402 {
403 p = xmalloc (strlen (argv[i + 1]) + 2);
404 p[0] = '-';
405 p[1] = 'J';
406 strcpy (&p[2], argv[i + 1]);
407 i++;
408 }
409 else
410 {
411 p = xmalloc (strlen (argv[i]) + 1);
412 strcpy (p, argv[i]);
413 }
414 append_arg (p);
415 continue;
416 }
417
418 if ((argv[i][0] == '-') && (argv[i][1] != 'l'))
419 {
f7b529fa 420 /* Not a filename or library. */
6de9cd9a 421
f7b529fa 422 if (saw_library == 1 && need_math) /* -l<library>. */
6de9cd9a
DN
423 append_arg (MATH_LIBRARY);
424
425 saw_library = 0;
426
427 lookup_option (&opt, &skip, &arg, argv[i]);
428
429 if (argv[i][1] == '\0')
430 {
f7b529fa 431 append_arg (argv[i]); /* "-" == Standard input. */
6de9cd9a
DN
432 continue;
433 }
434
435 if (opt == OPTION_x)
436 {
f7b529fa 437 /* Track input language. */
6de9cd9a
DN
438 const char *lang;
439
440 if (arg == NULL)
441 lang = argv[i + 1];
442 else
443 lang = arg;
444
445 saw_speclang = (strcmp (lang, "none") != 0);
446 }
447
448 append_arg (argv[i]);
449
450 for (; skip != 0; --skip)
451 append_arg (argv[++i]);
452
453 continue;
454 }
455
f7b529fa 456 /* A filename/library, not an option. */
6de9cd9a
DN
457
458 if (saw_speclang)
f7b529fa 459 saw_library = 0; /* -xfoo currently active. */
6de9cd9a 460 else
f7b529fa 461 { /* -lfoo or filename. */
6de9cd9a
DN
462 if (strcmp (argv[i], MATH_LIBRARY) == 0)
463 {
464 if (saw_library == 1)
f7b529fa 465 saw_library = 2; /* -l<library> -lm. */
6de9cd9a
DN
466 else
467 {
468 if (0 == use_init)
469 {
470 append_arg (FORTRAN_INIT);
471 use_init = 1;
472 }
473 append_arg (FORTRAN_LIBRARY);
474 }
475 }
476 else if (strcmp (argv[i], FORTRAN_LIBRARY) == 0)
f7b529fa 477 saw_library = 1; /* -l<library>. */
6de9cd9a 478 else
f7b529fa 479 { /* Other library, or filename. */
6de9cd9a
DN
480 if (saw_library == 1 && need_math)
481 append_arg (MATH_LIBRARY);
482 saw_library = 0;
483 }
484 }
485 append_arg (argv[i]);
486 }
487
488 /* Append `-lg2c -lm' as necessary. */
489
490 if (library)
f7b529fa 491 { /* Doing a link and no -nostdlib. */
6de9cd9a
DN
492 if (saw_speclang)
493 append_arg ("-xnone");
494
495 switch (saw_library)
496 {
497 case 0:
498 if (0 == use_init)
499 {
500 append_arg (FORTRAN_INIT);
501 use_init = 1;
502 }
503 append_arg (library);
504 case 1:
505 if (need_math)
506 append_arg (MATH_LIBRARY);
507 default:
508 break;
509 }
510 }
511
512#ifdef ENABLE_SHARED_LIBGCC
513 if (library)
514 {
515 int i;
516
517 for (i = 1; i < g77_newargc; i++)
518 if (g77_newargv[i][0] == '-')
519 if (strcmp (g77_newargv[i], "-static-libgcc") == 0
520 || strcmp (g77_newargv[i], "-static") == 0)
521 break;
522
523 if (i == g77_newargc)
524 append_arg ("-shared-libgcc");
525 }
526
527#endif
528
529 if (verbose && g77_newargv != g77_xargv)
530 {
531 fprintf (stderr, "Driving:");
532 for (i = 0; i < g77_newargc; i++)
533 fprintf (stderr, " %s", g77_newargv[i]);
534 fprintf (stderr, "\n");
535 }
536
537 *in_argc = g77_newargc;
538 *in_argv = g77_newargv;
539}
540
f7b529fa 541/* Called before linking. Returns 0 on success and -1 on failure. */
6de9cd9a 542int
f7b529fa 543lang_specific_pre_link (void) /* Not used for F77. */
6de9cd9a
DN
544{
545 return 0;
546}
547
f7b529fa
KH
548/* Number of extra output files that lang_specific_pre_link may generate. */
549int lang_specific_extra_outfiles = 0; /* Not used for F77. */
This page took 0.755514 seconds and 5 git commands to generate.