465a06c16a90db8711c6a4602f0c29459a9c9654
[platform/upstream/coreutils.git] / src / pr.c
1 /* pr -- convert text files for printing.
2    Copyright (C) 1988, 1991, 1995 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
16    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
17
18 /*  Author: Pete TerMaat.  */
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
33    Options:
34
35    +PAGE        Begin output at page PAGE of the output.
36
37    -COLUMN      Produce output that is COLUMN columns wide and print
38                 columns down.
39
40    -a           Print columns across rather than down.  The input
41                 one
42                 two
43                 three
44                 four
45                 will be printed as
46                 one     two     three
47                 four
48
49    -b           Balance columns on the last page.
50
51    -c           Print unprintable characters as control prefixes.
52                 Control-g is printed as ^G.
53
54    -d           Double space the output.
55
56    -e[c[k]]     Expand tabs to spaces on input.  Optional argument C
57                 is the input tab character. (Default is `\t'.)  Optional
58                 argument K is the input tab character's width.  (Default is 8.)
59
60    -F
61    -f           Use formfeeds instead of newlines to separate pages.
62
63    -h header    Replace the filename in the header with the string HEADER.
64
65    -i[c[k]]     Replace spaces with tabs on output.  Optional argument
66                 C is the output tab character.  (Default is `\t'.)  Optional
67                 argument K is the output tab character's width.  (Default
68                 is 8.)
69
70    -l lines     Set the page length to LINES.  Default is 66.
71
72    -m           Print files in parallel.
73
74    -n[c[k]]     Precede each column with a line number.
75                 (With parallel files, precede each line with a line
76                 number.)  Optional argument C is the character to print
77                 after each number.  (Default `\t'.)  Optional argument
78                 K is the number of digits per line number.  (Default 5.)
79
80    -o offset    Offset each line with a margin OFFSET spaces wide.
81                 Total page width is the size of this offset plus the
82                 width set with `-w'.
83
84    -r           Ignore files that can't be opened.
85
86    -s[c]        Separate each line with a character.  Optional argument C is
87                 the character to be used.  Default is `\t'.
88
89    -t           Do not print headers or footers.
90
91    -v           Print unprintable characters as escape sequences.
92                 Control-G becomes \007.
93
94    -w width     Set the page width to WIDTH characters. */
95 \f
96
97 #include <config.h>
98
99 #include <stdio.h>
100 #include <getopt.h>
101 #include <sys/types.h>
102 #include <time.h>
103 #include "system.h"
104 #include "version.h"
105 #include "error.h"
106
107 char *xmalloc ();
108 char *xrealloc ();
109
110 #ifndef TRUE
111 #define TRUE    1
112 #define FALSE   0
113 #endif
114
115 /* Used with start_position in the struct COLUMN described below.
116    If start_position == ANYWHERE, we aren't truncating columns and
117    can begin printing a column anywhere.  Otherwise we must pad to
118    the horizontal position start_position. */
119 #define ANYWHERE        0
120
121 /* Each column has one of these structures allocated for it.
122    If we're only dealing with one file, fp is the same for all
123    columns.
124
125    The general strategy is to spend time setting up these column
126    structures (storing columns if necessary), after which printing
127    is a matter of flitting from column to column and calling
128    print_func.
129
130    Parallel files, single files printing across in multiple
131    columns, and single files printing down in multiple columns all
132    fit the same printing loop.
133
134    print_func           Function used to print lines in this column.
135                         If we're storing this column it will be
136                         print_stored(), Otherwise it will be read_line().
137
138    char_func            Function used to process characters in this column.
139                         If we're storing this column it will be store_char(),
140                         otherwise it will be print_char().
141
142    current_line         Index of the current entry in line_vector, which
143                         contains the index of the first character of the
144                         current line in buff[].
145
146    lines_stored         Number of lines in this column which are stored in
147                         buff.
148
149    lines_to_print       If we're storing this column, lines_to_print is
150                         the number of stored_lines which remain to be
151                         printed.  Otherwise it is the number of lines
152                         we can print without exceeding lines_per_body.
153
154    start_position       The horizontal position we want to be in before we
155                         print the first character in this column.
156
157    numbered             True means precede this column with a line number. */
158
159 struct COLUMN
160 {
161   FILE *fp;                     /* Input stream for this column. */
162   char *name;                   /* File name. */
163   enum
164   {
165     OPEN,
166     ON_HOLD,                    /* Hit a form feed. */
167     CLOSED
168   } status;                     /* Status of the file pointer. */
169   int (*print_func) ();         /* Func to print lines in this col. */
170   void (*char_func) ();         /* Func to print/store chars in this col. */
171   int current_line;             /* Index of current place in line_vector. */
172   int lines_stored;             /* Number of lines stored in buff. */
173   int lines_to_print;           /* No. lines stored or space left on page. */
174   int start_position;           /* Horizontal position of first char. */
175   int numbered;
176 };
177
178 typedef struct COLUMN COLUMN;
179
180 #define NULLCOL (COLUMN *)0
181
182 static int char_to_clump __P ((int c));
183 static int read_line __P ((COLUMN *p));
184 static int print_page __P ((void));
185 static int print_stored __P ((COLUMN *p));
186 static int open_file __P ((char *name, COLUMN *p));
187 static int skip_to_page __P ((int page));
188 static void getoptarg __P ((char *arg, char switch_char, char *character, int *number));
189 static void usage __P ((int status));
190 static void print_files __P ((int number_of_files, char **av));
191 static void init_header __P ((char *filename, int desc));
192 static void init_store_cols __P ((void));
193 static void store_columns __P ((void));
194 static void balance __P ((int total_stored));
195 static void store_char __P ((int c));
196 static void pad_down __P ((int lines));
197 static void read_rest_of_line __P ((COLUMN *p));
198 static void print_char __P ((int c));
199 static void cleanup __P ((void));
200
201 /* The name under which this program was invoked. */
202 char *program_name;
203
204 /* All of the columns to print.  */
205 static COLUMN *column_vector;
206
207 /* When printing a single file in multiple downward columns,
208    we store the leftmost columns contiguously in buff.
209    To print a line from buff, get the index of the first char
210    from line_vector[i], and print up to line_vector[i + 1]. */
211 static char *buff;
212
213 /* Index of the position in buff where the next character
214    will be stored. */
215 static int buff_current;
216
217 /* The number of characters in buff.
218    Used for allocation of buff and to detect overflow of buff. */
219 static int buff_allocated;
220
221 /* Array of indices into buff.
222    Each entry is an index of the first character of a line.
223    This is used when storing lines to facilitate shuffling when
224    we do column balancing on the last page. */
225 static int *line_vector;
226
227 /* Array of horizonal positions.
228    For each line in line_vector, end_vector[line] is the horizontal
229    position we are in after printing that line.  We keep track of this
230    so that we know how much we need to pad to prepare for the next
231    column. */
232 static int *end_vector;
233
234 /* (-m) True means we're printing multiple files in parallel. */
235 static int parallel_files = FALSE;
236
237 /* (-[0-9]+) True means we're given an option explicitly specifying
238    number of columns.  Used to detect when this option is used with -m. */
239 static int explicit_columns = FALSE;
240
241 /* (-t) True means we're printing headers and footers. */
242 static int extremities = TRUE;
243
244 /* True means we need to print a header as soon as we know we've got input
245    to print after it. */
246 static int print_a_header;
247
248 /* (-h) True means we're using the standard header rather than a
249    customized one specified by the -h flag. */
250 static int standard_header = TRUE;
251
252 /* (-f) True means use formfeeds instead of newlines to separate pages. */
253 static int use_form_feed = FALSE;
254
255 /* True means we have read the standard input. */
256 static int have_read_stdin = FALSE;
257
258 /* True means the -a flag has been given. */
259 static int print_across_flag = FALSE;
260
261 /* True means we're printing one file in multiple (>1) downward columns. */
262 static int storing_columns = TRUE;
263
264 /* (-b) True means balance columns on the last page as Sys V does. */
265 static int balance_columns = FALSE;
266
267 /* (-l) Number of lines on a page, including header and footer lines. */
268 static int lines_per_page = 66;
269
270 /* Number of lines in the header and footer can be reset to 0 using
271    the -t flag. */
272 static int lines_per_header = 5;
273 static int lines_per_body;
274 static int lines_per_footer = 5;
275
276 /* (-w) Width in characters of the page.  Does not include the width of
277    the margin. */
278 static int chars_per_line = 72;
279
280 /* Number of characters in a column.  Based on the gutter and page widths. */
281 static int chars_per_column;
282
283 /* (-e) True means convert tabs to spaces on input. */
284 static int untabify_input = FALSE;
285
286 /* (-e) The input tab character. */
287 static char input_tab_char = '\t';
288
289 /* (-e) Tabstops are at chars_per_tab, 2*chars_per_tab, 3*chars_per_tab, ...
290    where the leftmost column is 1. */
291 static int chars_per_input_tab = 8;
292
293 /* (-i) True means convert spaces to tabs on output. */
294 static int tabify_output = FALSE;
295
296 /* (-i) The output tab character. */
297 static char output_tab_char = '\t';
298
299 /* (-i) The width of the output tab. */
300 static int chars_per_output_tab = 8;
301
302 /* Keeps track of pending white space.  When we hit a nonspace
303    character after some whitespace, we print whitespace, tabbing
304    if necessary to get to output_position + spaces_not_printed. */
305 static int spaces_not_printed;
306
307 /* Number of spaces between columns (though tabs can be used when possible to
308    use up the equivalent amount of space).  Not sure if this is worth making
309    a flag for.  BSD uses 0, Sys V uses 1.  Sys V looks better. */
310 static int chars_per_gutter = 1;
311
312 /* (-o) Number of spaces in the left margin (tabs used when possible). */
313 static int chars_per_margin = 0;
314
315 /* Position where the next character will fall.
316    Leftmost position is 0 + chars_per_margin.
317    Rightmost position is chars_per_margin + chars_per_line - 1.
318    This is important for converting spaces to tabs on output. */
319 static int output_position;
320
321 /* Horizontal position relative to the current file.
322    (output_position depends on where we are on the page;
323    input_position depends on where we are in the file.)
324    Important for converting tabs to spaces on input. */
325 static int input_position;
326
327 /* Count number of failed opens so we can exit with non-zero
328    status if there were any.  */
329 static int failed_opens = 0;
330
331 /* The horizontal position we'll be at after printing a tab character
332    of width c_ from the position h_. */
333 #define pos_after_tab(c_, h_) h_ - h_ % c_ + c_
334
335 /* The number of spaces taken up if we print a tab character with width
336    c_ from position h_. */
337 #define tab_width(c_, h_) - h_ % c_ + c_
338
339 /* (-NNN) Number of columns of text to print. */
340 static int columns = 1;
341
342 /* (+NNN) Page number on which to begin printing. */
343 static int first_page_number = 1;
344
345 /* Number of files open (not closed, not on hold). */
346 static int files_ready_to_read = 0;
347
348 /* Current page number.  Displayed in header. */
349 static int page_number;
350
351 /* Current line number.  Displayed when -n flag is specified.
352
353    When printing files in parallel (-m flag), line numbering is as follows:
354    1    foo     goo     moo
355    2    hoo     too     zoo
356
357    When printing files across (-a flag), ...
358    1    foo     2       moo     3       goo
359    4    hoo     3       too     6       zoo
360
361    Otherwise, line numbering is as follows:
362    1    foo     3       goo     5       too
363    2    moo     4       hoo     6       zoo */
364 static int line_number;
365
366 /* (-n) True means lines should be preceded by numbers. */
367 static int numbered_lines = FALSE;
368
369 /* (-n) Character which follows each line number. */
370 static char number_separator = '\t';
371
372 /* (-n) Width in characters of a line number. */
373 static int chars_per_number = 5;
374
375 /* Used when widening the first column to accommodate numbers -- only
376    needed when printing files in parallel.  Includes width of both the
377    number and the number_separator. */
378 static int number_width;
379
380 /* Buffer sprintf uses to format a line number. */
381 static char *number_buff;
382
383 /* (-v) True means unprintable characters are printed as escape sequences.
384    control-g becomes \007. */
385 static int use_esc_sequence = FALSE;
386
387 /* (-c) True means unprintable characters are printed as control prefixes.
388    control-g becomes ^G. */
389 static int use_cntrl_prefix = FALSE;
390
391 /* (-d) True means output is double spaced. */
392 static int double_space = FALSE;
393
394 /* Number of files opened initially in init_files.  Should be 1
395    unless we're printing multiple files in parallel. */
396 static int total_files = 0;
397
398 /* (-r) True means don't complain if we can't open a file. */
399 static int ignore_failed_opens = FALSE;
400
401 /* (-s) True means we separate columns with a specified character. */
402 static int use_column_separator = FALSE;
403
404 /* Character used to separate columns if the the -s flag has been specified. */
405 static char column_separator = '\t';
406
407 /* Number of separator characters waiting to be printed as soon as we
408    know that we have any input remaining to be printed. */
409 static int separators_not_printed;
410
411 /* Position we need to pad to, as soon as we know that we have input
412    remaining to be printed. */
413 static int padding_not_printed;
414
415 /* True means we should pad the end of the page.  Remains false until we
416    know we have a page to print. */
417 static int pad_vertically;
418
419 /* (-h) String of characters used in place of the filename in the header. */
420 static char *custom_header;
421
422 /* String containing the date, filename or custom header, and "Page ". */
423 static char *header;
424
425 static int *clump_buff;
426
427 /* True means we truncate lines longer than chars_per_column. */
428 static int truncate_lines = FALSE;
429
430 /* If non-zero, display usage information and exit.  */
431 static int show_help;
432
433 /* If non-zero, print the version on standard output then exit.  */
434 static int show_version;
435
436 static struct option const long_options[] =
437 {
438   {"help", no_argument, &show_help, 1},
439   {"version", no_argument, &show_version, 1},
440   {0, 0, 0, 0}
441 };
442
443 /* Return the number of columns that have either an open file or
444    stored lines. */
445
446 static int
447 cols_ready_to_print (void)
448 {
449   COLUMN *q;
450   int i;
451   int n;
452
453   n = 0;
454   for (q = column_vector, i = 0; i < columns; ++q, ++i)
455     if (q->status == OPEN ||
456         (storing_columns && q->lines_stored > 0 && q->lines_to_print > 0))
457       ++n;
458   return n;
459 }
460
461 void
462 main (int argc, char **argv)
463 {
464   int c;
465   int accum = 0;
466   int n_files;
467   char **file_names;
468
469   program_name = argv[0];
470
471   n_files = 0;
472   file_names = (argc > 1
473                 ? (char **) xmalloc ((argc - 1) * sizeof (char *))
474                 : NULL);
475
476   while (1)
477     {
478       c = getopt_long (argc, argv,
479                        "-0123456789abcde::fFh:i::l:mn::o:rs::tvw:",
480                        long_options, (int *) 0);
481       if (c == 1)              /* Non-option argument. */
482         {
483           char *s;
484           s = optarg;
485           if (*s == '+')
486             {
487               ++s;
488               if (!ISDIGIT (*s))
489                 {
490                   error (0, 0, _("`+' requires a numeric argument"));
491                   usage (2);
492                 }
493               /* FIXME: use strtol */
494               first_page_number = atoi (s);
495             }
496           else
497             {
498               file_names[n_files++] = optarg;
499             }
500         }
501       else
502         {
503           if (ISDIGIT (c))
504             {
505               accum = accum * 10 + c - '0';
506               continue;
507             }
508           else
509             {
510               if (accum > 0)
511                 {
512                   columns = accum;
513                   explicit_columns = TRUE;
514                   accum = 0;
515                 }
516             }
517         }
518
519       if (c == 1)
520         continue;
521
522       if (c == EOF)
523         break;
524
525       switch (c)
526         {
527         case 0: /* getopt long option */
528           break;
529
530         case 'a':
531           print_across_flag = TRUE;
532           storing_columns = FALSE;
533           break;
534         case 'b':
535           balance_columns = TRUE;
536           break;
537         case 'c':
538           use_cntrl_prefix = TRUE;
539           break;
540         case 'd':
541           double_space = TRUE;
542           break;
543         case 'e':
544           if (optarg)
545             getoptarg (optarg, 'e', &input_tab_char,
546                        &chars_per_input_tab);
547           /* Could check tab width > 0. */
548           untabify_input = TRUE;
549           break;
550         case 'f':
551         case 'F':
552           use_form_feed = TRUE;
553           break;
554         case 'h':
555           custom_header = optarg;
556           standard_header = FALSE;
557           break;
558         case 'i':
559           if (optarg)
560             getoptarg (optarg, 'i', &output_tab_char,
561                        &chars_per_output_tab);
562           /* Could check tab width > 0. */
563           tabify_output = TRUE;
564           break;
565         case 'l':
566           lines_per_page = atoi (optarg);
567           break;
568         case 'm':
569           parallel_files = TRUE;
570           storing_columns = FALSE;
571           break;
572         case 'n':
573           numbered_lines = TRUE;
574           if (optarg)
575             getoptarg (optarg, 'n', &number_separator,
576                        &chars_per_number);
577           break;
578         case 'o':
579           chars_per_margin = atoi (optarg);
580           break;
581         case 'r':
582           ignore_failed_opens = TRUE;
583           break;
584         case 's':
585           use_column_separator = TRUE;
586           if (optarg)
587             {
588               char *s;
589               s = optarg;
590               column_separator = *s;
591               if (*++s)
592                 {
593                   fprintf (stderr, _("\
594 %s: extra characters in the argument to the `-s' option: `%s'\n"),
595                            program_name, s);
596                   usage (2);
597                 }
598             }
599           break;
600         case 't':
601           extremities = FALSE;
602           break;
603         case 'v':
604           use_esc_sequence = TRUE;
605           break;
606         case 'w':
607           chars_per_line = atoi (optarg);
608           break;
609         default:
610           usage (2);
611           break;
612         }
613     }
614
615   if (show_version)
616     {
617       printf ("pr - %s\n", version_string);
618       exit (0);
619     }
620
621   if (show_help)
622     usage (0);
623
624   if (parallel_files && explicit_columns)
625     error (1, 0,
626   _("Cannot specify number of columns when printing in parallel."));
627
628   if (parallel_files && print_across_flag)
629     error (1, 0,
630   _("Cannot specify both printing across and printing in parallel."));
631
632   for ( ; optind < argc; optind++)
633     {
634       file_names[n_files++] = argv[optind];
635     }
636
637   if (n_files == 0)
638     {
639       /* No file arguments specified;  read from standard input.  */
640       print_files (0, (char **) 0);
641     }
642   else
643     {
644       if (parallel_files)
645         print_files (n_files, file_names);
646       else
647         {
648           int i;
649           for (i=0; i<n_files; i++)
650             print_files (1, &file_names[i]);
651         }
652     }
653
654   cleanup ();
655
656   if (have_read_stdin && fclose (stdin) == EOF)
657     error (1, errno, _("standard input"));
658   if (ferror (stdout) || fclose (stdout) == EOF)
659     error (1, errno, _("write error"));
660   if (failed_opens > 0)
661     exit(1);
662   exit (0);
663 }
664
665 /* Parse options of the form -scNNN.
666
667    Example: -nck, where 'n' is the option, c is the optional number
668    separator, and k is the optional width of the field used when printing
669    a number. */
670
671 static void
672 getoptarg (char *arg, char switch_char, char *character, int *number)
673 {
674   if (!ISDIGIT (*arg))
675     *character = *arg++;
676   if (*arg)
677     {
678       if (ISDIGIT (*arg))
679         *number = atoi (arg);
680       else
681         {
682           fprintf (stderr, _("\
683 %s: extra characters in the argument to the `-%c' option: `%s'\n"),
684                    program_name, switch_char, arg);
685           usage (2);
686         }
687     }
688 }
689 \f
690 /* Set parameters related to formatting. */
691
692 static void
693 init_parameters (int number_of_files)
694 {
695   int chars_used_by_number = 0;
696
697   lines_per_body = lines_per_page - lines_per_header - lines_per_footer;
698   if (lines_per_body <= 0)
699     extremities = FALSE;
700   if (extremities == FALSE)
701     lines_per_body = lines_per_page;
702
703   if (double_space)
704     lines_per_body = lines_per_body / 2;
705
706   /* If input is stdin, cannot print parallel files.  BSD dumps core
707      on this. */
708   if (number_of_files == 0)
709     parallel_files = FALSE;
710
711   if (parallel_files)
712     columns = number_of_files;
713
714   /* Tabification is assumed for multiple columns. */
715   if (columns > 1)
716     {
717       if (!use_column_separator)
718         truncate_lines = TRUE;
719
720       untabify_input = TRUE;
721       tabify_output = TRUE;
722     }
723   else
724     storing_columns = FALSE;
725
726   if (numbered_lines)
727     {
728       if (number_separator == input_tab_char)
729         {
730           number_width = chars_per_number +
731             tab_width (chars_per_input_tab,
732                        (chars_per_margin + chars_per_number));
733         }
734       else
735         number_width = chars_per_number + 1;
736       /* The number is part of the column width unless we are
737          printing files in parallel. */
738       if (parallel_files)
739         chars_used_by_number = number_width;
740     }
741
742   chars_per_column = (chars_per_line - chars_used_by_number -
743                       (columns - 1) * chars_per_gutter) / columns;
744
745   if (chars_per_column < 1)
746     error (1, 0, _("page width too narrow"));
747
748   if (numbered_lines)
749     {
750       if (number_buff != (char *) 0)
751         free (number_buff);
752       number_buff = (char *)
753         xmalloc (2 * chars_per_number * sizeof (char));
754     }
755
756   /* Pick the maximum between the tab width and the width of an
757      escape sequence. */
758   if (clump_buff != (int *) 0)
759     free (clump_buff);
760   clump_buff = (int *) xmalloc ((chars_per_input_tab > 4
761                                  ? chars_per_input_tab : 4) * sizeof (int));
762 }
763 \f
764 /* Open the necessary files,
765    maintaining a COLUMN structure for each column.
766
767    With multiple files, each column p has a different p->fp.
768    With single files, each column p has the same p->fp.
769    Return 1 if (number_of_files > 0) and no files can be opened,
770    0 otherwise.  */
771
772 static int
773 init_fps (int number_of_files, char **av)
774 {
775   int i, files_left;
776   COLUMN *p;
777   FILE *firstfp;
778   char *firstname;
779
780   total_files = 0;
781
782   if (column_vector != NULLCOL)
783     free ((char *) column_vector);
784   column_vector = (COLUMN *) xmalloc (columns * sizeof (COLUMN));
785
786   if (parallel_files)
787     {
788       files_left = number_of_files;
789       for (p = column_vector; files_left--; ++p, ++av)
790         {
791           if (open_file (*av, p) == 0)
792             {
793               --p;
794               --columns;
795             }
796         }
797       if (columns == 0)
798         return 1;
799       init_header ("", -1);
800     }
801   else
802     {
803       p = column_vector;
804       if (number_of_files > 0)
805         {
806           if (open_file (*av, p) == 0)
807             return 1;
808           init_header (*av, fileno (p->fp));
809         }
810       else
811         {
812           p->name = _("standard input");
813           p->fp = stdin;
814           have_read_stdin = TRUE;
815           p->status = OPEN;
816           ++total_files;
817           init_header ("", -1);
818         }
819
820       firstname = p->name;
821       firstfp = p->fp;
822       for (i = columns - 1, ++p; i; --i, ++p)
823         {
824           p->name = firstname;
825           p->fp = firstfp;
826           p->status = OPEN;
827         }
828     }
829   files_ready_to_read = total_files;
830   return 0;
831 }
832 \f
833 /* Determine print_func and char_func, the functions
834    used by each column for printing and/or storing.
835
836    Determine the horizontal position desired when we begin
837    printing a column (p->start_position). */
838
839 static void
840 init_funcs (void)
841 {
842   int i, h, h_next;
843   COLUMN *p;
844
845   h = chars_per_margin;
846
847   if (use_column_separator)
848     h_next = ANYWHERE;
849   else
850     {
851       /* When numbering lines of parallel files, we enlarge the
852          first column to accomodate the number.  Looks better than
853          the Sys V approach. */
854       if (parallel_files && numbered_lines)
855         h_next = h + chars_per_column + number_width;
856       else
857         h_next = h + chars_per_column;
858     }
859
860   /* This loop takes care of all but the rightmost column. */
861
862   for (p = column_vector, i = 1; i < columns; ++p, ++i)
863     {
864       if (storing_columns)      /* One file, multi columns down. */
865         {
866           p->char_func = store_char;
867           p->print_func = print_stored;
868         }
869       else
870         /* One file, multi columns across; or parallel files.  */
871         {
872           p->char_func = print_char;
873           p->print_func = read_line;
874         }
875
876       /* Number only the first column when printing files in
877          parallel. */
878       p->numbered = numbered_lines && (!parallel_files || i == 1);
879       p->start_position = h;
880
881       /* If we're using separators, all start_positions are
882          ANYWHERE, except the first column's start_position when
883          using a margin. */
884
885       if (use_column_separator)
886         {
887           h = ANYWHERE;
888           h_next = ANYWHERE;
889         }
890       else
891         {
892           h = h_next + chars_per_gutter;
893           h_next = h + chars_per_column;
894         }
895     }
896
897   /* The rightmost column.
898
899      Doesn't need to be stored unless we intend to balance
900      columns on the last page. */
901   if (storing_columns && balance_columns)
902     {
903       p->char_func = store_char;
904       p->print_func = print_stored;
905     }
906   else
907     {
908       p->char_func = print_char;
909       p->print_func = read_line;
910     }
911
912   p->numbered = numbered_lines && (!parallel_files || i == 1);
913   p->start_position = h;
914 }
915 \f
916 /* Open a file.  Return nonzero if successful, zero if failed. */
917
918 static int
919 open_file (char *name, COLUMN *p)
920 {
921   if (!strcmp (name, "-"))
922     {
923       p->name = _("standard input");
924       p->fp = stdin;
925       have_read_stdin = 1;
926     }
927   else
928     {
929       p->name = name;
930       p->fp = fopen (name, "r");
931     }
932   if (p->fp == NULL)
933     {
934       ++failed_opens;
935       if (!ignore_failed_opens)
936         error (0, errno, "%s", name);
937       return 0;
938     }
939   p->status = OPEN;
940   ++total_files;
941   return 1;
942 }
943
944 /* Close the file in P.
945
946    If we aren't dealing with multiple files in parallel, we change
947    the status of all columns in the column list to reflect the close. */
948
949 static void
950 close_file (COLUMN *p)
951 {
952   COLUMN *q;
953   int i;
954
955   if (p->status == CLOSED)
956     return;
957   if (ferror (p->fp))
958     error (1, errno, "%s", p->name);
959   if (p->fp != stdin && fclose (p->fp) == EOF)
960     error (1, errno, "%s", p->name);
961
962   if (!parallel_files)
963     {
964       for (q = column_vector, i = columns; i; ++q, --i)
965         {
966           q->status = CLOSED;
967           if (q->lines_stored == 0)
968             {
969               q->lines_to_print = 0;
970             }
971         }
972     }
973   else
974     {
975       p->status = CLOSED;
976       p->lines_to_print = 0;
977     }
978
979   --files_ready_to_read;
980 }
981
982 /* Put a file on hold until we start a new page,
983    since we've hit a form feed.
984
985    If we aren't dealing with parallel files, we must change the
986    status of all columns in the column list. */
987
988 static void
989 hold_file (COLUMN *p)
990 {
991   COLUMN *q;
992   int i;
993
994   if (!parallel_files)
995     for (q = column_vector, i = columns; i; ++q, --i)
996       q->status = ON_HOLD;
997   else
998     p->status = ON_HOLD;
999   p->lines_to_print = 0;
1000   --files_ready_to_read;
1001 }
1002
1003 /* Undo hold_file -- go through the column list and change any
1004    ON_HOLD columns to OPEN.  Used at the end of each page. */
1005
1006 static void
1007 reset_status (void)
1008 {
1009   int i = columns;
1010   COLUMN *p;
1011
1012   for (p = column_vector; i; --i, ++p)
1013     if (p->status == ON_HOLD)
1014       {
1015         p->status = OPEN;
1016         files_ready_to_read++;
1017       }
1018 }
1019 \f
1020 /* Print a single file, or multiple files in parallel.
1021
1022    Set up the list of columns, opening the necessary files.
1023    Allocate space for storing columns, if necessary.
1024    Skip to first_page_number, if user has asked to skip leading pages.
1025    Determine which functions are appropriate to store/print lines
1026    in each column.
1027    Print the file(s). */
1028
1029 static void
1030 print_files (int number_of_files, char **av)
1031 {
1032   init_parameters (number_of_files);
1033   if (init_fps (number_of_files, av))
1034     return;
1035   if (storing_columns)
1036     init_store_cols ();
1037
1038   if (first_page_number > 1)
1039     {
1040       if (!skip_to_page (first_page_number))
1041         return;
1042       else
1043         page_number = first_page_number;
1044     }
1045   else
1046     page_number = 1;
1047
1048   init_funcs ();
1049
1050   line_number = 1;
1051   while (print_page ())
1052     ;
1053 }
1054 \f
1055 /* Generous estimate of number of characters taken up by "Jun  7 00:08 " and
1056    "Page NNNNN". */
1057 #define CHARS_FOR_DATE_AND_PAGE 50
1058
1059 /* Initialize header information.
1060    If DESC is non-negative, it is a file descriptor open to
1061    FILENAME for reading.
1062
1063    Allocate space for a header string,
1064    Determine the time, insert file name or user-specified string.
1065
1066    It might be nice to have a "blank headers" option, since
1067    pr -h "" still prints the date and page number. */
1068
1069 static void
1070 init_header (char *filename, int desc)
1071 {
1072   int chars_per_header;
1073   char *f = filename;
1074   char *t, *middle;
1075   struct stat st;
1076
1077   if (filename == 0)
1078     f = "";
1079
1080   /* If parallel files or standard input, use current time. */
1081   if (desc < 0 || !strcmp (filename, "-") || fstat (desc, &st))
1082     st.st_mtime = time ((time_t *) 0);
1083   t = ctime (&st.st_mtime);
1084
1085   t[16] = '\0';                 /* Mark end of month and time string. */
1086   t[24] = '\0';                 /* Mark end of year string. */
1087
1088   middle = standard_header ? f : custom_header;
1089
1090   chars_per_header = strlen (middle) + CHARS_FOR_DATE_AND_PAGE + 1;
1091   if (header != (char *) 0)
1092     free (header);
1093   header = (char *) xmalloc (chars_per_header * sizeof (char));
1094
1095   sprintf (header, _("%s %s  %s Page"), &t[4], &t[20], middle);
1096 }
1097 \f
1098 /* Set things up for printing a page
1099
1100    Scan through the columns ...
1101      Determine which are ready to print
1102        (i.e., which have lines stored or open files)
1103      Set p->lines_to_print appropriately
1104        (to p->lines_stored if we're storing, or lines_per_body
1105        if we're reading straight from the file)
1106      Keep track of this total so we know when to stop printing */
1107
1108 static void
1109 init_page (void)
1110 {
1111   int j;
1112   COLUMN *p;
1113
1114   if (storing_columns)
1115     {
1116       store_columns ();
1117       for (j = columns - 1, p = column_vector; j; --j, ++p)
1118         {
1119           p->lines_to_print = p->lines_stored;
1120         }
1121
1122       /* Last column. */
1123       if (balance_columns)
1124         {
1125           p->lines_to_print = p->lines_stored;
1126         }
1127       /* Since we're not balancing columns, we don't need to store
1128          the rightmost column.   Read it straight from the file. */
1129       else
1130         {
1131           if (p->status == OPEN)
1132             {
1133               p->lines_to_print = lines_per_body;
1134             }
1135           else
1136             p->lines_to_print = 0;
1137         }
1138     }
1139   else
1140     for (j = columns, p = column_vector; j; --j, ++p)
1141       if (p->status == OPEN)
1142         {
1143           p->lines_to_print = lines_per_body;
1144         }
1145       else
1146         p->lines_to_print = 0;
1147 }
1148
1149 /* Print one page.
1150
1151    As long as there are lines left on the page and columns ready to print,
1152      Scan across the column list
1153        if the column has stored lines or the file is open
1154          pad to the appropriate spot
1155          print the column
1156    pad the remainder of the page with \n or \f as requested
1157    reset the status of all files -- any files which where on hold because
1158      of formfeeds are now put back into the lineup. */
1159
1160 static int
1161 print_page (void)
1162 {
1163   int j;
1164   int lines_left_on_page;
1165   COLUMN *p;
1166
1167   /* Used as an accumulator (with | operator) of successive values of
1168      pad_vertically.  The trick is to set pad_vertically
1169      to zero before each run through the inner loop, then after that
1170      loop, it tells us whether a line was actually printed (whether a
1171      newline needs to be output -- or two for double spacing).  But those
1172      values have to be accumulated (in pv) so we can invoke pad_down
1173      properly after the outer loop completes. */
1174   int pv;
1175
1176   init_page ();
1177
1178   if (cols_ready_to_print () == 0)
1179     return FALSE;
1180
1181   if (extremities)
1182     print_a_header = TRUE;
1183
1184   /* Don't pad unless we know a page was printed. */
1185   pad_vertically = FALSE;
1186   pv = FALSE;
1187
1188   lines_left_on_page = lines_per_body;
1189   if (double_space)
1190     lines_left_on_page *= 2;
1191
1192   while (lines_left_on_page > 0 && cols_ready_to_print () > 0)
1193     {
1194       output_position = 0;
1195       spaces_not_printed = 0;
1196       separators_not_printed = 0;
1197       pad_vertically = FALSE;
1198
1199       for (j = 1, p = column_vector; j <= columns; ++j, ++p)
1200         {
1201           input_position = 0;
1202           if (p->lines_to_print > 0)
1203             {
1204               padding_not_printed = p->start_position;
1205
1206               if (!(p->print_func) (p))
1207                 read_rest_of_line (p);
1208               pv |= pad_vertically;
1209
1210               if (use_column_separator)
1211                 ++separators_not_printed;
1212
1213               --p->lines_to_print;
1214               if (p->lines_to_print <= 0)
1215                 {
1216                   if (cols_ready_to_print () <= 0)
1217                     break;
1218                 }
1219             }
1220         }
1221
1222       if (pad_vertically)
1223         {
1224           putchar ('\n');
1225           --lines_left_on_page;
1226         }
1227
1228       if (double_space && pv && extremities)
1229         {
1230           putchar ('\n');
1231           --lines_left_on_page;
1232         }
1233     }
1234
1235   pad_vertically = pv;
1236
1237   if (pad_vertically && extremities)
1238     pad_down (lines_left_on_page + lines_per_footer);
1239
1240   reset_status ();              /* Change ON_HOLD to OPEN. */
1241
1242   return TRUE;                  /* More pages to go. */
1243 }
1244 \f
1245 /* Allocate space for storing columns.
1246
1247    This is necessary when printing multiple columns from a single file.
1248    Lines are stored consecutively in buff, separated by '\0'.
1249    (We can't use a fixed offset since with the '-s' flag lines aren't
1250    truncated.)
1251
1252    We maintain a list (line_vector) of pointers to the beginnings
1253    of lines in buff.  We allocate one more than the number of lines
1254    because the last entry tells us the index of the last character,
1255    which we need to know in order to print the last line in buff. */
1256
1257 static void
1258 init_store_cols (void)
1259 {
1260   int total_lines = lines_per_body * columns;
1261   int chars_if_truncate = total_lines * (chars_per_column + 1);
1262
1263   if (line_vector != (int *) 0)
1264     free ((int *) line_vector);
1265   line_vector = (int *) xmalloc ((total_lines + 1) * sizeof (int *));
1266
1267   if (end_vector != (int *) 0)
1268     free ((int *) end_vector);
1269   end_vector = (int *) xmalloc (total_lines * sizeof (int *));
1270
1271   if (buff != (char *) 0)
1272     free (buff);
1273   buff_allocated = use_column_separator ? 2 * chars_if_truncate
1274     : chars_if_truncate;        /* Tune this. */
1275   buff = (char *) xmalloc (buff_allocated * sizeof (char));
1276 }
1277
1278 /* Store all but the rightmost column.
1279    (Used when printing a single file in multiple downward columns)
1280
1281    For each column
1282      set p->current_line to be the index in line_vector of the
1283        first line in the column
1284      For each line in the column
1285        store the line in buff
1286        add to line_vector the index of the line's first char
1287     buff_start is the index in buff of the first character in the
1288      current line. */
1289
1290 static void
1291 store_columns (void)
1292 {
1293   int i, j;
1294   int line = 0;
1295   int buff_start;
1296   int last_col;                 /* The rightmost column which will be saved in buff */
1297   COLUMN *p;
1298
1299   buff_current = 0;
1300   buff_start = 0;
1301
1302   if (balance_columns)
1303     last_col = columns;
1304   else
1305     last_col = columns - 1;
1306
1307   for (i = 1, p = column_vector; i <= last_col; ++i, ++p)
1308     p->lines_stored = 0;
1309
1310   for (i = 1, p = column_vector; i <= last_col && files_ready_to_read;
1311        ++i, ++p)
1312     {
1313       p->current_line = line;
1314       for (j = lines_per_body; j && files_ready_to_read; --j)
1315
1316         if (p->status == OPEN)  /* Redundant.  Clean up. */
1317           {
1318             input_position = 0;
1319
1320             if (!read_line (p))
1321               read_rest_of_line (p);
1322
1323             if (p->status == OPEN
1324                 || buff_start != buff_current)
1325               {
1326                 ++p->lines_stored;
1327                 line_vector[line] = buff_start;
1328                 end_vector[line++] = input_position;
1329                 buff_start = buff_current;
1330               }
1331           }
1332     }
1333
1334   /* Keep track of the location of the last char in buff. */
1335   line_vector[line] = buff_start;
1336
1337   if (balance_columns && p->lines_stored != lines_per_body)
1338     balance (line);
1339 }
1340
1341 static void
1342 balance (int total_stored)
1343 {
1344   COLUMN *p;
1345   int i, lines;
1346   int first_line = 0;
1347
1348   for (i = 1, p = column_vector; i <= columns; ++i, ++p)
1349     {
1350       lines = total_stored / columns;
1351       if (i <= total_stored % columns)
1352         ++lines;
1353
1354       p->lines_stored = lines;
1355       p->current_line = first_line;
1356
1357       first_line += lines;
1358     }
1359 }
1360
1361 /* Store a character in the buffer. */
1362
1363 static void
1364 store_char (int c)
1365 {
1366   if (buff_current >= buff_allocated)
1367     {
1368       /* May be too generous. */
1369       buff_allocated = 2 * buff_allocated;
1370       buff = (char *) xrealloc (buff, buff_allocated * sizeof (char));
1371     }
1372   buff[buff_current++] = (char) c;
1373 }
1374
1375 static void
1376 number (COLUMN *p)
1377 {
1378   int i;
1379   char *s;
1380
1381   sprintf (number_buff, "%*d", chars_per_number, line_number++);
1382   s = number_buff;
1383   for (i = chars_per_number; i > 0; i--)
1384     (p->char_func) ((int) *s++);
1385
1386   if (number_separator == input_tab_char)
1387     {
1388       i = number_width - chars_per_number;
1389       while (i-- > 0)
1390         (p->char_func) ((int) ' ');
1391     }
1392   else
1393     (p->char_func) ((int) number_separator);
1394
1395   if (truncate_lines && !parallel_files)
1396     input_position += number_width;
1397 }
1398 \f
1399 /* Print (or store) padding until the current horizontal position
1400    is position. */
1401
1402 static void
1403 pad_across_to (int position)
1404 {
1405   register int h = output_position;
1406
1407   if (tabify_output)
1408     spaces_not_printed = position - output_position;
1409   else
1410     {
1411       while (++h <= position)
1412         putchar (' ');
1413       output_position = position;
1414     }
1415 }
1416
1417 /* Pad to the bottom of the page.
1418
1419    If the user has requested a formfeed, use one.
1420    Otherwise, use newlines. */
1421
1422 static void
1423 pad_down (int lines)
1424 {
1425   register int i;
1426
1427   if (use_form_feed)
1428     putchar ('\f');
1429   else
1430     for (i = lines; i; --i)
1431       putchar ('\n');
1432 }
1433
1434 /* Read the rest of the line.
1435
1436    Read from the current column's file until an end of line is
1437    hit.  Used when we've truncated a line and we no longer need
1438    to print or store its characters. */
1439
1440 static void
1441 read_rest_of_line (COLUMN *p)
1442 {
1443   register int c;
1444   FILE *f = p->fp;
1445
1446   while ((c = getc (f)) != '\n')
1447     {
1448       if (c == '\f')
1449         {
1450           hold_file (p);
1451           break;
1452         }
1453       else if (c == EOF)
1454         {
1455           close_file (p);
1456           break;
1457         }
1458     }
1459 }
1460 \f
1461 /* If we're tabifying output,
1462
1463    When print_char encounters white space it keeps track
1464    of our desired horizontal position and delays printing
1465    until this function is called. */
1466
1467 static void
1468 print_white_space (void)
1469 {
1470   register int h_new;
1471   register int h_old = output_position;
1472   register int goal = h_old + spaces_not_printed;
1473
1474   while (goal - h_old > 1
1475           && (h_new = pos_after_tab (chars_per_output_tab, h_old)) <= goal)
1476     {
1477       putchar (output_tab_char);
1478       h_old = h_new;
1479     }
1480   while (++h_old <= goal)
1481     putchar (' ');
1482
1483   output_position = goal;
1484   spaces_not_printed = 0;
1485 }
1486
1487 /* Print column separators.
1488
1489    We keep a count until we know that we'll be printing a line,
1490    then print_separators() is called. */
1491
1492 static void
1493 print_separators (void)
1494 {
1495   for (; separators_not_printed > 0; --separators_not_printed)
1496     print_char (column_separator);
1497 }
1498
1499 /* Print (or store, depending on p->char_func) a clump of N
1500    characters. */
1501
1502 static void
1503 print_clump (COLUMN *p, int n, int *clump)
1504 {
1505   while (n--)
1506     (p->char_func) (*clump++);
1507 }
1508
1509 /* Print a character.
1510
1511    If we're tabifying, all tabs have been converted to spaces by
1512    process_char().  Keep a count of consecutive spaces, and when
1513    a nonspace is encountered, call print_white_space() to print the
1514    required number of tabs and spaces. */
1515
1516 static void
1517 print_char (int c)
1518 {
1519   if (tabify_output)
1520     {
1521       if (c == ' ')
1522         {
1523           ++spaces_not_printed;
1524           return;
1525         }
1526       else if (spaces_not_printed > 0)
1527         print_white_space ();
1528
1529       /* Nonprintables are assumed to have width 0, except '\b'. */
1530       if (!ISPRINT (c))
1531         {
1532           if (c == '\b')
1533             --output_position;
1534         }
1535       else
1536         ++output_position;
1537     }
1538   putchar (c);
1539 }
1540
1541 /* Skip to page PAGE before printing. */
1542
1543 static int
1544 skip_to_page (int page)
1545 {
1546   int n, i, j;
1547   COLUMN *p;
1548
1549   for (n = 1; n < page; ++n)
1550     {
1551       for (i = 1; i <= lines_per_body; ++i)
1552         {
1553           for (j = 1, p = column_vector; j <= columns; ++j, ++p)
1554             read_rest_of_line (p);
1555         }
1556       reset_status ();
1557     }
1558   return files_ready_to_read > 0;
1559 }
1560
1561 /* Print a header.
1562
1563    Formfeeds are assumed to use up two lines at the beginning of
1564    the page. */
1565
1566 static void
1567 print_header (void)
1568 {
1569   if (!use_form_feed)
1570     fprintf (stdout, "\n\n");
1571
1572   output_position = 0;
1573   pad_across_to (chars_per_margin);
1574   print_white_space ();
1575
1576   fprintf (stdout, "%s %d\n\n\n", header, page_number++);
1577
1578   print_a_header = FALSE;
1579   output_position = 0;
1580 }
1581
1582 /* Print (or store, if p->char_func is store_char()) a line.
1583
1584    Read a character to determine whether we have a line or not.
1585    (We may hit EOF, \n, or \f)
1586
1587    Once we know we have a line,
1588      set pad_vertically = TRUE, meaning it's safe
1589        to pad down at the end of the page, since we do have a page.
1590        print a header if needed.
1591      pad across to padding_not_printed if needed.
1592      print any separators which need to be printed.
1593      print a line number if it needs to be printed.
1594
1595    Print the clump which corresponds to the first character.
1596
1597    Enter a loop and keep printing until an end of line condition
1598      exists, or until we exceed chars_per_column.
1599
1600    Return FALSE if we exceed chars_per_column before reading
1601      an end of line character, TRUE otherwise. */
1602
1603 static int
1604 read_line (COLUMN *p)
1605 {
1606   register int c, chars;
1607   int last_input_position;
1608
1609 #ifdef lint  /* Suppress `used before initialized' warning.  */
1610   chars = 0;
1611 #endif
1612
1613   c = getc (p->fp);
1614
1615   last_input_position = input_position;
1616   switch (c)
1617     {
1618     case '\f':
1619       hold_file (p);
1620       return TRUE;
1621     case EOF:
1622       close_file (p);
1623       return TRUE;
1624     case '\n':
1625       break;
1626     default:
1627       chars = char_to_clump (c);
1628     }
1629
1630   if (truncate_lines && input_position > chars_per_column)
1631     {
1632       input_position = last_input_position;
1633       return FALSE;
1634     }
1635
1636   if (p->char_func != store_char)
1637     {
1638       pad_vertically = TRUE;
1639
1640       if (print_a_header)
1641         print_header ();
1642
1643       if (padding_not_printed != ANYWHERE)
1644         {
1645           pad_across_to (padding_not_printed);
1646           padding_not_printed = ANYWHERE;
1647         }
1648
1649       if (use_column_separator)
1650         print_separators ();
1651     }
1652
1653   if (p->numbered)
1654     number (p);
1655
1656   if (c == '\n')
1657     return TRUE;
1658
1659   print_clump (p, chars, clump_buff);
1660
1661   for (;;)
1662     {
1663       c = getc (p->fp);
1664
1665       switch (c)
1666         {
1667         case '\n':
1668           return TRUE;
1669         case '\f':
1670           hold_file (p);
1671           return TRUE;
1672         case EOF:
1673           close_file (p);
1674           return TRUE;
1675         }
1676
1677       last_input_position = input_position;
1678       chars = char_to_clump (c);
1679       if (truncate_lines && input_position > chars_per_column)
1680         {
1681           input_position = last_input_position;
1682           return FALSE;
1683         }
1684
1685       print_clump (p, chars, clump_buff);
1686     }
1687 }
1688
1689 /* Print a line from buff.
1690
1691    If this function has been called, we know we have something to
1692    print.  Therefore we set pad_vertically to TRUE, print
1693    a header if necessary, pad across if necessary, and print
1694    separators if necessary.
1695
1696    Return TRUE, meaning there is no need to call read_rest_of_line. */
1697
1698 static int
1699 print_stored (COLUMN *p)
1700 {
1701   int line = p->current_line++;
1702   register char *first = &buff[line_vector[line]];
1703   register char *last = &buff[line_vector[line + 1]];
1704
1705   pad_vertically = TRUE;
1706
1707   if (print_a_header)
1708     print_header ();
1709
1710   if (padding_not_printed != ANYWHERE)
1711     {
1712       pad_across_to (padding_not_printed);
1713       padding_not_printed = ANYWHERE;
1714     }
1715
1716   if (use_column_separator)
1717     print_separators ();
1718
1719   while (first != last)
1720     print_char (*first++);
1721
1722   if (spaces_not_printed == 0)
1723     output_position = p->start_position + end_vector[line];
1724
1725   return TRUE;
1726 }
1727
1728 /* Convert a character to the proper format and return the number of
1729    characters in the resulting clump.  Increment input_position by
1730    the width of the clump.
1731
1732    Tabs are converted to clumps of spaces.
1733    Nonprintable characters may be converted to clumps of escape
1734    sequences or control prefixes.
1735
1736    Note: the width of a clump is not necessarily equal to the number of
1737    characters in clump_buff.  (e.g, the width of '\b' is -1, while the
1738    number of characters is 1.) */
1739
1740 static int
1741 char_to_clump (int c)
1742 {
1743   register int *s = clump_buff;
1744   register int i;
1745   char esc_buff[4];
1746   int width;
1747   int chars;
1748
1749   if (c == input_tab_char)
1750     {
1751       width = tab_width (chars_per_input_tab, input_position);
1752
1753       if (untabify_input)
1754         {
1755           for (i = width; i; --i)
1756             *s++ = ' ';
1757           chars = width;
1758         }
1759       else
1760         {
1761           *s = c;
1762           chars = 1;
1763         }
1764
1765     }
1766   else if (!ISPRINT (c))
1767     {
1768       if (use_esc_sequence)
1769         {
1770           width = 4;
1771           chars = 4;
1772           *s++ = '\\';
1773           sprintf (esc_buff, "%03o", c);
1774           for (i = 0; i <= 2; ++i)
1775             *s++ = (int) esc_buff[i];
1776         }
1777       else if (use_cntrl_prefix)
1778         {
1779           if (c < 0200)
1780             {
1781               width = 2;
1782               chars = 2;
1783               *s++ = '^';
1784               *s++ = c ^ 0100;
1785             }
1786           else
1787             {
1788               width = 4;
1789               chars = 4;
1790               *s++ = '\\';
1791               sprintf (esc_buff, "%03o", c);
1792               for (i = 0; i <= 2; ++i)
1793                 *s++ = (int) esc_buff[i];
1794             }
1795         }
1796       else if (c == '\b')
1797         {
1798           width = -1;
1799           chars = 1;
1800           *s = c;
1801         }
1802       else
1803         {
1804           width = 0;
1805           chars = 1;
1806           *s = c;
1807         }
1808     }
1809   else
1810     {
1811       width = 1;
1812       chars = 1;
1813       *s = c;
1814     }
1815
1816   input_position += width;
1817   return chars;
1818 }
1819
1820 /* We've just printed some files and need to clean up things before
1821    looking for more options and printing the next batch of files.
1822
1823    Free everything we've xmalloc'ed, except `header'. */
1824
1825 static void
1826 cleanup (void)
1827 {
1828   if (number_buff)
1829     free (number_buff);
1830   if (clump_buff)
1831     free (clump_buff);
1832   if (column_vector)
1833     free (column_vector);
1834   if (line_vector)
1835     free (line_vector);
1836   if (end_vector)
1837     free (end_vector);
1838   if (buff)
1839     free (buff);
1840 }
1841 \f
1842 /* Complain, print a usage message, and die. */
1843
1844 static void
1845 usage (int status)
1846 {
1847   if (status != 0)
1848     fprintf (stderr, _("Try `%s --help' for more information.\n"),
1849              program_name);
1850   else
1851     {
1852       printf (_("\
1853 Usage: %s [OPTION]... [FILE]...\n\
1854 "),
1855               program_name);
1856       printf (_("\
1857 Paginate or columnate FILE(s) for printing.\n\
1858 \n\
1859   +PAGE             begin printing with page PAGE\n\
1860   -COLUMN           produce COLUMN-column output and print columns down\n\
1861   -F, -f            simulate formfeed with newlines on output\n\
1862   -a                print columns across rather than down\n\
1863   -b                balance columns on the last page\n\
1864   -c                use hat notation (^G) and octal backslash notation\n\
1865   -d                double space the output\n\
1866   -e[CHAR[WIDTH]]   expand input CHARs (TABs) to tab WIDTH (8)\n\
1867   -h HEADER         use HEADER instead of filename in page headers\n\
1868   -i[CHAR[WIDTH]]   replace spaces with CHARs (TABs) to tab WIDTH (8)\n\
1869   -l PAGE_LENGTH    set the page length to PAGE_LENGTH (66) lines\n\
1870   -m                print all files in parallel, one in each column\n\
1871   -n[SEP[DIGITS]]   number lines, use DIGITS (5) digits, then SEP (TAB)\n\
1872   -o MARGIN         offset each line with MARGIN spaces (do not affect -w)\n\
1873   -r                inhibit warning when a file cannot be opened\n\
1874   -s[SEP]           separate columns by character SEP (TAB)\n\
1875   -t                inhibit 5-line page headers and trailers\n\
1876   -v                use octal backslash notation\n\
1877   -w PAGE_WIDTH     set page width to PAGE_WIDTH (72) columns\n\
1878       --help        display this help and exit\n\
1879       --version     output version information and exit\n\
1880 \n\
1881 -t implied by -l N when N < 10.  Without -s, columns are separated by\n\
1882 spaces.  With no FILE, or when FILE is -, read standard input.\n\
1883 "));
1884     }
1885   exit (status);
1886 }