changeset 1100:b50e00c9df4b draft

Promote nl from pending to posix, and add tests.
author Rob Landley <rob@landley.net>
date Sun, 27 Oct 2013 02:50:55 -0500
parents 71326585c02d
children ccf4193167c3
files scripts/test/nl.test toys/pending/nl.c toys/posix/nl.c
diffstat 3 files changed, 144 insertions(+), 94 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/test/nl.test	Sun Oct 27 02:50:55 2013 -0500
@@ -0,0 +1,50 @@
+#!/bin/bash
+
+[ -f testing.sh ] && . testing.sh
+
+#testing "name" "command" "result" "infile" "stdin"
+
+testing "nl" "nl" "     1\tone\n     2\ttwo\n     3\tthree\n" \
+  "" "one\ntwo\nthree\n"
+
+testing "nl explicit defaults" "nl -nrn -b a" \
+  "     1\tone\n     2\ttwo\n     3\tthree\n" "" "one\ntwo\nthree\n"
+
+# -n ln rn rz
+
+testing "nl -nln" "nl -nln" "1     \tone\n2     \ttwo\n3     \tthree\n" \
+  "" "one\ntwo\nthree\n"
+testing "nl -nln -w" "nl -nln -w 8" \
+  "1       \tone\n2       \ttwo\n3       \tthree\n" "" "one\ntwo\nthree\n"
+
+testing "nl -nrz" "nl -nrz" "000001\tone\n000002\ttwo\n000003\tthree\n" \
+  "" "one\ntwo\nthree\n"
+
+testing "nl -nrz -w" "nl -w3 -nrz" "001\tone\n002\ttwo\n003\tthree\n" \
+  "" "one\ntwo\nthree\n"
+
+
+# For non-matching lines the separator is "suppressed" meaning it...
+# turns into spaces! And the tab turns into one space, and -d boom turns
+# into 4 spaces, but these:
+#   nl -s"$(echo -e 'bo\tom')" -bpand README
+#   nl -w 3 -bpthe README
+# Yeah. And I doubt utf8 fontmetrics are used either.
+
+testing "nl -b t" "nl -b t" "       \n     1\tone\n       \n     2\ttwo\n" \
+  "" "\none\n\ntwo\n"
+testing "nl -b n" "nl -b n" "       one\n       two\n       three\n" \
+  "" "one\ntwo\nthree\n"
+testing "nl -sook -b p" "nl -sook -bpoing" \
+  "         one\n     1ookboing\n     2ooksproingy\n" \
+  "" "one\nboing\nsproingy\n"
+
+testing "nl -v" "nl -v 42" "    42\tone\n    43\ttwo\n    44\tthree\n" \
+  "" "one\ntwo\nthree\n"
+testing "nl -l" "nl -ba -l2 -w2 - input" \
+  " 1\tone\n   \n 2\t\n 3\ttwo\n   \n 4\t\n   \n 5\tthree\n 6\tfour\n   \n 7\t\n   \n 8\tbang\n   \n" \
+  "\n\nbang\n\n" "one\n\n\ntwo\n\n\n\nthree\nfour\n\n"
+testing "nl no space" "nl -w 1 -v 42" "42\tline\n" "" "line\n"
+
+# Should test for -E but no other implementation seems to have it?
+#testing "nl -E" "nl -w2 -sx -Ebp'(one|two)'" " 1x" "one\nand\ntwo\n"
--- a/toys/pending/nl.c	Sun Oct 27 02:48:13 2013 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,94 +0,0 @@
-/* nl.c - print line numbers
- *
- * Copyright 2013 CE Strake <strake888@gmail.com>
- *
- * See http://pubs.opengroup.org/onlinepubs/9699919799/utilities/nl.html
- *
- * This implements a subset: only one logical page (-ip), no sections (-dfh).
- * todo: -lv
-
-USE_NL(NEWTOY(nl, "v#<1=1l#b:n:s:w#<0=6E", TOYFLAG_BIN))
-
-config NL
-  bool "nl"
-  default n
-  help
-    usage: nl [-E] [-l #] [-b MODE] [-n STYLE] [-s SEPARATOR] [-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)
-    -w	Width of line numbers (default 6)
-*/
-
-#define FOR_nl
-#include "toys.h"
-#include "lib/xregcomp.h"
-
-GLOBALS(
-  long w;
-  char *s;
-  char *n;
-  char *b;
-  long l;
-  long v;
-
-  // Count of consecutive blank lines for -l has to persist between files
-  long lcount;
-)
-
-void do_nl(int fd, char *name)
-{
-  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("%s", 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)
-{
-  char *clip = "";
-
-  if (!TT.s) TT.s = "\t";
-
-  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 | (toys.optflags&FLAG_E)*REG_EXTENDED);
-  else if (!strchr("atn", *TT.b)) error_exit("bad -b '%s'", TT.b);
-
-  loopfiles (toys.optargs, do_nl);
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/toys/posix/nl.c	Sun Oct 27 02:50:55 2013 -0500
@@ -0,0 +1,94 @@
+/* nl.c - print line numbers
+ *
+ * Copyright 2013 CE Strake <strake888@gmail.com>
+ *
+ * See http://pubs.opengroup.org/onlinepubs/9699919799/utilities/nl.html
+ *
+ * This implements a subset: only one logical page (-ip), no sections (-dfh).
+ * todo: -lv
+
+USE_NL(NEWTOY(nl, "v#<1=1l#b:n:s:w#<0=6E", TOYFLAG_BIN))
+
+config NL
+  bool "nl"
+  default y
+  help
+    usage: nl [-E] [-l #] [-b MODE] [-n STYLE] [-s SEPARATOR] [-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)
+    -w	Width of line numbers (default 6)
+*/
+
+#define FOR_nl
+#include "toys.h"
+#include "lib/xregcomp.h"
+
+GLOBALS(
+  long w;
+  char *s;
+  char *n;
+  char *b;
+  long l;
+  long v;
+
+  // Count of consecutive blank lines for -l has to persist between files
+  long lcount;
+)
+
+void do_nl(int fd, char *name)
+{
+  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("%s", 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)
+{
+  char *clip = "";
+
+  if (!TT.s) TT.s = "\t";
+
+  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 | (toys.optflags&FLAG_E)*REG_EXTENDED);
+  else if (!strchr("atn", *TT.b)) error_exit("bad -b '%s'", TT.b);
+
+  loopfiles (toys.optargs, do_nl);
+}