Commit 62507ee1 authored by Gallacchi Mattia's avatar Gallacchi Mattia
Browse files

First commit

parent b2682085
Loading
Loading
Loading
Loading

.gitignore

0 → 100644
+2 −0
Original line number Diff line number Diff line
build/
.vscode/
 No newline at end of file

CMakeLists.txt

0 → 100644
+8 −0
Original line number Diff line number Diff line
cmake_minimum_required(VERSION 3.20)

project(rsvp)

include_directories(src)
add_subdirectory(src)

add_subdirectory(tests)
 No newline at end of file

src/CMakeLists.txt

0 → 100644
+7 −0
Original line number Diff line number Diff line
cmake_minimum_required(VERSION 3.20)

project(rsvp)

file(GLOB SRC *.c)

add_library(${PROJECT_NAME} ${SRC})
 No newline at end of file

src/rsvp.c

0 → 100644
+259 −0
Original line number Diff line number Diff line
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "rsvp.h"

static char delimiter = 0x3B; // ;
static char delimiter_vecd = 0x2C; // ,

RSVP_TYPE get_type(char *type)
{
    RSVP_TYPE type_ = STR;

    for (int i = 0; i < TYPE_COUNT; i++) {
        int n = i > 2 ? 4 : 3;

        if (strncmp(type, rsvp_type_str[i], n) == 0) {
            type_ = (RSVP_TYPE)i;
        }
    }

    return type_;
}

void get_vecd_elem(char *token, rsvp_vecd_elem_t* elem)
{
    char *value = NULL, *begin = token;
    int index = 0;

    while ((*token != '\0') && (value == NULL)) {

        switch (*token) {
            case '=':
                value = ++token;
                break;
            default:
                index++;
                break;
        }
    }

    elem->name = (char*)malloc(index);
    memcpy(elem->name, begin, index);

    elem->value = strtod(value, NULL);
}

void *get_vecd(char *value, int *elems)
{
    char *begin = value, *token;
    int elems_count = 0;
    rsvp_vecd_elem_t *vecd = NULL;

    printf("VECD: %s\n", value);

    while (*value != '\0') {
        if (*value == '=')
            elems_count++;
        value++;
    }
    value = begin;

    printf("Vecd count: %d\n", elems_count);
    
    vecd = (rsvp_vecd_elem_t*)malloc(sizeof(rsvp_vecd_elem_t) * elems_count);
    token = strtok(value, &delimiter_vecd);
    for (int i = 0; i < elems_count; i++) {
        get_vecd_elem(token, vecd++);
        strtok(NULL, &delimiter_vecd);
    }

    *elems = elems_count;
    return vecd;
}

void process_args(char *arg, rsvp_var_t* var)
{
    char *begin = arg;
    char *value = NULL;
    int index = 0, type_start = 0;

    printf("ARG: %s\n", arg);

    // Search for the variable name
    while ((*arg != '\0') && (value == NULL))  {

        switch (*arg)
        {
        case '(':
            var->name = (char*)malloc(index + 1);
            memcpy(var->name, begin, index);
            var->name[index] = '\0';
            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);
            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';
            }
            value = ++arg;
            break;

        default:
            index++;
            break;
        }

        arg++;
    }
    
    printf("Value: %s\n", value);

    switch (var->type) {

        case INT:
        {
            int value_int;
            var->value = malloc(sizeof(int));
            value_int = strtol(value, NULL, 0);
            memcpy(var->value, &value_int, sizeof(int));
            break;
        }

        case DBL:
        {
            double value_dbl;
            var->value = malloc(sizeof(double));
            value_dbl = strtod(value, NULL);
            memcpy(var->value, &value_dbl, sizeof(double));
            break;
        }

        case BOOL:
        {
            int val = 0;
            var->value = malloc(1);
            if (strcmp(value, "TRUE") == 0) {
                val = 1;
            }
            memcpy(var->value, &val, 1);
            break;
        }

        case VECD:
            get_vecd(value, &var->len);
            break;  

        case VECS:

            break;

        default:
            var->value = (char*)malloc(strlen(value) + 1);
            memset(var->value, 0, strlen(value) + 1);
            memcpy(var->value, value, strlen(value));
            break;

    }

#ifdef DEBUG
    rsvp_var_print(var);
#endif

}

rsvp_data_t *rsvp_parse_data(char* data)
{
    char *token;
    rsvp_var_t *current_var;
    rsvp_data_t *rsvp_data = (rsvp_data_t*)malloc(sizeof(rsvp_data_t));
    memset(rsvp_data, 0, sizeof(rsvp_data_t));

    // Get command string
    token = strtok(data, &delimiter);
    rsvp_data->cmd = (char*)malloc(strlen(token) + 1);
    memcpy(rsvp_data->cmd, token, strlen(token) + 1);

    // Process args
    while (token != NULL) {
        token = strtok(NULL, &delimiter);
        if (!token) {
            // No more tokens
            break;
        }

#ifdef DEBUG
        printf("*** DBG *** token[%d]: %s\n", rsvp_data->args_count, token);
#endif
        rsvp_data->args_count++;
        current_var = (rsvp_var_t*)malloc(sizeof(rsvp_var_t));
        rsvp_data->args = (rsvp_var_t*)realloc(rsvp_data->args, rsvp_data->args_count * sizeof(rsvp_var_t));
        process_args(token, &rsvp_data->args[rsvp_data->args_count - 1]);
    }

#ifdef DEBUG
    rsvp_data_print(rsvp_data);
#endif

    return rsvp_data;
}

void rsvp_var_print(rsvp_var_t *var)
{
    printf("Name: %s, type: %s, value: ", var->name, rsvp_type_str[var->type]);

    switch (var->type)
    {
    case INT:
        printf("%d\n", *(int*)var->value);
        break;
    
    case DBL:
        printf("%f\n", *(double*)var->value);
        break;

    case BOOL:
        printf("%d\n", *(int*)var->value);
        break;

    default:
        printf("%s\n", (char*)var->value);
        break;
    }
}

void rsvp_data_print(rsvp_data_t *data)
{
    printf("Command: %s, args:\n", data->cmd);

    for(int i = 0; i < data->args_count; i++) {
        rsvp_var_print(&data->args[i]);
    }
}

void rsvp_data_free(rsvp_data_t *data)
{
    for (int i = 0; i < data->args_count; i++) {
        rsvp_var_free(&data->args[i]);
    }

    free(data->cmd);
}

void rsvp_var_free(rsvp_var_t *var) 
{
    free(var->name);
    free(var->value);
}
 No newline at end of file

src/rsvp.h

0 → 100644
+54 −0
Original line number Diff line number Diff line
#ifndef RSVP_H
#define RSVP_H

#define TYPE_COUNT  6

typedef enum  {
    STR = 0,
    INT,
    DBL,
    BOOL,
    VECD,
    VECS,
} RSVP_TYPE;

static char rsvp_type_str [TYPE_COUNT][5] = {
    "STR\0",
    "INT\0",
    "DBL\0",
    "BOOL",
    "VECD",
    "VECS"
};

struct rsvp_vecd_elem {
    char *name;
    double value;
};
typedef struct rsvp_vecd_elem rsvp_vecd_elem_t;

struct rsvp_var {
    char *name;
    int len;
    RSVP_TYPE type;
    void *value;
};
typedef struct rsvp_var rsvp_var_t;

struct rsvp_data {
    char *cmd;
    rsvp_var_t *args;
    unsigned int args_count;
};
typedef struct rsvp_data rsvp_data_t;

extern rsvp_data_t* rsvp_parse_data(char* data);

extern void rsvp_data_print(rsvp_data_t* data);
extern void rsvp_data_free(rsvp_data_t *data);

extern rsvp_var_t* rsvp_var_create(char *name, RSVP_TYPE type, void* value);
extern void rsvp_var_print(rsvp_var_t *var);
extern void rsvp_var_free(rsvp_var_t *var);

#endif //RSVP_H
 No newline at end of file
Loading