]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
ul: remove function prototypes
authorSami Kerola <kerolasa@iki.fi>
Mon, 29 Jun 2020 20:41:38 +0000 (21:41 +0100)
committerSami Kerola <kerolasa@iki.fi>
Tue, 20 Oct 2020 19:29:27 +0000 (20:29 +0100)
Signed-off-by: Sami Kerola <kerolasa@iki.fi>
text-utils/ul.c

index f23991d9145d917b663c2d58ff61ad8f5fe5601e..6aa986a6429681b4bf1fc73c70813d88487b6d7e 100644 (file)
@@ -78,22 +78,6 @@ static int put1wc(int c)
 # define putwp(s) putp(s)
 #endif
 
-static int handle_escape(FILE *f);
-static void filter(FILE *f);
-static void flushln(void);
-static void overstrike(void);
-static void iattr(void);
-static void initbuf(void);
-static void fwd(void);
-static void reverse(void);
-static void initinfo(void);
-static void outc(wint_t c, int width);
-static void xsetmode(int newmode);
-static void setcol(int newcol);
-static void needcol(int col);
-static void sig_handler(int signo);
-static void print_out(char *line);
-
 #define        IESC    '\033'
 #define        SO      '\016'
 #define        SI      '\017'
@@ -136,6 +120,8 @@ static int  halfpos;
 static int     upln;
 static int     iflag;
 
+static int curmode = 0;
+
 static void __attribute__((__noreturn__)) usage(void)
 {
        FILE *out = stdout;
@@ -157,248 +143,193 @@ static void __attribute__((__noreturn__)) usage(void)
        exit(EXIT_SUCCESS);
 }
 
-int main(int argc, char **argv)
+static void needcol(int acol)
 {
-       int c, ret, tflag = 0;
-       char *termtype;
-       FILE *f;
+       maxcol = acol;
 
-       static const struct option longopts[] = {
-               { "terminal",   required_argument,      NULL, 't' },
-               { "indicated",  no_argument,            NULL, 'i' },
-               { "version",    no_argument,            NULL, 'V' },
-               { "help",       no_argument,            NULL, 'h' },
-               { NULL, 0, NULL, 0 }
-       };
+       /* If col >= obuflen, expand obuf until obuflen > col. */
+       while (acol >= obuflen) {
+               /* Paranoid check for obuflen == INT_MAX. */
+               if (obuflen == INT_MAX)
+                       errx(EXIT_FAILURE, _("Input line too long."));
 
-       setlocale(LC_ALL, "");
-       bindtextdomain(PACKAGE, LOCALEDIR);
-       textdomain(PACKAGE);
-       close_stdout_atexit();
+               /* Similar paranoia: double only up to INT_MAX. */
+               if (obuflen < (INT_MAX / 2))
+                       obuflen *= 2;
+               else
+                       obuflen = INT_MAX;
 
-       signal(SIGINT, sig_handler);
-       signal(SIGTERM, sig_handler);
+               /* Now we can try to expand obuf. */
+               obuf = xrealloc(obuf, sizeof(struct CHAR) * obuflen);
+       }
+}
 
-       termtype = getenv("TERM");
+static void setcol(int newcol)
+{
+       col = newcol;
 
-       while ((c = getopt_long(argc, argv, "it:T:Vh", longopts, NULL)) != -1)
-               switch (c) {
+       if (col < 0)
+               col = 0;
+       else if (col > maxcol)
+               needcol(col);
+}
 
-               case 't':
-               case 'T':
-                       /* for nroff compatibility */
-                       termtype = optarg;
-                       tflag = 1;
-                       break;
-               case 'i':
-                       iflag = 1;
-                       break;
+static void initbuf(void)
+{
+       if (obuf == NULL) {
+               /* First time. */
+               obuflen = BUFSIZ;
+               obuf = xcalloc(obuflen, sizeof(struct CHAR));
+       } else
+               /* assumes NORMAL == 0 */
+               memset(obuf, 0, sizeof(struct CHAR) * maxcol);
 
-               case 'V':
-                       print_version(EXIT_SUCCESS);
-               case 'h':
-                       usage();
-               default:
-                       errtryhelp(EXIT_FAILURE);
-               }
-       setupterm(termtype, STDOUT_FILENO, &ret);
-       switch (ret) {
+       setcol(0);
+       maxcol = 0;
+       mode &= ALTSET;
+}
 
-       case 1:
-               break;
+static void initinfo(void)
+{
+       CURS_UP         = tigetstr("cuu1");
+       CURS_RIGHT      = tigetstr("cuf1");
+       CURS_LEFT       = tigetstr("cub1");
+       if (CURS_LEFT == NULL)
+               CURS_LEFT = "\b";
 
-       default:
-               warnx(_("trouble reading terminfo"));
-               /* fallthrough */
+       ENTER_STANDOUT  = tigetstr("smso");
+       EXIT_STANDOUT   = tigetstr("rmso");
+       ENTER_UNDERLINE = tigetstr("smul");
+       EXIT_UNDERLINE  = tigetstr("rmul");
+       ENTER_DIM       = tigetstr("dim");
+       ENTER_BOLD      = tigetstr("bold");
+       ENTER_REVERSE   = tigetstr("rev");
+       EXIT_ATTRIBUTES = tigetstr("sgr0");
 
-       case 0:
-               if (tflag)
-                       warnx(_("terminal `%s' is not known, defaulting to `dumb'"),
-                               termtype);
-               setupterm("dumb", STDOUT_FILENO, (int *)0);
-               break;
+       if (!ENTER_BOLD && ENTER_REVERSE)
+               ENTER_BOLD = ENTER_REVERSE;
+       if (!ENTER_BOLD && ENTER_STANDOUT)
+               ENTER_BOLD = ENTER_STANDOUT;
+       if (!ENTER_UNDERLINE && ENTER_STANDOUT) {
+               ENTER_UNDERLINE = ENTER_STANDOUT;
+               EXIT_UNDERLINE = EXIT_STANDOUT;
        }
+       if (!ENTER_DIM && ENTER_STANDOUT)
+               ENTER_DIM = ENTER_STANDOUT;
+       if (!ENTER_REVERSE && ENTER_STANDOUT)
+               ENTER_REVERSE = ENTER_STANDOUT;
+       if (!EXIT_ATTRIBUTES && EXIT_STANDOUT)
+               EXIT_ATTRIBUTES = EXIT_STANDOUT;
 
-       initinfo();
-       if ((tigetflag("os") && ENTER_BOLD == NULL) ||
-           (tigetflag("ul") && ENTER_UNDERLINE == NULL && UNDER_CHAR == NULL))
-               must_overstrike = 1;
-       initbuf();
-       if (optind == argc)
-               filter(stdin);
-       else
-               for (; optind < argc; optind++) {
-                       f = fopen(argv[optind], "r");
-                       if (!f)
-                               err(EXIT_FAILURE, _("cannot open %s"), argv[optind]);
-                       filter(f);
-                       fclose(f);
-               }
-       free(obuf);
-       return EXIT_SUCCESS;
+       /*
+        * Note that we use REVERSE for the alternate character set,
+        * not the as/ae capabilities.  This is because we are modeling
+        * the model 37 teletype (since that's what nroff outputs) and
+        * the typical as/ae is more of a graphics set, not the greek
+        * letters the 37 has.
+        */
+       UNDER_CHAR = tigetstr("uc");
+       must_use_uc = (UNDER_CHAR && !ENTER_UNDERLINE);
 }
 
-static int handle_escape(FILE *f)
+static void sig_handler(int signo __attribute__((__unused__)))
 {
-       wint_t c;
+       _exit(EXIT_SUCCESS);
+}
 
-       switch (c = getwc(f)) {
-       case HREV:
-               if (halfpos == 0) {
-                       mode |= SUPERSC;
-                       halfpos--;
-               } else if (halfpos > 0) {
-                       mode &= ~SUBSC;
-                       halfpos--;
-               } else {
-                       halfpos = 0;
-                       reverse();
-               }
-               return 0;
-       case HFWD:
-               if (halfpos == 0) {
-                       mode |= SUBSC;
-                       halfpos++;
-               } else if (halfpos < 0) {
-                       mode &= ~SUPERSC;
-                       halfpos++;
-               } else {
-                       halfpos = 0;
-                       fwd();
+static void print_out(char *line)
+{
+       if (line == NULL)
+               return;
+
+       putwp(line);
+}
+
+static void xsetmode(int newmode)
+{
+       if (!iflag) {
+               if (curmode != NORMAL && newmode != NORMAL)
+                       xsetmode(NORMAL);
+               switch (newmode) {
+               case NORMAL:
+                       switch (curmode) {
+                       case NORMAL:
+                               break;
+                       case UNDERL:
+                               print_out(EXIT_UNDERLINE);
+                               break;
+                       default:
+                               /* This includes standout */
+                               print_out(EXIT_ATTRIBUTES);
+                               break;
+                       }
+                       break;
+               case ALTSET:
+                       print_out(ENTER_REVERSE);
+                       break;
+               case SUPERSC:
+                       /*
+                        * This only works on a few terminals.
+                        * It should be fixed.
+                        */
+                       print_out(ENTER_UNDERLINE);
+                       print_out(ENTER_DIM);
+                       break;
+               case SUBSC:
+                       print_out(ENTER_DIM);
+                       break;
+               case UNDERL:
+                       print_out(ENTER_UNDERLINE);
+                       break;
+               case BOLD:
+                       print_out(ENTER_BOLD);
+                       break;
+               default:
+                       /*
+                        * We should have some provision here for multiple modes
+                        * on at once.  This will have to come later.
+                        */
+                       print_out(ENTER_STANDOUT);
+                       break;
                }
-               return 0;
-       case FREV:
-               reverse();
-               return 0;
-       default:
-               /* unknown escape */
-               ungetwc(c, f);
-               return 1;
        }
+       curmode = newmode;
 }
 
-static void filter(FILE *f)
+static void iattr(void)
 {
-       wint_t c;
-       int i, w;
+       int i;
+       wchar_t *lbuf = xcalloc(maxcol + 1, sizeof(wchar_t));
+       wchar_t *cp = lbuf;
 
-       while ((c = getwc(f)) != WEOF) {
-               switch (c) {
-               case '\b':
-                       setcol(col - 1);
-                       continue;
-               case '\t':
-                       setcol((col + 8) & ~07);
-                       continue;
-               case '\r':
-                       setcol(0);
-                       continue;
-               case SO:
-                       mode |= ALTSET;
-                       continue;
-               case SI:
-                       mode &= ~ALTSET;
-                       continue;
-               case IESC:
-                       if (handle_escape(f)) {
-                               c = getwc(f);
-                               errx(EXIT_FAILURE,
-                                    _("unknown escape sequence in input: %o, %o"), IESC, c);
-                       }
-                       continue;
-               case '_':
-                       if (obuf[col].c_char || obuf[col].c_width < 0) {
-                               while (col > 0 && obuf[col].c_width < 0)
-                                       col--;
-                               w = obuf[col].c_width;
-                               for (i = 0; i < w; i++)
-                                       obuf[col++].c_mode |= UNDERL | mode;
-                               setcol(col);
-                               continue;
-                       }
-                       obuf[col].c_char = '_';
-                       obuf[col].c_width = 1;
-                       /* fallthrough */
-               case ' ':
-                       setcol(col + 1);
-                       continue;
-               case '\n':
-                       flushln();
-                       continue;
-               case '\f':
-                       flushln();
-                       putwchar('\f');
-                       continue;
-               default:
-                       if (!iswprint(c))
-                               /* non printable */
-                               continue;
-                       w = wcwidth(c);
-                       needcol(col + w);
-                       if (obuf[col].c_char == '\0') {
-                               obuf[col].c_char = c;
-                               for (i = 0; i < w; i++)
-                                       obuf[col + i].c_mode = mode;
-                               obuf[col].c_width = w;
-                               for (i = 1; i < w; i++)
-                                       obuf[col + i].c_width = -1;
-                       } else if (obuf[col].c_char == '_') {
-                               obuf[col].c_char = c;
-                               for (i = 0; i < w; i++)
-                                       obuf[col + i].c_mode |= UNDERL | mode;
-                               obuf[col].c_width = w;
-                               for (i = 1; i < w; i++)
-                                       obuf[col + i].c_width = -1;
-                       } else if ((wint_t) obuf[col].c_char == c) {
-                               for (i = 0; i < w; i++)
-                                       obuf[col + i].c_mode |= BOLD | mode;
-                       } else {
-                               w = obuf[col].c_width;
-                               for (i = 0; i < w; i++)
-                                       obuf[col + i].c_mode = mode;
-                       }
-                       setcol(col + w);
-                       continue;
+       for (i = 0; i < maxcol; i++)
+               switch (obuf[i].c_mode) {
+               case NORMAL:    *cp++ = ' '; break;
+               case ALTSET:    *cp++ = 'g'; break;
+               case SUPERSC:   *cp++ = '^'; break;
+               case SUBSC:     *cp++ = 'v'; break;
+               case UNDERL:    *cp++ = '_'; break;
+               case BOLD:      *cp++ = '!'; break;
+               default:        *cp++ = 'X'; break;
                }
-       }
-       if (maxcol)
-               flushln();
+       for (*cp = ' '; *cp == ' '; cp--)
+               *cp = 0;
+       fputws(lbuf, stdout);
+       putwchar('\n');
+       free(lbuf);
 }
 
-static void flushln(void)
+static void outc(wint_t c, int width)
 {
-       int lastmode;
        int i;
-       int hadmodes = 0;
 
-       lastmode = NORMAL;
-       for (i = 0; i < maxcol; i++) {
-               if (obuf[i].c_mode != lastmode) {
-                       hadmodes++;
-                       xsetmode(obuf[i].c_mode);
-                       lastmode = obuf[i].c_mode;
-               }
-               if (obuf[i].c_char == '\0') {
-                       if (upln)
-                               print_out(CURS_RIGHT);
-                       else
-                               outc(' ', 1);
-               } else
-                       outc(obuf[i].c_char, obuf[i].c_width);
-               if (obuf[i].c_width > 1)
-                       i += obuf[i].c_width - 1;
+       putwchar(c);
+       if (must_use_uc && (curmode & UNDERL)) {
+               for (i = 0; i < width; i++)
+                       print_out(CURS_LEFT);
+               for (i = 0; i < width; i++)
+                       print_out(UNDER_CHAR);
        }
-       if (lastmode != NORMAL)
-               xsetmode(NORMAL);
-       if (must_overstrike && hadmodes)
-               overstrike();
-       putwchar('\n');
-       if (iflag && hadmodes)
-               iattr();
-       fflush(stdout);
-       if (upln)
-               upln--;
-       initbuf();
 }
 
 /*
@@ -444,42 +375,40 @@ static void overstrike(void)
        free(lbuf);
 }
 
-static void iattr(void)
+static void flushln(void)
 {
+       int lastmode;
        int i;
-       wchar_t *lbuf = xcalloc(maxcol + 1, sizeof(wchar_t));
-       wchar_t *cp = lbuf;
+       int hadmodes = 0;
 
-       for (i = 0; i < maxcol; i++)
-               switch (obuf[i].c_mode) {
-               case NORMAL:    *cp++ = ' '; break;
-               case ALTSET:    *cp++ = 'g'; break;
-               case SUPERSC:   *cp++ = '^'; break;
-               case SUBSC:     *cp++ = 'v'; break;
-               case UNDERL:    *cp++ = '_'; break;
-               case BOLD:      *cp++ = '!'; break;
-               default:        *cp++ = 'X'; break;
+       lastmode = NORMAL;
+       for (i = 0; i < maxcol; i++) {
+               if (obuf[i].c_mode != lastmode) {
+                       hadmodes++;
+                       xsetmode(obuf[i].c_mode);
+                       lastmode = obuf[i].c_mode;
                }
-       for (*cp = ' '; *cp == ' '; cp--)
-               *cp = 0;
-       fputws(lbuf, stdout);
+               if (obuf[i].c_char == '\0') {
+                       if (upln)
+                               print_out(CURS_RIGHT);
+                       else
+                               outc(' ', 1);
+               } else
+                       outc(obuf[i].c_char, obuf[i].c_width);
+               if (obuf[i].c_width > 1)
+                       i += obuf[i].c_width - 1;
+       }
+       if (lastmode != NORMAL)
+               xsetmode(NORMAL);
+       if (must_overstrike && hadmodes)
+               overstrike();
        putwchar('\n');
-       free(lbuf);
-}
-
-static void initbuf(void)
-{
-       if (obuf == NULL) {
-               /* First time. */
-               obuflen = BUFSIZ;
-               obuf = xcalloc(obuflen, sizeof(struct CHAR));
-       } else
-               /* assumes NORMAL == 0 */
-               memset(obuf, 0, sizeof(struct CHAR) * maxcol);
-
-       setcol(0);
-       maxcol = 0;
-       mode &= ALTSET;
+       if (iflag && hadmodes)
+               iattr();
+       fflush(stdout);
+       if (upln)
+               upln--;
+       initbuf();
 }
 
 static void fwd(void)
@@ -502,155 +431,210 @@ static void reverse(void)
        upln++;
 }
 
-static void initinfo(void)
+static int handle_escape(FILE *f)
 {
-       CURS_UP         = tigetstr("cuu1");
-       CURS_RIGHT      = tigetstr("cuf1");
-       CURS_LEFT       = tigetstr("cub1");
-       if (CURS_LEFT == NULL)
-               CURS_LEFT = "\b";
-
-       ENTER_STANDOUT  = tigetstr("smso");
-       EXIT_STANDOUT   = tigetstr("rmso");
-       ENTER_UNDERLINE = tigetstr("smul");
-       EXIT_UNDERLINE  = tigetstr("rmul");
-       ENTER_DIM       = tigetstr("dim");
-       ENTER_BOLD      = tigetstr("bold");
-       ENTER_REVERSE   = tigetstr("rev");
-       EXIT_ATTRIBUTES = tigetstr("sgr0");
+       wint_t c;
 
-       if (!ENTER_BOLD && ENTER_REVERSE)
-               ENTER_BOLD = ENTER_REVERSE;
-       if (!ENTER_BOLD && ENTER_STANDOUT)
-               ENTER_BOLD = ENTER_STANDOUT;
-       if (!ENTER_UNDERLINE && ENTER_STANDOUT) {
-               ENTER_UNDERLINE = ENTER_STANDOUT;
-               EXIT_UNDERLINE = EXIT_STANDOUT;
+       switch (c = getwc(f)) {
+       case HREV:
+               if (halfpos == 0) {
+                       mode |= SUPERSC;
+                       halfpos--;
+               } else if (halfpos > 0) {
+                       mode &= ~SUBSC;
+                       halfpos--;
+               } else {
+                       halfpos = 0;
+                       reverse();
+               }
+               return 0;
+       case HFWD:
+               if (halfpos == 0) {
+                       mode |= SUBSC;
+                       halfpos++;
+               } else if (halfpos < 0) {
+                       mode &= ~SUPERSC;
+                       halfpos++;
+               } else {
+                       halfpos = 0;
+                       fwd();
+               }
+               return 0;
+       case FREV:
+               reverse();
+               return 0;
+       default:
+               /* unknown escape */
+               ungetwc(c, f);
+               return 1;
        }
-       if (!ENTER_DIM && ENTER_STANDOUT)
-               ENTER_DIM = ENTER_STANDOUT;
-       if (!ENTER_REVERSE && ENTER_STANDOUT)
-               ENTER_REVERSE = ENTER_STANDOUT;
-       if (!EXIT_ATTRIBUTES && EXIT_STANDOUT)
-               EXIT_ATTRIBUTES = EXIT_STANDOUT;
-
-       /*
-        * Note that we use REVERSE for the alternate character set,
-        * not the as/ae capabilities.  This is because we are modeling
-        * the model 37 teletype (since that's what nroff outputs) and
-        * the typical as/ae is more of a graphics set, not the greek
-        * letters the 37 has.
-        */
-       UNDER_CHAR = tigetstr("uc");
-       must_use_uc = (UNDER_CHAR && !ENTER_UNDERLINE);
 }
 
-static int curmode = 0;
-
-static void outc(wint_t c, int width)
+static void filter(FILE *f)
 {
-       int i;
-
-       putwchar(c);
-       if (must_use_uc && (curmode & UNDERL)) {
-               for (i = 0; i < width; i++)
-                       print_out(CURS_LEFT);
-               for (i = 0; i < width; i++)
-                       print_out(UNDER_CHAR);
-       }
-}
+       wint_t c;
+       int i, w;
 
-static void xsetmode(int newmode)
-{
-       if (!iflag) {
-               if (curmode != NORMAL && newmode != NORMAL)
-                       xsetmode(NORMAL);
-               switch (newmode) {
-               case NORMAL:
-                       switch (curmode) {
-                       case NORMAL:
-                               break;
-                       case UNDERL:
-                               print_out(EXIT_UNDERLINE);
-                               break;
-                       default:
-                               /* This includes standout */
-                               print_out(EXIT_ATTRIBUTES);
-                               break;
+       while ((c = getwc(f)) != WEOF) {
+               switch (c) {
+               case '\b':
+                       setcol(col - 1);
+                       continue;
+               case '\t':
+                       setcol((col + 8) & ~07);
+                       continue;
+               case '\r':
+                       setcol(0);
+                       continue;
+               case SO:
+                       mode |= ALTSET;
+                       continue;
+               case SI:
+                       mode &= ~ALTSET;
+                       continue;
+               case IESC:
+                       if (handle_escape(f)) {
+                               c = getwc(f);
+                               errx(EXIT_FAILURE,
+                                    _("unknown escape sequence in input: %o, %o"), IESC, c);
                        }
-                       break;
-               case ALTSET:
-                       print_out(ENTER_REVERSE);
-                       break;
-               case SUPERSC:
-                       /*
-                        * This only works on a few terminals.
-                        * It should be fixed.
-                        */
-                       print_out(ENTER_UNDERLINE);
-                       print_out(ENTER_DIM);
-                       break;
-               case SUBSC:
-                       print_out(ENTER_DIM);
-                       break;
-               case UNDERL:
-                       print_out(ENTER_UNDERLINE);
-                       break;
-               case BOLD:
-                       print_out(ENTER_BOLD);
-                       break;
+                       continue;
+               case '_':
+                       if (obuf[col].c_char || obuf[col].c_width < 0) {
+                               while (col > 0 && obuf[col].c_width < 0)
+                                       col--;
+                               w = obuf[col].c_width;
+                               for (i = 0; i < w; i++)
+                                       obuf[col++].c_mode |= UNDERL | mode;
+                               setcol(col);
+                               continue;
+                       }
+                       obuf[col].c_char = '_';
+                       obuf[col].c_width = 1;
+                       /* fallthrough */
+               case ' ':
+                       setcol(col + 1);
+                       continue;
+               case '\n':
+                       flushln();
+                       continue;
+               case '\f':
+                       flushln();
+                       putwchar('\f');
+                       continue;
                default:
-                       /*
-                        * We should have some provision here for multiple modes
-                        * on at once.  This will have to come later.
-                        */
-                       print_out(ENTER_STANDOUT);
-                       break;
+                       if (!iswprint(c))
+                               /* non printable */
+                               continue;
+                       w = wcwidth(c);
+                       needcol(col + w);
+                       if (obuf[col].c_char == '\0') {
+                               obuf[col].c_char = c;
+                               for (i = 0; i < w; i++)
+                                       obuf[col + i].c_mode = mode;
+                               obuf[col].c_width = w;
+                               for (i = 1; i < w; i++)
+                                       obuf[col + i].c_width = -1;
+                       } else if (obuf[col].c_char == '_') {
+                               obuf[col].c_char = c;
+                               for (i = 0; i < w; i++)
+                                       obuf[col + i].c_mode |= UNDERL | mode;
+                               obuf[col].c_width = w;
+                               for (i = 1; i < w; i++)
+                                       obuf[col + i].c_width = -1;
+                       } else if ((wint_t) obuf[col].c_char == c) {
+                               for (i = 0; i < w; i++)
+                                       obuf[col + i].c_mode |= BOLD | mode;
+                       } else {
+                               w = obuf[col].c_width;
+                               for (i = 0; i < w; i++)
+                                       obuf[col + i].c_mode = mode;
+                       }
+                       setcol(col + w);
+                       continue;
                }
        }
-       curmode = newmode;
+       if (maxcol)
+               flushln();
 }
 
-static void setcol(int newcol)
+int main(int argc, char **argv)
 {
-       col = newcol;
+       int c, ret, tflag = 0;
+       char *termtype;
+       FILE *f;
 
-       if (col < 0)
-               col = 0;
-       else if (col > maxcol)
-               needcol(col);
-}
+       static const struct option longopts[] = {
+               { "terminal",   required_argument,      NULL, 't' },
+               { "indicated",  no_argument,            NULL, 'i' },
+               { "version",    no_argument,            NULL, 'V' },
+               { "help",       no_argument,            NULL, 'h' },
+               { NULL, 0, NULL, 0 }
+       };
 
-static void needcol(int acol)
-{
-       maxcol = acol;
+       setlocale(LC_ALL, "");
+       bindtextdomain(PACKAGE, LOCALEDIR);
+       textdomain(PACKAGE);
+       close_stdout_atexit();
 
-       /* If col >= obuflen, expand obuf until obuflen > col. */
-       while (acol >= obuflen) {
-               /* Paranoid check for obuflen == INT_MAX. */
-               if (obuflen == INT_MAX)
-                       errx(EXIT_FAILURE, _("Input line too long."));
+       signal(SIGINT, sig_handler);
+       signal(SIGTERM, sig_handler);
 
-               /* Similar paranoia: double only up to INT_MAX. */
-               if (obuflen < (INT_MAX / 2))
-                       obuflen *= 2;
-               else
-                       obuflen = INT_MAX;
+       termtype = getenv("TERM");
 
-               /* Now we can try to expand obuf. */
-               obuf = xrealloc(obuf, sizeof(struct CHAR) * obuflen);
-       }
-}
+       while ((c = getopt_long(argc, argv, "it:T:Vh", longopts, NULL)) != -1)
+               switch (c) {
 
-static void sig_handler(int signo __attribute__((__unused__)))
-{
-       _exit(EXIT_SUCCESS);
-}
+               case 't':
+               case 'T':
+                       /* for nroff compatibility */
+                       termtype = optarg;
+                       tflag = 1;
+                       break;
+               case 'i':
+                       iflag = 1;
+                       break;
 
-static void print_out(char *line)
-{
-       if (line == NULL)
-               return;
+               case 'V':
+                       print_version(EXIT_SUCCESS);
+               case 'h':
+                       usage();
+               default:
+                       errtryhelp(EXIT_FAILURE);
+               }
+       setupterm(termtype, STDOUT_FILENO, &ret);
+       switch (ret) {
 
-       putwp(line);
+       case 1:
+               break;
+
+       default:
+               warnx(_("trouble reading terminfo"));
+               /* fallthrough */
+
+       case 0:
+               if (tflag)
+                       warnx(_("terminal `%s' is not known, defaulting to `dumb'"),
+                               termtype);
+               setupterm("dumb", STDOUT_FILENO, (int *)0);
+               break;
+       }
+
+       initinfo();
+       if ((tigetflag("os") && ENTER_BOLD == NULL) ||
+           (tigetflag("ul") && ENTER_UNDERLINE == NULL && UNDER_CHAR == NULL))
+               must_overstrike = 1;
+       initbuf();
+       if (optind == argc)
+               filter(stdin);
+       else
+               for (; optind < argc; optind++) {
+                       f = fopen(argv[optind], "r");
+                       if (!f)
+                               err(EXIT_FAILURE, _("cannot open %s"), argv[optind]);
+                       filter(f);
+                       fclose(f);
+               }
+       free(obuf);
+       return EXIT_SUCCESS;
 }