Commit 8853f790 authored by Jeroen Vreeken's avatar Jeroen Vreeken
Browse files

Unify dt_ctrl and dt_ctrl_sim.

Also fix some reentrancy issues in the controller_load functions.
parent 2a57221a
dt_ctrl
dt_ctrl_sim
dt_ctrl.dot
dt_ctrl.pdf
......@@ -11,16 +11,14 @@ LDFLAGS= -lpthread -lrt -lm -ldl -Wl,-E -L../common/lib -L./lib
CFLAGS_SIM=-DUSE_AZ_SIM -DUSE_EL_SIM
dt_ctrl_sim_LDFLAGS=`controller/block_list.sh lib/*.a` \
dt_ctrl_LDFLAGS=`controller/block_list.sh lib/*.a` \
-lcontroller -lethercat -llog -lshell -ldt_azimuth -ldt_elevation
dt_ctrl_LDFLAGS=$(dt_ctrl_sim_LDFLAGS)
all: dt_ctrl dt_ctrl_sim \
all: dt_ctrl \
test \
controller
dt_ctrl: lib/libcontroller.la lib/libethercat.la lib/libdt_azimuth.la lib/libdt_elevation.la
dt_ctrl_sim: lib/libcontroller.la lib/libethercat.la lib/libdt_azimuth.la lib/libdt_elevation.la
lib/libethercat.la: lib/libcontroller.la
lib/libdt_azimuth.la: lib/libcontroller.la
......@@ -28,11 +26,6 @@ lib/libdt_elevation.la: lib/libcontroller.la
dt_ctrl: dt_ctrl.o
dt_ctrl_sim: dt_ctrl_sim.o
dt_ctrl_sim.o: dt_ctrl.c
@echo "COMPILE: dt_ctrl.c (OUTPUT: dt_ctrl_sim.o)"
@$(CC) $(CFLAGS) $(CFLAGS_SIM) dt_ctrl.c -c -o dt_ctrl_sim.o
test: lib/libcontroller.la lib/libethercat.la lib/liblog.la
@echo " SUBDIR: $@"
......@@ -75,8 +68,7 @@ clean:
rm -f *.o *.d *.a *.la *.lo lib/*
rm -f dt_az dt_az_ctrl \
command_shell \
dt_ctrl \
dt_ctrl_sim
dt_ctrl
$(MAKE) -C controller clean
$(MAKE) -C dt_azimuth clean
$(MAKE) -C dt_elevation clean
......
......@@ -29,145 +29,163 @@
#include "../../common/include/dynarg.h"
#include <shell/shell.h>
static char *controller_load_filename;
struct controller_load_array {
void *array;
size_t size;
};
int yyparse(yyscan_t scanner, FILE *);
struct controller_load_extra {
char *filename;
int ret;
bool va_list_start;
va_list va_list;
struct controller_load_va_entry *va_entries;
struct controller_load_array *array;
bool use_string;
char *string;
size_t stringlen;
FILE *input_file;
};
static int controller_load_ret;
int yyparse(yyscan_t scanner, FILE *);
void yyerror(yyscan_t scanner, char const *s)
{
struct controller_load_extra *extra = yyget_extra(scanner);
fprintf(stderr, "%s:%d: %s\n",
controller_load_filename,
extra->filename,
yyget_lineno(scanner),
s);
controller_load_ret = -1;
extra->ret = -1;
}
bool controller_load_va_list_start = false;
va_list controller_load_va_list;
struct controller_load_va_entry {
struct controller_load_va_entry *next;
void *ptr;
};
static struct controller_load_va_entry *va_entries = NULL;
void controller_load_var_add_str(char *string)
void controller_load_var_add_str(char *string, yyscan_t scanner)
{
struct controller_load_extra *extra = yyget_extra(scanner);
struct controller_load_va_entry **entryp;
if (!controller_load_va_list_start) {
va_new(controller_load_va_list);
controller_load_va_list_start = true;
if (!extra->va_list_start) {
va_new(extra->va_list);
extra->va_list_start = true;
}
va_add(controller_load_va_list, char *, string);
va_add(extra->va_list, char *, string);
for (entryp = &va_entries; *entryp; entryp = &(*entryp)->next);
for (entryp = &extra->va_entries; *entryp; entryp = &(*entryp)->next);
*entryp = malloc(sizeof(struct controller_load_va_entry));
(*entryp)->next = NULL;
(*entryp)->ptr = string;
}
void controller_load_var_add_dbl(double dbl)
void controller_load_var_add_dbl(double dbl, yyscan_t scanner)
{
if (!controller_load_va_list_start) {
va_new(controller_load_va_list);
controller_load_va_list_start = true;
struct controller_load_extra *extra = yyget_extra(scanner);
if (!extra->va_list_start) {
va_new(extra->va_list);
extra->va_list_start = true;
}
va_add(controller_load_va_list, double, dbl);
va_add(extra->va_list, double, dbl);
}
struct controller_load_array {
void *array;
size_t size;
};
static struct controller_load_array *controller_load_array = NULL;
void controller_load_var_add_flt(float flt)
void controller_load_var_add_flt(float flt, yyscan_t scanner)
{
if (controller_load_array) {
controller_load_array->array = realloc(
controller_load_array->array,
controller_load_array->size + sizeof(float));
*(float*)(controller_load_array->array + controller_load_array->size) = flt;
controller_load_array->size += sizeof(float);
struct controller_load_extra *extra = yyget_extra(scanner);
if (extra->array) {
extra->array->array = realloc(
extra->array->array,
extra->array->size + sizeof(float));
*(float*)(extra->array->array + extra->array->size) = flt;
extra->array->size += sizeof(float);
} else {
/* float is promoted to double in a variadic function */
controller_load_var_add_dbl(flt);
controller_load_var_add_dbl(flt, scanner);
}
}
void controller_load_var_add_float_array_start(void)
void controller_load_var_add_float_array_start(yyscan_t scanner)
{
controller_load_array = malloc(sizeof(struct controller_load_array));
controller_load_array->array = NULL;
controller_load_array->size = 0;
struct controller_load_extra *extra = yyget_extra(scanner);
extra->array = malloc(sizeof(struct controller_load_array));
extra->array->array = NULL;
extra->array->size = 0;
}
void controller_load_var_add_float_array_end(void)
void controller_load_var_add_float_array_end(yyscan_t scanner)
{
struct controller_load_extra *extra = yyget_extra(scanner);
struct controller_load_va_entry **entryp;
if (!controller_load_va_list_start) {
va_new(controller_load_va_list);
controller_load_va_list_start = true;
if (!extra->va_list_start) {
va_new(extra->va_list);
extra->va_list_start = true;
}
va_add(controller_load_va_list, float *, controller_load_array->array);
va_add(extra->va_list, float *, extra->array->array);
for (entryp = &va_entries; *entryp; entryp = &(*entryp)->next);
for (entryp = &extra->va_entries; *entryp; entryp = &(*entryp)->next);
*entryp = malloc(sizeof(struct controller_load_va_entry));
(*entryp)->next = NULL;
(*entryp)->ptr = controller_load_array->array;
(*entryp)->ptr = extra->array->array;
free(controller_load_array);
controller_load_array = NULL;
free(extra->array);
extra->array = NULL;
}
void controller_load_var_add_int(int i)
void controller_load_var_add_int(int i, yyscan_t scanner)
{
if (!controller_load_va_list_start) {
va_new(controller_load_va_list);
controller_load_va_list_start = true;
struct controller_load_extra *extra = yyget_extra(scanner);
if (!extra->va_list_start) {
va_new(extra->va_list);
extra->va_list_start = true;
}
va_add(controller_load_va_list, int, i);
va_add(extra->va_list, int, i);
}
void controller_load_var_add_ul(unsigned long ul)
void controller_load_var_add_ul(unsigned long ul, yyscan_t scanner)
{
if (!controller_load_va_list_start) {
va_new(controller_load_va_list);
controller_load_va_list_start = true;
struct controller_load_extra *extra = yyget_extra(scanner);
if (!extra->va_list_start) {
va_new(extra->va_list);
extra->va_list_start = true;
}
va_add(controller_load_va_list, unsigned long, ul);
va_add(extra->va_list, unsigned long, ul);
}
void controller_load_var_clear(void)
void controller_load_var_clear(yyscan_t scanner)
{
struct controller_load_extra *extra = yyget_extra(scanner);
struct controller_load_va_entry *entry, *next;
for (entry = va_entries; entry; entry = next) {
for (entry = extra->va_entries; entry; entry = next) {
if (entry->ptr)
free(entry->ptr);
next = entry->next;
free(entry);
}
va_entries = NULL;
extra->va_entries = NULL;
if (controller_load_va_list_start) {
va_free(controller_load_va_list);
controller_load_va_list_start = false;
if (extra->va_list_start) {
va_free(extra->va_list);
extra->va_list_start = false;
}
}
......@@ -176,26 +194,46 @@ void controller_load_frequency(double frequency)
controller_sample_frequency_set(frequency);
}
static bool controller_load_use_string = false;
static char *controller_load_string = NULL;
static size_t controller_load_stringlen = 0;
static FILE *controller_load_input_file;
int controller_load_block_create(char *type, char *name, yyscan_t scanner)
{
struct controller_load_extra *extra = yyget_extra(scanner);
return controller_block_create(type, name, extra->va_list);
}
int controller_load_block_param_set(char *block, char *param, yyscan_t scanner)
{
struct controller_load_extra *extra = yyget_extra(scanner);
int controller_load_yy_input(char *buf, int *readbytes, int sizebytes)
return controller_block_param_set(block, param, extra->va_list);
}
void controller_load_include(char *file_name)
{
if (!controller_load_use_string) {
*readbytes = fread(buf, 1, sizebytes,
controller_load_input_file);
int r;
printf("Include '%s'\n", file_name);
r = controller_load(file_name);
printf("End of include '%s': %d\n", file_name, r);
}
int controller_load_yy_input(char *buf, int *readbytes, int sizebytes, yyscan_t scanner)
{
struct controller_load_extra *extra = yyget_extra(scanner);
if (!extra->use_string) {
*readbytes = fread(buf, 1, sizebytes, extra->input_file);
} else {
int copybytes;
copybytes = sizebytes;
if (copybytes > controller_load_stringlen)
copybytes = controller_load_stringlen;
if (copybytes > extra->stringlen)
copybytes = extra->stringlen;
*readbytes = copybytes;
memcpy(buf, controller_load_string, copybytes);
controller_load_string += copybytes;
controller_load_stringlen -= copybytes;
memcpy(buf, extra->string, copybytes);
extra->string += copybytes;
extra->stringlen -= copybytes;
}
return 0;
......@@ -205,6 +243,7 @@ int controller_load_yy_input(char *buf, int *readbytes, int sizebytes)
static int controller_load_shell(char *args, char *out, int *outlen)
{
int ret;
struct controller_load_extra extra;
yyscan_t scanner;
if (!args) {
......@@ -213,13 +252,17 @@ static int controller_load_shell(char *args, char *out, int *outlen)
return *outlen;
}
controller_load_string = args;
controller_load_stringlen = strlen(args);
controller_load_use_string = true;
extra.ret = 0;
extra.va_entries = NULL;
extra.va_list_start = false;
extra.array = NULL;
extra.use_string = true;
extra.stringlen = strlen(args);
extra.string = args;
printf("parsing: %s\n", args);
yylex_init(&scanner);
yylex_init_extra(&extra, &scanner);
ret = yyparse(scanner, NULL);
......@@ -236,41 +279,79 @@ static int controller_load_shell(char *args, char *out, int *outlen)
return *outlen;
}
static struct shell_cmd controller_cmd = {
"controller",
static int controller_load_file_shell(char *args, char *out, int *outlen)
{
int ret;
if (!args) {
*outlen = sprintf(out,
"no arguments\n");
return *outlen;
}
printf("loading: %s\n", args);
ret = controller_load(args);
if (ret) {
*outlen = sprintf(out,
"failed to load file\n");
} else {
*outlen = sprintf(out,
"parsed file\n");
}
return *outlen;
}
static struct shell_cmd controller_cmd[] = {
{ "controller",
"parse arguments as controller commands",
controller_load_shell
},
{ "controller_file",
"load controller commands from file",
controller_load_file_shell
}
};
int controller_load_shell_add(void)
{
int ret;
int ret = 0, i;
ret = shell_cmd_add(&controller_cmd);
for (i = 0; i < sizeof(controller_cmd)/sizeof(struct shell_cmd); i++) {
ret |= shell_cmd_add(&controller_cmd[i]);
}
return ret;
}
int controller_load(char *filename)
{
controller_load_filename = filename;
controller_load_ret = 0;
struct controller_load_extra extra;
extra.filename = filename;
extra.ret = 0;
extra.va_entries = NULL;
extra.va_list_start = false;
extra.array = NULL;
extra.use_string = false;
extra.stringlen = 0;
yyscan_t scanner;
controller_load_input_file = fopen(filename, "r");
if (!controller_load_input_file)
extra.input_file = fopen(filename, "r");
if (!extra.input_file)
return -1;
controller_load_use_string = false;
yylex_init(&scanner);
yylex_init_extra(&extra, &scanner);
controller_load_ret = yyparse(scanner, controller_load_input_file);
extra.ret = yyparse(scanner, extra.input_file);
yylex_destroy(scanner);
fclose(controller_load_input_file);
fclose(extra.input_file);
controller_block_link();
return controller_load_ret;
return extra.ret;
}
/*
Copyright Jeroen Vreeken (pe1rxq@amsat.org), 2009
Copyright Stichting C.A. Muller Radioastronomiestation, 2009
Copyright Jeroen Vreeken (pe1rxq@amsat.org), 2009, 2013
Copyright Stichting C.A. Muller Radioastronomiestation, 2009, 2013
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -22,22 +22,27 @@
#include <stdarg.h>
typedef void * yyscan_t;
int controller_load_shell_add(void);
int controller_load(char *filename);
int controller_load_yy_input(char *buf, int *readbytes, int sizebytes);
int controller_load_yy_input(char *buf, int *readbytes, int sizebytes, yyscan_t scanner);
void controller_load_var_add_str(char *string);
void controller_load_var_add_dbl(double dbl);
void controller_load_var_add_flt(float flt);
void controller_load_var_add_ul(unsigned long ul);
void controller_load_var_add_int(int i);
void controller_load_var_clear(void);
void controller_load_var_add_float_array_start(void);
void controller_load_var_add_float_array_end(void);
void controller_load_var_add_str(char *string, yyscan_t scanner);
void controller_load_var_add_dbl(double dbl, yyscan_t scanner);
void controller_load_var_add_flt(float flt, yyscan_t scanner);
void controller_load_var_add_ul(unsigned long ul, yyscan_t scanner);
void controller_load_var_add_int(int i, yyscan_t scanner);
void controller_load_var_clear(yyscan_t scanner);
void controller_load_var_add_float_array_start(yyscan_t scanner);
void controller_load_var_add_float_array_end(yyscan_t scanner);
void controller_load_frequency(double frequency);
void controller_load_include(char *file_name);
extern va_list controller_load_va_list;
int controller_load_block_create(char *type, char *name, yyscan_t scanner);
int controller_load_block_param_set(char *block, char *param, yyscan_t scanner);
#endif /* _INCLUDE_CONTROLLER_LOAD_H_ */
/*
Copyright Jeroen Vreeken (pe1rxq@amsat.org), 2009
Copyright Stichting C.A. Muller Radioastronomiestation, 2009
Copyright Jeroen Vreeken (pe1rxq@amsat.org), 2009, 2013
Copyright Stichting C.A. Muller Radioastronomiestation, 2009, 2013
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -29,7 +29,7 @@
#include "controller_load.h"
#undef YY_INPUT
#define YY_INPUT(buf,readbytes,sizebytes) controller_load_yy_input(buf,&readbytes,sizebytes)
#define YY_INPUT(buf,readbytes,sizebytes) controller_load_yy_input(buf,&readbytes,sizebytes, yyscanner)
%}
......@@ -64,6 +64,7 @@ boolcast "("[ \t]*"bool"[ \t]*")"
"links" { return LINKSSYM; }
"traces" { return TRACESSYM; }
"params" { return PARAMSSYM; }
"include" { return INCLUDESYM; }
{floatcast} { return FLOATCASTSYM; }
{doublecast} { return DOUBLECASTSYM; }
......
/*
Copyright Jeroen Vreeken (pe1rxq@amsat.org), 2009
Copyright Stichting C.A. Muller Radioastronomiestation, 2009
Copyright Jeroen Vreeken (pe1rxq@amsat.org), 2009, 2013
Copyright Stichting C.A. Muller Radioastronomiestation, 2009, 2013
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -58,6 +58,7 @@ void yyerror(yyscan_t *scanner, char const *s);
%token DOUBLECASTSYM
%token INTCASTSYM
%token BOOLCASTSYM
%token INCLUDESYM
%union
{
......@@ -78,6 +79,7 @@ ctrl : frequency
| blocks
| traces
| params
| include
;
frequency: FREQUENCYSYM DOUBLESYM
......@@ -86,6 +88,10 @@ frequency: FREQUENCYSYM DOUBLESYM
{ controller_load_frequency($2); }
;
include: INCLUDESYM STRINGSYM
{ controller_load_include($2); }
;
blocks : BLOCKSSYM BRACEOPENSYM blocklist BRACECLOSESYM
blocklist: block
......@@ -97,11 +103,11 @@ block : BRACEOPENSYM
STRINGSYM varlist
BRACECLOSESYM
{
if(controller_block_create($2, $4, controller_load_va_list))
if(controller_load_block_create($2, $4, scanner))
yyerror(scanner, "Error creating block");
free($2);
free($4);
controller_load_var_clear();
controller_load_var_clear(scanner);
}
;
......@@ -117,9 +123,9 @@ param : BRACEOPENSYM
varlist
BRACECLOSESYM
{
if (controller_block_param_set($2, $4, controller_load_va_list))
if (controller_load_block_param_set($2, $4, scanner))
yyerror(scanner, "Error setting parameter");
controller_load_var_clear();
controller_load_var_clear(scanner);
}
;
......@@ -128,31 +134,31 @@ varlist : /* varlist may be emtpy */
;
var : STRINGSYM
{ controller_load_var_add_str($1); }
{ controller_load_var_add_str($1, scanner); }
| FLOATCASTSYM DOUBLESYM
{ controller_load_var_add_flt($2); }
{ controller_load_var_add_flt($2, scanner); }
| FLOATCASTSYM INTSYM
{ controller_load_var_add_flt($2); }
{ controller_load_var_add_flt($2, scanner); }
| DOUBLESYM
{ controller_load_var_add_dbl($1); }
{ controller_load_var_add_dbl($1, scanner); }
| DOUBLECASTSYM DOUBLESYM
{ controller_load_var_add_dbl($2); }
{ controller_load_var_add_dbl($2, scanner); }
| DOUBLECASTSYM INTSYM
{ controller_load_var_add_dbl($2); }
{ controller_load_var_add_dbl($2, scanner); }
| BOOLSYM
{ controller_load_var_add_int($1); }
{ controller_load_var_add_int($1, scanner); }
| BOOLCASTSYM INTSYM
{ controller_load_var_add_int($2); }
{ controller_load_var_add_int($2, scanner); }
| INTSYM