Re: [libgpiod v2][PATCH v3 2/5] tools: line name focussed rework

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, Nov 08, 2022 at 02:13:20PM +0100, Bartosz Golaszewski wrote:
>  On Tue, Oct 11, 2022 at 2:29 AM Kent Gibson <warthog618@xxxxxxxxx> wrote:
> >
> > Rework the tool suite to support identifying lines by name and to
> > support operating on the GPIO lines available to the user at once, rather
> > than on one particular GPIO chip.
> >
> > All tools, other than gpiodetect, now provide the name to (chip,offset)
> > mapping that was previously only performed by gpiofind. As names are not
> > guaranteed to be unique, a --strict option is provided for all tools to
> > either abort the operation or report all lines with the matching name, as
> > appropriate.
> > By default the tools operate on the first line found with a matching name.
> >
> > Selection of line by (chip,offset) is still supported with a --chip
> > option, though it restricts the scope of the operation to an individual
> > chip.  When the --chip option is specified, the lines are assumed to be
> > identified by offset where they parse as an integer, else by name.
> > To cater for the unusual case where a line name parses as an integer,
> > but is different from the offset, the --by-name option forces the lines
> > to be identified by name.
> >
> > The updated tools are intentionally NOT backwardly compatible with the
> > previous tools. Using old command lines with the updated tools will
> > almost certainly fail, though migrating old command lines is generally as
> > simple as adding a '-c' before the chip.
> >
> 
> While at it: how about adding the --consumer/-C switch to specify a
> consumer string other than the name of the program?
> 

Ironically I added that to the Rust version, for the long lived
commands anyway, so it could better emulate the C version for testing
purposes.
But could be generally useful, so ok.

I only used the long form there to avoid confusion with -c (as they are
visually very similar) and following the principle that rarely used
options only get a long form, so I will omit the short -C option - unless
you insist.

> > In addition the individual tools are modified as follows:
> >
> > gpiodetect:
> >
> > Add the option to select individual chips.
> >
> > gpioinfo:
> >
> > Change the focus from chips to lines, so the scope can be
> > an individual line, a subset of lines, all lines on a particular chip,
> > or all the lines available to the user.  For line scope a single line
> > summary is output for each line.  For chip scope the existing format
> > displaying a summary of the chip and each of its lines is retained.
> >
> > Line attributes are consolidated into a list format, and are extended
> > to cover all attributes supported by uAPI v2.
> >
> 
> One change in the output that bothers me is the removal of quotation
> marks around the line name and consumer. I did that in v1 to visually
> distinguish between unnamed/unused lines and those that are named. I
> know it's highly unlikely that a line would be named "unnamed" (sic!)
> but still:
> 
> line 0: "foo"
> line 1: unnamed
> 
> looks more intuitive to me.

I disagree on this one. In the longer term all lines should be named
and then the quotes just become pointless noise, and require more
work to parse.

>Same for the consumer as with your current
> version, if the consumer string has spaces in it, it will look like
> this: consumer=foo bar. I think consumer="foo bar" would be easier to
> parse.

For this very reason, the consumer is explicitly listed last, so the
consumer name matches everything between the "consumer=" and end of
line.

Unless consumer names with spaces are very common in the wild then
quotes only add more clutter.

> 
> > gpioget:
> >
> > The default output format is becomes line=value, as per the
> > input for gpioset, and the value is reported as active or inactive,
> > rather than 0 or 1.
> > The previous format is available using the --numeric option.
> >
> > Add an optional hold period between requesting a line and reading the
> > value to allow the line to settle once the requested configuration has
> > been applied (e.g. bias).
> >
> > gpiomon:
> >
> > Consolidate the edge options into a single option.
> >
> > Add a debounce period option.
> >
> > Add options to report event times as UTC or localtime.
> >
> > Add format specifiers for GPIO chip path, line name, stringified event
> > type, and event time as a datetime.
> >
> > Rearrange default output format to place fields with more predicable
> > widths to the left, and to separate major field groups with tabs.
> > Lines are identified consistent with the command line.
> >
> > gpioset:
> >
> > Add a hold period option that specifies the minimum period the line
> > value must be held for.  This applies to all set options.
> >
> > Support line values specified as active/inactive, on/off and
> > true/false, as well as 1/0.
> >
> > Add a toggle option that specifies a time sequence over which the
> > requested lines should be toggled.  If the sequence is 0 terminated then
> > gpioset exits when the sequence completes, else it repeats the sequence.
> > This allows for anything from simple blinkers to bit bashing from the
> > command line. e.g. gpioset -t 500ms LED=on
> >
> > Add an interactive option to provide a shell-like interface to allow
> > manual or scripted manipulation of requested lines.  A basic command set
> > allows lines to be get, set, or toggled, and to insert sleeps between
> > operations.
> >
> 
> As discussed elsewhere - it would be great if this part was optional
> and configurable at build-time so that the dependency on libedit could
> be dropped if unavailable.
> 

Agreed.

> > Remove the --mode, --sec, and --usec options.
> > The combination of hold period and interactive mode provide functionality
> > equivalent to the old --mode options.
> >
> 
> I have one problem with that - I think the basic functionality of:
> "take a line, set its value and wait for a signal" would still be
> useful. As it is now, I'm not sure how to make gpioset just hold a
> line without calling the GPIO_V2_LINE_SET_VALUES_IOCTL ioctl
> periodically.
> 

I forgot to mention the daemonize option here, so

gpioset -z myline=1

will do that.

(or 

gpioset -i myline=1

if you want to keep the process in the foreground.)

I'll add something to the daemonize help to highlight that it will hold
the line until killed. Is that sufficient?

> > Signed-off-by: Kent Gibson <warthog618@xxxxxxxxx>
> > ---
> >  configure.ac         |   8 +-
> >  tools/Makefile.am    |   2 +-
> >  tools/gpiodetect.c   | 113 +++++-
> >  tools/gpioget.c      | 204 ++++++++++-
> >  tools/gpioinfo.c     | 223 +++++++++++-
> >  tools/gpiomon.c      | 450 +++++++++++++++++++++++-
> >  tools/gpioset.c      | 815 ++++++++++++++++++++++++++++++++++++++++++-
> >  tools/tools-common.c | 713 ++++++++++++++++++++++++++++++++++++-
> >  tools/tools-common.h |  99 +++++-
> >  9 files changed, 2585 insertions(+), 42 deletions(-)
> >
> > diff --git a/configure.ac b/configure.ac
> > index 6ac1d8e..c8033c5 100644
> > --- a/configure.ac
> > +++ b/configure.ac
> > @@ -106,14 +106,14 @@ AC_DEFUN([FUNC_NOT_FOUND_TOOLS],
> >  AC_DEFUN([HEADER_NOT_FOUND_TOOLS],
> >         [ERR_NOT_FOUND([$1 header], [tools])])
> >
> > +AC_DEFUN([LIB_NOT_FOUND_TOOLS],
> > +       [ERR_NOT_FOUND([lib$1], [tools])])
> > +
> >  if test "x$with_tools" = xtrue
> >  then
> >         # These are only needed to build tools
> > -       AC_CHECK_FUNC([basename], [], [FUNC_NOT_FOUND_TOOLS([basename])])
> >         AC_CHECK_FUNC([daemon], [], [FUNC_NOT_FOUND_TOOLS([daemon])])
> > -       AC_CHECK_FUNC([signalfd], [], [FUNC_NOT_FOUND_TOOLS([signalfd])])
> > -       AC_CHECK_FUNC([setlinebuf], [], [FUNC_NOT_FOUND_TOOLS([setlinebuf])])
> > -       AC_CHECK_HEADERS([sys/signalfd.h], [], [HEADER_NOT_FOUND_TOOLS([sys/signalfd.h])])
> > +       PKG_CHECK_MODULES(LIBEDIT, libedit)
> >  fi
> >
> >  AC_ARG_ENABLE([tests],
> > diff --git a/tools/Makefile.am b/tools/Makefile.am
> > index fc074b9..c956314 100644
> > --- a/tools/Makefile.am
> > +++ b/tools/Makefile.am
> > @@ -7,7 +7,7 @@ AM_CFLAGS += -Wall -Wextra -g -std=gnu89
> >  noinst_LTLIBRARIES = libtools-common.la
> >  libtools_common_la_SOURCES = tools-common.c tools-common.h
> >
> > -LDADD = libtools-common.la $(top_builddir)/lib/libgpiod.la
> > +LDADD = libtools-common.la $(top_builddir)/lib/libgpiod.la $(LIBEDIT_LIBS)
> >
> >  bin_PROGRAMS = gpiodetect gpioinfo gpioget gpioset gpiomon
> >
> > diff --git a/tools/gpiodetect.c b/tools/gpiodetect.c
> > index 30bde32..910fe9e 100644
> > --- a/tools/gpiodetect.c
> > +++ b/tools/gpiodetect.c
> > @@ -1,8 +1,7 @@
> >  // SPDX-License-Identifier: GPL-2.0-or-later
> >  // SPDX-FileCopyrightText: 2017-2021 Bartosz Golaszewski <bartekgola@xxxxxxxxx>
> > +// SPDX-FileCopyrightText: 2022 Kent Gibson <warthog618@xxxxxxxxx>
> >
> > -#include <dirent.h>
> > -#include <errno.h>
> >  #include <getopt.h>
> >  #include <gpiod.h>
> >  #include <stdio.h>
> > @@ -11,3 +10,113 @@
> >
> >  #include "tools-common.h"
> >
> > +static void print_help(void)
> > +{
> > +       printf("Usage: %s [OPTIONS] [chip]...\n", get_progname());
> > +       printf("\n");
> > +       printf("List GPIO chips, print their labels and number of GPIO lines.\n");
> > +       printf("\n");
> > +       printf("Chips may be identified by number, name, or path.\n");
> > +       printf("e.g. '0', 'gpiochip0', and '/dev/gpiochip0' all refer to the same chip.\n");
> > +       printf("\n");
> > +       printf("If no chips are specified then all chips are listed.\n");
> > +       printf("\n");
> > +       printf("Options:\n");
> > +       printf("  -h, --help\t\tdisplay this help and exit\n");
> > +       printf("  -v, --version\t\toutput version information and exit\n");
> > +}
> > +
> > +int parse_config(int argc, char **argv)
> > +{
> > +       int optc, opti;
> > +       const char *const shortopts = "+hv";
> > +       const struct option longopts[] = {
> > +               { "help",       no_argument,    NULL,   'h' },
> > +               { "version",    no_argument,    NULL,   'v' },
> > +               { GETOPT_NULL_LONGOPT },
> > +       };
> 
> This can be static as there are no addresses of flag variables assigned.
> 

Indeed - and now you mention it I notice a few other things that should be
static too.

> > +
> > +       for (;;) {
> > +               optc = getopt_long(argc, argv, shortopts, longopts, &opti);
> > +               if (optc < 0)
> > +                       break;
> > +
> > +               switch (optc) {
> > +               case 'h':
> > +                       print_help();
> > +                       exit(EXIT_SUCCESS);
> > +               case 'v':
> > +                       print_version();
> > +                       exit(EXIT_SUCCESS);
> > +               case '?':
> > +                       die("try %s --help", get_progname());
> > +               default:
> > +                       abort();
> > +               }
> > +       }
> > +       return optind;
> > +}
> > +
> > +int print_chip_info(const char *path)
> > +{
> > +       struct gpiod_chip *chip;
> > +       struct gpiod_chip_info *info;
> > +
> > +       chip = gpiod_chip_open(path);
> > +       if (!chip) {
> > +               print_perror("unable to open chip '%s'", path);
> > +               return 1;
> > +       }
> > +
> > +       info = gpiod_chip_get_info(chip);
> > +       if (!info)
> > +               die_perror("unable to read info for '%s'", path);
> > +
> > +       printf("%s [%s] (%zu lines)\n",
> > +              gpiod_chip_info_get_name(info),
> > +              gpiod_chip_info_get_label(info),
> > +              gpiod_chip_info_get_num_lines(info));
> > +
> > +       gpiod_chip_info_free(info);
> > +       gpiod_chip_close(chip);
> > +       return 0;
> > +}
> > +
> > +int main(int argc, char **argv)
> > +{
> > +       int num_chips, i;
> > +       char **paths;
> > +       char *path;
> > +       int ret = EXIT_SUCCESS;
> > +
> > +       i = parse_config(argc, argv);
> > +       argc -= i;
> > +       argv += i;
> > +
> > +       if (argc == 0) {
> > +               num_chips = all_chip_paths(&paths);
> > +               for (i = 0; i < num_chips; i++) {
> > +                       if (print_chip_info(paths[i]))
> > +                               ret = EXIT_FAILURE;
> > +
> > +                       free(paths[i]);
> > +               }
> > +               free(paths);
> > +       }
> > +
> > +       for (i = 0; i < argc; i++) {
> > +               if (chip_path_lookup(argv[i], &path)) {
> > +                       if (print_chip_info(path))
> > +                               ret = EXIT_FAILURE;
> > +
> > +                       free(path);
> > +               } else {
> > +                       print_error(
> > +                               "cannot find GPIO chip character device '%s'",
> > +                               argv[i]);
> > +                       ret = EXIT_FAILURE;
> > +               }
> > +       }
> > +
> > +       return ret;
> > +}
> > diff --git a/tools/gpioget.c b/tools/gpioget.c
> > index 1b3e666..7a26066 100644
> > --- a/tools/gpioget.c
> > +++ b/tools/gpioget.c
> > @@ -1,12 +1,214 @@
> >  // SPDX-License-Identifier: GPL-2.0-or-later
> >  // SPDX-FileCopyrightText: 2017-2021 Bartosz Golaszewski <bartekgola@xxxxxxxxx>
> > +// SPDX-FileCopyrightText: 2022 Kent Gibson <warthog618@xxxxxxxxx>
> >
> >  #include <getopt.h>
> >  #include <gpiod.h>
> > -#include <limits.h>
> >  #include <stdio.h>
> >  #include <stdlib.h>
> >  #include <string.h>
> > +#include <unistd.h>
> >
> >  #include "tools-common.h"
> >
> > +static void print_help(void)
> > +{
> > +       printf("Usage: %s [OPTIONS] <line>...\n", get_progname());
> > +       printf("\n");
> > +       printf("Read values of GPIO lines.\n");
> > +       printf("\n");
> > +       printf("Lines are specified by name, or optionally by offset if the chip option\n");
> > +       printf("is provided.\n");
> > +       printf("\n");
> > +       printf("Options:\n");
> > +       printf("  -a, --as-is\t\tleave the line direction unchanged, not forced to input\n");
> > +       print_bias_help();
> > +       printf("      --by-name\t\ttreat lines as names even if they would parse as an offset\n");
> > +       printf("  -c, --chip <chip>\trestrict scope to a particular chip\n");
> > +       printf("  -h, --help\t\tdisplay this help and exit\n");
> > +       printf("  -l, --active-low\ttreat the line as active low\n");
> > +       printf("  -p, --hold-period <period>\n");
> > +       printf("\t\t\twait between requesting the lines and reading the values\n");
> > +       printf("      --numeric\t\tdisplay line values as '0' (inactive) or '1' (active)\n");
> > +       printf("  -s, --strict\t\tabort if requested line names are not unique\n");
> > +       printf("  -v, --version\t\toutput version information and exit\n");
> > +       print_chip_help();
> > +       print_period_help();
> > +}
> > +struct config {
> > +       bool active_low;
> > +       bool strict;
> > +       int bias;
> > +       int direction;
> > +       unsigned int hold_period_us;
> > +       const char *chip_id;
> > +       int by_name;
> > +       int numeric;
> > +};
> > +
> > +int parse_config(int argc, char **argv, struct config *cfg)
> > +{
> > +       int opti, optc;
> > +       const char *const shortopts = "+ab:c:hlp:sv";
> > +       const struct option longopts[] = {
> > +               { "active-low", no_argument,            NULL,   'l' },
> > +               { "as-is",      no_argument,            NULL,   'a' },
> > +               { "bias",       required_argument,      NULL,   'b' },
> > +               { "by-name",    no_argument,            &cfg->by_name,  1 },
> > +               { "chip",       required_argument,      NULL,   'c' },
> > +               { "help",       no_argument,            NULL,   'h' },
> > +               { "hold-period", required_argument,     NULL,   'p' },
> > +               { "numeric",    no_argument,            &cfg->numeric,  1 },
> > +               { "strict",     no_argument,            NULL,   's' },
> > +               { "version",    no_argument,            NULL,   'v' },
> > +               { GETOPT_NULL_LONGOPT },
> > +       };
> > +
> > +       memset(cfg, 0, sizeof(*cfg));
> > +       cfg->direction = GPIOD_LINE_DIRECTION_INPUT;
> > +
> > +       for (;;) {
> > +               optc = getopt_long(argc, argv, shortopts, longopts, &opti);
> > +               if (optc < 0)
> > +                       break;
> > +
> > +               switch (optc) {
> > +               case 'a':
> > +                       cfg->direction = GPIOD_LINE_DIRECTION_AS_IS;
> > +                       break;
> > +               case 'b':
> > +                       cfg->bias = parse_bias_or_die(optarg);
> > +                       break;
> > +               case 'c':
> > +                       cfg->chip_id = optarg;
> > +                       break;
> > +               case 'l':
> > +                       cfg->active_low = true;
> > +                       break;
> > +               case 'p':
> > +                       cfg->hold_period_us = parse_period_or_die(optarg);
> > +                       break;
> > +               case 's':
> > +                       cfg->strict = true;
> > +                       break;
> > +               case 'h':
> > +                       print_help();
> > +                       exit(EXIT_SUCCESS);
> > +               case 'v':
> > +                       print_version();
> > +                       exit(EXIT_SUCCESS);
> > +               case '?':
> > +                       die("try %s --help", get_progname());
> > +               case 0:
> > +                       break;
> > +               default:
> > +                       abort();
> > +               }
> > +       }
> > +
> > +       return optind;
> > +}
> > +
> > +int main(int argc, char **argv)
> > +{
> > +       int i, num_lines, ret, *values;
> > +       struct gpiod_line_settings *settings;
> > +       struct gpiod_request_config *req_cfg;
> > +       struct gpiod_line_request *request;
> > +       struct gpiod_line_config *line_cfg;
> > +       struct gpiod_chip *chip;
> > +       unsigned int *offsets;
> > +       struct line_resolver *resolver;
> > +       struct resolved_line *line;
> > +       struct config cfg;
> > +
> > +       i = parse_config(argc, argv, &cfg);
> > +       argc -= i;
> > +       argv += i;
> > +
> > +       if (argc < 1)
> > +               die("at least one GPIO line must be specified");
> > +
> > +       resolver = resolve_lines(argc, argv, cfg.chip_id, cfg.strict,
> > +                                cfg.by_name);
> > +       validate_resolution(resolver, cfg.chip_id);
> > +
> > +       offsets = calloc(resolver->num_lines, sizeof(*offsets));
> > +       values = calloc(resolver->num_lines, sizeof(*values));
> > +       if (!offsets || !values)
> > +               die("out of memory");
> > +
> > +       settings = gpiod_line_settings_new();
> > +       if (!settings)
> > +               die_perror("unable to allocate line settings");
> > +
> > +       gpiod_line_settings_set_direction(settings, cfg.direction);
> > +
> > +       if (cfg.bias)
> > +               gpiod_line_settings_set_bias(settings, cfg.bias);
> > +
> > +       if (cfg.active_low)
> > +               gpiod_line_settings_set_active_low(settings, true);
> > +
> > +       req_cfg = gpiod_request_config_new();
> > +       if (!req_cfg)
> > +               die_perror("unable to allocate the request config structure");
> > +
> > +       line_cfg = gpiod_line_config_new();
> > +       if (!line_cfg)
> > +               die_perror("unable to allocate the line config structure");
> > +
> > +       gpiod_request_config_set_consumer(req_cfg, "gpioget");
> > +       for (i = 0; i < resolver->num_chips; i++) {
> > +               chip = gpiod_chip_open(resolver->chips[i].path);
> > +               if (!chip)
> > +                       die_perror("unable to open chip '%s'",
> > +                                  resolver->chips[i].path);
> > +
> > +               num_lines = get_line_offsets_and_values(resolver, i, offsets,
> > +                                                       NULL);
> > +
> > +               gpiod_line_config_reset(line_cfg);
> > +               ret = gpiod_line_config_add_line_settings(line_cfg, offsets,
> > +                                                         num_lines, settings);
> > +               if (ret)
> > +                       die_perror("unable to add line settings");
> > +
> > +               request = gpiod_chip_request_lines(chip, req_cfg, line_cfg);
> > +               if (!request)
> > +                       die_perror("unable to request lines");
> > +
> > +               if (cfg.hold_period_us)
> > +                       usleep(cfg.hold_period_us);
> > +
> > +               ret = gpiod_line_request_get_values(request, values);
> > +               if (ret)
> > +                       die_perror("unable to read GPIO line values");
> > +
> > +               set_line_values(resolver, i, values);
> > +
> > +               gpiod_line_request_release(request);
> > +               gpiod_chip_close(chip);
> > +       }
> > +       for (i = 0; i < resolver->num_lines; i++) {
> > +               line = &resolver->lines[i];
> > +               if (cfg.numeric)
> > +                       printf("%d", line->value);
> > +               else
> > +                       printf("%s=%s", line->id,
> > +                              line->value ? "active" : "inactive");
> > +
> > +               if (i != resolver->num_lines - 1)
> > +                       printf(" ");
> > +       }
> > +       printf("\n");
> > +
> > +       free_line_resolver(resolver);
> > +       gpiod_request_config_free(req_cfg);
> > +       gpiod_line_config_free(line_cfg);
> > +       gpiod_line_settings_free(settings);
> > +       free(offsets);
> > +       free(values);
> > +
> > +       return EXIT_SUCCESS;
> > +}
> > diff --git a/tools/gpioinfo.c b/tools/gpioinfo.c
> > index ae368fa..5dc28f8 100644
> > --- a/tools/gpioinfo.c
> > +++ b/tools/gpioinfo.c
> > @@ -1,8 +1,7 @@
> >  // SPDX-License-Identifier: GPL-2.0-or-later
> >  // SPDX-FileCopyrightText: 2017-2021 Bartosz Golaszewski <bartekgola@xxxxxxxxx>
> > +// SPDX-FileCopyrightText: 2022 Kent Gibson <warthog618@xxxxxxxxx>
> >
> > -#include <dirent.h>
> > -#include <errno.h>
> >  #include <getopt.h>
> >  #include <gpiod.h>
> >  #include <stdarg.h>
> > @@ -12,3 +11,223 @@
> >
> >  #include "tools-common.h"
> >
> > +static void print_help(void)
> > +{
> > +       printf("Usage: %s [OPTIONS] [line]...\n", get_progname());
> > +       printf("\n");
> > +       printf("Print information about GPIO lines.\n");
> > +       printf("\n");
> > +       printf("Lines are specified by name, or optionally by offset if the chip option\n");
> > +       printf("is provided.\n");
> > +       printf("\n");
> > +       printf("If no lines are specified than all lines are displayed.\n");
> > +       printf("\n");
> > +       printf("Options:\n");
> > +       printf("      --by-name\t\ttreat lines as names even if they would parse as an offset\n");
> > +       printf("  -c, --chip <chip>\trestrict scope to a particular chip\n");
> > +       printf("  -h, --help\t\tdisplay this help and exit\n");
> > +       printf("  -s, --strict\t\tcheck all lines - don't assume line names are unique\n");
> > +       printf("  -v, --version\t\toutput version information and exit\n");
> > +       print_chip_help();
> > +}
> > +
> > +struct config {
> > +       bool strict;
> > +       const char *chip_id;
> > +       int by_name;
> > +};
> > +
> > +int parse_config(int argc, char **argv, struct config *cfg)
> > +{
> > +       int opti, optc;
> > +       const char *const shortopts = "+c:hsv";
> > +       const struct option longopts[] = {
> > +               { "by-name",    no_argument,    &cfg->by_name,  1 },
> > +               { "chip",       required_argument,      NULL,   'c' },
> > +               { "help",       no_argument,    NULL,           'h' },
> > +               { "strict",     no_argument,    NULL,           's' },
> > +               { "version",    no_argument,    NULL,           'v' },
> > +               { GETOPT_NULL_LONGOPT },
> > +       };
> > +
> > +       memset(cfg, 0, sizeof(*cfg));
> > +
> > +       for (;;) {
> > +               optc = getopt_long(argc, argv, shortopts, longopts, &opti);
> > +               if (optc < 0)
> > +                       break;
> > +
> > +               switch (optc) {
> > +               case 'c':
> > +                       cfg->chip_id = optarg;
> > +                       break;
> > +               case 's':
> > +                       cfg->strict = true;
> > +                       break;
> > +               case 'h':
> > +                       print_help();
> > +                       exit(EXIT_SUCCESS);
> > +               case 'v':
> > +                       print_version();
> > +                       exit(EXIT_SUCCESS);
> > +               case '?':
> > +                       die("try %s --help", get_progname());
> > +               case 0:
> > +                       break;
> > +               default:
> > +                       abort();
> > +               }
> > +       }
> > +
> > +       return optind;
> > +}
> > +
> > +
> > +// minimal version similar to tools-common that indicates if a line should be
> > +// printed rather than storing details into the resolver.
> > +// Does not die on non-unique lines.
> 
> C-style comments only please. Same elsewhere.
> 

Yeah - sorry again - I'm so used to that style that I don't even notice
I'm doing it.

> <snip>
> 
> I like the new tools in general. I don't have many issues with the
> code - you are a much better coder than I am.

That's being a bit harsh.

One thing I was considering was reworking the resolver so it would be
more suitable for general use, and move it to core libgpiod so apps
could more readily perform line name discovery.

> I would change the
> coding style here and there but I will probably just spend some time
> on a good clang-format config and use it indiscriminately like I did
> with black for Python.
> 

That could be useful.  Why doesn't the kernel do that?
And that reminds me - I still need to circle back and take another look
through the Python bindings.

Cheers,
Kent.



[Index of Archives]     [Linux SPI]     [Linux Kernel]     [Linux ARM (vger)]     [Linux ARM MSM]     [Linux Omap]     [Linux Arm]     [Linux Tegra]     [Fedora ARM]     [Linux for Samsung SOC]     [eCos]     [Linux Fastboot]     [Gcc Help]     [Git]     [DCCP]     [IETF Announce]     [Security]     [Linux MIPS]     [Yosemite Campsites]

  Powered by Linux