The ftepp now always outputs into a string buffer, with -E the buffer will be dumped to stdout or the via -o specified file, without -E it'll be passed to the parser to be compiled

This commit is contained in:
Wolfgang (Blub) Bumiller 2012-11-18 13:33:53 +01:00
parent f0d56d07fe
commit 0330b082a2
5 changed files with 77 additions and 39 deletions

43
ftepp.c
View file

@ -62,9 +62,7 @@ typedef struct {
ppcondition *conditions; ppcondition *conditions;
ppmacro **macros; ppmacro **macros;
bool to_string; char *output_string;
char *output;
FILE *output_file;
} ftepp_t; } ftepp_t;
#define ftepp_tokval(f) ((f)->lex->tok.value) #define ftepp_tokval(f) ((f)->lex->tok.value)
@ -174,8 +172,6 @@ static void ftepp_delete(ftepp_t *self)
vec_free(self->conditions); vec_free(self->conditions);
if (self->lex) if (self->lex)
lex_close(self->lex); lex_close(self->lex);
if (self->output_file)
fclose(self->output_file);
mem_d(self); mem_d(self);
} }
@ -185,12 +181,8 @@ static void ftepp_out(ftepp_t *ftepp, const char *str, bool ignore_cond)
{ {
size_t len; size_t len;
char *data; char *data;
if (!ftepp->to_string) {
fprintf((ftepp->output_file ? ftepp->output_file : stdout), "%s", str);
return;
}
len = strlen(str); len = strlen(str);
data = vec_add(ftepp->output, len); data = vec_add(ftepp->output_string, len);
memcpy(data, str, len); memcpy(data, str, len);
} }
} }
@ -449,8 +441,7 @@ static bool macro_params_find(ppmacro *macro, const char *name, size_t *idx)
static bool ftepp_preprocess(ftepp_t *ftepp); static bool ftepp_preprocess(ftepp_t *ftepp);
static bool ftepp_macro_expand(ftepp_t *ftepp, ppmacro *macro, macroparam *params) static bool ftepp_macro_expand(ftepp_t *ftepp, ppmacro *macro, macroparam *params)
{ {
char *old_string = ftepp->output; char *old_string = ftepp->output_string;
bool old_string_flag = ftepp->to_string;
lex_file *old_lexer = ftepp->lex; lex_file *old_lexer = ftepp->lex;
bool retval = true; bool retval = true;
@ -461,8 +452,7 @@ static bool ftepp_macro_expand(ftepp_t *ftepp, ppmacro *macro, macroparam *param
if (!vec_size(macro->output)) if (!vec_size(macro->output))
return true; return true;
ftepp->output = NULL; ftepp->output_string = NULL;
ftepp->to_string = true;
for (o = 0; o < vec_size(macro->output); ++o) { for (o = 0; o < vec_size(macro->output); ++o) {
pptoken *out = macro->output[o]; pptoken *out = macro->output[o];
switch (out->token) { switch (out->token) {
@ -498,19 +488,18 @@ static bool ftepp_macro_expand(ftepp_t *ftepp, ppmacro *macro, macroparam *param
break; break;
} }
} }
vec_push(ftepp->output, 0); vec_push(ftepp->output_string, 0);
/* Now run the preprocessor recursively on this string buffer */ /* Now run the preprocessor recursively on this string buffer */
/* /*
printf("__________\n%s\n=========\n", ftepp->output); printf("__________\n%s\n=========\n", ftepp->output_string);
*/ */
inlex = lex_open_string(ftepp->output, vec_size(ftepp->output)-1, ftepp->lex->name); inlex = lex_open_string(ftepp->output_string, vec_size(ftepp->output_string)-1, ftepp->lex->name);
if (!inlex) { if (!inlex) {
ftepp_error(ftepp, "internal error: failed to instantiate lexer"); ftepp_error(ftepp, "internal error: failed to instantiate lexer");
retval = false; retval = false;
goto cleanup; goto cleanup;
} }
ftepp->output = old_string; ftepp->output_string = old_string;
ftepp->to_string = old_string_flag;
ftepp->lex = inlex; ftepp->lex = inlex;
if (!ftepp_preprocess(ftepp)) { if (!ftepp_preprocess(ftepp)) {
lex_close(ftepp->lex); lex_close(ftepp->lex);
@ -520,8 +509,7 @@ static bool ftepp_macro_expand(ftepp_t *ftepp, ppmacro *macro, macroparam *param
cleanup: cleanup:
ftepp->lex = old_lexer; ftepp->lex = old_lexer;
ftepp->output = old_string; ftepp->output_string = old_string;
ftepp->to_string = old_string_flag;
return retval; return retval;
} }
@ -1056,13 +1044,22 @@ bool ftepp_preprocess_string(const char *name, const char *str)
return ftepp_preprocess_done(); return ftepp_preprocess_done();
} }
bool ftepp_init(FILE *out) bool ftepp_init()
{ {
ftepp = ftepp_new(); ftepp = ftepp_new();
ftepp->output_file = out;
return !!ftepp; return !!ftepp;
} }
const char *ftepp_get()
{
return ftepp->output_string;
}
void ftepp_flush()
{
vec_free(ftepp->output_string);
}
void ftepp_finish() void ftepp_finish()
{ {
if (!ftepp) if (!ftepp)

View file

@ -751,14 +751,18 @@ bool parser_compile_file (const char *filename);
bool parser_compile_string(const char *name, const char *str); bool parser_compile_string(const char *name, const char *str);
bool parser_finish (const char *output); bool parser_finish (const char *output);
void parser_cleanup (); void parser_cleanup ();
/* There's really no need to strlen() preprocessed files */
bool parser_compile_string_len(const char *name, const char *str, size_t len);
/*===================================================================*/ /*===================================================================*/
/*====================== ftepp.c commandline ========================*/ /*====================== ftepp.c commandline ========================*/
/*===================================================================*/ /*===================================================================*/
bool ftepp_init (FILE *out); bool ftepp_init ();
bool ftepp_preprocess_file (const char *filename); bool ftepp_preprocess_file (const char *filename);
bool ftepp_preprocess_string(const char *name, const char *str); bool ftepp_preprocess_string(const char *name, const char *str);
void ftepp_finish (); void ftepp_finish ();
const char *ftepp_get ();
void ftepp_flush ();
/*===================================================================*/ /*===================================================================*/
/*======================= main.c commandline ========================*/ /*======================= main.c commandline ========================*/

50
main.c
View file

@ -202,6 +202,7 @@ static bool options_parse(int argc, char **argv) {
options_set(opts_flags, ADJUST_VECTOR_FIELDS, false); options_set(opts_flags, ADJUST_VECTOR_FIELDS, false);
opts_standard = COMPILER_QCC; opts_standard = COMPILER_QCC;
} else if (!strcmp(argarg, "fte") || !strcmp(argarg, "fteqcc")) { } else if (!strcmp(argarg, "fte") || !strcmp(argarg, "fteqcc")) {
options_set(opts_flags, FTEPP, true);
options_set(opts_flags, ADJUST_VECTOR_FIELDS, false); options_set(opts_flags, ADJUST_VECTOR_FIELDS, false);
opts_standard = COMPILER_FTEQCC; opts_standard = COMPILER_FTEQCC;
} else if (!strcmp(argarg, "qccx")) { } else if (!strcmp(argarg, "qccx")) {
@ -416,6 +417,7 @@ int main(int argc, char **argv) {
int retval = 0; int retval = 0;
bool opts_output_free = false; bool opts_output_free = false;
bool progs_src = false; bool progs_src = false;
FILE *outfile = NULL;
app_name = argv[0]; app_name = argv[0];
con_init(); con_init();
@ -440,6 +442,7 @@ int main(int argc, char **argv) {
options_set(opts_warn, WARN_MULTIFILE_IF, true); options_set(opts_warn, WARN_MULTIFILE_IF, true);
options_set(opts_flags, ADJUST_VECTOR_FIELDS, true); options_set(opts_flags, ADJUST_VECTOR_FIELDS, true);
options_set(opts_flags, FTEPP, false);
if (!options_parse(argc, argv)) { if (!options_parse(argc, argv)) {
return usage(); return usage();
@ -466,6 +469,19 @@ int main(int argc, char **argv) {
con_out("standard = %i\n", opts_standard); con_out("standard = %i\n", opts_standard);
} }
if (opts_pp_only) {
if (opts_output_wasset) {
outfile = util_fopen(opts_output, "wb");
if (!outfile) {
con_err("failed to open `%s` for writing\n", opts_output);
retval = 1;
goto cleanup;
}
}
else
outfile = stdout;
}
if (!opts_pp_only) { if (!opts_pp_only) {
if (!parser_init()) { if (!parser_init()) {
con_err("failed to initialize parser\n"); con_err("failed to initialize parser\n");
@ -473,17 +489,8 @@ int main(int argc, char **argv) {
goto cleanup; goto cleanup;
} }
} }
if (opts_pp_only || opts_standard == COMPILER_FTEQCC) { if (opts_pp_only || OPTS_FLAG(FTEPP)) {
FILE *out = NULL; if (!ftepp_init()) {
if (opts_output_wasset) {
out = util_fopen(opts_output, "wb");
if (!out) {
con_err("failed to open `%s` for writing\n", opts_output);
retval = 1;
goto cleanup;
}
}
if (!ftepp_init(out)) {
con_err("failed to initialize parser\n"); con_err("failed to initialize parser\n");
retval = 1; retval = 1;
goto cleanup; goto cleanup;
@ -555,11 +562,30 @@ srcdone:
retval = 1; retval = 1;
goto cleanup; goto cleanup;
} }
fprintf(outfile, "%s", ftepp_get());
ftepp_flush();
} }
else if (!parser_compile_file(items[itr].filename)) { else {
if (OPTS_FLAG(FTEPP)) {
const char *data;
if (!ftepp_preprocess_file(items[itr].filename)) {
retval = 1; retval = 1;
goto cleanup; goto cleanup;
} }
data = ftepp_get();
if (!parser_compile_string_len(items[itr].filename, data, vec_size(data)-1)) {
retval = 1;
goto cleanup;
}
ftepp_flush();
}
else {
if (!parser_compile_file(items[itr].filename)) {
retval = 1;
goto cleanup;
}
}
}
if (progs_src) { if (progs_src) {
mem_d(items[itr].filename); mem_d(items[itr].filename);

View file

@ -31,6 +31,7 @@
GMQCC_DEFINE_FLAG(DARKPLACES_STRING_TABLE_BUG) GMQCC_DEFINE_FLAG(DARKPLACES_STRING_TABLE_BUG)
GMQCC_DEFINE_FLAG(OMIT_NULL_BYTES) GMQCC_DEFINE_FLAG(OMIT_NULL_BYTES)
GMQCC_DEFINE_FLAG(ADJUST_VECTOR_FIELDS) GMQCC_DEFINE_FLAG(ADJUST_VECTOR_FIELDS)
GMQCC_DEFINE_FLAG(FTEPP)
#endif #endif
/* warning flags */ /* warning flags */

View file

@ -3425,6 +3425,16 @@ bool parser_compile_file(const char *filename)
return parser_compile(); return parser_compile();
} }
bool parser_compile_string_len(const char *name, const char *str, size_t len)
{
parser->lex = lex_open_string(str, len, name);
if (!parser->lex) {
con_err("failed to create lexer for string \"%s\"\n", name);
return false;
}
return parser_compile();
}
bool parser_compile_string(const char *name, const char *str) bool parser_compile_string(const char *name, const char *str)
{ {
parser->lex = lex_open_string(str, strlen(str), name); parser->lex = lex_open_string(str, strlen(str), name);