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
dt_ctrl_sim
dt_ctrl.dot dt_ctrl.dot
dt_ctrl.pdf dt_ctrl.pdf
...@@ -11,16 +11,14 @@ LDFLAGS= -lpthread -lrt -lm -ldl -Wl,-E -L../common/lib -L./lib ...@@ -11,16 +11,14 @@ LDFLAGS= -lpthread -lrt -lm -ldl -Wl,-E -L../common/lib -L./lib
CFLAGS_SIM=-DUSE_AZ_SIM -DUSE_EL_SIM 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 -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 \ test \
controller controller
dt_ctrl: lib/libcontroller.la lib/libethercat.la lib/libdt_azimuth.la lib/libdt_elevation.la 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/libethercat.la: lib/libcontroller.la
lib/libdt_azimuth.la: lib/libcontroller.la lib/libdt_azimuth.la: lib/libcontroller.la
...@@ -28,11 +26,6 @@ lib/libdt_elevation.la: lib/libcontroller.la ...@@ -28,11 +26,6 @@ lib/libdt_elevation.la: lib/libcontroller.la
dt_ctrl: dt_ctrl.o 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 test: lib/libcontroller.la lib/libethercat.la lib/liblog.la
@echo " SUBDIR: $@" @echo " SUBDIR: $@"
...@@ -75,8 +68,7 @@ clean: ...@@ -75,8 +68,7 @@ clean:
rm -f *.o *.d *.a *.la *.lo lib/* rm -f *.o *.d *.a *.la *.lo lib/*
rm -f dt_az dt_az_ctrl \ rm -f dt_az dt_az_ctrl \
command_shell \ command_shell \
dt_ctrl \ dt_ctrl
dt_ctrl_sim
$(MAKE) -C controller clean $(MAKE) -C controller clean
$(MAKE) -C dt_azimuth clean $(MAKE) -C dt_azimuth clean
$(MAKE) -C dt_elevation clean $(MAKE) -C dt_elevation clean
......
...@@ -29,145 +29,163 @@ ...@@ -29,145 +29,163 @@
#include "../../common/include/dynarg.h" #include "../../common/include/dynarg.h"
#include <shell/shell.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) void yyerror(yyscan_t scanner, char const *s)
{ {
struct controller_load_extra *extra = yyget_extra(scanner);
fprintf(stderr, "%s:%d: %s\n", fprintf(stderr, "%s:%d: %s\n",
controller_load_filename, extra->filename,
yyget_lineno(scanner), yyget_lineno(scanner),
s); 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 {
struct controller_load_va_entry *next; struct controller_load_va_entry *next;
void *ptr; 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; struct controller_load_va_entry **entryp;
if (!controller_load_va_list_start) { if (!extra->va_list_start) {
va_new(controller_load_va_list); va_new(extra->va_list);
controller_load_va_list_start = true; 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 = malloc(sizeof(struct controller_load_va_entry));
(*entryp)->next = NULL; (*entryp)->next = NULL;
(*entryp)->ptr = string; (*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) { struct controller_load_extra *extra = yyget_extra(scanner);
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, double, dbl); va_add(extra->va_list, double, dbl);
} }
struct controller_load_array { void controller_load_var_add_flt(float flt, yyscan_t scanner)
void *array;
size_t size;
};
static struct controller_load_array *controller_load_array = NULL;
void controller_load_var_add_flt(float flt)
{ {
if (controller_load_array) { struct controller_load_extra *extra = yyget_extra(scanner);
controller_load_array->array = realloc(
controller_load_array->array, if (extra->array) {
controller_load_array->size + sizeof(float)); extra->array->array = realloc(
*(float*)(controller_load_array->array + controller_load_array->size) = flt; extra->array->array,
controller_load_array->size += sizeof(float); extra->array->size + sizeof(float));
*(float*)(extra->array->array + extra->array->size) = flt;
extra->array->size += sizeof(float);
} else { } else {
/* float is promoted to double in a variadic function */ /* 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)); struct controller_load_extra *extra = yyget_extra(scanner);
controller_load_array->array = NULL;
controller_load_array->size = 0; 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; struct controller_load_va_entry **entryp;
if (!controller_load_va_list_start) { if (!extra->va_list_start) {
va_new(controller_load_va_list); va_new(extra->va_list);
controller_load_va_list_start = true; 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 = malloc(sizeof(struct controller_load_va_entry));
(*entryp)->next = NULL; (*entryp)->next = NULL;
(*entryp)->ptr = controller_load_array->array; (*entryp)->ptr = extra->array->array;
free(controller_load_array); free(extra->array);
controller_load_array = NULL; 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) { struct controller_load_extra *extra = yyget_extra(scanner);
va_new(controller_load_va_list); if (!extra->va_list_start) {
controller_load_va_list_start = true; 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) { struct controller_load_extra *extra = yyget_extra(scanner);
va_new(controller_load_va_list); if (!extra->va_list_start) {
controller_load_va_list_start = true; 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; 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) if (entry->ptr)
free(entry->ptr); free(entry->ptr);
next = entry->next; next = entry->next;
free(entry); free(entry);
} }
va_entries = NULL; extra->va_entries = NULL;
if (controller_load_va_list_start) { if (extra->va_list_start) {
va_free(controller_load_va_list); va_free(extra->va_list);
controller_load_va_list_start = false; extra->va_list_start = false;
} }
} }
...@@ -176,26 +194,46 @@ void controller_load_frequency(double frequency) ...@@ -176,26 +194,46 @@ void controller_load_frequency(double frequency)
controller_sample_frequency_set(frequency); controller_sample_frequency_set(frequency);
} }
static bool controller_load_use_string = false; int controller_load_block_create(char *type, char *name, yyscan_t scanner)
static char *controller_load_string = NULL; {
static size_t controller_load_stringlen = 0; struct controller_load_extra *extra = yyget_extra(scanner);
static FILE *controller_load_input_file;
return controller_block_create(type, name, extra->va_list);
}
int controller_load_yy_input(char *buf, int *readbytes, int sizebytes) int controller_load_block_param_set(char *block, char *param, yyscan_t scanner)
{ {
if (!controller_load_use_string) { struct controller_load_extra *extra = yyget_extra(scanner);
*readbytes = fread(buf, 1, sizebytes,
controller_load_input_file); return controller_block_param_set(block, param, extra->va_list);
}
void controller_load_include(char *file_name)
{
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 { } else {
int copybytes; int copybytes;
copybytes = sizebytes; copybytes = sizebytes;
if (copybytes > controller_load_stringlen) if (copybytes > extra->stringlen)
copybytes = controller_load_stringlen; copybytes = extra->stringlen;
*readbytes = copybytes; *readbytes = copybytes;
memcpy(buf, controller_load_string, copybytes); memcpy(buf, extra->string, copybytes);
controller_load_string += copybytes; extra->string += copybytes;
controller_load_stringlen -= copybytes; extra->stringlen -= copybytes;
} }
return 0; return 0;
...@@ -205,6 +243,7 @@ int controller_load_yy_input(char *buf, int *readbytes, int sizebytes) ...@@ -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) static int controller_load_shell(char *args, char *out, int *outlen)
{ {
int ret; int ret;
struct controller_load_extra extra;
yyscan_t scanner; yyscan_t scanner;
if (!args) { if (!args) {
...@@ -213,13 +252,17 @@ static int controller_load_shell(char *args, char *out, int *outlen) ...@@ -213,13 +252,17 @@ static int controller_load_shell(char *args, char *out, int *outlen)
return *outlen; return *outlen;
} }
controller_load_string = args; extra.ret = 0;
controller_load_stringlen = strlen(args); extra.va_entries = NULL;
controller_load_use_string = true; extra.va_list_start = false;
extra.array = NULL;
extra.use_string = true;
extra.stringlen = strlen(args);
extra.string = args;
printf("parsing: %s\n", args); printf("parsing: %s\n", args);
yylex_init(&scanner); yylex_init_extra(&extra, &scanner);
ret = yyparse(scanner, NULL); ret = yyparse(scanner, NULL);
...@@ -236,41 +279,79 @@ static int controller_load_shell(char *args, char *out, int *outlen) ...@@ -236,41 +279,79 @@ static int controller_load_shell(char *args, char *out, int *outlen)
return *outlen; return *outlen;
} }
static struct shell_cmd controller_cmd = { static int controller_load_file_shell(char *args, char *out, int *outlen)
"controller", {
"parse arguments as controller commands", int ret;
controller_load_shell
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 controller_load_shell_add(void)
{ {
int ret; int ret = 0, i;
for (i = 0; i < sizeof(controller_cmd)/sizeof(struct shell_cmd); i++) {
ret |= shell_cmd_add(&controller_cmd[i]);
}
ret = shell_cmd_add(&controller_cmd);
return ret; return ret;
} }
int controller_load(char *filename) int controller_load(char *filename)
{ {
controller_load_filename = filename; struct controller_load_extra extra;
controller_load_ret = 0;
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; yyscan_t scanner;
controller_load_input_file = fopen(filename, "r"); extra.input_file = fopen(filename, "r");
if (!controller_load_input_file) if (!extra.input_file)
return -1; 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); yylex_destroy(scanner);
fclose(controller_load_input_file); fclose(extra.input_file);
controller_block_link(); controller_block_link();
return controller_load_ret; return extra.ret;
} }
/* /*
Copyright Jeroen Vreeken (pe1rxq@amsat.org), 2009 Copyright Jeroen Vreeken (pe1rxq@amsat.org), 2009, 2013
Copyright Stichting C.A. Muller Radioastronomiestation, 2009 Copyright Stichting C.A. Muller Radioastronomiestation, 2009, 2013
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
...@@ -22,22 +22,27 @@ ...@@ -22,22 +22,27 @@
#include <stdarg.h> #include <stdarg.h>
typedef void * yyscan_t;
int controller_load_shell_add(void); int controller_load_shell_add(void);
int controller_load(char *filename); 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_str(char *string, yyscan_t scanner);
void controller_load_var_add_dbl(double dbl); void controller_load_var_add_dbl(double dbl, yyscan_t scanner);
void controller_load_var_add_flt(float flt); void controller_load_var_add_flt(float flt, yyscan_t scanner);
void controller_load_var_add_ul(unsigned long ul); void controller_load_var_add_ul(unsigned long ul, yyscan_t scanner);
void controller_load_var_add_int(int i); void controller_load_var_add_int(int i, yyscan_t scanner);