aboutsummaryrefslogtreecommitdiff
path: root/coreutils/cat.c
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2017-04-12 17:17:29 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2017-04-12 17:17:29 +0200
commite31ca2e9b206a05263708a3c10fbaec920920ba8 (patch)
tree060741e2cfcae4bea4fae834423a95fe001e8c67 /coreutils/cat.c
parentd9eb40c18519d10aac3b3d008aa7e338ae830b72 (diff)
downloadbusybox-w32-e31ca2e9b206a05263708a3c10fbaec920920ba8.tar.gz
busybox-w32-e31ca2e9b206a05263708a3c10fbaec920920ba8.tar.bz2
busybox-w32-e31ca2e9b206a05263708a3c10fbaec920920ba8.zip
catv: convert this bbox-specific applet into "cat -v"
function old new delta cat_main 150 320 +170 packed_usage 31511 31552 +41 applet_install_loc 190 189 -1 applet_main 1516 1512 -4 applet_names 2618 2613 -5 catv_main 227 - -227 ------------------------------------------------------------------------------ (add/remove: 0/2 grow/shrink: 2/3 up/down: 211/-237) Total: -26 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'coreutils/cat.c')
-rw-r--r--coreutils/cat.c140
1 files changed, 122 insertions, 18 deletions
diff --git a/coreutils/cat.c b/coreutils/cat.c
index 96970b19d..4d9147f8a 100644
--- a/coreutils/cat.c
+++ b/coreutils/cat.c
@@ -12,8 +12,15 @@
12//config: help 12//config: help
13//config: cat is used to concatenate files and print them to the standard 13//config: cat is used to concatenate files and print them to the standard
14//config: output. Enable this option if you wish to enable the 'cat' utility. 14//config: output. Enable this option if you wish to enable the 'cat' utility.
15//config:
16//config:config FEATURE_CATV
17//config: bool "cat -v[etA]"
18//config: default y
19//config: depends on CAT
20//config: help
21//config: Display nonprinting characters as escape sequences
15 22
16//applet:IF_CAT(APPLET_NOFORK(cat, cat, BB_DIR_BIN, BB_SUID_DROP, cat)) 23//applet:IF_CAT(APPLET(cat, BB_DIR_BIN, BB_SUID_DROP))
17 24
18//kbuild:lib-$(CONFIG_CAT) += cat.o 25//kbuild:lib-$(CONFIG_CAT) += cat.o
19 26
@@ -21,22 +28,27 @@
21/* http://www.opengroup.org/onlinepubs/007904975/utilities/cat.html */ 28/* http://www.opengroup.org/onlinepubs/007904975/utilities/cat.html */
22 29
23//usage:#define cat_trivial_usage 30//usage:#define cat_trivial_usage
24//usage: "[-n] [FILE]..." 31//usage: "[-nb"IF_FEATURE_CATV("vteA")"] [FILE]..."
25//usage:#define cat_full_usage "\n\n" 32//usage:#define cat_full_usage "\n\n"
26//usage: "Concatenate FILEs and print them to stdout" 33//usage: "Print FILEs to stdout\n"
27//usage: "\n -n Number output lines" 34//usage: "\n -n Number output lines"
35//usage: "\n -b Number nonempty lines"
36//usage: IF_FEATURE_CATV(
37//usage: "\n -v Show nonprinting characters as ^x or M-x"
38//usage: "\n -t ...and tabs as ^I"
39//usage: "\n -e ...and end lines with $"
40//usage: "\n -A Same as -vte"
41//usage: )
28/* 42/*
29 Longopts not implemented yet: 43 Longopts not implemented yet:
30 --number-nonblank number nonempty output lines, overrides -n 44 --number-nonblank number nonempty output lines, overrides -n
31 --number number all output lines 45 --number number all output lines
46 --show-nonprinting use ^ and M- notation, except for LFD and TAB
47 --show-all equivalent to -vet
32 Not implemented yet: 48 Not implemented yet:
33 -A, --show-all equivalent to -vET 49 -E, --show-ends display $ at end of each line (-e sans -v)
34 -e equivalent to -vE 50 -T, --show-tabs display TAB characters as ^I (-t sans -v)
35 -E, --show-ends display $ at end of each line
36 -s, --squeeze-blank suppress repeated empty output lines 51 -s, --squeeze-blank suppress repeated empty output lines
37 -t equivalent to -vT
38 -T, --show-tabs display TAB characters as ^I
39 -v, --show-nonprinting use ^ and M- notation, except for LFD and TAB
40*/ 52*/
41//usage: 53//usage:
42//usage:#define cat_example_usage 54//usage:#define cat_example_usage
@@ -44,19 +56,111 @@
44//usage: "110716.72 17.67" 56//usage: "110716.72 17.67"
45 57
46#include "libbb.h" 58#include "libbb.h"
59#include "common_bufsiz.h"
60
61#if ENABLE_FEATURE_CATV
62/*
63 * cat -v implementation for busybox
64 *
65 * Copyright (C) 2006 Rob Landley <rob@landley.net>
66 *
67 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
68 */
69/* Rob had "cat -v" implemented as a separate applet, catv.
70 * See "cat -v considered harmful" at
71 * http://cm.bell-labs.com/cm/cs/doc/84/kp.ps.gz
72 * From USENIX Summer Conference Proceedings, 1983
73 * """
74 * The talk reviews reasons for UNIX's popularity and shows, using UCB cat
75 * as a primary example, how UNIX has grown fat. cat isn't for printing
76 * files with line numbers, it isn't for compressing multiple blank lines,
77 * it's not for looking at non-printing ASCII characters, it's for
78 * concatenating files.
79 * We are reminded that ls isn't the place for code to break a single column
80 * into multiple ones, and that mailnews shouldn't have its own more
81 * processing or joke encryption code.
82 * """
83 *
84 * I agree with the argument. Unfortunately, this ship has sailed (1983...).
85 * There are dozens of Linux distros and each of them has "cat" which supports -v.
86 * It's unrealistic for us to "reeducate" them to use our, incompatible way
87 * to achieve "cat -v" effect. The actuall effect would be "users pissed off
88 * by gratuitous incompatibility".
89 */
90#define CATV_OPT_e (1<<0)
91#define CATV_OPT_t (1<<1)
92#define CATV_OPT_v (1<<2)
93static int catv(unsigned opts, char **argv)
94{
95 int retval = EXIT_SUCCESS;
96 int fd;
47 97
48/* This is a NOFORK applet. Be very careful! */ 98 BUILD_BUG_ON(CATV_OPT_e != VISIBLE_ENDLINE);
99 BUILD_BUG_ON(CATV_OPT_t != VISIBLE_SHOW_TABS);
100#if 0 /* These consts match, we can just pass "opts" to visible() */
101 if (opts & CATV_OPT_e)
102 flags |= VISIBLE_ENDLINE;
103 if (opts & CATV_OPT_t)
104 flags |= VISIBLE_SHOW_TABS;
105#endif
106
107 /* Read from stdin if there's nothing else to do. */
108 if (!argv[0])
109 *--argv = (char*)"-";
110
111#define read_buf bb_common_bufsiz1
112 setup_common_bufsiz();
113 do {
114 fd = open_or_warn_stdin(*argv);
115 if (fd < 0) {
116 retval = EXIT_FAILURE;
117 continue;
118 }
119 for (;;) {
120 int i, res;
121
122 res = read(fd, read_buf, COMMON_BUFSIZE);
123 if (res < 0)
124 retval = EXIT_FAILURE;
125 if (res <= 0)
126 break;
127 for (i = 0; i < res; i++) {
128 unsigned char c = read_buf[i];
129 char buf[sizeof("M-^c")];
130 visible(c, buf, opts);
131 fputs(buf, stdout);
132 }
133 }
134 if (ENABLE_FEATURE_CLEAN_UP && fd)
135 close(fd);
136 } while (*++argv);
137
138 fflush_stdout_and_exit(retval);
139}
140#endif
49 141
50int cat_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 142int cat_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
51int cat_main(int argc UNUSED_PARAM, char **argv) 143int cat_main(int argc UNUSED_PARAM, char **argv)
52{ 144{
53 struct number_state ns; 145 struct number_state ns;
54 unsigned opt; 146 unsigned opts;
55 147
56 /* -u is ignored */ 148 IF_FEATURE_CATV(opt_complementary = "Aetv"; /* -A == -vet */)
57 opt = getopt32(argv, "nbu"); 149 /* -u is ignored ("unbuffered") */
150 opts = getopt32(argv, IF_FEATURE_CATV("etvA")"nbu");
58 argv += optind; 151 argv += optind;
59 if (!(opt & 3)) /* no -n or -b */ 152
153#if ENABLE_FEATURE_CATV
154 if (opts & 7)
155 return catv(opts, argv);
156//BUG: -v,-e,-t,-A ignore -nb
157 opts >>= 4;
158#endif
159
160#define CAT_OPT_n (1<<0)
161#define CAT_OPT_b (1<<1)
162#define CAT_OPT_u (1<<2)
163 if (!(opts & (CAT_OPT_n|CAT_OPT_b))) /* no -n or -b */
60 return bb_cat(argv); 164 return bb_cat(argv);
61 165
62 if (!*argv) 166 if (!*argv)
@@ -66,8 +170,8 @@ int cat_main(int argc UNUSED_PARAM, char **argv)
66 ns.inc = 1; 170 ns.inc = 1;
67 ns.sep = "\t"; 171 ns.sep = "\t";
68 ns.empty_str = "\n"; 172 ns.empty_str = "\n";
69 ns.all = !(opt & 2); /* -n without -b */ 173 ns.all = !(opts & CAT_OPT_b); /* -n without -b */
70 ns.nonempty = (opt & 2); /* -b (with or without -n) */ 174 ns.nonempty = (opts & CAT_OPT_b); /* -b (with or without -n) */
71 do { 175 do {
72 print_numbered_lines(&ns, *argv); 176 print_numbered_lines(&ns, *argv);
73 } while (*++argv); 177 } while (*++argv);