]> git.ipfire.org Git - thirdparty/util-linux.git/blob - text-utils/colrm.c
misc: consolidate version printing and close_stdout()
[thirdparty/util-linux.git] / text-utils / colrm.c
1 /*
2 * Copyright (c) 1980 Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34 /*
35 * 1999-02-22 Arkadiusz Miƛkiewicz <misiek@pld.ORG.PL>
36 * added Native Language Support
37 * 1999-09-19 Bruno Haible <haible@clisp.cons.org>
38 * modified to work correctly in multi-byte locales
39 */
40
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <getopt.h>
44 #include <unistd.h>
45
46 #include "nls.h"
47 #include "strutils.h"
48 #include "c.h"
49 #include "widechar.h"
50 #include "closestream.h"
51
52 /*
53 COLRM removes unwanted columns from a file
54 Jeff Schriebman UC Berkeley 11-74
55 */
56
57 static void __attribute__((__noreturn__)) usage(void)
58 {
59 FILE *out = stdout;
60 fprintf(out, _("\nUsage:\n"
61 " %s [startcol [endcol]]\n"),
62 program_invocation_short_name);
63
64 fputs(USAGE_SEPARATOR, out);
65 fputs(_("Filter out the specified columns.\n"), out);
66
67 fputs(USAGE_OPTIONS, out);
68 printf(USAGE_HELP_OPTIONS(16));
69 fprintf(out, _("%s reads from standard input and writes to standard output\n\n"),
70 program_invocation_short_name);
71 printf(USAGE_MAN_TAIL("colrm(1)"));
72 exit(EXIT_SUCCESS);
73 }
74
75 static int process_input(unsigned long first, unsigned long last)
76 {
77 unsigned long ct = 0;
78 wint_t c;
79 unsigned long i;
80 int w;
81 int padding;
82
83 for (;;) {
84 c = getwc(stdin);
85 if (c == WEOF)
86 return 0;
87 if (c == '\t')
88 w = ((ct + 8) & ~7) - ct;
89 else if (c == '\b')
90 w = (ct ? ct - 1 : 0) - ct;
91 else {
92 w = wcwidth(c);
93 if (w < 0)
94 w = 0;
95 }
96 ct += w;
97 if (c == '\n') {
98 putwc(c, stdout);
99 ct = 0;
100 continue;
101
102 }
103 if (!first || ct < first) {
104 putwc(c, stdout);
105 continue;
106 }
107 break;
108 }
109
110 for (i = ct - w + 1; i < first; i++)
111 putwc(' ', stdout);
112
113 /* Loop getting rid of characters */
114 while (!last || ct < last) {
115 c = getwc(stdin);
116 if (c == WEOF)
117 return 0;
118 if (c == '\n') {
119 putwc(c, stdout);
120 return 1;
121 }
122 if (c == '\t')
123 ct = (ct + 8) & ~7;
124 else if (c == '\b')
125 ct = ct ? ct - 1 : 0;
126 else {
127 w = wcwidth(c);
128 if (w < 0)
129 w = 0;
130 ct += w;
131 }
132 }
133
134 padding = 0;
135
136 /* Output last of the line */
137 for (;;) {
138 c = getwc(stdin);
139 if (c == WEOF)
140 break;
141 if (c == '\n') {
142 putwc(c, stdout);
143 return 1;
144 }
145 if (padding == 0 && last < ct) {
146 for (i = last; i < ct; i++)
147 putwc(' ', stdout);
148 padding = 1;
149 }
150 putwc(c, stdout);
151 }
152 return 0;
153 }
154
155 int main(int argc, char **argv)
156 {
157 unsigned long first = 0, last = 0;
158 int opt;
159
160 static const struct option longopts[] = {
161 {"version", no_argument, NULL, 'V'},
162 {"help", no_argument, NULL, 'h'},
163 {NULL, 0, NULL, 0}
164 };
165
166 setlocale(LC_ALL, "");
167 bindtextdomain(PACKAGE, LOCALEDIR);
168 textdomain(PACKAGE);
169 atexit(close_stdout);
170
171 while ((opt =
172 getopt_long(argc, argv, "bfhl:pxVH", longopts,
173 NULL)) != -1)
174 switch (opt) {
175 case 'V':
176 print_version(EXIT_SUCCESS);
177 case 'h':
178 usage();
179 default:
180 errtryhelp(EXIT_FAILURE);
181 }
182
183 if (argc > 1)
184 first = strtoul_or_err(*++argv, _("first argument"));
185 if (argc > 2)
186 last = strtoul_or_err(*++argv, _("second argument"));
187
188 while (process_input(first, last))
189 ;
190
191 fflush(stdout);
192 return EXIT_SUCCESS;
193 }