From 78a626066ecb7dcc899fc7c7d70f6d7e403269ba Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Tue, 25 Jun 2002 21:36:10 +0000 Subject: [PATCH] get command line parsing working in an appropriate manner for separate compilation --- tools/qfcc/include/idstuff.h | 2 +- tools/qfcc/include/options.h | 2 +- tools/qfcc/source/idstuff.c | 9 +- tools/qfcc/source/options.c | 31 ++++++ tools/qfcc/source/qfcc.c | 182 ++++++++++++++++++++++++----------- 5 files changed, 167 insertions(+), 59 deletions(-) diff --git a/tools/qfcc/include/idstuff.h b/tools/qfcc/include/idstuff.h index 4f11be41c..88e87651e 100644 --- a/tools/qfcc/include/idstuff.h +++ b/tools/qfcc/include/idstuff.h @@ -38,7 +38,7 @@ struct def_s; void PrecacheSound (struct def_s *e, int ch); void PrecacheModel (struct def_s *e, int ch); void PrecacheFile (struct def_s *e, int ch); -void WriteFiles (const char *sourcedir); +int WriteFiles (const char *sourcedir); int WriteProgdefs (char *filename); #endif//__idstuff_h diff --git a/tools/qfcc/include/options.h b/tools/qfcc/include/options.h index eb45a48a8..bf5d3866e 100644 --- a/tools/qfcc/include/options.h +++ b/tools/qfcc/include/options.h @@ -72,7 +72,7 @@ typedef struct { extern options_t options; int DecodeArgs (int argc, char **argv); extern const char *progs_src; - +extern const char **source_files; extern const char *this_program; extern const char *sourcedir; diff --git a/tools/qfcc/source/idstuff.c b/tools/qfcc/source/idstuff.c index 74088375b..c90bed6e5 100644 --- a/tools/qfcc/source/idstuff.c +++ b/tools/qfcc/source/idstuff.c @@ -155,7 +155,7 @@ PrecacheFile (def_t *e, int ch) Generates files.dat, which contains all of the data files actually used by the game, to be processed by qfiles */ -void +int WriteFiles (const char *sourcedir) { FILE *f; @@ -164,8 +164,10 @@ WriteFiles (const char *sourcedir) dsprintf (filename, "%s%cfiles.dat", sourcedir, PATH_SEPARATOR); f = fopen (filename->str, "w"); - if (!f) - Error ("Couldn't open %s", filename->str); + if (!f) { + fprintf (stderr, "Couldn't open %s", filename->str); + return 1; + } fprintf (f, "%i\n", numsounds); for (i = 0; i < numsounds; i++) @@ -181,6 +183,7 @@ WriteFiles (const char *sourcedir) fclose (f); dstring_delete (filename); + return 0; } /* diff --git a/tools/qfcc/source/options.c b/tools/qfcc/source/options.c index 281590b56..9f3a8bc14 100644 --- a/tools/qfcc/source/options.c +++ b/tools/qfcc/source/options.c @@ -52,6 +52,9 @@ static const char rcsid[] = #include "options.h" const char *this_program; +const char **source_files; +static int num_files; +static int files_size; static struct option const long_options[] = { {"output-file", required_argument, 0, 'o'}, @@ -76,6 +79,8 @@ static struct option const long_options[] = { }; static const char *short_options = + "-" // magic option parsing mode doohicky (must come first) + "l:" // lib file "o:" // output file "c" // separate compilation "s:" // source dir @@ -122,6 +127,17 @@ usage (int status) exit (status); } +static void +add_file (const char *file) +{ + if (num_files >= files_size - 1) { + files_size += 16; + source_files = realloc (source_files, files_size * sizeof (char *)); + } + source_files[num_files++] = strdup (file); + source_files[num_files] = 0; +} + int DecodeArgs (int argc, char **argv) { @@ -145,6 +161,21 @@ DecodeArgs (int argc, char **argv) while ((c = getopt_long (argc, argv, short_options, long_options, 0)) != EOF) { switch (c) { + case 1: // ordinary file + add_file (optarg); + break; + case 'o': + if (options.output_file) { + fprintf (stderr, "%s: -o must not be used more than once\n", + this_program); + exit (1); + } else { + options.output_file = strdup (optarg); + } + break; + case 'l': // lib file + add_file (va ("-l%s", optarg)); + break; case 'h': // help usage (0); break; diff --git a/tools/qfcc/source/qfcc.c b/tools/qfcc/source/qfcc.c index 6c1490e41..31a3a25ec 100644 --- a/tools/qfcc/source/qfcc.c +++ b/tools/qfcc/source/qfcc.c @@ -124,7 +124,7 @@ InitData (void) } -void +int WriteData (int crc) { def_t *def; @@ -251,7 +251,7 @@ WriteData (int crc) fclose (h); if (!options.code.debug) { - return; + return 0; } h = SafeOpenRead (options.output_file); @@ -298,6 +298,7 @@ WriteData (int crc) fseek (h, 0, SEEK_SET); SafeWrite (h, &debug, sizeof (debug)); fclose (h); + return 0; } @@ -390,58 +391,13 @@ strip_path (const char *filename) return filename; } -/* - main - - The nerve center of our little operation -*/ -int -main (int argc, char **argv) +static void +setup_sym_file (const char *output_file) { - char *src; - dstring_t *filename = dstring_newstr (); - int crc = 0; - double start, stop; - - start = Sys_DoubleTime (); - - this_program = argv[0]; - - DecodeArgs (argc, argv); - - tempname = dstring_new (); - parse_cpp_name (); - - if (options.verbosity >= 1 && strcmp (sourcedir, "")) { - printf ("Source directory: %s\n", sourcedir); - } - if (options.verbosity >= 1 && strcmp (progs_src, "progs.src")) { - printf ("progs.src: %s\n", progs_src); - } - - opcode_init (); - - InitData (); - init_types (); - - if (*sourcedir) - dsprintf (filename, "%s/%s", sourcedir, progs_src); - else - dsprintf (filename, "%s", progs_src); - LoadFile (filename->str, (void *) &src); - - if (!(src = Parse (src))) - Error ("No destination filename. qfcc --help for info.\n"); - - if (!options.output_file) - options.output_file = strdup (qfcc_com_token); - if (options.verbosity >= 1) { - printf ("output file: %s\n", options.output_file); - } if (options.code.debug) { char *s; - strcpy (debugfile, qfcc_com_token); + strcpy (debugfile, output_file); s = debugfile + strlen (debugfile); while (s-- > debugfile) { @@ -456,6 +412,85 @@ main (int argc, char **argv) if (options.verbosity >= 1) printf ("debug file: %s\n", debugfile); } +} + +static int +separate_compile (void) +{ + const char **file; + dstring_t *output_file = dstring_newstr (); + dstring_t *extension = dstring_newstr (); + char *f; + + if (options.compile && options.output_file && source_files[1]) { + fprintf (stderr, "%s: cannot use -c and -o together with multiple " + "files\n", this_program); + return 1; + } + + for (file = source_files; *file; file++) { + dstring_clearstr (extension); + dstring_clearstr (output_file); + dstring_appendstr (output_file, *file); + + f = output_file->str + strlen (output_file->str); + while (f >= output_file->str && *f != '.' && *f != '/') + f--; + if (*f == '.') { + output_file->size -= strlen (f); + dstring_appendstr (extension, f); + *f = 0; + } + dstring_appendstr (output_file, ".qfo"); + if (strncmp (*file, "-l", 2) + && (!strcmp (extension->str, ".r") + || !strcmp (extension->str, ".qc"))) { + free ((char *)*file); + *file = strdup (output_file->str); + } else { + if (options.compile) + fprintf (stderr, "%s: %s: ignoring object file since linking " + "not done\n", this_program, *file); + } + } + if (!options.compile) { + for (file = source_files; *file; file++) { + } + } + return 0; +} + +static int +progs_src_compile (void) +{ + dstring_t *filename = dstring_newstr (); + char *src; + int crc = 0; + + if (options.verbosity >= 1 && strcmp (sourcedir, "")) { + printf ("Source directory: %s\n", sourcedir); + } + if (options.verbosity >= 1 && strcmp (progs_src, "progs.src")) { + printf ("progs.src: %s\n", progs_src); + } + + if (*sourcedir) + dsprintf (filename, "%s/%s", sourcedir, progs_src); + else + dsprintf (filename, "%s", progs_src); + LoadFile (filename->str, (void *) &src); + + if (!(src = Parse (src))) { + fprintf (stderr, "No destination filename. qfcc --help for info.\n"); + return 1; + } + + if (!options.output_file) + options.output_file = strdup (qfcc_com_token); + if (options.verbosity >= 1) { + printf ("output file: %s\n", options.output_file); + } + setup_sym_file (options.output_file); begin_compilation (); @@ -498,21 +533,60 @@ main (int argc, char **argv) if (options.compile) { write_obj_file (options.output_file); } else { - if (!finish_compilation ()) - Error ("compilation errors"); + if (!finish_compilation ()) { + fprintf (stderr, "compilation errors\n"); + return 1; + } // write progdefs.h if (options.code.progsversion == PROG_ID_VERSION) crc = WriteProgdefs ("progdefs.h"); // write data file - WriteData (crc); + if (WriteData (crc)) + return 1; // write files.dat if (options.files_dat) - WriteFiles (sourcedir); + if (WriteFiles (sourcedir)) + return 1; } + return 0; +} + +/* + main + + The nerve center of our little operation +*/ +int +main (int argc, char **argv) +{ + double start, stop; + int res; + + start = Sys_DoubleTime (); + + this_program = argv[0]; + + DecodeArgs (argc, argv); + + tempname = dstring_new (); + parse_cpp_name (); + + opcode_init (); + init_types (); + + InitData (); + + if (source_files) { + res = separate_compile (); + } else { + res = progs_src_compile (); + } + if (res) + return res; stop = Sys_DoubleTime (); if (options.verbosity >= 0) printf ("Compilation time: %0.3g seconds.\n", (stop - start));