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