*/
#include "gpiod.h"
+#include "tools-common.h"
#include <stdio.h>
#include <string.h>
-
-/* REVISIT This program needs a nicer, better formatted output. */
+#include <getopt.h>
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x)))
},
};
-int main(int argc, char **argv)
+static const struct option longopts[] = {
+ { "help", no_argument, NULL, 'h' },
+ { 0 },
+};
+
+static const char *const shortopts = "+h";
+
+static void print_help(void)
+{
+ printf("Usage: %s <options> [GPIOCHIP1...]\n", get_progname());
+ printf("List all lines of a GPIO chip.\n");
+ printf("Options:\n");
+ printf(" -h, --help:\t\tdisplay this message and exit\n");
+}
+
+static void list_lines(struct gpiod_chip *chip)
{
- int i, direction, flag_printed, active_state;
+ int direction, active_state;
struct gpiod_line_iter iter;
const char *name, *consumer;
struct gpiod_line *line;
- struct gpiod_chip *chip;
- unsigned int j;
-
- for (i = 1; i < argc; i++) {
- chip = gpiod_chip_open_lookup(argv[i]);
- if (!chip) {
- fprintf(stderr,
- "%s: unable to access %s: %s\n",
- argv[0], argv[i],
- gpiod_strerror(gpiod_errno()));
- continue;
+ bool flag_printed;
+ unsigned int i;
+
+ printf("%s - %u lines:\n",
+ gpiod_chip_name(chip), gpiod_chip_num_lines(chip));
+
+ gpiod_line_iter_init(&iter, chip);
+ gpiod_foreach_line(&iter, line) {
+ name = gpiod_line_name(line);
+ consumer = gpiod_line_consumer(line);
+ direction = gpiod_line_direction(line);
+ active_state = gpiod_line_active_state(line);
+
+ printf("\tline %2u: ", gpiod_line_offset(line));
+
+ if (name)
+ printf("\"%s\"", name);
+ else
+ printf("unnamed");
+ printf(" ");
+
+ if (consumer)
+ printf("\"%s\"", consumer);
+ else
+ printf("unused");
+ printf(" ");
+
+ printf("%s ", direction == GPIOD_DIRECTION_INPUT
+ ? "input" : "output");
+ printf("%s ", active_state == GPIOD_ACTIVE_STATE_LOW
+ ? "active-low"
+ : "active-high");
+
+ flag_printed = false;
+ for (i = 0; i < ARRAY_SIZE(flags); i++) {
+ if (flags[i].is_set(line)) {
+ if (flag_printed)
+ printf(" ");
+ else
+ printf("[");
+ printf("%s", flags[i].name);
+ flag_printed = true;
+ }
}
+ if (flag_printed)
+ printf("]");
- printf("%s - %u lines:\n",
- gpiod_chip_name(chip), gpiod_chip_num_lines(chip));
-
- gpiod_line_iter_init(&iter, chip);
- gpiod_foreach_line(&iter, line) {
- name = gpiod_line_name(line);
- consumer = gpiod_line_consumer(line);
- direction = gpiod_line_direction(line);
- active_state = gpiod_line_active_state(line);
-
- printf("\tline %2u: ", gpiod_line_offset(line));
-
- if (name)
- printf("\"%s\"", name);
- else
- printf("unnamed");
- printf(" ");
-
- if (consumer)
- printf("\"%s\"", consumer);
- else
- printf("unused");
- printf(" ");
-
- printf("%s ", direction == GPIOD_DIRECTION_INPUT
- ? "input" : "output");
- printf("%s ", active_state == GPIOD_ACTIVE_STATE_LOW
- ? "active-low"
- : "active-high");
-
- flag_printed = false;
- for (j = 0; j < ARRAY_SIZE(flags); j++) {
- if (flags[j].is_set(line)) {
- if (flag_printed)
- printf(" ");
- else
- printf("[");
- printf("%s", flags[j].name);
- flag_printed = 1;
- }
- }
- if (flag_printed)
- printf("]");
+ printf("\n");
+ }
+}
- printf("\n");
+int main(int argc, char **argv)
+{
+ struct gpiod_chip_iter *chip_iter;
+ struct gpiod_chip *chip;
+ int i, optc, opti;
+
+ set_progname(argv[0]);
+
+ for (;;) {
+ optc = getopt_long(argc, argv, shortopts, longopts, &opti);
+ if (optc < 0)
+ break;
+
+ switch (optc) {
+ case 'h':
+ print_help();
+ return EXIT_SUCCESS;
+ case '?':
+ die("try %s --help", get_progname());
+ default:
+ abort();
}
+ }
+
+ argc -= optind;
+ argv += optind;
- gpiod_chip_close(chip);
+ if (argc == 0) {
+ chip_iter = gpiod_chip_iter_new();
+ if (!chip_iter)
+ die_perror("error accessing GPIO chips");
+
+ gpiod_foreach_chip(chip_iter, chip)
+ list_lines(chip);
+
+ gpiod_chip_iter_free(chip_iter);
+ } else {
+ for (i = 0; i < argc; i++) {
+ chip = gpiod_chip_open_lookup(argv[i]);
+ if (!chip)
+ die_perror("looking up chip %s", argv[i]);
+
+ list_lines(chip);
+
+ gpiod_chip_close(chip);
+ }
}
return EXIT_SUCCESS;