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

45
ftepp.c
View file

@ -62,9 +62,7 @@ typedef struct {
ppcondition *conditions;
ppmacro **macros;
bool to_string;
char *output;
FILE *output_file;
char *output_string;
} ftepp_t;
#define ftepp_tokval(f) ((f)->lex->tok.value)
@ -174,8 +172,6 @@ static void ftepp_delete(ftepp_t *self)
vec_free(self->conditions);
if (self->lex)
lex_close(self->lex);
if (self->output_file)
fclose(self->output_file);
mem_d(self);
}
@ -185,12 +181,8 @@ static void ftepp_out(ftepp_t *ftepp, const char *str, bool ignore_cond)
{
size_t len;
char *data;
if (!ftepp->to_string) {
fprintf((ftepp->output_file ? ftepp->output_file : stdout), "%s", str);
return;
}
len = strlen(str);
data = vec_add(ftepp->output, len);
data = vec_add(ftepp->output_string, 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_macro_expand(ftepp_t *ftepp, ppmacro *macro, macroparam *params)
{
char *old_string = ftepp->output;
bool old_string_flag = ftepp->to_string;
char *old_string = ftepp->output_string;
lex_file *old_lexer = ftepp->lex;
bool retval = true;
@ -461,8 +452,7 @@ static bool ftepp_macro_expand(ftepp_t *ftepp, ppmacro *macro, macroparam *param
if (!vec_size(macro->output))
return true;
ftepp->output = NULL;
ftepp->to_string = true;
ftepp->output_string = NULL;
for (o = 0; o < vec_size(macro->output); ++o) {
pptoken *out = macro->output[o];
switch (out->token) {
@ -498,19 +488,18 @@ static bool ftepp_macro_expand(ftepp_t *ftepp, ppmacro *macro, macroparam *param
break;
}
}
vec_push(ftepp->output, 0);
vec_push(ftepp->output_string, 0);
/* 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) {
ftepp_error(ftepp, "internal error: failed to instantiate lexer");
retval = false;
goto cleanup;
}
ftepp->output = old_string;
ftepp->to_string = old_string_flag;
ftepp->output_string = old_string;
ftepp->lex = inlex;
if (!ftepp_preprocess(ftepp)) {
lex_close(ftepp->lex);
@ -519,9 +508,8 @@ static bool ftepp_macro_expand(ftepp_t *ftepp, ppmacro *macro, macroparam *param
}
cleanup:
ftepp->lex = old_lexer;
ftepp->output = old_string;
ftepp->to_string = old_string_flag;
ftepp->lex = old_lexer;
ftepp->output_string = old_string;
return retval;
}
@ -1056,13 +1044,22 @@ bool ftepp_preprocess_string(const char *name, const char *str)
return ftepp_preprocess_done();
}
bool ftepp_init(FILE *out)
bool ftepp_init()
{
ftepp = ftepp_new();
ftepp->output_file = out;
return !!ftepp;
}
const char *ftepp_get()
{
return ftepp->output_string;
}
void ftepp_flush()
{
vec_free(ftepp->output_string);
}
void ftepp_finish()
{
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_finish (const char *output);
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 ========================*/
/*===================================================================*/
bool ftepp_init (FILE *out);
bool ftepp_init ();
bool ftepp_preprocess_file (const char *filename);
bool ftepp_preprocess_string(const char *name, const char *str);
void ftepp_finish ();
const char *ftepp_get ();
void ftepp_flush ();
/*===================================================================*/
/*======================= main.c commandline ========================*/

54
main.c
View file

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

View file

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

View file

@ -3425,6 +3425,16 @@ bool parser_compile_file(const char *filename)
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)
{
parser->lex = lex_open_string(str, strlen(str), name);