mirror of
https://github.com/DarkPlacesEngine/gmqcc.git
synced 2025-01-31 03:50:36 +00:00
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:
parent
f0d56d07fe
commit
0330b082a2
5 changed files with 77 additions and 39 deletions
45
ftepp.c
45
ftepp.c
|
@ -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)
|
||||
|
|
6
gmqcc.h
6
gmqcc.h
|
@ -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
54
main.c
|
@ -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) {
|
||||
|
|
1
opts.def
1
opts.def
|
@ -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 */
|
||||
|
|
10
parser.c
10
parser.c
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue