]> git.ipfire.org Git - thirdparty/util-linux.git/blame - text-utils/ul.c
libfdisk: (dos) accept start for log.partitions on template
[thirdparty/util-linux.git] / text-utils / ul.c
CommitLineData
6dbe3af9
KZ
1/*
2 * Copyright (c) 1980, 1993
3 * The Regents of the University of California. 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
fd6b7a7f 34/*
eb63b9b8
KZ
35 * modified by Kars de Jong <jongk@cs.utwente.nl>
36 * to use terminfo instead of termcap.
b50945d4 37 * 1999-02-22 Arkadiusz Miƛkiewicz <misiek@pld.ORG.PL>
eb63b9b8
KZ
38 * added Native Language Support
39 * 1999-09-19 Bruno Haible <haible@clisp.cons.org>
40 * modified to work correctly in multi-byte locales
41 */
fd6b7a7f 42
6dbe3af9 43#include <stdio.h>
fd6b7a7f 44#include <unistd.h> /* for getopt(), isatty() */
c0f19ccf 45#include <string.h> /* for memset(), strcpy() */
2b6fc908 46#include <stdlib.h> /* for getenv() */
5c36a0eb 47#include <limits.h> /* for INT_MAX */
4727b169 48#include <signal.h> /* for signal() */
59f8c787 49#include <errno.h>
a3b76180 50#include <getopt.h>
fd6b7a7f 51
3947ca4c
KZ
52#if defined(HAVE_NCURSESW_TERM_H)
53# include <ncursesw/term.h>
2ac1bc84
KZ
54#elif defined(HAVE_NCURSES_TERM_H)
55# include <ncurses/term.h>
3947ca4c
KZ
56#elif defined(HAVE_TERM_H)
57# include <term.h>
2ac1bc84
KZ
58#endif
59
f0961db2
DB
60#include "nls.h"
61#include "xalloc.h"
eb63b9b8 62#include "widechar.h"
eb76ca98 63#include "c.h"
b87cbe84 64#include "closestream.h"
eb63b9b8 65
06b04b23 66#ifdef HAVE_WIDECHAR
565239b0
SK
67/* Output an ASCII character as a wide character */
68static int put1wc(int c)
eb63b9b8 69{
565239b0
SK
70 if (putwchar(c) == WEOF)
71 return EOF;
72 else
73 return c;
eb63b9b8 74}
cc319747 75#define putwp(s) tputs(s, STDOUT_FILENO, put1wc)
eb63b9b8
KZ
76#else
77#define putwp(s) putp(s)
78#endif
79
a4949aaa 80static int handle_escape(FILE * f);
565239b0
SK
81static void filter(FILE *f);
82static void flushln(void);
83static void overstrike(void);
84static void iattr(void);
85static void initbuf(void);
86static void fwd(void);
87static void reverse(void);
88static void initinfo(void);
89static void outc(wint_t c, int width);
b0b24b11 90static void xsetmode(int newmode);
66ee8158
KZ
91static void setcol(int newcol);
92static void needcol(int col);
4727b169 93static void sig_handler(int signo);
cdbe31fc 94static void print_out(char *line);
6dbe3af9
KZ
95
96#define IESC '\033'
97#define SO '\016'
98#define SI '\017'
99#define HFWD '9'
100#define HREV '8'
101#define FREV '7'
6dbe3af9
KZ
102
103#define NORMAL 000
104#define ALTSET 001 /* Reverse */
105#define SUPERSC 002 /* Dim */
106#define SUBSC 004 /* Dim | Ul */
107#define UNDERL 010 /* Ul */
108#define BOLD 020 /* Bold */
109
2ba641e5
SK
110static int must_use_uc, must_overstrike;
111static char *CURS_UP,
112 *CURS_RIGHT,
113 *CURS_LEFT,
114 *ENTER_STANDOUT,
115 *EXIT_STANDOUT,
116 *ENTER_UNDERLINE,
117 *EXIT_UNDERLINE,
118 *ENTER_DIM,
119 *ENTER_BOLD,
120 *ENTER_REVERSE,
121 *UNDER_CHAR,
122 *EXIT_ATTRIBUTES;
6dbe3af9 123
2ba641e5 124struct CHAR {
6dbe3af9 125 char c_mode;
eb63b9b8 126 wchar_t c_char;
66ee8158 127 int c_width;
565239b0 128};
6dbe3af9 129
2ba641e5
SK
130static struct CHAR *obuf;
131static int obuflen;
132static int col, maxcol;
133static int mode;
134static int halfpos;
135static int upln;
136static int iflag;
6dbe3af9 137
a3b76180
SK
138static void __attribute__((__noreturn__))
139usage(FILE *out)
140{
a2343e03
KZ
141 fputs(USAGE_HEADER, out);
142 fprintf(out, _(" %s [options] [<file> ...]\n"), program_invocation_short_name);
a3b76180 143
451dbcfa
BS
144 fputs(USAGE_SEPARATOR, out);
145 fputs(_("Do underlining.\n"), out);
146
147 fputs(USAGE_OPTIONS, out);
a2343e03
KZ
148 fputs(_(" -t, -T, --terminal TERMINAL override the TERM environment variable\n"), out);
149 fputs(_(" -i, --indicated underlining is indicated via a separate line\n"), out);
150 fputs(USAGE_SEPARATOR, out);
151 fputs(USAGE_HELP, out);
152 fputs(USAGE_VERSION, out);
153
154 fprintf(out, USAGE_MAN_TAIL("ul(1)"));
a3b76180
SK
155
156 exit(out == stderr ? EXIT_FAILURE : EXIT_SUCCESS);
157}
158
fd6b7a7f 159int main(int argc, char **argv)
6dbe3af9 160{
0200c801 161 int c, ret, tflag = 0;
6dbe3af9
KZ
162 char *termtype;
163 FILE *f;
6dbe3af9 164
a3b76180 165 static const struct option longopts[] = {
87918040
SK
166 { "terminal", required_argument, NULL, 't' },
167 { "indicated", no_argument, NULL, 'i' },
168 { "version", no_argument, NULL, 'V' },
169 { "help", no_argument, NULL, 'h' },
170 { NULL, 0, NULL, 0 }
a3b76180
SK
171 };
172
7eda085c
KZ
173 setlocale(LC_ALL, "");
174 bindtextdomain(PACKAGE, LOCALEDIR);
175 textdomain(PACKAGE);
b87cbe84 176 atexit(close_stdout);
7eda085c 177
4727b169
DB
178 signal(SIGINT, sig_handler);
179 signal(SIGTERM, sig_handler);
180
6dbe3af9 181 termtype = getenv("TERM");
565239b0 182
a3b76180 183 while ((c = getopt_long(argc, argv, "it:T:Vh", longopts, NULL)) != -1)
565239b0 184 switch (c) {
6dbe3af9
KZ
185
186 case 't':
565239b0
SK
187 case 'T':
188 /* for nroff compatibility */
189 termtype = optarg;
0200c801 190 tflag = 1;
6dbe3af9
KZ
191 break;
192 case 'i':
193 iflag = 1;
194 break;
a3b76180 195 case 'V':
f6277500 196 printf(UTIL_LINUX_VERSION);
262aee0b 197 return EXIT_SUCCESS;
a3b76180
SK
198 case 'h':
199 usage(stdout);
6dbe3af9 200 default:
677ec86c 201 errtryhelp(EXIT_FAILURE);
6dbe3af9 202 }
cc319747 203 setupterm(termtype, STDOUT_FILENO, &ret);
565239b0 204 switch (ret) {
6dbe3af9
KZ
205
206 case 1:
207 break;
208
209 default:
59f8c787 210 warnx(_("trouble reading terminfo"));
6dbe3af9
KZ
211 /* fall through to ... */
212
213 case 0:
0200c801
SK
214 if (tflag)
215 warnx(_("terminal `%s' is not known, defaulting to `dumb'"),
216 termtype);
565239b0 217 setupterm("dumb", STDOUT_FILENO, (int *)0);
6dbe3af9
KZ
218 break;
219 }
fd6b7a7f 220 initinfo();
565239b0
SK
221 if ((tigetflag("os") && ENTER_BOLD==NULL ) ||
222 (tigetflag("ul") && ENTER_UNDERLINE==NULL && UNDER_CHAR==NULL))
223 must_overstrike = 1;
6dbe3af9
KZ
224 initbuf();
225 if (optind == argc)
226 filter(stdin);
565239b0
SK
227 else
228 for (; optind < argc; optind++) {
229 f = fopen(argv[optind],"r");
230 if (!f)
289dcc90 231 err(EXIT_FAILURE, _("cannot open %s"),
565239b0
SK
232 argv[optind]);
233 filter(f);
78b0fdd3 234 fclose(f);
565239b0 235 }
78b0fdd3 236 free(obuf);
59f8c787 237 return EXIT_SUCCESS;
6dbe3af9
KZ
238}
239
a4949aaa
SK
240static int handle_escape(FILE * f)
241{
242 wint_t c;
243
244 switch (c = getwc(f)) {
245 case HREV:
246 if (halfpos == 0) {
247 mode |= SUPERSC;
248 halfpos--;
249 } else if (halfpos > 0) {
250 mode &= ~SUBSC;
251 halfpos--;
252 } else {
253 halfpos = 0;
254 reverse();
255 }
256 return 0;
257 case HFWD:
258 if (halfpos == 0) {
259 mode |= SUBSC;
260 halfpos++;
261 } else if (halfpos < 0) {
262 mode &= ~SUPERSC;
263 halfpos++;
264 } else {
265 halfpos = 0;
266 fwd();
267 }
268 return 0;
269 case FREV:
270 reverse();
271 return 0;
272 default:
273 /* unknown escape */
274 ungetwc(c, f);
275 return 1;
276 }
277}
278
565239b0 279static void filter(FILE *f)
6dbe3af9 280{
eb63b9b8 281 wint_t c;
66ee8158 282 int i, w;
6dbe3af9 283
d07b2237
SK
284 while ((c = getwc(f)) != WEOF) {
285 switch (c) {
286 case '\b':
287 setcol(col - 1);
66ee8158 288 continue;
d07b2237
SK
289 case '\t':
290 setcol((col + 8) & ~07);
291 continue;
292 case '\r':
293 setcol(0);
294 continue;
295 case SO:
296 mode |= ALTSET;
297 continue;
298 case SI:
299 mode &= ~ALTSET;
300 continue;
301 case IESC:
302 if (handle_escape(f)) {
303 c = getwc(f);
304 errx(EXIT_FAILURE,
305 _("unknown escape sequence in input: %o, %o"), IESC, c);
306 }
307 continue;
308 case '_':
309 if (obuf[col].c_char || obuf[col].c_width < 0) {
310 while (col > 0 && obuf[col].c_width < 0)
311 col--;
312 w = obuf[col].c_width;
313 for (i = 0; i < w; i++)
314 obuf[col++].c_mode |= UNDERL | mode;
315 setcol(col);
316 continue;
317 }
318 obuf[col].c_char = '_';
319 obuf[col].c_width = 1;
320 /* fall through */
321 case ' ':
322 setcol(col + 1);
323 continue;
324 case '\n':
325 flushln();
326 continue;
327 case '\f':
328 flushln();
329 putwchar('\f');
330 continue;
331 default:
332 if (!iswprint(c))
333 /* non printable */
334 continue;
335 w = wcwidth(c);
336 needcol(col + w);
337 if (obuf[col].c_char == '\0') {
338 obuf[col].c_char = c;
339 for (i = 0; i < w; i++)
340 obuf[col + i].c_mode = mode;
341 obuf[col].c_width = w;
342 for (i = 1; i < w; i++)
343 obuf[col + i].c_width = -1;
344 } else if (obuf[col].c_char == '_') {
345 obuf[col].c_char = c;
346 for (i = 0; i < w; i++)
347 obuf[col + i].c_mode |= UNDERL | mode;
348 obuf[col].c_width = w;
349 for (i = 1; i < w; i++)
350 obuf[col + i].c_width = -1;
351 } else if ((wint_t) obuf[col].c_char == c) {
352 for (i = 0; i < w; i++)
353 obuf[col + i].c_mode |= BOLD | mode;
354 } else {
355 w = obuf[col].c_width;
356 for (i = 0; i < w; i++)
357 obuf[col + i].c_mode = mode;
358 }
359 setcol(col + w);
6dbe3af9 360 continue;
66ee8158 361 }
6dbe3af9
KZ
362 }
363 if (maxcol)
364 flushln();
365}
366
565239b0 367static void flushln(void)
6dbe3af9 368{
5c36a0eb
KZ
369 int lastmode;
370 int i;
6dbe3af9
KZ
371 int hadmodes = 0;
372
373 lastmode = NORMAL;
565239b0 374 for (i = 0; i < maxcol; i++) {
6dbe3af9
KZ
375 if (obuf[i].c_mode != lastmode) {
376 hadmodes++;
b0b24b11 377 xsetmode(obuf[i].c_mode);
6dbe3af9
KZ
378 lastmode = obuf[i].c_mode;
379 }
380 if (obuf[i].c_char == '\0') {
5c36a0eb 381 if (upln) {
cdbe31fc 382 print_out(CURS_RIGHT);
5c36a0eb 383 } else
66ee8158 384 outc(' ', 1);
6dbe3af9 385 } else
66ee8158
KZ
386 outc(obuf[i].c_char, obuf[i].c_width);
387 if (obuf[i].c_width > 1)
565239b0 388 i += obuf[i].c_width - 1;
6dbe3af9
KZ
389 }
390 if (lastmode != NORMAL) {
b0b24b11 391 xsetmode(0);
6dbe3af9
KZ
392 }
393 if (must_overstrike && hadmodes)
394 overstrike();
eb63b9b8 395 putwchar('\n');
6dbe3af9
KZ
396 if (iflag && hadmodes)
397 iattr();
565239b0 398 fflush(stdout);
6dbe3af9
KZ
399 if (upln)
400 upln--;
401 initbuf();
402}
403
404/*
405 * For terminals that can overstrike, overstrike underlines and bolds.
406 * We don't do anything with halfline ups and downs, or Greek.
407 */
565239b0 408static void overstrike(void)
6dbe3af9
KZ
409{
410 register int i;
f20b214e 411 register wchar_t *lbuf = xmalloc((maxcol + 1) * sizeof(wchar_t));
eb63b9b8 412 register wchar_t *cp = lbuf;
6dbe3af9
KZ
413 int hadbold=0;
414
415 /* Set up overstrike buffer */
565239b0 416 for (i = 0; i < maxcol; i++)
6dbe3af9
KZ
417 switch (obuf[i].c_mode) {
418 case NORMAL:
419 default:
420 *cp++ = ' ';
421 break;
422 case UNDERL:
423 *cp++ = '_';
424 break;
425 case BOLD:
426 *cp++ = obuf[i].c_char;
66ee8158
KZ
427 if (obuf[i].c_width > 1)
428 i += obuf[i].c_width - 1;
6dbe3af9
KZ
429 hadbold=1;
430 break;
431 }
eb63b9b8 432 putwchar('\r');
565239b0 433 for (*cp = ' '; *cp == ' '; cp--)
6dbe3af9 434 *cp = 0;
67519cdd 435 fputws(lbuf, stdout);
6dbe3af9 436 if (hadbold) {
eb63b9b8 437 putwchar('\r');
565239b0
SK
438 for (cp = lbuf; *cp; cp++)
439 putwchar(*cp == '_' ? ' ' : *cp);
eb63b9b8 440 putwchar('\r');
565239b0
SK
441 for (cp = lbuf; *cp; cp++)
442 putwchar(*cp == '_' ? ' ' : *cp);
6dbe3af9 443 }
f20b214e 444 free(lbuf);
6dbe3af9
KZ
445}
446
565239b0 447static void iattr(void)
6dbe3af9
KZ
448{
449 register int i;
f20b214e 450 register wchar_t *lbuf = xmalloc((maxcol + 1) * sizeof(wchar_t));
aa971f7d 451 register wchar_t *cp = lbuf;
6dbe3af9 452
565239b0 453 for (i = 0; i < maxcol; i++)
6dbe3af9
KZ
454 switch (obuf[i].c_mode) {
455 case NORMAL: *cp++ = ' '; break;
456 case ALTSET: *cp++ = 'g'; break;
457 case SUPERSC: *cp++ = '^'; break;
458 case SUBSC: *cp++ = 'v'; break;
459 case UNDERL: *cp++ = '_'; break;
460 case BOLD: *cp++ = '!'; break;
461 default: *cp++ = 'X'; break;
462 }
565239b0 463 for (*cp = ' '; *cp == ' '; cp--)
6dbe3af9 464 *cp = 0;
67519cdd 465 fputws(lbuf, stdout);
eb63b9b8 466 putwchar('\n');
f20b214e 467 free(lbuf);
6dbe3af9
KZ
468}
469
565239b0 470static void initbuf(void)
6dbe3af9 471{
565239b0
SK
472 if (obuf == NULL) {
473 /* First time. */
cc319747 474 obuflen = BUFSIZ;
99361a9c
SK
475 obuf = xcalloc(obuflen, sizeof(struct CHAR));
476 } else
477 /* assumes NORMAL == 0 */
478 memset(obuf, 0, sizeof(struct CHAR) * maxcol);
6dbe3af9 479
5c36a0eb 480 setcol(0);
6dbe3af9
KZ
481 maxcol = 0;
482 mode &= ALTSET;
483}
484
565239b0 485static void fwd(void)
6dbe3af9 486{
5c36a0eb 487 int oldcol, oldmax;
6dbe3af9
KZ
488
489 oldcol = col;
490 oldmax = maxcol;
491 flushln();
5c36a0eb 492 setcol(oldcol);
6dbe3af9
KZ
493 maxcol = oldmax;
494}
495
565239b0 496static void reverse(void)
6dbe3af9
KZ
497{
498 upln++;
499 fwd();
cdbe31fc
SK
500 print_out(CURS_UP);
501 print_out(CURS_UP);
6dbe3af9
KZ
502 upln++;
503}
504
565239b0 505static void initinfo(void)
6dbe3af9 506{
fd6b7a7f
KZ
507 CURS_UP = tigetstr("cuu1");
508 CURS_RIGHT = tigetstr("cuf1");
509 CURS_LEFT = tigetstr("cub1");
6dbe3af9 510 if (CURS_LEFT == NULL)
6dbe3af9
KZ
511 CURS_LEFT = "\b";
512
fd6b7a7f
KZ
513 ENTER_STANDOUT = tigetstr("smso");
514 EXIT_STANDOUT = tigetstr("rmso");
515 ENTER_UNDERLINE = tigetstr("smul");
516 EXIT_UNDERLINE = tigetstr("rmul");
517 ENTER_DIM = tigetstr("dim");
518 ENTER_BOLD = tigetstr("bold");
519 ENTER_REVERSE = tigetstr("rev");
520 EXIT_ATTRIBUTES = tigetstr("sgr0");
6dbe3af9
KZ
521
522 if (!ENTER_BOLD && ENTER_REVERSE)
523 ENTER_BOLD = ENTER_REVERSE;
524 if (!ENTER_BOLD && ENTER_STANDOUT)
525 ENTER_BOLD = ENTER_STANDOUT;
526 if (!ENTER_UNDERLINE && ENTER_STANDOUT) {
527 ENTER_UNDERLINE = ENTER_STANDOUT;
528 EXIT_UNDERLINE = EXIT_STANDOUT;
529 }
530 if (!ENTER_DIM && ENTER_STANDOUT)
531 ENTER_DIM = ENTER_STANDOUT;
532 if (!ENTER_REVERSE && ENTER_STANDOUT)
533 ENTER_REVERSE = ENTER_STANDOUT;
534 if (!EXIT_ATTRIBUTES && EXIT_STANDOUT)
535 EXIT_ATTRIBUTES = EXIT_STANDOUT;
59f8c787 536
6dbe3af9
KZ
537 /*
538 * Note that we use REVERSE for the alternate character set,
9e930041 539 * not the as/ae capabilities. This is because we are modeling
6dbe3af9
KZ
540 * the model 37 teletype (since that's what nroff outputs) and
541 * the typical as/ae is more of a graphics set, not the greek
542 * letters the 37 has.
543 */
544
fd6b7a7f 545 UNDER_CHAR = tigetstr("uc");
6dbe3af9
KZ
546 must_use_uc = (UNDER_CHAR && !ENTER_UNDERLINE);
547}
548
6dbe3af9
KZ
549static int curmode = 0;
550
565239b0 551static void outc(wint_t c, int width) {
66ee8158
KZ
552 int i;
553
eb63b9b8 554 putwchar(c);
6dbe3af9 555 if (must_use_uc && (curmode&UNDERL)) {
565239b0 556 for (i = 0; i < width; i++)
cdbe31fc 557 print_out(CURS_LEFT);
565239b0 558 for (i = 0; i < width; i++)
cdbe31fc 559 print_out(UNDER_CHAR);
6dbe3af9
KZ
560 }
561}
562
b0b24b11 563static void xsetmode(int newmode)
6dbe3af9
KZ
564{
565 if (!iflag) {
566 if (curmode != NORMAL && newmode != NORMAL)
b0b24b11 567 xsetmode(NORMAL);
6dbe3af9
KZ
568 switch (newmode) {
569 case NORMAL:
565239b0 570 switch (curmode) {
6dbe3af9
KZ
571 case NORMAL:
572 break;
573 case UNDERL:
cdbe31fc 574 print_out(EXIT_UNDERLINE);
6dbe3af9
KZ
575 break;
576 default:
577 /* This includes standout */
cdbe31fc 578 print_out(EXIT_ATTRIBUTES);
6dbe3af9
KZ
579 break;
580 }
581 break;
582 case ALTSET:
cdbe31fc 583 print_out(ENTER_REVERSE);
6dbe3af9
KZ
584 break;
585 case SUPERSC:
586 /*
587 * This only works on a few terminals.
588 * It should be fixed.
589 */
cdbe31fc
SK
590 print_out(ENTER_UNDERLINE);
591 print_out(ENTER_DIM);
6dbe3af9
KZ
592 break;
593 case SUBSC:
cdbe31fc 594 print_out(ENTER_DIM);
6dbe3af9
KZ
595 break;
596 case UNDERL:
cdbe31fc 597 print_out(ENTER_UNDERLINE);
6dbe3af9
KZ
598 break;
599 case BOLD:
cdbe31fc 600 print_out(ENTER_BOLD);
6dbe3af9
KZ
601 break;
602 default:
603 /*
604 * We should have some provision here for multiple modes
605 * on at once. This will have to come later.
606 */
cdbe31fc 607 print_out(ENTER_STANDOUT);
6dbe3af9
KZ
608 break;
609 }
610 }
611 curmode = newmode;
612}
5c36a0eb 613
565239b0 614static void setcol(int newcol) {
5c36a0eb
KZ
615 col = newcol;
616
617 if (col < 0)
618 col = 0;
66ee8158
KZ
619 else if (col > maxcol)
620 needcol(col);
621}
5c36a0eb 622
72851044
SK
623static void needcol(int acol) {
624 maxcol = acol;
66ee8158
KZ
625
626 /* If col >= obuflen, expand obuf until obuflen > col. */
72851044 627 while (acol >= obuflen) {
66ee8158 628 /* Paranoid check for obuflen == INT_MAX. */
59f8c787
KZ
629 if (obuflen == INT_MAX)
630 errx(EXIT_FAILURE, _("Input line too long."));
66ee8158
KZ
631
632 /* Similar paranoia: double only up to INT_MAX. */
565239b0
SK
633 if (obuflen < (INT_MAX / 2))
634 obuflen *= 2;
635 else
636 obuflen = INT_MAX;
66ee8158
KZ
637
638 /* Now we can try to expand obuf. */
f0961db2 639 obuf = xrealloc(obuf, sizeof(struct CHAR) * obuflen);
5c36a0eb
KZ
640 }
641}
4727b169 642
2afa872f 643static void sig_handler(int signo __attribute__ ((__unused__)))
4727b169 644{
50644ff4 645 _exit(EXIT_SUCCESS);
4727b169
DB
646}
647
cdbe31fc
SK
648static void print_out(char *line)
649{
650 if (line == NULL)
651 return;
652
653 putwp(line);
654}