Since like with parsing, the preprocessor state has to be preserved across files for macros, we do that now, and with that introduce a new warning: -Wmultifile-if in case an #if spans over several command-line-provided source files (or progs.src file provided for that matter)

This commit is contained in:
Wolfgang (Blub) Bumiller 2012-11-18 11:54:11 +01:00
parent 2b65ea599f
commit 366557bbab
4 changed files with 50 additions and 11 deletions

40
ftepp.c
View file

@ -152,7 +152,7 @@ static void ppmacro_delete(ppmacro *self)
mem_d(self);
}
static ftepp_t* ftepp_init()
static ftepp_t* ftepp_new()
{
ftepp_t *ftepp;
@ -509,6 +509,7 @@ static bool ftepp_macro_expand(ftepp_t *ftepp, ppmacro *macro, macroparam *param
ftepp->output_string = old_string_flag;
ftepp->lex = inlex;
if (!ftepp_preprocess(ftepp)) {
lex_close(ftepp->lex);
retval = false;
goto cleanup;
}
@ -1005,9 +1006,25 @@ static bool ftepp_preprocess(ftepp_t *ftepp)
return newline;
}
/* Like in parser.c - files keep the previous state so we have one global
* preprocessor. Except here we will want to warn about dangling #ifs.
*/
static ftepp_t *ftepp;
static bool ftepp_preprocess_done()
{
bool retval = true;
lex_close(ftepp->lex);
ftepp->lex = NULL;
if (vec_size(ftepp->conditions)) {
if (ftepp_warn(ftepp, WARN_MULTIFILE_IF, "#if spanning multiple files, is this intended?"))
retval = false;
}
return retval;
}
bool ftepp_preprocess_file(const char *filename)
{
ftepp_t *ftepp = ftepp_init();
ftepp->lex = lex_open(filename);
if (!ftepp->lex) {
con_out("failed to open file \"%s\"\n", filename);
@ -1017,13 +1034,12 @@ bool ftepp_preprocess_file(const char *filename)
ftepp_delete(ftepp);
return false;
}
ftepp_delete(ftepp);
return true;
return ftepp_preprocess_done();
}
bool ftepp_preprocess_string(const char *name, const char *str)
{
ftepp_t *ftepp = ftepp_init();
ftepp_t *ftepp = ftepp_new();
ftepp->lex = lex_open_string(str, strlen(str), name);
if (!ftepp->lex) {
con_out("failed to create lexer for string \"%s\"\n", name);
@ -1033,6 +1049,16 @@ bool ftepp_preprocess_string(const char *name, const char *str)
ftepp_delete(ftepp);
return false;
}
ftepp_delete(ftepp);
return true;
return ftepp_preprocess_done();
}
bool ftepp_init()
{
ftepp = ftepp_new();
return !!ftepp;
}
void ftepp_finish()
{
ftepp_delete(ftepp);
}

View file

@ -755,8 +755,10 @@ void parser_cleanup ();
/*===================================================================*/
/*====================== ftepp.c commandline ========================*/
/*===================================================================*/
bool ftepp_init ();
bool ftepp_preprocess_file (const char *filename);
bool ftepp_preprocess_string(const char *name, const char *str);
void ftepp_finish ();
/*===================================================================*/
/*======================= main.c commandline ========================*/

18
main.c
View file

@ -436,6 +436,7 @@ int main(int argc, char **argv) {
options_set(opts_warn, WARN_END_SYS_FIELDS, true);
options_set(opts_warn, WARN_ASSIGN_FUNCTION_TYPES, true);
options_set(opts_warn, WARN_PREPROCESSOR, true);
options_set(opts_warn, WARN_MULTIFILE_IF, true);
options_set(opts_flags, ADJUST_VECTOR_FIELDS, true);
@ -464,10 +465,19 @@ int main(int argc, char **argv) {
con_out("standard = %i\n", opts_standard);
}
if (!parser_init()) {
con_out("failed to initialize parser\n");
retval = 1;
goto cleanup;
if (!opts_pp_only) {
if (!parser_init()) {
con_err("failed to initialize parser\n");
retval = 1;
goto cleanup;
}
}
if (opts_pp_only || opts_standard == COMPILER_FTEQCC) {
if (!ftepp_init()) {
con_err("failed to initialize parser\n");
retval = 1;
goto cleanup;
}
}
util_debug("COM", "starting ...\n");

View file

@ -53,6 +53,7 @@
GMQCC_DEFINE_FLAG(END_SYS_FIELDS)
GMQCC_DEFINE_FLAG(ASSIGN_FUNCTION_TYPES)
GMQCC_DEFINE_FLAG(PREPROCESSOR)
GMQCC_DEFINE_FLAG(MULTIFILE_IF)
#endif
/* some cleanup so we don't have to */