Skip to content

Commit

Permalink
Use new input API.
Browse files Browse the repository at this point in the history
  • Loading branch information
biot committed Aug 28, 2014
1 parent f99038b commit a8b4041
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 107 deletions.
4 changes: 3 additions & 1 deletion doc/sigrok-cli.1
Original file line number Diff line number Diff line change
Expand Up @@ -379,11 +379,13 @@ need a serial port specified:
$
.B "sigrok\-cli \-\-driver ols:conn=/dev/ttyACM0 \-\-show
.sp
This also works for protocol decoders and output modules:
This also works for protocol decoders, input modules and output modules:
.sp
$
.B "sigrok\-cli \-\-protocol\-decoders i2c \-\-show
$
.B "sigrok\-cli \-\-input\-format csv \-\-show
$
.B "sigrok\-cli \-\-output\-format bits \-\-show
.TP
.B "\-\-scan"
Expand Down
174 changes: 74 additions & 100 deletions input.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,140 +19,114 @@

#include "sigrok-cli.h"
#include "config.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <glib.h>

/**
* Return the input file format which the CLI tool should use.
*
* If the user specified -I / --input-format, use that one. Otherwise, try to
* autodetect the format as good as possible. Failing that, return NULL.
*
* @param filename The filename of the input file. Must not be NULL.
* @param opt The -I / --input-file option the user specified (or NULL).
*
* @return A pointer to the 'struct sr_input_format' that should be used,
* or NULL if no input format was selected or auto-detected.
*/
static struct sr_input_format *determine_input_file_format(
const char *filename, const char *opt)
{
int i;
struct sr_input_format **inputs;

/* If there are no input formats, return NULL right away. */
inputs = sr_input_list();
if (!inputs) {
g_critical("No supported input formats available.");
return NULL;
}

/* If the user specified -I / --input-format, use that one. */
if (opt) {
for (i = 0; inputs[i]; i++) {
if (strcasecmp(inputs[i]->id, opt))
continue;
g_debug("Using user-specified input file format '%s'.",
inputs[i]->id);
return inputs[i];
}

/* The user specified an unknown input format, return NULL. */
g_critical("Error: specified input file format '%s' is "
"unknown.", opt);
return NULL;
}

/* Otherwise, try to find an input module that can handle this file. */
for (i = 0; inputs[i]; i++) {
if (inputs[i]->format_match(filename))
break;
}

/* Return NULL if no input module wanted to touch this. */
if (!inputs[i]) {
g_critical("Error: no matching input module found.");
return NULL;
}

g_debug("cli: Autodetected '%s' input format for file '%s'.",
inputs[i]->id, filename);

return inputs[i];
}
#define BUFSIZE 16384

static void load_input_file_format(void)
static void load_input_file_module(void)
{
GHashTable *fmtargs = NULL;
struct stat st;
struct sr_session *session;
struct sr_input *in;
struct sr_input_format *input_format;
char *fmtspec = NULL;
const struct sr_input *in;
const struct sr_input_module *imod;
const struct sr_option **options;
struct sr_dev_inst *sdi;
GHashTable *mod_args, *mod_opts;
GString *buf;
int fd;
ssize_t len;
char *mod_id;

if (opt_input_format) {
fmtargs = parse_generic_arg(opt_input_format, TRUE);
fmtspec = g_hash_table_lookup(fmtargs, "sigrok_key");
}
if (!sr_input_list())
g_critical("No supported input formats available.");

if (!(input_format = determine_input_file_format(opt_input_file,
fmtspec))) {
/* The exact cause was already logged. */
return;
mod_id = NULL;
mod_args = NULL;
if (opt_input_format) {
mod_args = parse_generic_arg(opt_input_format, TRUE);
mod_id = g_hash_table_lookup(mod_args, "sigrok_key");
}

if (fmtargs)
g_hash_table_remove(fmtargs, "sigrok_key");

if (stat(opt_input_file, &st) == -1) {
g_critical("Failed to load %s: %s", opt_input_file,
strerror(errno));
exit(1);
buf = g_string_sized_new(BUFSIZE);
if (mod_id) {
/* User specified an input module to use. */
if (!(imod = sr_input_find(mod_id)))
g_critical("Error: unknown input module '%s'.", mod_id);
g_hash_table_remove(mod_args, "sigrok_key");
if ((options = sr_input_options_get(imod))) {
mod_opts = generic_arg_to_opt(options, mod_args);
sr_output_options_free(options);
} else
mod_opts = NULL;
if (!(in = sr_input_new(imod, mod_opts)))
g_critical("Error: failed to initialize input module.");
if (mod_opts)
g_hash_table_destroy(mod_opts);
if (mod_args)
g_hash_table_destroy(mod_args);
if ((fd = open(opt_input_file, O_RDONLY)) == -1)
g_critical("Failed to load %s: %s.", opt_input_file,
strerror(errno));
} else {
/* Let the input modules try to identify the file. */
if ((fd = open(opt_input_file, O_RDONLY)) == -1)
g_critical("Failed to load %s: %s.", opt_input_file,
strerror(errno));
if ((len = read(fd, buf->str, BUFSIZE)) < 1)
g_critical("Failed to read %s: %s.", opt_input_file,
strerror(errno));
buf->len = len;
if (!(in = sr_input_scan_buffer(buf)))
g_critical("Error: no input module found for this file.");
}
sdi = sr_input_dev_inst_get(in);

/* Initialize the input module. */
if (!(in = g_try_malloc(sizeof(struct sr_input)))) {
g_critical("Failed to allocate input module.");
exit(1);
}
in->format = input_format;
in->param = fmtargs;
if (in->format->init) {
if (in->format->init(in, opt_input_file) != SR_OK) {
g_critical("Input format init failed.");
exit(1);
}
}

if (select_channels(in->sdi) != SR_OK)
if (select_channels(sdi) != SR_OK)
return;

sr_session_new(&session);
sr_session_datafeed_callback_add(session, &datafeed_in, NULL);
if (sr_session_dev_add(session, in->sdi) != SR_OK) {
if (sr_session_dev_add(session, sdi) != SR_OK) {
g_critical("Failed to use device.");
sr_session_destroy(session);
return;
}

input_format->loadfile(in, opt_input_file);
while(TRUE) {
g_string_truncate(buf, 0);
len = read(fd, buf->str, BUFSIZE);
if (len < 0)
g_critical("Read failed: %s", strerror(errno));
buf->len = len;
if (sr_input_send(in, buf) != SR_OK)
break;
if (len < BUFSIZE)
break;
}
sr_input_free(in);
g_string_free(buf, TRUE);

sr_session_destroy(session);

if (fmtargs)
g_hash_table_destroy(fmtargs);
}

void load_input_file(void)
{
GSList *devices;
struct sr_session *session;
struct sr_dev_inst *sdi;
GSList *devices;
struct stat st;
int ret;

if (stat(opt_input_file, &st) == -1)
g_critical("Failed to load %s: %s.", opt_input_file, strerror(errno));

if (sr_session_load(opt_input_file, &session) == SR_OK) {
/* sigrok session file */
ret = sr_session_dev_list(session, &devices);
Expand All @@ -173,6 +147,6 @@ void load_input_file(void)
}
else {
/* fall back on input modules */
load_input_file_format();
load_input_file_module();
}
}
2 changes: 2 additions & 0 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,8 @@ int main(int argc, char **argv)

if (opt_version)
show_version();
else if (opt_input_format && opt_show)
show_input();
else if (opt_output_format && opt_show)
show_output();
else if (opt_scan_devs)
Expand Down
52 changes: 46 additions & 6 deletions show.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,8 @@

static gint sort_inputs(gconstpointer a, gconstpointer b)
{
const struct sr_input_format *ia = a, *ib = b;

return strcmp(ia->id, ib->id);
return strcmp(sr_input_id_get((struct sr_input_module *)a),
sr_input_id_get((struct sr_input_module *)b));
}

static gint sort_outputs(gconstpointer a, gconstpointer b)
Expand Down Expand Up @@ -53,7 +52,7 @@ static gint sort_pds(gconstpointer a, gconstpointer b)
void show_version(void)
{
struct sr_dev_driver **drivers, *driver;
struct sr_input_format **inputs, *input;
const struct sr_input_module **inputs, *input;
const struct sr_output_module **outputs, *output;
const GSList *l;
GSList *sl;
Expand Down Expand Up @@ -86,11 +85,12 @@ void show_version(void)
printf("Supported input formats:\n");
inputs = sr_input_list();
for (sl = NULL, i = 0; inputs[i]; i++)
sl = g_slist_append(sl, inputs[i]);
sl = g_slist_append(sl, (gpointer)inputs[i]);
sl = g_slist_sort(sl, sort_inputs);
for (l = sl; l; l = l->next) {
input = l->data;
printf(" %-20s %s\n", input->id, input->description);
printf(" %-20s %s\n", sr_input_id_get(input),
sr_input_description_get(input));
}
printf("\n");
g_slist_free(sl);
Expand Down Expand Up @@ -644,6 +644,46 @@ void show_pd_detail(void)
}
#endif

void show_input(void)
{
const struct sr_input_module *imod;
const struct sr_option **opts;
GSList *l;
int i;
char *s, **tok;

tok = g_strsplit(opt_input_format, ":", 0);
if (!tok[0] || !(imod = sr_input_find(tok[0])))
g_critical("Input module '%s' not found.", opt_input_format);

printf("ID: %s\nName: %s\n", sr_input_id_get(imod),
sr_input_name_get(imod));
printf("Description: %s\n", sr_input_description_get(imod));
if ((opts = sr_input_options_get(imod))) {
printf("Options:\n");
for (i = 0; opts[i]; i++) {
printf(" %s: %s", opts[i]->id, opts[i]->desc);
if (opts[i]->def) {
s = g_variant_print(opts[i]->def, FALSE);
printf(" (default %s", s);
g_free(s);
if (opts[i]->values) {
printf(", possible values ");
for (l = opts[i]->values; l; l = l->next) {
s = g_variant_print((GVariant *)l->data, FALSE);
printf("%s%s", s, l->next ? ", " : "");
g_free(s);
}
}
printf(")");
}
printf("\n");
}
sr_input_options_free(opts);
}
g_strfreev(tok);
}

void show_output(void)
{
const struct sr_output_module *omod;
Expand Down
1 change: 1 addition & 0 deletions sigrok-cli.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ void show_version(void);
void show_dev_list(void);
void show_dev_detail(void);
void show_pd_detail(void);
void show_input(void);
void show_output(void);

/* device.c */
Expand Down

0 comments on commit a8b4041

Please sign in to comment.