mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-01-18 06:51:47 +00:00
get command line parsing working in an appropriate manner for separate
compilation
This commit is contained in:
parent
8ddca92dd9
commit
78a626066e
5 changed files with 167 additions and 59 deletions
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
|
|
Loading…
Reference in a new issue