mirror of
https://github.com/DarkPlacesEngine/gmqcc.git
synced 2025-02-12 06:42:18 +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
43
ftepp.c
43
ftepp.c
|
@ -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)
|
||||||
|
|
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_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
50
main.c
|
@ -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);
|
||||||
|
|
1
opts.def
1
opts.def
|
@ -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 */
|
||||||
|
|
10
parser.c
10
parser.c
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue