ext/i18nema/i18nema.c in i18nema-0.0.5 vs ext/i18nema/i18nema.c in i18nema-0.0.6

- old
+ new

@@ -1,10 +1,12 @@ #include <ruby.h> #include <ruby/encoding.h> #include "vendor/syck.h" #include "vendor/uthash.h" +#define CAN_FREE(item) item != NULL && item->type != i_type_true && item->type != i_type_false && item->type != i_type_null + VALUE I18nema = Qnil, I18nemaBackend = Qnil, I18nemaBackendLoadError = Qnil; struct i_object; @@ -16,11 +18,11 @@ static void delete_object(struct i_object *object, int recurse); static void delete_object_r(struct i_object *object); static VALUE normalize_key(VALUE self, VALUE key, VALUE separator); enum i_object_type { - i_type_none, + i_type_unused, i_type_string, i_type_array, i_type_hash, i_type_int, i_type_float, @@ -30,11 +32,11 @@ i_type_null }; union i_object_data { char *string; - struct i_object **array; + struct i_object *array; struct i_key_value *hash; }; typedef struct i_object { @@ -90,11 +92,11 @@ static VALUE array_to_rarray(i_object_t *array) { VALUE result = rb_ary_new2(array->size); for (unsigned long i = 0; i < array->size; i++) - rb_ary_store(result, i, i_object_to_robject(array->data.array[i])); + rb_ary_store(result, i, i_object_to_robject(&array->data.array[i])); return result; } static VALUE hash_to_rhash(i_object_t *hash) @@ -165,17 +167,17 @@ switch (object->type) { case i_type_array: if (recurse) for (unsigned long i = 0; i < object->size; i++) - delete_object_r(object->data.array[i]); + empty_object(&object->data.array[i], 1); xfree(object->data.array); break; case i_type_hash: delete_hash(&object->data.hash, recurse); break; - case i_type_none: + case i_type_unused: break; default: xfree(object->data.string); break; } @@ -183,11 +185,11 @@ static void delete_object(i_object_t *object, int recurse) { empty_object(object, recurse); - if (object->type != i_type_null && object->type != i_type_true && object->type != i_type_false) + if (CAN_FREE(object)) xfree(object); } static void delete_object_r(i_object_t *object) @@ -246,12 +248,13 @@ static int delete_syck_st_entry(char *key, char *value, char *arg) { i_object_t *object = (i_object_t *)value; - // key object whose string we have yoinked into a kv - if (object->type == i_type_none) + // key object whose string we have yoinked into a kv, or item that + // has been copied into an array + if (object->type == i_type_unused) delete_object_r(object); return ST_DELETE; } static int @@ -291,27 +294,33 @@ strncpy(str, orig, len); str[len] = '\0'; return str; } -static i_object_t* -new_string_object(char *str, long len) +static void +set_string_object(i_object_t *object, char *str, long len) { - i_object_t *object = ALLOC(i_object_t); object->type = i_type_string; object->size = len; object->data.string = new_string(str, len); +} + +static i_object_t* +new_string_object(char *str, long len) +{ + i_object_t *object = ALLOC(i_object_t); + set_string_object(object, str, len); return object; } static i_object_t* new_array_object(long size) { i_object_t *object = ALLOC(i_object_t); object->type = i_type_array; object->size = size; - object->data.array = ALLOC_N(i_object_t*, size); + object->data.array = ALLOC_N(i_object_t, size); return object; } static i_object_t* new_hash_object() @@ -370,11 +379,13 @@ oid = syck_seq_read(node, i); syck_lookup_sym(parser, oid, (void **)&item); if (item->type == i_type_string) current_translation_count++; - result->data.array[i] = item; + memcpy(&result->data.array[i], item, sizeof(i_object_t)); + if (CAN_FREE(item)) + item->type = i_type_unused; } break; case syck_map_kind: result = new_hash_object(); for (long i = 0; i < node->data.pairs->idx; i++) { @@ -384,11 +395,11 @@ syck_lookup_sym(parser, oid, (void **)&key); oid = syck_map_read(node, map_value, i); syck_lookup_sym(parser, oid, (void **)&value); i_key_value_t *kv = new_key_value(key->data.string, value); - key->type = i_type_none; // so we know to free this node in delete_syck_st_entry + key->type = i_type_unused; // so we know to free this node in delete_syck_st_entry if (value->type == i_type_string) current_translation_count++; add_key_value(&result->data.hash, kv); } break; @@ -536,10 +547,10 @@ VALUE part = RARRAY_PTR(parts)[i]; // TODO: don't alloc for empty strings, since we discard them if (RSTRING_LEN(part) == 0) skipped++; else - key_frd->data.array[i - skipped] = new_string_object(RSTRING_PTR(part), RSTRING_LEN(part)); + set_string_object(&key_frd->data.array[i - skipped], RSTRING_PTR(part), RSTRING_LEN(part)); } key_frd->size -= skipped; char *key_orig = new_string(RSTRING_PTR(key), RSTRING_LEN(key)); i_key_value_t *kv = new_key_value(key_orig, key_frd);