1 /* pr -- convert text files for printing.
2 Copyright (C) 1988, 1991, 1995 Free Software Foundation, Inc.
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)
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.
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. */
18 /* Author: Pete TerMaat. */
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
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.
30 Improve the printing of control prefixes.
35 +PAGE Begin output at page PAGE of the output.
37 -COLUMN Produce output that is COLUMN columns wide and print
40 -a Print columns across rather than down. The input
49 -b Balance columns on the last page.
51 -c Print unprintable characters as control prefixes.
52 Control-g is printed as ^G.
54 -d Double space the output.
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.)
61 -f Use formfeeds instead of newlines to separate pages.
63 -h header Replace the filename in the header with the string HEADER.
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
70 -l lines Set the page length to LINES. Default is 66.
72 -m Print files in parallel.
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.)
80 -o offset Offset each line with a margin OFFSET spaces wide.
81 Total page width is the size of this offset plus the
84 -r Ignore files that can't be opened.
86 -s[c] Separate each line with a character. Optional argument C is
87 the character to be used. Default is `\t'.
89 -t Do not print headers or footers.
91 -v Print unprintable characters as escape sequences.
92 Control-G becomes \007.
94 -w width Set the page width to WIDTH characters. */
101 #include <sys/types.h>
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. */
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
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
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.
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().
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().
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[].
145 lines_stored Number of lines in this column which are stored in
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.
153 start_position The horizontal position we want to be in before we
154 print the first character in this column.
156 numbered True means precede this column with a line number. */
160 FILE *fp; /* Input stream for this column. */
161 char *name; /* File name. */
165 ON_HOLD, /* Hit a form feed. */
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. */
177 typedef struct COLUMN COLUMN;
179 #define NULLCOL (COLUMN *)0
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));
200 /* The name under which this program was invoked. */
203 /* All of the columns to print. */
204 static COLUMN *column_vector;
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]. */
212 /* Index of the position in buff where the next character
214 static int buff_current;
216 /* The number of characters in buff.
217 Used for allocation of buff and to detect overflow of buff. */
218 static int buff_allocated;
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;
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
231 static int *end_vector;
233 /* (-m) True means we're printing multiple files in parallel. */
234 static int parallel_files = FALSE;
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;
240 /* (-t) True means we're printing headers and footers. */
241 static int extremities = TRUE;
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;
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;
251 /* (-f) True means use formfeeds instead of newlines to separate pages. */
252 static int use_form_feed = FALSE;
254 /* True means we have read the standard input. */
255 static int have_read_stdin = FALSE;
257 /* True means the -a flag has been given. */
258 static int print_across_flag = FALSE;
260 /* True means we're printing one file in multiple (>1) downward columns. */
261 static int storing_columns = TRUE;
263 /* (-b) True means balance columns on the last page as Sys V does. */
264 static int balance_columns = FALSE;
266 /* (-l) Number of lines on a page, including header and footer lines. */
267 static int lines_per_page = 66;
269 /* Number of lines in the header and footer can be reset to 0 using
271 static int lines_per_header = 5;
272 static int lines_per_body;
273 static int lines_per_footer = 5;
275 /* (-w) Width in characters of the page. Does not include the width of
277 static int chars_per_line = 72;
279 /* Number of characters in a column. Based on the gutter and page widths. */
280 static int chars_per_column;
282 /* (-e) True means convert tabs to spaces on input. */
283 static int untabify_input = FALSE;
285 /* (-e) The input tab character. */
286 static char input_tab_char = '\t';
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;
292 /* (-i) True means convert spaces to tabs on output. */
293 static int tabify_output = FALSE;
295 /* (-i) The output tab character. */
296 static char output_tab_char = '\t';
298 /* (-i) The width of the output tab. */
299 static int chars_per_output_tab = 8;
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;
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;
311 /* (-o) Number of spaces in the left margin (tabs used when possible). */
312 static int chars_per_margin = 0;
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;
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;
326 /* Count number of failed opens so we can exit with nonzero
327 status if there were any. */
328 static int failed_opens = 0;
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_
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_
338 /* (-NNN) Number of columns of text to print. */
339 static int columns = 1;
341 /* (+NNN) Page number on which to begin printing. */
342 static int first_page_number = 1;
344 /* Number of files open (not closed, not on hold). */
345 static int files_ready_to_read = 0;
347 /* Current page number. Displayed in header. */
348 static int page_number;
350 /* Current line number. Displayed when -n flag is specified.
352 When printing files in parallel (-m flag), line numbering is as follows:
356 When printing files across (-a flag), ...
360 Otherwise, line numbering is as follows:
363 static int line_number;
365 /* (-n) True means lines should be preceded by numbers. */
366 static int numbered_lines = FALSE;
368 /* (-n) Character which follows each line number. */
369 static char number_separator = '\t';
371 /* (-n) Width in characters of a line number. */
372 static int chars_per_number = 5;
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;
379 /* Buffer sprintf uses to format a line number. */
380 static char *number_buff;
382 /* (-v) True means unprintable characters are printed as escape sequences.
383 control-g becomes \007. */
384 static int use_esc_sequence = FALSE;
386 /* (-c) True means unprintable characters are printed as control prefixes.
387 control-g becomes ^G. */
388 static int use_cntrl_prefix = FALSE;
390 /* (-d) True means output is double spaced. */
391 static int double_space = FALSE;
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;
397 /* (-r) True means don't complain if we can't open a file. */
398 static int ignore_failed_opens = FALSE;
400 /* (-s) True means we separate columns with a specified character. */
401 static int use_column_separator = FALSE;
403 /* Character used to separate columns if the the -s flag has been specified. */
404 static char column_separator = '\t';
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;
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;
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;
418 /* (-h) String of characters used in place of the filename in the header. */
419 static char *custom_header;
421 /* String containing the date, filename or custom header, and "Page ". */
424 static int *clump_buff;
426 /* True means we truncate lines longer than chars_per_column. */
427 static int truncate_lines = FALSE;
429 /* If nonzero, display usage information and exit. */
430 static int show_help;
432 /* If nonzero, print the version on standard output then exit. */
433 static int show_version;
435 static struct option const long_options[] =
437 {"help", no_argument, &show_help, 1},
438 {"version", no_argument, &show_version, 1},
442 /* Return the number of columns that have either an open file or
446 cols_ready_to_print (void)
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))
461 main (int argc, char **argv)
468 program_name = argv[0];
469 setlocale (LC_ALL, "");
470 bindtextdomain (PACKAGE, LOCALEDIR);
471 textdomain (PACKAGE);
474 file_names = (argc > 1
475 ? (char **) xmalloc ((argc - 1) * sizeof (char *))
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. */
492 error (0, 0, _("`+' requires a numeric argument"));
495 /* FIXME: use strtol */
496 first_page_number = atoi (s);
500 file_names[n_files++] = optarg;
507 accum = accum * 10 + c - '0';
515 explicit_columns = TRUE;
529 case 0: /* getopt long option */
533 print_across_flag = TRUE;
534 storing_columns = FALSE;
537 balance_columns = TRUE;
540 use_cntrl_prefix = TRUE;
547 getoptarg (optarg, 'e', &input_tab_char,
548 &chars_per_input_tab);
549 /* Could check tab width > 0. */
550 untabify_input = TRUE;
554 use_form_feed = TRUE;
557 custom_header = optarg;
558 standard_header = FALSE;
562 getoptarg (optarg, 'i', &output_tab_char,
563 &chars_per_output_tab);
564 /* Could check tab width > 0. */
565 tabify_output = TRUE;
568 lines_per_page = atoi (optarg);
571 parallel_files = TRUE;
572 storing_columns = FALSE;
575 numbered_lines = TRUE;
577 getoptarg (optarg, 'n', &number_separator,
581 chars_per_margin = atoi (optarg);
584 ignore_failed_opens = TRUE;
587 use_column_separator = TRUE;
592 column_separator = *s;
595 fprintf (stderr, _("\
596 %s: extra characters in the argument to the `-s' option: `%s'\n"),
606 use_esc_sequence = TRUE;
609 chars_per_line = atoi (optarg);
619 printf ("pr - %s\n", PACKAGE_VERSION);
626 if (parallel_files && explicit_columns)
628 _("Cannot specify number of columns when printing in parallel."));
630 if (parallel_files && print_across_flag)
632 _("Cannot specify both printing across and printing in parallel."));
634 for ( ; optind < argc; optind++)
636 file_names[n_files++] = argv[optind];
641 /* No file arguments specified; read from standard input. */
642 print_files (0, (char **) 0);
647 print_files (n_files, file_names);
651 for (i=0; i<n_files; i++)
652 print_files (1, &file_names[i]);
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)
667 /* Parse options of the form -scNNN.
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
674 getoptarg (char *arg, char switch_char, char *character, int *number)
681 *number = atoi (arg);
684 fprintf (stderr, _("\
685 %s: extra characters in the argument to the `-%c' option: `%s'\n"),
686 program_name, switch_char, arg);
692 /* Set parameters related to formatting. */
695 init_parameters (int number_of_files)
697 int chars_used_by_number = 0;
699 lines_per_body = lines_per_page - lines_per_header - lines_per_footer;
700 if (lines_per_body <= 0)
702 if (extremities == FALSE)
703 lines_per_body = lines_per_page;
706 lines_per_body = lines_per_body / 2;
708 /* If input is stdin, cannot print parallel files. BSD dumps core
710 if (number_of_files == 0)
711 parallel_files = FALSE;
714 columns = number_of_files;
716 /* Tabification is assumed for multiple columns. */
719 if (!use_column_separator)
720 truncate_lines = TRUE;
722 untabify_input = TRUE;
723 tabify_output = TRUE;
726 storing_columns = FALSE;
730 if (number_separator == input_tab_char)
732 number_width = chars_per_number +
733 tab_width (chars_per_input_tab,
734 (chars_per_margin + chars_per_number));
737 number_width = chars_per_number + 1;
738 /* The number is part of the column width unless we are
739 printing files in parallel. */
741 chars_used_by_number = number_width;
744 chars_per_column = (chars_per_line - chars_used_by_number -
745 (columns - 1) * chars_per_gutter) / columns;
747 if (chars_per_column < 1)
748 error (1, 0, _("page width too narrow"));
752 if (number_buff != (char *) 0)
754 number_buff = (char *)
755 xmalloc (2 * chars_per_number * sizeof (char));
758 /* Pick the maximum between the tab width and the width of an
760 if (clump_buff != (int *) 0)
762 clump_buff = (int *) xmalloc ((chars_per_input_tab > 4
763 ? chars_per_input_tab : 4) * sizeof (int));
766 /* Open the necessary files,
767 maintaining a COLUMN structure for each column.
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,
775 init_fps (int number_of_files, char **av)
784 if (column_vector != NULLCOL)
785 free ((char *) column_vector);
786 column_vector = (COLUMN *) xmalloc (columns * sizeof (COLUMN));
790 files_left = number_of_files;
791 for (p = column_vector; files_left--; ++p, ++av)
793 if (open_file (*av, p) == 0)
801 init_header ("", -1);
806 if (number_of_files > 0)
808 if (open_file (*av, p) == 0)
810 init_header (*av, fileno (p->fp));
814 p->name = _("standard input");
816 have_read_stdin = TRUE;
819 init_header ("", -1);
824 for (i = columns - 1, ++p; i; --i, ++p)
831 files_ready_to_read = total_files;
835 /* Determine print_func and char_func, the functions
836 used by each column for printing and/or storing.
838 Determine the horizontal position desired when we begin
839 printing a column (p->start_position). */
847 h = chars_per_margin;
849 if (use_column_separator)
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;
859 h_next = h + chars_per_column;
862 /* This loop takes care of all but the rightmost column. */
864 for (p = column_vector, i = 1; i < columns; ++p, ++i)
866 if (storing_columns) /* One file, multi columns down. */
868 p->char_func = store_char;
869 p->print_func = print_stored;
872 /* One file, multi columns across; or parallel files. */
874 p->char_func = print_char;
875 p->print_func = read_line;
878 /* Number only the first column when printing files in
880 p->numbered = numbered_lines && (!parallel_files || i == 1);
881 p->start_position = h;
883 /* If we're using separators, all start_positions are
884 ANYWHERE, except the first column's start_position when
887 if (use_column_separator)
894 h = h_next + chars_per_gutter;
895 h_next = h + chars_per_column;
899 /* The rightmost column.
901 Doesn't need to be stored unless we intend to balance
902 columns on the last page. */
903 if (storing_columns && balance_columns)
905 p->char_func = store_char;
906 p->print_func = print_stored;
910 p->char_func = print_char;
911 p->print_func = read_line;
914 p->numbered = numbered_lines && (!parallel_files || i == 1);
915 p->start_position = h;
918 /* Open a file. Return nonzero if successful, zero if failed. */
921 open_file (char *name, COLUMN *p)
923 if (!strcmp (name, "-"))
925 p->name = _("standard input");
932 p->fp = fopen (name, "r");
937 if (!ignore_failed_opens)
938 error (0, errno, "%s", name);
946 /* Close the file in P.
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. */
952 close_file (COLUMN *p)
957 if (p->status == CLOSED)
960 error (1, errno, "%s", p->name);
961 if (p->fp != stdin && fclose (p->fp) == EOF)
962 error (1, errno, "%s", p->name);
966 for (q = column_vector, i = columns; i; ++q, --i)
969 if (q->lines_stored == 0)
971 q->lines_to_print = 0;
978 p->lines_to_print = 0;
981 --files_ready_to_read;
984 /* Put a file on hold until we start a new page,
985 since we've hit a form feed.
987 If we aren't dealing with parallel files, we must change the
988 status of all columns in the column list. */
991 hold_file (COLUMN *p)
997 for (q = column_vector, i = columns; i; ++q, --i)
1000 p->status = ON_HOLD;
1001 p->lines_to_print = 0;
1002 --files_ready_to_read;
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. */
1014 for (p = column_vector; i; --i, ++p)
1015 if (p->status == ON_HOLD)
1018 files_ready_to_read++;
1022 /* Print a single file, or multiple files in parallel.
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
1029 Print the file(s). */
1032 print_files (int number_of_files, char **av)
1034 init_parameters (number_of_files);
1035 if (init_fps (number_of_files, av))
1037 if (storing_columns)
1040 if (first_page_number > 1)
1042 if (!skip_to_page (first_page_number))
1045 page_number = first_page_number;
1053 while (print_page ())
1057 /* Generous estimate of number of characters taken up by "Jun 7 00:08 " and
1059 #define CHARS_FOR_DATE_AND_PAGE 50
1061 /* Initialize header information.
1062 If DESC is non-negative, it is a file descriptor open to
1063 FILENAME for reading.
1065 Allocate space for a header string,
1066 Determine the time, insert file name or user-specified string.
1068 It might be nice to have a "blank headers" option, since
1069 pr -h "" still prints the date and page number. */
1072 init_header (char *filename, int desc)
1074 int chars_per_header;
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);
1087 t[16] = '\0'; /* Mark end of month and time string. */
1088 t[24] = '\0'; /* Mark end of year string. */
1090 middle = standard_header ? f : custom_header;
1092 chars_per_header = strlen (middle) + CHARS_FOR_DATE_AND_PAGE + 1;
1093 if (header != (char *) 0)
1095 header = (char *) xmalloc (chars_per_header * sizeof (char));
1097 sprintf (header, _("%s %s %s Page"), &t[4], &t[20], middle);
1100 /* Set things up for printing a page
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 */
1116 if (storing_columns)
1119 for (j = columns - 1, p = column_vector; j; --j, ++p)
1121 p->lines_to_print = p->lines_stored;
1125 if (balance_columns)
1127 p->lines_to_print = p->lines_stored;
1129 /* Since we're not balancing columns, we don't need to store
1130 the rightmost column. Read it straight from the file. */
1133 if (p->status == OPEN)
1135 p->lines_to_print = lines_per_body;
1138 p->lines_to_print = 0;
1142 for (j = columns, p = column_vector; j; --j, ++p)
1143 if (p->status == OPEN)
1145 p->lines_to_print = lines_per_body;
1148 p->lines_to_print = 0;
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
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. */
1166 int lines_left_on_page;
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. */
1180 if (cols_ready_to_print () == 0)
1184 print_a_header = TRUE;
1186 /* Don't pad unless we know a page was printed. */
1187 pad_vertically = FALSE;
1190 lines_left_on_page = lines_per_body;
1192 lines_left_on_page *= 2;
1194 while (lines_left_on_page > 0 && cols_ready_to_print () > 0)
1196 output_position = 0;
1197 spaces_not_printed = 0;
1198 separators_not_printed = 0;
1199 pad_vertically = FALSE;
1201 for (j = 1, p = column_vector; j <= columns; ++j, ++p)
1204 if (p->lines_to_print > 0)
1206 padding_not_printed = p->start_position;
1208 if (!(p->print_func) (p))
1209 read_rest_of_line (p);
1210 pv |= pad_vertically;
1212 if (use_column_separator)
1213 ++separators_not_printed;
1215 --p->lines_to_print;
1216 if (p->lines_to_print <= 0)
1218 if (cols_ready_to_print () <= 0)
1227 --lines_left_on_page;
1230 if (double_space && pv && extremities)
1233 --lines_left_on_page;
1237 pad_vertically = pv;
1239 if (pad_vertically && extremities)
1240 pad_down (lines_left_on_page + lines_per_footer);
1242 reset_status (); /* Change ON_HOLD to OPEN. */
1244 return TRUE; /* More pages to go. */
1247 /* Allocate space for storing columns.
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
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. */
1260 init_store_cols (void)
1262 int total_lines = lines_per_body * columns;
1263 int chars_if_truncate = total_lines * (chars_per_column + 1);
1265 if (line_vector != (int *) 0)
1266 free ((int *) line_vector);
1267 line_vector = (int *) xmalloc ((total_lines + 1) * sizeof (int *));
1269 if (end_vector != (int *) 0)
1270 free ((int *) end_vector);
1271 end_vector = (int *) xmalloc (total_lines * sizeof (int *));
1273 if (buff != (char *) 0)
1275 buff_allocated = use_column_separator ? 2 * chars_if_truncate
1276 : chars_if_truncate; /* Tune this. */
1277 buff = (char *) xmalloc (buff_allocated * sizeof (char));
1280 /* Store all but the rightmost column.
1281 (Used when printing a single file in multiple downward columns)
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
1293 store_columns (void)
1298 int last_col; /* The rightmost column which will be saved in buff */
1304 if (balance_columns)
1307 last_col = columns - 1;
1309 for (i = 1, p = column_vector; i <= last_col; ++i, ++p)
1310 p->lines_stored = 0;
1312 for (i = 1, p = column_vector; i <= last_col && files_ready_to_read;
1315 p->current_line = line;
1316 for (j = lines_per_body; j && files_ready_to_read; --j)
1318 if (p->status == OPEN) /* Redundant. Clean up. */
1323 read_rest_of_line (p);
1325 if (p->status == OPEN
1326 || buff_start != buff_current)
1329 line_vector[line] = buff_start;
1330 end_vector[line++] = input_position;
1331 buff_start = buff_current;
1336 /* Keep track of the location of the last char in buff. */
1337 line_vector[line] = buff_start;
1339 if (balance_columns && p->lines_stored != lines_per_body)
1344 balance (int total_stored)
1350 for (i = 1, p = column_vector; i <= columns; ++i, ++p)
1352 lines = total_stored / columns;
1353 if (i <= total_stored % columns)
1356 p->lines_stored = lines;
1357 p->current_line = first_line;
1359 first_line += lines;
1363 /* Store a character in the buffer. */
1368 if (buff_current >= buff_allocated)
1370 /* May be too generous. */
1371 buff_allocated = 2 * buff_allocated;
1372 buff = (char *) xrealloc (buff, buff_allocated * sizeof (char));
1374 buff[buff_current++] = (char) c;
1383 sprintf (number_buff, "%*d", chars_per_number, line_number++);
1385 for (i = chars_per_number; i > 0; i--)
1386 (p->char_func) ((int) *s++);
1388 if (number_separator == input_tab_char)
1390 i = number_width - chars_per_number;
1392 (p->char_func) ((int) ' ');
1395 (p->char_func) ((int) number_separator);
1397 if (truncate_lines && !parallel_files)
1398 input_position += number_width;
1401 /* Print (or store) padding until the current horizontal position
1405 pad_across_to (int position)
1407 register int h = output_position;
1410 spaces_not_printed = position - output_position;
1413 while (++h <= position)
1415 output_position = position;
1419 /* Pad to the bottom of the page.
1421 If the user has requested a formfeed, use one.
1422 Otherwise, use newlines. */
1425 pad_down (int lines)
1432 for (i = lines; i; --i)
1436 /* Read the rest of the line.
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. */
1443 read_rest_of_line (COLUMN *p)
1448 while ((c = getc (f)) != '\n')
1463 /* If we're tabifying output,
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. */
1470 print_white_space (void)
1473 register int h_old = output_position;
1474 register int goal = h_old + spaces_not_printed;
1476 while (goal - h_old > 1
1477 && (h_new = pos_after_tab (chars_per_output_tab, h_old)) <= goal)
1479 putchar (output_tab_char);
1482 while (++h_old <= goal)
1485 output_position = goal;
1486 spaces_not_printed = 0;
1489 /* Print column separators.
1491 We keep a count until we know that we'll be printing a line,
1492 then print_separators() is called. */
1495 print_separators (void)
1497 for (; separators_not_printed > 0; --separators_not_printed)
1498 print_char (column_separator);
1501 /* Print (or store, depending on p->char_func) a clump of N
1505 print_clump (COLUMN *p, int n, int *clump)
1508 (p->char_func) (*clump++);
1511 /* Print a character.
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. */
1525 ++spaces_not_printed;
1528 else if (spaces_not_printed > 0)
1529 print_white_space ();
1531 /* Nonprintables are assumed to have width 0, except '\b'. */
1543 /* Skip to page PAGE before printing. */
1546 skip_to_page (int page)
1551 for (n = 1; n < page; ++n)
1553 for (i = 1; i <= lines_per_body; ++i)
1555 for (j = 1, p = column_vector; j <= columns; ++j, ++p)
1556 read_rest_of_line (p);
1560 return files_ready_to_read > 0;
1565 Formfeeds are assumed to use up two lines at the beginning of
1572 fprintf (stdout, "\n\n");
1574 output_position = 0;
1575 pad_across_to (chars_per_margin);
1576 print_white_space ();
1578 fprintf (stdout, "%s %d\n\n\n", header, page_number++);
1580 print_a_header = FALSE;
1581 output_position = 0;
1584 /* Print (or store, if p->char_func is store_char()) a line.
1586 Read a character to determine whether we have a line or not.
1587 (We may hit EOF, \n, or \f)
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.
1597 Print the clump which corresponds to the first character.
1599 Enter a loop and keep printing until an end of line condition
1600 exists, or until we exceed chars_per_column.
1602 Return FALSE if we exceed chars_per_column before reading
1603 an end of line character, TRUE otherwise. */
1606 read_line (COLUMN *p)
1608 register int c, chars;
1609 int last_input_position;
1611 #ifdef lint /* Suppress `used before initialized' warning. */
1617 last_input_position = input_position;
1629 chars = char_to_clump (c);
1632 if (truncate_lines && input_position > chars_per_column)
1634 input_position = last_input_position;
1638 if (p->char_func != store_char)
1640 pad_vertically = TRUE;
1645 if (padding_not_printed != ANYWHERE)
1647 pad_across_to (padding_not_printed);
1648 padding_not_printed = ANYWHERE;
1651 if (use_column_separator)
1652 print_separators ();
1661 print_clump (p, chars, clump_buff);
1679 last_input_position = input_position;
1680 chars = char_to_clump (c);
1681 if (truncate_lines && input_position > chars_per_column)
1683 input_position = last_input_position;
1687 print_clump (p, chars, clump_buff);
1691 /* Print a line from buff.
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.
1698 Return TRUE, meaning there is no need to call read_rest_of_line. */
1701 print_stored (COLUMN *p)
1703 int line = p->current_line++;
1704 register char *first = &buff[line_vector[line]];
1705 register char *last = &buff[line_vector[line + 1]];
1707 pad_vertically = TRUE;
1712 if (padding_not_printed != ANYWHERE)
1714 pad_across_to (padding_not_printed);
1715 padding_not_printed = ANYWHERE;
1718 if (use_column_separator)
1719 print_separators ();
1721 while (first != last)
1722 print_char (*first++);
1724 if (spaces_not_printed == 0)
1725 output_position = p->start_position + end_vector[line];
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.
1734 Tabs are converted to clumps of spaces.
1735 Nonprintable characters may be converted to clumps of escape
1736 sequences or control prefixes.
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.) */
1743 char_to_clump (int c)
1745 register int *s = clump_buff;
1751 if (c == input_tab_char)
1753 width = tab_width (chars_per_input_tab, input_position);
1757 for (i = width; i; --i)
1768 else if (!ISPRINT (c))
1770 if (use_esc_sequence)
1775 sprintf (esc_buff, "%03o", c);
1776 for (i = 0; i <= 2; ++i)
1777 *s++ = (int) esc_buff[i];
1779 else if (use_cntrl_prefix)
1793 sprintf (esc_buff, "%03o", c);
1794 for (i = 0; i <= 2; ++i)
1795 *s++ = (int) esc_buff[i];
1818 input_position += width;
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.
1825 Free everything we've xmalloc'ed, except `header'. */
1835 free (column_vector);
1844 /* Complain, print a usage message, and die. */
1850 fprintf (stderr, _("Try `%s --help' for more information.\n"),
1855 Usage: %s [OPTION]... [FILE]...\n\
1859 Paginate or columnate FILE(s) for printing.\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\
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\