From e518d1ae47c1e4b97c02b37220052c87a5b53d32 Mon Sep 17 00:00:00 2001 From: Sara Date: Mon, 11 Sep 2023 18:45:21 +0200 Subject: [PATCH] implemented kwil_def declarations --- src/kwil.c | 197 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 197 insertions(+) create mode 100644 src/kwil.c diff --git a/src/kwil.c b/src/kwil.c new file mode 100644 index 0000000..217b3cc --- /dev/null +++ b/src/kwil.c @@ -0,0 +1,197 @@ +#include +#include +#include + +#include "args.h" +#include "kwil_def.h" +#include "kwil_parse.h" +#include "kwil_generate.h" + +int main(int argc, char* argv[]) { + struct kwil_args_t args; + struct kwil_header_t* headers; + + kwil_parse_args(&args, argc, argv); + + // allocate a header struct for each header + headers = malloc(args.filenames_len * sizeof(struct kwil_header_t)); + + for(int header_index = 0; header_index < args.filenames_len; ++header_index) { + kwil_init_header(&headers[header_index], args.filenames[header_index]); + kwil_header_parse(&headers[header_index]); + kwil_header_generate(&headers[header_index]); + } + + return 0; +} + +enum kwil_field_tag_t kwil_field_tag_from_string(const char* str) { + if(strcmp(str, "int") == 0) { + return KWIL_FIELD_INT; + } else if(strcmp(str, "float") == 0) { + return KWIL_FIELD_FLOAT; + } else if(strcmp(str, "char") == 0) { + return KWIL_FIELD_CHAR; + } else if(strcmp(str, "unsigned") == 0) { + return KWIL_FIELD_UNSIGNED; + } else { + return KWIL_FIELD_UNKNOWN; + } +} + +void kwil_init_enum(struct kwil_enum_t* self) { + // allocate with a capacity of one and a length of zero + *self = (struct kwil_enum_t) { + .enum_values = malloc(sizeof(struct kwil_enum_value_t)), + .enum_values_len = 0, + .enum_values_cap = 1 + }; +} + +int kwil_enum_add_value(struct kwil_enum_t* self, const char* name) { + // check if the enum values capacity needs resizing + if(self->enum_values_len >= self->enum_values_cap) { + // resize value capacity + size_t new_cap = self->enum_values_cap * 2; + struct kwil_enum_value_t* new_values = realloc(self->enum_values, new_cap * sizeof(struct kwil_enum_value_t)); + + if(new_values == NULL) { + return -1; + } else { + self->enum_values_cap = new_cap; + } + } + + // copy the name of the enum value into the array + strncpy(self->enum_values[self->enum_values_len].name, name, 42); + // increment the value length + ++self->enum_values_len; + + return 0; +} + +int kwil_free_enum(struct kwil_enum_t* self) { + free(self->enum_values); + self->enum_values_cap = 0; + self->enum_values_len = 0; + return 0; +} + +int kwil_init_field(struct kwil_field_t* self, const char* field_name, const char* type_str) { + *self = (struct kwil_field_t){ + .type_tag = KWIL_FIELD_UNKNOWN, + .type_ptr = NULL, + }; + + // copy the field and type names + strncpy(self->name_str, field_name, 47); + strncpy(self->type_str, type_str, 47); + + // append null terminators as strncpy does not guarantee null terminators + self->name_str[47] = '\0'; + self->type_str[47] = '\0'; + + // generate a type tag from the type string + self->type_tag = kwil_field_tag_from_string(type_str); + + return 0; +} + +int kwil_init_struct(struct kwil_struct_t* self) { + *self = (struct kwil_struct_t) { + .fields = malloc(sizeof(struct kwil_field_t)), + .fields_cap = 1, + .fields_len = 0 + }; + + if(self->fields == NULL) { + return 1; + } else { + return 0; + } +} + +int kwil_struct_add_field(struct kwil_struct_t *self, struct kwil_field_t *new) { + // check if the fields array needs resizing + if(self->fields_len >= self->fields_cap) { + size_t new_cap = self->fields_cap * 2; + struct kwil_field_t* new_fields = realloc(self->fields, new_cap * sizeof(struct kwil_field_t)); + + if(new_fields == NULL) { + return 1; + } + + self->fields_cap = new_cap; + } + + // copy in the new value + memcpy(self->fields + self->fields_len, new, sizeof(struct kwil_field_t)); + // increment the length + ++self->fields_len; + + return 0; +} + +int kwil_free_struct(struct kwil_struct_t* self) { + free(self->fields); + self->fields_cap = 0; + self->fields_len = 0; + return 0; +} + +int kwil_type_from_struct(struct kwil_type_t* self, struct kwil_struct_t* from, const char* name) { + // mark type as struct + self->type_tag = KWIL_TYPE_STRUCT; + + // copy the name string and append a null terminator + strncpy(self->type_name, name, 47); + self->type_name[47] = '\0'; + // copy the struct's field data + self->struct_type = *from; + + return 0; +} + +int kwil_type_from_enum(struct kwil_type_t* self, struct kwil_enum_t* from, const char* name) { + // mark type as enum + self->type_tag = KWIL_TYPE_ENUM; + + // copy the name string and append a null terminator + strncpy(self->type_name, name, 47); + self->type_name[47] = '\0'; + //copy the enum's value data + self->enum_type = *from; + return 0; +} + +int kwil_init_header(struct kwil_header_t* self, const char* filename) { + // copy filename and append null terminator + strncpy(self->file_name, filename, 47); + + // allocate an empty array with a starting capacity of one + self->types = malloc(sizeof(struct kwil_type_t)); + self->types_cap = 1; + self->types_len = 0; + + return 0; +} + +int kwil_header_add_type(struct kwil_header_t* self, struct kwil_type_t* new) { + // resize the types array if needed + if(self->types_len >= self->types_cap) { + size_t new_cap = self->types_cap * 2; + struct kwil_type_t* new_array = realloc(self->types, new_cap * sizeof(struct kwil_type_t)); + + if(new_array == NULL) { + return 1; + } + + self->types = new_array; + self->types_cap = new_cap; + } + + self->types[self->types_len] = *new; + ++self->types_len; + + return 0; +}