From 4e08e4fe236160832103301b75e426586391a5e0 Mon Sep 17 00:00:00 2001 From: Ludovic 'Archivist' Lagouardette Date: Tue, 1 Dec 2020 12:55:54 +0100 Subject: [PATCH] Started working on the generator --- .gitignore | 1 + .vscode/settings.json | 5 ++ generator/include/tstring.h | 23 ++++++ generator/src/generator.c | 104 ++++++++++++++++++++++++ generator/src/main.c | 21 +++++ generator/src/tstring.c | 154 ++++++++++++++++++++++++++++++++++++ src_list.txt | 3 + 7 files changed, 311 insertions(+) create mode 100644 generator/include/tstring.h create mode 100644 generator/src/generator.c create mode 100644 generator/src/main.c create mode 100644 generator/src/tstring.c create mode 100644 src_list.txt diff --git a/.gitignore b/.gitignore index cba7efc..488a468 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ a.out +generated_header.h diff --git a/.vscode/settings.json b/.vscode/settings.json index 74f3605..4b190c9 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -2,5 +2,10 @@ "clang.cxxflags": [ "-std=c++17", "-I${workspaceRoot}/include" + ], + "clang.cflags": [ + "-ansi", + "-I${workspaceRoot}/generator/include", + "-Wpedantic" ] } \ No newline at end of file diff --git a/generator/include/tstring.h b/generator/include/tstring.h new file mode 100644 index 0000000..85cd583 --- /dev/null +++ b/generator/include/tstring.h @@ -0,0 +1,23 @@ +#ifndef TSTRING_GUARD +#define TSTRING_GUARD + +#include +#include +#include + +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 \ No newline at end of file diff --git a/generator/src/generator.c b/generator/src/generator.c new file mode 100644 index 0000000..4baf59b --- /dev/null +++ b/generator/src/generator.c @@ -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); + } +} \ No newline at end of file diff --git a/generator/src/main.c b/generator/src/main.c new file mode 100644 index 0000000..e61b630 --- /dev/null +++ b/generator/src/main.c @@ -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") + ); +} \ No newline at end of file diff --git a/generator/src/tstring.c b/generator/src/tstring.c new file mode 100644 index 0000000..adda2af --- /dev/null +++ b/generator/src/tstring.c @@ -0,0 +1,154 @@ +#include "tstring.h" +#include +#include +#include +#include +#include + +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); +} \ No newline at end of file diff --git a/src_list.txt b/src_list.txt new file mode 100644 index 0000000..73b279a --- /dev/null +++ b/src_list.txt @@ -0,0 +1,3 @@ +generator/src/generator.c +generator/src/tstring.c +generator/src/main.c \ No newline at end of file