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