indent
This commit is contained in:
+71
-63
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user