Mercurial > hg > toybox
annotate toys/posix/nl.c @ 1239:9a13e6637d7b draft
Decided not to go with the sflate implementation of deflate/inflate. The decompression side's already reimplemented in compress, and I'm working on compression side.
author | Rob Landley <rob@landley.net> |
---|---|
date | Wed, 02 Apr 2014 06:37:14 -0500 |
parents | 63db77909fc8 |
children |
rev | line source |
---|---|
1100
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1 /* nl.c - print line numbers |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
2 * |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
3 * Copyright 2013 CE Strake <strake888@gmail.com> |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
4 * |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
5 * See http://pubs.opengroup.org/onlinepubs/9699919799/utilities/nl.html |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
6 * |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
7 * This implements a subset: only one logical page (-ip), no sections (-dfh). |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
8 * todo: -lv |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
9 |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
10 USE_NL(NEWTOY(nl, "v#<1=1l#b:n:s:w#<0=6E", TOYFLAG_BIN)) |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
11 |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
12 config NL |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
13 bool "nl" |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
14 default y |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
15 help |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
16 usage: nl [-E] [-l #] [-b MODE] [-n STYLE] [-s SEPARATOR] [-w WIDTH] [FILE...] |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
17 |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
18 Number lines of input. |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
19 |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
20 -E Use extended regex syntax (when doing -b pREGEX) |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
21 -b which lines to number: a (all) t (non-empty, default) pREGEX (pattern) |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
22 -l Only count last of this many consecutive blank lines |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
23 -n number STYLE: ln (left justified) rn (right justified) rz (zero pad) |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
24 -s Separator to use between number and line (instead of TAB) |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
25 -w Width of line numbers (default 6) |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
26 */ |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
27 |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
28 #define FOR_nl |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
29 #include "toys.h" |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
30 |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
31 GLOBALS( |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
32 long w; |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
33 char *s; |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
34 char *n; |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
35 char *b; |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
36 long l; |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
37 long v; |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
38 |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
39 // Count of consecutive blank lines for -l has to persist between files |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
40 long lcount; |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
41 ) |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
42 |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
43 void do_nl(int fd, char *name) |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
44 { |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
45 FILE *f = xfdopen(fd, "r"); |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
46 int w = TT.w, slen = strlen(TT.s); |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
47 |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
48 for (;;) { |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
49 char *line = 0; |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
50 size_t temp; |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
51 int match = *TT.b != 'n'; |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
52 |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
53 if (getline(&line, &temp, f) < 1) { |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
54 if (ferror(f)) perror_msg("%s", name); |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
55 break; |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
56 } |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
57 |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
58 if (*TT.b == 'p') match = !regexec((void *)(toybuf+16), line, 0, 0, 0); |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
59 if (TT.l || *TT.b == 't') |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
60 if (*line == '\n') match = TT.l && ++TT.lcount >= TT.l; |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
61 if (match) { |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
62 TT.lcount = 0; |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
63 printf(toybuf, w, TT.v++, TT.s); |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
64 } else printf("%*c", (int)w+slen, ' '); |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
65 xprintf("%s", line); |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
66 |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
67 free(line); |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
68 } |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
69 |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
70 fclose(f); |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
71 } |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
72 |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
73 void nl_main(void) |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
74 { |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
75 char *clip = ""; |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
76 |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
77 if (!TT.s) TT.s = "\t"; |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
78 |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
79 if (!TT.n || !strcmp(TT.n, "rn")); // default |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
80 else if (!strcmp(TT.n, "ln")) clip = "-"; |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
81 else if (!strcmp(TT.n, "rz")) clip = "0"; |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
82 else error_exit("bad -n '%s'", TT.n); |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
83 |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
84 sprintf(toybuf, "%%%s%s", clip, "*ld%s"); |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
85 |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
86 if (!TT.b) TT.b = "t"; |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
87 if (*TT.b == 'p' && TT.b[1]) |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
88 xregcomp((void *)(toybuf+16), TT.b+1, |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
89 REG_NOSUB | (toys.optflags&FLAG_E)*REG_EXTENDED); |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
90 else if (!strchr("atn", *TT.b)) error_exit("bad -b '%s'", TT.b); |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
91 |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
92 loopfiles (toys.optargs, do_nl); |
b50e00c9df4b
Promote nl from pending to posix, and add tests.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
93 } |