User Tools

Site Tools


,

Map of values

mapper.c
/*
 * Copyright 2023 Oleg Borodin  <borodin@unix7.org>
 */
 
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
 
 
static char* copystr(char* src) {
    size_t srcsize = strlen(src) + 1;
    char* dest = malloc(srcsize);
    memset(dest, '\0', srcsize);
    strcpy(dest, src);
    return dest;
}
 
typedef struct {
    char*   name;
    int     type;
    void*   vptr;
} mlink_t;
 
#define MAPPER_STRING   1
#define MAPPER_INTEGER  2
#define MAPPER_BOOL     3
 
mlink_t* new_mlink_string(char* name, char** val) {
    mlink_t* mlink = malloc(sizeof(mlink_t));
    mlink->name = name;
    mlink->vptr = (void*)val;
    mlink->type = MAPPER_STRING;
    return mlink;
}
 
mlink_t* new_mlink_integer(char* name, int* val) {
    mlink_t* mlink = malloc(sizeof(mlink_t));
    mlink->name = name;
    mlink->vptr = (void*)val;
    mlink->type = MAPPER_INTEGER;
    return mlink;
}
 
mlink_t* new_mlink_bool(char* name, bool* val) {
    mlink_t* mlink = malloc(sizeof(mlink_t));
    mlink->name = name;
    mlink->vptr = (void*)val;
    mlink->type = MAPPER_BOOL;
    return mlink;
}
 
 
typedef struct {
    mlink_t**   mlinks;
    size_t      size;
    size_t      capa;
    bool        err;
    char*       errstr;
} mapper_t;
 
#define MAPPER_INITCAPA 64
 
void mapper_init(mapper_t* mapper) {
    mapper->mlinks = malloc(sizeof(mlink_t) * MAPPER_INITCAPA);
    mapper->capa = MAPPER_INITCAPA;
    mapper->size = 0;
    mapper->err = false;
    mapper->errstr = NULL;
    return;
}
 
#define RES_BIND_OK   ((int)0)
#define RES_BIND_ERR  ((int)-1)
 
int mapper_check_capa(mapper_t* mapper) {
    if (mapper->size == mapper->capa) {
        size_t newcapa = mapper->capa * 2;
        mlink_t** newmlinks = realloc(mapper->mlinks, newcapa);
        if (newmlinks == NULL) return RES_BIND_ERR;
        mapper->mlinks = newmlinks;
        mapper->capa = newcapa;
    }
    return RES_BIND_OK;
}
 
int mapper_bind_string(mapper_t* mapper, char* name, char** val) {
    int res = 0;
    if ((res = mapper_check_capa(mapper)) != RES_BIND_OK) {
        return res;
    }
    mlink_t* mlink = new_mlink_string(name, val);
    mapper->mlinks[mapper->size] = mlink;
    mapper->size++;
    return RES_BIND_OK;
}
 
int mapper_bind_integer(mapper_t* mapper, char* name, int* val) {
    int res = 0;
    if ((res = mapper_check_capa(mapper)) != RES_BIND_OK) {
        return res;
    }
    mlink_t* mlink = new_mlink_integer(name, val);
    mapper->mlinks[mapper->size] = mlink;
    mapper->size++;
    return RES_BIND_OK;
}
 
 
int mapper_bind_bool(mapper_t* mapper, char* name, bool* val) {
    int res = 0;
    if ((res = mapper_check_capa(mapper)) != RES_BIND_OK) {
        return res;
    }
    mlink_t* mlink = new_mlink_bool(name, val);
    mapper->mlinks[mapper->size] = mlink;
    mapper->size++;
    return RES_BIND_OK;
}
 
int mapper_set_int(mapper_t* mapper, char* key, char* val) {
    for (size_t i = 0; i < mapper->size; i++) {
        mlink_t* mlink = mapper->mlinks[i];
        if (mlink->type == MAPPER_INTEGER && strcmp(mlink->name, key) == 0) {
            char* eptr = NULL;
            *(int*)(mlink->vptr) = (int)strtol(val, &eptr, 10);
        }
    }
    return 0;
}
 
int mapper_set_string(mapper_t* mapper, char* key, char* val) {
    for (size_t i = 0; i < mapper->size; i++) {
        mlink_t* mlink = mapper->mlinks[i];
        if (mlink->type == MAPPER_STRING && strcmp(mlink->name, key) == 0) {
            *(char**)(mlink->vptr) = copystr(val);
        }
    }
    return 0;
}
 
int mapper_set_bool(mapper_t* mapper, char* key, char* val) {
    for (size_t i = 0; i < mapper->size; i++) {
        mlink_t* mlink = mapper->mlinks[i];
        if (mlink->type == MAPPER_BOOL && strcmp(mlink->name, key) == 0) {
            if (strcmp(val, "true") == 0) {
                *(bool*)(mlink->vptr) = true;
            }
            if (strcmp(val, "false") == 0) {
                *(bool*)(mlink->vptr) = false;
            }
        }
    }
    return 0;
}
 
void mapper_destroy(mapper_t* mapper) {
    if (mapper != NULL) {
        for (size_t i = 0; i < mapper->size; i++) {
            free(mapper->mlinks[i]);
        }
        free(mapper->mlinks);
    }
    return;
}
 
int main(int argc, char **argv) {
 
    int   port   = 0;
    bool  flag   = false;
    char* ident  = NULL;
 
    mapper_t mapper;
    mapper_init(&mapper);
 
    mapper_bind_integer(&mapper, "port", &port);
    mapper_bind_string(&mapper, "ident", &ident);
    mapper_bind_bool(&mapper, "flag", &flag);
 
    mapper_set_int(&mapper, "port", "1234567");
    mapper_set_string(&mapper, "ident", "qwerty");
    mapper_set_bool(&mapper, "flag", "true");
 
    printf("port = %d\n", port);
    printf("ident = %s\n", ident);
    printf("flag = %d\n", flag);
 
    free(ident);
 
    mapper_destroy(&mapper);
 
    return 0;
}

Out

$ ./mapper
port = 1234567
ident = qwerty
flag = 1