12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879 |
- /* nl.c - print line numbers
- *
- * Copyright 2013 CE Strake <strake888@gmail.com>
- *
- * See http://pubs.opengroup.org/onlinepubs/9699919799/utilities/nl.html
- *
- * Deviations from posix: only one logical page (no -ip), no sections (-dfh),
- * add -E, support multiple FILE, -n output is long not int.
- USE_NL(NEWTOY(nl, "v#=1l#w#<0=6b:n:s:E", 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...]
- Number lines of input.
- -E Use extended regex syntax (when doing -b pREGEX)
- -b Which lines to number: a (all) t (non-empty, default) pREGEX (pattern)
- -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)
- */
- #define FOR_nl
- #include "toys.h"
- GLOBALS(
- char *s, *n, *b;
- long w, l, v;
- // Count of consecutive blank lines for -l has to persist between files
- long lcount, slen;
- )
- static void do_nl(char **pline, long len)
- {
- 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);
- }
- 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 = "-";
- else if (!strcmp(TT.n, "rz")) clip = "0";
- else error_exit("bad -n '%s'", TT.n);
- sprintf(toybuf, "%%%s%s", clip, "*ld%s");
- if (!TT.b) TT.b = "t";
- if (*TT.b=='p' && TT.b[1])
- xregcomp((void *)(toybuf+16), TT.b+1, REG_NOSUB|FLAG(E)*REG_EXTENDED);
- else if (!TT.b[0] || TT.b[1] || !strchr("atn", *TT.b))
- error_exit("bad -b '%s'", TT.b);
- loopfiles_lines(toys.optargs, do_nl);
- }
|