| @ -1 +1,2 @@ | |||
| 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 | |||