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