+/* __DATE__ */
+static char *ftepp_predef_date(ftepp_t *context) {
+ const struct tm *itime = NULL;
+ char *value = (char*)mem_a(82);
+ time_t rtime;
+
+ (void)context;
+
+ time (&rtime);
+ itime = util_localtime(&rtime);
+ strftime(value, 82, "\"%b %d %Y\"", itime);
+
+ return value;
+}
+
+/* __TIME__ */
+static char *ftepp_predef_time(ftepp_t *context) {
+ const struct tm *itime = NULL;
+ char *value = (char*)mem_a(82);
+ time_t rtime;
+
+ (void)context;
+
+ time (&rtime);
+ itime = util_localtime(&rtime);
+ strftime(value, 82, "\"%X\"", itime);
+
+ return value;
+}
+
+/* __LINE__ */
+static char *ftepp_predef_line(ftepp_t *context) {
+ char *value;
+
+ util_asprintf(&value, "%d", (int)context->lex->line);
+ return value;
+}
+/* __FILE__ */
+static char *ftepp_predef_file(ftepp_t *context) {
+ size_t length = strlen(context->lex->name) + 3; /* two quotes and a terminator */
+ char *value = (char*)mem_a(length);
+
+ util_snprintf(value, length, "\"%s\"", context->lex->name);
+ return value;
+}
+/* __COUNTER_LAST__ */
+static char *ftepp_predef_counterlast(ftepp_t *context) {
+ char *value;
+ util_asprintf(&value, "%u", context->predef_countval);
+ return value;
+}
+/* __COUNTER__ */
+static char *ftepp_predef_counter(ftepp_t *context) {
+ char *value;
+
+ context->predef_countval ++;
+ util_asprintf(&value, "%u", context->predef_countval);
+
+ return value;
+}
+/* __RANDOM__ */
+static char *ftepp_predef_random(ftepp_t *context) {
+ char *value;
+
+ context->predef_randval = (util_rand() % 0xFF) + 1;
+ util_asprintf(&value, "%u", context->predef_randval);
+ return value;
+}
+/* __RANDOM_LAST__ */
+static char *ftepp_predef_randomlast(ftepp_t *context) {
+ char *value;
+
+ util_asprintf(&value, "%u", context->predef_randval);
+ return value;
+}
+/* __TIMESTAMP__ */
+static char *ftepp_predef_timestamp(ftepp_t *context) {
+ struct stat finfo;
+ const char *find;
+ char *value;
+ size_t size;
+
+ if (stat(context->lex->name, &finfo))
+ return util_strdup("\"<failed to determine timestamp>\"");
+
+ find = util_ctime(&finfo.st_mtime);
+ value = (char*)mem_a(strlen(find) + 1);
+ memcpy(&value[1], find, (size = strlen(find)) - 1);
+
+ value[0] = '"';
+ value[size] = '"';
+
+ return value;
+}
+
+typedef struct {
+ const char *name;
+ char *(*func)(ftepp_t *);
+} ftepp_predef_t;
+
+static const ftepp_predef_t ftepp_predefs[] = {
+ { "__LINE__", &ftepp_predef_line },
+ { "__FILE__", &ftepp_predef_file },
+ { "__COUNTER__", &ftepp_predef_counter },
+ { "__COUNTER_LAST__", &ftepp_predef_counterlast },
+ { "__RANDOM__", &ftepp_predef_random },
+ { "__RANDOM_LAST__", &ftepp_predef_randomlast },
+ { "__DATE__", &ftepp_predef_date },
+ { "__TIME__", &ftepp_predef_time },
+ { "__TIME_STAMP__", &ftepp_predef_timestamp }
+};
+
+static GMQCC_INLINE size_t ftepp_predef_index(const char *name) {
+ /* no hashtable here, we simply check for one to exist the naive way */
+ 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 0;
+}
+
+bool ftepp_predef_exists(const char *name);
+bool ftepp_predef_exists(const char *name) {
+ return ftepp_predef_index(name) != 0;
+}
+
+/* singleton because we're allowed */
+static GMQCC_INLINE char *(*ftepp_predef(const char *name))(ftepp_t *context) {
+ size_t i = ftepp_predef_index(name);
+ return (i != 0) ? ftepp_predefs[i-1].func : NULL;
+}
+