can now generate basic *_to_json functions
parent
cc159c2244
commit
a8e2a1e28f
|
@ -0,0 +1,162 @@
|
|||
#include "kwil_generate.h"
|
||||
#include <inttypes.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
static
|
||||
int kwil_header_generated_file_name(struct kwil_header_t* self, char** out) {
|
||||
int len = strlen(self->file_name);
|
||||
char* filename = malloc(len + 5);
|
||||
strncpy(filename, self->file_name, len-2);
|
||||
strcpy(filename + len-2, ".kwil.h");
|
||||
*out = filename;
|
||||
return len;
|
||||
}
|
||||
|
||||
static
|
||||
int kwil_typename_to_prefix(const char* restrict type_name, char* out_prefix, size_t out_size) {
|
||||
int len = strlen(type_name);
|
||||
if(len > out_size) {
|
||||
return 1;
|
||||
}
|
||||
// generate a function prefix for a type name
|
||||
strcpy(out_prefix, type_name);
|
||||
|
||||
// remove _t postfix if relevant
|
||||
if(strcmp(out_prefix + len -3, "_t") == 0) {
|
||||
*(out_prefix + len - 3) = '\0';
|
||||
}
|
||||
return strlen(out_prefix);
|
||||
}
|
||||
|
||||
int kwil_header_generate(struct kwil_header_t* self) {
|
||||
char file_buffer[255];
|
||||
char* filename;
|
||||
kwil_header_generated_file_name(self, &filename);
|
||||
|
||||
FILE* file = fopen(filename, "w+");
|
||||
setvbuf(file, file_buffer, _IOLBF, 255);
|
||||
|
||||
if(!file) {
|
||||
printf("Failed to open kwil header for writing");
|
||||
free(filename);
|
||||
return 1;
|
||||
}
|
||||
|
||||
fprintf(file, "#include <string.h>\n"
|
||||
"#define KWIL_GEN_IMPL(...)\\\n");
|
||||
|
||||
for(int type_index = 0; type_index < self->types_len; ++type_index) {
|
||||
struct kwil_type_t* type = self->types + type_index;
|
||||
switch(type->type_tag) {
|
||||
case KWIL_TYPE_STRUCT:
|
||||
kwil_struct_generate_to_json(&type->struct_type, file, type->type_name);
|
||||
break;
|
||||
case KWIL_TYPE_ENUM:
|
||||
//kwil_enum_generate_to_string(&type->enum_type, file, type->type_name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(file, "\n");
|
||||
fclose(file);
|
||||
free(filename);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
void kwil_field_generate_to_string(struct kwil_field_t* self, FILE* file) {
|
||||
switch(self->type_tag) {
|
||||
case KWIL_FIELD_CHAR:
|
||||
if(self->array_length > 0 || self->array_dynamic) {
|
||||
fprintf(file, " if(src->%s != NULL) {\\\n"
|
||||
" json_len += sprintf(json + json_len, \"\\\"%%s\\\"\", src->%s);\\\n"
|
||||
" }\\\n",
|
||||
self->name_str, self->name_str);
|
||||
}
|
||||
break;
|
||||
case KWIL_FIELD_INT:
|
||||
fprintf(file, " json_len += sprintf(json + json_len, \"%%d\", src->%s);\\\n", self->name_str);
|
||||
break;
|
||||
case KWIL_FIELD_FLOAT:
|
||||
fprintf(file, " json_len += sprintf(json + json_len, \"%%f\", src->%s);\\\n", self->name_str);
|
||||
break;
|
||||
case KWIL_FIELD_UNSIGNED:
|
||||
fprintf(file, " json_len += sprintf(json + json_len, \"%%u\", src->%s);\\\n", self->name_str);
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
void kwil_field_get_serialized_length(struct kwil_field_t* self, FILE* file) {
|
||||
size_t len = strlen(self->name_str) + 4; // "name": ,
|
||||
|
||||
fprintf(file, " /* length of %s */\\\n"
|
||||
" json_capacity += %zu",
|
||||
self->name_str, len);
|
||||
|
||||
switch(self->type_tag) {
|
||||
case KWIL_FIELD_CHAR:
|
||||
if(self->array_dynamic || self->array_length > 0) {
|
||||
fprintf(file, " + strlen(src->%s);\\\n", self->name_str);
|
||||
} else {
|
||||
fprintf(file, " + 3;\\\n");
|
||||
}
|
||||
break;
|
||||
case KWIL_FIELD_INT:
|
||||
fprintf(file, "+ snprintf(NULL, 0, \"%%d\", src->%s);\\\n", self->name_str);
|
||||
break;
|
||||
case KWIL_FIELD_UNSIGNED:
|
||||
fprintf(file, " + snprintf(NULL, 0, \"%%du\", src->%s);\\\n", self->name_str);
|
||||
break;
|
||||
case KWIL_FIELD_FLOAT:
|
||||
fprintf(file, " + snprintf(NULL, 0, \"%%f\", src->%s);\\\n", self->name_str);
|
||||
break;
|
||||
case KWIL_FIELD_CUSTOM:
|
||||
case KWIL_FIELD_UNKNOWN:
|
||||
fprintf(file, ";\\\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int kwil_struct_generate_to_json(struct kwil_struct_t* self, FILE* file, const char* type_name) {
|
||||
char prefix[48];
|
||||
kwil_typename_to_prefix(type_name, prefix, 47);
|
||||
|
||||
fprintf(file, "int %s_to_json(struct %s* src, char** out_json) {\\\n"
|
||||
" int json_capacity = 2; \\\n" // allocate at least two for "{}\0"
|
||||
, prefix, type_name);
|
||||
|
||||
for(int field_index = 0; field_index < self->fields_len; ++field_index) {
|
||||
kwil_field_get_serialized_length(self->fields + field_index, file);
|
||||
}
|
||||
|
||||
fprintf(file, " char* json = malloc(json_capacity);\\\n"
|
||||
" int json_len = 1;\\\n"
|
||||
" strcpy(json, \"{\");\\\n"
|
||||
" *out_json = json;\\\n");
|
||||
|
||||
for(int field_index = 0; field_index < self->fields_len; ++field_index) {
|
||||
kwil_field_generate_to_json(self->fields + field_index, file);
|
||||
}
|
||||
|
||||
fprintf(file, " strcpy(json + json_len - 1, \"}\");\\\n"
|
||||
" return json_capacity;\\\n"
|
||||
"}\\\n");
|
||||
fflush(file);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int kwil_field_generate_to_json(struct kwil_field_t* self, FILE* file) {
|
||||
fprintf(file, " /* field: %s */\\\n", self->name_str);
|
||||
fprintf(file, " json_len += sprintf(json + json_len, \"\\\"%s\\\":\");\\\n",
|
||||
self->name_str);
|
||||
kwil_field_generate_to_string(self, file);
|
||||
fprintf(file, " strcpy(json + json_len, \",\");\\\n"
|
||||
" ++json_len;\\\n");
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
#ifndef _kwil_generate_H
|
||||
#define _kwil_generate_H
|
||||
|
||||
#include "kwil_def.h"
|
||||
#include <stdio.h>
|
||||
|
||||
extern int kwil_header_generate(struct kwil_header_t* self);
|
||||
|
||||
extern int kwil_struct_generate_to_json(struct kwil_struct_t* self, FILE* file, const char* type_name);
|
||||
extern int kwil_field_generate_to_json(struct kwil_field_t* self, FILE* file);
|
||||
extern int kwil_enum_generate_to_json(struct kwil_enum_t* self, FILE* file, const char* type_name);
|
||||
|
||||
#endif // !_kwil_generate_H
|
|
@ -0,0 +1,107 @@
|
|||
#include <string.h>
|
||||
#define KWIL_GEN_IMPL(...)\
|
||||
int struct_A_to_json(struct struct_A* src, char** out_json) {\
|
||||
int json_capacity = 2; \
|
||||
/* length of b */\
|
||||
json_capacity += 5+ snprintf(NULL, 0, "%d", src->b);\
|
||||
/* length of a */\
|
||||
json_capacity += 5 + snprintf(NULL, 0, "%f", src->a);\
|
||||
/* length of u */\
|
||||
json_capacity += 5 + snprintf(NULL, 0, "%du", src->u);\
|
||||
/* length of dyn_str */\
|
||||
json_capacity += 11 + strlen(src->dyn_str);\
|
||||
char* json = malloc(json_capacity);\
|
||||
int json_len = 1;\
|
||||
strcpy(json, "{");\
|
||||
*out_json = json;\
|
||||
/* field: b */\
|
||||
json_len += sprintf(json + json_len, "\"b\":");\
|
||||
json_len += sprintf(json + json_len, "%d", src->b);\
|
||||
strcpy(json + json_len, ",");\
|
||||
++json_len;\
|
||||
/* field: a */\
|
||||
json_len += sprintf(json + json_len, "\"a\":");\
|
||||
json_len += sprintf(json + json_len, "%f", src->a);\
|
||||
strcpy(json + json_len, ",");\
|
||||
++json_len;\
|
||||
/* field: u */\
|
||||
json_len += sprintf(json + json_len, "\"u\":");\
|
||||
json_len += sprintf(json + json_len, "%u", src->u);\
|
||||
strcpy(json + json_len, ",");\
|
||||
++json_len;\
|
||||
/* field: dyn_str */\
|
||||
json_len += sprintf(json + json_len, "\"dyn_str\":");\
|
||||
if(src->dyn_str != NULL) {\
|
||||
json_len += sprintf(json + json_len, "\"%s\"", src->dyn_str);\
|
||||
}\
|
||||
strcpy(json + json_len, ",");\
|
||||
++json_len;\
|
||||
strcpy(json + json_len - 1, "}");\
|
||||
return json_capacity;\
|
||||
}\
|
||||
int struct_B_to_json(struct struct_B* src, char** out_json) {\
|
||||
int json_capacity = 2; \
|
||||
/* length of f */\
|
||||
json_capacity += 5 + snprintf(NULL, 0, "%f", src->f);\
|
||||
/* length of i */\
|
||||
json_capacity += 5+ snprintf(NULL, 0, "%d", src->i);\
|
||||
/* length of str */\
|
||||
json_capacity += 7 + strlen(src->str);\
|
||||
/* length of str_static */\
|
||||
json_capacity += 14 + strlen(src->str_static);\
|
||||
/* length of other_struct */\
|
||||
json_capacity += 16;\
|
||||
/* length of other_struct_typedef */\
|
||||
json_capacity += 24;\
|
||||
/* length of other_enum */\
|
||||
json_capacity += 14;\
|
||||
/* length of other_enum_typedef */\
|
||||
json_capacity += 22;\
|
||||
char* json = malloc(json_capacity);\
|
||||
int json_len = 1;\
|
||||
strcpy(json, "{");\
|
||||
*out_json = json;\
|
||||
/* field: f */\
|
||||
json_len += sprintf(json + json_len, "\"f\":");\
|
||||
json_len += sprintf(json + json_len, "%f", src->f);\
|
||||
strcpy(json + json_len, ",");\
|
||||
++json_len;\
|
||||
/* field: i */\
|
||||
json_len += sprintf(json + json_len, "\"i\":");\
|
||||
json_len += sprintf(json + json_len, "%d", src->i);\
|
||||
strcpy(json + json_len, ",");\
|
||||
++json_len;\
|
||||
/* field: str */\
|
||||
json_len += sprintf(json + json_len, "\"str\":");\
|
||||
if(src->str != NULL) {\
|
||||
json_len += sprintf(json + json_len, "\"%s\"", src->str);\
|
||||
}\
|
||||
strcpy(json + json_len, ",");\
|
||||
++json_len;\
|
||||
/* field: str_static */\
|
||||
json_len += sprintf(json + json_len, "\"str_static\":");\
|
||||
if(src->str_static != NULL) {\
|
||||
json_len += sprintf(json + json_len, "\"%s\"", src->str_static);\
|
||||
}\
|
||||
strcpy(json + json_len, ",");\
|
||||
++json_len;\
|
||||
/* field: other_struct */\
|
||||
json_len += sprintf(json + json_len, "\"other_struct\":");\
|
||||
strcpy(json + json_len, ",");\
|
||||
++json_len;\
|
||||
/* field: other_struct_typedef */\
|
||||
json_len += sprintf(json + json_len, "\"other_struct_typedef\":");\
|
||||
strcpy(json + json_len, ",");\
|
||||
++json_len;\
|
||||
/* field: other_enum */\
|
||||
json_len += sprintf(json + json_len, "\"other_enum\":");\
|
||||
strcpy(json + json_len, ",");\
|
||||
++json_len;\
|
||||
/* field: other_enum_typedef */\
|
||||
json_len += sprintf(json + json_len, "\"other_enum_typedef\":");\
|
||||
strcpy(json + json_len, ",");\
|
||||
++json_len;\
|
||||
strcpy(json + json_len - 1, "}");\
|
||||
return json_capacity;\
|
||||
}\
|
||||
|
Loading…
Reference in New Issue