char *output_string;
char *itemname;
+ char *includename;
} ftepp_t;
#define ftepp_tokval(f) ((f)->lex->tok.value)
ftepp->errors++;
va_start(ap, fmt);
- con_vprintmsg(LVL_ERROR, ctx.file, ctx.line, "error", fmt, ap);
+ con_cvprintmsg((void*)&ctx, LVL_ERROR, "error", fmt, ap);
va_end(ap);
}
ftepp->errors++;
va_start(ap, fmt);
- con_vprintmsg(LVL_ERROR, ftepp->lex->tok.ctx.file, ftepp->lex->tok.ctx.line, "error", fmt, ap);
+ con_cvprintmsg((void*)&ftepp->lex->tok.ctx, LVL_ERROR, "error", fmt, ap);
va_end(ap);
}
}
va_start(ap, fmt);
- con_vprintmsg(lvl, ftepp->lex->tok.ctx.file, ftepp->lex->tok.ctx.line, "error", fmt, ap);
+ con_cvprintmsg((void*)&ftepp->lex->tok.ctx, lvl, "error", fmt, ap);
va_end(ap);
return opts_werror;
}
static ppmacro *ppmacro_new(lex_ctx ctx, const char *name)
{
ppmacro *macro = (ppmacro*)mem_a(sizeof(ppmacro));
+
+ (void)ctx;
memset(macro, 0, sizeof(*macro));
macro->name = util_strdup(name);
return macro;
size_t i;
if (self->itemname)
mem_d(self->itemname);
+ if (self->includename)
+ vec_free(self->includename);
for (i = 0; i < vec_size(self->macros); ++i)
ppmacro_delete(self->macros[i]);
vec_free(self->macros);
*out = 0;
}
-static char *ftepp_include_find(ftepp_t *ftepp, const char *file)
+static char *ftepp_include_find_path(const char *file, const char *pathfile)
{
- char *filename = NULL;
- size_t len;
+ FILE *fp;
+ char *filename = NULL;
+ const char *last_slash;
+ size_t len;
- if (ftepp->itemname) {
- const char *last_slash;
- last_slash = strrchr(ftepp->itemname, '/');
- if (last_slash) {
- len = last_slash - ftepp->itemname;
- memcpy(vec_add(filename, len), ftepp->itemname, len);
+ if (!pathfile)
+ return NULL;
+
+ last_slash = strrchr(pathfile, '/');
+
+ if (last_slash) {
+ len = last_slash - pathfile;
+ memcpy(vec_add(filename, len), pathfile, len);
+ vec_push(filename, '/');
+ }
+ else {
+ len = strlen(pathfile);
+ memcpy(vec_add(filename, len), pathfile, len);
+ if (vec_last(filename) != '/')
vec_push(filename, '/');
- }
- else {
- len = strlen(ftepp->itemname);
- memcpy(vec_add(filename, len), ftepp->itemname, len);
- if (vec_last(filename) != '/')
- vec_push(filename, '/');
- }
}
+
len = strlen(file);
- memcpy(vec_add(filename, len), file, len);
- vec_push(filename, 0);
+ memcpy(vec_add(filename, len+1), file, len);
+ vec_last(filename) = 0;
+
+ fp = util_fopen(filename, "rb");
+ if (fp) {
+ fclose(fp);
+ return filename;
+ }
+ vec_free(filename);
+ return NULL;
+}
+
+static char *ftepp_include_find(ftepp_t *ftepp, const char *file)
+{
+ char *filename = NULL;
+
+ filename = ftepp_include_find_path(file, ftepp->includename);
+ if (!filename)
+ filename = ftepp_include_find_path(file, ftepp->itemname);
return filename;
}
lex_ctx ctx;
char lineno[128];
char *filename;
+ char *old_includename;
(void)ftepp_next(ftepp);
if (!ftepp_skipspace(ftepp))
ftepp_out(ftepp, ")\n#pragma line(1)\n", false);
filename = ftepp_include_find(ftepp, ftepp_tokval(ftepp));
+ if (!filename) {
+ ftepp_error(ftepp, "failed to open include file `%s`", ftepp_tokval(ftepp));
+ return false;
+ }
inlex = lex_open(filename);
if (!inlex) {
ftepp_error(ftepp, "failed to open include file `%s`", filename);
vec_free(filename);
return false;
}
- vec_free(filename);
ftepp->lex = inlex;
+ old_includename = ftepp->includename;
+ ftepp->includename = filename;
if (!ftepp_preprocess(ftepp)) {
+ vec_free(ftepp->includename);
+ ftepp->includename = old_includename;
lex_close(ftepp->lex);
ftepp->lex = old_lexer;
return false;
}
+ vec_free(ftepp->includename);
+ ftepp->includename = old_includename;
lex_close(ftepp->lex);
ftepp->lex = old_lexer;
ftepp_error(ftepp, "unrecognized preprocessor directive: `%s`", ftepp_tokval(ftepp));
return false;
}
- break;
+ /* break; never reached */
default:
ftepp_error(ftepp, "unexpected preprocessor token: `%s`", ftepp_tokval(ftepp));
return false;
static bool ftepp_preprocess_done()
{
bool retval = true;
- lex_close(ftepp->lex);
- ftepp->lex = NULL;
if (vec_size(ftepp->conditions)) {
if (ftepp_warn(ftepp, WARN_MULTIFILE_IF, "#if spanning multiple files, is this intended?"))
retval = false;
}
+ lex_close(ftepp->lex);
+ ftepp->lex = NULL;
if (ftepp->itemname) {
mem_d(ftepp->itemname);
ftepp->itemname = NULL;
con_out("failed to open file \"%s\"\n", filename);
return false;
}
- if (!ftepp_preprocess(ftepp)) {
- ftepp_delete(ftepp);
+ if (!ftepp_preprocess(ftepp))
return false;
- }
return ftepp_preprocess_done();
}
con_out("failed to create lexer for string \"%s\"\n", name);
return false;
}
- if (!ftepp_preprocess(ftepp)) {
- ftepp_delete(ftepp);
+ if (!ftepp_preprocess(ftepp))
return false;
- }
return ftepp_preprocess_done();
}
bool ftepp_init()
{
ftepp = ftepp_new();
- return !!ftepp;
+ if (!ftepp)
+ return false;
+ ftepp_add_define(NULL, "GMQCC");
+ return true;
+}
+
+void ftepp_add_define(const char *source, const char *name)
+{
+ ppmacro *macro;
+ lex_ctx ctx = { "__builtin__", 0 };
+ ctx.file = source;
+ macro = ppmacro_new(ctx, name);
+ vec_push(ftepp->macros, macro);
}
const char *ftepp_get()