MINGW = $(findstring MINGW32, $(UNAME))
CC ?= clang
-CFLAGS += -Wall -Wextra -Werror -I. -fno-strict-aliasing -fsigned-char $(OPTIONAL)
+CFLAGS += -Wall -Wextra -Werror -I. -fno-strict-aliasing -fsigned-char -ffunction-sections -fdata-sections -Wl,-gc-sections $(OPTIONAL)
ifneq ($(shell git describe --always 2>/dev/null),)
CFLAGS += -DGMQCC_GITINFO="\"$(shell git describe --always)\""
endif
* purpose that is not garbage-collected.
*/
ast_expression_delete((ast_expression*)self);
+ mem_d(self->name);
mem_d(self);
}
break;
default:
ftepp_error(ftepp, "expected macro name");
- goto cleanup_false;
+ return false;
}
(void)ftepp_next(ftepp);
if (ftepp->token == '(') {
macro->has_params = true;
- if (!ftepp_define_params(ftepp, macro))
- goto cleanup_false;
+ if (!ftepp_define_params(ftepp, macro)) {
+ ppmacro_delete(macro);
+ return false;
+ }
}
- if (!ftepp_skipspace(ftepp))
- goto cleanup_false;
+ if (!ftepp_skipspace(ftepp)) {
+ ppmacro_delete(macro);
+ return false;
+ }
- if (!ftepp_define_body(ftepp, macro))
- goto cleanup_false;
+ if (!ftepp_define_body(ftepp, macro)) {
+ ppmacro_delete(macro);
+ return false;
+ }
if (ftepp->output_on)
vec_push(ftepp->macros, macro);
for (; l < ftepp_ctx(ftepp).line; ++l)
ftepp_out(ftepp, "\n", true);
return true;
-
-cleanup_false:
- if (macro) ppmacro_delete(macro);
- return false;
}
/**
bool util_filexists (const char *);
bool util_strupper (const char *);
bool util_strdigit (const char *);
-char *util_strdup (const char *);
+char *_util_Estrdup (const char *, const char *, size_t);
void util_debug (const char *, const char *, ...);
void util_endianswap (void *, size_t, unsigned int);
# define mem_r(x, n) util_memory_r((void*)(x), (n), __LINE__, __FILE__)
#endif /*! NOTRACK */
+#define util_strdup(X) _util_Estrdup((X), __FILE__, __LINE__)
+
/*
* A flexible vector implementation: all vector pointers contain some
* data about themselfs exactly - sizeof(vector_t) behind the pointer
return intrinsics;
}
-void intrin_intrinsics_destroy() {
- util_htdel(intrin_intrinsics());
-}
-
#define INTRIN_VAL(VALUE, NAME, FUNC, STYPE, VTYPE) \
do { \
(VALUE) = ast_value_new ( \
{&intrin_isnan, "__builtin_isnan", "isnan"}
};
+void intrin_intrinsics_destroy(parser_t *parser) {
+ /*size_t i;*/
+ (void)parser;
+ util_htdel(intrin_intrinsics());
+#if 0
+ for (i = 0; i < sizeof(intrinsics)/sizeof(intrin_t); i++)
+ ast_value_delete( (ast_value*) intrinsics[i].intrin(parser));
+#endif
+}
+
+
ast_expression *intrin_func(parser_t *parser, const char *name) {
static bool init = false;
size_t i = 0;
util_htdel(parser->aliases);
- intrin_intrinsics_destroy();
+ intrin_intrinsics_destroy(parser);
mem_d(parser);
}
return;
for (info = mem_start; info; info = info->next) {
- util_debug("MEM", "lost: % 8u (bytes) at %s:%u\n",
+ con_out("lost: % 8u (bytes) at %s:%u\n",
info->byte,
info->file,
info->line);
}
- util_debug("MEM", "Memory information:\n\
+ con_out("Memory information:\n\
Total allocations: %llu\n\
Total deallocations: %llu\n\
Total allocated: %llu (bytes)\n\
* Some string utility functions, because strdup uses malloc, and we want
* to track all memory (without replacing malloc).
*/
-char *util_strdup(const char *s) {
+char *_util_Estrdup(const char *s, const char *file, size_t line) {
size_t len = 0;
char *ptr = NULL;
if (!s)
return NULL;
- if ((len = strlen(s)) && (ptr = (char*)mem_a(len+1))) {
+ if ((len = strlen(s)) && (ptr = (char*)util_memory_a(len+1, line, file))) {
memcpy(ptr, s, len);
ptr[len] = '\0';
}