did anyone ever use it this way, or are you getting ahead of yourself. Scott Cheloha <scottchel...@gmail.com> wrote:
> Hi, > > head(1) takes line count arguments in two ways. The legacy (1977) > syntax is "-count" [1]. The "new" (1992) syntax is "-n count" [2]. > In either case, "count" must be a positive decimal value. > > Somewhere along the way, support for the legacy syntax was neutered. > At present it only works as expected if -count is the first option > argument to head(1), i.e. this works: > > $ head -20 file > > but this is an error: > > $ head -20 -25 file > > I'm not a fan of this. If we're going to support the legacy syntax I > think it should behave like option arguments for other utilities. You > should be able to specify -count multiple times. We do this for > tail(1), which has a similar legacy syntax problem. > > The easiest way to transparently support such invocations is to use > the GNU double-colon extension for getopt(3). We then rebuild the > number string with asprintf(3), parse it with strtonum(3), and free > the string. > > Before: > > $ jot 10 | head -5 -6 > head: unknown option -- 6 > usage: head [-count | -n count] [file ...] > > After: > > $ jot 10 | head -5 -6 > 1 > 2 > 3 > 4 > 5 > 6 > > -- > > ok? > > [1] > https://svnweb.freebsd.org/csrg/usr.bin/head/head.c?revision=1026&view=markup > > [2] > https://svnweb.freebsd.org/csrg/usr.bin/head/head.c?revision=52824&view=markup > > Index: head.c > =================================================================== > RCS file: /cvs/src/usr.bin/head/head.c,v > retrieving revision 1.22 > diff -u -p -r1.22 head.c > --- head.c 10 Oct 2021 15:57:25 -0000 1.22 > +++ head.c 10 Oct 2021 16:44:01 -0000 > @@ -49,27 +49,30 @@ int > main(int argc, char *argv[]) > { > const char *errstr; > + char *str; > FILE *fp; > long cnt; > int ch, firsttime; > long linecnt = 10; > - int status = 0; > + int error, status = 0; > > if (pledge("stdio rpath", NULL) == -1) > err(1, "pledge"); > > - /* handle obsolete -number syntax */ > - if (argc > 1 && argv[1][0] == '-' && > - isdigit((unsigned char)argv[1][1])) { > - linecnt = strtonum(argv[1] + 1, 1, LONG_MAX, &errstr); > - if (errstr != NULL) > - errx(1, "count is %s: %s", errstr, argv[1] + 1); > - argc--; > - argv++; > - } > - > - while ((ch = getopt(argc, argv, "n:")) != -1) { > +#define OPTSTR "0::1::2::3::4::5::6::7::8::9::n:" > + while ((ch = getopt(argc, argv, OPTSTR)) != -1) { > switch (ch) { > + case '0': case '1': case '2': case '3': case '4': > + case '5': case '6': case '7': case '8': case '9': > + error = asprintf(&str, "%c%s", > + ch, (optarg == NULL) ? "" : optarg); > + if (error == -1) > + err(1, "asprintf"); > + linecnt = strtonum(str, 1, LONG_MAX, &errstr); > + if (errstr != NULL) > + errx(1, "count is %s: %s", errstr, str); > + free(str); > + break; > case 'n': > linecnt = strtonum(optarg, 1, LONG_MAX, &errstr); > if (errstr != NULL) >