mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-02-21 11:11:37 +00:00
instead of having cpp args in progs.src, potentially breaking some mods, generate progs.i as a series of #includes and then compile everything in one pass
This commit is contained in:
parent
8f097ce3dd
commit
f7df6fea17
7 changed files with 122 additions and 71 deletions
|
@ -32,8 +32,12 @@
|
|||
#ifndef __cpp_h
|
||||
#define __cpp_h
|
||||
|
||||
struct dstring_s;
|
||||
|
||||
void parse_cpp_name (void);
|
||||
void add_cpp_def (const char *arg);
|
||||
void intermediate_file (struct dstring_s *ifile, const char *filename,
|
||||
const char *ext);
|
||||
FILE * preprocess_file (const char *filename);
|
||||
extern const char *cpp_name;
|
||||
extern struct dstring_s *tempname;
|
||||
|
|
|
@ -70,6 +70,9 @@ typedef struct {
|
|||
notice_options_t notices; // Notice options
|
||||
|
||||
int verbosity; // 0=silent, goes up to 2 currently
|
||||
qboolean single_cpp; // process progs.src into a series of
|
||||
// #include directives and then compile
|
||||
// that
|
||||
qboolean save_temps; // save temporary files
|
||||
qboolean files_dat; // generate files.dat
|
||||
qboolean traditional; // behave more like qcc
|
||||
|
|
|
@ -147,6 +147,47 @@ build_cpp_args (const char *in_name, const char *out_name)
|
|||
|
||||
//============================================================================
|
||||
|
||||
void
|
||||
intermediate_file (dstring_t *ifile, const char *filename, const char *ext)
|
||||
{
|
||||
const char *temp1;
|
||||
char *temp2 = strrchr (this_program, PATH_SEPARATOR);
|
||||
|
||||
if (options.save_temps) {
|
||||
char *basename = strdup (filename);
|
||||
char *temp;
|
||||
|
||||
temp = strrchr (basename, '.');
|
||||
if (temp)
|
||||
*temp = '\0'; // ignore the rest of the string
|
||||
|
||||
temp = strrchr (basename, '/');
|
||||
if (!temp)
|
||||
temp = basename;
|
||||
else
|
||||
temp++;
|
||||
|
||||
if (*sourcedir) {
|
||||
dsprintf (ifile, "%s%c%s.%s", sourcedir,
|
||||
PATH_SEPARATOR, temp, ext);
|
||||
} else {
|
||||
dsprintf (ifile, "%s.%s", temp, ext);
|
||||
}
|
||||
free (basename);
|
||||
} else {
|
||||
temp1 = getenv ("TMPDIR");
|
||||
if ((!temp1) || (!temp1[0])) {
|
||||
temp1 = getenv ("TEMP");
|
||||
if ((!temp1) || (!temp1[0])) {
|
||||
temp1 = "/tmp";
|
||||
}
|
||||
}
|
||||
|
||||
dsprintf (ifile, "%s%c%sXXXXXX", temp1,
|
||||
PATH_SEPARATOR, temp2 ? temp2 + 1 : this_program);
|
||||
}
|
||||
}
|
||||
|
||||
FILE *
|
||||
preprocess_file (const char *filename)
|
||||
{
|
||||
|
@ -154,43 +195,9 @@ preprocess_file (const char *filename)
|
|||
pid_t pid;
|
||||
int tempfd = 0;
|
||||
#endif
|
||||
const char *temp1;
|
||||
char *temp2 = strrchr (this_program, PATH_SEPARATOR);
|
||||
|
||||
if (cpp_name) {
|
||||
if (options.save_temps) {
|
||||
char *basename = strdup (filename);
|
||||
char *temp;
|
||||
|
||||
temp = strrchr (basename, '.');
|
||||
if (temp)
|
||||
*temp = '\0'; // ignore the rest of the string
|
||||
|
||||
temp = strrchr (basename, '/');
|
||||
if (!temp)
|
||||
temp = basename;
|
||||
else
|
||||
temp++;
|
||||
|
||||
if (*sourcedir) {
|
||||
dsprintf (tempname, "%s%c%s", sourcedir,
|
||||
PATH_SEPARATOR, temp);
|
||||
} else {
|
||||
dsprintf (tempname, "%s.p", temp);
|
||||
}
|
||||
free (basename);
|
||||
} else {
|
||||
temp1 = getenv ("TMPDIR");
|
||||
if ((!temp1) || (!temp1[0])) {
|
||||
temp1 = getenv ("TEMP");
|
||||
if ((!temp1) || (!temp1[0])) {
|
||||
temp1 = "/tmp";
|
||||
}
|
||||
}
|
||||
|
||||
dsprintf (tempname, "%s%c%sXXXXXX", temp1,
|
||||
PATH_SEPARATOR, temp2 ? temp2 + 1 : this_program);
|
||||
}
|
||||
intermediate_file (tempname, filename, "p");
|
||||
build_cpp_args (filename, tempname->str);
|
||||
|
||||
#ifdef _WIN32
|
||||
|
|
|
@ -304,9 +304,9 @@ emit_assign_expr (int oper, expr_t *e)
|
|||
def_a->name);
|
||||
} else {
|
||||
if (options.traditional) {
|
||||
//FIXME correct option?
|
||||
if (options.warnings.cow)
|
||||
warning (e1, "assignment to constant %s", def_a->name);
|
||||
warning (e1, "assignment to constant %s (Moooooooo!)",
|
||||
def_a->name);
|
||||
} else
|
||||
error (e1, "assignment to constant %s", def_a->name);
|
||||
}
|
||||
|
|
|
@ -184,6 +184,7 @@ DecodeArgs (int argc, char **argv)
|
|||
options.warnings.initializer = true;
|
||||
options.warnings.unimplemented = true;
|
||||
|
||||
options.single_cpp = true;
|
||||
options.save_temps = false;
|
||||
options.verbosity = 0;
|
||||
options.strip_path = 0;
|
||||
|
@ -274,6 +275,8 @@ DecodeArgs (int argc, char **argv)
|
|||
options.code.cow = flag;
|
||||
} else if (!(strcasecmp (temp, "cpp"))) {
|
||||
cpp_name = flag ? CPP_NAME : 0;
|
||||
} else if (!(strcasecmp (temp, "single-cpp"))) {
|
||||
options.single_cpp = flag;
|
||||
} else if (!(strcasecmp (temp, "debug"))) {
|
||||
options.code.debug = flag;
|
||||
} else if (!(strcasecmp (temp, "short-circuit"))) {
|
||||
|
|
|
@ -688,14 +688,39 @@ parse_cpp_line (script_t *script, dstring_t *filename)
|
|||
Script_GetToken (script, 0);
|
||||
}
|
||||
|
||||
static int
|
||||
compile_file (const char *filename)
|
||||
{
|
||||
int err;
|
||||
|
||||
yyin = preprocess_file (filename);
|
||||
if (!yyin)
|
||||
return !options.preprocess_only;
|
||||
|
||||
pr.source_file = ReuseString (strip_path (filename));
|
||||
pr.source_line = 1;
|
||||
clear_frame_macros ();
|
||||
err = yyparse () || pr.error_count;
|
||||
fclose (yyin);
|
||||
if (cpp_name && (!options.save_temps)) {
|
||||
if (unlink (tempname->str)) {
|
||||
perror ("unlink");
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
static int
|
||||
progs_src_compile (void)
|
||||
{
|
||||
dstring_t *filename = dstring_newstr ();
|
||||
dstring_t *qc_filename = dstring_newstr ();
|
||||
dstring_t *single_name = dstring_newstr ();
|
||||
const char *src;
|
||||
int crc = 0;
|
||||
script_t *script;
|
||||
FILE *single = 0;
|
||||
|
||||
if (options.verbosity >= 1 && strcmp (sourcedir, "")) {
|
||||
printf ("Source directory: %s\n", sourcedir);
|
||||
|
@ -709,6 +734,24 @@ progs_src_compile (void)
|
|||
else
|
||||
dsprintf (filename, "%s", progs_src);
|
||||
|
||||
if (options.single_cpp) {
|
||||
intermediate_file (single_name, filename->str, "i");
|
||||
if (!options.save_temps) {
|
||||
#ifdef _WIN32
|
||||
mktemp (single_name->str);
|
||||
#else
|
||||
int tempfd = mkstemp (single_name->str);
|
||||
single = fdopen (tempfd, "rt");
|
||||
#endif
|
||||
}
|
||||
if (!single)
|
||||
single = fopen (single_name->str, "wt");
|
||||
if (!single) {
|
||||
perror (single_name->str);
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
|
||||
src = load_file (filename->str);
|
||||
if (!src) {
|
||||
fprintf (stderr, "couldn't open %s: %s\n", filename->str,
|
||||
|
@ -737,12 +780,6 @@ progs_src_compile (void)
|
|||
}
|
||||
setup_sym_file (options.output_file);
|
||||
|
||||
// Consume any aditional tokens on this line.
|
||||
// FIXME compilation options?
|
||||
// FIXME could break some progs.src files, have an optional control?
|
||||
while (Script_TokenAvailable (script, 0))
|
||||
Script_GetToken (script, 0);
|
||||
|
||||
InitData ();
|
||||
chain_initial_types ();
|
||||
|
||||
|
@ -753,41 +790,38 @@ progs_src_compile (void)
|
|||
|
||||
// compile all the files
|
||||
while (Script_GetToken (script, 1)) {
|
||||
int err;
|
||||
|
||||
if (strcmp (script->token->str, "#") == 0) {
|
||||
parse_cpp_line (script, filename);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (*sourcedir)
|
||||
dsprintf (qc_filename, "%s%c%s", sourcedir, PATH_SEPARATOR,
|
||||
script->token->str);
|
||||
else
|
||||
dsprintf (qc_filename, "%s", script->token->str);
|
||||
if (options.verbosity >= 2)
|
||||
printf ("%s:%d: compiling %s\n", script->file, script->line, qc_filename->str);
|
||||
while (1) {
|
||||
if (*sourcedir)
|
||||
dsprintf (qc_filename, "%s%c%s", sourcedir, PATH_SEPARATOR,
|
||||
script->token->str);
|
||||
else
|
||||
dsprintf (qc_filename, "%s", script->token->str);
|
||||
if (options.verbosity >= 2)
|
||||
printf ("%s:%d: compiling %s\n", script->file, script->line, qc_filename->str);
|
||||
|
||||
// Consume any aditional tokens on this line, cumulatively adding them
|
||||
// to the cpp command line.
|
||||
// FIXME is non-cumulative more desirable? make an option?
|
||||
// FIXME could break some progs.src files. have an optional control?
|
||||
while (Script_TokenAvailable (script, 0)) {
|
||||
if (single) {
|
||||
fprintf (single, "# %d \"%s\"\n", script->line, script->file);
|
||||
fprintf (single, "#include \"%s\"\n", qc_filename->str);
|
||||
} else {
|
||||
if (compile_file (qc_filename->str))
|
||||
return 1;
|
||||
}
|
||||
if (!Script_TokenAvailable (script, 0))
|
||||
break;
|
||||
Script_GetToken (script, 0);
|
||||
add_cpp_def (save_string (script->token->str));
|
||||
}
|
||||
|
||||
yyin = preprocess_file (qc_filename->str);
|
||||
if (!yyin)
|
||||
return !options.preprocess_only;
|
||||
|
||||
pr.source_file = ReuseString (strip_path (qc_filename->str));
|
||||
pr.source_line = 1;
|
||||
clear_frame_macros ();
|
||||
err = yyparse () || pr.error_count;
|
||||
fclose (yyin);
|
||||
if (cpp_name && (!options.save_temps)) {
|
||||
if (unlink (tempname->str)) {
|
||||
}
|
||||
if (single) {
|
||||
int err;
|
||||
fclose (single);
|
||||
err = compile_file (single_name->str);
|
||||
if (!options.save_temps) {
|
||||
if (unlink (single_name->str)) {
|
||||
perror ("unlink");
|
||||
exit (1);
|
||||
}
|
||||
|
|
|
@ -7,6 +7,6 @@ qwaq.dat
|
|||
@top_srcdir@/ruamoko/lib/script.r
|
||||
@top_srcdir@/ruamoko/lib/string.r
|
||||
@top_srcdir@/ruamoko/lib/Object.r
|
||||
@top_srcdir@/ruamoko/lib/Protocol.r -D__ruamoko_Object_h
|
||||
@top_srcdir@/ruamoko/lib/Protocol.r
|
||||
@srcdir@/test.r
|
||||
@srcdir@/main.qc
|
||||
|
|
Loading…
Reference in a new issue