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