Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Anders Blomdell
moberg
Commits
c8715ad3
Commit
c8715ad3
authored
Feb 22, 2019
by
Anders Blomdell
Browse files
Check-in before renaming
parent
0679cf7c
Changes
16
Hide whitespace changes
Inline
Side-by-side
Makefile
View file @
c8715ad3
...
...
@@ -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_d
river
.o
build/libmoberg.so
:
build/lib/moberg_config.o
build/libmoberg.so
:
build/lib/moberg_d
evice
.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
moberg.c
View file @
c8715ad3
...
...
@@ -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
(
...
...
moberg_config.c
0 → 100644
View file @
c8715ad3
#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
;
}
moberg_config.h
View file @
c8715ad3
#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
moberg_config_parser.c
View file @
c8715ad3
...
...
@@ -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_d
river
*
driver
)
struct
moberg_d
evice
*
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
(
!
accept
sym
(
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
(
accept
keyword
(
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
;
}
st
ruct
moberg_device
*
parse_device
(
context_t
*
c
,
struct
moberg_d
river
*
driver
)
st
atic
int
parse_device
(
context_t
*
c
,
struct
moberg_d
evice
*
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_d
river
*
driver
;
struct
moberg_d
evice
*
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
;
}
moberg_config_parser.h
View file @
c8715ad3
...
...
@@ -3,6 +3,8 @@
#include
<moberg_config.h>
struct
moberg_config_parser_context
;
struct
moberg_config
*
moberg_config_parse
(
const
char
*
buf
);
#endif
moberg_config_parser_module.h
View file @
c8715ad3
...
...
@@ -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
{
...
...
moberg_device.c
0 → 100644
View file @
c8715ad3
#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
;
}
}
moberg_device.h
View file @
c8715ad3
#ifndef __MOBERG_DEVICE_H__
#define __MOBERG_DEVICE_H__
struct
moberg_device
{
int
(
*
add_config
)(
void
*
config
);