This commit is contained in:
Олег Бородин
2025-10-16 00:08:17 +02:00
parent 5dca71f775
commit fc578f6e48
26 changed files with 994 additions and 931 deletions
+71 -63
View File
@@ -14,106 +14,114 @@
#define STREAM_INITCAPA 128 #define STREAM_INITCAPA 128
bstream_t* bstream_init(bstream_t* stream) { bstream_t* bstream_init(bstream_t * stream) {
stream->data = malloc(STREAM_INITCAPA); stream->data = malloc(STREAM_INITCAPA);
stream->wpos = 0; stream->wpos = 0;
stream->rpos = 0; stream->rpos = 0;
stream->capa = STREAM_INITCAPA; stream->capa = STREAM_INITCAPA;
return stream; return stream;
} }
bstream_t* new_bstream() { bstream_t* new_bstream() {
bstream_t* stream = malloc(sizeof(bstream_t)); bstream_t* stream = malloc(sizeof(bstream_t));
if (stream == NULL) return NULL;
stream->data = malloc(STREAM_INITCAPA); if (stream == NULL)
stream->wpos = 0; return NULL;
stream->rpos = 0; stream->data = malloc(STREAM_INITCAPA);
stream->capa = STREAM_INITCAPA; stream->wpos = 0;
return stream; stream->rpos = 0;
stream->capa = STREAM_INITCAPA;
return stream;
} }
size_t bstream_dump(bstream_t * stream) { size_t bstream_dump(bstream_t * stream) {
for (size_t i = 0; i < stream->wpos; i++) { for (size_t i = 0; i < stream->wpos; i++) {
printf("%c", stream->data[i]); printf("%c", stream->data[i]);
} }
return stream->wpos; return stream->wpos;
} }
ssize_t bstream_write(bstream_t * stream, void* buf, size_t size) { ssize_t bstream_write(bstream_t * stream, void* buf, size_t size) {
if ((stream->wpos + size) > stream->capa) { if ((stream->wpos + size) > stream->capa) {
size_t newcapa = stream->capa * 2; size_t newcapa = stream->capa * 2;
stream->data = realloc(stream->data, (size_t)newcapa);
stream->capa = newcapa; stream->data = realloc(stream->data, (size_t)newcapa);
} stream->capa = newcapa;
if (buf != NULL) { }
memcpy(&(stream->data[stream->wpos]), buf, (size_t)size); if (buf != NULL) {
} memcpy(&(stream->data[stream->wpos]), buf, (size_t)size);
stream->wpos += size; }
return (ssize_t)size; stream->wpos += size;
return (ssize_t) size;
} }
ssize_t bstream_read(bstream_t * stream, void* buf, size_t size) { ssize_t bstream_read(bstream_t * stream, void* buf, size_t size) {
size_t unread = stream->wpos - stream->rpos; size_t unread = stream->wpos - stream->rpos;
if (size > unread) {
size = unread; if (size > unread) {
} size = unread;
if (buf != NULL) { }
memcpy(buf, &(stream->data[stream->rpos]), size); if (buf != NULL) {
} memcpy(buf, &(stream->data[stream->rpos]), size);
stream->rpos += size; }
return (ssize_t)size; stream->rpos += size;
return (ssize_t) size;
} }
#define RBUF_SIZE 64 #define RBUF_SIZE 64
ssize_t bstream_fread(bstream_t * stream, char* filename) { ssize_t bstream_fread(bstream_t * stream, char* filename) {
int fd = open(filename, O_RDONLY); int fd = open(filename, O_RDONLY);
if (fd < 0) return (ssize_t)-1;
char buf[RBUF_SIZE]; if (fd < 0)
size_t size = 0; return (ssize_t) - 1;
size_t rsize = 0;
while ((size = (size_t)read(fd, buf, RBUF_SIZE)) > 0) { char buf[RBUF_SIZE];
if ((stream->wpos + size) > stream->capa) { size_t size = 0;
size_t newcapa = stream->capa * 2; size_t rsize = 0;
stream->data = realloc(stream->data, (size_t)newcapa);
stream->capa = newcapa; while ((size = (size_t)read(fd, buf, RBUF_SIZE)) > 0) {
if ((stream->wpos + size) > stream->capa) {
size_t newcapa = stream->capa * 2;
stream->data = realloc(stream->data, (size_t)newcapa);
stream->capa = newcapa;
}
memcpy(&(stream->data[stream->wpos]), buf, (size_t)size);
stream->wpos += size;
rsize += size;
} }
memcpy(&(stream->data[stream->wpos]), buf, (size_t)size); close(fd);
stream->wpos += size; return (ssize_t) rsize;
rsize += size;
}
close(fd);
return (ssize_t)rsize;
} }
char bstream_getc(bstream_t * stream) { char bstream_getc(bstream_t * stream) {
size_t unread = stream->wpos - stream->rpos; size_t unread = stream->wpos - stream->rpos;
if (unread == 0) if (unread == 0)
return EOF; return EOF;
return (char)stream->data[stream->rpos++]; return (char)stream->data[stream->rpos++];
} }
size_t bstream_wpos(bstream_t * stream) { size_t bstream_wpos(bstream_t * stream) {
return stream->wpos; return stream->wpos;
} }
size_t bstream_rpos(bstream_t * stream) { size_t bstream_rpos(bstream_t * stream) {
return stream->rpos; return stream->rpos;
} }
void bstream_destroy(bstream_t * stream) { void bstream_destroy(bstream_t * stream) {
if (stream != NULL) if (stream != NULL)
free(stream->data); free(stream->data);
} }
void bstream_free(bstream_t * stream) { void bstream_free(bstream_t * stream) {
if (stream != NULL) if (stream != NULL)
free(stream->data); free(stream->data);
free(stream); free(stream);
} }
+4 -4
View File
@@ -11,10 +11,10 @@
#include <unistd.h> #include <unistd.h>
typedef struct { typedef struct {
size_t rpos; size_t rpos;
size_t wpos; size_t wpos;
size_t capa; size_t capa;
uint8_t* data; uint8_t* data;
} bstream_t; } bstream_t;
+29 -25
View File
@@ -10,38 +10,42 @@
#include <massert.h> #include <massert.h>
void test_rwrite(void) { void test_rwrite(void) {
bstream_t stream; bstream_t stream;
bstream_init(&stream);
char* data = "_123456789";
size_t dsize = strlen(data);
ssize_t wsize = 0;
size_t count = 3; bstream_init(&stream);
for (size_t i = 0; i < count; i++) { char* data = "_123456789";
wsize += bstream_write(&stream, data, dsize); size_t dsize = strlen(data);
} ssize_t wsize = 0;
printf("wsize = %ld, data = [%s]\n", wsize, stream.data);
MASSERT(stream.wpos == dsize * count); size_t count = 3;
MASSERT(wsize == (ssize_t)(dsize * count));
size_t bsize = bstream_wpos(&stream); for (size_t i = 0; i < count; i++) {
char* buf = malloc((size_t)bsize + (size_t)1); wsize += bstream_write(&stream, data, dsize);
memset(buf, 0, (size_t)bsize + (size_t)1); }
printf("wsize = %ld, data = [%s]\n", wsize, stream.data);
ssize_t rsize = bstream_read(&stream, buf, bsize); MASSERT(stream.wpos == dsize * count);
printf("rsize = %lu, buf = [%s]\n", rsize, buf); MASSERT(wsize == (ssize_t) (dsize * count));
MASSERT(wsize == (ssize_t)(dsize * count)); size_t bsize = bstream_wpos(&stream);
MASSERT(rsize == wsize); char* buf = malloc((size_t)bsize + (size_t)1);
bstream_destroy(&stream); memset(buf, 0, (size_t)bsize + (size_t)1);
ssize_t rsize = bstream_read(&stream, buf, bsize);
printf("rsize = %lu, buf = [%s]\n", rsize, buf);
MASSERT(wsize == (ssize_t) (dsize * count));
MASSERT(rsize == wsize);
bstream_destroy(&stream);
} }
int main(int argc, char **argv) { int main(int argc, char** argv) {
(void)argc; (void)argc;
(void)argv; (void)argv;
test_rwrite(); test_rwrite();
return 0; return 0;
} }
+77 -74
View File
@@ -13,14 +13,15 @@
#include <clcomp.h> #include <clcomp.h>
static char* strcopy(char* src) { static char* strcopy(char* src) {
size_t srcsize = strlen(src) + 1; size_t srcsize = strlen(src) + 1;
char* dst = malloc(srcsize); char* dst = malloc(srcsize);
memset(dst, '\0', srcsize);
strcpy(dst, src); memset(dst, '\0', srcsize);
return dst; strcpy(dst, src);
return dst;
} }
void clcomp_init(clcomp_t* comp, vmapper_t* vmapper, char** argv, int argc) { void clcomp_init(clcomp_t * comp, vmapper_t * vmapper, char** argv, int argc) {
comp->argv = argv; comp->argv = argv;
comp->argc = argc; comp->argc = argc;
comp->argn = 1; comp->argn = 1;
@@ -28,97 +29,99 @@ void clcomp_init(clcomp_t* comp, vmapper_t* vmapper, char** argv, int argc) {
comp->errstr = NULL; comp->errstr = NULL;
comp->vmapper = vmapper; comp->vmapper = vmapper;
if (comp->argc > comp->argn) { if (comp->argc > comp->argn) {
cllexer_init(&(comp->lexer), comp->argv[comp->argn]); cllexer_init(&(comp->lexer), comp->argv[comp->argn]);
} }
} }
char* clcomp_geterr(clcomp_t* comp) { char* clcomp_geterr(clcomp_t * comp) {
return comp->errstr; return comp->errstr;
} }
int clcomp_gettok(clcomp_t* comp, char* token) { int clcomp_gettok(clcomp_t * comp, char* token) {
if (comp->argn > comp->argc) { if (comp->argn > comp->argc) {
strcpy(token, "EOF"); strcpy(token, "EOF");
return TOKEN_ENDF; return TOKEN_ENDF;
} }
int toktype = cllexer_gettok(&(comp->lexer), token); int toktype = cllexer_gettok(&(comp->lexer), token);
if (toktype == TOKEN_ENDF && comp->argn != comp->argc) {
comp->argn++; if (toktype == TOKEN_ENDF && comp->argn != comp->argc) {
cllexer_init(&(comp->lexer), comp->argv[comp->argn]); comp->argn++;
strcpy(token, "space"); cllexer_init(&(comp->lexer), comp->argv[comp->argn]);
return TOKEN_SPACE; strcpy(token, "space");
} return TOKEN_SPACE;
return toktype; }
return toktype;
} }
int clcomp_parse(clcomp_t* comp) { int clcomp_parse(clcomp_t * comp) {
char token[1024]; char token[1024];
int toktype = TOKEN_NULL; int toktype = TOKEN_NULL;
int i = 0; int i = 0;
char* key = NULL; char* key = NULL;
char* val = NULL; char* val = NULL;
while (toktype != TOKEN_ENDF) {
toktype = clcomp_gettok(comp, token);
i++;
printf("cllexer_parse res: %d: %d [%s]\n", i, toktype, token);
switch (comp->pos) {
case 0: {
if (toktype == TOKEN_PREF) {
comp->pos = 1;
printf("pos %d: TOKEN_PREF %s\n", comp->pos, token);
}
continue;
}
case 1: {
if (toktype == TOKEN_WORD) {
comp->pos = 2;
key = strcopy(token);
printf("pos %d: TOKEN_WORD %s\n", comp->pos, token);
continue;
} else {
comp->errstr = "Unknown key token";
goto error;
}
}
case 2: {
if (toktype == TOKEN_DELIM || toktype == TOKEN_SPACE) {
comp->pos = 3;
printf("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);
printf("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;
}
}
} while (toktype != TOKEN_ENDF) {
toktype = clcomp_gettok(comp, token);
i++;
printf("cllexer_parse res: %d: %d [%s]\n", i, toktype, token);
switch (comp->pos) {
case 0:{
if (toktype == TOKEN_PREF) {
comp->pos = 1;
printf("pos %d: TOKEN_PREF %s\n", comp->pos, token);
}
continue;
}
case 1:{
if (toktype == TOKEN_WORD) {
comp->pos = 2;
key = strcopy(token);
printf("pos %d: TOKEN_WORD %s\n", comp->pos, token);
continue;
} else {
comp->errstr = "Unknown key token";
goto error;
}
}
case 2:{
if (toktype == TOKEN_DELIM || toktype == TOKEN_SPACE) {
comp->pos = 3;
printf("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);
printf("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; return 0;
error: error:
free(key); free(key);
free(val); free(val);
return -1; return -1;
} }
void clcomp_destroy(clcomp_t* clcomp) { void clcomp_destroy(clcomp_t * clcomp) {
(void)clcomp; (void)clcomp;
} }
+5 -5
View File
@@ -20,9 +20,9 @@ typedef struct {
char* errstr; char* errstr;
} clcomp_t; } clcomp_t;
void clcomp_init(clcomp_t* clcomp, vmapper_t* vmapper, char** argv, int argc); void clcomp_init(clcomp_t * clcomp, vmapper_t * vmapper, char** argv, int argc);
int clcomp_gettok(clcomp_t* clcomp, char* token); int clcomp_gettok(clcomp_t * clcomp, char* token);
int clcomp_parse(clcomp_t* clcomp); int clcomp_parse(clcomp_t * clcomp);
char* clcomp_geterr(clcomp_t* clcomp); char* clcomp_geterr(clcomp_t * clcomp);
void clcomp_destroy(clcomp_t* clcomp); void clcomp_destroy(clcomp_t * clcomp);
#endif #endif
+4 -2
View File
@@ -12,17 +12,19 @@
#include <clcomp.h> #include <clcomp.h>
#include <vmapper.h> #include <vmapper.h>
int main(int argc, char **argv) { int main(int argc, char** argv) {
(void)argc; (void)argc;
(void)argv; (void)argv;
char*_argv[] = { argv[0], "--qwerty=12345", "--foo=bar" }; char* _argv[] = { argv[0], "--qwerty=12345", "--foo=bar" };
int _argc = 2; int _argc = 2;
vmapper_t vmapper; vmapper_t vmapper;
vmapper_init(&vmapper); vmapper_init(&vmapper);
clcomp_t clcomp; clcomp_t clcomp;
clcomp_init(&clcomp, &vmapper, _argv, _argc); clcomp_init(&clcomp, &vmapper, _argv, _argc);
clcomp_parse(&clcomp); clcomp_parse(&clcomp);
+17 -16
View File
@@ -10,33 +10,34 @@
#include <vmapper.h> #include <vmapper.h>
#include <clconfig.h> #include <clconfig.h>
void clconfig_init(clconfig_t* clconfig, int argc, char **argv) { void clconfig_init(clconfig_t * clconfig, int argc, char** argv) {
clconfig->errstr = NULL; clconfig->errstr = NULL;
vmapper_init(&(clconfig->vmapper)); vmapper_init(&(clconfig->vmapper));
clcomp_init(&(clconfig->comp), &(clconfig->vmapper), argv, argc); clcomp_init(&(clconfig->comp), &(clconfig->vmapper), argv, argc);
} }
int clconfig_bind(clconfig_t* clconfig, int type, char* name, void* ptr) { int clconfig_bind(clconfig_t * clconfig, int type, char* name, void* ptr) {
vmapper_t* vmapper = &(clconfig->vmapper); vmapper_t* vmapper = &(clconfig->vmapper);
return vmapper_bind(vmapper, type, name, ptr);
return vmapper_bind(vmapper, type, name, ptr);
} }
int clconfig_parse(clconfig_t* clconfig) { int clconfig_parse(clconfig_t * clconfig) {
int res = clcomp_parse(&(clconfig->comp)); int res = clcomp_parse(&(clconfig->comp));
if (res < 0) { if (res < 0) {
if ((clconfig->errstr = clcomp_geterr(&(clconfig->comp))) == NULL) { if ((clconfig->errstr = clcomp_geterr(&(clconfig->comp))) == NULL) {
clconfig->errstr = "Undefined command line error"; clconfig->errstr = "Undefined command line error";
} }
} }
return res; return res;
} }
char* clconfig_geterr(clconfig_t* clconfig) { char* clconfig_geterr(clconfig_t * clconfig) {
return clconfig->errstr; return clconfig->errstr;
} }
void clconfig_destroy(clconfig_t* clconfig) { void clconfig_destroy(clconfig_t * clconfig) {
clcomp_destroy(&(clconfig->comp)); clcomp_destroy(&(clconfig->comp));
vmapper_destroy(&(clconfig->vmapper)); vmapper_destroy(&(clconfig->vmapper));
} }
+10 -10
View File
@@ -11,21 +11,21 @@
#include <vmapper.h> #include <vmapper.h>
typedef struct { typedef struct {
clcomp_t comp; clcomp_t comp;
vmapper_t vmapper; vmapper_t vmapper;
int argc; int argc;
char ** argv; char** argv;
char* errstr; char* errstr;
} clconfig_t; } clconfig_t;
#define GCONF_STR MAPPER_STR #define GCONF_STR MAPPER_STR
#define GCONF_INT MAPPER_INT #define GCONF_INT MAPPER_INT
#define GCONF_BOOL MAPPER_BOOL #define GCONF_BOOL MAPPER_BOOL
void clconfig_init(clconfig_t* clconfig, int argc, char **argv); void clconfig_init(clconfig_t * clconfig, int argc, char** argv);
int clconfig_bind(clconfig_t* clconfig, int type, char* name, void* ptr); int clconfig_bind(clconfig_t * clconfig, int type, char* name, void* ptr);
int clconfig_parse(clconfig_t* clconfig); int clconfig_parse(clconfig_t * clconfig);
char* clconfig_geterr(clconfig_t* clconfig); char* clconfig_geterr(clconfig_t * clconfig);
void clconfig_destroy(clconfig_t* clconfig); void clconfig_destroy(clconfig_t * clconfig);
#endif #endif
+22 -20
View File
@@ -9,33 +9,35 @@
#include <clconfig.h> #include <clconfig.h>
#include <massert.h> #include <massert.h>
int main(int argc, char **argv) { int main(int argc, char** argv) {
(void)argc; (void)argc;
(void)argv; (void)argv;
char*_argv[] = { argv[0], "--strkey=num5678", "--intkey=12345" }; char* _argv[] = { argv[0], "--strkey=num5678", "--intkey=12345" };
int _argc = 2; int _argc = 2;
clconfig_t clconfig; clconfig_t clconfig;
clconfig_init(&clconfig, _argc, _argv);
int intkey = 0; clconfig_init(&clconfig, _argc, _argv);
char* strkey = NULL;
clconfig_bind(&clconfig, GCONF_INT, "intkey", &intkey); int intkey = 0;
clconfig_bind(&clconfig, GCONF_STR, "strkey", &strkey); char* strkey = NULL;
int res = clconfig_parse(&clconfig); clconfig_bind(&clconfig, GCONF_INT, "intkey", &intkey);
if (res < 0) { clconfig_bind(&clconfig, GCONF_STR, "strkey", &strkey);
printf("error: %s\n", clconfig_geterr(&clconfig));
}
MASSERT(res == 0); int res = clconfig_parse(&clconfig);
clconfig_destroy(&clconfig); if (res < 0) {
printf("error: %s\n", clconfig_geterr(&clconfig));
}
printf("int key = %d\n", intkey); MASSERT(res == 0);
printf("str key = %s\n", strkey);
return 0; clconfig_destroy(&clconfig);
printf("int key = %d\n", intkey);
printf("str key = %s\n", strkey);
return 0;
} }
+109 -105
View File
@@ -22,19 +22,19 @@
#define LCONTEXT_UNDEF 7 #define LCONTEXT_UNDEF 7
static int get_ltype(char newletter) { static int get_ltype(char newletter) {
switch (newletter) { switch (newletter) {
case '-': case '-':
case '+': case '+':
return LTYPE_PREFIX; return LTYPE_PREFIX;
case '=': case '=':
return LTYPE_DELIM; return LTYPE_DELIM;
case EOF: case EOF:
return LTYPE_EOF; return LTYPE_EOF;
} }
return LTYPE_LETTER; return LTYPE_LETTER;
} }
void cllexer_init(cllexer_t* lexer, char* arg) { void cllexer_init(cllexer_t * lexer, char* arg) {
lexer->arg = arg; lexer->arg = arg;
lexer->rpos = 0; lexer->rpos = 0;
lexer->tpos = 0; lexer->tpos = 0;
@@ -42,125 +42,129 @@ void cllexer_init(cllexer_t* lexer, char* arg) {
lexer->newletter = '\0'; lexer->newletter = '\0';
} }
static void cllexer_getletter(cllexer_t* lexer, char* arg, int size) { static void cllexer_getletter(cllexer_t * lexer, char* arg, int size) {
lexer->newletter = EOF; lexer->newletter = EOF;
if (lexer->rpos < size) { if (lexer->rpos < size) {
lexer->newletter = arg[lexer->rpos++]; lexer->newletter = arg[lexer->rpos++];
} }
} }
int cllexer_gettok(cllexer_t* lexer, char* token) { int cllexer_gettok(cllexer_t * lexer, char* token) {
char* arg = lexer->arg; char* arg = lexer->arg;
size_t size = strlen(arg); size_t size = strlen(arg);
if (lexer->currcontext == LCONTEXT_START) { if (lexer->currcontext == LCONTEXT_START) {
lexer->newletter = arg[lexer->rpos++]; lexer->newletter = arg[lexer->rpos++];
int ltype = get_ltype(lexer->newletter); int ltype = get_ltype(lexer->newletter);
int newcontext = LCONTEXT_ENDFL; int newcontext = LCONTEXT_ENDFL;
switch (ltype) {
case LTYPE_PREFIX: {
newcontext = LCONTEXT_PREFIX;
break;
}
case LTYPE_DELIM: {
newcontext = LCONTEXT_DELIM;
break;
}
case LTYPE_LETTER: {
newcontext = LCONTEXT_WORD;
break;
}
case LTYPE_EOF: {
newcontext = LCONTEXT_ENDFL;
break;
}
}
lexer->currcontext = newcontext;
}
while (lexer->currcontext != LCONTEXT_ENDFL) {
int ltype = get_ltype(lexer->newletter);
switch (lexer->currcontext) {
case LCONTEXT_ENDFL: {
lexer->currcontext = LCONTEXT_ENDFL;
break;
}
case LCONTEXT_DELIM: {
int newcontext = lexer->currcontext;
switch (ltype) { switch (ltype) {
case LTYPE_PREFIX: case LTYPE_PREFIX:{
case LTYPE_LETTER: { newcontext = LCONTEXT_PREFIX;
newcontext = LCONTEXT_WORD;
break; break;
} }
case LTYPE_EOF: { case LTYPE_DELIM:{
newcontext = LCONTEXT_ENDFL;
break;
}
}
if (newcontext != lexer->currcontext) {
lexer->currcontext = newcontext;
token[lexer->tpos] = '\0';
lexer->tpos = 0;
return TOKEN_DELIM;
}
break;
}
case LCONTEXT_PREFIX: {
int newcontext = lexer->currcontext;
switch (ltype) {
case LTYPE_DELIM: {
newcontext = LCONTEXT_DELIM; newcontext = LCONTEXT_DELIM;
break; break;
} }
case LTYPE_LETTER: { case LTYPE_LETTER:{
newcontext = LCONTEXT_WORD; newcontext = LCONTEXT_WORD;
break; break;
} }
case LTYPE_EOF: { case LTYPE_EOF:{
newcontext = LCONTEXT_ENDFL; newcontext = LCONTEXT_ENDFL;
break; break;
} }
} }
if (newcontext != lexer->currcontext) { lexer->currcontext = newcontext;
lexer->currcontext = newcontext;
token[lexer->tpos++] = '\0';
lexer->tpos = 0;
return TOKEN_PREF;
}
break;
}
case LCONTEXT_WORD: {
int newcontext = lexer->currcontext;
switch (ltype) {
case LTYPE_DELIM: {
newcontext = LCONTEXT_DELIM;
break;
}
case LTYPE_EOF: {
newcontext = LCONTEXT_ENDFL;
break;
}
}
if (newcontext != lexer->currcontext) {
lexer->currcontext = newcontext;
token[lexer->tpos] = '\0';
lexer->tpos = 0;
return TOKEN_WORD;
}
break;
}
} }
token[lexer->tpos++] = lexer->newletter;
cllexer_getletter(lexer, arg, size);
}
lexer->currcontext = LCONTEXT_ENDFL; while (lexer->currcontext != LCONTEXT_ENDFL) {
lexer->tpos = 0;
token[lexer->tpos] = '\0'; int ltype = get_ltype(lexer->newletter);
strcpy(token, "EOF");
return TOKEN_ENDF; switch (lexer->currcontext) {
case LCONTEXT_ENDFL:{
lexer->currcontext = LCONTEXT_ENDFL;
break;
}
case LCONTEXT_DELIM:{
int newcontext = lexer->currcontext;
switch (ltype) {
case LTYPE_PREFIX:
case LTYPE_LETTER:{
newcontext = LCONTEXT_WORD;
break;
}
case LTYPE_EOF:{
newcontext = LCONTEXT_ENDFL;
break;
}
}
if (newcontext != lexer->currcontext) {
lexer->currcontext = newcontext;
token[lexer->tpos] = '\0';
lexer->tpos = 0;
return TOKEN_DELIM;
}
break;
}
case LCONTEXT_PREFIX:{
int newcontext = lexer->currcontext;
switch (ltype) {
case LTYPE_DELIM:{
newcontext = LCONTEXT_DELIM;
break;
}
case LTYPE_LETTER:{
newcontext = LCONTEXT_WORD;
break;
}
case LTYPE_EOF:{
newcontext = LCONTEXT_ENDFL;
break;
}
}
if (newcontext != lexer->currcontext) {
lexer->currcontext = newcontext;
token[lexer->tpos++] = '\0';
lexer->tpos = 0;
return TOKEN_PREF;
}
break;
}
case LCONTEXT_WORD:{
int newcontext = lexer->currcontext;
switch (ltype) {
case LTYPE_DELIM:{
newcontext = LCONTEXT_DELIM;
break;
}
case LTYPE_EOF:{
newcontext = LCONTEXT_ENDFL;
break;
}
}
if (newcontext != lexer->currcontext) {
lexer->currcontext = newcontext;
token[lexer->tpos] = '\0';
lexer->tpos = 0;
return TOKEN_WORD;
}
break;
}
}
token[lexer->tpos++] = lexer->newletter;
cllexer_getletter(lexer, arg, size);
}
lexer->currcontext = LCONTEXT_ENDFL;
lexer->tpos = 0;
token[lexer->tpos] = '\0';
strcpy(token, "EOF");
return TOKEN_ENDF;
} }
+8 -8
View File
@@ -16,15 +16,15 @@
typedef struct { typedef struct {
char* arg; char* arg;
int currcontext; int currcontext;
int argn; int argn;
int rpos; int rpos;
int tpos; int tpos;
char newletter; char newletter;
} cllexer_t; } cllexer_t;
void cllexer_init(cllexer_t* lexer, char* arg); void cllexer_init(cllexer_t * lexer, char* arg);
int cllexer_gettok(cllexer_t* lexer, char* token); int cllexer_gettok(cllexer_t * lexer, char* token);
#endif #endif
+6 -4
View File
@@ -10,22 +10,24 @@
#include <cllexer.h> #include <cllexer.h>
int main(int argc, char **argv) { int main(int argc, char** argv) {
(void)argc; (void)argc;
(void)argv; (void)argv;
char* arg = "--qwerty=-num-12345"; char* arg = "--qwerty=-num-12345";
cllexer_t lex; cllexer_t lex;
cllexer_init(&lex, arg); cllexer_init(&lex, arg);
char token[1024]; char token[1024];
int toktype = TOKEN_NULL; int toktype = TOKEN_NULL;
int i = 0; int i = 0;
while (toktype != TOKEN_ENDF) { while (toktype != TOKEN_ENDF) {
toktype = cllexer_gettok(&lex, token); toktype = cllexer_gettok(&lex, token);
printf("cllexer_gettok res: %d: %d [%s]\n", i, toktype, token); printf("cllexer_gettok res: %d: %d [%s]\n", i, toktype, token);
i++; i++;
} }
return 0; return 0;
+3 -3
View File
@@ -8,7 +8,7 @@
#include <massert.h> #include <massert.h>
void x__assert (char* path, int line, const char* func) { void x__assert(char* path, int line, const char* func) {
printf("%s:%d: assert error in %s\n", path, line, func); printf("%s:%d: assert error in %s\n", path, line, func);
exit(1); exit(1);
} }
+1 -1
View File
@@ -12,5 +12,5 @@
#define MASSERT(expr) if (!(expr)) \ #define MASSERT(expr) if (!(expr)) \
{ x__assert(__FILE__, __LINE__, (const char*)__func__); } { x__assert(__FILE__, __LINE__, (const char*)__func__); }
void x__assert (char* path, int line, const char* func); void x__assert(char* path, int line, const char* func);
#endif #endif
+83 -79
View File
@@ -25,101 +25,105 @@
#define POS4TYPE TOKEN_COMM #define POS4TYPE TOKEN_COMM
static char* strcopy(char* src) { static char* strcopy(char* src) {
size_t srcsize = strlen(src) + 1; size_t srcsize = strlen(src) + 1;
char* dst = malloc(srcsize); char* dst = malloc(srcsize);
memset(dst, '\0', srcsize);
strcpy(dst, src); memset(dst, '\0', srcsize);
return dst; strcpy(dst, src);
return dst;
} }
tccomp_t * new_tccomp(tclexer_t * lexer, vmapper_t* vmapper) { tccomp_t* new_tccomp(tclexer_t * lexer, vmapper_t * vmapper) {
tccomp_t *comp = malloc(sizeof(tccomp_t)); tccomp_t* comp = malloc(sizeof(tccomp_t));
if (comp == NULL) return NULL;
comp->lexer = lexer; if (comp == NULL)
comp->vmapper = vmapper; return NULL;
comp->pos = 0; comp->lexer = lexer;
comp->lnum = 0; comp->vmapper = vmapper;
return comp; comp->pos = 0;
comp->lnum = 0;
return comp;
} }
void tccomp_init(tccomp_t * comp, tclexer_t * lexer, vmapper_t* vmapper) { void tccomp_init(tccomp_t * comp, tclexer_t * lexer, vmapper_t * vmapper) {
comp->lexer = lexer; comp->lexer = lexer;
comp->vmapper = vmapper; comp->vmapper = vmapper;
comp->pos = 0; comp->pos = 0;
comp->lnum = 0; comp->lnum = 0;
} }
int tccomp_parse(tccomp_t * comp) { int tccomp_parse(tccomp_t * comp) {
char token[MAX_TOK_SIZE]; char token[MAX_TOK_SIZE];
int toktype = -1; int toktype = -1;
tclexer_t* lexer = comp->lexer; tclexer_t* lexer = comp->lexer;
char* key = NULL; char* key = NULL;
char* val = NULL; char* val = NULL;
while (true) { while (true) {
toktype = tclexer_get_token(lexer, token, MAX_TOK_SIZE); toktype = tclexer_get_token(lexer, token, MAX_TOK_SIZE);
if (toktype == TOKEN_SPACE) { if (toktype == TOKEN_SPACE) {
continue; continue;
} }
if (toktype == TOKEN_COMM) { if (toktype == TOKEN_COMM) {
continue; continue;
} }
//printf("tok=%d pos=%d line=%d [%s]\n", toktype, comp->pos, comp->lnum, token); //printf("tok=%d pos=%d line=%d [%s]\n", toktype, comp->pos, comp->lnum, token);
if (toktype == TOKEN_NEWLN) {
comp->lnum++;
}
switch (comp->pos) {
case 0: {
if (toktype == TOKEN_NEWLN) { if (toktype == TOKEN_NEWLN) {
comp->pos = 0; comp->lnum++;
break;
} }
if (toktype != TOKEN_WORD) {
return -1; switch (comp->pos) {
case 0:{
if (toktype == TOKEN_NEWLN) {
comp->pos = 0;
break;
}
if (toktype != TOKEN_WORD) {
return -1;
}
comp->pos++;
key = strcopy(token);
break;
}
case 1:{
if (toktype != TOKEN_OPER) {
return -1;
}
comp->pos++;
break;
}
case 2:{
if (toktype != TOKEN_WORD) {
return -1;
}
comp->pos++;
val = strcopy(token);
break;
}
case 3:{
if (toktype != TOKEN_NEWLN && toktype != TOKEN_ENDFL) {
return -1;
}
comp->pos = 0;
//printf("keyval = [%s], [%s]\n", key, val);
vmapper_set(comp->vmapper, key, val);
free(key);
free(val);
break;
}
} }
comp->pos++; if (toktype == TOKEN_ENDFL)
key = strcopy(token); break;
break;
}
case 1: {
if (toktype != TOKEN_OPER) {
return -1;
}
comp->pos++;
break;
}
case 2: {
if (toktype != TOKEN_WORD) {
return -1;
}
comp->pos++;
val = strcopy(token);
break;
}
case 3: {
if (toktype != TOKEN_NEWLN && toktype != TOKEN_ENDFL) {
return -1;
}
comp->pos = 0;
//printf("keyval = [%s], [%s]\n", key, val);
vmapper_set(comp->vmapper, key, val);
free(key);
free(val);
break;
}
} }
if (toktype == TOKEN_ENDFL) break; return 0;
}
return 0;
} }
void tccomp_destroy(tccomp_t* comp) { void tccomp_destroy(tccomp_t * comp) {
(void)comp; (void)comp;
} }
void tccomp_free(tccomp_t* comp) { void tccomp_free(tccomp_t * comp) {
free(comp); free(comp);
} }
+9 -9
View File
@@ -9,16 +9,16 @@
#include <vmapper.h> #include <vmapper.h>
typedef struct { typedef struct {
tclexer_t* lexer; tclexer_t* lexer;
vmapper_t* vmapper; vmapper_t* vmapper;
int pos; int pos;
int lnum; int lnum;
} tccomp_t; } tccomp_t;
tccomp_t * new_tccomp(tclexer_t * lexer, vmapper_t* vmapper); tccomp_t* new_tccomp(tclexer_t * lexer, vmapper_t * vmapper);
void tccomp_init(tccomp_t* comp, tclexer_t* lexer, vmapper_t* vmapper); void tccomp_init(tccomp_t * comp, tclexer_t * lexer, vmapper_t * vmapper);
int tccomp_parse(tccomp_t* comp); int tccomp_parse(tccomp_t * comp);
void tccomp_destroy(tccomp_t* comp); void tccomp_destroy(tccomp_t * comp);
void tccomp_free(tccomp_t* comp); void tccomp_free(tccomp_t * comp);
#endif #endif
+38 -35
View File
@@ -18,55 +18,58 @@
int main(void) { int main(void) {
char* src = "key1 = var1 # comment 1\nkey2 = var2 # comment 2 and 3\n# comment 4\nkey3 = var3"; char* src = "key1 = var1 # comment 1\nkey2 = var2 # comment 2 and 3\n# comment 4\nkey3 = var3";
bstream_t stream; bstream_t stream;
bstream_init(&stream); bstream_init(&stream);
tclexer_t lexer; tclexer_t lexer;
tclexer_init(&lexer, &stream);
vmapper_t vmapper; tclexer_init(&lexer, &stream);
vmapper_init(&vmapper);
tccomp_t comp; vmapper_t vmapper;
tccomp_init(&comp, &lexer, &vmapper);
bstream_write(&stream, src, strlen(src)); vmapper_init(&vmapper);
int port = 0; tccomp_t comp;
bool flag = false;
char* ident = NULL;
vmapper_bind_int(&vmapper, "port", &port); tccomp_init(&comp, &lexer, &vmapper);
vmapper_bind_string(&vmapper, "ident", &ident);
vmapper_bind_bool(&vmapper, "flag", &flag);
vmapper_set(&vmapper, "port", "12345"); bstream_write(&stream, src, strlen(src));
vmapper_set(&vmapper, "ident", "qwerty");
vmapper_set(&vmapper, "flag", "true");
int res = tccomp_parse(&comp); int port = 0;
bool flag = false;
char* ident = NULL;
if (res < 0) { vmapper_bind_int(&vmapper, "port", &port);
printf("parsing error pos %d line %d\n", comp.pos, comp.lnum); vmapper_bind_string(&vmapper, "ident", &ident);
} vmapper_bind_bool(&vmapper, "flag", &flag);
printf("port = %d\n", port); vmapper_set(&vmapper, "port", "12345");
MASSERT(port == 12345); vmapper_set(&vmapper, "ident", "qwerty");
vmapper_set(&vmapper, "flag", "true");
printf("ident = %s\n", ident); int res = tccomp_parse(&comp);
MASSERT(strcmp(ident, "qwerty") == 0);
free(ident);
printf("flag = %d\n", flag); if (res < 0) {
MASSERT(flag == true); printf("parsing error pos %d line %d\n", comp.pos, comp.lnum);
}
tccomp_destroy(&comp); printf("port = %d\n", port);
tclexer_destroy(&lexer); MASSERT(port == 12345);
vmapper_destroy(&vmapper);
bstream_destroy(&stream);
return 0; printf("ident = %s\n", ident);
MASSERT(strcmp(ident, "qwerty") == 0);
free(ident);
printf("flag = %d\n", flag);
MASSERT(flag == true);
tccomp_destroy(&comp);
tclexer_destroy(&lexer);
vmapper_destroy(&vmapper);
bstream_destroy(&stream);
return 0;
} }
+225 -222
View File
@@ -29,248 +29,251 @@
static int get_ltype(char letter) { static int get_ltype(char letter) {
switch (letter) { switch (letter) {
case '\n': case '\n':
return LTYPE_NEWLN; return LTYPE_NEWLN;
case ' ': case ' ':
return LTYPE_SPACE; return LTYPE_SPACE;
case '#': case '#':
case ';': case ';':
return LTYPE_COMMB; return LTYPE_COMMB;
case '=': case '=':
return LTYPE_OPER; return LTYPE_OPER;
case EOF: case EOF:
return LTYPE_ENDFL; return LTYPE_ENDFL;
} }
return LTYPE_LETTER; return LTYPE_LETTER;
} }
tclexer_t* new_tclexer(bstream_t * stream) { tclexer_t* new_tclexer(bstream_t * stream) {
tclexer_t* lexer = malloc(sizeof(tclexer_t)); tclexer_t* lexer = malloc(sizeof(tclexer_t));
if (lexer == NULL) return NULL;
lexer->stream = stream; if (lexer == NULL)
lexer->context = LEXCONT_UNDEF; return NULL;
return lexer; lexer->stream = stream;
lexer->context = LEXCONT_UNDEF;
return lexer;
} }
void tclexer_init(tclexer_t * lexer, bstream_t * stream) { void tclexer_init(tclexer_t * lexer, bstream_t * stream) {
lexer->stream = stream; lexer->stream = stream;
lexer->context = LEXCONT_UNDEF; lexer->context = LEXCONT_UNDEF;
lexer->pos = 0; lexer->pos = 0;
} }
int tclexer_get_token(tclexer_t * lexer, char* token, int maxsize) { int tclexer_get_token(tclexer_t * lexer, char* token, int maxsize) {
lexer->pos = 0; lexer->pos = 0;
if (lexer->pos > (maxsize - 1)) { if (lexer->pos > (maxsize - 1)) {
return -2; return -2;
}
if (lexer->context == LEXCONT_UNDEF) {
lexer->letter = bstream_getc(lexer->stream);
}
while (true) {
int ltype = get_ltype(lexer->letter);
switch (lexer->context) {
case LEXCONT_ENDFL:{
return TOKEN_ENDFL;
}
case LEXCONT_WORD:{
int newcontext = LEXCONT_WORD;
switch (ltype) {
case LTYPE_SPACE:{
newcontext = LEXCONT_SPACE;
break;
}
case LTYPE_NEWLN:{
newcontext = LEXCONT_NEWLN;
break;
}
case LTYPE_COMMB:{
newcontext = LEXCONT_COMM;
break;
}
case LTYPE_OPER:{
newcontext = LEXCONT_OPER;
break;
}
case LTYPE_ENDFL:{
newcontext = LEXCONT_ENDFL;
break;
}
}
if (newcontext != lexer->context) {
lexer->context = newcontext;
token[lexer->pos++] = '\0';
return TOKEN_WORD;
}
token[lexer->pos++] = lexer->letter;
break;
}
case LEXCONT_COMM:{
int newcontext = LEXCONT_COMM;
switch (ltype) {
case LTYPE_NEWLN:{
newcontext = LEXCONT_NEWLN;
break;
}
case LTYPE_ENDFL:{
newcontext = LEXCONT_ENDFL;
break;
}
}
if (newcontext != lexer->context) {
token[lexer->pos++] = '\0';
lexer->context = newcontext;
return TOKEN_COMM;
}
token[lexer->pos++] = lexer->letter;
break;
}
case LEXCONT_SPACE:{
int newcontext = LEXCONT_SPACE;
switch (ltype) {
case LTYPE_OPER:{
newcontext = LEXCONT_OPER;
break;
}
case LTYPE_COMMB:{
newcontext = LEXCONT_COMM;
break;
}
case LTYPE_LETTER:{
newcontext = LEXCONT_WORD;
break;
}
case LTYPE_NEWLN:{
newcontext = LEXCONT_NEWLN;
break;
}
case LTYPE_ENDFL:{
newcontext = LEXCONT_ENDFL;
break;
}
}
if (newcontext != lexer->context) {
lexer->context = newcontext;
strcpy(token, "SPACE");
return TOKEN_SPACE;
}
token[lexer->pos++] = lexer->letter;
break;
}
case LEXCONT_OPER:{
int newcontext = LEXCONT_OPER;
switch (ltype) {
case LTYPE_SPACE:{
newcontext = LEXCONT_SPACE;
break;
}
case LTYPE_NEWLN:{
newcontext = LEXCONT_NEWLN;
break;
}
case LTYPE_COMMB:{
newcontext = LEXCONT_COMM;
break;
}
case LTYPE_LETTER:{
newcontext = LEXCONT_WORD;
break;
}
case LTYPE_ENDFL:{
newcontext = LEXCONT_ENDFL;
break;
}
}
if (newcontext != lexer->context) {
lexer->context = newcontext;
strcpy(token, "=");
return TOKEN_OPER;
}
token[lexer->pos++] = lexer->letter;
break;
}
case LEXCONT_NEWLN:{
int newcontext = LEXCONT_NEWLN;
switch (ltype) {
case LTYPE_SPACE:{
newcontext = LEXCONT_SPACE;
break;
}
case LTYPE_COMMB:{
newcontext = LEXCONT_COMM;
break;
}
case LTYPE_LETTER:{
newcontext = LEXCONT_WORD;
break;
}
case LTYPE_ENDFL:{
newcontext = LEXCONT_ENDFL;
break;
}
}
if (newcontext != lexer->context) {
lexer->context = newcontext;
strcpy(token, "NL");
return TOKEN_NEWLN;
}
token[lexer->pos++] = lexer->letter;
break;
}
case LEXCONT_UNDEF:
default:{
int newcontext = LEXCONT_UNDEF;
switch (ltype) {
case LTYPE_SPACE:{
newcontext = LEXCONT_SPACE;
break;
}
case LTYPE_NEWLN:{
newcontext = LEXCONT_NEWLN;
break;
}
case LTYPE_COMMB:{
newcontext = LEXCONT_COMM;
break;
}
case LTYPE_LETTER:{
newcontext = LEXCONT_WORD;
break;
}
case LTYPE_OPER:{
newcontext = LEXCONT_OPER;
break;
}
case LTYPE_ENDFL:{
newcontext = LEXCONT_ENDFL;
break;
}
}
lexer->context = newcontext;
token[lexer->pos++] = lexer->letter;
break;
}
} }
lexer->letter = bstream_getc(lexer->stream);
} if (lexer->context == LEXCONT_UNDEF) {
return TOKEN_ENDFL; lexer->letter = bstream_getc(lexer->stream);
}
while (true) {
int ltype = get_ltype(lexer->letter);
switch (lexer->context) {
case LEXCONT_ENDFL:{
return TOKEN_ENDFL;
}
case LEXCONT_WORD:{
int newcontext = LEXCONT_WORD;
switch (ltype) {
case LTYPE_SPACE:{
newcontext = LEXCONT_SPACE;
break;
}
case LTYPE_NEWLN:{
newcontext = LEXCONT_NEWLN;
break;
}
case LTYPE_COMMB:{
newcontext = LEXCONT_COMM;
break;
}
case LTYPE_OPER:{
newcontext = LEXCONT_OPER;
break;
}
case LTYPE_ENDFL:{
newcontext = LEXCONT_ENDFL;
break;
}
}
if (newcontext != lexer->context) {
lexer->context = newcontext;
token[lexer->pos++] = '\0';
return TOKEN_WORD;
}
token[lexer->pos++] = lexer->letter;
break;
}
case LEXCONT_COMM:{
int newcontext = LEXCONT_COMM;
switch (ltype) {
case LTYPE_NEWLN:{
newcontext = LEXCONT_NEWLN;
break;
}
case LTYPE_ENDFL:{
newcontext = LEXCONT_ENDFL;
break;
}
}
if (newcontext != lexer->context) {
token[lexer->pos++] = '\0';
lexer->context = newcontext;
return TOKEN_COMM;
}
token[lexer->pos++] = lexer->letter;
break;
}
case LEXCONT_SPACE:{
int newcontext = LEXCONT_SPACE;
switch (ltype) {
case LTYPE_OPER:{
newcontext = LEXCONT_OPER;
break;
}
case LTYPE_COMMB:{
newcontext = LEXCONT_COMM;
break;
}
case LTYPE_LETTER:{
newcontext = LEXCONT_WORD;
break;
}
case LTYPE_NEWLN:{
newcontext = LEXCONT_NEWLN;
break;
}
case LTYPE_ENDFL:{
newcontext = LEXCONT_ENDFL;
break;
}
}
if (newcontext != lexer->context) {
lexer->context = newcontext;
strcpy(token, "SPACE");
return TOKEN_SPACE;
}
token[lexer->pos++] = lexer->letter;
break;
}
case LEXCONT_OPER:{
int newcontext = LEXCONT_OPER;
switch (ltype) {
case LTYPE_SPACE:{
newcontext = LEXCONT_SPACE;
break;
}
case LTYPE_NEWLN:{
newcontext = LEXCONT_NEWLN;
break;
}
case LTYPE_COMMB:{
newcontext = LEXCONT_COMM;
break;
}
case LTYPE_LETTER:{
newcontext = LEXCONT_WORD;
break;
}
case LTYPE_ENDFL:{
newcontext = LEXCONT_ENDFL;
break;
}
}
if (newcontext != lexer->context) {
lexer->context = newcontext;
strcpy(token, "=");
return TOKEN_OPER;
}
token[lexer->pos++] = lexer->letter;
break;
}
case LEXCONT_NEWLN:{
int newcontext = LEXCONT_NEWLN;
switch (ltype) {
case LTYPE_SPACE:{
newcontext = LEXCONT_SPACE;
break;
}
case LTYPE_COMMB:{
newcontext = LEXCONT_COMM;
break;
}
case LTYPE_LETTER:{
newcontext = LEXCONT_WORD;
break;
}
case LTYPE_ENDFL:{
newcontext = LEXCONT_ENDFL;
break;
}
}
if (newcontext != lexer->context) {
lexer->context = newcontext;
strcpy(token, "NL");
return TOKEN_NEWLN;
}
token[lexer->pos++] = lexer->letter;
break;
}
case LEXCONT_UNDEF:
default:{
int newcontext = LEXCONT_UNDEF;
switch (ltype) {
case LTYPE_SPACE:{
newcontext = LEXCONT_SPACE;
break;
}
case LTYPE_NEWLN:{
newcontext = LEXCONT_NEWLN;
break;
}
case LTYPE_COMMB:{
newcontext = LEXCONT_COMM;
break;
}
case LTYPE_LETTER:{
newcontext = LEXCONT_WORD;
break;
}
case LTYPE_OPER:{
newcontext = LEXCONT_OPER;
break;
}
case LTYPE_ENDFL:{
newcontext = LEXCONT_ENDFL;
break;
}
}
lexer->context = newcontext;
token[lexer->pos++] = lexer->letter;
break;
}
}
lexer->letter = bstream_getc(lexer->stream);
}
return TOKEN_ENDFL;
} }
void tclexer_destroy(tclexer_t* lexer) { void tclexer_destroy(tclexer_t * lexer) {
(void)lexer; (void)lexer;
} }
void tclexer_free(tclexer_t* lexer) { void tclexer_free(tclexer_t * lexer) {
free(lexer); free(lexer);
} }
+6 -6
View File
@@ -8,10 +8,10 @@
#include <bstream.h> #include <bstream.h>
typedef struct { typedef struct {
bstream_t* stream; bstream_t* stream;
int context; int context;
char letter; char letter;
int pos; int pos;
} tclexer_t; } tclexer_t;
#define MAX_TOK_SIZE 1024 #define MAX_TOK_SIZE 1024
@@ -27,6 +27,6 @@ typedef struct {
tclexer_t* new_tclexer(bstream_t * stream); tclexer_t* new_tclexer(bstream_t * stream);
void tclexer_init(tclexer_t * tclexer, bstream_t * stream); void tclexer_init(tclexer_t * tclexer, bstream_t * stream);
int tclexer_get_token(tclexer_t * tclexer, char* token, int maxsize); int tclexer_get_token(tclexer_t * tclexer, char* token, int maxsize);
void tclexer_destroy(tclexer_t* lexer); void tclexer_destroy(tclexer_t * lexer);
void tclexer_free(tclexer_t* lexer); void tclexer_free(tclexer_t * lexer);
#endif #endif
+17 -14
View File
@@ -14,24 +14,27 @@
int main(void) { int main(void) {
char* src = " key1 = var1 # comment 1\nkey2 = var2 # comment 2 and 3\n# comment 4\nkey3 = var3"; char* src = " key1 = var1 # comment 1\nkey2 = var2 # comment 2 and 3\n# comment 4\nkey3 = var3";
bstream_t stream; bstream_t stream;
bstream_init(&stream);
bstream_write(&stream, src, strlen(src)); bstream_init(&stream);
bstream_write(&stream, src, strlen(src));
tclexer_t lexer; tclexer_t lexer;
tclexer_init(&lexer, &stream);
int token_typ = TOKEN_NULL; tclexer_init(&lexer, &stream);
char token[MAX_TOK_SIZE];
while ((token_typ = tclexer_get_token(&lexer, token, MAX_TOK_SIZE)) != TOKEN_ENDFL) {
printf("%d:[%s]\n", token_typ, token);
}
tclexer_destroy(&lexer); int token_typ = TOKEN_NULL;
bstream_destroy(&stream); char token[MAX_TOK_SIZE];
return 0; while ((token_typ = tclexer_get_token(&lexer, token, MAX_TOK_SIZE)) != TOKEN_ENDFL) {
printf("%d:[%s]\n", token_typ, token);
}
tclexer_destroy(&lexer);
bstream_destroy(&stream);
return 0;
} }
+20 -18
View File
@@ -11,31 +11,33 @@
#include <vmapper.h> #include <vmapper.h>
#include <tconfig.h> #include <tconfig.h>
void tconfig_init(tconfig_t* tconfig) { void tconfig_init(tconfig_t * tconfig) {
bstream_init(&(tconfig->stream)); bstream_init(&(tconfig->stream));
vmapper_init(&(tconfig->mapper)); vmapper_init(&(tconfig->mapper));
tclexer_init(&(tconfig->lexer), &(tconfig->stream)); tclexer_init(&(tconfig->lexer), &(tconfig->stream));
tccomp_init(&(tconfig->comp), &(tconfig->lexer), &(tconfig->mapper)); tccomp_init(&(tconfig->comp), &(tconfig->lexer), &(tconfig->mapper));
} }
int tconfig_bind(tconfig_t* tconfig, int type, char* name, void* ptr) { int tconfig_bind(tconfig_t * tconfig, int type, char* name, void* ptr) {
vmapper_t* vmapper = &(tconfig->mapper); vmapper_t* vmapper = &(tconfig->mapper);
return vmapper_bind(vmapper, type, name, ptr);
return vmapper_bind(vmapper, type, name, ptr);
} }
ssize_t tconfig_read(tconfig_t* tconfig, char* filename) { ssize_t tconfig_read(tconfig_t * tconfig, char* filename) {
bstream_t* stream = &(tconfig->stream); bstream_t* stream = &(tconfig->stream);
return bstream_fread(stream, filename);
return bstream_fread(stream, filename);
} }
int tconfig_parse(tconfig_t* tconfig) { int tconfig_parse(tconfig_t * tconfig) {
return tccomp_parse(&(tconfig->comp)); return tccomp_parse(&(tconfig->comp));
} }
void tconfig_destroy(tconfig_t* tconfig) { void tconfig_destroy(tconfig_t * tconfig) {
tccomp_destroy(&(tconfig->comp)); tccomp_destroy(&(tconfig->comp));
tclexer_destroy(&(tconfig->lexer)); tclexer_destroy(&(tconfig->lexer));
bstream_destroy(&(tconfig->stream)); bstream_destroy(&(tconfig->stream));
vmapper_destroy(&(tconfig->mapper)); vmapper_destroy(&(tconfig->mapper));
} }
+9 -9
View File
@@ -12,20 +12,20 @@
#include <bstream.h> #include <bstream.h>
typedef struct { typedef struct {
bstream_t stream; bstream_t stream;
tclexer_t lexer; tclexer_t lexer;
tccomp_t comp; tccomp_t comp;
vmapper_t mapper; vmapper_t mapper;
} tconfig_t; } tconfig_t;
#define TCONF_STR MAPPER_STR #define TCONF_STR MAPPER_STR
#define TCONF_INT MAPPER_INT #define TCONF_INT MAPPER_INT
#define TCONF_BOOL MAPPER_BOOL #define TCONF_BOOL MAPPER_BOOL
void tconfig_init(tconfig_t* tconfig); void tconfig_init(tconfig_t * tconfig);
int tconfig_bind(tconfig_t* tconfig, int type, char* name, void* ptr); int tconfig_bind(tconfig_t * tconfig, int type, char* name, void* ptr);
ssize_t tconfig_read(tconfig_t* tconfig, char* filename); ssize_t tconfig_read(tconfig_t * tconfig, char* filename);
int tconfig_parse(tconfig_t* tconfig); int tconfig_parse(tconfig_t * tconfig);
void tconfig_destroy(tconfig_t* tconfig); void tconfig_destroy(tconfig_t * tconfig);
#endif #endif
+21 -18
View File
@@ -10,30 +10,33 @@
#include <tconfig.h> #include <tconfig.h>
#include <massert.h> #include <massert.h>
int main(int argc, char **argv) { int main(int argc, char** argv) {
(void)argc; (void)argc;
(void)argv; (void)argv;
tconfig_t tconfig; tconfig_t tconfig;
tconfig_init(&tconfig);
int intkey = 0; tconfig_init(&tconfig);
char* strkey = NULL;
tconfig_bind(&tconfig, TCONF_INT, "intkey", &intkey); int intkey = 0;
tconfig_bind(&tconfig, TCONF_STR, "strkey", &strkey); char* strkey = NULL;
ssize_t rsize = tconfig_read(&tconfig, "test.conf"); tconfig_bind(&tconfig, TCONF_INT, "intkey", &intkey);
printf("%ld\n", rsize); tconfig_bind(&tconfig, TCONF_STR, "strkey", &strkey);
MASSERT(rsize > 0);
int res = tconfig_parse(&tconfig); ssize_t rsize = tconfig_read(&tconfig, "test.conf");
MASSERT(res == -1);
tconfig_destroy(&tconfig); printf("%ld\n", rsize);
MASSERT(rsize > 0);
printf("int key = %d\n", intkey); int res = tconfig_parse(&tconfig);
printf("str key = %s\n", strkey);
return 0; MASSERT(res == -1);
tconfig_destroy(&tconfig);
printf("int key = %d\n", intkey);
printf("str key = %s\n", strkey);
return 0;
} }
+156 -138
View File
@@ -10,37 +10,41 @@
#include <vmapper.h> #include <vmapper.h>
static char* copystr(char* src) { static char* copystr(char* src) {
size_t srcsize = strlen(src) + 1; size_t srcsize = strlen(src) + 1;
char* dest = malloc(srcsize); char* dest = malloc(srcsize);
memset(dest, '\0', srcsize);
strcpy(dest, src); memset(dest, '\0', srcsize);
return dest; strcpy(dest, src);
return dest;
} }
static mlink_t* new_mlink_string(char* name, char** val) { static mlink_t* new_mlink_string(char* name, char** val) {
mlink_t* mlink = malloc(sizeof(mlink_t)); mlink_t* mlink = malloc(sizeof(mlink_t));
mlink->name = name;
mlink->vptr = (void*)val; mlink->name = name;
mlink->type = MAPPER_STR; mlink->vptr = (void *)val;
return mlink; mlink->type = MAPPER_STR;
return mlink;
} }
static mlink_t* new_mlink_integer(char* name, int* val) { static mlink_t* new_mlink_integer(char* name, int* val) {
mlink_t* mlink = malloc(sizeof(mlink_t)); mlink_t* mlink = malloc(sizeof(mlink_t));
mlink->name = name;
mlink->vptr = (void*)val; mlink->name = name;
mlink->type = MAPPER_INT; mlink->vptr = (void *)val;
return mlink; mlink->type = MAPPER_INT;
return mlink;
} }
static mlink_t* new_mlink_bool(char* name, bool* val) { static mlink_t* new_mlink_bool(char* name, bool* val) {
mlink_t* mlink = malloc(sizeof(mlink_t)); mlink_t* mlink = malloc(sizeof(mlink_t));
mlink->name = name;
mlink->vptr = (void*)val; mlink->name = name;
mlink->type = MAPPER_BOOL; mlink->vptr = (void *)val;
return mlink; mlink->type = MAPPER_BOOL;
return mlink;
} }
@@ -48,150 +52,164 @@ static mlink_t* new_mlink_bool(char* name, bool* val) {
vmapper_t* new_vmapper(void) { vmapper_t* new_vmapper(void) {
vmapper_t* vmapper = malloc(sizeof(vmapper_t)); vmapper_t* vmapper = malloc(sizeof(vmapper_t));
if (vmapper == NULL) return NULL;
vmapper->mlinks = malloc(sizeof(mlink_t) * MAPPER_INITCAPA); if (vmapper == NULL)
vmapper->capa = MAPPER_INITCAPA; return NULL;
vmapper->size = 0; vmapper->mlinks = malloc(sizeof(mlink_t) * MAPPER_INITCAPA);
vmapper->err = false; vmapper->capa = MAPPER_INITCAPA;
vmapper->errstr = NULL; vmapper->size = 0;
return vmapper; vmapper->err = false;
vmapper->errstr = NULL;
return vmapper;
} }
void vmapper_init(vmapper_t* vmapper) { void vmapper_init(vmapper_t * vmapper) {
vmapper->mlinks = malloc(sizeof(mlink_t) * MAPPER_INITCAPA); vmapper->mlinks = malloc(sizeof(mlink_t) * MAPPER_INITCAPA);
vmapper->capa = MAPPER_INITCAPA; vmapper->capa = MAPPER_INITCAPA;
vmapper->size = 0; vmapper->size = 0;
vmapper->err = false; vmapper->err = false;
vmapper->errstr = NULL; vmapper->errstr = NULL;
return; return;
} }
#define RES_BIND_OK ((int)0) #define RES_BIND_OK ((int)0)
#define RES_BIND_ERR ((int)-1) #define RES_BIND_ERR ((int)-1)
int vmapper_check_capa(vmapper_t* vmapper) { int vmapper_check_capa(vmapper_t * vmapper) {
if (vmapper->size == vmapper->capa) { if (vmapper->size == vmapper->capa) {
size_t newcapa = vmapper->capa * 2; size_t newcapa = vmapper->capa * 2;
mlink_t** newmlinks = realloc(vmapper->mlinks, newcapa); mlink_t** newmlinks = realloc(vmapper->mlinks, newcapa);
if (newmlinks == NULL) return RES_BIND_ERR;
vmapper->mlinks = newmlinks;
vmapper->capa = newcapa;
}
return RES_BIND_OK;
}
int vmapper_bind_string(vmapper_t* vmapper, char* name, char** val) { if (newmlinks == NULL)
int res = 0; return RES_BIND_ERR;
if ((res = vmapper_check_capa(vmapper)) != RES_BIND_OK) { vmapper->mlinks = newmlinks;
return res; vmapper->capa = newcapa;
}
mlink_t* mlink = new_mlink_string(name, val);
vmapper->mlinks[vmapper->size] = mlink;
vmapper->size++;
return RES_BIND_OK;
}
int vmapper_bind_int(vmapper_t* vmapper, char* name, int* val) {
int res = 0;
if ((res = vmapper_check_capa(vmapper)) != RES_BIND_OK) {
return res;
}
mlink_t* mlink = new_mlink_integer(name, val);
vmapper->mlinks[vmapper->size] = mlink;
vmapper->size++;
return RES_BIND_OK;
}
int vmapper_bind_bool(vmapper_t* vmapper, char* name, bool* val) {
int res = 0;
if ((res = vmapper_check_capa(vmapper)) != RES_BIND_OK) {
return res;
}
mlink_t* mlink = new_mlink_bool(name, val);
vmapper->mlinks[vmapper->size] = mlink;
vmapper->size++;
return RES_BIND_OK;
}
int vmapper_set_int(vmapper_t* vmapper, char* key, char* val) {
for (size_t i = 0; i < vmapper->size; i++) {
mlink_t* mlink = vmapper->mlinks[i];
if (mlink->type == MAPPER_INT && strcmp(mlink->name, key) == 0) {
char* eptr = NULL;
*(int*)(mlink->vptr) = (int)strtol(val, &eptr, 10);
} }
} return RES_BIND_OK;
return 0;
} }
int vmapper_set_string(vmapper_t* vmapper, char* key, char* val) { int vmapper_bind_string(vmapper_t * vmapper, char* name, char** val) {
for (size_t i = 0; i < vmapper->size; i++) { int res = 0;
mlink_t* mlink = vmapper->mlinks[i];
if (mlink->type == MAPPER_STR && strcmp(mlink->name, key) == 0) { if ((res = vmapper_check_capa(vmapper)) != RES_BIND_OK) {
*(char**)(mlink->vptr) = copystr(val); return res;
} }
} mlink_t* mlink = new_mlink_string(name, val);
return 0;
vmapper->mlinks[vmapper->size] = mlink;
vmapper->size++;
return RES_BIND_OK;
} }
int vmapper_set_bool(vmapper_t* vmapper, char* key, char* val) { int vmapper_bind_int(vmapper_t * vmapper, char* name, int* val) {
for (size_t i = 0; i < vmapper->size; i++) { int res = 0;
mlink_t* mlink = vmapper->mlinks[i];
if (mlink->type == MAPPER_BOOL && strcmp(mlink->name, key) == 0) { if ((res = vmapper_check_capa(vmapper)) != RES_BIND_OK) {
if (strcmp(val, "true") == 0) { return res;
*(bool*)(mlink->vptr) = true; }
mlink_t* mlink = new_mlink_integer(name, val);
vmapper->mlinks[vmapper->size] = mlink;
vmapper->size++;
return RES_BIND_OK;
}
int vmapper_bind_bool(vmapper_t * vmapper, char* name, bool* val) {
int res = 0;
if ((res = vmapper_check_capa(vmapper)) != RES_BIND_OK) {
return res;
}
mlink_t* mlink = new_mlink_bool(name, val);
vmapper->mlinks[vmapper->size] = mlink;
vmapper->size++;
return RES_BIND_OK;
}
int vmapper_set_int(vmapper_t * vmapper, char* key, char* val) {
for (size_t i = 0; i < vmapper->size; i++) {
mlink_t* mlink = vmapper->mlinks[i];
if (mlink->type == MAPPER_INT && strcmp(mlink->name, key) == 0) {
char* eptr = NULL;
*(int *)(mlink->vptr) = (int)strtol(val, &eptr, 10);
}
}
return 0;
}
int vmapper_set_string(vmapper_t * vmapper, char* key, char* val) {
for (size_t i = 0; i < vmapper->size; i++) {
mlink_t* mlink = vmapper->mlinks[i];
if (mlink->type == MAPPER_STR && strcmp(mlink->name, key) == 0) {
*(char **)(mlink->vptr) = copystr(val);
}
}
return 0;
}
int vmapper_set_bool(vmapper_t * vmapper, char* key, char* val) {
for (size_t i = 0; i < vmapper->size; i++) {
mlink_t* mlink = vmapper->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;
}
int vmapper_bind(vmapper_t * vmapper, int type, char* name, void* val) {
switch (type) {
case MAPPER_STR:{
return vmapper_bind_string(vmapper, name, (char **)val);
} }
if (strcmp(val, "false") == 0) { case MAPPER_INT:{
*(bool*)(mlink->vptr) = false; return vmapper_bind_int(vmapper, name, (int *)val);
}
case MAPPER_BOOL:{
return vmapper_bind_bool(vmapper, name, (bool *)val);
} }
} }
} return 0;
return 0;
}
int vmapper_bind(vmapper_t* vmapper, int type, char* name, void* val) {
switch (type) {
case MAPPER_STR: {
return vmapper_bind_string(vmapper, name, (char**)val);
}
case MAPPER_INT: {
return vmapper_bind_int(vmapper, name, (int*)val);
}
case MAPPER_BOOL: {
return vmapper_bind_bool(vmapper, name, (bool*)val);
}
}
return 0;
} }
int vmapper_set(vmapper_t* vmapper, char* key, char* val) { int vmapper_set(vmapper_t * vmapper, char* key, char* val) {
vmapper_set_int(vmapper, key, val); vmapper_set_int(vmapper, key, val);
vmapper_set_string(vmapper, key, val); vmapper_set_string(vmapper, key, val);
vmapper_set_bool(vmapper, key, val); vmapper_set_bool(vmapper, key, val);
return 0; return 0;
} }
void vmapper_destroy(vmapper_t* vmapper) { void vmapper_destroy(vmapper_t * vmapper) {
if (vmapper != NULL) { if (vmapper != NULL) {
for (size_t i = 0; i < vmapper->size; i++) { for (size_t i = 0; i < vmapper->size; i++) {
free(vmapper->mlinks[i]); free(vmapper->mlinks[i]);
}
free(vmapper->mlinks);
} }
free(vmapper->mlinks); return;
}
return;
} }
void vmapper_free(vmapper_t* vmapper) { void vmapper_free(vmapper_t * vmapper) {
if (vmapper != NULL) { if (vmapper != NULL) {
for (size_t i = 0; i < vmapper->size; i++) { for (size_t i = 0; i < vmapper->size; i++) {
free(vmapper->mlinks[i]); free(vmapper->mlinks[i]);
}
free(vmapper->mlinks);
} }
free(vmapper->mlinks); free(vmapper);
}
free(vmapper);
} }
+20 -20
View File
@@ -12,9 +12,9 @@
typedef struct { typedef struct {
char* name; char* name;
int type; int type;
void* vptr; void* vptr;
} mlink_t; } mlink_t;
#define MAPPER_STR 1 #define MAPPER_STR 1
@@ -22,28 +22,28 @@ typedef struct {
#define MAPPER_BOOL 3 #define MAPPER_BOOL 3
typedef struct { typedef struct {
mlink_t** mlinks; mlink_t** mlinks;
size_t size; size_t size;
size_t capa; size_t capa;
bool err; bool err;
char* errstr; char* errstr;
} vmapper_t; } vmapper_t;
vmapper_t* new_vmapper(void); vmapper_t* new_vmapper(void);
void vmapper_init(vmapper_t* vmapper); void vmapper_init(vmapper_t * vmapper);
int vmapper_check_capa(vmapper_t* vmapper); int vmapper_check_capa(vmapper_t * vmapper);
int vmapper_bind_string(vmapper_t* vmapper, char* name, char** val); int vmapper_bind_string(vmapper_t * vmapper, char* name, char** val);
int vmapper_bind_int(vmapper_t* vmapper, char* name, int* val); int vmapper_bind_int(vmapper_t * vmapper, char* name, int* val);
int vmapper_bind_bool(vmapper_t* vmapper, char* name, bool* val); int vmapper_bind_bool(vmapper_t * vmapper, char* name, bool* val);
int vmapper_set_int(vmapper_t* vmapper, char* key, char* val); int vmapper_set_int(vmapper_t * vmapper, char* key, char* val);
int vmapper_set_string(vmapper_t* vmapper, char* key, char* val); int vmapper_set_string(vmapper_t * vmapper, char* key, char* val);
int vmapper_set_bool(vmapper_t* vmapper, char* key, char* val); int vmapper_set_bool(vmapper_t * vmapper, char* key, char* val);
int vmapper_set(vmapper_t* vmapper, char* key, char* val); int vmapper_set(vmapper_t * vmapper, char* key, char* val);
int vmapper_bind(vmapper_t* vmapper, int type, char* name, void* val); int vmapper_bind(vmapper_t * vmapper, int type, char* name, void* val);
void vmapper_destroy(vmapper_t* vmapper); void vmapper_destroy(vmapper_t * vmapper);
void vmapper_free(vmapper_t* vmapper); void vmapper_free(vmapper_t * vmapper);
#endif #endif
+24 -23
View File
@@ -10,36 +10,37 @@
#include <vmapper.h> #include <vmapper.h>
#include <massert.h> #include <massert.h>
int main(int argc, char **argv) { int main(int argc, char** argv) {
(void)argc; (void)argc;
(void)argv; (void)argv;
vmapper_t vmapper; vmapper_t vmapper;
vmapper_init(&vmapper);
int port = 0; vmapper_init(&vmapper);
bool flag = false;
char* ident = NULL;
vmapper_bind_int(&vmapper, "port", &port); int port = 0;
vmapper_bind_string(&vmapper, "ident", &ident); bool flag = false;
vmapper_bind_bool(&vmapper, "flag", &flag); char* ident = NULL;
vmapper_set(&vmapper, "port", "12345"); vmapper_bind_int(&vmapper, "port", &port);
vmapper_set(&vmapper, "ident", "qwerty"); vmapper_bind_string(&vmapper, "ident", &ident);
vmapper_set(&vmapper, "flag", "true"); vmapper_bind_bool(&vmapper, "flag", &flag);
printf("port = %d\n", port); vmapper_set(&vmapper, "port", "12345");
MASSERT(port = 12345); vmapper_set(&vmapper, "ident", "qwerty");
vmapper_set(&vmapper, "flag", "true");
printf("ident = %s\n", ident); printf("port = %d\n", port);
MASSERT(strcmp(ident, "qwerty") == 0); MASSERT(port = 12345);
free(ident);
printf("flag = %d\n", flag); printf("ident = %s\n", ident);
MASSERT(flag = true); MASSERT(strcmp(ident, "qwerty") == 0);
free(ident);
vmapper_destroy(&vmapper); printf("flag = %d\n", flag);
MASSERT(flag = true);
return 0; vmapper_destroy(&vmapper);
return 0;
} }