diff options
Diffstat (limited to 'toys/posix/nl.c')
-rw-r--r-- | toys/posix/nl.c | 53 |
1 files changed, 31 insertions, 22 deletions
diff --git a/toys/posix/nl.c b/toys/posix/nl.c index ef2d7ab3..b9e60ae2 100644 --- a/toys/posix/nl.c +++ b/toys/posix/nl.c @@ -5,15 +5,15 @@ * See http://pubs.opengroup.org/onlinepubs/9699919799/utilities/nl.html * * This implements a subset: only one logical page (-ip), no sections (-dfh). - * todo: -l + * todo: -lv -USE_NL(NEWTOY(nl, "v#=1l#w#<0=6Eb:n:s:", TOYFLAG_USR|TOYFLAG_BIN)) +USE_NL(NEWTOY(nl, "v#<1=1l#w#<0=6Eb:n:s:", TOYFLAG_USR|TOYFLAG_BIN)) config NL bool "nl" default y help - usage: nl [-E] [-l #] [-b MODE] [-n STYLE] [-s SEPARATOR] [-v #] [-w WIDTH] [FILE...] + usage: nl [-E] [-l #] [-b MODE] [-n STYLE] [-s SEPARATOR] [-w WIDTH] [FILE...] Number lines of input. @@ -22,7 +22,6 @@ config NL -l Only count last of this many consecutive blank lines -n Number STYLE: ln (left justified) rn (right justified) rz (zero pad) -s Separator to use between number and line (instead of TAB) - -v Starting line number for each section (default 1) -w Width of line numbers (default 6) */ @@ -35,25 +34,36 @@ GLOBALS( // Count of consecutive blank lines for -l has to persist between files long lcount; - long slen; ) -static void do_nl(char **pline, long len) +static void do_nl(int fd, char *name) { - char *line; - int match = *TT.b != 'n'; - - if (!pline) return; - line = *pline; - - if (*TT.b == 'p') match = !regexec((void *)(toybuf+16), line, 0, 0, 0); - if (TT.l || *TT.b == 't') - if (*line == '\n') match = TT.l && ++TT.lcount >= TT.l; - if (match) { - TT.lcount = 0; - printf(toybuf, TT.w, TT.v++, TT.s); - } else printf("%*c", (int)(TT.w+TT.slen), ' '); - xprintf("%s", line); + FILE *f = xfdopen(fd, "r"); + int w = TT.w, slen = strlen(TT.s); + + for (;;) { + char *line = 0; + size_t temp; + int match = *TT.b != 'n'; + + if (getline(&line, &temp, f) < 1) { + if (ferror(f)) perror_msg_raw(name); + break; + } + + if (*TT.b == 'p') match = !regexec((void *)(toybuf+16), line, 0, 0, 0); + if (TT.l || *TT.b == 't') + if (*line == '\n') match = TT.l && ++TT.lcount >= TT.l; + if (match) { + TT.lcount = 0; + printf(toybuf, w, TT.v++, TT.s); + } else printf("%*c", (int)w+slen, ' '); + xprintf("%s", line); + + free(line); + } + + fclose(f); } void nl_main(void) @@ -61,7 +71,6 @@ void nl_main(void) char *clip = ""; if (!TT.s) TT.s = "\t"; - TT.slen = strlen(TT.s); if (!TT.n || !strcmp(TT.n, "rn")); // default else if (!strcmp(TT.n, "ln")) clip = "-"; @@ -76,5 +85,5 @@ void nl_main(void) REG_NOSUB | (toys.optflags&FLAG_E)*REG_EXTENDED); else if (!strchr("atn", *TT.b)) error_exit("bad -b '%s'", TT.b); - loopfiles_lines(toys.optargs, do_nl); + loopfiles (toys.optargs, do_nl); } |