131 lines
4.0 KiB
C
131 lines
4.0 KiB
C
/*
|
|
*
|
|
* Copyright 2023 Oleg Borodin <borodin@unix7.org>
|
|
*
|
|
*/
|
|
|
|
#include <string.h>
|
|
#include <stdbool.h>
|
|
#include <stdio.h>
|
|
#include <strings.h>
|
|
|
|
#include <cllexer.h>
|
|
#include <clcomp.h>
|
|
#include <xdebug.h>
|
|
|
|
|
|
static char* strcopy(char* src) {
|
|
size_t srcsize = strlen(src) + 1;
|
|
char* dst = malloc(srcsize);
|
|
|
|
memset(dst, '\0', srcsize);
|
|
strcpy(dst, src);
|
|
return dst;
|
|
}
|
|
|
|
void clcomp_init(clcomp_t * comp, vmapper_t * vmapper, char** argv, int argc) {
|
|
comp->argv = argv;
|
|
comp->argc = argc;
|
|
comp->argn = 1;
|
|
comp->pos = 0;
|
|
comp->errstr = NULL;
|
|
comp->vmapper = vmapper;
|
|
if (comp->argc > comp->argn) {
|
|
cllexer_init(&(comp->lexer), comp->argv[comp->argn]);
|
|
}
|
|
}
|
|
|
|
char* clcomp_geterr(clcomp_t * comp) {
|
|
return comp->errstr;
|
|
}
|
|
|
|
#define SPACE_TOKEN "space"
|
|
|
|
int clcomp_gettok(clcomp_t * comp, char* token) {
|
|
if (comp->argn > comp->argc) {
|
|
strcpy(token, "EOF");
|
|
return TOKEN_ENDF;
|
|
}
|
|
|
|
int toktype = cllexer_gettok(&(comp->lexer), token);
|
|
|
|
if (toktype == TOKEN_ENDF && comp->argn != comp->argc) {
|
|
comp->argn++;
|
|
cllexer_init(&(comp->lexer), comp->argv[comp->argn]);
|
|
strcpy(token, SPACE_TOKEN);
|
|
return TOKEN_SPACE;
|
|
}
|
|
return toktype;
|
|
}
|
|
|
|
int clcomp_parse(clcomp_t * comp) {
|
|
char token[1024];
|
|
int toktype = TOKEN_NULL;
|
|
int i = 0;
|
|
|
|
char* key = NULL;
|
|
char* val = NULL;
|
|
|
|
while (toktype != TOKEN_ENDF) {
|
|
toktype = clcomp_gettok(comp, token);
|
|
i++;
|
|
DPRINTF("cllexer_parse res: %d: %d [%s]\n", i, toktype, token);
|
|
switch (comp->pos) {
|
|
case 0:{
|
|
if (toktype == TOKEN_PREF) {
|
|
comp->pos = 1;
|
|
DPRINTF("pos %d: TOKEN_PREF %s\n", comp->pos, token);
|
|
}
|
|
continue;
|
|
}
|
|
case 1:{
|
|
if (toktype == TOKEN_WORD) {
|
|
comp->pos = 2;
|
|
key = strcopy(token);
|
|
DPRINTF("pos %d: TOKEN_WORD %s\n", comp->pos, token);
|
|
continue;
|
|
} else {
|
|
comp->errstr = "Unknown key token";
|
|
goto error;
|
|
}
|
|
}
|
|
case 2:{
|
|
if (toktype == TOKEN_DELIM) {
|
|
comp->pos = 3;
|
|
DPRINTF("pos %d: TOKEN_DELIM %s\n", comp->pos, token);
|
|
continue;
|
|
} else {
|
|
comp->errstr = "Unknown delimeter token";
|
|
goto error;
|
|
}
|
|
}
|
|
case 3:{
|
|
if (toktype == TOKEN_WORD) {
|
|
comp->pos = 0;
|
|
printf("pos %d: TOKEN_WORD %s\n", comp->pos, token);
|
|
val = strcopy(token);
|
|
DPRINTF("keyval = [%s], [%s]\n", key, val);
|
|
vmapper_set(comp->vmapper, key, val);
|
|
free(key);
|
|
free(val);
|
|
continue;
|
|
} else {
|
|
comp->errstr = "Unknown key token";
|
|
goto error;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return 0;
|
|
|
|
error:
|
|
free(key);
|
|
free(val);
|
|
return -1;
|
|
}
|
|
|
|
|
|
void clcomp_destroy(clcomp_t * clcomp) {
|
|
(void)clcomp;
|
|
}
|