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

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [gcc/] [fortran/] [gfortranspec.c] - Blame information for rev 20

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

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

powered by: WebSVN 2.1.0

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