logo

utils-std

Collection of commonly available Unix tools
commit: e3dc53404bd34234de0803f671ba0e57aa9d562c
parent 40752967b170218b7e93b5d32a046c2c90ac4304
Author: Haelwenn (lanodan) Monnier <contact@hacktivis.me>
Date:   Tue,  4 Jun 2024 07:38:02 +0200

cmd/head: Add support for historical -num

Diffstat:

Mcmd/head.113+++++++++++--
Mcmd/head.c32+++++++++++++++++++++++++++++---
Mtest-cmd/head.t7+++++++
3 files changed, 47 insertions(+), 5 deletions(-)

diff --git a/cmd/head.1 b/cmd/head.1 @@ -10,7 +10,7 @@ .Sh SYNOPSIS .Nm .Op Fl qv -.Op Fl c Ar size | Fl n Ar num +.Op Fl c Ar size | Fl n Ar num | Fl Ar num .Op Ar file... .Sh DESCRIPTION .Nm @@ -35,11 +35,17 @@ in each can be multiplied by one of KMGTP (Kilo, Mega, Giga, Tera, ...) using power of 1024 by default, which can be either explicit via adding iB (like MiB), or turned into powers of 1000 by adding B (like MB). -.It Fl n Ar num +.It Fl n Ar num , Fl Ar num Read the first .Ar num lines in each .Ar file . +.Pp +The +.Fl Ar num +form is historical, new scripts should use the standard +.Fl n Ar num +form. .It Fl q Don't print header when multiple .Ar file @@ -81,5 +87,8 @@ The and .Fl v options are extensions. +The +.Fl Ar num +option is historical. .Sh AUTHORS .An Haelwenn (lanodan) Monnier Aq Mt contact+utils@hacktivis.me diff --git a/cmd/head.c b/cmd/head.c @@ -7,6 +7,7 @@ #include "../lib/truncation.h" // apply_size_suffix #include <assert.h> +#include <ctype.h> // isdigit #include <errno.h> #include <fcntl.h> // open #include <stdio.h> // fprintf, fopen, fread @@ -148,7 +149,7 @@ copy_lines(char *filename) static void usage() { - fprintf(stderr, "Usage: head [-qv] [-c size | -n num] [file...]\n"); + fprintf(stderr, "Usage: head [-qv] [-c size | -n num | -num] [file...]\n"); } int @@ -157,9 +158,34 @@ main(int argc, char *argv[]) int (*copy_action)(char *filename) = copy_lines; int print_header = 0; - int c = -1; - while((c = getopt(argc, argv, ":qvc:n:")) != -1) + while(optind < argc) { + /* Skip getopt(3) for parsing -num option due to how it works: + * - optstring = "12"; args="head -12" considered the same as -1 -2 + * - optstring = "1:"; args="head -12" considered the same as -1 2 + * + * And we need args="head -12" as "12" + */ + if(argv[optind] && argv[optind][0] == '-' && isdigit(argv[optind][1])) + { + assert(errno == 0); + char *arg = argv[optind] + 1; + + char *endptr = NULL; + lines = strtoul(arg, &endptr, 0); + if(errno != 0) + { + fprintf(stderr, "head: Error while parsing number for `-%s`: %s\n", arg, strerror(errno)); + return 1; + } + + optind++; + continue; + } + + int c = getopt(argc, argv, ":qvc:n:"); + if(c == -1) break; + switch(c) { case 'q': diff --git a/test-cmd/head.t b/test-cmd/head.t @@ -27,6 +27,13 @@ 4 5 + $ seq 1 20 | head -5 + 1 + 2 + 3 + 4 + 5 + $ seq 1 5 | head 1 2