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