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