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