diff --git a/cmeta.h b/cmeta.h index f85911e..edb4561 100644 --- a/cmeta.h +++ b/cmeta.h @@ -15,21 +15,6 @@ typedef struct { } Struct_Info; // AUTO GENERATED CODE // -static Struct_Info foo_struct_info = { // cmeta.h:214 - .name = "Foo_Struct", // cmeta.h:215 - .fields_count = 1, // cmeta.h:216 - .fields = (Field_Info[1]) { // cmeta.h:217 - { .type = "int", .name = "int_field" }, // cmeta.h:219 - }, // cmeta.h:221 -}; // cmeta.h:222 -static Struct_Info bar_struct_info = { // cmeta.h:214 - .name = "Bar_Struct", // cmeta.h:215 - .fields_count = 2, // cmeta.h:216 - .fields = (Field_Info[2]) { // cmeta.h:217 - { .type = "int", .name = "int_field" }, // cmeta.h:219 - { .type = "long", .name = "long_fields" }, // cmeta.h:219 - }, // cmeta.h:221 -}; // cmeta.h:222 // AUTO GENERATED CODE // // #define CMETA_COMPTIME @@ -51,12 +36,24 @@ typedef struct { char* name; } Parsed_Field_Info; +typedef struct { + Parsed_Field_Info* items; + size_t count; + size_t capacity; +} Parsed_Field_Infos; + typedef struct { char* name; size_t fields_count; Parsed_Field_Info *fields; } Parsed_Struct_Info; +typedef struct { + Parsed_Struct_Info* items; + size_t count; + size_t capacity; +} Parsed_Struct_Infos; + typedef struct { char* data; size_t capacity; @@ -67,9 +64,9 @@ void sb_append(String_Builder* sb, const char* data) { size_t data_len = strlen(data); size_t total_len = sb->length + data_len; - if(total_len + 1 > sb->capacity) { + if (total_len + 1 > sb->capacity) { size_t new_capacity = sb->capacity == 0 ? 64 : sb->capacity * 2; - while(new_capacity < total_len + 1) { + while (new_capacity < total_len + 1) { new_capacity *= 2; } sb->data = (char*) realloc(sb->data, new_capacity); @@ -81,6 +78,18 @@ void sb_append(String_Builder* sb, const char* data) { sb->data[sb->length] = '\0'; } +#define da_append(da, item) \ + do { \ + if ((da)->count + 1 > (da)->capacity) { \ + size_t new_capacity = (da)->capacity == 0 ? 64 : (da)->capacity * 2; \ + while ((da)->count + 1 > new_capacity) { \ + new_capacity *= 2; \ + } \ + (da)->items = realloc((da)->items, new_capacity * sizeof(*(da)->items)); \ + } \ + (da)->items[(da)->count++] = (item); \ + } while (0) \ + bool lexer_expect_keyword(const char* expected) { stb_c_lexer_get_token(&lexer); @@ -132,8 +141,7 @@ bool parse_struct(Parsed_Struct_Info* info) { bool result = false; char* name = NULL; - size_t fields_count = 0; - Parsed_Field_Info fields[16] = {0}; // TODO: use dynamic array + Parsed_Field_Infos fields = {0}; if (!lexer_expect_keyword("typedef")) goto fail; if (!lexer_expect_keyword("struct")) goto fail; @@ -155,9 +163,11 @@ bool parse_struct(Parsed_Struct_Info* info) { if (!lexer_expect(CLEX_id, "field name")) goto fail; char* field_name = strdup(lexer.string); - fields[fields_count].type = field_type; - fields[fields_count].name = field_name; - fields_count += 1; + Parsed_Field_Info field = { + .type = field_type, + .name = field_name, + }; + da_append(&fields, field); if(!lexer_expect(';', NULL)) goto fail; } @@ -166,21 +176,22 @@ bool parse_struct(Parsed_Struct_Info* info) { name = strdup(lexer.string); info->name = name; - info->fields_count = fields_count; - info->fields = (Parsed_Field_Info*)calloc(fields_count, sizeof(Parsed_Field_Info)); - for(size_t i = 0; i < fields_count; i += 1) { - info->fields[i].type = fields[i].type; - info->fields[i].name = fields[i].name; + info->fields_count = fields.count; + info->fields = (Parsed_Field_Info*)calloc(info->fields_count, sizeof(Parsed_Field_Info)); + for(size_t i = 0; i < info->fields_count; i += 1) { + info->fields[i].type = fields.items[i].type; + info->fields[i].name = fields.items[i].name; } result = true; fail: if(!result) { free(name); - for(size_t i = 0; i < fields_count; i += 1) { - free(fields[i].name); - free(fields[i].type); + for(size_t i = 0; i < fields.count; i += 1) { + free(fields.items[i].name); + free(fields.items[i].type); } + free(fields.items); } return result; @@ -254,7 +265,7 @@ fail: return result; } -bool generate_output_file(const char* output_path, Parsed_Struct_Info *struct_infos, size_t struct_infos_count) { +bool generate_output_file(const char* output_path, Parsed_Struct_Infos struct_infos) { const char* GENERATION_MARK = "// AUTO GENERATED CODE //\n"; const size_t GENERATION_MARK_LEN = strlen(GENERATION_MARK); @@ -287,8 +298,8 @@ bool generate_output_file(const char* output_path, Parsed_Struct_Info *struct_in // write up to the generation mark, including it fwrite(header_content, generate_begin + GENERATION_MARK_LEN - header_content, 1, stream); - for (size_t i = 0; i < struct_infos_count; i += 1) { - generate_struct_info(stream, struct_infos[i]); + for (size_t i = 0; i < struct_infos.count; i += 1) { + generate_struct_info(stream, struct_infos.items[i]); } fwrite(generate_end, strlen(generate_end), 1, stream); @@ -315,7 +326,6 @@ bool preprocess_file(const char* file_path, String_Builder* result) { size_t line_num = 0; char file_name[512]; - // TODO: use dynamic array instead size_t cursor = 0; result->length = 0; @@ -351,8 +361,7 @@ bool process_file(const char* input_file) { stb_c_lexer_init(&lexer, input_content.data, input_content.data + input_content.length, string_store, sizeof(string_store) / sizeof(char)); // find and parse all structs - size_t struct_infos_count = 0; - Parsed_Struct_Info struct_infos[16]; // TODO: use dynamic array + Parsed_Struct_Infos struct_infos = {0}; while (true) { char* mark = lexer.parse_point; @@ -361,13 +370,14 @@ bool process_file(const char* input_file) { if (lexer.token == CLEX_id && strcmp(lexer.string, "typedef") == 0) { lexer.parse_point = mark; - if (parse_struct(&struct_infos[struct_infos_count])) { - struct_infos_count += 1; + Parsed_Struct_Info struct_info = {0}; + if (parse_struct(&struct_info)) { + da_append(&struct_infos, struct_info); } } } - if (!generate_output_file(__FILE__, struct_infos, struct_infos_count)) return false; + if (!generate_output_file(__FILE__, struct_infos)) return false; return true; }