Reindent with -TCOLUMN.
[platform/upstream/coreutils.git] / src / pr.c
1 /* pr -- convert text files for printing.
2    Copyright (C) 1988, 1991, 1995, 1996 Free Software Foundation, Inc.
3
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; either version 2, or (at your option)
7    any later version.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program; if not, write to the Free Software
16    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
17
18 /*  Author: Pete TerMaat.  */
19 \f
20 /* Things to watch: Sys V screws up on ...
21    pr -n -3 -s: /usr/dict/words
22    pr -m -o10 -n /usr/dict/words{,,,}
23    pr -6 -a -n -o5 /usr/dict/words
24
25    Ideas:
26
27    Keep a things_to_do list of functions to call when we know we have
28    something to print.  Cleaner than current series of checks.
29
30    Improve the printing of control prefixes.
31
32
33    Options:
34
35    +FIRST_PAGE[:LAST_PAGE]
36                 begin [stop] printing with page FIRST_[LAST_]PAGE
37
38    -COLUMN      Produce output that is COLUMN columns wide and print
39                 columns down.
40                 Balance columns on the last page is automatically set.
41
42    -a           Print columns across rather than down.  The input
43                 one
44                 two
45                 three
46                 four
47                 will be printed as
48                 one     two     three
49                 four
50
51    -b           Balance columns on the last page.
52                 -b is no longer an independent option. It's always used
53                 together with -COLUMN (unless -a is used) to get a
54                 consistent formulation with "FF set by hand" in input
55                 files. Each formfeed found terminates the number of lines
56                 to be read with the actual page. The situation for
57                 printing columns down is equivalent to that on the last
58                 page. So we need a balancing.
59
60                 We do not yet eliminate source text dealing with -COLUMN
61                 only. Tune this if it proved to be a satisfactory
62                 procedure.
63
64                 Keeping -b as an underground option guarantees some
65                 downward compatibility. Utilities using pr with -b
66                 (a most frequently used form) still work as usual.
67
68    -c           Print unprintable characters as control prefixes.
69                 Control-g is printed as ^G.
70
71    -d           Double space the output.
72
73    -e[c[k]]     Expand tabs to spaces on input.  Optional argument C
74                 is the input tab character. (Default is `\t'.)  Optional
75                 argument K is the input tab character's width.  (Default is 8.)
76
77    -F
78    -f           Use formfeeds instead of newlines to separate pages.
79                 A three line HEADER is used, no TRAILER (without -f
80                 both HEADER and TRAILER are made of five lines).
81
82    -h HEADER    Replace the filename in the header with the string HEADER.
83                 Checking and left-hand-side truncation of the length of the
84                 standard and custom header string. A centered header is used.
85                 The format of date and time has been shortened
86                 to  yy-mm-dd HH:MM  to give place to a maximal filename
87                 information.
88                 -h ""  now prints a blank line header. -h"" shows an error.
89
90    -i[c[k]]     Replace spaces with tabs on output.  Optional argument
91                 C is the output tab character.  (Default is `\t'.)  Optional
92                 argument K is the output tab character's width.  (Default
93                 is 8.)
94
95   -j            Merge full lines, turns off -w line truncation, no column
96                 alignment, -s[STRING] sets separators, works with all
97                 column options (-COLUMN | -a -COLUMN | -m).
98
99    -l lines     Set the page length to LINES.  Default is 66.
100
101    -m           Print files in parallel; pad_across_to align columns;
102                 truncate lines and print separator strings;
103                 Do it also with empty columns to get a continuous line
104                 numbering and column marking by separators throughout
105                 the whole merged file.
106
107                 Empty pages in some input files produce empty columns
108                 [marked by separators] in the common pages. Completely
109                 empty common pages show no column separators at all.
110
111                 The layout of a merged page is ruled by the largest form
112                 feed distance of the single pages at that page. Shorter
113                 columns will be filled up with empty lines.
114
115                 Together with -j option join lines of full length and
116                 in addition set separators when -s option is used.
117
118    -n[c[k]]     Precede each column with a line number.
119                 (With parallel files, precede each line with a line
120                 number.)  Optional argument C is the character to print
121                 after each number.  (Default `\t'.)  Optional argument
122                 k is the number of digits per line number.  (Default 5.)
123                 Default counting starts with 1st line of input file.
124
125   -N number     Start counting with  number  at 1st line of first page
126                 printed.
127
128    -o offset    Offset each line with a margin OFFSET spaces wide.
129                 Total page width is the size of this offset plus the
130                 width set with `-w'.
131
132    -r           Ignore files that can't be opened.
133
134   -s[STRING]    Separate columns by any string STRING.
135                 Don't use -s "STRING".
136                 without -s: default separator 'space' s used,
137                 same as -s" ",
138                 with -s only: no separator is used, same as -s"".
139                 Quotes should be used with blanks and some shell active
140                 characters.
141
142    -t           Do not print headers or footers but retain form feeds
143                 set in input files (some page layout is not changed).
144
145    -T           Do not print headers or footers, eliminate form feeds
146                 in input files.
147
148    -v           Print unprintable characters as escape sequences.
149                 Control-G becomes \007.
150
151    -w width     Set the page width to WIDTH characters.
152                 (In pr versions newer than 1.14 -s option does no longer
153                 affect -w option.)
154
155                 With/without  -w width  the header line is truncated.
156                 Default is 72 characters.
157                 With  -w width  text lines will be truncated, unless -j is
158                 used. Together with one of the column options
159                 (-COLUMN| -a -COLUMN| -m) column alignment is used.
160                 Without  -w PAGE_WIDTH
161                 - but with one of the column options default truncation of
162                   72 characters is used (to keep downward compatibility
163                   and to simplify most frequently met column tasks).
164                   Column alignment and column separators are used.
165                 - and without any of the column options no line truncation
166                   is used (to keep downward compatibility and to meet most
167                   frequent tasks). That's equivalent to  -w 72 -j .
168 */
169 \f
170
171 #include <config.h>
172
173 #include <stdio.h>
174 #include <getopt.h>
175 #include <sys/types.h>
176 #include <time.h>
177 #include "system.h"
178 #include "error.h"
179 #include "xstrtol.h"
180
181 #if HAVE_LIMITS_H
182 #include <limits.h>
183 #endif
184
185 char *xmalloc ();
186 char *xrealloc ();
187
188 #ifndef UINT_MAX
189 #define UINT_MAX ((unsigned int) ~(unsigned int) 0)
190 #endif
191
192 #ifndef INT_MAX
193 #define INT_MAX ((int) (UINT_MAX >> 1))
194 #endif
195
196 #ifndef TRUE
197 #define TRUE    1
198 #define FALSE   0
199 #endif
200
201 /* Used with start_position in the struct COLUMN described below.
202    If start_position == ANYWHERE, we aren't truncating columns and
203    can begin printing a column anywhere.  Otherwise we must pad to
204    the horizontal position start_position. */
205 #define ANYWHERE        0
206
207 /* Each column has one of these structures allocated for it.
208    If we're only dealing with one file, fp is the same for all
209    columns.
210
211    The general strategy is to spend time setting up these column
212    structures (storing columns if necessary), after which printing
213    is a matter of flitting from column to column and calling
214    print_func.
215
216    Parallel files, single files printing across in multiple
217    columns, and single files printing down in multiple columns all
218    fit the same printing loop.
219
220    print_func           Function used to print lines in this column.
221                         If we're storing this column it will be
222                         print_stored(), Otherwise it will be read_line().
223
224    char_func            Function used to process characters in this column.
225                         If we're storing this column it will be store_char(),
226                         otherwise it will be print_char().
227
228    current_line         Index of the current entry in line_vector, which
229                         contains the index of the first character of the
230                         current line in buff[].
231
232    lines_stored         Number of lines in this column which are stored in
233                         buff.
234
235    lines_to_print       If we're storing this column, lines_to_print is
236                         the number of stored_lines which remain to be
237                         printed.  Otherwise it is the number of lines
238                         we can print without exceeding lines_per_body.
239
240    start_position       The horizontal position we want to be in before we
241                         print the first character in this column.
242
243    numbered             True means precede this column with a line number. */
244
245 struct COLUMN
246   {
247     FILE *fp;                   /* Input stream for this column. */
248     char *name;                 /* File name. */
249     enum
250       {
251         OPEN,
252         FF_FOUND,               /* used with -b option, set with \f, changed
253                                    to ON_HOLD after print_header */
254         ON_HOLD,                /* Hit a form feed. */
255         CLOSED
256       }
257     status;                     /* Status of the file pointer. */
258     int (*print_func) ();       /* Func to print lines in this col. */
259     void (*char_func) ();       /* Func to print/store chars in this col. */
260     int current_line;           /* Index of current place in line_vector. */
261     int lines_stored;           /* Number of lines stored in buff. */
262     int lines_to_print;         /* No. lines stored or space left on page. */
263     int start_position;         /* Horizontal position of first char. */
264     int numbered;
265     int full_page_printed;      /* True means printed without a FF found. */
266
267     /* p->full_page_printed  controls a special case of "FF set by hand":
268        True means a full page has been printed without FF found. To avoid an
269        additional empty page we have to ignore a FF immediately following in
270        the next line. */
271   };
272
273 typedef struct COLUMN COLUMN;
274
275 #define NULLCOL (COLUMN *)0
276
277 static int char_to_clump __P ((int c));
278 static int read_line __P ((COLUMN *p));
279 static int print_page __P ((void));
280 static int print_stored __P ((COLUMN *p));
281 static int open_file __P ((char *name, COLUMN *p));
282 static int skip_to_page __P ((int page));
283 static void print_header __P ((void));
284 static void pad_across_to __P ((int position));
285 static void number __P ((COLUMN *p));
286 static void getoptarg __P ((char *arg, char switch_char, char *character, int *number));
287 static void usage __P ((int status));
288 static void print_files __P ((int number_of_files, char **av));
289 static void init_parameters __P ((int number_of_files));
290 static void init_header __P ((char *filename, int desc));
291 static void init_store_cols __P ((void));
292 static void store_columns __P ((void));
293 static void balance __P ((int total_stored));
294 static void store_char __P ((int c));
295 static void pad_down __P ((int lines));
296 static void read_rest_of_line __P ((COLUMN *p));
297 static void skip_read __P ((COLUMN *p, int column_number));
298 static void print_char __P ((int c));
299 static void cleanup __P ((void));
300 static void first_last_page __P ((char *pages));
301 static void print_sep_string __P ((void));
302 static void separator_string __P ((const char *optarg_S));
303
304 /* The name under which this program was invoked. */
305 char *program_name;
306
307 /* All of the columns to print.  */
308 static COLUMN *column_vector;
309
310 /* When printing a single file in multiple downward columns,
311    we store the leftmost columns contiguously in buff.
312    To print a line from buff, get the index of the first character
313    from line_vector[i], and print up to line_vector[i + 1]. */
314 static char *buff;
315
316 /* Index of the position in buff where the next character
317    will be stored. */
318 static int buff_current;
319
320 /* The number of characters in buff.
321    Used for allocation of buff and to detect overflow of buff. */
322 static int buff_allocated;
323
324 /* Array of indices into buff.
325    Each entry is an index of the first character of a line.
326    This is used when storing lines to facilitate shuffling when
327    we do column balancing on the last page. */
328 static int *line_vector;
329
330 /* Array of horizonal positions.
331    For each line in line_vector, end_vector[line] is the horizontal
332    position we are in after printing that line.  We keep track of this
333    so that we know how much we need to pad to prepare for the next
334    column. */
335 static int *end_vector;
336
337 /* (-m) True means we're printing multiple files in parallel. */
338 static int parallel_files = FALSE;
339
340 /* (-m) True means a line starts with some empty columns (some files
341    already CLOSED or ON_HOLD) which we have to align. */
342 static int align_empty_cols;
343
344 /* (-m) True means we have not yet found any printable column in a line.
345    align_empty_cols = TRUE  has to be maintained. */
346 static int empty_line;
347
348 /* (-m) False means printable column output precedes a form feed found.
349    Column align is done only once. No additional action with that form
350    feed.
351    True means we found only a form feed in a column. Maybe we have to do
352    some column align with that form feed. */
353 static int FF_only;
354
355 /* (-[0-9]+) True means we're given an option explicitly specifying
356    number of columns.  Used to detect when this option is used with -m. */
357 static int explicit_columns = FALSE;
358
359 /* (-t|-T) False means we aren't printing headers and footers. */
360 static int extremities = TRUE;
361
362 /* (-t) True means we retain all FF set by hand in input files.
363    False is set with -T option. */
364 static int keep_FF = FALSE;
365 static int print_a_FF = FALSE;
366
367 /* True means we need to print a header as soon as we know we've got input
368    to print after it. */
369 static int print_a_header;
370
371 /* (-h) True means we're using the standard header rather than a
372    customized one specified by the -h flag. */
373 static int standard_header = TRUE;
374
375 /* (-f) True means use formfeeds instead of newlines to separate pages. */
376 static int use_form_feed = FALSE;
377
378 /* True means we have read the standard input. */
379 static int have_read_stdin = FALSE;
380
381 /* True means the -a flag has been given. */
382 static int print_across_flag = FALSE;
383
384 /* True means we're printing one file in multiple (>1) downward columns. */
385 static int storing_columns = TRUE;
386
387 /* (-b) True means balance columns on the last page as Sys V does. */
388 /* That's no longer an independent option. With storing_columns = TRUE
389    balance_columns = TRUE is used too (s. function init_parameters).
390    We get a consistent formulation with "FF set by hand" in input files. */
391 static int balance_columns = FALSE;
392
393 /* (-l) Number of lines on a page, including header and footer lines. */
394 static int lines_per_page = 66;
395
396 /* Number of lines in the header and footer can be reset to 0 using
397    the -t flag. */
398 static int lines_per_header = 5;
399 static int lines_per_body;
400 static int lines_per_footer = 5;
401
402 /* (-w) Width in characters of the page.  Does not include the width of
403    the margin. */
404 static int chars_per_line = 72;
405
406 /* (-w) True means we truncate lines longer than chars_per_column. */
407 static int truncate_lines = FALSE;
408
409 /* (-j) True means we join lines without any line truncation. -j
410    dominates -w option. */
411 static int join_lines = FALSE;
412
413 /* Number of characters in a column.  Based on col_sep_length and
414    page width. */
415 static int chars_per_column;
416
417 /* (-e) True means convert tabs to spaces on input. */
418 static int untabify_input = FALSE;
419
420 /* (-e) The input tab character. */
421 static char input_tab_char = '\t';
422
423 /* (-e) Tabstops are at chars_per_tab, 2*chars_per_tab, 3*chars_per_tab, ...
424    where the leftmost column is 1. */
425 static int chars_per_input_tab = 8;
426
427 /* (-i) True means convert spaces to tabs on output. */
428 static int tabify_output = FALSE;
429
430 /* (-i) The output tab character. */
431 static char output_tab_char = '\t';
432
433 /* (-i) The width of the output tab. */
434 static int chars_per_output_tab = 8;
435
436 /* Keeps track of pending white space.  When we hit a nonspace
437    character after some whitespace, we print whitespace, tabbing
438    if necessary to get to output_position + spaces_not_printed. */
439 static int spaces_not_printed;
440
441 /* (-o) Number of spaces in the left margin (tabs used when possible). */
442 static int chars_per_margin = 0;
443
444 /* Position where the next character will fall.
445    Leftmost position is 0 + chars_per_margin.
446    Rightmost position is chars_per_margin + chars_per_line - 1.
447    This is important for converting spaces to tabs on output. */
448 static int output_position;
449
450 /* Horizontal position relative to the current file.
451    (output_position depends on where we are on the page;
452    input_position depends on where we are in the file.)
453    Important for converting tabs to spaces on input. */
454 static int input_position;
455
456 /* Count number of failed opens so we can exit with nonzero
457    status if there were any.  */
458 static int failed_opens = 0;
459
460 /* The horizontal position we'll be at after printing a tab character
461    of width c_ from the position h_. */
462 #define pos_after_tab(c_, h_) h_ - h_ % c_ + c_
463
464 /* The number of spaces taken up if we print a tab character with width
465    c_ from position h_. */
466 #define tab_width(c_, h_) - h_ % c_ + c_
467
468 /* (-NNN) Number of columns of text to print. */
469 static int columns = 1;
470
471 /* (+NNN:MMM) Page numbers on which to begin and stop printing. */
472 static int first_page_number = 1;
473 static int last_page_number = 0;
474
475 /* Number of files open (not closed, not on hold). */
476 static int files_ready_to_read = 0;
477
478 /* Current page number.  Displayed in header. */
479 static int page_number;
480
481 /* Current line number.  Displayed when -n flag is specified.
482
483    When printing files in parallel (-m flag), line numbering is as follows:
484    1    foo     goo     moo
485    2    hoo     too     zoo
486
487    When printing files across (-a flag), ...
488    1    foo     2       moo     3       goo
489    4    hoo     3       too     6       zoo
490
491    Otherwise, line numbering is as follows:
492    1    foo     3       goo     5       too
493    2    moo     4       hoo     6       zoo */
494 static int line_number;
495
496 /* (-n) True means lines should be preceded by numbers. */
497 static int numbered_lines = FALSE;
498
499 /* (-n) Character which follows each line number. */
500 static char number_separator = '\t';
501
502 /* (-n) line counting starts with 1st line of input file (not with 1st
503    line of 1st page printed). */
504 static int line_count = 1;
505
506 /* (-n) True means counting of skipped lines starts with 1st line of
507    input file. False means -N option is used in addition, counting of
508    skipped lines not required. */
509 static int skip_count = TRUE;
510
511 /* (-N) Counting starts with start_line_number = NUMBER at 1st line of
512    first page printed, usually not 1st page of input file. */
513 static int start_line_num = 1;
514
515 /* (-n) Width in characters of a line number. */
516 static int chars_per_number = 5;
517
518 /* Used when widening the first column to accommodate numbers -- only
519    needed when printing files in parallel.  Includes width of both the
520    number and the number_separator. */
521 static int number_width;
522
523 /* Buffer sprintf uses to format a line number. */
524 static char *number_buff;
525
526 /* (-v) True means unprintable characters are printed as escape sequences.
527    control-g becomes \007. */
528 static int use_esc_sequence = FALSE;
529
530 /* (-c) True means unprintable characters are printed as control prefixes.
531    control-g becomes ^G. */
532 static int use_cntrl_prefix = FALSE;
533
534 /* (-d) True means output is double spaced. */
535 static int double_space = FALSE;
536
537 /* Number of files opened initially in init_files.  Should be 1
538    unless we're printing multiple files in parallel. */
539 static int total_files = 0;
540
541 /* (-r) True means don't complain if we can't open a file. */
542 static int ignore_failed_opens = FALSE;
543
544 /* (-s) True means we separate columns with a specified string.
545    -s option does not affect line truncation nor column alignment. */
546 static int use_col_separator = FALSE;
547
548 /* String used to separate columns if the -s option has been specified.
549    Default value with -s is a space. */
550 static char *col_sep_string;
551 static int col_sep_length = 0;
552 static char *column_separator = " ";
553
554 /* Number of separator characters waiting to be printed as soon as we
555    know that we have any input remaining to be printed. */
556 static int separators_not_printed;
557
558 /* Position we need to pad to, as soon as we know that we have input
559    remaining to be printed. */
560 static int padding_not_printed;
561
562 /* True means we should pad the end of the page.  Remains false until we
563    know we have a page to print. */
564 static int pad_vertically;
565
566 /* (-h) String of characters used in place of the filename in the header. */
567 static char *custom_header;
568
569 /* String containing the date, filename or custom header, and "Page ". */
570 static char *header;
571
572 static int *clump_buff;
573
574 /* If nonzero, display usage information and exit.  */
575 static int show_help;
576
577 /* If nonzero, print the version on standard output then exit.  */
578 static int show_version;
579
580 /* True means we read the line no. lines_per_body in skip_read
581    called by skip_to_page. That variable controls the coincidence of a
582    "FF set by hand" and "full_page_printed", see above the definition of
583    structure COLUMN. */
584 static int last_line = FALSE;
585
586 /* If nonzero, print a non-variable date and time with the header
587    -h HEADER using pr test-suite */
588 static int test_suite;
589
590 static struct option const long_options[] =
591 {
592   {"help", no_argument, &show_help, 1},
593   {"version", no_argument, &show_version, 1},
594   {"test", no_argument, &test_suite, 1},
595   {0, 0, 0, 0}
596 };
597
598 /* Return the number of columns that have either an open file or
599    stored lines. */
600
601 static int
602 cols_ready_to_print (void)
603 {
604   COLUMN *q;
605   int i;
606   int n;
607
608   n = 0;
609   for (q = column_vector, i = 0; i < columns; ++q, ++i)
610     if (q->status == OPEN ||
611         q->status == FF_FOUND ||        /* With -b: To print a header only */
612         (storing_columns && q->lines_stored > 0 && q->lines_to_print > 0))
613       ++n;
614   return n;
615 }
616
617 /* Estimate first_ / last_page_number
618    using option +FIRST_PAGE:LAST_PAGE */
619
620 static void
621 first_last_page (char *pages)
622 {
623   char *str1;
624
625   if (*pages == ':')
626     {
627       error (0, 0, _("invalid range of page numbers: `%s'"), pages);
628       usage (2);
629     }
630
631   str1 = strchr (pages, ':');
632   if (str1 != NULL)
633     *str1 = '\0';
634
635   {
636     long int tmp_long;
637     if (xstrtol (pages, NULL, 10, &tmp_long, NULL) != LONGINT_OK
638         || tmp_long <= 0 || tmp_long > INT_MAX)
639       error (EXIT_FAILURE, 0, _("invalid starting page number: `%s'"),
640              pages);
641     first_page_number = (int) tmp_long;
642   }
643
644   if (str1 == NULL)
645     return;
646
647   {
648     long int tmp_long;
649     if (xstrtol (str1 + 1, NULL, 10, &tmp_long, NULL) != LONGINT_OK
650         || tmp_long <= 0 || tmp_long > INT_MAX)
651       error (EXIT_FAILURE, 0, _("invalid ending page number: `%s'"),
652              str1 + 1);
653     last_page_number = (int) tmp_long;
654   }
655
656   if (first_page_number > last_page_number)
657     error (EXIT_FAILURE, 0,
658            _("starting page number is larger than ending page number"));
659 }
660
661 /* Estimate length of col_sep_string with option -s[STRING] */
662
663 static void
664 separator_string (const char *optarg_S)
665 {
666   col_sep_length = (int) strlen (optarg_S);
667   col_sep_string = (char *) xmalloc (col_sep_length + 1);
668   strcpy (col_sep_string, optarg_S);
669 }
670
671 int
672 main (int argc, char **argv)
673 {
674   int c;
675   int accum = 0;
676   int n_files;
677   char **file_names;
678
679   program_name = argv[0];
680   setlocale (LC_ALL, "");
681   bindtextdomain (PACKAGE, LOCALEDIR);
682   textdomain (PACKAGE);
683
684   n_files = 0;
685   file_names = (argc > 1
686                 ? (char **) xmalloc ((argc - 1) * sizeof (char *))
687                 : NULL);
688
689   while (1)
690     {
691       c = getopt_long (argc, argv,
692                        "-0123456789abcde::fFh:i::jl:mn::N:o:rs::tTvw:",
693                        long_options, (int *) 0);
694       if (c == 1)               /* Non-option argument. */
695         {
696           char *s;
697           s = optarg;
698           if (*s == '+')
699             {
700               ++s;
701               first_last_page (s);
702             }
703           else
704             {
705               file_names[n_files++] = optarg;
706             }
707         }
708       else
709         {
710           if (ISDIGIT (c))
711             {
712               accum = accum * 10 + c - '0';
713               continue;
714             }
715           else
716             {
717               if (accum > 0)
718                 {
719                   columns = accum;
720                   explicit_columns = TRUE;
721                   accum = 0;
722                 }
723             }
724         }
725
726       if (c == 1)
727         continue;
728
729       if (c == EOF)
730         break;
731
732       switch (c)
733         {
734         case 0:         /* getopt long option */
735           break;
736
737         case 'a':
738           print_across_flag = TRUE;
739           storing_columns = FALSE;
740           break;
741         case 'b':
742           balance_columns = TRUE;
743           break;
744         case 'c':
745           use_cntrl_prefix = TRUE;
746           break;
747         case 'd':
748           double_space = TRUE;
749           break;
750         case 'e':
751           if (optarg)
752             getoptarg (optarg, 'e', &input_tab_char,
753                        &chars_per_input_tab);
754           /* Could check tab width > 0. */
755           untabify_input = TRUE;
756           break;
757         case 'f':
758         case 'F':
759           use_form_feed = TRUE;
760           break;
761         case 'h':
762           custom_header = optarg;
763           standard_header = FALSE;
764           break;
765         case 'i':
766           if (optarg)
767             getoptarg (optarg, 'i', &output_tab_char,
768                        &chars_per_output_tab);
769           /* Could check tab width > 0. */
770           tabify_output = TRUE;
771           break;
772         case 'j':
773           join_lines = TRUE;
774           break;
775         case 'l':
776           {
777             long int tmp_long;
778             if (xstrtol (optarg, NULL, 10, &tmp_long, NULL) != LONGINT_OK
779                 || tmp_long <= 0 || tmp_long > INT_MAX)
780               {
781                 error (EXIT_FAILURE, 0,
782                        _("`-l PAGE_LENGTH' invalid number of lines: `%s'"),
783                        optarg);
784               }
785             lines_per_page = (int) tmp_long;
786             break;
787           }
788         case 'm':
789           parallel_files = TRUE;
790           storing_columns = FALSE;
791           break;
792         case 'n':
793           numbered_lines = TRUE;
794           if (optarg)
795             getoptarg (optarg, 'n', &number_separator,
796                        &chars_per_number);
797           break;
798         case 'N':
799           skip_count = FALSE;
800           {
801             long int tmp_long;
802             if (xstrtol (optarg, NULL, 10, &tmp_long, NULL) != LONGINT_OK
803                 || tmp_long > INT_MAX)
804               {
805                 error (EXIT_FAILURE, 0,
806                        _("`-N NUMBER' invalid starting line number: `%s'"),
807                        optarg);
808               }
809             start_line_num = (int) tmp_long;
810             break;
811           }
812         case 'o':
813           {
814             long int tmp_long;
815             if (xstrtol (optarg, NULL, 10, &tmp_long, NULL) != LONGINT_OK
816                 || tmp_long <= 0 || tmp_long > INT_MAX)
817               error (EXIT_FAILURE, 0,
818                      _("`-o MARGIN' invalid line offset: `%s'"), optarg);
819             chars_per_margin = (int) tmp_long;
820             break;
821           }
822         case 'r':
823           ignore_failed_opens = TRUE;
824           break;
825         case 's':
826           use_col_separator = TRUE;
827           if (optarg)
828             separator_string (optarg);
829           break;
830         case 't':
831           extremities = FALSE;
832           keep_FF = TRUE;
833           break;
834         case 'T':
835           extremities = FALSE;
836           keep_FF = FALSE;
837           break;
838         case 'v':
839           use_esc_sequence = TRUE;
840           break;
841         case 'w':
842           truncate_lines = TRUE;
843           {
844             long int tmp_long;
845             if (xstrtol (optarg, NULL, 10, &tmp_long, NULL) != LONGINT_OK
846                 || tmp_long <= 0 || tmp_long > INT_MAX)
847               error (EXIT_FAILURE, 0,
848                  _("`-w PAGE_WIDTH' invalid column number: `%s'"), optarg);
849             chars_per_line = (int) tmp_long;
850             break;
851           }
852         default:
853           usage (2);
854           break;
855         }
856     }
857
858   if (show_version)
859     {
860       printf ("pr (%s) %s\n", GNU_PACKAGE, VERSION);
861       exit (EXIT_SUCCESS);
862     }
863
864   if (show_help)
865     usage (0);
866
867   if (parallel_files && explicit_columns)
868     error (EXIT_FAILURE, 0,
869          _("Cannot specify number of columns when printing in parallel."));
870
871   if (parallel_files && print_across_flag)
872     error (EXIT_FAILURE, 0,
873        _("Cannot specify both printing across and printing in parallel."));
874
875   for (; optind < argc; optind++)
876     {
877       file_names[n_files++] = argv[optind];
878     }
879
880   if (n_files == 0)
881     {
882       /* No file arguments specified;  read from standard input.  */
883       print_files (0, (char **) 0);
884     }
885   else
886     {
887       if (parallel_files)
888         print_files (n_files, file_names);
889       else
890         {
891           int i;
892           for (i = 0; i < n_files; i++)
893             print_files (1, &file_names[i]);
894         }
895     }
896
897   cleanup ();
898
899   if (have_read_stdin && fclose (stdin) == EOF)
900     error (EXIT_FAILURE, errno, _("standard input"));
901   if (ferror (stdout) || fclose (stdout) == EOF)
902     error (EXIT_FAILURE, errno, _("write error"));
903   if (failed_opens > 0)
904     exit (EXIT_FAILURE);
905   exit (EXIT_SUCCESS);
906 }
907
908 /* Parse options of the form -scNNN.
909
910    Example: -nck, where 'n' is the option, c is the optional number
911    separator, and k is the optional width of the field used when printing
912    a number. */
913
914 static void
915 getoptarg (char *arg, char switch_char, char *character, int *number)
916 {
917   if (!ISDIGIT (*arg))
918     *character = *arg++;
919   if (*arg)
920     {
921       long int tmp_long;
922       if (xstrtol (arg, NULL, 10, &tmp_long, NULL) != LONGINT_OK
923           || tmp_long <= 0 || tmp_long > INT_MAX)
924         {
925           error (0, 0,
926                  _("`-%c' extra characters or invalid number in the argument: `%s'"),
927                  switch_char, arg);
928           usage (2);
929         }
930       *number = (int) tmp_long;
931     }
932 }
933 \f
934 /* Set parameters related to formatting. */
935
936 static void
937 init_parameters (int number_of_files)
938 {
939   int chars_used_by_number = 0;
940
941   if (use_form_feed)
942     {
943       lines_per_header = 3;
944       lines_per_footer = 0;
945     }
946
947   lines_per_body = lines_per_page - lines_per_header - lines_per_footer;
948   if (lines_per_body <= 0)
949     {
950       extremities = FALSE;
951       keep_FF = TRUE;
952     }
953   if (extremities == FALSE)
954     lines_per_body = lines_per_page;
955
956   if (double_space)
957     lines_per_body = lines_per_body / 2;
958
959   /* If input is stdin, cannot print parallel files.  BSD dumps core
960      on this. */
961   if (number_of_files == 0)
962     parallel_files = FALSE;
963
964   if (parallel_files)
965     columns = number_of_files;
966
967   /* One file, multi columns down: -b option is set to get a consistent
968      formulation with "FF set by hand" in input files. */
969   if (storing_columns)
970     balance_columns = TRUE;
971
972   /* Tabification is assumed for multiple columns. */
973   if (columns > 1)
974     {
975       if (!use_col_separator)
976         {
977           col_sep_string = column_separator;
978           col_sep_length = 1;
979           use_col_separator = TRUE;
980         }
981
982       truncate_lines = TRUE;
983       untabify_input = TRUE;
984       tabify_output = TRUE;
985     }
986   else
987     storing_columns = FALSE;
988
989   /* -j dominates -w in any case */
990   if (join_lines)
991     truncate_lines = FALSE;
992
993   if (numbered_lines)
994     {
995       line_count = start_line_num;
996       if (number_separator == input_tab_char)
997         {
998           number_width = chars_per_number +
999             tab_width (chars_per_input_tab,
1000                        (chars_per_margin + chars_per_number));
1001         }
1002       else
1003         number_width = chars_per_number + 1;
1004       /* The number is part of the column width unless we are
1005          printing files in parallel. */
1006       if (parallel_files)
1007         chars_used_by_number = number_width;
1008     }
1009
1010   chars_per_column = (chars_per_line - chars_used_by_number -
1011                       (columns - 1) * col_sep_length) / columns;
1012
1013   if (chars_per_column < 1)
1014     error (EXIT_FAILURE, 0, _("page width too narrow"));
1015
1016   if (numbered_lines)
1017     {
1018       if (number_buff != (char *) 0)
1019         free (number_buff);
1020       number_buff = (char *) xmalloc (2 * chars_per_number);
1021     }
1022
1023   /* Pick the maximum between the tab width and the width of an
1024      escape sequence. */
1025   if (clump_buff != (int *) 0)
1026     free (clump_buff);
1027   clump_buff = (int *) xmalloc ((chars_per_input_tab > 4
1028                                  ? chars_per_input_tab : 4) * sizeof (int));
1029 }
1030 \f
1031 /* Open the necessary files,
1032    maintaining a COLUMN structure for each column.
1033
1034    With multiple files, each column p has a different p->fp.
1035    With single files, each column p has the same p->fp.
1036    Return 1 if (number_of_files > 0) and no files can be opened,
1037    0 otherwise.
1038
1039    With each column/file p, p->full_page_printed is initialized,
1040    see also open_file.  */
1041
1042 static int
1043 init_fps (int number_of_files, char **av)
1044 {
1045   int i, files_left;
1046   COLUMN *p;
1047   FILE *firstfp;
1048   char *firstname;
1049
1050   total_files = 0;
1051
1052   if (column_vector != NULLCOL)
1053     free ((char *) column_vector);
1054   column_vector = (COLUMN *) xmalloc (columns * sizeof (COLUMN));
1055
1056   if (parallel_files)
1057     {
1058       files_left = number_of_files;
1059       for (p = column_vector; files_left--; ++p, ++av)
1060         {
1061           if (open_file (*av, p) == 0)
1062             {
1063               --p;
1064               --columns;
1065             }
1066         }
1067       if (columns == 0)
1068         return 1;
1069       init_header ("", -1);
1070     }
1071   else
1072     {
1073       p = column_vector;
1074       if (number_of_files > 0)
1075         {
1076           if (open_file (*av, p) == 0)
1077             return 1;
1078           init_header (*av, fileno (p->fp));
1079         }
1080       else
1081         {
1082           p->name = _("standard input");
1083           p->fp = stdin;
1084           have_read_stdin = TRUE;
1085           p->status = OPEN;
1086           p->full_page_printed = FALSE;
1087           ++total_files;
1088           init_header ("", -1);
1089         }
1090
1091       firstname = p->name;
1092       firstfp = p->fp;
1093       for (i = columns - 1, ++p; i; --i, ++p)
1094         {
1095           p->name = firstname;
1096           p->fp = firstfp;
1097           p->status = OPEN;
1098           p->full_page_printed = FALSE;
1099         }
1100     }
1101   files_ready_to_read = total_files;
1102   return 0;
1103 }
1104 \f
1105 /* Determine print_func and char_func, the functions
1106    used by each column for printing and/or storing.
1107
1108    Determine the horizontal position desired when we begin
1109    printing a column (p->start_position). */
1110
1111 static void
1112 init_funcs (void)
1113 {
1114   int i, h, h_next;
1115   COLUMN *p;
1116
1117   h = chars_per_margin;
1118
1119   if (!truncate_lines)
1120     h_next = ANYWHERE;
1121   else
1122     {
1123       /* When numbering lines of parallel files, we enlarge the
1124          first column to accomodate the number.  Looks better than
1125          the Sys V approach. */
1126       if (parallel_files && numbered_lines)
1127         h_next = h + chars_per_column + number_width;
1128       else
1129         h_next = h + chars_per_column;
1130     }
1131
1132   /* Enlarge p->start_position of first column to use the same form of
1133      padding_not_printed with all columns. */
1134   h = h + col_sep_length;
1135
1136   /* This loop takes care of all but the rightmost column. */
1137
1138   for (p = column_vector, i = 1; i < columns; ++p, ++i)
1139     {
1140       if (storing_columns)      /* One file, multi columns down. */
1141         {
1142           p->char_func = store_char;
1143           p->print_func = print_stored;
1144         }
1145       else
1146         /* One file, multi columns across; or parallel files.  */
1147         {
1148           p->char_func = print_char;
1149           p->print_func = read_line;
1150         }
1151
1152       /* Number only the first column when printing files in
1153          parallel. */
1154       p->numbered = numbered_lines && (!parallel_files || i == 1);
1155       p->start_position = h;
1156
1157       /* If we don't truncate lines, all start_positions are
1158          ANYWHERE, except the first column's start_position when
1159          using a margin. */
1160
1161       if (!truncate_lines)
1162         {
1163           h = ANYWHERE;
1164           h_next = ANYWHERE;
1165         }
1166       else
1167         {
1168           h = h_next + col_sep_length;
1169           h_next = h + chars_per_column;
1170         }
1171     }
1172
1173   /* The rightmost column.
1174
1175      Doesn't need to be stored unless we intend to balance
1176      columns on the last page. */
1177   if (storing_columns && balance_columns)
1178     {
1179       p->char_func = store_char;
1180       p->print_func = print_stored;
1181     }
1182   else
1183     {
1184       p->char_func = print_char;
1185       p->print_func = read_line;
1186     }
1187
1188   p->numbered = numbered_lines && (!parallel_files || i == 1);
1189   p->start_position = h;
1190 }
1191 \f
1192 /* Open a file.  Return nonzero if successful, zero if failed.
1193
1194    With each file p, p->full_page_printed is initialized,
1195    see also init_fps. */
1196
1197 static int
1198 open_file (char *name, COLUMN *p)
1199 {
1200   if (!strcmp (name, "-"))
1201     {
1202       p->name = _("standard input");
1203       p->fp = stdin;
1204       have_read_stdin = 1;
1205     }
1206   else
1207     {
1208       p->name = name;
1209       p->fp = fopen (name, "r");
1210     }
1211   if (p->fp == NULL)
1212     {
1213       ++failed_opens;
1214       if (!ignore_failed_opens)
1215         error (0, errno, "%s", name);
1216       return 0;
1217     }
1218   p->status = OPEN;
1219   p->full_page_printed = FALSE;
1220   ++total_files;
1221   return 1;
1222 }
1223
1224 /* Close the file in P.
1225
1226    If we aren't dealing with multiple files in parallel, we change
1227    the status of all columns in the column list to reflect the close. */
1228
1229 static void
1230 close_file (COLUMN *p)
1231 {
1232   COLUMN *q;
1233   int i;
1234
1235   if (p->status == CLOSED)
1236     return;
1237   if (ferror (p->fp))
1238     error (EXIT_FAILURE, errno, "%s", p->name);
1239   if (p->fp != stdin && fclose (p->fp) == EOF)
1240     error (EXIT_FAILURE, errno, "%s", p->name);
1241
1242   if (!parallel_files)
1243     {
1244       for (q = column_vector, i = columns; i; ++q, --i)
1245         {
1246           q->status = CLOSED;
1247           if (q->lines_stored == 0)
1248             {
1249               q->lines_to_print = 0;
1250             }
1251         }
1252     }
1253   else
1254     {
1255       p->status = CLOSED;
1256       p->lines_to_print = 0;
1257     }
1258
1259   --files_ready_to_read;
1260 }
1261
1262 /* Put a file on hold until we start a new page,
1263    since we've hit a form feed.
1264
1265    If we aren't dealing with parallel files, we must change the
1266    status of all columns in the column list. */
1267
1268 static void
1269 hold_file (COLUMN *p)
1270 {
1271   COLUMN *q;
1272   int i;
1273
1274   if (!parallel_files)
1275     for (q = column_vector, i = columns; i; ++q, --i)
1276       {
1277         if (storing_columns)
1278           q->status = FF_FOUND;
1279         else
1280           q->status = ON_HOLD;
1281       }
1282   else
1283     p->status = ON_HOLD;
1284
1285   p->lines_to_print = 0;
1286   --files_ready_to_read;
1287 }
1288
1289 /* Undo hold_file -- go through the column list and change any
1290    ON_HOLD columns to OPEN.  Used at the end of each page. */
1291
1292 static void
1293 reset_status (void)
1294 {
1295   int i = columns;
1296   COLUMN *p;
1297
1298   for (p = column_vector; i; --i, ++p)
1299     if (p->status == ON_HOLD)
1300       {
1301         p->status = OPEN;
1302         files_ready_to_read++;
1303       }
1304
1305   if (storing_columns)
1306     files_ready_to_read = 1;
1307 }
1308 \f
1309 /* Print a single file, or multiple files in parallel.
1310
1311    Set up the list of columns, opening the necessary files.
1312    Allocate space for storing columns, if necessary.
1313    Skip to first_page_number, if user has asked to skip leading pages.
1314    Determine which functions are appropriate to store/print lines
1315    in each column.
1316    Print the file(s). */
1317
1318 static void
1319 print_files (int number_of_files, char **av)
1320 {
1321   init_parameters (number_of_files);
1322   if (init_fps (number_of_files, av))
1323     return;
1324   if (storing_columns)
1325     init_store_cols ();
1326
1327   if (first_page_number > 1)
1328     {
1329       if (!skip_to_page (first_page_number))
1330         return;
1331       else
1332         page_number = first_page_number;
1333     }
1334   else
1335     page_number = 1;
1336
1337   init_funcs ();
1338
1339   line_number = line_count;
1340   while (print_page ())
1341     ;
1342 }
1343 \f
1344 /* Estimate the number of characters taken up by a short format date and
1345    time:  "yy-mm-dd HH:MM"  and:  "Page NNNN". */
1346 #define CHARS_FOR_DATE_AND_PAGE 23
1347
1348 /* Initialize header information.
1349    If DESC is non-negative, it is a file descriptor open to
1350    FILENAME for reading.
1351
1352    Allocate space for a header string,
1353    Determine the time, insert file name or user-specified string.
1354    Make use of a centered header with left-hand-side truncation marked by
1355    a '*` in front, if necessary. */
1356
1357 static void
1358 init_header (char *filename, int desc)
1359 {
1360   int chars_per_middle, chars_free, lhs_blanks, rhs_blanks;
1361   char *f = filename;
1362   char *no_middle = "";
1363   char *header_text, *fmt, *t_buf;
1364   struct tm *tmptr;
1365   struct stat st;
1366   char *datim = "- Date/Time --";
1367
1368   fmt = "%y-%m-%d %H:%M";       /* date/time short format */
1369
1370   if (filename == 0)
1371     f = "";
1372
1373   if (header != (char *) 0)
1374     free (header);
1375   header = (char *) xmalloc (chars_per_line + 1);
1376
1377   if (!standard_header && *custom_header == '\0')
1378     sprintf (header, "%s", " ");        /* blank line header */
1379   else
1380     {
1381       /* If parallel files or standard input, use current time. */
1382       if (desc < 0 || !strcmp (filename, "-") || fstat (desc, &st))
1383         st.st_mtime = time ((time_t *) 0);
1384
1385       {
1386         size_t t_buf_size = 15;
1387         t_buf = (char *) xmalloc (t_buf_size);
1388         tmptr = localtime (&st.st_mtime);
1389         strftime (t_buf, t_buf_size, fmt, tmptr);
1390       }
1391
1392       chars_per_middle = chars_per_line - CHARS_FOR_DATE_AND_PAGE;
1393       if (chars_per_middle < 3)
1394         {
1395           header_text = no_middle;      /* Nothing free for a heading */
1396           lhs_blanks = 1;
1397           rhs_blanks = 1;
1398         }
1399       else
1400         {
1401           header_text = standard_header ? f : custom_header;
1402           chars_free = chars_per_middle - (int) strlen (header_text);
1403           if (chars_free > 1)
1404             {
1405               lhs_blanks = chars_free / 2;      /* text not truncated */
1406               rhs_blanks = chars_free - lhs_blanks;
1407             }
1408           else
1409             {                   /* lhs truncation */
1410               header_text = header_text - chars_free + 2;
1411               *header_text = '*';
1412               lhs_blanks = 1;
1413               rhs_blanks = 1;
1414             }
1415         }
1416
1417       sprintf (header, _("%s%*s%s%*sPage"), (test_suite ? datim : t_buf),
1418                lhs_blanks, " ", header_text, rhs_blanks, " ");
1419     }
1420 }
1421 \f
1422 /* Set things up for printing a page
1423
1424    Scan through the columns ...
1425    Determine which are ready to print
1426    (i.e., which have lines stored or open files)
1427    Set p->lines_to_print appropriately
1428    (to p->lines_stored if we're storing, or lines_per_body
1429    if we're reading straight from the file)
1430    Keep track of this total so we know when to stop printing */
1431
1432 static void
1433 init_page (void)
1434 {
1435   int j;
1436   COLUMN *p;
1437
1438   if (storing_columns)
1439     {
1440       store_columns ();
1441       for (j = columns - 1, p = column_vector; j; --j, ++p)
1442         {
1443           p->lines_to_print = p->lines_stored;
1444         }
1445
1446       /* Last column. */
1447       if (balance_columns)
1448         {
1449           p->lines_to_print = p->lines_stored;
1450         }
1451       /* Since we're not balancing columns, we don't need to store
1452          the rightmost column.   Read it straight from the file. */
1453       else
1454         {
1455           if (p->status == OPEN)
1456             {
1457               p->lines_to_print = lines_per_body;
1458             }
1459           else
1460             p->lines_to_print = 0;
1461         }
1462     }
1463   else
1464     for (j = columns, p = column_vector; j; --j, ++p)
1465       if (p->status == OPEN)
1466         {
1467           p->lines_to_print = lines_per_body;
1468         }
1469       else
1470         p->lines_to_print = 0;
1471 }
1472
1473 /* Align empty columns and print separators.
1474    Empty columns will be formed by files with status ON_HOLD or CLOSED
1475    when printing multiple files in parallel. */
1476
1477 static void
1478 align_column (COLUMN *p)
1479 {
1480   padding_not_printed = p->start_position;
1481   if (padding_not_printed - col_sep_length > 0)
1482     {
1483       pad_across_to (padding_not_printed - col_sep_length);
1484       padding_not_printed = ANYWHERE;
1485     }
1486
1487   if (use_col_separator)
1488     print_sep_string ();
1489
1490   if (p->numbered)
1491     number (p);
1492 }
1493
1494 /* Print one page.
1495
1496    As long as there are lines left on the page and columns ready to print,
1497    Scan across the column list
1498    if the column has stored lines or the file is open
1499    pad to the appropriate spot
1500    print the column
1501    pad the remainder of the page with \n or \f as requested
1502    reset the status of all files -- any files which where on hold because
1503    of formfeeds are now put back into the lineup. */
1504
1505 static int
1506 print_page (void)
1507 {
1508   int j;
1509   int lines_left_on_page;
1510   COLUMN *p;
1511
1512   /* Used as an accumulator (with | operator) of successive values of
1513      pad_vertically.  The trick is to set pad_vertically
1514      to zero before each run through the inner loop, then after that
1515      loop, it tells us whether a line was actually printed (whether a
1516      newline needs to be output -- or two for double spacing).  But those
1517      values have to be accumulated (in pv) so we can invoke pad_down
1518      properly after the outer loop completes. */
1519   int pv;
1520
1521   init_page ();
1522
1523   if (cols_ready_to_print () == 0)
1524     return FALSE;
1525
1526   if (extremities)
1527     print_a_header = TRUE;
1528
1529   /* Don't pad unless we know a page was printed. */
1530   pad_vertically = FALSE;
1531   pv = FALSE;
1532
1533   lines_left_on_page = lines_per_body;
1534   if (double_space)
1535     lines_left_on_page *= 2;
1536
1537   while (lines_left_on_page > 0 && cols_ready_to_print () > 0)
1538     {
1539       output_position = 0;
1540       spaces_not_printed = 0;
1541       separators_not_printed = 0;
1542       pad_vertically = FALSE;
1543       align_empty_cols = FALSE;
1544       empty_line = TRUE;
1545
1546       for (j = 1, p = column_vector; j <= columns; ++j, ++p)
1547         {
1548           input_position = 0;
1549           if (p->lines_to_print > 0 || p->status == FF_FOUND)
1550             {
1551               FF_only = FALSE;
1552               padding_not_printed = p->start_position;
1553               if (!(p->print_func) (p))
1554                 read_rest_of_line (p);
1555               pv |= pad_vertically;
1556
1557               --p->lines_to_print;
1558               if (p->lines_to_print <= 0)
1559                 {
1560                   if (cols_ready_to_print () <= 0)
1561                     break;
1562                 }
1563
1564               /* File p changed its status to ON_HOLD or CLOSED */
1565               if (parallel_files && p->status != OPEN)
1566                 {
1567                   if (empty_line)
1568                     align_empty_cols = TRUE;
1569                   else if (p->status == CLOSED ||
1570                            (p->status == ON_HOLD && FF_only))
1571                     align_column (p);
1572                 }
1573             }
1574           else if (parallel_files)
1575             {
1576               /* File status ON_HOLD or CLOSED */
1577               if (empty_line)
1578                 align_empty_cols = TRUE;
1579               else
1580                 align_column (p);
1581             }
1582
1583           /* We need it also with an empty column */
1584           if (use_col_separator)
1585             ++separators_not_printed;
1586         }
1587
1588       if (pad_vertically)
1589         {
1590           putchar ('\n');
1591           --lines_left_on_page;
1592         }
1593
1594       if (double_space && pv && extremities)
1595         {
1596           putchar ('\n');
1597           --lines_left_on_page;
1598         }
1599     }
1600
1601   if (lines_left_on_page == 0)
1602     for (j = 1, p = column_vector; j <= columns; ++j, ++p)
1603       if (p->status == OPEN)
1604         p->full_page_printed = TRUE;
1605
1606   pad_vertically = pv;
1607
1608   if (pad_vertically && extremities)
1609     pad_down (lines_left_on_page + lines_per_footer);
1610   else if (keep_FF && print_a_FF)
1611     {
1612       putchar ('\f');
1613       print_a_FF = FALSE;
1614     }
1615
1616   if (last_page_number && page_number > last_page_number)
1617     return FALSE;               /* Stop printing with LAST_PAGE */
1618
1619   reset_status ();              /* Change ON_HOLD to OPEN. */
1620
1621   return TRUE;                  /* More pages to go. */
1622 }
1623 \f
1624 /* Allocate space for storing columns.
1625
1626    This is necessary when printing multiple columns from a single file.
1627    Lines are stored consecutively in buff, separated by '\0'.
1628
1629    The following doesn't apply any longer - any tuning possible?
1630    (We can't use a fixed offset since with the '-s' flag lines aren't
1631    truncated.)
1632
1633    We maintain a list (line_vector) of pointers to the beginnings
1634    of lines in buff.  We allocate one more than the number of lines
1635    because the last entry tells us the index of the last character,
1636    which we need to know in order to print the last line in buff. */
1637
1638 static void
1639 init_store_cols (void)
1640 {
1641   int total_lines = lines_per_body * columns;
1642   int chars_if_truncate = total_lines * (chars_per_column + 1);
1643
1644   if (line_vector != (int *) 0)
1645     free ((int *) line_vector);
1646   line_vector = (int *) xmalloc ((total_lines + 1) * sizeof (int *));
1647
1648   if (end_vector != (int *) 0)
1649     free ((int *) end_vector);
1650   end_vector = (int *) xmalloc (total_lines * sizeof (int *));
1651
1652   if (buff != (char *) 0)
1653     free (buff);
1654   buff_allocated = use_col_separator ? 2 * chars_if_truncate
1655     : chars_if_truncate;        /* Tune this. */
1656   buff = (char *) xmalloc (buff_allocated);
1657 }
1658
1659 /* Store all but the rightmost column.
1660    (Used when printing a single file in multiple downward columns)
1661
1662    For each column
1663    set p->current_line to be the index in line_vector of the
1664    first line in the column
1665    For each line in the column
1666    store the line in buff
1667    add to line_vector the index of the line's first char
1668    buff_start is the index in buff of the first character in the
1669    current line. */
1670
1671 static void
1672 store_columns (void)
1673 {
1674   int i, j;
1675   int line = 0;
1676   int buff_start;
1677   int last_col;                 /* The rightmost column which will be saved in buff */
1678   COLUMN *p;
1679
1680   buff_current = 0;
1681   buff_start = 0;
1682
1683   if (balance_columns)
1684     last_col = columns;
1685   else
1686     last_col = columns - 1;
1687
1688   for (i = 1, p = column_vector; i <= last_col; ++i, ++p)
1689     p->lines_stored = 0;
1690
1691   for (i = 1, p = column_vector; i <= last_col && files_ready_to_read;
1692        ++i, ++p)
1693     {
1694       p->current_line = line;
1695       for (j = lines_per_body; j && files_ready_to_read; --j)
1696
1697         if (p->status == OPEN)  /* Redundant.  Clean up. */
1698           {
1699             input_position = 0;
1700
1701             if (!read_line (p))
1702               read_rest_of_line (p);
1703
1704             if (p->status == OPEN
1705                 || buff_start != buff_current)
1706               {
1707                 ++p->lines_stored;
1708                 line_vector[line] = buff_start;
1709                 end_vector[line++] = input_position;
1710                 buff_start = buff_current;
1711               }
1712           }
1713     }
1714
1715   /* Keep track of the location of the last char in buff. */
1716   line_vector[line] = buff_start;
1717
1718   if (balance_columns && p->lines_stored != lines_per_body)
1719     balance (line);
1720 }
1721
1722 static void
1723 balance (int total_stored)
1724 {
1725   COLUMN *p;
1726   int i, lines;
1727   int first_line = 0;
1728
1729   for (i = 1, p = column_vector; i <= columns; ++i, ++p)
1730     {
1731       lines = total_stored / columns;
1732       if (i <= total_stored % columns)
1733         ++lines;
1734
1735       p->lines_stored = lines;
1736       p->current_line = first_line;
1737
1738       first_line += lines;
1739     }
1740 }
1741
1742 /* Store a character in the buffer. */
1743
1744 static void
1745 store_char (int c)
1746 {
1747   if (buff_current >= buff_allocated)
1748     {
1749       /* May be too generous. */
1750       buff_allocated = 2 * buff_allocated;
1751       buff = (char *) xrealloc (buff, buff_allocated * sizeof (char));
1752     }
1753   buff[buff_current++] = (char) c;
1754 }
1755
1756 static void
1757 number (COLUMN *p)
1758 {
1759   int i;
1760   char *s;
1761
1762   sprintf (number_buff, "%*d", chars_per_number, line_number++);
1763   s = number_buff;
1764   for (i = chars_per_number; i > 0; i--)
1765     (p->char_func) ((int) *s++);
1766
1767   if (number_separator == input_tab_char)
1768     {
1769       i = number_width - chars_per_number;
1770       while (i-- > 0)
1771         (p->char_func) ((int) ' ');
1772     }
1773   else
1774     (p->char_func) ((int) number_separator);
1775
1776   if (truncate_lines && !parallel_files)
1777     input_position += number_width;
1778 }
1779 \f
1780 /* Print (or store) padding until the current horizontal position
1781    is position. */
1782
1783 static void
1784 pad_across_to (int position)
1785 {
1786   register int h = output_position;
1787
1788   if (tabify_output)
1789     spaces_not_printed = position - output_position;
1790   else
1791     {
1792       while (++h <= position)
1793         putchar (' ');
1794       output_position = position;
1795     }
1796 }
1797
1798 /* Pad to the bottom of the page.
1799
1800    If the user has requested a formfeed, use one.
1801    Otherwise, use newlines. */
1802
1803 static void
1804 pad_down (int lines)
1805 {
1806   register int i;
1807
1808   if (use_form_feed)
1809     putchar ('\f');
1810   else
1811     for (i = lines; i; --i)
1812       putchar ('\n');
1813 }
1814
1815 /* Read the rest of the line.
1816
1817    Read from the current column's file until an end of line is
1818    hit.  Used when we've truncated a line and we no longer need
1819    to print or store its characters. */
1820
1821 static void
1822 read_rest_of_line (COLUMN *p)
1823 {
1824   register int c;
1825   FILE *f = p->fp;
1826
1827   while ((c = getc (f)) != '\n')
1828     {
1829       if (c == '\f')
1830         {
1831           if ((c = getc (f)) != '\n')
1832             ungetc (c, f);
1833           if (keep_FF)
1834             print_a_FF = TRUE;
1835           hold_file (p);
1836           break;
1837         }
1838       else if (c == EOF)
1839         {
1840           close_file (p);
1841           break;
1842         }
1843     }
1844 }
1845
1846 /* Read a line with skip_to_page.
1847
1848    Read from the current column's file until an end of line is
1849    hit.  Used when we read full lines to skip pages.
1850    With skip_to_page we have to check for FF-coincidence which is done
1851    in function read_line otherwise.
1852    Count lines of skipped pages to find the line number of 1st page
1853    printed relative to 1st line of input file (start_line_num). */
1854
1855 static void
1856 skip_read (COLUMN *p, int column_number)
1857 {
1858   register int c;
1859   FILE *f = p->fp;
1860   int i, single_ff = FALSE;
1861   COLUMN *q;
1862
1863   /* Read 1st character in a line or any character succeeding a FF */
1864   if ((c = getc (f)) == '\f' && p->full_page_printed)
1865     /* A FF-coincidence with a previous full_page_printed.
1866        To avoid an additional empty page, eliminate the FF */
1867     if ((c = getc (f)) == '\n')
1868       c = getc (f);
1869
1870   p->full_page_printed = FALSE;
1871
1872   /* 1st character a FF means a single FF without any printable
1873      characters. Don't count it as a line with -n option. */
1874   if (c == '\f')
1875     single_ff = TRUE;
1876
1877   /* Preparing for a FF-coincidence: Maybe we finish that page
1878      without a FF found */
1879   if (last_line)
1880     p->full_page_printed = TRUE;
1881
1882   while (c != '\n')
1883     {
1884       if (c == '\f')
1885         {
1886           /* No FF-coincidence possible,
1887              no catching up of a FF-coincidence with next page */
1888           if (last_line)
1889             {
1890               if (!parallel_files)
1891                 for (q = column_vector, i = columns; i; ++q, --i)
1892                   q->full_page_printed = FALSE;
1893               else
1894                 p->full_page_printed = FALSE;
1895             }
1896
1897           if ((c = getc (f)) != '\n')
1898             ungetc (c, f);
1899           hold_file (p);
1900           break;
1901         }
1902       else if (c == EOF)
1903         {
1904           close_file (p);
1905           break;
1906         }
1907       c = getc (f);
1908     }
1909
1910   if (skip_count)
1911     if ((!parallel_files || column_number == 1) && !single_ff)
1912       ++line_count;
1913 }
1914 \f
1915 /* If we're tabifying output,
1916
1917    When print_char encounters white space it keeps track
1918    of our desired horizontal position and delays printing
1919    until this function is called. */
1920
1921 static void
1922 print_white_space (void)
1923 {
1924   register int h_new;
1925   register int h_old = output_position;
1926   register int goal = h_old + spaces_not_printed;
1927
1928   while (goal - h_old > 1
1929          && (h_new = pos_after_tab (chars_per_output_tab, h_old)) <= goal)
1930     {
1931       putchar (output_tab_char);
1932       h_old = h_new;
1933     }
1934   while (++h_old <= goal)
1935     putchar (' ');
1936
1937   output_position = goal;
1938   spaces_not_printed = 0;
1939 }
1940
1941 /* Print column separators.
1942
1943    We keep a count until we know that we'll be printing a line,
1944    then print_sep_string() is called. */
1945
1946 static void
1947 print_sep_string ()
1948 {
1949   char *s;
1950   int l = col_sep_length;
1951
1952   s = col_sep_string;
1953
1954   if (spaces_not_printed > 0)
1955     print_white_space ();
1956
1957   for (; separators_not_printed > 0; --separators_not_printed)
1958     {
1959       while (l-- > 0)
1960         putchar (*s++);
1961       output_position += col_sep_length;
1962     }
1963 }
1964
1965 /* Print (or store, depending on p->char_func) a clump of N
1966    characters. */
1967
1968 static void
1969 print_clump (COLUMN *p, int n, int *clump)
1970 {
1971   while (n--)
1972     (p->char_func) (*clump++);
1973 }
1974
1975 /* Print a character.
1976
1977    Update the following comment: process-char hasn't been used any
1978    longer.
1979    If we're tabifying, all tabs have been converted to spaces by
1980    process_char().  Keep a count of consecutive spaces, and when
1981    a nonspace is encountered, call print_white_space() to print the
1982    required number of tabs and spaces. */
1983
1984 static void
1985 print_char (int c)
1986 {
1987   if (tabify_output)
1988     {
1989       if (c == ' ')
1990         {
1991           ++spaces_not_printed;
1992           return;
1993         }
1994       else if (spaces_not_printed > 0)
1995         print_white_space ();
1996
1997       /* Nonprintables are assumed to have width 0, except '\b'. */
1998       if (!ISPRINT (c))
1999         {
2000           if (c == '\b')
2001             --output_position;
2002         }
2003       else
2004         ++output_position;
2005     }
2006   putchar (c);
2007 }
2008
2009 /* Skip to page PAGE before printing. */
2010
2011 static int
2012 skip_to_page (int page)
2013 {
2014   int n, i, j;
2015   COLUMN *p;
2016
2017   for (n = 1; n < page; ++n)
2018     {
2019       for (i = 1; i < lines_per_body; ++i)
2020         {
2021           for (j = 1, p = column_vector; j <= columns; ++j, ++p)
2022             if (p->status == OPEN)
2023               skip_read (p, j);
2024         }
2025       last_line = TRUE;
2026       for (j = 1, p = column_vector; j <= columns; ++j, ++p)
2027         if (p->status == OPEN)
2028           skip_read (p, j);
2029
2030       if (storing_columns)      /* change FF_FOUND to ON_HOLD */
2031         for (j = 1, p = column_vector; j <= columns; ++j, ++p)
2032           p->status = ON_HOLD;
2033
2034       reset_status ();
2035       last_line = FALSE;
2036     }
2037   return files_ready_to_read > 0;
2038 }
2039
2040 /* Print a header.
2041
2042    Formfeeds are assumed to use up two lines at the beginning of
2043    the page. */
2044
2045 static void
2046 print_header (void)
2047 {
2048   if (!use_form_feed)
2049     fprintf (stdout, "\n\n");
2050
2051   output_position = 0;
2052   pad_across_to (chars_per_margin);
2053   print_white_space ();
2054
2055   if (!standard_header && *custom_header == '\0')
2056     fprintf (stdout, "%s\n\n\n", header);
2057   else
2058     fprintf (stdout, "%s%5d\n\n\n", header, page_number++);
2059
2060   print_a_header = FALSE;
2061   output_position = 0;
2062 }
2063
2064 /* Print (or store, if p->char_func is store_char()) a line.
2065
2066    Read a character to determine whether we have a line or not.
2067    (We may hit EOF, \n, or \f)
2068
2069    Once we know we have a line,
2070    set pad_vertically = TRUE, meaning it's safe
2071    to pad down at the end of the page, since we do have a page.
2072    print a header if needed.
2073    pad across to padding_not_printed if needed.
2074    print any separators which need to be printed.
2075    print a line number if it needs to be printed.
2076
2077    Print the clump which corresponds to the first character.
2078
2079    Enter a loop and keep printing until an end of line condition
2080    exists, or until we exceed chars_per_column.
2081
2082    Return FALSE if we exceed chars_per_column before reading
2083    an end of line character, TRUE otherwise. */
2084
2085 static int
2086 read_line (COLUMN *p)
2087 {
2088   register int c, chars;
2089   int last_input_position;
2090   int j, k;
2091   COLUMN *q;
2092
2093 /* Suppress `used before initialized' warning. */
2094 #ifdef lint
2095   chars = 0;
2096 #endif
2097
2098   /* read 1st character in each line or any character succeeding a FF: */
2099   c = getc (p->fp);
2100
2101   last_input_position = input_position;
2102
2103   if (c == '\f' && p->full_page_printed)
2104     if ((c = getc (p->fp)) == '\n')
2105       c = getc (p->fp);
2106   p->full_page_printed = FALSE;
2107
2108   switch (c)
2109     {
2110     case '\f':
2111       if ((c = getc (p->fp)) != '\n')
2112         ungetc (c, p->fp);
2113       FF_only = TRUE;
2114       if (print_a_header && !storing_columns)
2115         {
2116           pad_vertically = TRUE;
2117           print_header ();
2118         }
2119       else if (keep_FF)
2120         print_a_FF = TRUE;
2121       hold_file (p);
2122       return TRUE;
2123     case EOF:
2124       close_file (p);
2125       return TRUE;
2126     case '\n':
2127       break;
2128     default:
2129       chars = char_to_clump (c);
2130     }
2131
2132   if (truncate_lines && input_position > chars_per_column)
2133     {
2134       input_position = last_input_position;
2135       return FALSE;
2136     }
2137
2138   if (p->char_func != store_char)
2139     {
2140       pad_vertically = TRUE;
2141
2142       if (print_a_header && !storing_columns)
2143         print_header ();
2144
2145       if (parallel_files && align_empty_cols)
2146         {
2147           /* We have to align empty columns at the beginning of a line. */
2148           k = separators_not_printed;
2149           separators_not_printed = 0;
2150           for (j = 1, q = column_vector; j <= k; ++j, ++q)
2151             {
2152               align_column (q);
2153               separators_not_printed += 1;
2154             }
2155           padding_not_printed = p->start_position;
2156           if (truncate_lines)
2157             spaces_not_printed = chars_per_column;
2158           else
2159             spaces_not_printed = 0;
2160           align_empty_cols = FALSE;
2161         }
2162
2163       if (padding_not_printed - col_sep_length > 0)
2164         {
2165           pad_across_to (padding_not_printed - col_sep_length);
2166           padding_not_printed = ANYWHERE;
2167         }
2168
2169       if (use_col_separator)
2170         print_sep_string ();
2171     }
2172
2173   if (p->numbered)
2174     number (p);
2175
2176   empty_line = FALSE;
2177   if (c == '\n')
2178     return TRUE;
2179
2180   print_clump (p, chars, clump_buff);
2181
2182   for (;;)
2183     {
2184       c = getc (p->fp);
2185
2186       switch (c)
2187         {
2188         case '\n':
2189           return TRUE;
2190         case '\f':
2191           if ((c = getc (p->fp)) != '\n')
2192             ungetc (c, p->fp);
2193           if (keep_FF)
2194             print_a_FF = TRUE;
2195           hold_file (p);
2196           return TRUE;
2197         case EOF:
2198           close_file (p);
2199           return TRUE;
2200         }
2201
2202       last_input_position = input_position;
2203       chars = char_to_clump (c);
2204       if (truncate_lines && input_position > chars_per_column)
2205         {
2206           input_position = last_input_position;
2207           return FALSE;
2208         }
2209
2210       print_clump (p, chars, clump_buff);
2211     }
2212 }
2213
2214 /* Print a line from buff.
2215
2216    If this function has been called, we know we have "something to
2217    print". But it remains to be seen whether we have a real text page
2218    or an empty page (a single form feed) with/without a header only.
2219    Therefore first we set pad_vertically to TRUE and print a header
2220    if necessary.
2221    If FF_FOUND and we are using -t|-T option we omit any newline by
2222    setting pad_vertically to FALSE (see print_page).
2223    Otherwise we pad across if necessary, print separators if necessary
2224    and text of COLUMN *p.
2225
2226    Return TRUE, meaning there is no need to call read_rest_of_line. */
2227
2228 static int
2229 print_stored (COLUMN *p)
2230 {
2231   COLUMN *q;
2232   int i;
2233
2234   int line = p->current_line++;
2235   register char *first = &buff[line_vector[line]];
2236   register char *last = &buff[line_vector[line + 1]];
2237
2238   pad_vertically = TRUE;
2239
2240   if (print_a_header)
2241     print_header ();
2242
2243   if (p->status == FF_FOUND)
2244     {
2245       for (i = 1, q = column_vector; i <= columns; ++i, ++q)
2246         q->status = ON_HOLD;
2247       if (column_vector->lines_to_print <= 0)
2248         {
2249           if (!extremities)
2250             pad_vertically = FALSE;
2251           return TRUE;          /* print a header only */
2252         }
2253     }
2254
2255   if (padding_not_printed - col_sep_length > 0)
2256     {
2257       pad_across_to (padding_not_printed - col_sep_length);
2258       padding_not_printed = ANYWHERE;
2259     }
2260
2261   if (use_col_separator)
2262     print_sep_string ();
2263
2264   while (first != last)
2265     print_char (*first++);
2266
2267   if (spaces_not_printed == 0)
2268     {
2269       output_position = p->start_position + end_vector[line];
2270       if (p->start_position - col_sep_length == chars_per_margin)
2271         output_position -= col_sep_length;
2272     }
2273
2274   return TRUE;
2275 }
2276
2277 /* Convert a character to the proper format and return the number of
2278    characters in the resulting clump.  Increment input_position by
2279    the width of the clump.
2280
2281    Tabs are converted to clumps of spaces.
2282    Nonprintable characters may be converted to clumps of escape
2283    sequences or control prefixes.
2284
2285    Note: the width of a clump is not necessarily equal to the number of
2286    characters in clump_buff.  (e.g, the width of '\b' is -1, while the
2287    number of characters is 1.) */
2288
2289 static int
2290 char_to_clump (int c)
2291 {
2292   register int *s = clump_buff;
2293   register int i;
2294   char esc_buff[4];
2295   int width;
2296   int chars;
2297
2298   if (c == input_tab_char)
2299     {
2300       width = tab_width (chars_per_input_tab, input_position);
2301
2302       if (untabify_input)
2303         {
2304           for (i = width; i; --i)
2305             *s++ = ' ';
2306           chars = width;
2307         }
2308       else
2309         {
2310           *s = c;
2311           chars = 1;
2312         }
2313
2314     }
2315   else if (!ISPRINT (c))
2316     {
2317       if (use_esc_sequence)
2318         {
2319           width = 4;
2320           chars = 4;
2321           *s++ = '\\';
2322           sprintf (esc_buff, "%03o", c);
2323           for (i = 0; i <= 2; ++i)
2324             *s++ = (int) esc_buff[i];
2325         }
2326       else if (use_cntrl_prefix)
2327         {
2328           if (c < 0200)
2329             {
2330               width = 2;
2331               chars = 2;
2332               *s++ = '^';
2333               *s++ = c ^ 0100;
2334             }
2335           else
2336             {
2337               width = 4;
2338               chars = 4;
2339               *s++ = '\\';
2340               sprintf (esc_buff, "%03o", c);
2341               for (i = 0; i <= 2; ++i)
2342                 *s++ = (int) esc_buff[i];
2343             }
2344         }
2345       else if (c == '\b')
2346         {
2347           width = -1;
2348           chars = 1;
2349           *s = c;
2350         }
2351       else
2352         {
2353           width = 0;
2354           chars = 1;
2355           *s = c;
2356         }
2357     }
2358   else
2359     {
2360       width = 1;
2361       chars = 1;
2362       *s = c;
2363     }
2364
2365   input_position += width;
2366   return chars;
2367 }
2368
2369 /* We've just printed some files and need to clean up things before
2370    looking for more options and printing the next batch of files.
2371
2372    Free everything we've xmalloc'ed, except `header'. */
2373
2374 static void
2375 cleanup (void)
2376 {
2377   if (number_buff)
2378     free (number_buff);
2379   if (clump_buff)
2380     free (clump_buff);
2381   if (column_vector)
2382     free (column_vector);
2383   if (line_vector)
2384     free (line_vector);
2385   if (end_vector)
2386     free (end_vector);
2387   if (buff)
2388     free (buff);
2389 }
2390 \f
2391 /* Complain, print a usage message, and die. */
2392
2393 static void
2394 usage (int status)
2395 {
2396   if (status != 0)
2397     fprintf (stderr, _("Try `%s --help' for more information.\n"),
2398              program_name);
2399   else
2400     {
2401       printf (_("\
2402 Usage: %s [OPTION]... [FILE]...\n\
2403 "),
2404               program_name);
2405
2406       printf (_("\
2407 Paginate or columnate FILE(s) for printing.\n\
2408 \n\
2409   +FIRST_PAGE[:LAST_PAGE]\n\
2410                     begin [stop] printing with page FIRST_[LAST_]PAGE\n\
2411   -COLUMN           produce COLUMN-column output and print columns down,\n\
2412                     unless -a is used. Balance number of lines in the\n\
2413                     columns on each page.\n\
2414   -a                print columns across rather than down, used together\n\
2415                     with -COLUMN\n\
2416   -c                use hat notation (^G) and octal backslash notation\n\
2417   -d                double space the output\n\
2418   -e[CHAR[WIDTH]]   expand input CHARs (TABs) to tab WIDTH (8)\n\
2419   -F, -f            use form feeds instead of newlines to separate pages\n\
2420                     (by a 3-line page header with -f or a 5-line header\n\
2421                     and trailer without -f)\n\
2422   -h HEADER         use a centered HEADER instead of filename in page headers\n\
2423                     with long headers left-hand-side truncation may occur\n\
2424                     -h \"\" prints a blank line. Don't use -h\"\"\n\
2425   -i[CHAR[WIDTH]]   replace spaces with CHARs (TABs) to tab WIDTH (8)\n\
2426   -j                merge full lines, turns off -w line truncation, no column\n\
2427                     alignment, -s[STRING] sets separators\n\
2428   -l PAGE_LENGTH    set the page length to PAGE_LENGTH (66) lines\n\
2429                     (default number of lines of text 56, with -f 63)\n\
2430   -m                print all files in parallel, one in each column,\n\
2431                     truncate lines, but join lines of full length with -j\n\
2432   -n[SEP[DIGITS]]   number lines, use DIGITS (5) digits, then SEP (TAB)\n\
2433                     default counting starts with 1st line of input file\n\
2434   -N NUMBER         start counting with NUMBER at 1st line of first\n\
2435                     page printed (see +FIRST_PAGE)\n\
2436   -o MARGIN         offset each line with MARGIN spaces (do not affect -w)\n\
2437   -r                inhibit warning when a file cannot be opened\n\
2438   -s[STRING]        separate columns by an optional STRING\n\
2439                     don't use -s \"STRING\" \n\
2440                     without -s: default sep. \'space\' used, same as -s\" \"\n\
2441                     -s only: no separator used, same as -s\"\" \n\
2442   -t                inhibit page headers and trailers\n\
2443   -T                inhibit page headers and trailers, eliminate any page\n\
2444                     layout by form feeds set in input files\n\
2445   -v                use octal backslash notation\n\
2446   -w PAGE_WIDTH     set page width to PAGE_WIDTH (72) columns, truncate\n\
2447                     lines (see also -j option)\n\
2448   --help            display this help and exit\n\
2449   --version         output version information and exit\n\
2450 \n\
2451 -T implied by -l nn when nn <= 10 or <= 3 with -f. With no FILE, or when\n\
2452 FILE is -, read standard input.\n\
2453 "));
2454       puts (_("\nReport bugs to textutils-bugs@gnu.ai.mit.edu"));
2455     }
2456   exit (status == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
2457 }