Files
cworker/cfparser.c
2023-08-13 19:39:49 +02:00

153 lines
3.8 KiB
C

/*
* Copyright 2023 Oleg Borodin <borodin@unix7.org>
*/
#include <stdbool.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <cfparser.h>
#define INIT_BSIZE 64
static char* strcopy(char* src) {
size_t srcsize = strlen(src) + 1;
char* dst = malloc(srcsize);
memset(dst, '\0', srcsize);
strcpy(dst, src);
return dst;
}
static char* strconcat(char** str, int num) {
size_t tsize = 0;
size_t size[num];
for (int i = 0; i < num; i++) {
size[i] = 0;
if (str[i] != NULL) {
size[i] = strlen(str[i]);
tsize += size[i];
}
}
tsize++;
char* dst = malloc(tsize);
memset(dst, '\0', tsize);
int pos = 0;
for (int i = 0; i < num; i++) {
if (str[i] != NULL) {
strcpy(&dst[pos], str[i]);
pos += size[i];
}
}
return dst;
}
void cfparser_init(cfparser_t * parser, cflexer_t * lexer) {
parser->lexer = lexer;
parser->kvalarr = malloc(sizeof(cfkval_t) * INIT_BSIZE);
parser->kvalcapa = INIT_BSIZE;
parser->kvalsize = 0;
}
void cfparser_bind(cfparser_t * parser, int type, char* key, void* ref) {
for (int i = 0; i < parser->kvalsize; i++) {
if (strcmp(key, parser->kvalarr[i].key) == 0) {
switch (type) {
case CFVALTYPE_STR: {
*(char**)(ref) = strcopy(parser->kvalarr[i].val);
break;
}
case CFVALTYPE_INT: {
char* eptr = NULL;
*(int64_t*)(ref) = (int64_t)strtol(parser->kvalarr[i].val, &eptr, 10);
break;
}
}
}
}
}
#define MAX_TOKEN_SIZE 1024
int cfparser_parse(cfparser_t * parser) {
cflexer_t* lex = parser->lexer;
char token[MAX_TOKEN_SIZE];
int type = 0;
int pos = 0;
char* key;
char* val;
while ((type = cflexer_gettoken(lex, token)) != CFLEXTOK_END) {
switch (pos) {
// POS 0
case 0:{
if (type == CFLEXTOK_SPACE) continue;
if (type == CFLEXTOK_COMM) continue;
if (type == CFLEXTOK_NEXT) continue;
if (type == CFLEXTOK_WORD) {
key = strcopy(token);
pos++;
} else {
return -1;
}
break;
}
// POS 1
case 1:{
if (type == CFLEXTOK_SPACE) continue;
if (type == CFLEXTOK_SEPAR) {
pos++;
} else {
return -1;
}
break;
}
// POS 2
case 2:{
if (type == CFLEXTOK_SPACE) continue;
if (type == CFLEXTOK_WORD) {
char* val = strcopy(token);
if (parser->kvalsize >= parser->kvalcapa) {
// TODO
}
parser->kvalarr[parser->kvalsize].key = key;
parser->kvalarr[parser->kvalsize].val = val;
parser->kvalsize++;
pos++;
} else {
return -1;
}
break;
}
case 3:{
if (type == CFLEXTOK_SPACE) continue;
if (type == CFLEXTOK_COMM) continue;
if (type == CFLEXTOK_NEXT) {
pos = 0;
} else {
return -1;
}
break;
}
default:{
return -1;
}
}
}
return 0;
}
void cfparser_destroy(cfparser_t * parser) {
free(parser->kvalarr);
}