Commit c8715ad3 authored by Anders Blomdell's avatar Anders Blomdell
Browse files

Check-in before renaming

parent 0679cf7c
......@@ -5,7 +5,7 @@ MODULES:=$(wildcard modules/*)
export CCFLAGS LDFLAGS
LDFLAGS_parse_config=-ldl -export-dynamic
all: $(LIBRARIES:%=build/%) $(MODULES) parse_config
all: $(LIBRARIES:%=build/%) $(MODULES)
echo $(MODULES)
echo $(CCFLAGS)
......@@ -34,18 +34,20 @@ $(MODULES):
.PHONY: test
test: all
$(MAKE) -C test test
LD_LIBRARY_PATH=build \
valgrind ./parse_config test/*/*.conf
# LD_LIBRARY_PATH=build \
# valgrind ./parse_config test/*/*.conf
# LD_LIBRARY_PATH=build HOME=$$(pwd)/test \
# valgrind -q --error-exitcode=1 test/test_c
clean:
rm build/*
find build -type f -delete
rm *~
build/libmoberg.so: build/lib/moberg_driver.o
build/libmoberg.so: build/lib/moberg_config.o
build/libmoberg.so: build/lib/moberg_device.o
build/libmoberg.so: build/lib/moberg_config_parser.o
build/lib/moberg_device.o: moberg_device.h
build/parse_config.o: moberg_config_parser.h
parse_config: build/moberg_driver.o
parse_config: build/parse_config.o
......@@ -20,6 +20,7 @@ struct moberg_digital_in_t {
};
struct moberg {
struct moberg_config *config;
struct {
int count;
struct moberg_digital_in_t *value;
......@@ -42,9 +43,15 @@ static void parse_config_at(
buf[statbuf.st_size] = 0;
}
printf("Parsing... %s %d %d\n", pathname, dirfd, fd);
struct moberg_config *config;
config = moberg_config_parse(buf);
struct moberg_config *config = moberg_config_parse(buf);
printf("-> %p\n", config);
if (config) {
if (! moberg->config) {
moberg->config = config;
} else {
moberg_config_join(moberg->config, config);
moberg_config_free(config);
}
}
free(buf);
}
......@@ -85,7 +92,10 @@ struct moberg *moberg_new(
struct moberg_config *config)
{
struct moberg *result = malloc(sizeof(*result));
if (result) {
if (! result) {
fprintf(stderr, "Failed to allocate moberg struct\n");
} else {
result->config = NULL;
if (! config) {
/* Parse default configuration(s) */
const char * const *config_paths = xdgSearchableConfigDirectories(NULL);
......@@ -96,6 +106,7 @@ struct moberg *moberg_new(
parse_config_at(result, dirfd1, "moberg.conf");
int dirfd2 = openat(dirfd1, "moberg.d", O_DIRECTORY);
if (dirfd2 >= 0) {
parse_config_dir_at(result, dirfd2);
parse_config_dir_at(result, dirfd2);
close(dirfd2);
}
......@@ -115,7 +126,10 @@ struct moberg *moberg_new(
void moberg_free(struct moberg *moberg)
{
free(moberg);
if (moberg) {
moberg_config_free(moberg->config);
free(moberg);
}
}
enum moberg_status moberg_start(
......
#include <stdlib.h>
#include <string.h>
#include <moberg_config.h>
#define LIST_COND_GROW(LIST, INDEX, ONERR) \
({ \
if (LIST.capacity <= INDEX) { \
int new_cap; \
for (new_cap = 2 ; new_cap <= INDEX ; new_cap *= 2); \
void *new = realloc(LIST.value, new_cap * sizeof(*LIST.value)); \
if (! new) { ONERR; } \
void *p = new + LIST.capacity * sizeof(*LIST.value); \
memset(p, 0, (new_cap - LIST.capacity) * sizeof(*LIST.value)); \
LIST.value = new; \
LIST.capacity= new_cap; \
} \
})
#define LIST_SET(LIST, INDEX, VALUE, ONERR) \
( LIST_COND_GROW(LIST, INDEX, ONERR), \
LIST.value[INDEX] = VALUE )
#define LIST_GET(LIST, INDEX, VALUE, ONERR) \
( LIST_COND_GROW(LIST, INDEX, ONERR), \
LIST.value[INDEX] )
struct moberg_config
{
struct device_entry {
struct device_entry *next;
struct moberg_device *device;
} *device;
struct {
int capacity;
struct analog_in_entry {
struct moberg_device* device;
struct moberg_device_analog_in *channel;
} *value;
} analog_in;
};
struct moberg_config *moberg_config_new()
{
struct moberg_config *result = malloc(sizeof *result);
result->device = NULL;
return result;
}
void moberg_config_free(struct moberg_config *config)
{
struct device_entry *entry = config->device;
while (entry) {
struct device_entry *tmp = entry;
entry = entry->next;
moberg_device_free(tmp->device);
free(tmp);
}
free(config);
}
int moberg_config_join(struct moberg_config *dest,
struct moberg_config *src)
{
if (src && dest) {
struct device_entry **tail;
for (tail = &dest->device ; *tail ; tail = &(*tail)->next) { }
*tail = src->device;
src->device = NULL;
return 1;
}
return 0;
}
int moberg_config_add_device(struct moberg_config *config,
struct moberg_device *device)
{
struct device_entry *entry = malloc(sizeof(*entry));
entry->next = config->device;
entry->device = device;
config->device = entry;
return 1;
}
int moberg_config_add_analog_in(struct moberg_config *config,
int index,
struct moberg_device* device,
struct moberg_device_analog_in *channel)
{
struct analog_in_entry e = { device, channel };
LIST_SET(config->analog_in, index, e, goto err);
return 1;
err:
return 0;
}
#ifndef __MOBERG_CONFIG_H__
#define __MOBERG_CONFIG_H__
#include <moberg_device.h>
struct moberg_config;
struct moberg_config *moberg_config_new();
void moberg_config_free(struct moberg_config *config);
int moberg_config_join(struct moberg_config *dest,
struct moberg_config *src);
int moberg_config_add_device(struct moberg_config *config,
struct moberg_device *device);
int moberg_config_add_analog_in(struct moberg_config *config,
int index,
struct moberg_device* device,
struct moberg_device_analog_in *channel);
int moberg_config_add_analog_out(struct moberg_config *config,
int index,
struct moberg_device* device,
struct moberg_device_analog_out *channel);
int moberg_config_add_digital_in(struct moberg_config *config,
int index,
struct moberg_device* device,
struct moberg_device_digital_in *channel);
int moberg_config_add_digital_out(struct moberg_config *config,
int index,
struct moberg_device* device,
struct moberg_device_digital_out *channel);
int moberg_config_add_encoder_in(struct moberg_config *config,
int index,
struct moberg_device* device,
struct moberg_device_encoder_in *channel);
#endif
......@@ -7,7 +7,6 @@
#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;
......@@ -17,6 +16,7 @@ typedef struct moberg_config_parser_ident ident_t;
#define MAX_EXPECTED 10
typedef struct moberg_config_parser_context {
struct moberg_config *config;
const char *buf; /* Pointer to data to be parsed */
const char *p; /* current parse location */
token_t token;
......@@ -287,74 +287,78 @@ void moberg_config_parser_failed(
}
static int parse_map_range(context_t *c)
static int parse_map_range(context_t *c,
struct moberg_device_map_range *range)
{
token_t low, high;
if (! acceptsym(c, tok_LBRACKET, NULL)) { goto err; }
if (! acceptsym(c, tok_INTEGER, &low)) { goto err; }
token_t min, max;
if (! acceptsym(c, tok_LBRACKET, NULL)) { goto syntax_err; }
if (! acceptsym(c, tok_INTEGER, &min)) { goto syntax_err; }
if (acceptsym(c, tok_COLON, NULL)) {
if (! acceptsym(c, tok_INTEGER, &high)) { goto err; }
if (! acceptsym(c, tok_INTEGER, &max)) { goto syntax_err; }
} else {
high = low;
max = min;
}
if (! acceptsym(c, tok_RBRACKET, NULL)) { goto err; }
if (! acceptsym(c, tok_RBRACKET, NULL)) { goto syntax_err; }
if (! range) {
fprintf(stderr, "Range is NULL\n");
goto err;
}
range->min = min.u.integer.value;
range->max = max.u.integer.value;
return 1;
err:
syntax_err:
moberg_config_parser_failed(c, stderr);
exit(1);
err:
return 0;
}
static int parse_map(context_t *c,
struct moberg_driver *driver)
struct moberg_device *device)
{
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;
}
struct moberg_device_map_range range;
if (acceptkeyword(c, "analog_in")) { range.kind = map_analog_in; }
else if (acceptkeyword(c, "analog_out")) { range.kind = map_analog_out; }
else if (acceptkeyword(c, "digital_in")) { range.kind = map_digital_in; }
else if (acceptkeyword(c, "digital_out")) { range.kind = map_digital_out; }
else if (acceptkeyword(c, "encoder_in")) { range.kind = map_encoder_in; }
else { goto syntax_err; }
if (! parse_map_range(c, &range)) { goto syntax_err; }
if (! acceptsym(c, tok_EQUAL, NULL)) { goto syntax_err; }
if (! moberg_device_parse_map(device, c, range)) { goto err; }
if (! acceptsym(c, tok_SEMICOLON, NULL)) { goto syntax_err; }
return 1;
err:
syntax_err:
moberg_config_parser_failed(c, stderr);
exit(1);
err:
return 0;
}
struct moberg_device *parse_device(context_t *c,
struct moberg_driver *driver)
static int parse_device(context_t *c,
struct moberg_device *device)
{
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")) {
moberg_device_parse_config(device, c);
/*
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));
if (! parse_map(c, device)) { goto err; }
} else if (acceptsym(c, tok_RBRACE, NULL)) {
break;
} else {
goto syntax_err;
}
}
return result;
return 1;
syntax_err:
moberg_config_parser_failed(c, stderr);
err:
moberg_device_free(result);
return NULL;
return 0;
}
static int parse(context_t *c)
......@@ -364,24 +368,31 @@ static int parse(context_t *c)
break;
} else {
token_t t;
struct moberg_driver *driver;
struct moberg_device *device;
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",
char *name = strndup(t.u.ident.value, t.u.ident.length);
if (! name) {
fprintf(stderr, "Failed to allocate driver name '%.*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) {
device = moberg_device_new(name);
free(name);
if (! device) { goto err; }
if (! parse_device(c, device)) {
moberg_device_free(device);
goto err;
}
if (! moberg_config_add_device(c->config, device)) {
moberg_device_free(device);
goto err;
}
fprintf(stderr, "SAVE device\n");
}
}
return 1;
......@@ -396,13 +407,19 @@ 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);
context.config = moberg_config_new();
if (context.config) {
context.expected.n = 0;
context.buf = buf;
context.p = context.buf;
nextsym(&context);
if (! parse(&context)) {
moberg_config_free(context.config);
context.config = NULL;
}
}
return NULL;
return context.config;
}
......@@ -3,6 +3,8 @@
#include <moberg_config.h>
struct moberg_config_parser_context;
struct moberg_config *moberg_config_parse(const char *buf);
#endif
......@@ -2,8 +2,8 @@
#define __MOBERG_CONFIG_PARSER_MODULE_H__
#include <stdio.h>
#include <moberg_config_parser.h>
struct moberg_config_parser_context;
struct moberg_config_parser_token;
enum moberg_config_parser_token_kind {
......
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <dlfcn.h>
#include <moberg_config.h>
#include <moberg_device.h>
struct moberg_device {
void *driver_handle;
struct moberg_device_driver driver;
struct moberg_device_config *config;
struct moberg_device_map_range *range;
};
struct moberg_device *moberg_device_new(const char *driver)
{
struct moberg_device *result = NULL;
char *name = malloc(strlen("libmoberg_.so") + strlen(driver) + 1);
if (!name) { goto out; }
sprintf(name, "libmoberg_%s.so", driver);
void *handle = dlopen(name, RTLD_LAZY || RTLD_DEEPBIND);
if (! handle) {
fprintf(stderr, "Could not find driver %s\n", name);
goto free_name;
}
struct moberg_device_driver *device_driver =
(struct moberg_device_driver *) dlsym(handle, "moberg_device_driver");
if (! device_driver) {
fprintf(stderr, "No moberg_device_driver in driver %s\n", name);
goto dlclose_driver;
}
result = malloc(sizeof(*result));
if (! result) {
fprintf(stderr, "Could not allocate result for %s\n", name);
goto dlclose_driver;
}
result->driver_handle = handle;
result->driver = *device_driver;
result->config = NULL;
goto free_name;
dlclose_driver:
dlclose(handle);
free_name:
free(name);
out:
return result;
}
void moberg_device_free(struct moberg_device *device)
{
device->driver.config_free(device->config);
free(device->config);
free(device);
}
int moberg_device_parse_config(struct moberg_device *device,
struct moberg_config_parser_context *context)
{
return device->driver.parse_config(device, context);
}
int moberg_device_set_config(struct moberg_device *device,
struct moberg_device_config *config)
{
if (device->config) {
device->driver.config_free(device->config);
free(device->config);
}
device->config = config;
return 1;
}
int moberg_device_parse_map(struct moberg_device* device,
struct moberg_config_parser_context *context,
struct moberg_device_map_range range)
{
int result;
struct moberg_device_map_range r = range;
device->range = &r;
result = device->driver.parse_map(device, context, range.kind);
device->range = NULL;
printf("RRR %d %d\n", r.min, r.max);
return result;
}
int moberg_device_add_analog_in(struct moberg_device* device,
struct moberg_device_analog_in *channel)
{
if (device->range->kind == map_analog_in &&
device->range->min <= device->range->max) {
printf("Mapping %d\n", device->range->min);
// moberg_config_add_analog_in()
device->range->min++;
return 1;
} else {
return 0;
}
}
int moberg_device_add_analog_out(struct moberg_device* device,
struct moberg_device_analog_out *channel)
{
if (device->range->kind == map_analog_out &&
device->range->min <= device->range->max) {
printf("Mapping %d\n", device->range->min);
device->range->min++;
return 1;
} else {
return 0;
}
}
int moberg_device_add_digital_in(struct moberg_device* device,
struct moberg_device_digital_in *channel)
{
if (device->range->kind == map_digital_in &&
device->range->min <= device->range->max) {
printf("Mapping %d\n", device->range->min);
device->range->min++;
return 1;
} else {
return 0;
}
}
int moberg_device_add_digital_out(struct moberg_device* device,
struct moberg_device_digital_out *channel)
{
if (device->range->kind == map_digital_out &&
device->range->min <= device->range->max) {
printf("Mapping %d\n", device->range->min);
device->range->min++;
return 1;
} else {
return 0;
}
}
int moberg_device_add_encoder_in(struct moberg_device* device,
struct moberg_device_encoder_in *channel)
{
if (device->range->kind == map_encoder_in &&
device->range->min <= device->range->max) {
printf("Mapping %d\n", device->range->min);
device->range->min++;
return 1;
} else {
return 0;
}
}
#ifndef __MOBERG_DEVICE_H__
#define __MOBERG_DEVICE_H__
struct moberg_device {
int (*add_config)(void *config);