aboutsummaryrefslogtreecommitdiff
path: root/toys/posix/nl.c
diff options
context:
space:
mode:
Diffstat (limited to 'toys/posix/nl.c')
-rw-r--r--toys/posix/nl.c53
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);
}