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)
vec_free(self->conditions);
if (self->lex)
lex_close(self->lex);
- if (self->output_file)
- fclose(self->output_file);
mem_d(self);
}
{
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);
}
}
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;
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) {
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);
}
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;
}
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)
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 ========================*/
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")) {
int retval = 0;
bool opts_output_free = false;
bool progs_src = false;
+ FILE *outfile = NULL;
app_name = argv[0];
con_init();
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();
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");
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;
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) {
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 */
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);