mirror of
https://github.com/DarkPlacesEngine/gmqcc.git
synced 2024-12-18 00:11:06 +00:00
parser_const_string now uses hashtables; hashtables may want to dup an empty string without it becoming NULL - also replacing ir_strdup with the new util_ one
This commit is contained in:
parent
8f2a22b8c3
commit
46752af74b
5 changed files with 44 additions and 17 deletions
6
gmqcc.h
6
gmqcc.h
|
@ -300,7 +300,8 @@ void util_meminfo ();
|
|||
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);
|
||||
|
||||
|
@ -329,6 +330,7 @@ int util_asprintf (char **ret, const char *fmt, ...);
|
|||
#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
|
||||
|
@ -336,7 +338,7 @@ int util_asprintf (char **ret, const char *fmt, ...);
|
|||
* 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;
|
||||
|
|
13
ir.c
13
ir.c
|
@ -1206,22 +1206,11 @@ bool ir_value_set_field(ir_value *self, ir_value *fld)
|
|||
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;
|
||||
}
|
||||
|
|
18
parser.c
18
parser.c
|
@ -47,6 +47,8 @@ typedef struct parser_s {
|
|||
ast_value **imm_vector;
|
||||
size_t translated;
|
||||
|
||||
ht ht_imm_string;
|
||||
|
||||
/* must be deleted first, they reference immediates and values */
|
||||
ast_value **accessors;
|
||||
|
||||
|
@ -253,12 +255,22 @@ static char *parser_strdup(const char *str)
|
|||
|
||||
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++));
|
||||
|
@ -269,6 +281,7 @@ static ast_value* parser_const_string(parser_t *parser, const char *str, bool do
|
|||
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;
|
||||
}
|
||||
|
||||
|
@ -5942,6 +5955,8 @@ parser_t *parser_create()
|
|||
|
||||
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);
|
||||
|
@ -6054,6 +6069,7 @@ void parser_cleanup(parser_t *parser)
|
|||
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);
|
||||
|
|
3
test.c
3
test.c
|
@ -679,7 +679,8 @@ bool task_propagate(const char *curdir, size_t *pad, const char *defs) {
|
|||
* 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
|
||||
|
|
21
util.c
21
util.c
|
@ -226,6 +226,25 @@ char *_util_Estrdup(const char *s, const char *file, size_t line) {
|
|||
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))
|
||||
|
@ -478,7 +497,7 @@ hash_node_t *_util_htnewpair(const char *key, void *value) {
|
|||
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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue