#include <getopt.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <inttypes.h>
#include <limits.h>
#include <dlfcn.h>
static void
{
const char *progname = argv[0];
printf(
"Usage:\n"
"\t%s type-name1 [type-name2...]\n"
"\t\twill find type based on its name (ie: 'wallclock/minute').\n"
"\t\tor will try to query names in configuration files (ie: sol-flow*.json).\n"
"\n"
"\t%s --of-module=modname\n"
"\t%s -m=modname\n"
"\t\tlist all node types names built inside dynamic module modname (ie: 'iio')\n"
"\n"
"\t%s --builtins\n"
"\t%s -b\n"
"\t\tlist all node types names built inside libsoletta.\n"
"\n",
progname, progname, progname, progname, progname);
}
#ifndef SOL_NO_API_VERSION
#define CHECK_TYPE_API_VERSION(type, ...) \
do { \
if (type->api_version != SOL_FLOW_NODE_TYPE_API_VERSION) { \
fprintf(stderr, "ERROR: type=%p has api_version=%" PRIu16 \
" while %" PRIu16 " was expected.\n", \
type, type->api_version, SOL_FLOW_NODE_TYPE_API_VERSION); \
return __VA_ARGS__; \
} \
} while (0)
#else
#define CHECK_TYPE_API_VERSION(type, ...) do { } while (0)
#endif
#ifndef SOL_NO_API_VERSION
#define CHECK_TYPE_DESC_API_VERSION(type, ...) \
do { \
if (!type->description) { \
fprintf(stderr, "ERROR: type=%p has no description.\n", type); \
return __VA_ARGS__; \
} \
if (type->description->api_version != SOL_FLOW_NODE_TYPE_DESCRIPTION_API_VERSION) { \
fprintf(stderr, "ERROR: type=%p description->api_version=%" PRIu16 \
" while %" PRIu16 " was expected.\n", \
type, type->description->api_version, SOL_FLOW_NODE_TYPE_DESCRIPTION_API_VERSION); \
return __VA_ARGS__; \
} \
} while (0)
#else
#define CHECK_TYPE_DESC_API_VERSION(type, ...) do { } while (0)
#endif
static bool
{
const char *prefix = data;
printf("%s: %s\n", prefix, type->description->name);
return true;
}
static void
{
}
static void
{
void (*
foreach)(bool (*cb)(
void *data,
const struct sol_flow_node_type *type),
const void *data);
char install_rootdir[PATH_MAX], path[PATH_MAX];
void *h;
int r;
if (!modname || modname[0] == '\0')
return;
if (modname[0] == '.' || modname[0] == '/') {
size_t len = strlen(modname);
if (len >= sizeof(path)) {
fprintf(stderr, "ERROR: path is too long: %s\n", modname);
return;
}
memcpy(path, modname, len + 1);
goto load;
}
if (r < 0 || r >= (int)sizeof(install_rootdir)) {
fputs("ERROR: could not get libsoletta installation dir.\n", stderr);
return;
}
#ifndef MODULESDIR
#define MODULESDIR "/usr/lib/soletta/modules"
#endif
#ifndef FLOWMODULESDIR
#define FLOWMODULESDIR MODULESDIR "/flow"
#endif
install_rootdir, modname);
if (r < 0 || r >= (int)sizeof(install_rootdir)) {
fprintf(stderr,
"ERROR: path is too long %s" FLOWMODULESDIR "/%s.so\n",
install_rootdir, modname);
return;
}
load:
h = dlopen(path, RTLD_LAZY | RTLD_LOCAL);
if (!h) {
fprintf(stderr, "ERROR: could not load %s: %s\n",
path, dlerror());
return;
}
foreach = dlsym(h, "sol_flow_foreach_module_node_type");
if (!foreach) {
fprintf(stderr, "ERROR: could not find symbol "
"sol_flow_foreach_module_node_type() inside %s: %s\n",
path, dlerror());
goto end;
}
end:
dlclose(h);
}
static void
{
const struct sol_flow_node_type_description *tdesc;
tdesc = type->description;
printf(
"type {\n"
"\tname: %s\n"
"\tcetegory: %s\n"
"\tdescription: %s\n"
"\tauthor: %s\n"
"\turl: %s\n"
"\tlicense: %s\n"
"\tversion: %s\n",
tdesc->name,
tdesc->category,
tdesc->description,
tdesc->author,
tdesc->url,
tdesc->license,
tdesc->version);
if (tdesc->options) {
const struct sol_flow_node_options_description *odesc = tdesc->options;
const struct sol_flow_node_options_member_description *omemb;
printf(
"\toptions%s: [\n",
odesc->required ? " [required]" : "");
for (omemb = odesc->members; omemb->name != NULL; omemb++) {
printf("\t\t%s: %s%s # %s\n",
omemb->name, omemb->data_type,
omemb->required ? " [required]" : "",
omemb->description);
}
puts("\t]");
}
if (!tdesc->ports_in)
puts("\tports_in: none");
else {
const struct sol_flow_port_description *const *pdesc = tdesc->ports_in;
puts("\tports_in: [");
for (; *pdesc != NULL; pdesc++) {
const struct sol_flow_port_description *d = *pdesc;
printf("\t\t%s", d->name);
if (d->array_size)
printf("[%" PRIu16 "]", d->array_size);
printf(": %s%s # %s\n", d->data_type,
d->required ? " [required]" : "", d->description);
}
puts("\t]");
}
if (!tdesc->ports_out)
puts("\tports_out: none");
else {
const struct sol_flow_port_description *const *pdesc = tdesc->ports_out;
puts("\tports_out: [");
for (; *pdesc != NULL; pdesc++) {
const struct sol_flow_port_description *d = *pdesc;
printf("\t\t%s", d->name);
if (d->array_size)
printf("[%" PRIu16 "]", d->array_size);
printf(": %s%s # %s\n", d->data_type,
d->required ? " [required]" : "", d->description);
}
puts("\t]");
}
puts("}\n");
}
static void
{
const struct sol_flow_node_type_description *tdesc;
int err;
if (err < 0) {
&type, &resolved_opts);
if (err < 0) {
fprintf(stderr, "ERROR: Couldn't resolve type '%s'\n", name);
return;
}
}
tdesc = type->description;
printf("resolved '%s' as type=%p '%s'", name, type, tdesc->name);
if (resolved_opts.
count) {
itr_end = itr + resolved_opts.
count;
fputs(" options={", stdout);
for (; itr < itr_end; itr++) {
printf(
"%s=", itr->
name);
printf(
"%s", itr->
boolean ?
"true" :
"false");
break;
printf(
"%#" PRIx8, itr->
byte);
break;
printf("x:%g|y:%g|z:%g|min:%g|max:%g",
break;
printf("min:%g|max:%g|step:%g",
break;
break;
printf(
"%" PRId32, itr->
i);
break;
printf("min:%" PRId32 "|max:%" PRId32 "|step:%" PRId32,
break;
printf(
"red:%" PRId32 "|green:%" PRId32 "|blue:%" PRId32 "|"
"red_max:%" PRId32 "|green_max:%" PRId32 "|blue_max:%" PRId32,
break;
break;
default:
fprintf(stderr,
"\nERROR: doesn't suppport printing named option of type '%d'\n", itr->
type);
}
if (itr + 1 < itr_end)
fputs(", ", stdout);
}
putchar('}');
}
putchar('\n');
}
static void
{
static const struct option opts[] = {
{ "builtins", no_argument, NULL, 'b' },
{ "of-module", required_argument, NULL, 'm' },
{ "help", no_argument, NULL, 'h' },
{ 0, 0, 0, 0 }
};
while ((c = getopt_long(argc, argv, "brm:h", opts, &opt_idx)) != -1) {
switch (c) {
case 'b':
break;
case 'm':
break;
case 'h':
return;
default:
return;
}
}
for (c = optind; c < argc; c++)
}
static void
{
}