X-Git-Url: https://git.xonotic.org/?a=blobdiff_plain;ds=sidebyside;f=ftepp.c;h=7337ba3571efec36117426617adadc856757991f;hb=eb2a74f7e7968f99f6a9e01de838a900ebd6efe0;hp=11b446525968fabc19195ed0ef972135ce4b9d6e;hpb=76614b311eeead774171a0759d4c7ca8f34889a3;p=xonotic%2Fgmqcc.git diff --git a/ftepp.c b/ftepp.c index 11b4465..7337ba3 100644 --- a/ftepp.c +++ b/ftepp.c @@ -82,7 +82,7 @@ static uint32_t ftepp_predef_randval = 0; char *ftepp_predef_date(lex_file *context) { struct tm *itime; time_t rtime; - char *value = mem_a(82); + char *value = (char*)mem_a(82); /* 82 is enough for strftime but we also have " " in our string */ (void)context; @@ -100,7 +100,7 @@ char *ftepp_predef_date(lex_file *context) { char *ftepp_predef_time(lex_file *context) { struct tm *itime; time_t rtime; - char *value = mem_a(82); + char *value = (char*)mem_a(82); /* 82 is enough for strftime but we also have " " in our string */ (void)context; @@ -124,8 +124,7 @@ char *ftepp_predef_line(lex_file *context) { char *ftepp_predef_file(lex_file *context) { size_t length = strlen(context->name) + 3; /* two quotes and a terminator */ char *value = (char*)mem_a(length); - memset (value, 0, length); - sprintf(value, "\"%s\"", context->name); + snprintf(value, length, "\"%s\"", context->name); return value; } @@ -423,7 +422,7 @@ static bool ftepp_define_body(ftepp_t *ftepp, ppmacro *macro) return false; } - index = atoi(ftepp_tokval(ftepp)); + index = (int)strtol(ftepp_tokval(ftepp), NULL, 10); if (ftepp_next(ftepp) != ']') { ftepp_error(ftepp, "expected `]` in __VA_ARGS__ subscript"); @@ -451,8 +450,12 @@ static bool ftepp_define_body(ftepp_t *ftepp, ppmacro *macro) ftepp->token = old; } } - else - { + else if (macro->variadic && !strcmp(ftepp_tokval(ftepp), "__VA_COUNT__")) { + ftepp->token = TOKEN_VA_COUNT; + ptok = pptoken_make(ftepp); + vec_push(macro->output, ptok); + ftepp_next(ftepp); + } else { ptok = pptoken_make(ftepp); vec_push(macro->output, ptok); ftepp_next(ftepp); @@ -468,7 +471,7 @@ static bool ftepp_define_body(ftepp_t *ftepp, ppmacro *macro) static bool ftepp_define(ftepp_t *ftepp) { - ppmacro *macro; + ppmacro *macro = NULL; size_t l = ftepp_ctx(ftepp).line; (void)ftepp_next(ftepp); @@ -489,7 +492,7 @@ static bool ftepp_define(ftepp_t *ftepp) break; default: ftepp_error(ftepp, "expected macro name"); - return false; + goto cleanup_false; } (void)ftepp_next(ftepp); @@ -497,14 +500,14 @@ static bool ftepp_define(ftepp_t *ftepp) if (ftepp->token == '(') { macro->has_params = true; if (!ftepp_define_params(ftepp, macro)) - return false; + goto cleanup_false; } if (!ftepp_skipspace(ftepp)) - return false; + goto cleanup_false; if (!ftepp_define_body(ftepp, macro)) - return false; + goto cleanup_false; if (ftepp->output_on) vec_push(ftepp->macros, macro); @@ -515,6 +518,10 @@ static bool ftepp_define(ftepp_t *ftepp) for (; l < ftepp_ctx(ftepp).line; ++l) ftepp_out(ftepp, "\n", true); return true; + +cleanup_false: + if (macro) ppmacro_delete(macro); + return false; } /** @@ -681,6 +688,7 @@ static void ftepp_param_out(ftepp_t *ftepp, macroparam *param) static bool ftepp_preprocess(ftepp_t *ftepp); static bool ftepp_macro_expand(ftepp_t *ftepp, ppmacro *macro, macroparam *params, bool resetline) { + char *buffer = NULL; char *old_string = ftepp->output_string; char *inner_string; lex_file *old_lexer = ftepp->lex; @@ -736,6 +744,12 @@ static bool ftepp_macro_expand(ftepp_t *ftepp, ppmacro *macro, macroparam *param ftepp_param_out(ftepp, ¶ms[out->constval.i + vararg_start]); break; + case TOKEN_VA_COUNT: + util_asprintf(&buffer, "%d", varargs); + ftepp_out(ftepp, buffer, false); + mem_d(buffer); + break; + case TOKEN_IDENT: case TOKEN_TYPENAME: case TOKEN_KEYWORD: @@ -820,7 +834,7 @@ static bool ftepp_macro_expand(ftepp_t *ftepp, ppmacro *macro, macroparam *param if (resetline && !ftepp->in_macro) { char lineno[128]; - sprintf(lineno, "\n#pragma line(%lu)\n", (unsigned long)(old_lexer->sline)); + snprintf(lineno, 128, "\n#pragma line(%lu)\n", (unsigned long)(old_lexer->sline)); ftepp_out(ftepp, lineno, false); } @@ -1011,7 +1025,7 @@ static bool ftepp_if_value(ftepp_t *ftepp, bool *out, double *value_out) default: ftepp_error(ftepp, "junk in #if: `%s` ...", ftepp_tokval(ftepp)); - if (opts.debug) + if (OPTS_OPTION_BOOL(OPTION_DEBUG)) ftepp_error(ftepp, "internal: token %i\n", ftepp->token); return false; } @@ -1250,9 +1264,9 @@ static char *ftepp_include_find_path(const char *file, const char *pathfile) memcpy(vec_add(filename, len+1), file, len); vec_last(filename) = 0; - fp = file_open(filename, "rb"); + fp = fs_file_open(filename, "rb"); if (fp) { - file_close(fp); + fs_file_close(fp); return filename; } vec_free(filename); @@ -1269,6 +1283,93 @@ static char *ftepp_include_find(ftepp_t *ftepp, const char *file) return filename; } +static bool ftepp_directive_warning(ftepp_t *ftepp) { + char *message = NULL; + + if (!ftepp_skipspace(ftepp)) + return false; + + /* handle the odd non string constant case so it works like C */ + if (ftepp->token != TOKEN_STRINGCONST) { + bool store = false; + vec_upload(message, "#warning", 8); + ftepp_next(ftepp); + while (ftepp->token != TOKEN_EOL) { + vec_upload(message, ftepp_tokval(ftepp), strlen(ftepp_tokval(ftepp))); + ftepp_next(ftepp); + } + vec_push(message, '\0'); + if (ftepp->output_on) + store = ftepp_warn(ftepp, WARN_CPP, message); + else + store = false; + vec_free(message); + return store; + } + + if (!ftepp->output_on) + return false; + + unescape (ftepp_tokval(ftepp), ftepp_tokval(ftepp)); + return ftepp_warn(ftepp, WARN_CPP, "#warning %s", ftepp_tokval(ftepp)); +} + +static void ftepp_directive_error(ftepp_t *ftepp) { + char *message = NULL; + + if (!ftepp_skipspace(ftepp)) + return; + + /* handle the odd non string constant case so it works like C */ + if (ftepp->token != TOKEN_STRINGCONST) { + vec_upload(message, "#error", 6); + ftepp_next(ftepp); + while (ftepp->token != TOKEN_EOL) { + vec_upload(message, ftepp_tokval(ftepp), strlen(ftepp_tokval(ftepp))); + ftepp_next(ftepp); + } + vec_push(message, '\0'); + if (ftepp->output_on) + ftepp_error(ftepp, message); + vec_free(message); + return; + } + + if (!ftepp->output_on) + return; + + unescape (ftepp_tokval(ftepp), ftepp_tokval(ftepp)); + ftepp_error(ftepp, "#error %s", ftepp_tokval(ftepp)); +} + +static void ftepp_directive_message(ftepp_t *ftepp) { + char *message = NULL; + + if (!ftepp_skipspace(ftepp)) + return; + + /* handle the odd non string constant case so it works like C */ + if (ftepp->token != TOKEN_STRINGCONST) { + vec_upload(message, "#message", 8); + ftepp_next(ftepp); + while (ftepp->token != TOKEN_EOL) { + vec_upload(message, ftepp_tokval(ftepp), strlen(ftepp_tokval(ftepp))); + ftepp_next(ftepp); + } + vec_push(message, '\0'); + if (ftepp->output_on) + con_cprintmsg(&ftepp->lex->tok.ctx, LVL_MSG, "message", message); + vec_free(message); + return; + } + + if (!ftepp->output_on) + return; + + unescape (ftepp_tokval(ftepp), ftepp_tokval(ftepp)); + con_cprintmsg(&ftepp->lex->tok.ctx, LVL_MSG, "message", ftepp_tokval(ftepp)); +} + /** * Include a file. * FIXME: do we need/want a -I option? @@ -1292,6 +1393,11 @@ static bool ftepp_include(ftepp_t *ftepp) return false; } + if (!ftepp->output_on) { + ftepp_next(ftepp); + return true; + } + ctx = ftepp_ctx(ftepp); unescape(ftepp_tokval(ftepp), ftepp_tokval(ftepp)); @@ -1464,6 +1570,18 @@ static bool ftepp_hash(ftepp_t *ftepp) ftepp_out(ftepp, "#", false); break; } + else if (!strcmp(ftepp_tokval(ftepp), "warning")) { + ftepp_directive_warning(ftepp); + break; + } + else if (!strcmp(ftepp_tokval(ftepp), "error")) { + ftepp_directive_error(ftepp); + break; + } + else if (!strcmp(ftepp_tokval(ftepp), "message")) { + ftepp_directive_message(ftepp); + break; + } else { if (ftepp->output_on) { ftepp_error(ftepp, "unrecognized preprocessor directive: `%s`", ftepp_tokval(ftepp)); @@ -1670,7 +1788,7 @@ bool ftepp_init() /* set the right macro based on the selected standard */ ftepp_add_define(NULL, "GMQCC"); - if (opts.standard == COMPILER_FTEQCC) { + if (OPTS_OPTION_U32(OPTION_STANDARD) == COMPILER_FTEQCC) { ftepp_add_define(NULL, "__STD_FTEQCC__"); /* 1.00 */ major[0] = '"'; @@ -1680,15 +1798,15 @@ bool ftepp_init() minor[0] = '"'; minor[1] = '0'; minor[2] = '"'; - } else if (opts.standard == COMPILER_GMQCC) { + } else if (OPTS_OPTION_U32(OPTION_STANDARD) == COMPILER_GMQCC) { ftepp_add_define(NULL, "__STD_GMQCC__"); - sprintf(major, "\"%d\"", GMQCC_VERSION_MAJOR); - sprintf(minor, "\"%d\"", GMQCC_VERSION_MINOR); - } else if (opts.standard == COMPILER_QCCX) { + snprintf(major, 32, "\"%d\"", GMQCC_VERSION_MAJOR); + snprintf(minor, 32, "\"%d\"", GMQCC_VERSION_MINOR); + } else if (OPTS_OPTION_U32(OPTION_STANDARD) == COMPILER_QCCX) { ftepp_add_define(NULL, "__STD_QCCX__"); - sprintf(major, "\"%d\"", GMQCC_VERSION_MAJOR); - sprintf(minor, "\"%d\"", GMQCC_VERSION_MINOR); - } else if (opts.standard == COMPILER_QCC) { + snprintf(major, 32, "\"%d\"", GMQCC_VERSION_MAJOR); + snprintf(minor, 32, "\"%d\"", GMQCC_VERSION_MINOR); + } else if (OPTS_OPTION_U32(OPTION_STANDARD) == COMPILER_QCC) { ftepp_add_define(NULL, "__STD_QCC__"); /* 1.0 */ major[0] = '"';