Commit 30a451cb authored by Gallacchi Mattia's avatar Gallacchi Mattia
Browse files

Add VECS to string conversion

parent 87d964d7
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -2,6 +2,9 @@ cmake_minimum_required(VERSION 3.20)

project(rsvp-c-cpp LANGUAGES C CXX)

include(CTest)
enable_testing()

include(FetchContent)
FetchContent_Declare(
  googletest
+159 −1
Original line number Diff line number Diff line
@@ -364,6 +364,164 @@ int rsvp_data_add_vars(rsvp_data_t* data, unsigned int count, ...)
    return NO_ERROR;
}

int count_char_in_int(int value)
{
    // Take into account the sign
    int chars = value < 0 ? 1 : 0;
    int modulo = 0;

    if (value == 0)
        return 1;
    
    value = abs(value);

    while (value > 0) {
        modulo = value % 10;

        if (modulo == 0)
            value /= 10;
        else
            value = (value - modulo) / 10;
        
        chars++;
    }

    return chars;
}

int count_chars_in_double(double value, int precision)
{  
    // Start at precision. Plus one to account for the dot
    int chars = precision + 1;
    int int_value = (int)value;

    // Account for negative 0
    if (value > -1.0 && value < 0.0)
        chars += 1;

    return count_char_in_int(int_value) + chars;
}

char* rsvp_data_to_string(rsvp_data_t* data, int double_precision)
{
    char *str = NULL;
    size_t len = strlen(data->cmd) + 1;
    char dbl_format[] = "%.5f";
    
    str = (char*)malloc(len);
    if (!str) {
        set_error_string("Allocation for command failed");
        return NULL;
    }
    memset(str, 0, len);
    memcpy(str, data->cmd, len - 1);

    for (unsigned int i = 0; i < data->args_count; i++) {
        rsvp_var_t *arg = data->args[i];
        const char *type = rsvp_type_str[arg->type];
        char *arg_value = NULL, *arg_name = NULL;
        size_t value_len = 0, arg_len = 0;
        int ret = 0;
        //       ";      NAME            (       INT         )=\0"
        arg_len = 1 + strlen(arg->name) + 1 + strlen(type) + 3;
        arg_name = (char*)malloc(arg_len);
        if (snprintf(arg_name, arg_len, ";%s(%s)=", arg->name, type) != (arg_len - 1))
            ret = -1;
        
        switch (arg->type) {
            case INT:
                value_len = count_char_in_int(arg->value.i) + 1;
                arg_value = (char*)malloc(value_len);
                if (snprintf(arg_value, value_len, "%d", arg->value.i) != (value_len - 1))
                    ret = -1;
                break;
            case DBL:
                value_len = count_chars_in_double(arg->value.d, double_precision) + 1;
                arg_value = (char*)malloc(value_len);
                if (snprintf(arg_value, value_len, "%.5f", arg->value.d) != (value_len - 1))
                    ret = -1;
                break;

            case BOOL:
                char *value = arg->value.b > 0 ? "TRUE" : "FALSE";
                value_len = strlen(value) + 1;
                arg_value = (char*)malloc(value_len);
                if (snprintf(arg_value, value_len, "%s", value) != (value_len - 1))
                    ret = -1;
                break;

            case STR:
                value_len = strlen(arg->value.s) + 1;
                arg_value = (char*)malloc(value_len);
                if (snprintf(arg_value, value_len, "%s", arg->value.s) != value_len - 1)
                    ret = -1;
                break;

            case VECD:
                int index = 0;
                // []
                value_len = 2;
                for (int i = 0; i < arg_len; i++) {
                    rsvp_vecd_elem_t* elem = rsvp_var_get_vecd_elem(arg->value.vecd, i);
                    // NAME + = + DOUBLE + , or \0
                    value_len += strlen(elem->name) + 1 + count_chars_in_double(elem->value, double_precision) + 1;
                }
                
                arg_value = (char*)malloc(value_len);
                memset(arg_value, 0, value_len);
                arg_value[index++] = '[';

                for (int i = 0; i < arg_len; i++) {
                    rsvp_vecd_elem_t* elem = rsvp_var_get_vecd_elem(arg->value.vecd, i);
                    size_t dbl_len = count_chars_in_double(elem->value, double_precision) ;
                    char* dbl_val = (char*)malloc(dbl_len + 1);
                    dbl_val = snprintf(dbl_val, dbl_len, dbl_format, elem->value);
                    strcat(arg_value, elem->name);
                    index += strlen(elem->name);
                    arg_value[index++] = '=';

                }


                ret = -1;
                break;

            case VECS:
                int index = 0;
                for (int i = 0; i < arg->len; i++) {
                    value_len += strlen(arg->value.vecs[i]) + 1;
                }

                arg_value = (char*)malloc(value_len);
                memset(arg_value, 0, value_len);

                for (int i = 0; i < arg->len; i++) {
                    char *str = arg->value.vecs[i];
                    strcat(arg_value, str);
                    index += strlen(str);
                    arg_value[index++] = '\t';
                }
                arg_value[index-1] = '\0';
                break;
        }

        if (ret < 0) {
            //Skip this arg
            continue;
        }

        str = (char*)realloc(str, len + strlen(arg_name) + strlen(arg_value));
        str = strcat(str, arg_name);
        str = strcat(str, arg_value);
        len = strlen(str) + 1;

        free(arg_value);
        free(arg_name);
    }

    return str;
}

void rsvp_var_print(rsvp_var_t *var)
{
    printf("Name: %s, type: %s, value: ", var->name, rsvp_type_str[var->type]);
@@ -526,7 +684,7 @@ rsvp_var_t* rsvp_var_create_bool(char *name, int value)

rsvp_var_t* rsvp_var_create_string(char *name, char* value)
{
    size_t len = strlen(name) + 1;
    size_t len = strlen(value) + 1;
    rsvp_var_t *var = rsvp_var_init(name);
    if (!var)
        return NULL;
+3 −2
Original line number Diff line number Diff line
@@ -110,12 +110,13 @@ extern int rsvp_data_add_var(rsvp_data_t* data, rsvp_var_t* var);
extern int rsvp_data_add_vars(rsvp_data_t* data, unsigned int count, ...);

/**
 * @brief Convert rsvp_data_t to a string of raw RSVP data
 * @brief Convert rsvp_data_t to a string of raw RSVP data. Remember to free the returned string
 * 
 * @param data Data to convert
 * @param double_precision Number of decimals for for double values
 * @return char* String of raw RSVP data
 */
extern char* rsvp_data_to_string(rsvp_data_t* data);
extern char* rsvp_data_to_string(rsvp_data_t* data, int double_precision);

/**
 * @brief Print the RSVP data struct to stdout
+8 −8
Original line number Diff line number Diff line
cmake_minimum_required(VERSION 3.20)

project(test)
project(tests)
set(C_TEST c_test)
set(CPP_TEST)

enable_testing()
add_executable(${C_TEST} rsvp_test.cpp)
target_link_libraries(${C_TEST} rsvp GTest::gtest_main)

add_executable(${PROJECT_NAME} rsvp_test.cpp ../src/rsvp.c)
target_link_libraries(${PROJECT_NAME} rsvp GTest::gtest_main)

add_executable(${PROJECT_NAME}pp testpp.cpp)
target_link_libraries(${PROJECT_NAME}pp rsvppp)
add_executable(${CPP_TEST}pp testpp.cpp)
target_link_libraries(${CPP_TEST}pp rsvppp)

include(GoogleTest)
gtest_discover_tests(${PROJECT_NAME})
 No newline at end of file
gtest_discover_tests(${C_TEST})
 No newline at end of file

tests/main.c

0 → 100644
+51 −0
Original line number Diff line number Diff line
#include <stdio.h>
#include <stdlib.h>

int count_char_in_int(int value)
{
    // Take into account the sign
    int chars = value < 0 ? 1 : 0;
    int modulo = 0;

    if (value == 0)
        return 1;
    
    value = abs(value);

    while (value > 0) {
        modulo = value % 10;

        if (modulo == 0)
            value /= 10;
        else
            value = (value - modulo) / 10;
        
        chars++;
    }

    return chars;
}

int count_chars_in_double(double value, int precision)
{  
    // Start at precision. Plus one to account for the dot
    int chars = precision + 1;
    int int_value = (int)value;

    // Account for negative 0
    if (value > -1.0 && value < 0.0)
        chars += 1;

    return count_char_in_int(int_value) + chars;
}

int main()
{
    int val = 11111111;
    double val1 = -1.87844189641134813;

    printf("Val: %d, chars: %d\n", val, count_char_in_int(val));
    printf("Val: %.5f, chars: %d\n", val1, count_chars_in_double(val1, 5));

    return 0;
}
 No newline at end of file
Loading