/* * Copyright (c) 1999 * Steven G. Kargl. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * This software is provided by Steven G. Kargl and contributors ``as is'' and * any express or implied warranties, including, but not limited to, the implied * warranties of merchantability and fitness for a particular purpose are * disclaimed. In no event shall Steven G. Kargl or contributors be liable for * any direct, indirect, incidental, special, exemplary, or consequential * damages (including, but not limited to, procurement of substitute goods or * services; loss of use, data, or profits; or business interruption) however * caused and on any theory of liability, whether in contract, strict liability, * or tort (including negligence or otherwise) arising in any way out of the * use of this software, even if advised of the possibility of such damage. */ #include #include #include #include #include "f77.h" #include "pathnames.h" #include "proto.h" char **files = NULL; /* Array to hold file names */ char **pp_cmd = NULL; /* Array to hold preprocessor command */ char **f2c_cmd = NULL; /* Array to hold f2c command */ char **cc_cmd = NULL; /* Array to hold cc command */ char **libdirs = NULL; /* Array to hold directories for library search */ char **libs = NULL; /* Array to hold libraries for linking */ char *output_name = NULL; /* Argument to -o option */ char *tmpdir = NULL; /* * Indices to move through the associated array. */ int index_files = 0; int index_f2c_cmd = 0; int index_cc_cmd = 0; int index_pp_cmd = 0; int index_libdirs = 0; int index_libs = 0; flags_t flags = CLEAR; int main(int argc, char *argv[]) { char **objs; char *s1, *s2, *s3; int i, len; if (argc == 1) usage(); objs = NULL; /* * Allocate arrays of strings to store the parsed command line. We add 5 * to argc because we have a few things to set that do not appear on the * command line. This might waste some space, but what the heck. */ argc += 5; files = alloc_strings(argc); objs = alloc_strings(argc); f2c_cmd = alloc_strings(argc); cc_cmd = alloc_strings(argc); pp_cmd = alloc_strings(argc); libdirs = alloc_strings(argc); libs = alloc_strings(argc); argc -= 5; f2c_cmd[index_f2c_cmd++] = mkstring(F2C_COMMAND); f2c_cmd[index_f2c_cmd++] = mkstring("-A"); cc_cmd[index_cc_cmd++] = mkstring(CC_COMMAND); pp_cmd[index_pp_cmd++] = mkstring(PP_COMMAND); #ifndef SUN_FPP /* These are GNU cpp flags that need to be set. */ pp_cmd[index_pp_cmd++] = mkstring("-nostdinc"); pp_cmd[index_pp_cmd++] = mkstring("-P"); #endif cmds(argc, argv); if (flags & PREPROCESS_ONLY) { /* * Loop over the list of files and preprocess. Only files ending * with .F will be preprocessed, all other files are ignored. */ for (i = 0; i < index_files; i++) { len = strlen(files[i]); if (files[i][len - 1] == 'F') { if (index_files == 1 && output_name) s2 = mkstring(output_name); else { s1 = extract_name(files[i]); s2 = combine(s1, "f"); free(s1); } pp_cmd[index_pp_cmd] = files[i]; pp_cmd[index_pp_cmd + 1] = s2; pp_cmd[index_pp_cmd + 2] = NULL; if (flags & ECHO) print_cmd(index_pp_cmd + 2, pp_cmd); if (phase(PP_COMMAND, pp_cmd) != 0) { fputs("f77: abnormal child return status: ", stderr); fprintf(stderr, "%s\n", files[i]); exit(1); } free(s2); } } } else if (flags & COMPILE_ONLY) { /* * If the -T option has not been given, then tmpdir is not set. * Try to get a temporary directory name. We also need to specify * where the f2c.h header file lives. Add the -o option to the * f2c command with the expectation that its argumwnt will be added * within the loop. */ if (!tmpdir) tmpdir = gettmpdir(); cc_cmd[index_cc_cmd++] = mkstring(F2C_INCLUDEDIR); f2c_cmd[index_f2c_cmd] = mkstring("-o"); if (output_name && index_files > 1) { fputs("Warning: multiple source files, -o ", stderr); fprintf(stderr, "%s, and -c\n", output_name); fputs(" option are incompatible.\n", stderr); fputs("Warning: -o option ignored.\n", stderr); } for (i = 0; i < index_files; i++) { len = strlen(files[i]); switch (files[i][len - 1]) { case 'F': /* Preprocess: file.F --> tmpdir/F77XXXX.f */ s1 = gettmpname(tmpdir, ".f"); pp_cmd[index_pp_cmd] = files[i]; pp_cmd[index_pp_cmd + 1] = s1; pp_cmd[index_pp_cmd + 2] = NULL; if (flags & ECHO) print_cmd(index_pp_cmd + 2, pp_cmd); if (phase(PP_COMMAND, pp_cmd) !=0) { fputs("f77: abnormal child return status: ", stderr); fprintf(stderr, "%s\n", files[i]); exit(1); } /* Convert: tmpdir/F77XXXX.f --> tmpdir/F77XXXX.c */ s2 = mkstring(s1); len = strlen(s2) - 1; s2[len] = 'c'; f2c_cmd[index_f2c_cmd + 1] = s2; f2c_cmd[index_f2c_cmd + 2] = s1; f2c_cmd[index_f2c_cmd + 3] = NULL; if (flags & ECHO) print_cmd(index_f2c_cmd + 3, f2c_cmd); if (phase(F2C_COMMAND, f2c_cmd) !=0) { fputs("f77: abnormal child return status: ", stderr); fprintf(stderr, "%s\n", files[i]); exit(1); } /* * Delete the temporary file tmpdir/F77XXXX.f. */ unlink(s1); /* Compile: tmpdir/F77XXXX.c --> file.o */ if (index_files == 1 && output_name) s3 = mkstring(output_name); else { free(s1); s1 = extract_name(files[i]); s3 = combine(s1, "o"); } cc_cmd[index_cc_cmd] = mkstring("-c"); cc_cmd[index_cc_cmd + 1] = mkstring("-o"); cc_cmd[index_cc_cmd + 2] = s3; cc_cmd[index_cc_cmd + 3] = s2; cc_cmd[index_cc_cmd + 4] = NULL; if (flags & ECHO) print_cmd(index_cc_cmd + 4, cc_cmd); if (phase(CC_COMMAND, cc_cmd) !=0) { fputs("f77: abnormal child return status: ", stderr); fprintf(stderr, "%s\n", files[i]); exit(1); } /* * Delete the temporary file tmpdir/F77XXXX.c, and * free memory from mkstring("-o") and mkstring("-c"). */ unlink(s2); free(cc_cmd[index_cc_cmd]); free(cc_cmd[index_cc_cmd + 1]); free(s1); free(s2); free(s3); break; case 'f': /* Convert: file.f --> tmpdir/F77XXXX.c */ s1 = gettmpname(tmpdir, ".c"); f2c_cmd[index_f2c_cmd + 1] = s1; f2c_cmd[index_f2c_cmd + 2] = files[i]; f2c_cmd[index_f2c_cmd + 3] = NULL; if (flags & ECHO) print_cmd(index_f2c_cmd + 3, f2c_cmd); if (phase(F2C_COMMAND, f2c_cmd) !=0) { fputs("f77: abnormal child return status: ", stderr); fprintf(stderr, "%s\n", files[i]); exit(1); } /* Compile: tmpdir/F77XXXX.c --> file.o */ if (index_files == 1 && output_name) s3 = mkstring(output_name); else { s2 = extract_name(files[i]); s3 = combine(s2, "o"); free(s2); } cc_cmd[index_cc_cmd] = mkstring("-c"); cc_cmd[index_cc_cmd + 1] = mkstring("-o"); cc_cmd[index_cc_cmd + 2] = s3; cc_cmd[index_cc_cmd + 3] = s1; cc_cmd[index_cc_cmd + 4] = NULL; if (flags & ECHO) print_cmd(index_cc_cmd + 4, cc_cmd); if (phase(CC_COMMAND, cc_cmd) !=0) { fputs("f77: abnormal child return status: ", stderr); fprintf(stderr, "%s\n", files[i]); exit(1); } /* * Delete the temporary file tmpdir/F77XXXX.c, and * free memory from mkstring("-o") and mkstring("-c"). */ unlink(s1); free(cc_cmd[index_cc_cmd]); free(cc_cmd[index_cc_cmd + 1]); free(s1); free(s3); break; } /* End of switch */ } /* End of for loop */ } else { /* End of COMPILE_ONLY */ /* * If the -T option has not been given, then tmpdir is not set. * Try to get a temporary directory name. We also need to specify * where the f2c.h header file lives. */ if (!tmpdir) tmpdir = gettmpdir(); cc_cmd[index_cc_cmd++] = mkstring(F2C_INCLUDEDIR); f2c_cmd[index_f2c_cmd] = mkstring("-o"); for (i = 0; i < index_files; i++) { len = strlen(files[i]); switch (files[i][len - 1]) { case 'F': /* Preprocess: file.F --> tmpdir/F77XXXX.f */ s1 = gettmpname(tmpdir, ".f"); pp_cmd[index_pp_cmd] = files[i]; pp_cmd[index_pp_cmd + 1] = s1; pp_cmd[index_pp_cmd + 2] = NULL; if (flags & ECHO) print_cmd(index_pp_cmd + 2, pp_cmd); if (phase(PP_COMMAND, pp_cmd) !=0) { fputs("f77: abnormal child return status: ", stderr); fprintf(stderr, "%s\n", files[i]); exit(1); } /* Convert: tmpdir/F77XXXX.f --> tmpdir/F77XXXX.c */ s2 = mkstring(s1); len = strlen(s2) - 1; s2[len] = 'c'; f2c_cmd[index_f2c_cmd + 1] = s2; f2c_cmd[index_f2c_cmd + 2] = s1; f2c_cmd[index_f2c_cmd + 3] = NULL; if (flags & ECHO) print_cmd(index_f2c_cmd + 3, f2c_cmd); if (phase(F2C_COMMAND, f2c_cmd) !=0) { fputs("f77: abnormal child return status: ", stderr); fprintf(stderr, "%s\n", files[i]); exit(1); } /* * Delete the temporary file tmpdir/F77XXXX.f. */ unlink(s1); /* Compile: tmpdir/F77XXXX.c --> tmpdir/F77XXXX.o */ s1[len] = 'o'; cc_cmd[index_cc_cmd] = mkstring("-c"); cc_cmd[index_cc_cmd + 1] = mkstring("-o"); cc_cmd[index_cc_cmd + 2] = s1; cc_cmd[index_cc_cmd + 3] = s2; cc_cmd[index_cc_cmd + 4] = NULL; if (flags & ECHO) print_cmd(index_cc_cmd + 4, cc_cmd); if (phase(CC_COMMAND, cc_cmd) !=0) { fputs("f77: abnormal child return status: ", stderr); fprintf(stderr, "%s\n", files[i]); exit(1); } /* * Delete the temporary file tmpdir/F77XXXX.c, and * free memory from mkstring("-o") and mkstring("-c"). */ unlink(s2); free(cc_cmd[index_cc_cmd]); free(cc_cmd[index_cc_cmd + 1]); /* Set objs[i] to point at the .o file. */ objs[i] = s1; free(s2); break; case 'f': /* Convert: file.f --> tmpdir/F77XXXX.c */ s1 = gettmpname(tmpdir, ".c"); f2c_cmd[index_f2c_cmd + 1] = s1; f2c_cmd[index_f2c_cmd + 2] = files[i]; f2c_cmd[index_f2c_cmd + 3] = NULL; if (flags & ECHO) print_cmd(index_f2c_cmd + 3, f2c_cmd); if (phase(F2C_COMMAND, f2c_cmd) !=0) { fputs("f77: abnormal child return status: ", stderr); fprintf(stderr, "%s\n", files[i]); exit(1); } /* Compile: tmpdir/F77XXXX.c --> tmpdir/F77XXXX.o */ s2 = mkstring(s1); len = strlen(s2) - 1; s2[len] = 'o'; cc_cmd[index_cc_cmd] = mkstring("-c"); cc_cmd[index_cc_cmd + 1] = mkstring("-o"); cc_cmd[index_cc_cmd + 2] = s2; cc_cmd[index_cc_cmd + 3] = s1; cc_cmd[index_cc_cmd + 4] = NULL; if (flags & ECHO) print_cmd(index_cc_cmd + 4, cc_cmd); if (phase(CC_COMMAND, cc_cmd) !=0) { fputs("f77: abnormal child return status: ", stderr); fprintf(stderr, "%s\n", files[i]); exit(1); } /* * Delete the temporary file tmpdir/F77XXXX.c, and * free memory from mkstring("-o") and mkstring("-c"). */ unlink(s1); free(cc_cmd[index_cc_cmd]); free(cc_cmd[index_cc_cmd + 1]); /* Set objs[i] to point at the .o */ objs[i] = s2; free(s1); break; default: /* * We need to save names of .o or .a files given on the * command. This will be useful for temporary file * cleanup. */ objs[i] = files[i]; } /* End of switch */ } /* End of for loop */ /* * Get ready to link the stuff. First, delete the need for * the f2c.h location. */ index_cc_cmd--; free(cc_cmd[index_cc_cmd]); /* Add the name if given */ if (output_name) { cc_cmd[index_cc_cmd++] = mkstring("-o"); cc_cmd[index_cc_cmd++] = output_name; } /* Add .o and .a files to command */ for (i = 0; i < index_files; i++) cc_cmd[index_cc_cmd++] = objs[i]; /* Add any -Ldirs */ for (i = 0; i < index_libdirs; i++) cc_cmd[index_cc_cmd++] = libdirs[i]; cc_cmd[index_cc_cmd++] = mkstring(F2C_LIBDIR); /* Add any -llib */ for (i = 0; i < index_libs; i++) cc_cmd[index_cc_cmd++] = libs[i]; cc_cmd[index_cc_cmd++] = mkstring("-lf2c"); cc_cmd[index_cc_cmd++] = mkstring("-lm"); cc_cmd[index_cc_cmd] = NULL; if (flags & ECHO) print_cmd(index_cc_cmd, cc_cmd); if (phase(CC_COMMAND, cc_cmd) !=0) { fputs("f77: abnormal child return status: ", stderr); fprintf(stderr, "%s\n", files[i]); exit(1); } /* Final step is to get rid f temporary .o files. */ for (i = 0; i < index_files; i++) { if (strcmp(objs[i], files[i]) != 0) unlink(objs[i]); } } return 0; }