| @ -1 +1,2 @@ | |||||
| a.out | a.out | ||||
| generated_header.h | |||||
| @ -0,0 +1,23 @@ | |||||
| #ifndef TSTRING_GUARD | |||||
| #define TSTRING_GUARD | |||||
| #include <stddef.h> | |||||
| #include <stdint.h> | |||||
| #include <stdio.h> | |||||
| typedef struct{ | |||||
| size_t size; | |||||
| char data[1]; | |||||
| }tstring; | |||||
| tstring* tstring_create(size_t); | |||||
| tstring* tstring_copy(tstring*); | |||||
| tstring* cstring_to_tstring(char*); | |||||
| tstring* integer_to_tstring(int64_t); | |||||
| tstring* tstring_concatenate(tstring*,tstring*); | |||||
| tstring* tstring_n_concatenate(size_t count, ...); | |||||
| int tstring_n_write(FILE* file, size_t count, ...); | |||||
| tstring* tstring_n_compose(const char* count, ...); | |||||
| void tstring_destroy(tstring*); | |||||
| #endif // TSTRING_GUARD | |||||
| @ -0,0 +1,104 @@ | |||||
| #include "tstring.h" | |||||
| #include "string.h" | |||||
| #include "stdlib.h" | |||||
| #include "stdio.h" | |||||
| void generator( | |||||
| tstring* header_filename, | |||||
| tstring* prefix, | |||||
| tstring* bucket_count, | |||||
| tstring* K_size, tstring* K_comp_pred, tstring* K_hash_func, | |||||
| tstring* V_size | |||||
| ) { | |||||
| tstring* key_type = tstring_n_compose("tc", | |||||
| prefix, "_key_t" | |||||
| ); | |||||
| tstring* key_type_decl = tstring_n_compose("ctctc", | |||||
| "struct ", key_type, "{\n" | |||||
| "char* data[",K_size,"];\n" | |||||
| "};\n" | |||||
| ); | |||||
| tstring* value_type = tstring_n_compose("tc", | |||||
| prefix, "_value_t" | |||||
| ); | |||||
| tstring* value_type_decl = tstring_n_compose("ctctc", | |||||
| "struct ", value_type, "{\n" | |||||
| "char* data[",V_size,"];\n" | |||||
| "};\n" | |||||
| ); | |||||
| tstring* accessor_type = tstring_n_compose("tc", | |||||
| prefix, "_accessor_t" | |||||
| ); | |||||
| tstring* accessor_type_decl = tstring_n_compose("ctc", | |||||
| "struct ", accessor_type, "{\n" | |||||
| "void* value;\n" | |||||
| "};\n" | |||||
| ); | |||||
| tstring* hash_decl = tstring_n_compose("ctctctctc", | |||||
| "size_t ",K_hash_func,"(void*);\n" | |||||
| "struct ",prefix,"_hashtype{\n" | |||||
| "size_t operator()(",key_type," key) {\n" | |||||
| "return ", K_hash_func, "(key);\n" | |||||
| "}\n" | |||||
| "}\n" | |||||
| ); | |||||
| tstring* hashmap_ptr_type = tstring_n_compose("tc", | |||||
| prefix,"_hashmap_ptr" | |||||
| ); | |||||
| tstring* hashmap_decl = tstring_n_compose("ctc", | |||||
| "typedef void* ",hashmap_ptr_type,";\n" | |||||
| ); | |||||
| tstring* create_hashmap_decl = tstring_n_compose("tctc", | |||||
| hashmap_ptr_type," ",prefix,"_hm_create();\n" | |||||
| ); | |||||
| tstring* destroy_hashmap_decl = tstring_n_compose("ctctc", | |||||
| "void ", prefix, "_hm_destroy(",hashmap_ptr_type,");\n" | |||||
| ); | |||||
| tstring* hashmap_push_decl = tstring_n_compose("ctctctc", | |||||
| "void ", prefix, "_hm_push(",key_type,"* k, ",value_type,"* v);\n" | |||||
| ); | |||||
| tstring* hashmap_get_decl = tstring_n_compose("tctctc", | |||||
| accessor_type, " ", prefix, "_hm_get(",key_type,"* k);\n" | |||||
| ); | |||||
| tstring* hashmap_endget_decl = tstring_n_compose("ctctc", | |||||
| "void ", prefix, "_hm_endget(",accessor_type," acc);\n" | |||||
| ); | |||||
| tstring* hashmap_remove_decl = tstring_n_compose("ctctc", | |||||
| "void ", prefix, "_hm_remove(",key_type,"* k);\n" | |||||
| ); | |||||
| tstring* top_guard = tstring_n_compose("ctctc", | |||||
| "#ifndef GUARD_", prefix, | |||||
| "\n#define GUARD_", prefix,"\n\n" | |||||
| ); | |||||
| tstring* bottom_guard = tstring_n_compose("ctc", | |||||
| "\n#endif // GUARD_", prefix, "\n" | |||||
| ); | |||||
| FILE* header; | |||||
| if( | |||||
| !(header = fopen(header_filename->data, "w")) | |||||
| ) { | |||||
| char* m = header_filename->data; | |||||
| fprintf(stderr, "Couldn't open header file: %s\n", header_filename->data); | |||||
| exit(EXIT_FAILURE); | |||||
| } | |||||
| if( | |||||
| tstring_n_write( | |||||
| header,12, | |||||
| top_guard, | |||||
| key_type_decl, | |||||
| value_type_decl, | |||||
| accessor_type_decl, | |||||
| hashmap_decl, | |||||
| create_hashmap_decl, | |||||
| destroy_hashmap_decl, | |||||
| hashmap_get_decl, | |||||
| hashmap_endget_decl, | |||||
| hashmap_push_decl, | |||||
| hashmap_remove_decl, | |||||
| bottom_guard | |||||
| ) != 0 | |||||
| ) { | |||||
| fprintf(stderr, "Couldn't generate header file: error writing to file: %s\n", header_filename->data); | |||||
| exit(EXIT_FAILURE); | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,21 @@ | |||||
| #include "tstring.h" | |||||
| void generator( | |||||
| tstring* header_filename, | |||||
| tstring* prefix, | |||||
| tstring* bucket_count, | |||||
| tstring* K_size, tstring* K_comp_pred, tstring* K_hash_func, | |||||
| tstring* V_size | |||||
| ); | |||||
| int main() { | |||||
| generator( | |||||
| cstring_to_tstring("./generated_header.h"), | |||||
| cstring_to_tstring("test"), | |||||
| cstring_to_tstring("8000"), | |||||
| cstring_to_tstring("8"), | |||||
| cstring_to_tstring("test_key_comp"), | |||||
| cstring_to_tstring("test_key_hash"), | |||||
| cstring_to_tstring("128") | |||||
| ); | |||||
| } | |||||
| @ -0,0 +1,154 @@ | |||||
| #include "tstring.h" | |||||
| #include <stdlib.h> | |||||
| #include <stdio.h> | |||||
| #include <stdarg.h> | |||||
| #include <string.h> | |||||
| #include <stdbool.h> | |||||
| tstring* tstring_create(size_t sz) { | |||||
| tstring* buffer = malloc(sizeof(tstring)+sz); | |||||
| memset(buffer, 0, sizeof(tstring)+sz); | |||||
| buffer->size = sz; | |||||
| return buffer; | |||||
| } | |||||
| tstring* tstring_copy(tstring* src) { | |||||
| tstring* buffer = tstring_create(src->size); | |||||
| memcpy(buffer->data, src->data, src->size+1); | |||||
| return buffer; | |||||
| } | |||||
| tstring* cstring_to_tstring(char* src) { | |||||
| size_t sz = strlen(src); | |||||
| tstring* buffer = tstring_create(sz); | |||||
| memcpy(buffer->data, src, sz); | |||||
| buffer->size = sz; | |||||
| return buffer; | |||||
| } | |||||
| tstring* integer_to_tstring(int64_t val) { | |||||
| char conversion[20]; | |||||
| bool sign = val < 0; | |||||
| char* it = conversion; | |||||
| if(sign) { | |||||
| val *= -1; | |||||
| } | |||||
| if(val == 0) { | |||||
| tstring* ret = tstring_create(1); | |||||
| ret->data[0] = '0'; | |||||
| return ret; | |||||
| } | |||||
| while(val != 0) { | |||||
| *(it++) = val%10+'0'; | |||||
| val/=10; | |||||
| } | |||||
| tstring* ret = tstring_create((it-conversion) + sign); | |||||
| char* dest_it = ret->data; | |||||
| if(sign) { | |||||
| *(dest_it++) = '-'; | |||||
| } | |||||
| do { | |||||
| *(dest_it++) = *(it--); | |||||
| } while(it != conversion); | |||||
| return ret; | |||||
| } | |||||
| tstring* tstring_concatenate(tstring* lhs, tstring* rhs) { | |||||
| tstring* ret = tstring_create(lhs->size + rhs->size); | |||||
| memcpy(ret->data, lhs->data, lhs->size); | |||||
| memcpy(ret->data + lhs->size, rhs->data, rhs->size); | |||||
| return ret; | |||||
| } | |||||
| tstring* tstring_n_concatenate(size_t count, ...) { | |||||
| va_list strs; | |||||
| va_start(strs, count); | |||||
| size_t tot_sz = 0; | |||||
| size_t idx; | |||||
| for(idx = 0; idx < count; idx++) { | |||||
| tot_sz += va_arg(strs, tstring*)->size; | |||||
| } | |||||
| tstring* ret = tstring_create(tot_sz); | |||||
| va_end(strs); | |||||
| va_start(strs, count); | |||||
| char* it = ret->data; | |||||
| for(idx = 0; idx < count; idx++) { | |||||
| tstring* curr = va_arg(strs, tstring*); | |||||
| memcpy(it, curr->data, curr->size); | |||||
| it+=curr->size; | |||||
| } | |||||
| va_end(strs); | |||||
| ret->size = tot_sz; | |||||
| return ret; | |||||
| } | |||||
| int tstring_n_write(FILE* file, size_t count, ...) { | |||||
| va_list strs; | |||||
| va_start(strs, count); | |||||
| size_t idx; | |||||
| for(idx = 0; idx < count; idx++) { | |||||
| tstring* curr = va_arg(strs, tstring*); | |||||
| if(fwrite(curr->data,1, curr->size, file) != curr->size) { | |||||
| return ferror(file); | |||||
| } | |||||
| } | |||||
| va_end(strs); | |||||
| return 0; | |||||
| } | |||||
| tstring* tstring_n_compose(const char* count, ...) { | |||||
| va_list strs; | |||||
| size_t nb = strlen(count); | |||||
| va_start(strs, count); | |||||
| size_t tot_sz = 0; | |||||
| size_t idx; | |||||
| for(idx = 0; idx < nb; idx++) { | |||||
| switch(count[idx]){ | |||||
| case 't': | |||||
| tot_sz += va_arg(strs, tstring*)->size; | |||||
| break; | |||||
| case 'c': | |||||
| tot_sz += strlen(va_arg(strs, char*)); | |||||
| break; | |||||
| default: | |||||
| va_end(strs); | |||||
| exit(EXIT_FAILURE); | |||||
| break; | |||||
| } | |||||
| } | |||||
| tstring* ret = tstring_create(tot_sz); | |||||
| char* it = ret->data; | |||||
| va_end(strs); | |||||
| va_start(strs, count); | |||||
| for(idx = 0; idx < nb; idx++) { | |||||
| switch(count[idx]){ | |||||
| case 't': | |||||
| { | |||||
| tstring* curr = va_arg(strs, tstring*); | |||||
| memcpy(it, curr->data, curr->size); | |||||
| it+=curr->size; | |||||
| } | |||||
| break; | |||||
| case 'c': | |||||
| { | |||||
| char* curr = va_arg(strs, char*); | |||||
| size_t sz = strlen(curr); | |||||
| memcpy(it, curr, sz); | |||||
| it+=sz; | |||||
| } | |||||
| break; | |||||
| default: | |||||
| perror("Invalid tstring concatenation"); | |||||
| exit(EXIT_FAILURE); | |||||
| break; | |||||
| } | |||||
| } | |||||
| va_end(strs); | |||||
| ret->size = tot_sz; | |||||
| return ret; | |||||
| } | |||||
| void tstring_destroy(tstring* del) { | |||||
| free(del); | |||||
| } | |||||
| @ -0,0 +1,3 @@ | |||||
| generator/src/generator.c | |||||
| generator/src/tstring.c | |||||
| generator/src/main.c | |||||