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:
Bill Currie 2006-05-24 14:35:39 +00:00 committed by Jeff Teunissen
parent 8f097ce3dd
commit f7df6fea17
7 changed files with 122 additions and 71 deletions

View file

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

View file

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

View file

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

View file

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

View file

@ -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"))) {

View file

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

View file

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