diff --git a/Makefile b/Makefile index 5951655ea65fa43749a2c9188f32ea4021833a97..cf7b049fc4480dd9ed30cd0566f54b72676ea9b5 100644 --- a/Makefile +++ b/Makefile @@ -1,18 +1,20 @@ LIBRARIES=libmoberg.so -CCFLAGS+=-Wall -Werror -I. -g -LDFLAGS+=-Lbuild/ -lmoberg +CCFLAGS+=-Wall -Werror -I$(shell pwd) -g +LDFLAGS+=-L$(shell pwd)/build/ -lmoberg MODULES:=$(wildcard modules/*) - +export CCFLAGS LDFLAGS LDFLAGS_parse_config=-ldl -export-dynamic -all: $(LIBRARIES:%=build/%) $(MODULES) test/test_c parse_config +all: $(LIBRARIES:%=build/%) $(MODULES) parse_config echo $(MODULES) + echo $(CCFLAGS) build/libmoberg.so: moberg.c Makefile | build - $(CC) -o $@ $(CCFLAGS) -lxdg-basedir -shared -fPIC -I. $< + $(CC) -o $@ $(CCFLAGS) -shared -fPIC -I. $< \ + $(filter %.o,$^) -lxdg-basedir -ldl -build: - mkdir $@ +build/lib build: + mkdir -p $@ %: build/%.o Makefile $(CC) $(LDFLAGS) $(LDFLAGS_$(*)) -o $@ $(filter %.o,$^) @@ -20,6 +22,9 @@ build: build/%.o: %.c Makefile $(CC) $(CCFLAGS) -c -o $@ $< +build/lib/%.o: %.c Makefile | build/lib + $(CC) $(CCFLAGS) -c -fPIC -o $@ $< + .PHONY: $(MODULES) $(MODULES): @@ -28,18 +33,19 @@ $(MODULES): .PHONY: test test: all + $(MAKE) -C test test LD_LIBRARY_PATH=build \ valgrind ./parse_config test/*/*.conf - LD_LIBRARY_PATH=build HOME=$$(pwd)/test \ - valgrind -q --error-exitcode=1 test/test_c +# LD_LIBRARY_PATH=build HOME=$$(pwd)/test \ +# valgrind -q --error-exitcode=1 test/test_c -test/test_c: test/test_c.c Makefile - $(CC) $(CCFLAGS) $(LDFLAGS) -o $@ $< clean: rm build/* +build/libmoberg.so: build/lib/moberg_driver.o +build/libmoberg.so: build/lib/moberg_config_parser.o build/parse_config.o: moberg_config_parser.h parse_config: build/moberg_driver.o parse_config: build/parse_config.o diff --git a/moberg.c b/moberg.c index 57fbdaaf2db4ab376f92b54303fd314d2272ebec..8df1bab409bbadb90400d05716680062e759421f 100644 --- a/moberg.c +++ b/moberg.c @@ -10,35 +10,52 @@ #include <stdio.h> #include <dirent.h> #include <string.h> -#include "moberg.h" +#include <moberg.h> +#include <moberg_config.h> +#include <moberg_config_parser.h> struct moberg_digital_in_t { int index; char *driver; }; -struct moberg_t { +struct moberg { struct { int count; struct moberg_digital_in_t *value; } digital_in; }; -static void parse_config_at(struct moberg_t *config, - int dirfd, - const char *pathname) +static void parse_config_at( + struct moberg *moberg, + int dirfd, + const char *pathname) { if (dirfd >= 0) { int fd = openat(dirfd, pathname, O_RDONLY); if (fd >= 0) { - printf("Parsing... %s %d %d\n", pathname, dirfd, fd); + struct stat statbuf; + if (fstat(fd, &statbuf) == 0) { + char *buf = malloc(statbuf.st_size + 1); + if (buf) { + if (read(fd, buf, statbuf.st_size) == statbuf.st_size) { + buf[statbuf.st_size] = 0; + } + printf("Parsing... %s %d %d\n", pathname, dirfd, fd); + struct moberg_config *config; + config = moberg_config_parse(buf); + if (config) { + } + free(buf); + } + } close(fd); } } - } -static int conf_filter(const struct dirent *entry) +static int conf_filter( + const struct dirent *entry) { char *dot = strrchr(entry->d_name, '.'); if (dot != NULL && strcmp(dot, ".conf") == 0) { @@ -48,44 +65,71 @@ static int conf_filter(const struct dirent *entry) } } -static void parse_config_dir_at(struct moberg_t *config, - int dirfd) +static void parse_config_dir_at( + struct moberg *config, + int dirfd) { if (dirfd >= 0) { struct dirent **entry = NULL; int n = scandirat(dirfd, ".", &entry, conf_filter, alphasort); for (int i = 0 ; i < n ; i++) { parse_config_at(config, dirfd, entry[i]->d_name); + free(entry[i]); } free(entry); } } -const struct moberg_t *moberg_init() +struct moberg *moberg_new( + struct moberg_config *config) { - struct moberg_t *result = malloc(sizeof(struct moberg_t)); - - const char * const *config_paths = xdgSearchableConfigDirectories(NULL); - const char * const *path; - for (path = config_paths ; *path ; path++) { - int dirfd1 = open(*path, O_DIRECTORY); - if (dirfd >= 0) { - parse_config_at(result, dirfd1, "moberg.conf"); - int dirfd2 = openat(dirfd1, "moberg.d", O_DIRECTORY); - if (dirfd2 >= 0) { - parse_config_dir_at(result, dirfd2); - close(dirfd2); + struct moberg *result = malloc(sizeof(*result)); + if (result) { + if (! config) { + /* Parse default configuration(s) */ + const char * const *config_paths = xdgSearchableConfigDirectories(NULL); + const char * const *path; + for (path = config_paths ; *path ; path++) { + int dirfd1 = open(*path, O_DIRECTORY); + if (dirfd >= 0) { + parse_config_at(result, dirfd1, "moberg.conf"); + int dirfd2 = openat(dirfd1, "moberg.d", O_DIRECTORY); + if (dirfd2 >= 0) { + parse_config_dir_at(result, dirfd2); + close(dirfd2); + } + close(dirfd1); + } + free((char*)*path); } - close(dirfd1); + free((const char **)config_paths); + + /* Read environment default */ + /* Parse environment overrides */ } } - free((const char **)config_paths); - - /* Read local default */ - /* Read environment default */ - /* Parse environment overrides */ - return result; } + +void moberg_free(struct moberg *moberg) +{ + free(moberg); +} + +enum moberg_status moberg_start( + struct moberg *moberg, + FILE *f) +{ + return moberg_OK; +} + + +enum moberg_status moberg_stop( + struct moberg *moberg, + FILE *f) +{ + return moberg_OK; +} + diff --git a/moberg.h b/moberg.h index c3dd7d212dc2fd83b8ba8fe31ce1c533d7874cf3..d2cb9d69b0d8a75b72ecfd6a4779769b6799cf08 100644 --- a/moberg.h +++ b/moberg.h @@ -1,15 +1,50 @@ #ifndef __MOBERG_H__ #define __MOBERG_H__ -struct moberg_t; -struct moberg_digital_in_t; +#include <stdio.h> +#include <moberg_config.h> +struct moberg; +enum moberg_status { moberg_OK }; -const struct moberg_t *moberg_init(); +struct moberg *moberg_new(struct moberg_config *config); +void moberg_free(struct moberg *moberg); -struct moberg_digital_in_t *moberg_open_digital_in( - const struct moberg_t *handle, +/* Input/output functions */ + +enum moberg_status moberg_analog_in( + double *value, + struct moberg *moberg, + int channel); + +enum moberg_status moberg_analog_out( + double value, + struct moberg *moberg, + int channel); + +enum moberg_status moberg_digital_in( + int *value, + struct moberg *moberg, + int channel); + +enum moberg_status moberg_digital_out( + int value, + struct moberg *moberg, + int channel); + +enum moberg_status moberg_encoder_in( + long *value, + struct moberg *moberg, int channel); - + +/* Install functionality */ + +enum moberg_status moberg_start( + struct moberg *moberg, + FILE *f); + +enum moberg_status moberg_stop( + struct moberg *moberg, + FILE *f); #endif diff --git a/moberg_config.h b/moberg_config.h new file mode 100644 index 0000000000000000000000000000000000000000..832b10a5ac92f3bc6b7a448685836bca0f91fc9e --- /dev/null +++ b/moberg_config.h @@ -0,0 +1,6 @@ +#ifndef __MOBERG_CONFIG_H__ +#define __MOBERG_CONFIG_H__ + +struct moberg_config; + +#endif diff --git a/moberg_config_parser.c b/moberg_config_parser.c new file mode 100644 index 0000000000000000000000000000000000000000..27b61c63677326dee15c0730dcc43dbbe08fe6e9 --- /dev/null +++ b/moberg_config_parser.c @@ -0,0 +1,408 @@ +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <moberg_config_parser.h> +#include <moberg_config_parser_module.h> +#include <moberg_driver.h> +#include <moberg_device.h> + +typedef enum moberg_config_parser_token_kind kind_t; +typedef struct moberg_config_parser_token token_t; +typedef struct moberg_config_parser_ident ident_t; + +#define MAX_EXPECTED 10 + +typedef struct moberg_config_parser_context { + const char *buf; /* Pointer to data to be parsed */ + const char *p; /* current parse location */ + token_t token; + struct { + int n; + const char *what[MAX_EXPECTED]; + } expected; +} context_t; + + +static inline int acceptsym(context_t *c, + kind_t kind, + token_t *token) +{ + return moberg_config_parser_acceptsym(c, kind, token); +} + +static inline int acceptkeyword(context_t *c, + const char *keyword) +{ + return moberg_config_parser_acceptkeyword(c, keyword); +} + +static const void nextsym_ident(context_t *c) +{ + c->token.kind = tok_IDENT; + c->token.u.ident.length = 1; + c->token.u.ident.value = c->p; + c->p++; + while (*c->p) { + switch (*c->p) { + case 'a'...'z': + case 'A'...'Z': + case '0'...'9': + case '_': + c->p++; + c->token.u.ident.length++; + break; + default: + return; + } + } +} + +static const void nextsym_integer(context_t *c) +{ + c->token.kind = tok_INTEGER; + c->token.u.integer.value = 0; + while (*c->p && '0' <= *c->p && *c->p <= '9') { + c->token.u.integer.value *= 10; + c->token.u.integer.value += *c->p - '0'; + c->p++; + } +} + +static const void nextsym_string(context_t *c) +{ + c->token.kind = tok_STRING; + c->p++; + c->token.u.string.value = c->p; + c->token.u.string.length = 0; + while (*c->p && *c->p != '"') { + if (*c->p == '\\') { + c->token.u.string.length++; + c->p++; + } + if (*c->p) { + c->token.u.string.length++; + c->p++; + } + } + c->p++; +} + +static int nextsym(context_t *c) +{ + c->token.kind = tok_none; + while (c->p && *c->p && c->token.kind == tok_none) { + if (c->p[0] == '/' && c->p[1] == '*') { + /* Skip comment */ + c->p += 2; + while (*c->p && (c->p[0] != '*' || c->p[1] != '/')) { + c->p++; + } + c->p += 2; + continue; + } + switch (*c->p) { + case ' ': + case '\t': + case '\n': + case '\r': + /* Skip whitespace */ + c->p++; + break; + case '(': + c->token.kind = tok_LPAREN; + c->p++; + break; + case ')': + c->token.kind = tok_RPAREN; + c->p++; + break; + case '{': + c->token.kind = tok_LBRACE; + c->p++; + break; + case '}': + c->token.kind = tok_RBRACE; + c->p++; + break; + case '[': + c->token.kind = tok_LBRACKET; + c->p++; + break; + case ']': + c->token.kind = tok_RBRACKET; + c->p++; + break; + case '=': + c->token.kind = tok_EQUAL; + c->p++; + break; + case ',': + c->token.kind = tok_COMMA; + c->p++; + break; + case ':': + c->token.kind = tok_COLON; + c->p++; + break; + case ';': + c->token.kind = tok_SEMICOLON; + c->p++; + break; + case '"': + nextsym_string(c); + break; + case 'a'...'z': + case 'A'...'Z': + case '_': + nextsym_ident(c); + break; + case '0'...'9': + nextsym_integer(c); + break; + default: + printf("UNEXPECTED %c\n\n", *c->p); + c->p++; + break; + } + } + if (c->token.kind != tok_none) { + return 1; + } else { + c->token.kind = tok_EOF; + return 0; + } +} + +static int peeksym(context_t *c, + kind_t kind, + token_t *token) +{ + if (c->token.kind == kind) { + if (token) { + *token = c->token; + } + return 1; + } + return 0; +} + +int moberg_config_parser_acceptsym(context_t *c, + kind_t kind, + token_t *token) +{ + if (c->token.kind == kind) { + if (token) { + *token = c->token; + } + nextsym(c); + c->expected.n = 0; + return 1; + } + if (c->expected.n < MAX_EXPECTED) { + const char *what = NULL; + switch (kind) { + case tok_none: break; + case tok_EOF: what = "<EOF>"; break; + case tok_LPAREN: what = "("; break; + case tok_RPAREN: what = ")"; break; + case tok_LBRACE: what = "{"; break; + case tok_RBRACE: what = "}"; break; + case tok_LBRACKET: what = "["; break; + case tok_RBRACKET: what = "]"; break; + case tok_EQUAL: what = "="; break; + case tok_COMMA: what = ","; break; + case tok_COLON: what = ":"; break; + case tok_SEMICOLON: what = ";"; break; + case tok_INTEGER: what = "<INTEGER>"; break; + case tok_IDENT: what = "<IDENT>"; break; + case tok_STRING: what = "<STRING>"; break; + } + if (what) { + c->expected.what[c->expected.n] = what; + c->expected.n++; + } + } + return 0; +} + +int moberg_config_parser_acceptkeyword(context_t *c, + const char *keyword) +{ + token_t t; + if (peeksym(c, tok_IDENT, &t) && + strncmp(keyword, t.u.ident.value, t.u.ident.length) == 0) { + nextsym(c); + c->expected.n = 0; + return 1; + } + if (c->expected.n < MAX_EXPECTED) { + c->expected.what[c->expected.n] = keyword; + c->expected.n++; + } + return 0; +} + +void moberg_config_parser_failed( + struct moberg_config_parser_context *c, + FILE *f) +{ + fprintf(f, "EXPECTED "); + for (int i = 0 ; i < c->expected.n; i++) { + if (i > 0) { + fprintf(f, " | "); + } + fprintf(f, "'%s'", c->expected.what[i]); + } + fprintf(f, "\nGOT: "); + switch (c->token.kind) { + case tok_none: break; + case tok_EOF: fprintf(f, "<EOF>"); break; + case tok_LPAREN: fprintf(f, "("); break; + case tok_RPAREN: fprintf(f, ")"); break; + case tok_LBRACE: fprintf(f, "{"); break; + case tok_RBRACE: fprintf(f, "}"); break; + case tok_LBRACKET: fprintf(f, "["); break; + case tok_RBRACKET: fprintf(f, "]"); break; + case tok_EQUAL: fprintf(f, "="); break; + case tok_COMMA: fprintf(f, ","); break; + case tok_COLON: fprintf(f, ":"); break; + case tok_SEMICOLON: fprintf(f, ";"); break; + case tok_INTEGER: + fprintf(f, "%d (<INTEGER>)", c->token.u.integer.value); + break; + case tok_IDENT: + fprintf(f, "%.*s (<IDENT>)", + c->token.u.ident.length, c->token.u.ident.value); + break; + case tok_STRING: + fprintf(f, "\"%.*s'\" (<STRING>)", + c->token.u.string.length, c->token.u.string.value); + break; + } + fprintf(f, "\n%s\n", c->p); +} + + +static int parse_map_range(context_t *c) +{ + token_t low, high; + if (! acceptsym(c, tok_LBRACKET, NULL)) { goto err; } + if (! acceptsym(c, tok_INTEGER, &low)) { goto err; } + if (acceptsym(c, tok_COLON, NULL)) { + if (! acceptsym(c, tok_INTEGER, &high)) { goto err; } + } else { + high = low; + } + if (! acceptsym(c, tok_RBRACKET, NULL)) { goto err; } + return 1; +err: + moberg_config_parser_failed(c, stderr); + exit(1); + return 0; +} + +static int parse_map(context_t *c, + struct moberg_driver *driver) +{ + if (acceptkeyword(c, "analog_in") || + acceptkeyword(c, "analog_out") || + acceptkeyword(c, "digital_in") || + acceptkeyword(c, "digital_out") || + acceptkeyword(c, "encoder_in")) { + if (! parse_map_range(c)) { goto err; } + if (! acceptsym(c, tok_EQUAL, NULL)) { goto err; } + driver->module.parse_map(c, 0); + if (! acceptsym(c, tok_SEMICOLON, NULL)) { goto err; } + } else { + goto err; + } + return 1; +err: + moberg_config_parser_failed(c, stderr); + exit(1); + return 0; +} + +struct moberg_device *parse_device(context_t *c, + struct moberg_driver *driver) +{ + struct moberg_device *result = moberg_device_new(driver); + if (! result) { + goto err; + } + + if (! acceptsym(c, tok_LBRACE, NULL)) { goto syntax_err; } + for (;;) { + if (acceptkeyword(c, "config")) { + void *config = driver->module.parse_config(c); + result->add_config(config); + free(config); + } else if (acceptkeyword(c, "map")) { + result->add_map(parse_map(c, driver)); + } else if (acceptsym(c, tok_RBRACE, NULL)) { + break; + } else { + goto syntax_err; + } + } + return result; +syntax_err: + moberg_config_parser_failed(c, stderr); +err: + moberg_device_free(result); + return NULL; +} + +static int parse(context_t *c) +{ + for (;;) { + if (acceptsym(c, tok_EOF, NULL)) { + break; + } else { + token_t t; + struct moberg_driver *driver; + + if (! acceptkeyword(c, "driver")) { goto syntax_err; } + if (! acceptsym(c, tok_LPAREN, NULL)) { goto syntax_err; } + if (! acceptsym(c, tok_IDENT, &t)) { goto syntax_err; } + if (! acceptsym(c, tok_RPAREN, NULL)) { goto syntax_err; } + + if (! (driver = moberg_driver_open(t.u.ident))) { + fprintf(stderr, "Could not open driver '%.*s'\n", + t.u.ident.length, t.u.ident.value); + goto err; + } + struct moberg_device *device = parse_device(c, driver); + moberg_driver_close(driver); + if (! device) { + goto err; + } + fprintf(stderr, "SAVE device\n"); + } + } + return 1; +syntax_err: + moberg_config_parser_failed(c, stderr); + goto err; +err: + return 0; +} + +struct moberg_config *moberg_config_parse(const char *buf) +{ + context_t context; + + context.expected.n = 0; + context.buf = buf; + context.p = context.buf; + nextsym(&context); + parse(&context); + + return NULL; +} + + diff --git a/moberg_config_parser.h b/moberg_config_parser.h index d968b507c8bb6a32ca443a8736d71aaa91b51ed0..5990c0fa34c1b2b697f51f60b54050a59b7c02d0 100644 --- a/moberg_config_parser.h +++ b/moberg_config_parser.h @@ -1,56 +1,8 @@ #ifndef __MOBERG_CONFIG_PARSER_H__ #define __MOBERG_CONFIG_PARSER_H__ -#include <stdio.h> +#include <moberg_config.h> -struct moberg_config_parser_context; -struct moberg_config_parser_token; - -enum moberg_config_parser_token_kind { - tok_none, - tok_EOF, - tok_LPAREN, - tok_RPAREN, - tok_LBRACE, - tok_RBRACE, - tok_LBRACKET, - tok_RBRACKET, - tok_EQUAL, - tok_COMMA, - tok_COLON, - tok_SEMICOLON, - tok_INTEGER, - tok_IDENT, - tok_STRING, -}; - -struct moberg_config_parser_ident { - int length; - const char *value; -}; - -struct moberg_config_parser_token { - enum moberg_config_parser_token_kind kind; - union { - struct moberg_config_parser_ident ident; - struct moberg_config_parser_ident string; - struct moberg_config_parser_integer { - int value; - } integer; - } u; -}; - -int moberg_config_parser_acceptsym( - struct moberg_config_parser_context *c, - enum moberg_config_parser_token_kind kind, - struct moberg_config_parser_token *token); - -int moberg_config_parser_acceptkeyword( - struct moberg_config_parser_context *c, - const char *keyword); - -void moberg_config_parser_failed( - struct moberg_config_parser_context *c, - FILE *f); +struct moberg_config *moberg_config_parse(const char *buf); #endif diff --git a/moberg_config_parser_module.h b/moberg_config_parser_module.h new file mode 100644 index 0000000000000000000000000000000000000000..bcfd2c87e397f83b975a6fbf823dd837eaa8ac71 --- /dev/null +++ b/moberg_config_parser_module.h @@ -0,0 +1,56 @@ +#ifndef __MOBERG_CONFIG_PARSER_MODULE_H__ +#define __MOBERG_CONFIG_PARSER_MODULE_H__ + +#include <stdio.h> + +struct moberg_config_parser_context; +struct moberg_config_parser_token; + +enum moberg_config_parser_token_kind { + tok_none, + tok_EOF, + tok_LPAREN, + tok_RPAREN, + tok_LBRACE, + tok_RBRACE, + tok_LBRACKET, + tok_RBRACKET, + tok_EQUAL, + tok_COMMA, + tok_COLON, + tok_SEMICOLON, + tok_INTEGER, + tok_IDENT, + tok_STRING, +}; + +struct moberg_config_parser_ident { + int length; + const char *value; +}; + +struct moberg_config_parser_token { + enum moberg_config_parser_token_kind kind; + union { + struct moberg_config_parser_ident ident; + struct moberg_config_parser_ident string; + struct moberg_config_parser_integer { + int value; + } integer; + } u; +}; + +int moberg_config_parser_acceptsym( + struct moberg_config_parser_context *c, + enum moberg_config_parser_token_kind kind, + struct moberg_config_parser_token *token); + +int moberg_config_parser_acceptkeyword( + struct moberg_config_parser_context *c, + const char *keyword); + +void moberg_config_parser_failed( + struct moberg_config_parser_context *c, + FILE *f); + +#endif diff --git a/moberg_device.h b/moberg_device.h new file mode 100644 index 0000000000000000000000000000000000000000..b792a758d30274288f243bda7c619a050296ff6c --- /dev/null +++ b/moberg_device.h @@ -0,0 +1,13 @@ +#ifndef __MOBERG_DEVICE_H__ +#define __MOBERG_DEVICE_H__ + +struct moberg_device { + int (*add_config)(void *config); + int (*add_map)(int config); +}; + +struct moberg_device *moberg_device_new(struct moberg_driver *driver); + +void moberg_device_free(struct moberg_device *device); + +#endif diff --git a/moberg_driver.h b/moberg_driver.h index a774da5ac0c0cadfa917eab559d6a859f10e9f72..ca1b3051e12346b7749633120c1a878d5159e1ae 100644 --- a/moberg_driver.h +++ b/moberg_driver.h @@ -1,7 +1,7 @@ #ifndef __MOBERG_DRIVER_H__ #define __MOBERG_DRIVER_H__ -#include <moberg_config_parser.h> +#include <moberg_config_parser_module.h> struct moberg_driver_device; diff --git a/modules/comedi/Makefile b/modules/comedi/Makefile index fc2fefaa1cd23d363ba28f3689385fcae3a736cb..4923fc69f0e63868378cb240e2b6e1f99fd1fea3 100644 --- a/modules/comedi/Makefile +++ b/modules/comedi/Makefile @@ -5,7 +5,7 @@ MODULES=$(wildcard modules/*) all: $(LIBRARIES:%=../../build/%) -../../build/libmoberg_comedi.so: comedi.c +../../build/libmoberg_comedi.so: comedi.c Makefile $(CC) -o $@ $(CCFLAGS) -shared -fPIC $< -../../build/libmoberg_comedi.so: ../../moberg_config_parser.h +../../build/libmoberg_comedi.so: ../../moberg_config_parser_module.h diff --git a/modules/comedi/comedi.c b/modules/comedi/comedi.c index f5ae143e86348d1e79ddc5cdac6084e0327254d7..59977600872a1325503f8ca35385ccf138040b01 100644 --- a/modules/comedi/comedi.c +++ b/modules/comedi/comedi.c @@ -1,4 +1,4 @@ -#include <moberg_config_parser.h> +#include <moberg_config_parser_module.h> #include <moberg_driver.h> #include <stdio.h> #include <stdlib.h> diff --git a/modules/serial2002/Makefile b/modules/serial2002/Makefile index c107b53804891310cdcdf1812e6585d86a1f54c4..9f66f2d087173ae0b696046dd2076d7bcb5d2de6 100644 --- a/modules/serial2002/Makefile +++ b/modules/serial2002/Makefile @@ -5,7 +5,7 @@ MODULES=$(wildcard modules/*) all: $(LIBRARIES:%=../../build/%) -../../build/libmoberg_serial2002.so: serial2002.c +../../build/libmoberg_serial2002.so: serial2002.c Makefile $(CC) -o $@ $(CCFLAGS) -shared -fPIC $< -../../build/libmoberg_serial2002.so: ../../moberg_config_parser.h +../../build/libmoberg_serial2002.so: ../../moberg_config_parser_module.h diff --git a/modules/serial2002/serial2002.c b/modules/serial2002/serial2002.c index af26b0c411504d36cb4db67d76bff68f5131e32b..35a7d344afc18b26c580970da2739733241900e8 100644 --- a/modules/serial2002/serial2002.c +++ b/modules/serial2002/serial2002.c @@ -1,4 +1,4 @@ -#include <moberg_config_parser.h> +#include <moberg_config_parser_module.h> #include <moberg_driver.h> #include <stdio.h> #include <stdlib.h> diff --git a/parse_config.c b/parse_config.c index 53bde81659456164707e48d2976e0bea8b8b4a54..2c2b398c0ce35f8cf63c48cceca7b4777953589e 100644 --- a/parse_config.c +++ b/parse_config.c @@ -6,6 +6,7 @@ #include <stdlib.h> #include <string.h> #include <moberg_config_parser.h> +#include <moberg_config_parser_module.h> #include <moberg_driver.h> typedef enum moberg_config_parser_token_kind kind_t; diff --git a/test/.config/moberg.d/moberg.conf b/test/.config/moberg.d/moberg.conf new file mode 100644 index 0000000000000000000000000000000000000000..9523ce1625d4cfb32c01da6c34920855acf2dbd8 --- /dev/null +++ b/test/.config/moberg.d/moberg.conf @@ -0,0 +1,25 @@ +driver(comedi) { + config { + /* Parsed by parse_config in libmoberg_comedi.so */ + device = "/dev/comedi0" ; + modprobe = [ comedi "8255" comedi_fc mite ni_tio ni_tiocmd ni_pcimio ] ; + config = [ ni_pcimio ] ; + } + /* Moberg mapping[indices] = {driver specific}[indices] + {driver specific} is parsed by parse_map in libmoberg_comedi.so */ + map analog_in[0:7] = { subdevice[0][0:7] }; + map analog_out[0:1] = { subdevice[1][0:1] }; + map digital_in[0:1] = { subdevice[7][15] , + subdevice[7][2] }; + map digital_out[0:1] = { subdevice[7] route 16 [0:1] }; +} +driver(serial2002) { + config { + /* Parsed by parse_config in libmoberg_serial2002.so */ + device = "/dev/ttyS0" ; + baud = 115200 ; + } + /* Moberg mapping[indices] = {driver specific}[indices] + {driver specific} is parsed by parse_map in libmoberg_serial2002.so */ + map digital_in[30:37] = digital_in[0:7] ; +} diff --git a/test/Makefile b/test/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..c23d259f1988f25c578a1cda772f11bf852d4407 --- /dev/null +++ b/test/Makefile @@ -0,0 +1,15 @@ +TEST = test_start_stop + +ENV_test_start_stop = LD_LIBRARY_PATH=../build HOME=. +all: + +.PHONY: test +test: $(TEST:%=run_%) + echo Testing + exit 1 + +run_%: % + $(ENV_$*) valgrind --leak-check=full ./$* + +%: %.c + $(CC) $(CCFLAGS) $(LDFLAGS) -o $@ $< diff --git a/test/test_start_stop.c b/test/test_start_stop.c new file mode 100644 index 0000000000000000000000000000000000000000..d5fd56671db61aab842f20992880dd6f50d9f09b --- /dev/null +++ b/test/test_start_stop.c @@ -0,0 +1,12 @@ +#include <stdio.h> +#include <moberg.h> + +int main(int argc, char *argv[]) +{ + struct moberg *moberg = moberg_new(NULL); + printf("START:\n"); + moberg_start(moberg, stdout); + printf("STOP:\n"); + moberg_stop(moberg, stdout); + moberg_free(moberg); +}