mirror of
https://git.rwth-aachen.de/acs/public/villas/node/
synced 2025-03-09 00:00:00 +01:00
add new option to command line utilities to specify signal type
This commit is contained in:
parent
49fd6d89f5
commit
4a5b0b65b2
9 changed files with 118 additions and 30 deletions
|
@ -82,7 +82,7 @@ struct io {
|
|||
|
||||
int io_init(struct io *io, const struct format_type *fmt, struct vlist *signals, int flags);
|
||||
|
||||
int io_init2(struct io *io, const struct format_type *fmt, enum signal_type type, int len, int flags);
|
||||
int io_init2(struct io *io, const struct format_type *fmt, const char *dt, int flags);
|
||||
|
||||
int io_destroy(struct io *io);
|
||||
|
||||
|
|
|
@ -109,11 +109,14 @@ int signal_list_init(struct vlist *list);
|
|||
int signal_list_destroy(struct vlist *list);
|
||||
int signal_list_parse(struct vlist *list, json_t *cfg);
|
||||
int signal_list_generate(struct vlist *list, unsigned len, enum signal_type fmt);
|
||||
int signal_list_generate2(struct vlist *list, const char *dt);
|
||||
void signal_list_dump(const struct vlist *list, const union signal_data *data, int len);
|
||||
int signal_list_copy(struct vlist *dst, const struct vlist *src);
|
||||
|
||||
enum signal_type signal_type_from_str(const char *str);
|
||||
|
||||
enum signal_type signal_type_from_fmtstr(char c);
|
||||
|
||||
const char * signal_type_to_str(enum signal_type fmt);
|
||||
|
||||
enum signal_type signal_type_detect(const char *val);
|
||||
|
|
4
lib/io.c
4
lib/io.c
|
@ -109,7 +109,7 @@ int io_init(struct io *io, const struct format_type *fmt, struct vlist *signals,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int io_init2(struct io *io, const struct format_type *fmt, enum signal_type type, int len, int flags)
|
||||
int io_init2(struct io *io, const struct format_type *fmt, const char *dt, int flags)
|
||||
{
|
||||
int ret;
|
||||
struct vlist *signals;
|
||||
|
@ -121,7 +121,7 @@ int io_init2(struct io *io, const struct format_type *fmt, enum signal_type type
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = signal_list_generate(signals, len, type);
|
||||
ret = signal_list_generate2(signals, dt);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
|
@ -126,8 +126,15 @@ int node_direction_parse(struct node_direction *nd, struct node *n, json_t *cfg)
|
|||
if (ret)
|
||||
error("Failed to parse signal definition of node %s", node_name(n));
|
||||
}
|
||||
else if (json_is_string(json_signals)) {
|
||||
const char *dt = json_string_value(json_signals);
|
||||
|
||||
ret = signal_list_generate2(&nd->signals, dt);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
else {
|
||||
int count = DEFAULT_SAMPLE_LENGTH;
|
||||
int count = 64;
|
||||
const char *type_str = "float";
|
||||
|
||||
if (json_is_object(json_signals)) {
|
||||
|
@ -137,13 +144,15 @@ int node_direction_parse(struct node_direction *nd, struct node *n, json_t *cfg)
|
|||
);
|
||||
}
|
||||
else
|
||||
warning("No signal definition found for node %s. Using the default config of %d floating point signals.", node_name(n), DEFAULT_SAMPLE_LENGTH);
|
||||
warning("No signal definition found for node %s. Using the default config of 64 floating point signals.", node_name(n));
|
||||
|
||||
int type = signal_type_from_str(type_str);
|
||||
if (type < 0)
|
||||
error("Invalid signal type %s", type_str);
|
||||
|
||||
signal_list_generate(&nd->signals, count, type);
|
||||
ret = signal_list_generate(&nd->signals, count, type);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef WITH_HOOKS
|
||||
|
|
56
lib/signal.c
56
lib/signal.c
|
@ -261,13 +261,14 @@ int signal_list_parse(struct vlist *list, json_t *cfg)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int signal_list_generate(struct vlist *list, unsigned len, enum signal_type fmt)
|
||||
int signal_list_generate(struct vlist *list, unsigned len, enum signal_type typ)
|
||||
{
|
||||
char name[32];
|
||||
|
||||
for (int i = 0; i < len; i++) {
|
||||
char name[32];
|
||||
snprintf(name, sizeof(name), "signal%d", i);
|
||||
|
||||
struct signal *sig = signal_create(name, NULL, fmt);
|
||||
struct signal *sig = signal_create(name, NULL, typ);
|
||||
if (!sig)
|
||||
return -1;
|
||||
|
||||
|
@ -277,6 +278,35 @@ int signal_list_generate(struct vlist *list, unsigned len, enum signal_type fmt)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int signal_list_generate2(struct vlist *list, const char *dt)
|
||||
{
|
||||
int len, i = 0;
|
||||
char name[32], *e;
|
||||
enum signal_type typ;
|
||||
|
||||
for (const char *t = dt; *t; t = e + 1) {
|
||||
len = strtoul(t, &e, 10);
|
||||
if (t == e)
|
||||
len = 1;
|
||||
|
||||
typ = signal_type_from_fmtstr(*e);
|
||||
if (typ == SIGNAL_TYPE_INVALID)
|
||||
return -1;
|
||||
|
||||
for (int j = 0; j < len; j++) {
|
||||
snprintf(name, sizeof(name), "signal%d", i++);
|
||||
|
||||
struct signal *sig = signal_create(name, NULL, typ);
|
||||
if (!sig)
|
||||
return -1;
|
||||
|
||||
vlist_push(list, sig);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void signal_list_dump(const struct vlist *list, const union signal_data *data, int len)
|
||||
{
|
||||
debug(5, " Signals:");
|
||||
|
@ -339,6 +369,26 @@ enum signal_type signal_type_from_str(const char *str)
|
|||
return SIGNAL_TYPE_INVALID;
|
||||
}
|
||||
|
||||
enum signal_type signal_type_from_fmtstr(char c)
|
||||
{
|
||||
switch (c) {
|
||||
case 'f':
|
||||
return SIGNAL_TYPE_FLOAT;
|
||||
|
||||
case 'i':
|
||||
return SIGNAL_TYPE_INTEGER;
|
||||
|
||||
case 'c':
|
||||
return SIGNAL_TYPE_COMPLEX;
|
||||
|
||||
case 'b':
|
||||
return SIGNAL_TYPE_BOOLEAN;
|
||||
|
||||
default:
|
||||
return SIGNAL_TYPE_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
const char * signal_type_to_str(enum signal_type fmt)
|
||||
{
|
||||
switch (fmt) {
|
||||
|
|
|
@ -42,6 +42,7 @@ static void usage()
|
|||
<< " OPTIONS are:" << std::endl
|
||||
<< " -i FMT set the input format" << std::endl
|
||||
<< " -o FMT set the output format" << std::endl
|
||||
<< " -t DT the data-type format string" << std::endl
|
||||
<< " -d LVL set debug log level to LVL" << std::endl
|
||||
<< " -h show this usage information" << std::endl
|
||||
<< " -V show the version of the tool" << std::endl << std::endl;
|
||||
|
@ -54,10 +55,11 @@ int main(int argc, char *argv[])
|
|||
int ret;
|
||||
const char *input_format = "villas.human";
|
||||
const char *output_format = "villas.human";
|
||||
const char *dtypes = "64f";
|
||||
|
||||
/* Parse optional command line arguments */
|
||||
int c;
|
||||
while ((c = getopt(argc, argv, "Vhd:i:o:")) != -1) {
|
||||
while ((c = getopt(argc, argv, "Vhd:i:o:t:")) != -1) {
|
||||
switch (c) {
|
||||
case 'V':
|
||||
print_version();
|
||||
|
@ -71,6 +73,10 @@ int main(int argc, char *argv[])
|
|||
output_format = optarg;
|
||||
break;
|
||||
|
||||
case 't':
|
||||
dtypes = optarg;
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
logging.setLevel(optarg);
|
||||
break;
|
||||
|
@ -87,7 +93,7 @@ int main(int argc, char *argv[])
|
|||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
struct format_type *fmt;
|
||||
struct format_type *ft;
|
||||
struct io input = { .state = STATE_DESTROYED };
|
||||
struct io output = { .state = STATE_DESTROYED };
|
||||
|
||||
|
@ -100,11 +106,11 @@ int main(int argc, char *argv[])
|
|||
};
|
||||
|
||||
for (unsigned i = 0; i < ARRAY_LEN(dirs); i++) {
|
||||
fmt = format_type_lookup(dirs[i].name);
|
||||
if (!fmt)
|
||||
ft = format_type_lookup(dirs[i].name);
|
||||
if (!ft)
|
||||
throw RuntimeError("Invalid format: {}", dirs[i].name);
|
||||
|
||||
ret = io_init2(dirs[i].io, fmt, SIGNAL_TYPE_FLOAT, DEFAULT_SAMPLE_LENGTH, SAMPLE_HAS_ALL);
|
||||
ret = io_init2(dirs[i].io, ft, dtypes, SAMPLE_HAS_ALL);
|
||||
if (ret)
|
||||
throw RuntimeError("Failed to initialize IO: {}", dirs[i].name);
|
||||
|
||||
|
|
|
@ -60,6 +60,7 @@ static void usage()
|
|||
<< " PARAM* a string of configuration settings for the hook" << std::endl
|
||||
<< " OPTIONS is one or more of the following options:" << std::endl
|
||||
<< " -f FMT the data format" << std::endl
|
||||
<< " -t DT the data-type format string" << std::endl
|
||||
<< " -d LVL set debug level to LVL" << std::endl
|
||||
<< " -v CNT process CNT smps at once" << std::endl
|
||||
<< " -h show this help" << std::endl
|
||||
|
@ -84,6 +85,7 @@ int main(int argc, char *argv[])
|
|||
{
|
||||
int ret, recv, sent, cnt;
|
||||
const char *format = "villas.human";
|
||||
const char *dtypes = "64f";
|
||||
|
||||
struct format_type *ft;
|
||||
struct hook_type *ht;
|
||||
|
@ -103,7 +105,7 @@ int main(int argc, char *argv[])
|
|||
/* Parse optional command line arguments */
|
||||
int c;
|
||||
char *endptr;
|
||||
while ((c = getopt(argc, argv, "Vhv:d:f:o:")) != -1) {
|
||||
while ((c = getopt(argc, argv, "Vhv:d:f:t:o:")) != -1) {
|
||||
switch (c) {
|
||||
case 'V':
|
||||
print_version();
|
||||
|
@ -113,6 +115,10 @@ int main(int argc, char *argv[])
|
|||
format = optarg;
|
||||
break;
|
||||
|
||||
case 't':
|
||||
dtypes = optarg;
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
cnt = strtoul(optarg, &endptr, 0);
|
||||
goto check;
|
||||
|
@ -169,7 +175,7 @@ check: if (optarg == endptr)
|
|||
if (!ft)
|
||||
throw RuntimeError("Unknown IO format '{}'", format);
|
||||
|
||||
ret = io_init2(&io, ft, SIGNAL_TYPE_FLOAT, DEFAULT_SAMPLE_LENGTH, SAMPLE_HAS_ALL);
|
||||
ret = io_init2(&io, ft, dtypes, SAMPLE_HAS_ALL);
|
||||
if (ret)
|
||||
throw RuntimeError("Failed to initialize IO");
|
||||
|
||||
|
|
|
@ -127,11 +127,12 @@ static void usage()
|
|||
<< " NODE the name of the node to which samples are sent and received from" << std::endl
|
||||
<< " OPTIONS are:" << std::endl
|
||||
<< " -f FMT set the format" << std::endl
|
||||
<< " -t DT the data-type format string" << std::endl
|
||||
<< " -o OPTION=VALUE overwrite options in config file" << std::endl
|
||||
<< " -x swap read / write endpoints" << std::endl
|
||||
<< " -s only read data from stdin and send it to node" << std::endl
|
||||
<< " -r only read data from node and write it to stdout" << std::endl
|
||||
<< " -t NUM terminate after NUM seconds" << std::endl
|
||||
<< " -T NUM terminate after NUM seconds" << std::endl
|
||||
<< " -L NUM terminate after NUM samples sent" << std::endl
|
||||
<< " -l NUM terminate after NUM samples received" << std::endl
|
||||
<< " -h show this usage information" << std::endl
|
||||
|
@ -253,6 +254,7 @@ int main(int argc, char *argv[])
|
|||
int ret, timeout = 0;
|
||||
bool reverse = false;
|
||||
const char *format = "villas.human";
|
||||
const char *dtypes = "64f";
|
||||
|
||||
struct node *node;
|
||||
static struct io io = { .state = STATE_DESTROYED };
|
||||
|
@ -268,7 +270,7 @@ int main(int argc, char *argv[])
|
|||
/* Parse optional command line arguments */
|
||||
int c;
|
||||
char *endptr;
|
||||
while ((c = getopt(argc, argv, "Vhxrsd:l:L:t:f:o:")) != -1) {
|
||||
while ((c = getopt(argc, argv, "Vhxrsd:l:L:T:f:t:o:")) != -1) {
|
||||
switch (c) {
|
||||
case 'V':
|
||||
print_version();
|
||||
|
@ -278,6 +280,10 @@ int main(int argc, char *argv[])
|
|||
format = optarg;
|
||||
break;
|
||||
|
||||
case 't':
|
||||
dtypes = optarg;
|
||||
break;
|
||||
|
||||
case 'x':
|
||||
reverse = true;
|
||||
break;
|
||||
|
@ -298,7 +304,7 @@ int main(int argc, char *argv[])
|
|||
limit_send = strtoul(optarg, &endptr, 10);
|
||||
goto check;
|
||||
|
||||
case 't':
|
||||
case 'T':
|
||||
timeout = strtoul(optarg, &endptr, 10);
|
||||
goto check;
|
||||
|
||||
|
@ -333,7 +339,7 @@ check: if (optarg == endptr)
|
|||
|
||||
char *uri = argv[optind];
|
||||
char *nodestr = argv[optind+1];
|
||||
struct format_type *fmt;
|
||||
struct format_type *ft;
|
||||
|
||||
ret = memory_init(0);
|
||||
if (ret)
|
||||
|
@ -351,11 +357,11 @@ check: if (optarg == endptr)
|
|||
else
|
||||
logger->warn("No configuration file specified. Starting unconfigured. Use the API to configure this instance.");
|
||||
|
||||
fmt = format_type_lookup(format);
|
||||
if (!fmt)
|
||||
ft = format_type_lookup(format);
|
||||
if (!ft)
|
||||
throw RuntimeError("Invalid format: {}", format);
|
||||
|
||||
ret = io_init2(&io, fmt, SIGNAL_TYPE_FLOAT, DEFAULT_SAMPLE_LENGTH, SAMPLE_HAS_ALL);
|
||||
ret = io_init2(&io, ft, dtypes, SAMPLE_HAS_ALL);
|
||||
if (ret)
|
||||
throw RuntimeError("Failed to initialize IO");
|
||||
|
||||
|
|
|
@ -47,15 +47,17 @@ public:
|
|||
|
||||
struct io io;
|
||||
struct format_type *format;
|
||||
const char *dtypes;
|
||||
|
||||
Side(const std::string &pth, struct format_type *fmt, struct pool *p) :
|
||||
Side(const std::string &pth, struct format_type *fmt, const char *dt, struct pool *p) :
|
||||
path(pth),
|
||||
format(fmt)
|
||||
format(fmt),
|
||||
dtypes(dt)
|
||||
{
|
||||
int ret;
|
||||
|
||||
io.state = STATE_DESTROYED;
|
||||
ret = io_init2(&io, format, SIGNAL_TYPE_FLOAT, DEFAULT_SAMPLE_LENGTH, 0);
|
||||
ret = io_init2(&io, format, dtypes, 0);
|
||||
if (ret)
|
||||
throw RuntimeError("Failed to initialize IO");
|
||||
|
||||
|
@ -96,9 +98,10 @@ void usage()
|
|||
<< " -d LVL adjust the debug level" << std::endl
|
||||
<< " -e EPS set epsilon for floating point comparisons to EPS" << std::endl
|
||||
<< " -v ignore data values" << std::endl
|
||||
<< " -t ignore timestamp" << std::endl
|
||||
<< " -T ignore timestamp" << std::endl
|
||||
<< " -s ignore sequence no" << std::endl
|
||||
<< " -f FMT file format for all files" << std::endl
|
||||
<< " -t DT the data-type format string" << std::endl
|
||||
<< " -h show this usage information" << std::endl
|
||||
<< " -V show the version of the tool" << std::endl << std::endl
|
||||
<< "Return codes:" << std::endl
|
||||
|
@ -119,6 +122,7 @@ int main(int argc, char *argv[])
|
|||
/* Default values */
|
||||
double epsilon = 1e-9;
|
||||
const char *format = "villas.human";
|
||||
const char *dtypes = "64f";
|
||||
int flags = SAMPLE_HAS_SEQUENCE | SAMPLE_HAS_DATA | SAMPLE_HAS_TS_ORIGIN;
|
||||
|
||||
struct pool pool = { .state = STATE_DESTROYED };
|
||||
|
@ -126,7 +130,7 @@ int main(int argc, char *argv[])
|
|||
/* Parse Arguments */
|
||||
int c;
|
||||
char *endptr;
|
||||
while ((c = getopt (argc, argv, "he:vtsf:Vd:")) != -1) {
|
||||
while ((c = getopt (argc, argv, "he:vTsf:t:Vd:")) != -1) {
|
||||
switch (c) {
|
||||
case 'e':
|
||||
epsilon = strtod(optarg, &endptr);
|
||||
|
@ -136,7 +140,7 @@ int main(int argc, char *argv[])
|
|||
flags &= ~SAMPLE_HAS_DATA;
|
||||
break;
|
||||
|
||||
case 't':
|
||||
case 'T':
|
||||
flags &= ~SAMPLE_HAS_TS_ORIGIN;
|
||||
break;
|
||||
|
||||
|
@ -148,6 +152,10 @@ int main(int argc, char *argv[])
|
|||
format = optarg;
|
||||
break;
|
||||
|
||||
case 't':
|
||||
dtypes = optarg;
|
||||
break;
|
||||
|
||||
case 'V':
|
||||
print_version();
|
||||
exit(EXIT_SUCCESS);
|
||||
|
@ -191,7 +199,7 @@ check: if (optarg == endptr)
|
|||
|
||||
/* Open files */
|
||||
for (int i = 0; i < n; i++)
|
||||
s[i] = new Side(argv[optind + i], fmt, &pool);
|
||||
s[i] = new Side(argv[optind + i], fmt, dtypes, &pool);
|
||||
|
||||
line = 0;
|
||||
for (;;) {
|
||||
|
|
Loading…
Add table
Reference in a new issue