@ -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 |