1 /* pr -- convert text files for printing.
2 Copyright (C) 88, 91, 95, 96, 1997 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 Foundation,
16 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 +FIRST_PAGE[:LAST_PAGE]
36 begin [stop] printing with page FIRST_[LAST_]PAGE
38 -COLUMN Produce output that is COLUMN columns wide and print
40 Balance columns on the last page is automatically set.
42 -a Print columns across rather than down. The input
51 -b Balance columns on the last page.
52 -b is no longer an independent option. It's always used
53 together with -COLUMN (unless -a is used) to get a
54 consistent formulation with "FF set by hand" in input
55 files. Each formfeed found terminates the number of lines
56 to be read with the actual page. The situation for
57 printing columns down is equivalent to that on the last
58 page. So we need a balancing.
60 We do not yet eliminate source text dealing with -COLUMN
61 only. Tune this if it proved to be a satisfactory
64 Keeping -b as an underground option guarantees some
65 downward compatibility. Utilities using pr with -b
66 (a most frequently used form) still work as usual.
68 -c Print unprintable characters as control prefixes.
69 Control-g is printed as ^G.
71 -d Double space the output.
73 -e[c[k]] Expand tabs to spaces on input. Optional argument C
74 is the input tab character. (Default is `\t'.) Optional
75 argument K is the input tab character's width. (Default is 8.)
78 -f Use formfeeds instead of newlines to separate pages.
79 A three line HEADER is used, no TRAILER (without -f
80 both HEADER and TRAILER are made of five lines).
82 -h HEADER Replace the filename in the header with the string HEADER.
83 Checking and left-hand-side truncation of the length of the
84 standard and custom header string. A centered header is used.
85 The format of date and time has been shortened
86 to yy-mm-dd HH:MM to give place to a maximal filename
88 -h "" now prints a blank line header. -h"" shows an error.
90 -i[c[k]] Replace spaces with tabs on output. Optional argument
91 C is the output tab character. (Default is `\t'.) Optional
92 argument K is the output tab character's width. (Default
95 -j Merge full lines, turns off -w line truncation, no column
96 alignment, -s[STRING] sets separators, works with all
97 column options (-COLUMN | -a -COLUMN | -m).
99 -l lines Set the page length to LINES. Default is 66.
101 -m Print files in parallel; pad_across_to align columns;
102 truncate lines and print separator strings;
103 Do it also with empty columns to get a continuous line
104 numbering and column marking by separators throughout
105 the whole merged file.
107 Empty pages in some input files produce empty columns
108 [marked by separators] in the common pages. Completely
109 empty common pages show no column separators at all.
111 The layout of a merged page is ruled by the largest form
112 feed distance of the single pages at that page. Shorter
113 columns will be filled up with empty lines.
115 Together with -j option join lines of full length and
116 in addition set separators when -s option is used.
118 -n[c[k]] Precede each column with a line number.
119 (With parallel files, precede each line with a line
120 number.) Optional argument C is the character to print
121 after each number. (Default `\t'.) Optional argument
122 k is the number of digits per line number. (Default 5.)
123 Default counting starts with 1st line of input file.
125 -N number Start counting with number at 1st line of first page
128 -o offset Offset each line with a margin OFFSET spaces wide.
129 Total page width is the size of this offset plus the
132 -r Ignore files that can't be opened.
134 -s[STRING] Separate columns by any string STRING.
135 Don't use -s "STRING".
136 without -s: Default separator `TAB' with -j and `space'
137 otherwise (same as -s\" \"),
138 with -s only: no separator is used, same as -s"".
139 Quotes should be used with blanks and some shell active
142 -t Do not print headers or footers but retain form feeds
143 set in input files (some page layout is not changed).
145 -T Do not print headers or footers, eliminate form feeds
148 -v Print unprintable characters as escape sequences.
149 Control-G becomes \007.
151 -w width Set the page width to WIDTH characters.
152 (In pr versions newer than 1.14 -s option does no longer
155 With/without -w width the header line is truncated.
156 Default is 72 characters.
157 With -w width text lines will be truncated, unless -j is
158 used. Together with one of the column options
159 (-COLUMN| -a -COLUMN| -m) column alignment is used.
160 Without -w PAGE_WIDTH
161 - but with one of the column options default truncation of
162 72 characters is used (to keep downward compatibility
163 and to simplify most frequently met column tasks).
164 Column alignment and column separators are used.
165 - and without any of the column options no line truncation
166 is used (to keep downward compatibility and to meet most
167 frequent tasks). That's equivalent to -w 72 -j .
175 #include <sys/types.h>
186 # define UINT_MAX ((unsigned int) ~(unsigned int) 0)
190 # define INT_MAX ((int) (UINT_MAX >> 1))
198 /* Used with start_position in the struct COLUMN described below.
199 If start_position == ANYWHERE, we aren't truncating columns and
200 can begin printing a column anywhere. Otherwise we must pad to
201 the horizontal position start_position. */
204 /* Each column has one of these structures allocated for it.
205 If we're only dealing with one file, fp is the same for all
208 The general strategy is to spend time setting up these column
209 structures (storing columns if necessary), after which printing
210 is a matter of flitting from column to column and calling
213 Parallel files, single files printing across in multiple
214 columns, and single files printing down in multiple columns all
215 fit the same printing loop.
217 print_func Function used to print lines in this column.
218 If we're storing this column it will be
219 print_stored(), Otherwise it will be read_line().
221 char_func Function used to process characters in this column.
222 If we're storing this column it will be store_char(),
223 otherwise it will be print_char().
225 current_line Index of the current entry in line_vector, which
226 contains the index of the first character of the
227 current line in buff[].
229 lines_stored Number of lines in this column which are stored in
232 lines_to_print If we're storing this column, lines_to_print is
233 the number of stored_lines which remain to be
234 printed. Otherwise it is the number of lines
235 we can print without exceeding lines_per_body.
237 start_position The horizontal position we want to be in before we
238 print the first character in this column.
240 numbered True means precede this column with a line number. */
244 FILE *fp; /* Input stream for this column. */
245 char *name; /* File name. */
249 FF_FOUND, /* used with -b option, set with \f, changed
250 to ON_HOLD after print_header */
251 ON_HOLD, /* Hit a form feed. */
254 status; /* Status of the file pointer. */
255 int (*print_func) (); /* Func to print lines in this col. */
256 void (*char_func) (); /* Func to print/store chars in this col. */
257 int current_line; /* Index of current place in line_vector. */
258 int lines_stored; /* Number of lines stored in buff. */
259 int lines_to_print; /* No. lines stored or space left on page. */
260 int start_position; /* Horizontal position of first char. */
262 int full_page_printed; /* True means printed without a FF found. */
264 /* p->full_page_printed controls a special case of "FF set by hand":
265 True means a full page has been printed without FF found. To avoid an
266 additional empty page we have to ignore a FF immediately following in
270 typedef struct COLUMN COLUMN;
272 #define NULLCOL (COLUMN *)0
274 static int char_to_clump __P ((int c));
275 static int read_line __P ((COLUMN *p));
276 static int print_page __P ((void));
277 static int print_stored __P ((COLUMN *p));
278 static int open_file __P ((char *name, COLUMN *p));
279 static int skip_to_page __P ((int page));
280 static void print_header __P ((void));
281 static void pad_across_to __P ((int position));
282 static void add_line_number __P ((COLUMN *p));
283 static void getoptarg __P ((char *arg, char switch_char, char *character,
285 static void usage __P ((int status));
286 static void print_files __P ((int number_of_files, char **av));
287 static void init_parameters __P ((int number_of_files));
288 static void init_header __P ((char *filename, int desc));
289 static void init_store_cols __P ((void));
290 static void store_columns __P ((void));
291 static void balance __P ((int total_stored));
292 static void store_char __P ((int c));
293 static void pad_down __P ((int lines));
294 static void read_rest_of_line __P ((COLUMN *p));
295 static void skip_read __P ((COLUMN *p, int column_number));
296 static void print_char __P ((int c));
297 static void cleanup __P ((void));
298 static void first_last_page __P ((char *pages));
299 static void print_sep_string __P ((void));
300 static void separator_string __P ((const char *optarg_S));
302 /* The name under which this program was invoked. */
305 /* All of the columns to print. */
306 static COLUMN *column_vector;
308 /* When printing a single file in multiple downward columns,
309 we store the leftmost columns contiguously in buff.
310 To print a line from buff, get the index of the first character
311 from line_vector[i], and print up to line_vector[i + 1]. */
314 /* Index of the position in buff where the next character
316 static int buff_current;
318 /* The number of characters in buff.
319 Used for allocation of buff and to detect overflow of buff. */
320 static int buff_allocated;
322 /* Array of indices into buff.
323 Each entry is an index of the first character of a line.
324 This is used when storing lines to facilitate shuffling when
325 we do column balancing on the last page. */
326 static int *line_vector;
328 /* Array of horizonal positions.
329 For each line in line_vector, end_vector[line] is the horizontal
330 position we are in after printing that line. We keep track of this
331 so that we know how much we need to pad to prepare for the next
333 static int *end_vector;
335 /* (-m) True means we're printing multiple files in parallel. */
336 static int parallel_files = FALSE;
338 /* (-m) True means a line starts with some empty columns (some files
339 already CLOSED or ON_HOLD) which we have to align. */
340 static int align_empty_cols;
342 /* (-m) True means we have not yet found any printable column in a line.
343 align_empty_cols = TRUE has to be maintained. */
344 static int empty_line;
346 /* (-m) False means printable column output precedes a form feed found.
347 Column align is done only once. No additional action with that form
349 True means we found only a form feed in a column. Maybe we have to do
350 some column align with that form feed. */
353 /* (-[0-9]+) True means we're given an option explicitly specifying
354 number of columns. Used to detect when this option is used with -m. */
355 static int explicit_columns = FALSE;
357 /* (-t|-T) False means we aren't printing headers and footers. */
358 static int extremities = TRUE;
360 /* (-t) True means we retain all FF set by hand in input files.
361 False is set with -T option. */
362 static int keep_FF = FALSE;
363 static int print_a_FF = FALSE;
365 /* True means we need to print a header as soon as we know we've got input
366 to print after it. */
367 static int print_a_header;
369 /* (-h) True means we're using the standard header rather than a
370 customized one specified by the -h flag. */
371 static int standard_header = TRUE;
373 /* (-f) True means use formfeeds instead of newlines to separate pages. */
374 static int use_form_feed = FALSE;
376 /* True means we have read the standard input. */
377 static int have_read_stdin = FALSE;
379 /* True means the -a flag has been given. */
380 static int print_across_flag = FALSE;
382 /* True means we're printing one file in multiple (>1) downward columns. */
383 static int storing_columns = TRUE;
385 /* (-b) True means balance columns on the last page as Sys V does. */
386 /* That's no longer an independent option. With storing_columns = TRUE
387 balance_columns = TRUE is used too (s. function init_parameters).
388 We get a consistent formulation with "FF set by hand" in input files. */
389 static int balance_columns = FALSE;
391 /* (-l) Number of lines on a page, including header and footer lines. */
392 static int lines_per_page = 66;
394 /* Number of lines in the header and footer can be reset to 0 using
396 static int lines_per_header = 5;
397 static int lines_per_body;
398 static int lines_per_footer = 5;
400 /* (-w) Width in characters of the page. Does not include the width of
402 static int chars_per_line = 72;
404 /* (-w) True means we truncate lines longer than chars_per_column. */
405 static int truncate_lines = FALSE;
407 /* (-j) True means we join lines without any line truncation. -j
408 dominates -w option. */
409 static int join_lines = FALSE;
411 /* Number of characters in a column. Based on col_sep_length and
413 static int chars_per_column;
415 /* (-e) True means convert tabs to spaces on input. */
416 static int untabify_input = FALSE;
418 /* (-e) The input tab character. */
419 static char input_tab_char = '\t';
421 /* (-e) Tabstops are at chars_per_tab, 2*chars_per_tab, 3*chars_per_tab, ...
422 where the leftmost column is 1. */
423 static int chars_per_input_tab = 8;
425 /* (-i) True means convert spaces to tabs on output. */
426 static int tabify_output = FALSE;
428 /* (-i) The output tab character. */
429 static char output_tab_char = '\t';
431 /* (-i) The width of the output tab. */
432 static int chars_per_output_tab = 8;
434 /* Keeps track of pending white space. When we hit a nonspace
435 character after some whitespace, we print whitespace, tabbing
436 if necessary to get to output_position + spaces_not_printed. */
437 static int spaces_not_printed;
439 /* (-o) Number of spaces in the left margin (tabs used when possible). */
440 static int chars_per_margin = 0;
442 /* Position where the next character will fall.
443 Leftmost position is 0 + chars_per_margin.
444 Rightmost position is chars_per_margin + chars_per_line - 1.
445 This is important for converting spaces to tabs on output. */
446 static int output_position;
448 /* Horizontal position relative to the current file.
449 (output_position depends on where we are on the page;
450 input_position depends on where we are in the file.)
451 Important for converting tabs to spaces on input. */
452 static int input_position;
454 /* Count number of failed opens so we can exit with nonzero
455 status if there were any. */
456 static int failed_opens = 0;
458 /* The number of spaces taken up if we print a tab character with width
459 c_ from position h_. */
460 #define TAB_WIDTH(c_, h_) ((c_) - ((h_) % (c_)))
462 /* The horizontal position we'll be at after printing a tab character
463 of width c_ from the position h_. */
464 #define POS_AFTER_TAB(c_, h_) ((h_) + TAB_WIDTH (c_, h_))
466 /* (-NNN) Number of columns of text to print. */
467 static int columns = 1;
469 /* (+NNN:MMM) Page numbers on which to begin and stop printing. */
470 static int first_page_number = 1;
471 static int last_page_number = 0;
473 /* Number of files open (not closed, not on hold). */
474 static int files_ready_to_read = 0;
476 /* Current page number. Displayed in header. */
477 static int page_number;
479 /* Current line number. Displayed when -n flag is specified.
481 When printing files in parallel (-m flag), line numbering is as follows:
485 When printing files across (-a flag), ...
489 Otherwise, line numbering is as follows:
492 static int line_number;
494 /* (-n) True means lines should be preceded by numbers. */
495 static int numbered_lines = FALSE;
497 /* (-n) Character which follows each line number. */
498 static char number_separator = '\t';
500 /* (-n) line counting starts with 1st line of input file (not with 1st
501 line of 1st page printed). */
502 static int line_count = 1;
504 /* (-n) True means counting of skipped lines starts with 1st line of
505 input file. False means -N option is used in addition, counting of
506 skipped lines not required. */
507 static int skip_count = TRUE;
509 /* (-N) Counting starts with start_line_number = NUMBER at 1st line of
510 first page printed, usually not 1st page of input file. */
511 static int start_line_num = 1;
513 /* (-n) Width in characters of a line number. */
514 static int chars_per_number = 5;
516 /* Used when widening the first column to accommodate numbers -- only
517 needed when printing files in parallel. Includes width of both the
518 number and the number_separator. */
519 static int number_width;
521 /* Buffer sprintf uses to format a line number. */
522 static char *number_buff;
524 /* (-v) True means unprintable characters are printed as escape sequences.
525 control-g becomes \007. */
526 static int use_esc_sequence = FALSE;
528 /* (-c) True means unprintable characters are printed as control prefixes.
529 control-g becomes ^G. */
530 static int use_cntrl_prefix = FALSE;
532 /* (-d) True means output is double spaced. */
533 static int double_space = FALSE;
535 /* Number of files opened initially in init_files. Should be 1
536 unless we're printing multiple files in parallel. */
537 static int total_files = 0;
539 /* (-r) True means don't complain if we can't open a file. */
540 static int ignore_failed_opens = FALSE;
542 /* (-s) True means we separate columns with a specified string.
543 -s option does not affect line truncation nor column alignment. */
544 static int use_col_separator = FALSE;
546 /* String used to separate columns if the -s option has been specified.
547 Default without -s but together with one of the column options
548 -a|COLUMN|-m is a `space' and with the -j option a `tab'. */
549 static char *col_sep_string;
550 static int col_sep_length = 0;
551 static char *column_separator = " ";
552 static char *line_separator = "\t";
554 /* Number of separator characters waiting to be printed as soon as we
555 know that we have any input remaining to be printed. */
556 static int separators_not_printed;
558 /* Position we need to pad to, as soon as we know that we have input
559 remaining to be printed. */
560 static int padding_not_printed;
562 /* True means we should pad the end of the page. Remains false until we
563 know we have a page to print. */
564 static int pad_vertically;
566 /* (-h) String of characters used in place of the filename in the header. */
567 static char *custom_header;
569 /* String containing the date, filename or custom header, and "Page ". */
572 static int *clump_buff;
574 /* If nonzero, display usage information and exit. */
575 static int show_help;
577 /* If nonzero, print the version on standard output then exit. */
578 static int show_version;
580 /* True means we read the line no. lines_per_body in skip_read
581 called by skip_to_page. That variable controls the coincidence of a
582 "FF set by hand" and "full_page_printed", see above the definition of
584 static int last_line = FALSE;
586 /* If nonzero, print a non-variable date and time with the header
587 -h HEADER using pr test-suite */
588 static int test_suite;
590 static struct option const long_options[] =
592 {"help", no_argument, &show_help, 1},
593 {"version", no_argument, &show_version, 1},
594 {"test", no_argument, &test_suite, 1},
598 /* Return the number of columns that have either an open file or
602 cols_ready_to_print (void)
609 for (q = column_vector, i = 0; i < columns; ++q, ++i)
610 if (q->status == OPEN ||
611 q->status == FF_FOUND || /* With -b: To print a header only */
612 (storing_columns && q->lines_stored > 0 && q->lines_to_print > 0))
617 /* Estimate first_ / last_page_number
618 using option +FIRST_PAGE:LAST_PAGE */
621 first_last_page (char *pages)
627 error (0, 0, _("invalid range of page numbers: `%s'"), pages);
631 str1 = strchr (pages, ':');
637 if (xstrtol (pages, NULL, 10, &tmp_long, "") != LONGINT_OK
638 || tmp_long <= 0 || tmp_long > INT_MAX)
639 error (EXIT_FAILURE, 0, _("invalid starting page number: `%s'"),
641 first_page_number = (int) tmp_long;
649 if (xstrtol (str1 + 1, NULL, 10, &tmp_long, "") != LONGINT_OK
650 || tmp_long <= 0 || tmp_long > INT_MAX)
651 error (EXIT_FAILURE, 0, _("invalid ending page number: `%s'"),
653 last_page_number = (int) tmp_long;
656 if (first_page_number > last_page_number)
657 error (EXIT_FAILURE, 0,
658 _("starting page number is larger than ending page number"));
661 /* Estimate length of col_sep_string with option -s[STRING] */
664 separator_string (const char *optarg_S)
666 col_sep_length = (int) strlen (optarg_S);
667 col_sep_string = (char *) xmalloc (col_sep_length + 1);
668 strcpy (col_sep_string, optarg_S);
672 main (int argc, char **argv)
679 program_name = argv[0];
680 setlocale (LC_ALL, "");
681 bindtextdomain (PACKAGE, LOCALEDIR);
682 textdomain (PACKAGE);
685 file_names = (argc > 1
686 ? (char **) xmalloc ((argc - 1) * sizeof (char *))
691 c = getopt_long (argc, argv,
692 "-0123456789abcde::fFh:i::jl:mn::N:o:rs::tTvw:",
694 if (c == 1) /* Non-option argument. */
705 file_names[n_files++] = optarg;
712 accum = accum * 10 + c - '0';
720 explicit_columns = TRUE;
734 case 0: /* getopt long option */
738 print_across_flag = TRUE;
739 storing_columns = FALSE;
742 balance_columns = TRUE;
745 use_cntrl_prefix = TRUE;
752 getoptarg (optarg, 'e', &input_tab_char,
753 &chars_per_input_tab);
754 /* Could check tab width > 0. */
755 untabify_input = TRUE;
759 use_form_feed = TRUE;
762 custom_header = optarg;
763 standard_header = FALSE;
767 getoptarg (optarg, 'i', &output_tab_char,
768 &chars_per_output_tab);
769 /* Could check tab width > 0. */
770 tabify_output = TRUE;
778 if (xstrtol (optarg, NULL, 10, &tmp_long, "") != LONGINT_OK
779 || tmp_long <= 0 || tmp_long > INT_MAX)
781 error (EXIT_FAILURE, 0,
782 _("`-l PAGE_LENGTH' invalid number of lines: `%s'"),
785 lines_per_page = (int) tmp_long;
789 parallel_files = TRUE;
790 storing_columns = FALSE;
793 numbered_lines = TRUE;
795 getoptarg (optarg, 'n', &number_separator,
802 if (xstrtol (optarg, NULL, 10, &tmp_long, "") != LONGINT_OK
803 || tmp_long > INT_MAX)
805 error (EXIT_FAILURE, 0,
806 _("`-N NUMBER' invalid starting line number: `%s'"),
809 start_line_num = (int) tmp_long;
815 if (xstrtol (optarg, NULL, 10, &tmp_long, "") != LONGINT_OK
816 || tmp_long < 0 || tmp_long > INT_MAX)
817 error (EXIT_FAILURE, 0,
818 _("`-o MARGIN' invalid line offset: `%s'"), optarg);
819 chars_per_margin = (int) tmp_long;
823 ignore_failed_opens = TRUE;
826 use_col_separator = TRUE;
828 separator_string (optarg);
839 use_esc_sequence = TRUE;
842 truncate_lines = TRUE;
845 if (xstrtol (optarg, NULL, 10, &tmp_long, "") != LONGINT_OK
846 || tmp_long <= 0 || tmp_long > INT_MAX)
847 error (EXIT_FAILURE, 0,
848 _("`-w PAGE_WIDTH' invalid column number: `%s'"), optarg);
849 chars_per_line = (int) tmp_long;
860 printf ("pr (%s) %s\n", GNU_PACKAGE, VERSION);
867 if (parallel_files && explicit_columns)
868 error (EXIT_FAILURE, 0,
869 _("Cannot specify number of columns when printing in parallel."));
871 if (parallel_files && print_across_flag)
872 error (EXIT_FAILURE, 0,
873 _("Cannot specify both printing across and printing in parallel."));
875 for (; optind < argc; optind++)
877 file_names[n_files++] = argv[optind];
882 /* No file arguments specified; read from standard input. */
883 print_files (0, NULL);
888 print_files (n_files, file_names);
892 for (i = 0; i < n_files; i++)
893 print_files (1, &file_names[i]);
899 if (have_read_stdin && fclose (stdin) == EOF)
900 error (EXIT_FAILURE, errno, _("standard input"));
901 if (ferror (stdout) || fclose (stdout) == EOF)
902 error (EXIT_FAILURE, errno, _("write error"));
903 if (failed_opens > 0)
908 /* Parse options of the form -scNNN.
910 Example: -nck, where 'n' is the option, c is the optional number
911 separator, and k is the optional width of the field used when printing
915 getoptarg (char *arg, char switch_char, char *character, int *number)
922 if (xstrtol (arg, NULL, 10, &tmp_long, "") != LONGINT_OK
923 || tmp_long <= 0 || tmp_long > INT_MAX)
926 _("`-%c' extra characters or invalid number in the argument: `%s'"),
930 *number = (int) tmp_long;
934 /* Set parameters related to formatting. */
937 init_parameters (int number_of_files)
939 int chars_used_by_number = 0;
943 lines_per_header = 3;
944 lines_per_footer = 0;
947 lines_per_body = lines_per_page - lines_per_header - lines_per_footer;
948 if (lines_per_body <= 0)
953 if (extremities == FALSE)
954 lines_per_body = lines_per_page;
957 lines_per_body = lines_per_body / 2;
959 /* If input is stdin, cannot print parallel files. BSD dumps core
961 if (number_of_files == 0)
962 parallel_files = FALSE;
965 columns = number_of_files;
967 /* One file, multi columns down: -b option is set to get a consistent
968 formulation with "FF set by hand" in input files. */
970 balance_columns = TRUE;
972 /* Tabification is assumed for multiple columns. */
975 if (!use_col_separator)
977 /* Use default separator */
979 col_sep_string = line_separator;
981 col_sep_string = column_separator;
983 use_col_separator = TRUE;
986 truncate_lines = TRUE;
987 untabify_input = TRUE;
988 tabify_output = TRUE;
991 storing_columns = FALSE;
993 /* -j dominates -w in any case */
995 truncate_lines = FALSE;
999 line_count = start_line_num;
1000 if (number_separator == input_tab_char)
1002 number_width = chars_per_number +
1003 TAB_WIDTH (chars_per_input_tab,
1004 (chars_per_margin + chars_per_number));
1007 number_width = chars_per_number + 1;
1008 /* The number is part of the column width unless we are
1009 printing files in parallel. */
1011 chars_used_by_number = number_width;
1014 chars_per_column = (chars_per_line - chars_used_by_number -
1015 (columns - 1) * col_sep_length) / columns;
1017 if (chars_per_column < 1)
1018 error (EXIT_FAILURE, 0, _("page width too narrow"));
1022 if (number_buff != NULL)
1024 number_buff = (char *) xmalloc (2 * chars_per_number);
1027 /* Pick the maximum between the tab width and the width of an
1029 if (clump_buff != NULL)
1031 clump_buff = (int *) xmalloc ((chars_per_input_tab > 4
1032 ? chars_per_input_tab : 4) * sizeof (int));
1035 /* Open the necessary files,
1036 maintaining a COLUMN structure for each column.
1038 With multiple files, each column p has a different p->fp.
1039 With single files, each column p has the same p->fp.
1040 Return 1 if (number_of_files > 0) and no files can be opened,
1043 With each column/file p, p->full_page_printed is initialized,
1044 see also open_file. */
1047 init_fps (int number_of_files, char **av)
1056 if (column_vector != NULLCOL)
1057 free ((char *) column_vector);
1058 column_vector = (COLUMN *) xmalloc (columns * sizeof (COLUMN));
1062 files_left = number_of_files;
1063 for (p = column_vector; files_left--; ++p, ++av)
1065 if (open_file (*av, p) == 0)
1073 init_header ("", -1);
1078 if (number_of_files > 0)
1080 if (open_file (*av, p) == 0)
1082 init_header (*av, fileno (p->fp));
1083 p->lines_stored = 0;
1087 p->name = _("standard input");
1089 have_read_stdin = TRUE;
1091 p->full_page_printed = FALSE;
1093 init_header ("", -1);
1094 p->lines_stored = 0;
1097 firstname = p->name;
1099 for (i = columns - 1, ++p; i; --i, ++p)
1101 p->name = firstname;
1104 p->full_page_printed = FALSE;
1105 p->lines_stored = 0;
1108 files_ready_to_read = total_files;
1112 /* Determine print_func and char_func, the functions
1113 used by each column for printing and/or storing.
1115 Determine the horizontal position desired when we begin
1116 printing a column (p->start_position). */
1124 h = chars_per_margin;
1126 if (!truncate_lines)
1130 /* When numbering lines of parallel files, we enlarge the
1131 first column to accomodate the number. Looks better than
1132 the Sys V approach. */
1133 if (parallel_files && numbered_lines)
1134 h_next = h + chars_per_column + number_width;
1136 h_next = h + chars_per_column;
1139 /* Enlarge p->start_position of first column to use the same form of
1140 padding_not_printed with all columns. */
1141 h = h + col_sep_length;
1143 /* This loop takes care of all but the rightmost column. */
1145 for (p = column_vector, i = 1; i < columns; ++p, ++i)
1147 if (storing_columns) /* One file, multi columns down. */
1149 p->char_func = store_char;
1150 p->print_func = print_stored;
1153 /* One file, multi columns across; or parallel files. */
1155 p->char_func = print_char;
1156 p->print_func = read_line;
1159 /* Number only the first column when printing files in
1161 p->numbered = numbered_lines && (!parallel_files || i == 1);
1162 p->start_position = h;
1164 /* If we don't truncate lines, all start_positions are
1165 ANYWHERE, except the first column's start_position when
1168 if (!truncate_lines)
1175 h = h_next + col_sep_length;
1176 h_next = h + chars_per_column;
1180 /* The rightmost column.
1182 Doesn't need to be stored unless we intend to balance
1183 columns on the last page. */
1184 if (storing_columns && balance_columns)
1186 p->char_func = store_char;
1187 p->print_func = print_stored;
1191 p->char_func = print_char;
1192 p->print_func = read_line;
1195 p->numbered = numbered_lines && (!parallel_files || i == 1);
1196 p->start_position = h;
1199 /* Open a file. Return nonzero if successful, zero if failed.
1201 With each file p, p->full_page_printed is initialized,
1202 see also init_fps. */
1205 open_file (char *name, COLUMN *p)
1207 if (!strcmp (name, "-"))
1209 p->name = _("standard input");
1211 have_read_stdin = 1;
1216 p->fp = fopen (name, "r");
1221 if (!ignore_failed_opens)
1222 error (0, errno, "%s", name);
1226 p->full_page_printed = FALSE;
1231 /* Close the file in P.
1233 If we aren't dealing with multiple files in parallel, we change
1234 the status of all columns in the column list to reflect the close. */
1237 close_file (COLUMN *p)
1242 if (p->status == CLOSED)
1245 error (EXIT_FAILURE, errno, "%s", p->name);
1246 if (p->fp != stdin && fclose (p->fp) == EOF)
1247 error (EXIT_FAILURE, errno, "%s", p->name);
1249 if (!parallel_files)
1251 for (q = column_vector, i = columns; i; ++q, --i)
1254 if (q->lines_stored == 0)
1256 q->lines_to_print = 0;
1263 p->lines_to_print = 0;
1266 --files_ready_to_read;
1269 /* Put a file on hold until we start a new page,
1270 since we've hit a form feed.
1272 If we aren't dealing with parallel files, we must change the
1273 status of all columns in the column list. */
1276 hold_file (COLUMN *p)
1281 if (!parallel_files)
1282 for (q = column_vector, i = columns; i; ++q, --i)
1284 if (storing_columns)
1285 q->status = FF_FOUND;
1287 q->status = ON_HOLD;
1290 p->status = ON_HOLD;
1292 p->lines_to_print = 0;
1293 --files_ready_to_read;
1296 /* Undo hold_file -- go through the column list and change any
1297 ON_HOLD columns to OPEN. Used at the end of each page. */
1305 for (p = column_vector; i; --i, ++p)
1306 if (p->status == ON_HOLD)
1309 files_ready_to_read++;
1312 if (storing_columns)
1313 files_ready_to_read = 1;
1316 /* Print a single file, or multiple files in parallel.
1318 Set up the list of columns, opening the necessary files.
1319 Allocate space for storing columns, if necessary.
1320 Skip to first_page_number, if user has asked to skip leading pages.
1321 Determine which functions are appropriate to store/print lines
1323 Print the file(s). */
1326 print_files (int number_of_files, char **av)
1328 init_parameters (number_of_files);
1329 if (init_fps (number_of_files, av))
1331 if (storing_columns)
1334 if (first_page_number > 1)
1336 if (!skip_to_page (first_page_number))
1339 page_number = first_page_number;
1346 line_number = line_count;
1347 while (print_page ())
1351 /* Estimate the number of characters taken up by a short format date and
1352 time: "yy-mm-dd HH:MM" and: "Page NNNN". */
1353 #define CHARS_FOR_DATE_AND_PAGE 23
1355 /* Initialize header information.
1356 If DESC is non-negative, it is a file descriptor open to
1357 FILENAME for reading.
1359 Allocate space for a header string,
1360 Determine the time, insert file name or user-specified string.
1361 Make use of a centered header with left-hand-side truncation marked by
1362 a '*` in front, if necessary. */
1365 init_header (char *filename, int desc)
1367 int chars_per_middle, chars_free, lhs_blanks, rhs_blanks;
1369 char *no_middle = "";
1373 char *datim = "- Date/Time --";
1375 if (filename == NULL)
1380 header = (char *) xmalloc (chars_per_line + 1);
1382 if (!standard_header && *custom_header == '\0')
1383 sprintf (header, "%s", " "); /* blank line header */
1386 #define T_BUF_FMT "%Y-%m-%d %H:%M" /* date/time short format */
1387 #define T_BUF_SIZE 17 /* FIXME: using a literal here is fragile. */
1388 char t_buf[T_BUF_SIZE];
1390 /* If parallel files or standard input, use current time. */
1391 if (desc < 0 || !strcmp (filename, "-") || fstat (desc, &st))
1392 st.st_mtime = time (NULL);
1394 tmptr = localtime (&st.st_mtime);
1395 strftime (t_buf, T_BUF_SIZE, T_BUF_FMT, tmptr);
1397 chars_per_middle = chars_per_line - CHARS_FOR_DATE_AND_PAGE;
1398 if (chars_per_middle < 3)
1400 header_text = no_middle; /* Nothing free for a heading */
1406 header_text = standard_header ? f : custom_header;
1407 chars_free = chars_per_middle - (int) strlen (header_text);
1410 lhs_blanks = chars_free / 2; /* text not truncated */
1411 rhs_blanks = chars_free - lhs_blanks;
1414 { /* lhs truncation */
1415 header_text = header_text - chars_free + 2;
1422 sprintf (header, _("%s%*s%s%*sPage"), (test_suite ? datim : t_buf),
1423 lhs_blanks, " ", header_text, rhs_blanks, " ");
1427 /* Set things up for printing a page
1429 Scan through the columns ...
1430 Determine which are ready to print
1431 (i.e., which have lines stored or open files)
1432 Set p->lines_to_print appropriately
1433 (to p->lines_stored if we're storing, or lines_per_body
1434 if we're reading straight from the file)
1435 Keep track of this total so we know when to stop printing */
1443 if (storing_columns)
1446 for (j = columns - 1, p = column_vector; j; --j, ++p)
1448 p->lines_to_print = p->lines_stored;
1452 if (balance_columns)
1454 p->lines_to_print = p->lines_stored;
1456 /* Since we're not balancing columns, we don't need to store
1457 the rightmost column. Read it straight from the file. */
1460 if (p->status == OPEN)
1462 p->lines_to_print = lines_per_body;
1465 p->lines_to_print = 0;
1469 for (j = columns, p = column_vector; j; --j, ++p)
1470 if (p->status == OPEN)
1472 p->lines_to_print = lines_per_body;
1475 p->lines_to_print = 0;
1478 /* Align empty columns and print separators.
1479 Empty columns will be formed by files with status ON_HOLD or CLOSED
1480 when printing multiple files in parallel. */
1483 align_column (COLUMN *p)
1485 padding_not_printed = p->start_position;
1486 if (padding_not_printed - col_sep_length > 0)
1488 pad_across_to (padding_not_printed - col_sep_length);
1489 padding_not_printed = ANYWHERE;
1492 if (use_col_separator)
1493 print_sep_string ();
1496 add_line_number (p);
1501 As long as there are lines left on the page and columns ready to print,
1502 Scan across the column list
1503 if the column has stored lines or the file is open
1504 pad to the appropriate spot
1506 pad the remainder of the page with \n or \f as requested
1507 reset the status of all files -- any files which where on hold because
1508 of formfeeds are now put back into the lineup. */
1514 int lines_left_on_page;
1517 /* Used as an accumulator (with | operator) of successive values of
1518 pad_vertically. The trick is to set pad_vertically
1519 to zero before each run through the inner loop, then after that
1520 loop, it tells us whether a line was actually printed (whether a
1521 newline needs to be output -- or two for double spacing). But those
1522 values have to be accumulated (in pv) so we can invoke pad_down
1523 properly after the outer loop completes. */
1528 if (cols_ready_to_print () == 0)
1532 print_a_header = TRUE;
1534 /* Don't pad unless we know a page was printed. */
1535 pad_vertically = FALSE;
1538 lines_left_on_page = lines_per_body;
1540 lines_left_on_page *= 2;
1542 while (lines_left_on_page > 0 && cols_ready_to_print () > 0)
1544 output_position = 0;
1545 spaces_not_printed = 0;
1546 separators_not_printed = 0;
1547 pad_vertically = FALSE;
1548 align_empty_cols = FALSE;
1551 for (j = 1, p = column_vector; j <= columns; ++j, ++p)
1554 if (p->lines_to_print > 0 || p->status == FF_FOUND)
1557 padding_not_printed = p->start_position;
1558 if (!(p->print_func) (p))
1559 read_rest_of_line (p);
1560 pv |= pad_vertically;
1562 --p->lines_to_print;
1563 if (p->lines_to_print <= 0)
1565 if (cols_ready_to_print () <= 0)
1569 /* File p changed its status to ON_HOLD or CLOSED */
1570 if (parallel_files && p->status != OPEN)
1573 align_empty_cols = TRUE;
1574 else if (p->status == CLOSED ||
1575 (p->status == ON_HOLD && FF_only))
1579 else if (parallel_files)
1581 /* File status ON_HOLD or CLOSED */
1583 align_empty_cols = TRUE;
1588 /* We need it also with an empty column */
1589 if (use_col_separator)
1590 ++separators_not_printed;
1596 --lines_left_on_page;
1599 if (double_space && pv && extremities)
1602 --lines_left_on_page;
1606 if (lines_left_on_page == 0)
1607 for (j = 1, p = column_vector; j <= columns; ++j, ++p)
1608 if (p->status == OPEN)
1609 p->full_page_printed = TRUE;
1611 pad_vertically = pv;
1613 if (pad_vertically && extremities)
1614 pad_down (lines_left_on_page + lines_per_footer);
1615 else if (keep_FF && print_a_FF)
1621 if (last_page_number && page_number > last_page_number)
1622 return FALSE; /* Stop printing with LAST_PAGE */
1624 reset_status (); /* Change ON_HOLD to OPEN. */
1626 return TRUE; /* More pages to go. */
1629 /* Allocate space for storing columns.
1631 This is necessary when printing multiple columns from a single file.
1632 Lines are stored consecutively in buff, separated by '\0'.
1634 The following doesn't apply any longer - any tuning possible?
1635 (We can't use a fixed offset since with the '-s' flag lines aren't
1638 We maintain a list (line_vector) of pointers to the beginnings
1639 of lines in buff. We allocate one more than the number of lines
1640 because the last entry tells us the index of the last character,
1641 which we need to know in order to print the last line in buff. */
1644 init_store_cols (void)
1646 int total_lines = lines_per_body * columns;
1647 int chars_if_truncate = total_lines * (chars_per_column + 1);
1649 if (line_vector != NULL)
1650 free ((int *) line_vector);
1651 /* FIXME: here's where it was allocated. */
1652 line_vector = (int *) xmalloc ((total_lines + 1) * sizeof (int *));
1654 if (end_vector != NULL)
1655 free ((int *) end_vector);
1656 end_vector = (int *) xmalloc (total_lines * sizeof (int *));
1660 buff_allocated = (use_col_separator
1661 ? 2 * chars_if_truncate
1662 : chars_if_truncate); /* Tune this. */
1663 buff = (char *) xmalloc (buff_allocated);
1666 /* Store all but the rightmost column.
1667 (Used when printing a single file in multiple downward columns)
1670 set p->current_line to be the index in line_vector of the
1671 first line in the column
1672 For each line in the column
1673 store the line in buff
1674 add to line_vector the index of the line's first char
1675 buff_start is the index in buff of the first character in the
1679 store_columns (void)
1684 int last_col; /* The rightmost column which will be saved in buff */
1690 if (balance_columns)
1693 last_col = columns - 1;
1695 for (i = 1, p = column_vector; i <= last_col; ++i, ++p)
1696 p->lines_stored = 0;
1698 for (i = 1, p = column_vector; i <= last_col && files_ready_to_read;
1701 p->current_line = line;
1702 for (j = lines_per_body; j && files_ready_to_read; --j)
1704 if (p->status == OPEN) /* Redundant. Clean up. */
1709 read_rest_of_line (p);
1711 if (p->status == OPEN
1712 || buff_start != buff_current)
1715 line_vector[line] = buff_start;
1716 end_vector[line++] = input_position;
1717 buff_start = buff_current;
1722 /* Keep track of the location of the last char in buff. */
1723 line_vector[line] = buff_start;
1725 if (balance_columns && p->lines_stored != lines_per_body)
1730 balance (int total_stored)
1736 for (i = 1, p = column_vector; i <= columns; ++i, ++p)
1738 lines = total_stored / columns;
1739 if (i <= total_stored % columns)
1742 p->lines_stored = lines;
1743 p->current_line = first_line;
1745 first_line += lines;
1749 /* Store a character in the buffer. */
1754 if (buff_current >= buff_allocated)
1756 /* May be too generous. */
1757 buff_allocated = 2 * buff_allocated;
1758 buff = (char *) xrealloc (buff, buff_allocated * sizeof (char));
1760 buff[buff_current++] = (char) c;
1764 add_line_number (COLUMN *p)
1769 sprintf (number_buff, "%*d", chars_per_number, line_number++);
1771 for (i = chars_per_number; i > 0; i--)
1772 (p->char_func) ((int) *s++);
1774 if (number_separator == input_tab_char)
1776 i = number_width - chars_per_number;
1778 (p->char_func) ((int) ' ');
1781 (p->char_func) ((int) number_separator);
1783 if (truncate_lines && !parallel_files)
1784 input_position += number_width;
1787 /* Print (or store) padding until the current horizontal position
1791 pad_across_to (int position)
1793 register int h = output_position;
1796 spaces_not_printed = position - output_position;
1799 while (++h <= position)
1801 output_position = position;
1805 /* Pad to the bottom of the page.
1807 If the user has requested a formfeed, use one.
1808 Otherwise, use newlines. */
1811 pad_down (int lines)
1818 for (i = lines; i; --i)
1822 /* Read the rest of the line.
1824 Read from the current column's file until an end of line is
1825 hit. Used when we've truncated a line and we no longer need
1826 to print or store its characters. */
1829 read_rest_of_line (COLUMN *p)
1834 while ((c = getc (f)) != '\n')
1838 if ((c = getc (f)) != '\n')
1853 /* Read a line with skip_to_page.
1855 Read from the current column's file until an end of line is
1856 hit. Used when we read full lines to skip pages.
1857 With skip_to_page we have to check for FF-coincidence which is done
1858 in function read_line otherwise.
1859 Count lines of skipped pages to find the line number of 1st page
1860 printed relative to 1st line of input file (start_line_num). */
1863 skip_read (COLUMN *p, int column_number)
1867 int i, single_ff = FALSE;
1870 /* Read 1st character in a line or any character succeeding a FF */
1871 if ((c = getc (f)) == '\f' && p->full_page_printed)
1872 /* A FF-coincidence with a previous full_page_printed.
1873 To avoid an additional empty page, eliminate the FF */
1874 if ((c = getc (f)) == '\n')
1877 p->full_page_printed = FALSE;
1879 /* 1st character a FF means a single FF without any printable
1880 characters. Don't count it as a line with -n option. */
1884 /* Preparing for a FF-coincidence: Maybe we finish that page
1885 without a FF found */
1887 p->full_page_printed = TRUE;
1893 /* No FF-coincidence possible,
1894 no catching up of a FF-coincidence with next page */
1897 if (!parallel_files)
1898 for (q = column_vector, i = columns; i; ++q, --i)
1899 q->full_page_printed = FALSE;
1901 p->full_page_printed = FALSE;
1904 if ((c = getc (f)) != '\n')
1918 if ((!parallel_files || column_number == 1) && !single_ff)
1922 /* If we're tabifying output,
1924 When print_char encounters white space it keeps track
1925 of our desired horizontal position and delays printing
1926 until this function is called. */
1929 print_white_space (void)
1932 register int h_old = output_position;
1933 register int goal = h_old + spaces_not_printed;
1935 while (goal - h_old > 1
1936 && (h_new = POS_AFTER_TAB (chars_per_output_tab, h_old)) <= goal)
1938 putchar (output_tab_char);
1941 while (++h_old <= goal)
1944 output_position = goal;
1945 spaces_not_printed = 0;
1948 /* Print column separators.
1950 We keep a count until we know that we'll be printing a line,
1951 then print_sep_string() is called. */
1957 int l = col_sep_length;
1961 if (spaces_not_printed > 0)
1962 print_white_space ();
1964 for (; separators_not_printed > 0; --separators_not_printed)
1968 output_position += col_sep_length;
1972 /* Print (or store, depending on p->char_func) a clump of N
1976 print_clump (COLUMN *p, int n, int *clump)
1979 (p->char_func) (*clump++);
1982 /* Print a character.
1984 Update the following comment: process-char hasn't been used any
1986 If we're tabifying, all tabs have been converted to spaces by
1987 process_char(). Keep a count of consecutive spaces, and when
1988 a nonspace is encountered, call print_white_space() to print the
1989 required number of tabs and spaces. */
1998 ++spaces_not_printed;
2001 else if (spaces_not_printed > 0)
2002 print_white_space ();
2004 /* Nonprintables are assumed to have width 0, except '\b'. */
2016 /* Skip to page PAGE before printing. */
2019 skip_to_page (int page)
2024 for (n = 1; n < page; ++n)
2026 for (i = 1; i < lines_per_body; ++i)
2028 for (j = 1, p = column_vector; j <= columns; ++j, ++p)
2029 if (p->status == OPEN)
2033 for (j = 1, p = column_vector; j <= columns; ++j, ++p)
2034 if (p->status == OPEN)
2037 if (storing_columns) /* change FF_FOUND to ON_HOLD */
2038 for (j = 1, p = column_vector; j <= columns; ++j, ++p)
2039 p->status = ON_HOLD;
2044 return files_ready_to_read > 0;
2049 Formfeeds are assumed to use up two lines at the beginning of
2056 fprintf (stdout, "\n\n");
2058 output_position = 0;
2059 pad_across_to (chars_per_margin);
2060 print_white_space ();
2062 if (!standard_header && *custom_header == '\0')
2063 fprintf (stdout, "%s\n\n\n", header);
2065 fprintf (stdout, "%s%5d\n\n\n", header, page_number++);
2067 print_a_header = FALSE;
2068 output_position = 0;
2071 /* Print (or store, if p->char_func is store_char()) a line.
2073 Read a character to determine whether we have a line or not.
2074 (We may hit EOF, \n, or \f)
2076 Once we know we have a line,
2077 set pad_vertically = TRUE, meaning it's safe
2078 to pad down at the end of the page, since we do have a page.
2079 print a header if needed.
2080 pad across to padding_not_printed if needed.
2081 print any separators which need to be printed.
2082 print a line number if it needs to be printed.
2084 Print the clump which corresponds to the first character.
2086 Enter a loop and keep printing until an end of line condition
2087 exists, or until we exceed chars_per_column.
2089 Return FALSE if we exceed chars_per_column before reading
2090 an end of line character, TRUE otherwise. */
2093 read_line (COLUMN *p)
2095 register int c, chars;
2096 int last_input_position;
2100 /* Suppress `used before initialized' warning. */
2105 /* read 1st character in each line or any character succeeding a FF: */
2108 last_input_position = input_position;
2110 if (c == '\f' && p->full_page_printed)
2111 if ((c = getc (p->fp)) == '\n')
2113 p->full_page_printed = FALSE;
2118 if ((c = getc (p->fp)) != '\n')
2121 if (print_a_header && !storing_columns)
2123 pad_vertically = TRUE;
2136 chars = char_to_clump (c);
2139 if (truncate_lines && input_position > chars_per_column)
2141 input_position = last_input_position;
2145 if (p->char_func != store_char)
2147 pad_vertically = TRUE;
2149 if (print_a_header && !storing_columns)
2152 if (parallel_files && align_empty_cols)
2154 /* We have to align empty columns at the beginning of a line. */
2155 k = separators_not_printed;
2156 separators_not_printed = 0;
2157 for (j = 1, q = column_vector; j <= k; ++j, ++q)
2160 separators_not_printed += 1;
2162 padding_not_printed = p->start_position;
2164 spaces_not_printed = chars_per_column;
2166 spaces_not_printed = 0;
2167 align_empty_cols = FALSE;
2170 if (padding_not_printed - col_sep_length > 0)
2172 pad_across_to (padding_not_printed - col_sep_length);
2173 padding_not_printed = ANYWHERE;
2176 if (use_col_separator)
2177 print_sep_string ();
2181 add_line_number (p);
2187 print_clump (p, chars, clump_buff);
2198 if ((c = getc (p->fp)) != '\n')
2209 last_input_position = input_position;
2210 chars = char_to_clump (c);
2211 if (truncate_lines && input_position > chars_per_column)
2213 input_position = last_input_position;
2217 print_clump (p, chars, clump_buff);
2221 /* Print a line from buff.
2223 If this function has been called, we know we have "something to
2224 print". But it remains to be seen whether we have a real text page
2225 or an empty page (a single form feed) with/without a header only.
2226 Therefore first we set pad_vertically to TRUE and print a header
2228 If FF_FOUND and we are using -t|-T option we omit any newline by
2229 setting pad_vertically to FALSE (see print_page).
2230 Otherwise we pad across if necessary, print separators if necessary
2231 and text of COLUMN *p.
2233 Return TRUE, meaning there is no need to call read_rest_of_line. */
2236 print_stored (COLUMN *p)
2241 int line = p->current_line++;
2242 register char *first = &buff[line_vector[line]];
2244 UMR: Uninitialized memory read:
2245 * This is occurring while in:
2246 print_stored [pr.c:2239]
2247 * Reading 4 bytes from 0x5148c in the heap.
2248 * Address 0x5148c is 4 bytes into a malloc'd block at 0x51488 of 676 bytes
2249 * This block was allocated from:
2251 xmalloc [xmalloc.c:94]
2252 init_store_cols [pr.c:1648]
2254 register char *last = &buff[line_vector[line + 1]];
2256 pad_vertically = TRUE;
2261 if (p->status == FF_FOUND)
2263 for (i = 1, q = column_vector; i <= columns; ++i, ++q)
2264 q->status = ON_HOLD;
2265 if (column_vector->lines_to_print <= 0)
2268 pad_vertically = FALSE;
2269 return TRUE; /* print a header only */
2273 if (padding_not_printed - col_sep_length > 0)
2275 pad_across_to (padding_not_printed - col_sep_length);
2276 padding_not_printed = ANYWHERE;
2279 if (use_col_separator)
2280 print_sep_string ();
2282 while (first != last)
2283 print_char (*first++);
2285 if (spaces_not_printed == 0)
2287 output_position = p->start_position + end_vector[line];
2288 if (p->start_position - col_sep_length == chars_per_margin)
2289 output_position -= col_sep_length;
2295 /* Convert a character to the proper format and return the number of
2296 characters in the resulting clump. Increment input_position by
2297 the width of the clump.
2299 Tabs are converted to clumps of spaces.
2300 Nonprintable characters may be converted to clumps of escape
2301 sequences or control prefixes.
2303 Note: the width of a clump is not necessarily equal to the number of
2304 characters in clump_buff. (e.g, the width of '\b' is -1, while the
2305 number of characters is 1.) */
2308 char_to_clump (int c)
2310 register int *s = clump_buff;
2316 if (c == input_tab_char)
2318 width = TAB_WIDTH (chars_per_input_tab, input_position);
2322 for (i = width; i; --i)
2333 else if (!ISPRINT (c))
2335 if (use_esc_sequence)
2340 sprintf (esc_buff, "%03o", c);
2341 for (i = 0; i <= 2; ++i)
2342 *s++ = (int) esc_buff[i];
2344 else if (use_cntrl_prefix)
2358 sprintf (esc_buff, "%03o", c);
2359 for (i = 0; i <= 2; ++i)
2360 *s++ = (int) esc_buff[i];
2383 input_position += width;
2387 /* We've just printed some files and need to clean up things before
2388 looking for more options and printing the next batch of files.
2390 Free everything we've xmalloc'ed, except `header'. */
2400 free (column_vector);
2409 /* Complain, print a usage message, and die. */
2415 fprintf (stderr, _("Try `%s --help' for more information.\n"),
2420 Usage: %s [OPTION]... [FILE]...\n\
2425 Paginate or columnate FILE(s) for printing.\n\
2427 +FIRST_PAGE[:LAST_PAGE]\n\
2428 begin [stop] printing with page FIRST_[LAST_]PAGE\n\
2429 -COLUMN produce COLUMN-column output and print columns down,\n\
2430 unless -a is used. Balance number of lines in the\n\
2431 columns on each page.\n\
2432 -a print columns across rather than down, used together\n\
2434 -c use hat notation (^G) and octal backslash notation\n\
2435 -d double space the output\n\
2436 -e[CHAR[WIDTH]] expand input CHARs (TABs) to tab WIDTH (8)\n\
2437 -F, -f use form feeds instead of newlines to separate pages\n\
2438 (by a 3-line page header with -f or a 5-line header\n\
2439 and trailer without -f)\n\
2440 -h HEADER use a centered HEADER instead of filename in page headers\n\
2441 with long headers left-hand-side truncation may occur\n\
2442 -h \"\" prints a blank line. Don't use -h\"\"\n\
2443 -i[CHAR[WIDTH]] replace spaces with CHARs (TABs) to tab WIDTH (8)\n\
2444 -j merge full lines, turns off -w line truncation, no column\n\
2445 alignment, -s[STRING] sets separators\n\
2446 -l PAGE_LENGTH set the page length to PAGE_LENGTH (66) lines\n\
2447 (default number of lines of text 56, with -f 63)\n"));
2449 -m print all files in parallel, one in each column,\n\
2450 truncate lines, but join lines of full length with -j\n\
2451 -n[SEP[DIGITS]] number lines, use DIGITS (5) digits, then SEP (TAB)\n\
2452 default counting starts with 1st line of input file\n\
2453 -N NUMBER start counting with NUMBER at 1st line of first\n\
2454 page printed (see +FIRST_PAGE)\n\
2455 -o MARGIN offset each line with MARGIN spaces (do not affect -w)\n\
2456 -r inhibit warning when a file cannot be opened\n\
2457 -s[STRING] separate columns by an optional STRING, don't use\n\
2458 -s \"STRING\", -s only: No separator used (same as -s\"\"),\n\
2459 without -s: Default separator \'TAB\' with -j and \'space\'\n\
2460 otherwise (same as -s\" \")\n\
2461 -t inhibit page headers and trailers\n\
2462 -T inhibit page headers and trailers, eliminate any page\n\
2463 layout by form feeds set in input files\n\
2464 -v use octal backslash notation\n\
2465 -w PAGE_WIDTH set page width to PAGE_WIDTH (72) columns, truncate\n\
2466 lines (see also -j option)\n\
2467 --help display this help and exit\n\
2468 --version output version information and exit\n\
2470 -T implied by -l nn when nn <= 10 or <= 3 with -f. With no FILE, or when\n\
2471 FILE is -, read standard input.\n\
2473 puts (_("\nReport bugs to <textutils-bugs@gnu.org>."));
2475 exit (status == 0 ? EXIT_SUCCESS : EXIT_FAILURE);