#include struct cudl_array_value { struct cudl_value *values; size_t length; }; struct cudl_map_value { struct cudl_map_field { char *key; struct cudl_value value; } *fields; size_t length; }; struct cudl_value { union { char *string; double number; int boolean; struct array_value array; struct map_value map; } data; int tag; }; #define CUDL_TAG_NULL 0 #define CUDL_TAG_ARRAY 1 #define CUDL_OK 0 #define CUDL_ERR_OUT_OF_MEMORY 1 #define CUDL_ERR_MISSING_VALUE 2 #define CUDL_ERR_READING 3 static char *fread_all(FILE *file) { size_t size; char *buffer; fseek(file, 0, SEEK_END); size = ftell(file); rewind(file); clearerr(file); if ((buffer = malloc(size + 1)) == NULL) return NULL; if (fread(buffer, 1, size, file) != size) { free(buffer); return NULL; } buffer[size] = '\0'; return buffer; } void cudl_debug(struct cudl_value *value) { } /* Free all children of the value, not the value itself */ void cudl_deinit_value(struct cudl_value value) { int i; switch (value.tag) { case CUDL_TAG_ARRAY: for (i = 0; i < value.data.array.length; i++) { cudl_deinit_value(value.data.array.values[i]); } free(value.data.array.values); break; case CUDL_TAG_NULL: case default: break; } } int cudl_parse_from_file(FILE *file, struct cudl_value *value) { char *input; if ((input = fread_all(file)) == NULL) { if (ferror(file)) return CUDL_ERR_READING; else return CUDL_ERR_OUT_OF_MEMORY; } return cudl_parse(input, value); } int cudl_parse(char *input, struct cudl_value *value) { }