Loading CMakeLists.txt +3 −1 Original line number Diff line number Diff line cmake_minimum_required(VERSION 3.20) project(rsvp LANGUAGES C CXX) project(rsvp-c-cpp LANGUAGES C CXX) include_directories(src) add_compile_options("-Wall") add_subdirectory(src) add_subdirectory(tests) No newline at end of file check_mem.sh 0 → 100755 +12 −0 Original line number Diff line number Diff line #!/bin/bash SCRIPTPATH="$( cd "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )" cd $SCRIPTPATH/build make valgrind --leak-check=full \ --show-leak-kinds=all \ --track-origins=yes \ --log-file=valgrind-out.txt \ ./tests/testpp No newline at end of file src/CMakeLists.txt +3 −3 Original line number Diff line number Diff line Loading @@ -3,8 +3,8 @@ cmake_minimum_required(VERSION 3.20) project(rsvp) file(GLOB SRC *.c) add_library(${PROJECT_NAME} ${SRC}) file(GLOB SRC *.c *.hpp) file(GLOB SRC *.cpp) add_library(${PROJECT_NAME}pp ${SRC}) target_link_libraries(${PROJECT_NAME}pp rsvp) No newline at end of file src/rsvp.c +288 −101 Original line number Diff line number Diff line #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdarg.h> #include "rsvp.h" RSVP_TYPE get_type(char *type) Loading Loading @@ -31,10 +32,12 @@ int count_tokens(char *str, char delimiter) return counter; } void get_vecd_elem(char *token, rsvp_vecd_elem_t* elem) rsvp_vecd_elem_t* get_vecd_elem(char *token) { char *value = NULL, *begin = token; rsvp_vecd_elem_t* elem = NULL; int index = 0; size_t name_len = 0; while ((*token != '\0') && (value == NULL)) { Loading @@ -44,31 +47,41 @@ void get_vecd_elem(char *token, rsvp_vecd_elem_t* elem) break; default: index++; token++; break; } token++; } elem->name = (char*)malloc(index); memcpy(elem->name, begin, index); elem = (rsvp_vecd_elem_t*)malloc(sizeof(rsvp_vecd_elem_t)); if (!elem) { error_code = ALLOCATION_FAILED; goto exit; } elem->value = strtod(value, NULL); name_len = index + 1; elem->name = (char*)malloc(name_len); if (!elem->name) { error_code = ALLOCATION_FAILED; goto free_elem; } void get_vecd(char *value, rsvp_var_t* var) { char *token, delimiter = '='; var->len = count_tokens(value, delimiter); var->value = (rsvp_vecd_elem_t*)malloc(sizeof(rsvp_vecd_elem_t) * var->len); rsvp_vecd_elem_t* begin = (rsvp_vecd_elem_t*)var->value; memset(elem->name, 0, name_len); memcpy(elem->name, begin, name_len - 1); delimiter = ','; token = strtok(value, &delimiter); for (int i = 0; i < var->len; i++) { get_vecd_elem(token, begin++); token = strtok(NULL, &delimiter); if ((elem->value = strtod(value, NULL)) == 0.0) { error_code = DBL_CONVERSION_FAILED; sprintf(error_str, "Failed to convert %s to double", value); goto free_name; } return elem; free_name: free(elem->name); free_elem: free(elem); exit: return NULL; } rsvp_vecd_elem_t* rsvp_var_get_vecd_elem(rsvp_var_t* var, int index) Loading @@ -76,15 +89,16 @@ rsvp_vecd_elem_t* rsvp_var_get_vecd_elem(rsvp_var_t* var, int index) if (index >= var->len) { return NULL; } return (rsvp_vecd_elem_t*)var->value + index; return (rsvp_vecd_elem_t*)var->value.vecd + index; } void process_args(char *arg, rsvp_var_t* var) rsvp_var_t* process_args(char *arg) { char *begin = arg; char *value = NULL; char *begin = arg, *name = NULL, *value = NULL; RSVP_TYPE type = STR; int index = 0, type_start = 0; rsvp_var_t* var = NULL; size_t name_len = 0; // Search for the variable name while ((*arg != '\0') && (value == NULL)) { Loading @@ -92,27 +106,28 @@ void process_args(char *arg, rsvp_var_t* var) switch (*arg) { case '(': var->name = (char*)malloc(index + 1); memcpy(var->name, begin, index); var->name[index] = '\0'; name_len = index + 1; name = (char*)malloc(name_len); memset(name, 0, name_len); memcpy(name, begin, name_len - 1); type_start = index + 1; break; case ')': { size_t type_len = (index - type_start) + 1; char type[type_len]; memcpy(type, &begin[type_start], type_len); var->type = get_type(type); char type_str[type_len]; memcpy(type_str, &begin[type_start], type_len); type = get_type(type_str); break; } case '=': // We found the variable value if (var->name == NULL) { var->name = (char*)malloc(index + 1); memcpy(var->name, begin, index); var->name[index] = '\0'; if (name == NULL) { name_len = index + 1; name = (char*)malloc(name_len); memset(name, 0, name_len); memcpy(name, begin, name_len - 1); } value = ++arg; break; Loading @@ -125,51 +140,73 @@ void process_args(char *arg, rsvp_var_t* var) arg++; } switch (var->type) { switch (type) { case INT: { int value_int; var->value = malloc(sizeof(int)); value_int = strtol(value, NULL, 0); memcpy(var->value, &value_int, sizeof(int)); int value_int = strtol(value, NULL, 0); var = rsvp_var_create_int(name, value_int); break; } case DBL: { double value_dbl; var->value = malloc(sizeof(double)); value_dbl = strtod(value, NULL); memcpy(var->value, &value_dbl, sizeof(double)); double value_dbl = strtod(value, NULL); var = rsvp_var_create_double(name, value_dbl); break; } case BOOL: { int val = 0; var->value = malloc(1); if (strcmp(value, "TRUE") == 0) { val = 1; } memcpy(var->value, &val, 1); var = rsvp_var_create_bool(name, val); break; } case VECD: { get_vecd(++value, var); char *token = NULL, delimiter = '='; int elem_count = count_tokens(value, delimiter); var = rsvp_var_create_vecd(name); delimiter = ','; token = strtok(++value, &delimiter); for (int i = 0; i < elem_count; i++) { rsvp_vecd_elem_t *elem = NULL; elem = get_vecd_elem(token); if (!elem) { printf("Error: %s\n", error_str); continue; } rsvp_vecd_add_elem(var, elem->name, elem->value); free(elem->name); free(elem); token = strtok(NULL, &delimiter); } break; } case VECS: { char *token = NULL, delimiter = '\t'; int elem_count = count_tokens(value, delimiter) + 1; var = rsvp_var_create_vecs(name); token = strtok(value, &delimiter); for (int i = 0; i < elem_count; i++) { rsvp_vecs_add_elem(var, token); token = strtok(NULL, &delimiter); } break; } default: var->value = (char*)malloc(strlen(value) + 1); memset(var->value, 0, strlen(value) + 1); memcpy(var->value, value, strlen(value)); var = rsvp_var_create_string(name, value); break; } Loading @@ -178,15 +215,29 @@ void process_args(char *arg, rsvp_var_t* var) rsvp_var_print(var); #endif free(name); if (!var) { error_code = VAR_CREATION_FAILED; printf("Failed to add arg\n"); return NULL; } return var; } rsvp_data_t *rsvp_data_parse(char* data) { char *token; char **args; char *token = NULL; char **args =NULL; char delimiter = ';'; size_t index = 0; size_t index = 0, token_len = 0; rsvp_data_t *rsvp_data = (rsvp_data_t*)malloc(sizeof(rsvp_data_t)); if (!rsvp_data) { error_code = ALLOCATION_FAILED; return NULL; } memset(rsvp_data, 0, sizeof(rsvp_data_t)); rsvp_data->args_count = count_tokens(data, delimiter); Loading @@ -194,8 +245,10 @@ rsvp_data_t *rsvp_data_parse(char* data) // Get command string token = strtok(data, &delimiter); rsvp_data->cmd = (char*)malloc(strlen(token)); memcpy(rsvp_data->cmd, token, strlen(token)); token_len = strlen(token) + 1; rsvp_data->cmd = (char*)malloc(token_len); memset(rsvp_data->cmd, 0, token_len); memcpy(rsvp_data->cmd, token, token_len - 1); // Process args while (token != NULL) { Loading @@ -205,22 +258,38 @@ rsvp_data_t *rsvp_data_parse(char* data) break; } token_len = strlen(token) + 1; #ifdef DEBUG printf("*** DBG *** token[%d]: %s\n", rsvp_data->args_count, token); #endif args[index] = (char*)malloc(strlen(token)); memcpy(args[index++], token, strlen(token)); args[index] = (char*)malloc(token_len); memset(args[index], 0, token_len); memcpy(args[index++], token, token_len - 1); } rsvp_data->args = (rsvp_var_t*)malloc(rsvp_data->args_count * sizeof(rsvp_var_t)); rsvp_data->args = (rsvp_var_t**)malloc(rsvp_data->args_count * sizeof(rsvp_var_t*)); if (!rsvp_data->args) { error_code = ALLOCATION_FAILED; return NULL; } #ifdef DEBUG rsvp_data_print(rsvp_data); #endif for(int i = 0; i < rsvp_data->args_count; i++) { process_args(args[i], &rsvp_data->args[i]); rsvp_data->args[i] = process_args(args[i]); if (!rsvp_data->args[i]) { break; } } for (int i = 0; i < rsvp_data->args_count; i++) { free(args[i]); } free(args); return rsvp_data; } Loading @@ -232,77 +301,119 @@ void rsvp_var_print(rsvp_var_t *var) switch (var->type) { case INT: printf("%d\n", *(int*)var->value); printf("%d\n", var->value.i); break; case DBL: printf("%f\n", *(double*)var->value); printf("%f\n", var->value.d); break; case BOOL: printf("%d\n", *(int*)var->value); printf("%d\n", var->value.b); break; case VECD: printf("["); for (int i = 0; i < var->len; i++) { rsvp_vecd_elem_t* elem = rsvp_var_get_vecd_elem(var, i); printf("%s=%f,", elem->name, elem->value); printf("%s=%f", elem->name, elem->value); if (i < var->len - 1) { printf(","); } elem++; } printf("]\n"); break; case VECS: for (int i = 0; i < var->len; i++) { printf("%s\t", var->value.vecs[i]); } printf("\n"); break; default: printf("%s\n", (char*)var->value); printf("%s\n", var->value.s); break; } } void rsvp_data_print(rsvp_data_t *data) { printf("Command: %s, args:\n", data->cmd); printf("Command: %s, args [%d]:\n", data->cmd, data->args_count); for(int i = 0; i < data->args_count; i++) { rsvp_var_print(&data->args[i]); printf("ARG[%d] => ", i); rsvp_var_print(data->args[i]); } } void rsvp_data_free(rsvp_data_t *data) { if (data != NULL) { for (int i = 0; i < data->args_count; i++) { rsvp_var_free(&data->args[i]); rsvp_var_free(data->args[i]); } if (data->args) free(data->args); free(data->cmd); free(data); } } void rsvp_var_free(rsvp_var_t *var) { free(var->name); if (var) { switch (var->type) { case VECD: for (int i = 0; i < var->len; i++) { rsvp_vecd_elem_t* elem = rsvp_var_get_vecd_elem(var, i); free(elem->name); elem++; } free(var->value.vecd); break; case VECS: for (int i = 0; i < var->len; i++) { free(var->value.vecs[i]); } free(var->value.vecs); break; case STR: free(var->value.s); break; default: free(var->value); break; } free(var->name); free(var); } } rsvp_var_t* rsvp_var_init(char *name) { size_t len = strlen(name) + 1; rsvp_var_t *var = (rsvp_var_t*)malloc(sizeof(rsvp_var_t)); if (!var) { error_code = ALLOCATION_FAILED; return NULL; } memset(var, 0, sizeof(rsvp_var_t)); var->name = (char*)malloc(strlen(name)); memcpy(var->name, name, strlen(name)); var->name = (char*)malloc(len); if (!var->name) { error_code = ALLOCATION_FAILED; free(var); return NULL; } memset(var->name, '\0', len); memcpy(var->name, name, len - 1); return var; } Loading @@ -310,9 +421,11 @@ rsvp_var_t* rsvp_var_init(char *name) rsvp_var_t* rsvp_var_create_int(char *name, int value) { rsvp_var_t *var = rsvp_var_init(name); if (!var) return NULL; var->type = INT; var->value = malloc(sizeof(int)); memcpy(var->value, &value, sizeof(int)); var->value.i = value; return var; } Loading @@ -320,17 +433,23 @@ rsvp_var_t* rsvp_var_create_int(char *name, int value) rsvp_var_t* rsvp_var_create_double(char *name, double value) { rsvp_var_t *var = rsvp_var_init(name); if (!var) return NULL; var->type = DBL; var->value = malloc(sizeof(double)); memcpy(var->value, &value, sizeof(double)); var->value.d = value; return var; } rsvp_var_t* rsvp_var_create_bool(char *name, int value) { rsvp_var_t *var = rsvp_var_create_int(name, value); rsvp_var_t *var = rsvp_var_init(name); if (!var) return NULL; var->type = BOOL; var->value.b = value; return var; } Loading @@ -338,28 +457,96 @@ rsvp_var_t* rsvp_var_create_bool(char *name, int value) rsvp_var_t* rsvp_var_create_string(char *name, char* value) { rsvp_var_t *var = rsvp_var_init(name); if (!var) return NULL; var->type = STR; var->value = malloc(strlen(value)); memcpy(var->value, &value, strlen(value)); var->value.s = (char*)malloc(strlen(value)); if (!var->value.s) { error_code = ALLOCATION_FAILED; return NULL; } memcpy(var->value.s, value, strlen(value)); return var; } rsvp_var_t* rsvp_var_create_vecd(char *name, rsvp_vecd_elem_t *elem, unsigned int count) rsvp_var_t* rsvp_var_create_vecd(char *name) { rsvp_var_t *var = rsvp_var_init(name); if (!var) return NULL; var->type = VECD; var->value = malloc(count * sizeof(rsvp_vecd_elem_t)); var->len = count; for (int i = 0; i < count; i++) { // rsvp_vecd_elem_t *elem = rsvp_var_get_vecd_elem(var, i); // elem->name = (char*)malloc(strlen(names)); // memcpy(elem->name, names, strlen(names)); // names += strlen(names); // elem->value = values[i]; return var; } int rsvp_vecd_add_elem(rsvp_var_t* vecd, char* name, double value) { size_t name_len = strlen(name) + 1; if (vecd->type != VECD) { error_code = WRONG_VARIABLE_TYPE; return -1; } vecd->len += 1; vecd->value.vecd = (rsvp_vecd_elem_t*)realloc(vecd->value.vecd, vecd->len * sizeof(rsvp_vecd_elem_t)); if (!vecd->value.vecd) { error_code = ALLOCATION_FAILED; vecd->len -= 1; return -1; } vecd->value.vecd[vecd->len - 1].name = (char*)malloc(name_len); if (!vecd->value.vecd[vecd->len - 1].name) { } memset(vecd->value.vecd[vecd->len - 1].name, 0, name_len); memcpy(vecd->value.vecd[vecd->len - 1].name, name, name_len - 1); vecd->value.vecd[vecd->len - 1].value = value; return 0; } rsvp_var_t* rsvp_var_create_vecs(char *name) { rsvp_var_t *var = rsvp_var_init(name); if (!var) return NULL; var->type = VECS; return var; } int rsvp_vecs_add_elem(rsvp_var_t* vecs, char *value) { size_t value_len = strlen(value) + 1; if (vecs->type != VECS) { error_code = WRONG_VARIABLE_TYPE; return -1; } vecs->len += 1; vecs->value.vecs = (char**)realloc(vecs->value.vecs, vecs->len * sizeof(char*)); if (!vecs->value.vecs) { error_code = ALLOCATION_FAILED; return -1; } vecs->value.vecs[vecs->len - 1] = (char*)malloc(value_len); if (!vecs->value.vecs[vecs->len - 1]) { error_code = ALLOCATION_FAILED; return -1; } memset(vecs->value.vecs[vecs->len - 1], 0, value_len); memcpy(vecs->value.vecs[vecs->len - 1], value, value_len - 1); return NO_ERROR; } No newline at end of file src/rsvp.h +32 −3 Original line number Diff line number Diff line Loading @@ -3,6 +3,18 @@ #define TYPE_COUNT 6 #define ERR_STR_SIZE 256 #define NO_ERROR 0 #define ALLOCATION_FAILED (NO_ERROR + 1) #define VAR_CREATION_FAILED (ALLOCATION_FAILED + 1) #define DBL_CONVERSION_FAILED (VAR_CREATION_FAILED + 1) #define INT_CONVERSION_FAILED 4 #define BOOL_CONVERSION_FAILED 5 #define WRONG_VARIABLE_TYPE 6 static int error_code = NO_ERROR; static char error_str[ERR_STR_SIZE] = {0}; typedef enum { STR = 0, INT, Loading Loading @@ -32,17 +44,31 @@ struct rsvp_vecs_elem { }; typedef struct rsvp_vecs_elem rsvp_vecs_elem_t; typedef union { int i; double d; int b; char *s; rsvp_vecd_elem_t* vecd; char** vecs; } value_t; struct rsvp_var { char *name; int len; RSVP_TYPE type; void *value; value_t value; // void *value; }; typedef struct rsvp_var rsvp_var_t; struct rsvp_data { char *cmd; rsvp_var_t *args; rsvp_var_t **args; unsigned int args_count; }; typedef struct rsvp_data rsvp_data_t; Loading @@ -58,7 +84,10 @@ extern rsvp_var_t* rsvp_var_create_int(char *name, int value); extern rsvp_var_t* rsvp_var_create_double(char *name, double value); extern rsvp_var_t* rsvp_var_create_bool(char *name, int value); extern rsvp_var_t* rsvp_var_create_string(char *name, char* value); extern rsvp_var_t* rsvp_var_create_vecd(char *name, rsvp_vecd_elem_t *elem, unsigned int count); extern rsvp_var_t* rsvp_var_create_vecd(char *name); extern int rsvp_vecd_add_elem(rsvp_var_t* vecd, char* name, double value); extern rsvp_var_t* rsvp_var_create_vecs(char *name); extern int rsvp_vecs_add_elem(rsvp_var_t* vecs, char* value); extern rsvp_vecd_elem_t* rsvp_var_get_vecd_elem(rsvp_var_t* var, int index); extern void rsvp_var_print(rsvp_var_t *var); Loading Loading
CMakeLists.txt +3 −1 Original line number Diff line number Diff line cmake_minimum_required(VERSION 3.20) project(rsvp LANGUAGES C CXX) project(rsvp-c-cpp LANGUAGES C CXX) include_directories(src) add_compile_options("-Wall") add_subdirectory(src) add_subdirectory(tests) No newline at end of file
check_mem.sh 0 → 100755 +12 −0 Original line number Diff line number Diff line #!/bin/bash SCRIPTPATH="$( cd "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )" cd $SCRIPTPATH/build make valgrind --leak-check=full \ --show-leak-kinds=all \ --track-origins=yes \ --log-file=valgrind-out.txt \ ./tests/testpp No newline at end of file
src/CMakeLists.txt +3 −3 Original line number Diff line number Diff line Loading @@ -3,8 +3,8 @@ cmake_minimum_required(VERSION 3.20) project(rsvp) file(GLOB SRC *.c) add_library(${PROJECT_NAME} ${SRC}) file(GLOB SRC *.c *.hpp) file(GLOB SRC *.cpp) add_library(${PROJECT_NAME}pp ${SRC}) target_link_libraries(${PROJECT_NAME}pp rsvp) No newline at end of file
src/rsvp.c +288 −101 Original line number Diff line number Diff line #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdarg.h> #include "rsvp.h" RSVP_TYPE get_type(char *type) Loading Loading @@ -31,10 +32,12 @@ int count_tokens(char *str, char delimiter) return counter; } void get_vecd_elem(char *token, rsvp_vecd_elem_t* elem) rsvp_vecd_elem_t* get_vecd_elem(char *token) { char *value = NULL, *begin = token; rsvp_vecd_elem_t* elem = NULL; int index = 0; size_t name_len = 0; while ((*token != '\0') && (value == NULL)) { Loading @@ -44,31 +47,41 @@ void get_vecd_elem(char *token, rsvp_vecd_elem_t* elem) break; default: index++; token++; break; } token++; } elem->name = (char*)malloc(index); memcpy(elem->name, begin, index); elem = (rsvp_vecd_elem_t*)malloc(sizeof(rsvp_vecd_elem_t)); if (!elem) { error_code = ALLOCATION_FAILED; goto exit; } elem->value = strtod(value, NULL); name_len = index + 1; elem->name = (char*)malloc(name_len); if (!elem->name) { error_code = ALLOCATION_FAILED; goto free_elem; } void get_vecd(char *value, rsvp_var_t* var) { char *token, delimiter = '='; var->len = count_tokens(value, delimiter); var->value = (rsvp_vecd_elem_t*)malloc(sizeof(rsvp_vecd_elem_t) * var->len); rsvp_vecd_elem_t* begin = (rsvp_vecd_elem_t*)var->value; memset(elem->name, 0, name_len); memcpy(elem->name, begin, name_len - 1); delimiter = ','; token = strtok(value, &delimiter); for (int i = 0; i < var->len; i++) { get_vecd_elem(token, begin++); token = strtok(NULL, &delimiter); if ((elem->value = strtod(value, NULL)) == 0.0) { error_code = DBL_CONVERSION_FAILED; sprintf(error_str, "Failed to convert %s to double", value); goto free_name; } return elem; free_name: free(elem->name); free_elem: free(elem); exit: return NULL; } rsvp_vecd_elem_t* rsvp_var_get_vecd_elem(rsvp_var_t* var, int index) Loading @@ -76,15 +89,16 @@ rsvp_vecd_elem_t* rsvp_var_get_vecd_elem(rsvp_var_t* var, int index) if (index >= var->len) { return NULL; } return (rsvp_vecd_elem_t*)var->value + index; return (rsvp_vecd_elem_t*)var->value.vecd + index; } void process_args(char *arg, rsvp_var_t* var) rsvp_var_t* process_args(char *arg) { char *begin = arg; char *value = NULL; char *begin = arg, *name = NULL, *value = NULL; RSVP_TYPE type = STR; int index = 0, type_start = 0; rsvp_var_t* var = NULL; size_t name_len = 0; // Search for the variable name while ((*arg != '\0') && (value == NULL)) { Loading @@ -92,27 +106,28 @@ void process_args(char *arg, rsvp_var_t* var) switch (*arg) { case '(': var->name = (char*)malloc(index + 1); memcpy(var->name, begin, index); var->name[index] = '\0'; name_len = index + 1; name = (char*)malloc(name_len); memset(name, 0, name_len); memcpy(name, begin, name_len - 1); type_start = index + 1; break; case ')': { size_t type_len = (index - type_start) + 1; char type[type_len]; memcpy(type, &begin[type_start], type_len); var->type = get_type(type); char type_str[type_len]; memcpy(type_str, &begin[type_start], type_len); type = get_type(type_str); break; } case '=': // We found the variable value if (var->name == NULL) { var->name = (char*)malloc(index + 1); memcpy(var->name, begin, index); var->name[index] = '\0'; if (name == NULL) { name_len = index + 1; name = (char*)malloc(name_len); memset(name, 0, name_len); memcpy(name, begin, name_len - 1); } value = ++arg; break; Loading @@ -125,51 +140,73 @@ void process_args(char *arg, rsvp_var_t* var) arg++; } switch (var->type) { switch (type) { case INT: { int value_int; var->value = malloc(sizeof(int)); value_int = strtol(value, NULL, 0); memcpy(var->value, &value_int, sizeof(int)); int value_int = strtol(value, NULL, 0); var = rsvp_var_create_int(name, value_int); break; } case DBL: { double value_dbl; var->value = malloc(sizeof(double)); value_dbl = strtod(value, NULL); memcpy(var->value, &value_dbl, sizeof(double)); double value_dbl = strtod(value, NULL); var = rsvp_var_create_double(name, value_dbl); break; } case BOOL: { int val = 0; var->value = malloc(1); if (strcmp(value, "TRUE") == 0) { val = 1; } memcpy(var->value, &val, 1); var = rsvp_var_create_bool(name, val); break; } case VECD: { get_vecd(++value, var); char *token = NULL, delimiter = '='; int elem_count = count_tokens(value, delimiter); var = rsvp_var_create_vecd(name); delimiter = ','; token = strtok(++value, &delimiter); for (int i = 0; i < elem_count; i++) { rsvp_vecd_elem_t *elem = NULL; elem = get_vecd_elem(token); if (!elem) { printf("Error: %s\n", error_str); continue; } rsvp_vecd_add_elem(var, elem->name, elem->value); free(elem->name); free(elem); token = strtok(NULL, &delimiter); } break; } case VECS: { char *token = NULL, delimiter = '\t'; int elem_count = count_tokens(value, delimiter) + 1; var = rsvp_var_create_vecs(name); token = strtok(value, &delimiter); for (int i = 0; i < elem_count; i++) { rsvp_vecs_add_elem(var, token); token = strtok(NULL, &delimiter); } break; } default: var->value = (char*)malloc(strlen(value) + 1); memset(var->value, 0, strlen(value) + 1); memcpy(var->value, value, strlen(value)); var = rsvp_var_create_string(name, value); break; } Loading @@ -178,15 +215,29 @@ void process_args(char *arg, rsvp_var_t* var) rsvp_var_print(var); #endif free(name); if (!var) { error_code = VAR_CREATION_FAILED; printf("Failed to add arg\n"); return NULL; } return var; } rsvp_data_t *rsvp_data_parse(char* data) { char *token; char **args; char *token = NULL; char **args =NULL; char delimiter = ';'; size_t index = 0; size_t index = 0, token_len = 0; rsvp_data_t *rsvp_data = (rsvp_data_t*)malloc(sizeof(rsvp_data_t)); if (!rsvp_data) { error_code = ALLOCATION_FAILED; return NULL; } memset(rsvp_data, 0, sizeof(rsvp_data_t)); rsvp_data->args_count = count_tokens(data, delimiter); Loading @@ -194,8 +245,10 @@ rsvp_data_t *rsvp_data_parse(char* data) // Get command string token = strtok(data, &delimiter); rsvp_data->cmd = (char*)malloc(strlen(token)); memcpy(rsvp_data->cmd, token, strlen(token)); token_len = strlen(token) + 1; rsvp_data->cmd = (char*)malloc(token_len); memset(rsvp_data->cmd, 0, token_len); memcpy(rsvp_data->cmd, token, token_len - 1); // Process args while (token != NULL) { Loading @@ -205,22 +258,38 @@ rsvp_data_t *rsvp_data_parse(char* data) break; } token_len = strlen(token) + 1; #ifdef DEBUG printf("*** DBG *** token[%d]: %s\n", rsvp_data->args_count, token); #endif args[index] = (char*)malloc(strlen(token)); memcpy(args[index++], token, strlen(token)); args[index] = (char*)malloc(token_len); memset(args[index], 0, token_len); memcpy(args[index++], token, token_len - 1); } rsvp_data->args = (rsvp_var_t*)malloc(rsvp_data->args_count * sizeof(rsvp_var_t)); rsvp_data->args = (rsvp_var_t**)malloc(rsvp_data->args_count * sizeof(rsvp_var_t*)); if (!rsvp_data->args) { error_code = ALLOCATION_FAILED; return NULL; } #ifdef DEBUG rsvp_data_print(rsvp_data); #endif for(int i = 0; i < rsvp_data->args_count; i++) { process_args(args[i], &rsvp_data->args[i]); rsvp_data->args[i] = process_args(args[i]); if (!rsvp_data->args[i]) { break; } } for (int i = 0; i < rsvp_data->args_count; i++) { free(args[i]); } free(args); return rsvp_data; } Loading @@ -232,77 +301,119 @@ void rsvp_var_print(rsvp_var_t *var) switch (var->type) { case INT: printf("%d\n", *(int*)var->value); printf("%d\n", var->value.i); break; case DBL: printf("%f\n", *(double*)var->value); printf("%f\n", var->value.d); break; case BOOL: printf("%d\n", *(int*)var->value); printf("%d\n", var->value.b); break; case VECD: printf("["); for (int i = 0; i < var->len; i++) { rsvp_vecd_elem_t* elem = rsvp_var_get_vecd_elem(var, i); printf("%s=%f,", elem->name, elem->value); printf("%s=%f", elem->name, elem->value); if (i < var->len - 1) { printf(","); } elem++; } printf("]\n"); break; case VECS: for (int i = 0; i < var->len; i++) { printf("%s\t", var->value.vecs[i]); } printf("\n"); break; default: printf("%s\n", (char*)var->value); printf("%s\n", var->value.s); break; } } void rsvp_data_print(rsvp_data_t *data) { printf("Command: %s, args:\n", data->cmd); printf("Command: %s, args [%d]:\n", data->cmd, data->args_count); for(int i = 0; i < data->args_count; i++) { rsvp_var_print(&data->args[i]); printf("ARG[%d] => ", i); rsvp_var_print(data->args[i]); } } void rsvp_data_free(rsvp_data_t *data) { if (data != NULL) { for (int i = 0; i < data->args_count; i++) { rsvp_var_free(&data->args[i]); rsvp_var_free(data->args[i]); } if (data->args) free(data->args); free(data->cmd); free(data); } } void rsvp_var_free(rsvp_var_t *var) { free(var->name); if (var) { switch (var->type) { case VECD: for (int i = 0; i < var->len; i++) { rsvp_vecd_elem_t* elem = rsvp_var_get_vecd_elem(var, i); free(elem->name); elem++; } free(var->value.vecd); break; case VECS: for (int i = 0; i < var->len; i++) { free(var->value.vecs[i]); } free(var->value.vecs); break; case STR: free(var->value.s); break; default: free(var->value); break; } free(var->name); free(var); } } rsvp_var_t* rsvp_var_init(char *name) { size_t len = strlen(name) + 1; rsvp_var_t *var = (rsvp_var_t*)malloc(sizeof(rsvp_var_t)); if (!var) { error_code = ALLOCATION_FAILED; return NULL; } memset(var, 0, sizeof(rsvp_var_t)); var->name = (char*)malloc(strlen(name)); memcpy(var->name, name, strlen(name)); var->name = (char*)malloc(len); if (!var->name) { error_code = ALLOCATION_FAILED; free(var); return NULL; } memset(var->name, '\0', len); memcpy(var->name, name, len - 1); return var; } Loading @@ -310,9 +421,11 @@ rsvp_var_t* rsvp_var_init(char *name) rsvp_var_t* rsvp_var_create_int(char *name, int value) { rsvp_var_t *var = rsvp_var_init(name); if (!var) return NULL; var->type = INT; var->value = malloc(sizeof(int)); memcpy(var->value, &value, sizeof(int)); var->value.i = value; return var; } Loading @@ -320,17 +433,23 @@ rsvp_var_t* rsvp_var_create_int(char *name, int value) rsvp_var_t* rsvp_var_create_double(char *name, double value) { rsvp_var_t *var = rsvp_var_init(name); if (!var) return NULL; var->type = DBL; var->value = malloc(sizeof(double)); memcpy(var->value, &value, sizeof(double)); var->value.d = value; return var; } rsvp_var_t* rsvp_var_create_bool(char *name, int value) { rsvp_var_t *var = rsvp_var_create_int(name, value); rsvp_var_t *var = rsvp_var_init(name); if (!var) return NULL; var->type = BOOL; var->value.b = value; return var; } Loading @@ -338,28 +457,96 @@ rsvp_var_t* rsvp_var_create_bool(char *name, int value) rsvp_var_t* rsvp_var_create_string(char *name, char* value) { rsvp_var_t *var = rsvp_var_init(name); if (!var) return NULL; var->type = STR; var->value = malloc(strlen(value)); memcpy(var->value, &value, strlen(value)); var->value.s = (char*)malloc(strlen(value)); if (!var->value.s) { error_code = ALLOCATION_FAILED; return NULL; } memcpy(var->value.s, value, strlen(value)); return var; } rsvp_var_t* rsvp_var_create_vecd(char *name, rsvp_vecd_elem_t *elem, unsigned int count) rsvp_var_t* rsvp_var_create_vecd(char *name) { rsvp_var_t *var = rsvp_var_init(name); if (!var) return NULL; var->type = VECD; var->value = malloc(count * sizeof(rsvp_vecd_elem_t)); var->len = count; for (int i = 0; i < count; i++) { // rsvp_vecd_elem_t *elem = rsvp_var_get_vecd_elem(var, i); // elem->name = (char*)malloc(strlen(names)); // memcpy(elem->name, names, strlen(names)); // names += strlen(names); // elem->value = values[i]; return var; } int rsvp_vecd_add_elem(rsvp_var_t* vecd, char* name, double value) { size_t name_len = strlen(name) + 1; if (vecd->type != VECD) { error_code = WRONG_VARIABLE_TYPE; return -1; } vecd->len += 1; vecd->value.vecd = (rsvp_vecd_elem_t*)realloc(vecd->value.vecd, vecd->len * sizeof(rsvp_vecd_elem_t)); if (!vecd->value.vecd) { error_code = ALLOCATION_FAILED; vecd->len -= 1; return -1; } vecd->value.vecd[vecd->len - 1].name = (char*)malloc(name_len); if (!vecd->value.vecd[vecd->len - 1].name) { } memset(vecd->value.vecd[vecd->len - 1].name, 0, name_len); memcpy(vecd->value.vecd[vecd->len - 1].name, name, name_len - 1); vecd->value.vecd[vecd->len - 1].value = value; return 0; } rsvp_var_t* rsvp_var_create_vecs(char *name) { rsvp_var_t *var = rsvp_var_init(name); if (!var) return NULL; var->type = VECS; return var; } int rsvp_vecs_add_elem(rsvp_var_t* vecs, char *value) { size_t value_len = strlen(value) + 1; if (vecs->type != VECS) { error_code = WRONG_VARIABLE_TYPE; return -1; } vecs->len += 1; vecs->value.vecs = (char**)realloc(vecs->value.vecs, vecs->len * sizeof(char*)); if (!vecs->value.vecs) { error_code = ALLOCATION_FAILED; return -1; } vecs->value.vecs[vecs->len - 1] = (char*)malloc(value_len); if (!vecs->value.vecs[vecs->len - 1]) { error_code = ALLOCATION_FAILED; return -1; } memset(vecs->value.vecs[vecs->len - 1], 0, value_len); memcpy(vecs->value.vecs[vecs->len - 1], value, value_len - 1); return NO_ERROR; } No newline at end of file
src/rsvp.h +32 −3 Original line number Diff line number Diff line Loading @@ -3,6 +3,18 @@ #define TYPE_COUNT 6 #define ERR_STR_SIZE 256 #define NO_ERROR 0 #define ALLOCATION_FAILED (NO_ERROR + 1) #define VAR_CREATION_FAILED (ALLOCATION_FAILED + 1) #define DBL_CONVERSION_FAILED (VAR_CREATION_FAILED + 1) #define INT_CONVERSION_FAILED 4 #define BOOL_CONVERSION_FAILED 5 #define WRONG_VARIABLE_TYPE 6 static int error_code = NO_ERROR; static char error_str[ERR_STR_SIZE] = {0}; typedef enum { STR = 0, INT, Loading Loading @@ -32,17 +44,31 @@ struct rsvp_vecs_elem { }; typedef struct rsvp_vecs_elem rsvp_vecs_elem_t; typedef union { int i; double d; int b; char *s; rsvp_vecd_elem_t* vecd; char** vecs; } value_t; struct rsvp_var { char *name; int len; RSVP_TYPE type; void *value; value_t value; // void *value; }; typedef struct rsvp_var rsvp_var_t; struct rsvp_data { char *cmd; rsvp_var_t *args; rsvp_var_t **args; unsigned int args_count; }; typedef struct rsvp_data rsvp_data_t; Loading @@ -58,7 +84,10 @@ extern rsvp_var_t* rsvp_var_create_int(char *name, int value); extern rsvp_var_t* rsvp_var_create_double(char *name, double value); extern rsvp_var_t* rsvp_var_create_bool(char *name, int value); extern rsvp_var_t* rsvp_var_create_string(char *name, char* value); extern rsvp_var_t* rsvp_var_create_vecd(char *name, rsvp_vecd_elem_t *elem, unsigned int count); extern rsvp_var_t* rsvp_var_create_vecd(char *name); extern int rsvp_vecd_add_elem(rsvp_var_t* vecd, char* name, double value); extern rsvp_var_t* rsvp_var_create_vecs(char *name); extern int rsvp_vecs_add_elem(rsvp_var_t* vecs, char* value); extern rsvp_vecd_elem_t* rsvp_var_get_vecd_elem(rsvp_var_t* var, int index); extern void rsvp_var_print(rsvp_var_t *var); Loading