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