at work
This commit is contained in:
178
clib/cfparser.c
Normal file
178
clib/cfparser.c
Normal file
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* Copyright 2023 Oleg Borodin <borodin@unix7.org>
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include <cfparser.h>
|
||||
#include <logger.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;
|
||||
}
|
||||
|
||||
#if 0
|
||||
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;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
int 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) {
|
||||
char* key = parser->kvalarr[i].key;
|
||||
char* val = parser->kvalarr[i].val;
|
||||
switch (type) {
|
||||
case CFVALTYPE_STR: {
|
||||
*(char**)(ref) = strcopy(val);
|
||||
break;
|
||||
}
|
||||
case CFVALTYPE_INT: {
|
||||
for (size_t i = 0; i < strlen(val); i++) {
|
||||
if (isdigit(val[i]) == 0 && val[i] != '-' ) {
|
||||
log_error("wrong integer value: %s = %s", key, val);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
char* eptr = NULL;
|
||||
*(int64_t*)(ref) = (int64_t)strtol(val, &eptr, 10);
|
||||
break;
|
||||
}
|
||||
case CFVALTYPE_BOOL:{
|
||||
*(bool*)(ref) = false;
|
||||
if (strcmp(val, "true") == 0) {
|
||||
*(bool*)(ref) = true;
|
||||
} else if (strcmp(val, "false") == 0) {
|
||||
*(bool*)(ref) = false;
|
||||
} else {
|
||||
log_error("wrong boolean key value: %s = %s", key, val);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#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);
|
||||
}
|
||||
Reference in New Issue
Block a user