00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047 #include "config.h"
00048 #include "system.h"
00049 #include "gcc.h"
00050 #include <f/version.h>
00051
00052 #ifndef MATH_LIBRARY
00053 #define MATH_LIBRARY "-lm"
00054 #endif
00055
00056 #ifndef FORTRAN_INIT
00057 #define FORTRAN_INIT "-lfrtbegin"
00058 #endif
00059
00060 #ifndef FORTRAN_LIBRARY
00061 #define FORTRAN_LIBRARY "-lg2c"
00062 #endif
00063
00064
00065
00066 typedef enum
00067 {
00068 OPTION_b,
00069 OPTION_B,
00070 OPTION_c,
00071 OPTION_driver,
00072 OPTION_E,
00073 OPTION_help,
00074 OPTION_i,
00075 OPTION_l,
00076 OPTION_L,
00077 OPTION_M,
00078 OPTION_MM,
00079 OPTION_nostdlib,
00080
00081 OPTION_o,
00082 OPTION_S,
00083 OPTION_syntax_only,
00084 OPTION_v,
00085 OPTION_version,
00086 OPTION_V,
00087 OPTION_x,
00088 OPTION_
00089 } Option;
00090
00091
00092 static int g77_xargc;
00093 static const char *const *g77_xargv;
00094 static void lookup_option PARAMS ((Option *, int *, const char **,
00095 const char *));
00096 static void append_arg PARAMS ((const char *));
00097
00098
00099 static int g77_newargc;
00100 static const char **g77_newargv;
00101
00102
00103
00104
00105
00106 #define DEFAULT_SWITCH_TAKES_ARG(CHAR) \
00107 ((CHAR) == 'D' || (CHAR) == 'U' || (CHAR) == 'o' \
00108 || (CHAR) == 'e' || (CHAR) == 'T' || (CHAR) == 'u' \
00109 || (CHAR) == 'I' || (CHAR) == 'm' || (CHAR) == 'x' \
00110 || (CHAR) == 'L' || (CHAR) == 'A')
00111
00112 #ifndef SWITCH_TAKES_ARG
00113 #define SWITCH_TAKES_ARG(CHAR) DEFAULT_SWITCH_TAKES_ARG(CHAR)
00114 #endif
00115
00116
00117
00118 #define DEFAULT_WORD_SWITCH_TAKES_ARG(STR) \
00119 (!strcmp (STR, "Tdata") || !strcmp (STR, "Ttext") \
00120 || !strcmp (STR, "Tbss") || !strcmp (STR, "include") \
00121 || !strcmp (STR, "imacros") || !strcmp (STR, "aux-info") \
00122 || !strcmp (STR, "idirafter") || !strcmp (STR, "iprefix") \
00123 || !strcmp (STR, "iwithprefix") || !strcmp (STR, "iwithprefixbefore") \
00124 || !strcmp (STR, "isystem") || !strcmp (STR, "specs"))
00125
00126 #ifndef WORD_SWITCH_TAKES_ARG
00127 #define WORD_SWITCH_TAKES_ARG(STR) DEFAULT_WORD_SWITCH_TAKES_ARG (STR)
00128 #endif
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140 static void
00141 lookup_option (xopt, xskip, xarg, text)
00142 Option *xopt;
00143 int *xskip;
00144 const char **xarg;
00145 const char *text;
00146 {
00147 Option opt = OPTION_;
00148 int skip;
00149 const char *arg = NULL;
00150
00151 if ((skip = SWITCH_TAKES_ARG (text[1])))
00152 skip -= (text[2] != '\0');
00153
00154 if (text[1] == 'B')
00155 opt = OPTION_B, skip = (text[2] == '\0'), arg = text + 2;
00156 else if (text[1] == 'b')
00157 opt = OPTION_b, skip = (text[2] == '\0'), arg = text + 2;
00158 else if ((text[1] == 'c') && (text[2] == '\0'))
00159 opt = OPTION_c, skip = 0;
00160 else if ((text[1] == 'E') && (text[2] == '\0'))
00161 opt = OPTION_E, skip = 0;
00162 else if (text[1] == 'i')
00163 opt = OPTION_i, skip = 0;
00164 else if (text[1] == 'l')
00165 opt = OPTION_l;
00166 else if (text[1] == 'L')
00167 opt = OPTION_L, arg = text + 2;
00168 else if (text[1] == 'o')
00169 opt = OPTION_o;
00170 else if ((text[1] == 'S') && (text[2] == '\0'))
00171 opt = OPTION_S, skip = 0;
00172 else if (text[1] == 'V')
00173 opt = OPTION_V, skip = (text[2] == '\0');
00174 else if ((text[1] == 'v') && (text[2] == '\0'))
00175 opt = OPTION_v, skip = 0;
00176 else if (text[1] == 'x')
00177 opt = OPTION_x, arg = text + 2;
00178 else
00179 {
00180 if ((skip = WORD_SWITCH_TAKES_ARG (text + 1)) != 0)
00181 ;
00182 else if (! strncmp (text, "-fdriver", 8))
00183 opt = OPTION_driver;
00184 else if (! strcmp (text, "-fhelp"))
00185 opt = OPTION_help;
00186 else if (! strcmp (text, "-M"))
00187 opt = OPTION_M;
00188 else if (! strcmp (text, "-MM"))
00189 opt = OPTION_MM;
00190 else if (! strcmp (text, "-nostdlib")
00191 || ! strcmp (text, "-nodefaultlibs"))
00192 opt = OPTION_nostdlib;
00193 else if (! strcmp (text, "-fsyntax-only"))
00194 opt = OPTION_syntax_only;
00195 else if (! strcmp (text, "-dumpversion"))
00196 opt = OPTION_version;
00197 else if (! strcmp (text, "-fversion"))
00198 opt = OPTION_version;
00199 else if (! strcmp (text, "-Xlinker")
00200 || ! strcmp (text, "-specs"))
00201 skip = 1;
00202 else
00203 skip = 0;
00204 }
00205
00206 if (xopt != NULL)
00207 *xopt = opt;
00208 if (xskip != NULL)
00209 *xskip = skip;
00210 if (xarg != NULL)
00211 {
00212 if ((arg != NULL)
00213 && (arg[0] == '\0'))
00214 *xarg = NULL;
00215 else
00216 *xarg = arg;
00217 }
00218 }
00219
00220
00221
00222
00223
00224 static void
00225 append_arg (arg)
00226 const char *arg;
00227 {
00228 static int newargsize;
00229
00230 #if 0
00231 fprintf (stderr, "`%s'\n", arg);
00232 #endif
00233
00234 if (g77_newargv == g77_xargv
00235 && g77_newargc < g77_xargc
00236 && (arg == g77_xargv[g77_newargc]
00237 || ! strcmp (arg, g77_xargv[g77_newargc])))
00238 {
00239 ++g77_newargc;
00240 return;
00241 }
00242
00243 if (g77_newargv == g77_xargv)
00244 {
00245 int i;
00246
00247 newargsize = (g77_xargc << 2) + 20;
00248 g77_newargv = (const char **) xmalloc (newargsize * sizeof (char *));
00249
00250
00251 for (i = 0; i < g77_newargc; ++i)
00252 g77_newargv[i] = g77_xargv[i];
00253 }
00254
00255 if (g77_newargc == newargsize)
00256 fatal ("overflowed output arg list for `%s'", arg);
00257
00258 g77_newargv[g77_newargc++] = arg;
00259 }
00260
00261 void
00262 lang_specific_driver (in_argc, in_argv, in_added_libraries)
00263 int *in_argc;
00264 const char *const **in_argv;
00265 int *in_added_libraries ATTRIBUTE_UNUSED;
00266 {
00267 int argc = *in_argc;
00268 const char *const *argv = *in_argv;
00269 int i;
00270 int verbose = 0;
00271 Option opt;
00272 int skip;
00273 const char *arg;
00274
00275
00276
00277 const char *library = FORTRAN_LIBRARY;
00278
00279
00280
00281 int saw_speclang = 0;
00282
00283
00284
00285
00286 int saw_library = 0;
00287
00288
00289
00290 int use_init = 0;
00291
00292 int need_math = (MATH_LIBRARY[0] != '\0');
00293
00294
00295 int n_infiles = 0;
00296 int n_outfiles = 0;
00297
00298 #if 0
00299 fprintf (stderr, "Incoming:");
00300 for (i = 0; i < argc; i++)
00301 fprintf (stderr, " %s", argv[i]);
00302 fprintf (stderr, "\n");
00303 #endif
00304
00305 g77_xargc = argc;
00306 g77_xargv = argv;
00307 g77_newargc = 0;
00308 g77_newargv = (const char **) argv;
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325 for (i = 1; i < argc; ++i)
00326 {
00327 if ((argv[i][0] == '+') && (argv[i][1] == 'e'))
00328 {
00329 continue;
00330 }
00331
00332 if ((argv[i][0] != '-') || (argv[i][1] == '\0'))
00333 {
00334 ++n_infiles;
00335 continue;
00336 }
00337
00338 lookup_option (&opt, &skip, NULL, argv[i]);
00339
00340 switch (opt)
00341 {
00342 case OPTION_nostdlib:
00343 case OPTION_c:
00344 case OPTION_S:
00345 case OPTION_syntax_only:
00346 case OPTION_E:
00347 case OPTION_M:
00348 case OPTION_MM:
00349
00350
00351 library = 0;
00352 break;
00353
00354 case OPTION_l:
00355 ++n_infiles;
00356 break;
00357
00358 case OPTION_o:
00359 ++n_outfiles;
00360 break;
00361
00362 case OPTION_v:
00363 verbose = 1;
00364 break;
00365
00366 case OPTION_b:
00367 case OPTION_B:
00368 case OPTION_L:
00369 case OPTION_i:
00370 case OPTION_V:
00371
00372
00373 break;
00374
00375 case OPTION_version:
00376 printf ("\
00377 GNU Fortran (GCC %s) %s\n\
00378 Copyright (C) 2002 Free Software Foundation, Inc.\n\
00379 \n\
00380 GNU Fortran comes with NO WARRANTY, to the extent permitted by law.\n\
00381 You may redistribute copies of GNU Fortran\n\
00382 under the terms of the GNU General Public License.\n\
00383 For more information about these matters, see the file named COPYING\n\
00384 or type the command `info -f g77 Copying'.\n\
00385 ", version_string, ffe_version_string);
00386 exit (0);
00387 break;
00388
00389 case OPTION_help:
00390
00391
00392 return;
00393
00394 case OPTION_driver:
00395 fatal ("--driver no longer supported");
00396 break;
00397
00398 default:
00399 break;
00400 }
00401
00402
00403
00404
00405 if (i + skip < argc)
00406 i += skip;
00407 else
00408 fatal ("argument to `%s' missing", argv[i]);
00409 }
00410
00411 if ((n_outfiles != 0) && (n_infiles == 0))
00412 fatal ("no input files; unwilling to write output files");
00413
00414
00415 if (n_infiles == 0)
00416 library = 0;
00417
00418
00419
00420 append_arg (argv[0]);
00421
00422 for (i = 1; i < argc; ++i)
00423 {
00424 if (argv[i][0] == '\0')
00425 {
00426 append_arg (argv[i]);
00427 continue;
00428 }
00429
00430 if ((argv[i][0] == '-') && (argv[i][1] != 'l'))
00431 {
00432
00433
00434 if (saw_library == 1 && need_math)
00435 append_arg (MATH_LIBRARY);
00436
00437 saw_library = 0;
00438
00439 lookup_option (&opt, &skip, &arg, argv[i]);
00440
00441 if (argv[i][1] == '\0')
00442 {
00443 append_arg (argv[i]);
00444 continue;
00445 }
00446
00447 if (opt == OPTION_x)
00448 {
00449
00450 const char *lang;
00451
00452 if (arg == NULL)
00453 lang = argv[i+1];
00454 else
00455 lang = arg;
00456
00457 saw_speclang = (strcmp (lang, "none") != 0);
00458 }
00459
00460 append_arg (argv[i]);
00461
00462 for (; skip != 0; --skip)
00463 append_arg (argv[++i]);
00464
00465 continue;
00466 }
00467
00468
00469
00470 if (saw_speclang)
00471 saw_library = 0;
00472 else
00473 {
00474 if (strcmp (argv[i], MATH_LIBRARY) == 0
00475 #ifdef ALT_LIBM
00476 || strcmp (argv[i], ALT_LIBM) == 0
00477 #endif
00478 )
00479 {
00480 if (saw_library == 1)
00481 saw_library = 2;
00482 else
00483 {
00484 if (0 == use_init)
00485 {
00486 append_arg (FORTRAN_INIT);
00487 use_init = 1;
00488 }
00489 append_arg (FORTRAN_LIBRARY);
00490 }
00491 }
00492 else if (strcmp (argv[i], FORTRAN_LIBRARY) == 0)
00493 saw_library = 1;
00494 else
00495 {
00496 if (saw_library == 1 && need_math)
00497 append_arg (MATH_LIBRARY);
00498 saw_library = 0;
00499 }
00500 }
00501 append_arg (argv[i]);
00502 }
00503
00504
00505
00506 if (library)
00507 {
00508 if (saw_speclang)
00509 append_arg ("-xnone");
00510
00511 switch (saw_library)
00512 {
00513 case 0:
00514 if (0 == use_init)
00515 {
00516 append_arg (FORTRAN_INIT);
00517 use_init = 1;
00518 }
00519 append_arg (library);
00520 case 1:
00521 if (need_math)
00522 append_arg (MATH_LIBRARY);
00523 default:
00524 break;
00525 }
00526 }
00527
00528 #ifdef ENABLE_SHARED_LIBGCC
00529 if (library)
00530 {
00531 int i;
00532
00533 for (i = 1; i < g77_newargc; i++)
00534 if (g77_newargv[i][0] == '-')
00535 if (strcmp (g77_newargv[i], "-static-libgcc") == 0
00536 || strcmp (g77_newargv[i], "-static") == 0)
00537 break;
00538
00539 if (i == g77_newargc)
00540 append_arg ("-shared-libgcc");
00541 }
00542
00543 #endif
00544
00545 if (verbose
00546 && g77_newargv != g77_xargv)
00547 {
00548 fprintf (stderr, "Driving:");
00549 for (i = 0; i < g77_newargc; i++)
00550 fprintf (stderr, " %s", g77_newargv[i]);
00551 fprintf (stderr, "\n");
00552 }
00553
00554 *in_argc = g77_newargc;
00555 *in_argv = g77_newargv;
00556 }
00557
00558
00559 int lang_specific_pre_link ()
00560 {
00561 return 0;
00562 }
00563
00564
00565 int lang_specific_extra_outfiles = 0;