bool util_filexists (const char *);
bool util_strupper (const char *);
bool util_strdigit (const char *);
-char *_util_Estrdup (const char *, const char *, size_t);
+char *_util_Estrdup (const char *, const char *, size_t);
+char *_util_Estrdup_empty(const char *, const char *, size_t);
void util_debug (const char *, const char *, ...);
void util_endianswap (void *, size_t, unsigned int);
#endif /*! NOTRACK */
#define util_strdup(X) _util_Estrdup((X), __FILE__, __LINE__)
+#define util_strdupe(X) _util_Estrdup_empty((X), __FILE__, __LINE__)
/*
* A flexible vector implementation: all vector pointers contain some
* this data is represented in the structure below. Doing this allows
* us to use the array [] to access individual elements from the vector
* opposed to using set/get methods.
- */
+ */
typedef struct {
size_t allocated;
size_t used;
return true;
}
-static char *ir_strdup(const char *str)
-{
- if (str && !*str) {
- /* actually dup empty strings */
- char *out = (char*)mem_a(1);
- *out = 0;
- return out;
- }
- return util_strdup(str);
-}
-
bool ir_value_set_string(ir_value *self, const char *str)
{
if (self->vtype != TYPE_STRING)
return false;
- self->constval.vstring = ir_strdup(str);
+ self->constval.vstring = util_strdupe(str);
self->hasvalue = true;
return true;
}
ast_value **imm_vector;
size_t translated;
+ ht ht_imm_string;
+
/* must be deleted first, they reference immediates and values */
ast_value **accessors;
static ast_value* parser_const_string(parser_t *parser, const char *str, bool dotranslate)
{
- size_t i;
+ size_t hash = util_hthash(parser->ht_imm_string, str);
ast_value *out;
+ if ( (out = util_htgeth(parser->ht_imm_string, str, hash)) ) {
+ if (dotranslate && out->name[0] == '#') {
+ char name[32];
+ snprintf(name, sizeof(name), "dotranslate_%lu", (unsigned long)(parser->translated++));
+ ast_value_set_name(out, name);
+ }
+ return out;
+ }
+ /*
for (i = 0; i < vec_size(parser->imm_string); ++i) {
if (!strcmp(parser->imm_string[i]->constval.vstring, str))
return parser->imm_string[i];
}
+ */
if (dotranslate) {
char name[32];
snprintf(name, sizeof(name), "dotranslate_%lu", (unsigned long)(parser->translated++));
out->hasvalue = true;
out->constval.vstring = parser_strdup(str);
vec_push(parser->imm_string, out);
+ util_htseth(parser->ht_imm_string, str, hash, out);
return out;
}
parser->aliases = util_htnew(PARSER_HT_SIZE);
+ parser->ht_imm_string = util_htnew(512);
+
/* corrector */
vec_push(parser->correct_variables, correct_trie_new());
vec_push(parser->correct_variables_score, NULL);
vec_free(parser->functions);
vec_free(parser->imm_vector);
vec_free(parser->imm_string);
+ util_htdel(parser->ht_imm_string);
vec_free(parser->imm_float);
vec_free(parser->globals);
vec_free(parser->fields);
* Generate a temportary file name for the output binary
* so we don't trample over an existing one.
*/
- tmpl->tempfilename = tempnam(curdir, "TMPDAT");
+ tmpl->tempfilename = NULL;
+ util_asprintf(&tmpl->tempfilename, "%s/TMPDAT.%s", curdir, files->d_name);
/*
* Additional QCFLAGS enviroment variable may be used
return ptr;
}
+char *_util_Estrdup_empty(const char *s, const char *file, size_t line) {
+ size_t len = 0;
+ char *ptr = NULL;
+
+ /* in case of -DNOTRACK */
+ (void)file;
+ (void)line;
+
+ if (!s)
+ return NULL;
+
+ len = strlen(s);
+ if ((ptr = (char*)mem_af(len+1, line, file))) {
+ memcpy(ptr, s, len);
+ ptr[len] = '\0';
+ }
+ return ptr;
+}
+
void util_debug(const char *area, const char *ms, ...) {
va_list va;
if (!OPTS_OPTION_BOOL(OPTION_DEBUG))
if (!(node = (hash_node_t*)mem_a(sizeof(hash_node_t))))
return NULL;
- if (!(node->key = util_strdup(key))) {
+ if (!(node->key = util_strdupe(key))) {
mem_d(node);
return NULL;
}