X-Git-Url: https://git.xonotic.org/?a=blobdiff_plain;f=ftepp.c;h=fe63fbf656cb9c172ee060abf7f68b3d4a8aaa01;hb=dd33f4e498aafc7fcd989f6e6b0dbbf0d4ef414f;hp=3f45bc22d8b6d120eccfd3d7bf5f7acee3b513fb;hpb=d6ca5673dc7f2760faca1200477808d919a290ca;p=xonotic%2Fgmqcc.git diff --git a/ftepp.c b/ftepp.c index 3f45bc2..fe63fbf 100644 --- a/ftepp.c +++ b/ftepp.c @@ -21,7 +21,6 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -#include #include #include #include @@ -30,6 +29,7 @@ #include "lexer.h" #define HT_MACROS 1024 + typedef struct { bool on; bool was_on; @@ -85,22 +85,14 @@ static uint32_t ftepp_predef_randval = 0; /* __DATE__ */ static char *ftepp_predef_date(lex_file *context) { - struct tm *itime = NULL; - time_t rtime; - char *value = (char*)mem_a(82); - /* 82 is enough for strftime but we also have " " in our string */ + const struct tm *itime = NULL; + char *value = (char*)mem_a(82); + time_t rtime; (void)context; - /* get time */ time (&rtime); - -#ifdef _MSC_VER - localtime_s(itime, &rtime); -#else - itime = localtime(&rtime); -#endif - + itime = util_localtime(&rtime); strftime(value, 82, "\"%b %d %Y\"", itime); return value; @@ -108,22 +100,14 @@ static char *ftepp_predef_date(lex_file *context) { /* __TIME__ */ static char *ftepp_predef_time(lex_file *context) { - struct tm *itime = NULL; - time_t rtime; - char *value = (char*)mem_a(82); - /* 82 is enough for strftime but we also have " " in our string */ + const struct tm *itime = NULL; + char *value = (char*)mem_a(82); + time_t rtime; (void)context; - /* get time */ time (&rtime); - -#ifdef _MSC_VER - localtime_s(itime, &rtime); -#else - itime = localtime(&rtime); -#endif - + itime = util_localtime(&rtime); strftime(value, 82, "\"%X\"", itime); return value; @@ -180,17 +164,14 @@ static char *ftepp_predef_randomlast(lex_file *context) { /* __TIMESTAMP__ */ static char *ftepp_predef_timestamp(lex_file *context) { struct stat finfo; - char *find; + const char *find; char *value; size_t size; + if (stat(context->name, &finfo)) return util_strdup("\"\""); - /* - * ctime and its fucking annoying newline char, no worries, we're - * professionals here. - */ - find = ctime(&finfo.st_mtime); + find = util_ctime(&finfo.st_mtime); value = (char*)mem_a(strlen(find) + 1); memcpy(&value[1], find, (size = strlen(find)) - 1); @@ -217,23 +198,24 @@ static const ftepp_predef_t ftepp_predefs[] = { { "__TIME_STAMP__", &ftepp_predef_timestamp } }; -static GMQCC_INLINE int ftepp_predef_index(const char *name) { +static GMQCC_INLINE size_t ftepp_predef_index(const char *name) { /* no hashtable here, we simply check for one to exist the naive way */ - int i; - for(i = 0; i < (int)(sizeof(ftepp_predefs)/sizeof(*ftepp_predefs)); i++) - if (!strcmp(ftepp_predefs[i].name, name)) + size_t i; + for(i = 1; i < GMQCC_ARRAY_COUNT(ftepp_predefs) + 1; i++) + if (!strcmp(ftepp_predefs[i-1].name, name)) return i; - return -1; + return 0; } +bool ftepp_predef_exists(const char *name); bool ftepp_predef_exists(const char *name) { - return ftepp_predef_index(name) != -1; + return ftepp_predef_index(name) != 0; } /* singleton because we're allowed */ static GMQCC_INLINE char *(*ftepp_predef(const char *name))(lex_file *context) { - int i = ftepp_predef_index(name); - return (i != -1) ? ftepp_predefs[i].func : NULL; + size_t i = ftepp_predef_index(name); + return (i != 0) ? ftepp_predefs[i-1].func : NULL; } #define ftepp_tokval(f) ((f)->lex->tok.value) @@ -1292,7 +1274,7 @@ static void unescape(const char *str, char *out) { static char *ftepp_include_find_path(const char *file, const char *pathfile) { - FILE *fp; + fs_file_t *fp; char *filename = NULL; const char *last_slash; size_t len; @@ -1340,10 +1322,10 @@ static bool ftepp_directive_warning(ftepp_t *ftepp) { /* 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); + vec_append(message, 8, "#warning"); ftepp_next(ftepp); while (ftepp->token != TOKEN_EOL) { - vec_upload(message, ftepp_tokval(ftepp), strlen(ftepp_tokval(ftepp))); + vec_append(message, strlen(ftepp_tokval(ftepp)), ftepp_tokval(ftepp)); ftepp_next(ftepp); } vec_push(message, '\0'); @@ -1370,10 +1352,10 @@ static void ftepp_directive_error(ftepp_t *ftepp) { /* handle the odd non string constant case so it works like C */ if (ftepp->token != TOKEN_STRINGCONST) { - vec_upload(message, "#error", 6); + vec_append(message, 6, "#error"); ftepp_next(ftepp); while (ftepp->token != TOKEN_EOL) { - vec_upload(message, ftepp_tokval(ftepp), strlen(ftepp_tokval(ftepp))); + vec_append(message, strlen(ftepp_tokval(ftepp)), ftepp_tokval(ftepp)); ftepp_next(ftepp); } vec_push(message, '\0'); @@ -1398,10 +1380,10 @@ static void ftepp_directive_message(ftepp_t *ftepp) { /* handle the odd non string constant case so it works like C */ if (ftepp->token != TOKEN_STRINGCONST) { - vec_upload(message, "#message", 8); + vec_append(message, 8, "#message"); ftepp_next(ftepp); while (ftepp->token != TOKEN_EOL) { - vec_upload(message, ftepp_tokval(ftepp), strlen(ftepp_tokval(ftepp))); + vec_append(message, strlen(ftepp_tokval(ftepp)), ftepp_tokval(ftepp)); ftepp_next(ftepp); } vec_push(message, '\0'); @@ -1512,6 +1494,11 @@ static bool ftepp_else_allowed(ftepp_t *ftepp) return true; } +static GMQCC_INLINE void ftepp_inmacro(ftepp_t *ftepp, const char *hash) { + if (ftepp->in_macro) + (void)!ftepp_warn(ftepp, WARN_DIRECTIVE_INMACRO, "`#%s` directive in macro", hash); +} + static bool ftepp_hash(ftepp_t *ftepp) { ppcondition cond; @@ -1527,12 +1514,15 @@ static bool ftepp_hash(ftepp_t *ftepp) case TOKEN_IDENT: case TOKEN_TYPENAME: if (!strcmp(ftepp_tokval(ftepp), "define")) { + ftepp_inmacro(ftepp, "define"); return ftepp_define(ftepp); } else if (!strcmp(ftepp_tokval(ftepp), "undef")) { + ftepp_inmacro(ftepp, "undef"); return ftepp_undef(ftepp); } else if (!strcmp(ftepp_tokval(ftepp), "ifdef")) { + ftepp_inmacro(ftepp, "ifdef"); if (!ftepp_ifdef(ftepp, &cond)) return false; cond.was_on = cond.on; @@ -1541,6 +1531,7 @@ static bool ftepp_hash(ftepp_t *ftepp) break; } else if (!strcmp(ftepp_tokval(ftepp), "ifndef")) { + ftepp_inmacro(ftepp, "ifndef"); if (!ftepp_ifdef(ftepp, &cond)) return false; cond.on = !cond.on; @@ -1550,6 +1541,7 @@ static bool ftepp_hash(ftepp_t *ftepp) break; } else if (!strcmp(ftepp_tokval(ftepp), "elifdef")) { + ftepp_inmacro(ftepp, "elifdef"); if (!ftepp_else_allowed(ftepp)) return false; if (!ftepp_ifdef(ftepp, &cond)) @@ -1561,6 +1553,7 @@ static bool ftepp_hash(ftepp_t *ftepp) break; } else if (!strcmp(ftepp_tokval(ftepp), "elifndef")) { + ftepp_inmacro(ftepp, "elifndef"); if (!ftepp_else_allowed(ftepp)) return false; if (!ftepp_ifdef(ftepp, &cond)) @@ -1573,6 +1566,7 @@ static bool ftepp_hash(ftepp_t *ftepp) break; } else if (!strcmp(ftepp_tokval(ftepp), "elif")) { + ftepp_inmacro(ftepp, "elif"); if (!ftepp_else_allowed(ftepp)) return false; if (!ftepp_if(ftepp, &cond)) @@ -1584,6 +1578,7 @@ static bool ftepp_hash(ftepp_t *ftepp) break; } else if (!strcmp(ftepp_tokval(ftepp), "if")) { + ftepp_inmacro(ftepp, "if"); if (!ftepp_if(ftepp, &cond)) return false; cond.was_on = cond.on; @@ -1592,6 +1587,7 @@ static bool ftepp_hash(ftepp_t *ftepp) break; } else if (!strcmp(ftepp_tokval(ftepp), "else")) { + ftepp_inmacro(ftepp, "else"); if (!ftepp_else_allowed(ftepp)) return false; pc = &vec_last(ftepp->conditions); @@ -1602,6 +1598,7 @@ static bool ftepp_hash(ftepp_t *ftepp) break; } else if (!strcmp(ftepp_tokval(ftepp), "endif")) { + ftepp_inmacro(ftepp, "endif"); if (!vec_size(ftepp->conditions)) { ftepp_error(ftepp, "#endif without #if"); return false; @@ -1612,6 +1609,7 @@ static bool ftepp_hash(ftepp_t *ftepp) break; } else if (!strcmp(ftepp_tokval(ftepp), "include")) { + ftepp_inmacro(ftepp, "include"); return ftepp_include(ftepp); } else if (!strcmp(ftepp_tokval(ftepp), "pragma")) { @@ -1808,10 +1806,10 @@ void ftepp_add_macro(ftepp_t *ftepp, const char *name, const char *value) { return; } - vec_upload(create, "#define ", 8); - vec_upload(create, name, strlen(name)); + vec_append(create, 8, "#define "); + vec_append(create, strlen(name), name); vec_push (create, ' '); - vec_upload(create, value, strlen(value)); + vec_append(create, strlen(value), value); vec_push (create, 0); ftepp_preprocess_string(ftepp, "__builtin__", create);