get command line parsing working in an appropriate manner for separate

compilation
This commit is contained in:
Bill Currie 2002-06-25 21:36:10 +00:00
parent 8ddca92dd9
commit 78a626066e
5 changed files with 167 additions and 59 deletions

View file

@ -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

View file

@ -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;

View file

@ -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;
}
/*

View file

@ -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;

View file

@ -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));