1 /* pr -- convert text files for printing.
2 Copyright (C) 88, 91, 95, 96, 1997, 1998 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 /* Used with start_position in the struct COLUMN described below.
187 If start_position == ANYWHERE, we aren't truncating columns and
188 can begin printing a column anywhere. Otherwise we must pad to
189 the horizontal position start_position. */
192 /* Each column has one of these structures allocated for it.
193 If we're only dealing with one file, fp is the same for all
196 The general strategy is to spend time setting up these column
197 structures (storing columns if necessary), after which printing
198 is a matter of flitting from column to column and calling
201 Parallel files, single files printing across in multiple
202 columns, and single files printing down in multiple columns all
203 fit the same printing loop.
205 print_func Function used to print lines in this column.
206 If we're storing this column it will be
207 print_stored(), Otherwise it will be read_line().
209 char_func Function used to process characters in this column.
210 If we're storing this column it will be store_char(),
211 otherwise it will be print_char().
213 current_line Index of the current entry in line_vector, which
214 contains the index of the first character of the
215 current line in buff[].
217 lines_stored Number of lines in this column which are stored in
220 lines_to_print If we're storing this column, lines_to_print is
221 the number of stored_lines which remain to be
222 printed. Otherwise it is the number of lines
223 we can print without exceeding lines_per_body.
225 start_position The horizontal position we want to be in before we
226 print the first character in this column.
228 numbered True means precede this column with a line number. */
232 FILE *fp
; /* Input stream for this column. */
233 char *name
; /* File name. */
237 FF_FOUND
, /* used with -b option, set with \f, changed
238 to ON_HOLD after print_header */
239 ON_HOLD
, /* Hit a form feed. */
242 status
; /* Status of the file pointer. */
243 int (*print_func
) (); /* Func to print lines in this col. */
244 void (*char_func
) (); /* Func to print/store chars in this col. */
245 int current_line
; /* Index of current place in line_vector. */
246 int lines_stored
; /* Number of lines stored in buff. */
247 int lines_to_print
; /* No. lines stored or space left on page. */
248 int start_position
; /* Horizontal position of first char. */
250 int full_page_printed
; /* True means printed without a FF found. */
252 /* p->full_page_printed controls a special case of "FF set by hand":
253 True means a full page has been printed without FF found. To avoid an
254 additional empty page we have to ignore a FF immediately following in
258 typedef struct COLUMN COLUMN
;
260 #define NULLCOL (COLUMN *)0
262 static int char_to_clump
PARAMS ((int c
));
263 static int read_line
PARAMS ((COLUMN
*p
));
264 static int print_page
PARAMS ((void));
265 static int print_stored
PARAMS ((COLUMN
*p
));
266 static int open_file
PARAMS ((char *name
, COLUMN
*p
));
267 static int skip_to_page
PARAMS ((int page
));
268 static void print_header
PARAMS ((void));
269 static void pad_across_to
PARAMS ((int position
));
270 static void add_line_number
PARAMS ((COLUMN
*p
));
271 static void getoptarg
PARAMS ((char *arg
, char switch_char
, char *character
,
273 static void usage
PARAMS ((int status
));
274 static void print_files
PARAMS ((int number_of_files
, char **av
));
275 static void init_parameters
PARAMS ((int number_of_files
));
276 static void init_header
PARAMS ((char *filename
, int desc
));
277 static void init_store_cols
PARAMS ((void));
278 static void store_columns
PARAMS ((void));
279 static void balance
PARAMS ((int total_stored
));
280 static void store_char
PARAMS ((int c
));
281 static void pad_down
PARAMS ((int lines
));
282 static void read_rest_of_line
PARAMS ((COLUMN
*p
));
283 static void skip_read
PARAMS ((COLUMN
*p
, int column_number
));
284 static void print_char
PARAMS ((int c
));
285 static void cleanup
PARAMS ((void));
286 static void first_last_page
PARAMS ((char *pages
));
287 static void print_sep_string
PARAMS ((void));
288 static void separator_string
PARAMS ((const char *optarg_S
));
290 /* The name under which this program was invoked. */
293 /* All of the columns to print. */
294 static COLUMN
*column_vector
;
296 /* When printing a single file in multiple downward columns,
297 we store the leftmost columns contiguously in buff.
298 To print a line from buff, get the index of the first character
299 from line_vector[i], and print up to line_vector[i + 1]. */
302 /* Index of the position in buff where the next character
304 static int buff_current
;
306 /* The number of characters in buff.
307 Used for allocation of buff and to detect overflow of buff. */
308 static int buff_allocated
;
310 /* Array of indices into buff.
311 Each entry is an index of the first character of a line.
312 This is used when storing lines to facilitate shuffling when
313 we do column balancing on the last page. */
314 static int *line_vector
;
316 /* Array of horizonal positions.
317 For each line in line_vector, end_vector[line] is the horizontal
318 position we are in after printing that line. We keep track of this
319 so that we know how much we need to pad to prepare for the next
321 static int *end_vector
;
323 /* (-m) True means we're printing multiple files in parallel. */
324 static int parallel_files
= FALSE
;
326 /* (-m) True means a line starts with some empty columns (some files
327 already CLOSED or ON_HOLD) which we have to align. */
328 static int align_empty_cols
;
330 /* (-m) True means we have not yet found any printable column in a line.
331 align_empty_cols = TRUE has to be maintained. */
332 static int empty_line
;
334 /* (-m) False means printable column output precedes a form feed found.
335 Column align is done only once. No additional action with that form
337 True means we found only a form feed in a column. Maybe we have to do
338 some column align with that form feed. */
341 /* (-[0-9]+) True means we're given an option explicitly specifying
342 number of columns. Used to detect when this option is used with -m. */
343 static int explicit_columns
= FALSE
;
345 /* (-t|-T) False means we aren't printing headers and footers. */
346 static int extremities
= TRUE
;
348 /* (-t) True means we retain all FF set by hand in input files.
349 False is set with -T option. */
350 static int keep_FF
= FALSE
;
351 static int print_a_FF
= FALSE
;
353 /* True means we need to print a header as soon as we know we've got input
354 to print after it. */
355 static int print_a_header
;
357 /* (-h) True means we're using the standard header rather than a
358 customized one specified by the -h flag. */
359 static int standard_header
= TRUE
;
361 /* (-f) True means use formfeeds instead of newlines to separate pages. */
362 static int use_form_feed
= FALSE
;
364 /* True means we have read the standard input. */
365 static int have_read_stdin
= FALSE
;
367 /* True means the -a flag has been given. */
368 static int print_across_flag
= FALSE
;
370 /* True means we're printing one file in multiple (>1) downward columns. */
371 static int storing_columns
= TRUE
;
373 /* (-b) True means balance columns on the last page as Sys V does. */
374 /* That's no longer an independent option. With storing_columns = TRUE
375 balance_columns = TRUE is used too (s. function init_parameters).
376 We get a consistent formulation with "FF set by hand" in input files. */
377 static int balance_columns
= FALSE
;
379 /* (-l) Number of lines on a page, including header and footer lines. */
380 static int lines_per_page
= 66;
382 /* Number of lines in the header and footer can be reset to 0 using
384 static int lines_per_header
= 5;
385 static int lines_per_body
;
386 static int lines_per_footer
= 5;
388 /* (-w) Width in characters of the page. Does not include the width of
390 static int chars_per_line
= 72;
392 /* (-w) True means we truncate lines longer than chars_per_column. */
393 static int truncate_lines
= FALSE
;
395 /* (-j) True means we join lines without any line truncation. -j
396 dominates -w option. */
397 static int join_lines
= FALSE
;
399 /* Number of characters in a column. Based on col_sep_length and
401 static int chars_per_column
;
403 /* (-e) True means convert tabs to spaces on input. */
404 static int untabify_input
= FALSE
;
406 /* (-e) The input tab character. */
407 static char input_tab_char
= '\t';
409 /* (-e) Tabstops are at chars_per_tab, 2*chars_per_tab, 3*chars_per_tab, ...
410 where the leftmost column is 1. */
411 static int chars_per_input_tab
= 8;
413 /* (-i) True means convert spaces to tabs on output. */
414 static int tabify_output
= FALSE
;
416 /* (-i) The output tab character. */
417 static char output_tab_char
= '\t';
419 /* (-i) The width of the output tab. */
420 static int chars_per_output_tab
= 8;
422 /* Keeps track of pending white space. When we hit a nonspace
423 character after some whitespace, we print whitespace, tabbing
424 if necessary to get to output_position + spaces_not_printed. */
425 static int spaces_not_printed
;
427 /* (-o) Number of spaces in the left margin (tabs used when possible). */
428 static int chars_per_margin
= 0;
430 /* Position where the next character will fall.
431 Leftmost position is 0 + chars_per_margin.
432 Rightmost position is chars_per_margin + chars_per_line - 1.
433 This is important for converting spaces to tabs on output. */
434 static int output_position
;
436 /* Horizontal position relative to the current file.
437 (output_position depends on where we are on the page;
438 input_position depends on where we are in the file.)
439 Important for converting tabs to spaces on input. */
440 static int input_position
;
442 /* Count number of failed opens so we can exit with nonzero
443 status if there were any. */
444 static int failed_opens
= 0;
446 /* The number of spaces taken up if we print a tab character with width
447 c_ from position h_. */
448 #define TAB_WIDTH(c_, h_) ((c_) - ((h_) % (c_)))
450 /* The horizontal position we'll be at after printing a tab character
451 of width c_ from the position h_. */
452 #define POS_AFTER_TAB(c_, h_) ((h_) + TAB_WIDTH (c_, h_))
454 /* (-NNN) Number of columns of text to print. */
455 static int columns
= 1;
457 /* (+NNN:MMM) Page numbers on which to begin and stop printing. */
458 static int first_page_number
= 1;
459 static int last_page_number
= 0;
461 /* Number of files open (not closed, not on hold). */
462 static int files_ready_to_read
= 0;
464 /* Current page number. Displayed in header. */
465 static int page_number
;
467 /* Current line number. Displayed when -n flag is specified.
469 When printing files in parallel (-m flag), line numbering is as follows:
473 When printing files across (-a flag), ...
477 Otherwise, line numbering is as follows:
480 static int line_number
;
482 /* (-n) True means lines should be preceded by numbers. */
483 static int numbered_lines
= FALSE
;
485 /* (-n) Character which follows each line number. */
486 static char number_separator
= '\t';
488 /* (-n) line counting starts with 1st line of input file (not with 1st
489 line of 1st page printed). */
490 static int line_count
= 1;
492 /* (-n) True means counting of skipped lines starts with 1st line of
493 input file. False means -N option is used in addition, counting of
494 skipped lines not required. */
495 static int skip_count
= TRUE
;
497 /* (-N) Counting starts with start_line_number = NUMBER at 1st line of
498 first page printed, usually not 1st page of input file. */
499 static int start_line_num
= 1;
501 /* (-n) Width in characters of a line number. */
502 static int chars_per_number
= 5;
504 /* Used when widening the first column to accommodate numbers -- only
505 needed when printing files in parallel. Includes width of both the
506 number and the number_separator. */
507 static int number_width
;
509 /* Buffer sprintf uses to format a line number. */
510 static char *number_buff
;
512 /* (-v) True means unprintable characters are printed as escape sequences.
513 control-g becomes \007. */
514 static int use_esc_sequence
= FALSE
;
516 /* (-c) True means unprintable characters are printed as control prefixes.
517 control-g becomes ^G. */
518 static int use_cntrl_prefix
= FALSE
;
520 /* (-d) True means output is double spaced. */
521 static int double_space
= FALSE
;
523 /* Number of files opened initially in init_files. Should be 1
524 unless we're printing multiple files in parallel. */
525 static int total_files
= 0;
527 /* (-r) True means don't complain if we can't open a file. */
528 static int ignore_failed_opens
= FALSE
;
530 /* (-s) True means we separate columns with a specified string.
531 -s option does not affect line truncation nor column alignment. */
532 static int use_col_separator
= FALSE
;
534 /* String used to separate columns if the -s option has been specified.
535 Default without -s but together with one of the column options
536 -a|COLUMN|-m is a `space' and with the -j option a `tab'. */
537 static char *col_sep_string
;
538 static int col_sep_length
= 0;
539 static char *column_separator
= " ";
540 static char *line_separator
= "\t";
542 /* Number of separator characters waiting to be printed as soon as we
543 know that we have any input remaining to be printed. */
544 static int separators_not_printed
;
546 /* Position we need to pad to, as soon as we know that we have input
547 remaining to be printed. */
548 static int padding_not_printed
;
550 /* True means we should pad the end of the page. Remains false until we
551 know we have a page to print. */
552 static int pad_vertically
;
554 /* (-h) String of characters used in place of the filename in the header. */
555 static char *custom_header
;
557 /* String containing the date, filename or custom header, and "Page ". */
560 static int *clump_buff
;
562 /* If nonzero, display usage information and exit. */
563 static int show_help
;
565 /* If nonzero, print the version on standard output then exit. */
566 static int show_version
;
568 /* True means we read the line no. lines_per_body in skip_read
569 called by skip_to_page. That variable controls the coincidence of a
570 "FF set by hand" and "full_page_printed", see above the definition of
572 static int last_line
= FALSE
;
574 /* If nonzero, print a non-variable date and time with the header
575 -h HEADER using pr test-suite */
576 static int test_suite
;
578 static struct option
const long_options
[] =
580 {"help", no_argument
, &show_help
, 1},
581 {"version", no_argument
, &show_version
, 1},
582 {"test", no_argument
, &test_suite
, 1},
583 {"pages", required_argument
, NULL
, CHAR_MAX
+ 1},
584 {"columns", required_argument
, NULL
, CHAR_MAX
+ 2},
585 {"across", no_argument
, NULL
, 'a'},
586 {"show-control-chars", no_argument
, NULL
, 'c'},
587 {"double-space", no_argument
, NULL
, 'd'},
588 {"expand-tabs", optional_argument
, NULL
, 'e'},
589 {"form-feed", no_argument
, NULL
, 'f'},
590 {"header", required_argument
, NULL
, 'h'},
591 {"output-tabs", optional_argument
, NULL
, 'i'},
592 {"join-lines", no_argument
, NULL
, 'j'},
593 {"length", required_argument
, NULL
, 'l'},
594 {"merge", no_argument
, NULL
, 'm'},
595 {"number-lines", optional_argument
, NULL
, 'n'},
596 {"first-line-number", required_argument
, NULL
, 'N'},
597 {"indent", required_argument
, NULL
, 'o'},
598 {"no-file-warnings", no_argument
, NULL
, 'r'},
599 {"separator", optional_argument
, NULL
, 's'},
600 {"omit-header", no_argument
, NULL
, 't'},
601 {"omit-pagination", no_argument
, NULL
, 'T'},
602 {"show-nonprinting", no_argument
, NULL
, 'v'},
603 {"width", required_argument
, NULL
, 'w'},
607 /* Return the number of columns that have either an open file or
611 cols_ready_to_print (void)
618 for (q
= column_vector
, i
= 0; i
< columns
; ++q
, ++i
)
619 if (q
->status
== OPEN
||
620 q
->status
== FF_FOUND
|| /* With -b: To print a header only */
621 (storing_columns
&& q
->lines_stored
> 0 && q
->lines_to_print
> 0))
626 /* Estimate first_ / last_page_number
627 using option +FIRST_PAGE:LAST_PAGE */
630 first_last_page (char *pages
)
636 error (0, 0, _("invalid range of page numbers: `%s'"), pages
);
640 str1
= strchr (pages
, ':');
646 if (xstrtol (pages
, NULL
, 10, &tmp_long
, "") != LONGINT_OK
647 || tmp_long
<= 0 || tmp_long
> INT_MAX
)
648 error (EXIT_FAILURE
, 0, _("invalid starting page number: `%s'"),
650 first_page_number
= (int) tmp_long
;
658 if (xstrtol (str1
+ 1, NULL
, 10, &tmp_long
, "") != LONGINT_OK
659 || tmp_long
<= 0 || tmp_long
> INT_MAX
)
660 error (EXIT_FAILURE
, 0, _("invalid ending page number: `%s'"),
662 last_page_number
= (int) tmp_long
;
665 if (first_page_number
> last_page_number
)
666 error (EXIT_FAILURE
, 0,
667 _("starting page number is larger than ending page number"));
670 /* Estimate length of col_sep_string with option -s[STRING] */
673 separator_string (const char *optarg_S
)
675 col_sep_length
= (int) strlen (optarg_S
);
676 col_sep_string
= (char *) xmalloc (col_sep_length
+ 1);
677 strcpy (col_sep_string
, optarg_S
);
681 main (int argc
, char **argv
)
688 program_name
= argv
[0];
689 setlocale (LC_ALL
, "");
690 bindtextdomain (PACKAGE
, LOCALEDIR
);
691 textdomain (PACKAGE
);
694 file_names
= (argc
> 1
695 ? (char **) xmalloc ((argc
- 1) * sizeof (char *))
700 c
= getopt_long (argc
, argv
,
701 "-0123456789abcde::fFh:i::jl:mn::N:o:rs::tTvw:",
703 if (c
== 1) /* Non-option argument. */
714 file_names
[n_files
++] = optarg
;
721 accum
= accum
* 10 + c
- '0';
729 explicit_columns
= TRUE
;
743 case 0: /* getopt long option */
746 case CHAR_MAX
+ 1: /* --pages=FIRST_PAGE[:LAST_PAGE] */
747 first_last_page (optarg
);
750 case CHAR_MAX
+ 2: /* --columns=COLUMN */
753 if (xstrtol (optarg
, NULL
, 10, &tmp_long
, "") != LONGINT_OK
754 || tmp_long
<= 0 || tmp_long
> INT_MAX
)
756 error (EXIT_FAILURE
, 0,
757 _("`--columns=COLUMN' invalid number of columns: `%s'"),
760 columns
= (int) tmp_long
;
765 print_across_flag
= TRUE
;
766 storing_columns
= FALSE
;
769 balance_columns
= TRUE
;
772 use_cntrl_prefix
= TRUE
;
779 getoptarg (optarg
, 'e', &input_tab_char
,
780 &chars_per_input_tab
);
781 /* Could check tab width > 0. */
782 untabify_input
= TRUE
;
786 use_form_feed
= TRUE
;
789 custom_header
= optarg
;
790 standard_header
= FALSE
;
794 getoptarg (optarg
, 'i', &output_tab_char
,
795 &chars_per_output_tab
);
796 /* Could check tab width > 0. */
797 tabify_output
= TRUE
;
805 if (xstrtol (optarg
, NULL
, 10, &tmp_long
, "") != LONGINT_OK
806 || tmp_long
<= 0 || tmp_long
> INT_MAX
)
808 error (EXIT_FAILURE
, 0,
809 _("`-l PAGE_LENGTH' invalid number of lines: `%s'"),
812 lines_per_page
= (int) tmp_long
;
816 parallel_files
= TRUE
;
817 storing_columns
= FALSE
;
820 numbered_lines
= TRUE
;
822 getoptarg (optarg
, 'n', &number_separator
,
829 if (xstrtol (optarg
, NULL
, 10, &tmp_long
, "") != LONGINT_OK
830 || tmp_long
> INT_MAX
)
832 error (EXIT_FAILURE
, 0,
833 _("`-N NUMBER' invalid starting line number: `%s'"),
836 start_line_num
= (int) tmp_long
;
842 if (xstrtol (optarg
, NULL
, 10, &tmp_long
, "") != LONGINT_OK
843 || tmp_long
< 0 || tmp_long
> INT_MAX
)
844 error (EXIT_FAILURE
, 0,
845 _("`-o MARGIN' invalid line offset: `%s'"), optarg
);
846 chars_per_margin
= (int) tmp_long
;
850 ignore_failed_opens
= TRUE
;
853 use_col_separator
= TRUE
;
855 separator_string (optarg
);
866 use_esc_sequence
= TRUE
;
869 truncate_lines
= TRUE
;
872 if (xstrtol (optarg
, NULL
, 10, &tmp_long
, "") != LONGINT_OK
873 || tmp_long
<= 0 || tmp_long
> INT_MAX
)
874 error (EXIT_FAILURE
, 0,
875 _("`-w PAGE_WIDTH' invalid column number: `%s'"), optarg
);
876 chars_per_line
= (int) tmp_long
;
887 printf ("pr (%s) %s\n", GNU_PACKAGE
, VERSION
);
894 if (parallel_files
&& explicit_columns
)
895 error (EXIT_FAILURE
, 0,
896 _("Cannot specify number of columns when printing in parallel."));
898 if (parallel_files
&& print_across_flag
)
899 error (EXIT_FAILURE
, 0,
900 _("Cannot specify both printing across and printing in parallel."));
902 for (; optind
< argc
; optind
++)
904 file_names
[n_files
++] = argv
[optind
];
909 /* No file arguments specified; read from standard input. */
910 print_files (0, NULL
);
915 print_files (n_files
, file_names
);
919 for (i
= 0; i
< n_files
; i
++)
920 print_files (1, &file_names
[i
]);
926 if (have_read_stdin
&& fclose (stdin
) == EOF
)
927 error (EXIT_FAILURE
, errno
, _("standard input"));
928 if (ferror (stdout
) || fclose (stdout
) == EOF
)
929 error (EXIT_FAILURE
, errno
, _("write error"));
930 if (failed_opens
> 0)
935 /* Parse options of the form -scNNN.
937 Example: -nck, where 'n' is the option, c is the optional number
938 separator, and k is the optional width of the field used when printing
942 getoptarg (char *arg
, char switch_char
, char *character
, int *number
)
949 if (xstrtol (arg
, NULL
, 10, &tmp_long
, "") != LONGINT_OK
950 || tmp_long
<= 0 || tmp_long
> INT_MAX
)
953 _("`-%c' extra characters or invalid number in the argument: `%s'"),
957 *number
= (int) tmp_long
;
961 /* Set parameters related to formatting. */
964 init_parameters (int number_of_files
)
966 int chars_used_by_number
= 0;
970 lines_per_header
= 3;
971 lines_per_footer
= 0;
974 lines_per_body
= lines_per_page
- lines_per_header
- lines_per_footer
;
975 if (lines_per_body
<= 0)
980 if (extremities
== FALSE
)
981 lines_per_body
= lines_per_page
;
984 lines_per_body
= lines_per_body
/ 2;
986 /* If input is stdin, cannot print parallel files. BSD dumps core
988 if (number_of_files
== 0)
989 parallel_files
= FALSE
;
992 columns
= number_of_files
;
994 /* One file, multi columns down: -b option is set to get a consistent
995 formulation with "FF set by hand" in input files. */
997 balance_columns
= TRUE
;
999 /* Tabification is assumed for multiple columns. */
1002 if (!use_col_separator
)
1004 /* Use default separator */
1006 col_sep_string
= line_separator
;
1008 col_sep_string
= column_separator
;
1010 use_col_separator
= TRUE
;
1013 truncate_lines
= TRUE
;
1014 untabify_input
= TRUE
;
1015 tabify_output
= TRUE
;
1018 storing_columns
= FALSE
;
1020 /* -j dominates -w in any case */
1022 truncate_lines
= FALSE
;
1026 line_count
= start_line_num
;
1027 if (number_separator
== input_tab_char
)
1029 number_width
= chars_per_number
+
1030 TAB_WIDTH (chars_per_input_tab
,
1031 (chars_per_margin
+ chars_per_number
));
1034 number_width
= chars_per_number
+ 1;
1035 /* The number is part of the column width unless we are
1036 printing files in parallel. */
1038 chars_used_by_number
= number_width
;
1041 chars_per_column
= (chars_per_line
- chars_used_by_number
-
1042 (columns
- 1) * col_sep_length
) / columns
;
1044 if (chars_per_column
< 1)
1045 error (EXIT_FAILURE
, 0, _("page width too narrow"));
1049 if (number_buff
!= NULL
)
1051 number_buff
= (char *) xmalloc (2 * chars_per_number
);
1054 /* Pick the maximum between the tab width and the width of an
1056 if (clump_buff
!= NULL
)
1058 clump_buff
= (int *) xmalloc ((chars_per_input_tab
> 4
1059 ? chars_per_input_tab
: 4) * sizeof (int));
1062 /* Open the necessary files,
1063 maintaining a COLUMN structure for each column.
1065 With multiple files, each column p has a different p->fp.
1066 With single files, each column p has the same p->fp.
1067 Return 1 if (number_of_files > 0) and no files can be opened,
1070 With each column/file p, p->full_page_printed is initialized,
1071 see also open_file. */
1074 init_fps (int number_of_files
, char **av
)
1083 if (column_vector
!= NULLCOL
)
1084 free ((char *) column_vector
);
1085 column_vector
= (COLUMN
*) xmalloc (columns
* sizeof (COLUMN
));
1089 files_left
= number_of_files
;
1090 for (p
= column_vector
; files_left
--; ++p
, ++av
)
1092 if (open_file (*av
, p
) == 0)
1100 init_header ("", -1);
1105 if (number_of_files
> 0)
1107 if (open_file (*av
, p
) == 0)
1109 init_header (*av
, fileno (p
->fp
));
1110 p
->lines_stored
= 0;
1114 p
->name
= _("standard input");
1116 have_read_stdin
= TRUE
;
1118 p
->full_page_printed
= FALSE
;
1120 init_header ("", -1);
1121 p
->lines_stored
= 0;
1124 firstname
= p
->name
;
1126 for (i
= columns
- 1, ++p
; i
; --i
, ++p
)
1128 p
->name
= firstname
;
1131 p
->full_page_printed
= FALSE
;
1132 p
->lines_stored
= 0;
1135 files_ready_to_read
= total_files
;
1139 /* Determine print_func and char_func, the functions
1140 used by each column for printing and/or storing.
1142 Determine the horizontal position desired when we begin
1143 printing a column (p->start_position). */
1151 h
= chars_per_margin
;
1153 if (!truncate_lines
)
1157 /* When numbering lines of parallel files, we enlarge the
1158 first column to accomodate the number. Looks better than
1159 the Sys V approach. */
1160 if (parallel_files
&& numbered_lines
)
1161 h_next
= h
+ chars_per_column
+ number_width
;
1163 h_next
= h
+ chars_per_column
;
1166 /* Enlarge p->start_position of first column to use the same form of
1167 padding_not_printed with all columns. */
1168 h
= h
+ col_sep_length
;
1170 /* This loop takes care of all but the rightmost column. */
1172 for (p
= column_vector
, i
= 1; i
< columns
; ++p
, ++i
)
1174 if (storing_columns
) /* One file, multi columns down. */
1176 p
->char_func
= store_char
;
1177 p
->print_func
= print_stored
;
1180 /* One file, multi columns across; or parallel files. */
1182 p
->char_func
= print_char
;
1183 p
->print_func
= read_line
;
1186 /* Number only the first column when printing files in
1188 p
->numbered
= numbered_lines
&& (!parallel_files
|| i
== 1);
1189 p
->start_position
= h
;
1191 /* If we don't truncate lines, all start_positions are
1192 ANYWHERE, except the first column's start_position when
1195 if (!truncate_lines
)
1202 h
= h_next
+ col_sep_length
;
1203 h_next
= h
+ chars_per_column
;
1207 /* The rightmost column.
1209 Doesn't need to be stored unless we intend to balance
1210 columns on the last page. */
1211 if (storing_columns
&& balance_columns
)
1213 p
->char_func
= store_char
;
1214 p
->print_func
= print_stored
;
1218 p
->char_func
= print_char
;
1219 p
->print_func
= read_line
;
1222 p
->numbered
= numbered_lines
&& (!parallel_files
|| i
== 1);
1223 p
->start_position
= h
;
1226 /* Open a file. Return nonzero if successful, zero if failed.
1228 With each file p, p->full_page_printed is initialized,
1229 see also init_fps. */
1232 open_file (char *name
, COLUMN
*p
)
1234 if (STREQ (name
, "-"))
1236 p
->name
= _("standard input");
1238 have_read_stdin
= 1;
1243 p
->fp
= fopen (name
, "r");
1248 if (!ignore_failed_opens
)
1249 error (0, errno
, "%s", name
);
1253 p
->full_page_printed
= FALSE
;
1258 /* Close the file in P.
1260 If we aren't dealing with multiple files in parallel, we change
1261 the status of all columns in the column list to reflect the close. */
1264 close_file (COLUMN
*p
)
1269 if (p
->status
== CLOSED
)
1272 error (EXIT_FAILURE
, errno
, "%s", p
->name
);
1273 if (p
->fp
!= stdin
&& fclose (p
->fp
) == EOF
)
1274 error (EXIT_FAILURE
, errno
, "%s", p
->name
);
1276 if (!parallel_files
)
1278 for (q
= column_vector
, i
= columns
; i
; ++q
, --i
)
1281 if (q
->lines_stored
== 0)
1283 q
->lines_to_print
= 0;
1290 p
->lines_to_print
= 0;
1293 --files_ready_to_read
;
1296 /* Put a file on hold until we start a new page,
1297 since we've hit a form feed.
1299 If we aren't dealing with parallel files, we must change the
1300 status of all columns in the column list. */
1303 hold_file (COLUMN
*p
)
1308 if (!parallel_files
)
1309 for (q
= column_vector
, i
= columns
; i
; ++q
, --i
)
1311 if (storing_columns
)
1312 q
->status
= FF_FOUND
;
1314 q
->status
= ON_HOLD
;
1317 p
->status
= ON_HOLD
;
1319 p
->lines_to_print
= 0;
1320 --files_ready_to_read
;
1323 /* Undo hold_file -- go through the column list and change any
1324 ON_HOLD columns to OPEN. Used at the end of each page. */
1332 for (p
= column_vector
; i
; --i
, ++p
)
1333 if (p
->status
== ON_HOLD
)
1336 files_ready_to_read
++;
1339 if (storing_columns
)
1340 files_ready_to_read
= 1;
1343 /* Print a single file, or multiple files in parallel.
1345 Set up the list of columns, opening the necessary files.
1346 Allocate space for storing columns, if necessary.
1347 Skip to first_page_number, if user has asked to skip leading pages.
1348 Determine which functions are appropriate to store/print lines
1350 Print the file(s). */
1353 print_files (int number_of_files
, char **av
)
1355 init_parameters (number_of_files
);
1356 if (init_fps (number_of_files
, av
))
1358 if (storing_columns
)
1361 if (first_page_number
> 1)
1363 if (!skip_to_page (first_page_number
))
1366 page_number
= first_page_number
;
1373 line_number
= line_count
;
1374 while (print_page ())
1378 /* Estimate the number of characters taken up by a short format date and
1379 time: "yy-mm-dd HH:MM" and: "Page NNNN". */
1380 #define CHARS_FOR_DATE_AND_PAGE 23
1382 /* Initialize header information.
1383 If DESC is non-negative, it is a file descriptor open to
1384 FILENAME for reading.
1386 Allocate space for a header string,
1387 Determine the time, insert file name or user-specified string.
1388 Make use of a centered header with left-hand-side truncation marked by
1389 a '*` in front, if necessary. */
1392 init_header (char *filename
, int desc
)
1394 int chars_per_middle
, chars_free
, lhs_blanks
, rhs_blanks
;
1396 char *no_middle
= "";
1400 char *datim
= "- Date/Time --";
1402 if (filename
== NULL
)
1407 header
= (char *) xmalloc (chars_per_line
+ 1);
1409 if (!standard_header
&& *custom_header
== '\0')
1410 sprintf (header
, "%s", " "); /* blank line header */
1413 #define T_BUF_FMT "%Y-%m-%d %H:%M" /* date/time short format */
1414 #define T_BUF_SIZE 17 /* FIXME: using a literal here is fragile. */
1415 char t_buf
[T_BUF_SIZE
];
1417 /* If parallel files or standard input, use current time. */
1418 if (desc
< 0 || STREQ (filename
, "-") || fstat (desc
, &st
))
1419 st
.st_mtime
= time (NULL
);
1421 tmptr
= localtime (&st
.st_mtime
);
1422 strftime (t_buf
, T_BUF_SIZE
, T_BUF_FMT
, tmptr
);
1424 chars_per_middle
= chars_per_line
- CHARS_FOR_DATE_AND_PAGE
;
1425 if (chars_per_middle
< 3)
1427 header_text
= no_middle
; /* Nothing free for a heading */
1433 header_text
= standard_header
? f
: custom_header
;
1434 chars_free
= chars_per_middle
- (int) strlen (header_text
);
1437 lhs_blanks
= chars_free
/ 2; /* text not truncated */
1438 rhs_blanks
= chars_free
- lhs_blanks
;
1441 { /* lhs truncation */
1442 header_text
= header_text
- chars_free
+ 2;
1449 sprintf (header
, _("%s%*s%s%*sPage"), (test_suite
? datim
: t_buf
),
1450 lhs_blanks
, " ", header_text
, rhs_blanks
, " ");
1454 /* Set things up for printing a page
1456 Scan through the columns ...
1457 Determine which are ready to print
1458 (i.e., which have lines stored or open files)
1459 Set p->lines_to_print appropriately
1460 (to p->lines_stored if we're storing, or lines_per_body
1461 if we're reading straight from the file)
1462 Keep track of this total so we know when to stop printing */
1470 if (storing_columns
)
1473 for (j
= columns
- 1, p
= column_vector
; j
; --j
, ++p
)
1475 p
->lines_to_print
= p
->lines_stored
;
1479 if (balance_columns
)
1481 p
->lines_to_print
= p
->lines_stored
;
1483 /* Since we're not balancing columns, we don't need to store
1484 the rightmost column. Read it straight from the file. */
1487 if (p
->status
== OPEN
)
1489 p
->lines_to_print
= lines_per_body
;
1492 p
->lines_to_print
= 0;
1496 for (j
= columns
, p
= column_vector
; j
; --j
, ++p
)
1497 if (p
->status
== OPEN
)
1499 p
->lines_to_print
= lines_per_body
;
1502 p
->lines_to_print
= 0;
1505 /* Align empty columns and print separators.
1506 Empty columns will be formed by files with status ON_HOLD or CLOSED
1507 when printing multiple files in parallel. */
1510 align_column (COLUMN
*p
)
1512 padding_not_printed
= p
->start_position
;
1513 if (padding_not_printed
- col_sep_length
> 0)
1515 pad_across_to (padding_not_printed
- col_sep_length
);
1516 padding_not_printed
= ANYWHERE
;
1519 if (use_col_separator
)
1520 print_sep_string ();
1523 add_line_number (p
);
1528 As long as there are lines left on the page and columns ready to print,
1529 Scan across the column list
1530 if the column has stored lines or the file is open
1531 pad to the appropriate spot
1533 pad the remainder of the page with \n or \f as requested
1534 reset the status of all files -- any files which where on hold because
1535 of formfeeds are now put back into the lineup. */
1541 int lines_left_on_page
;
1544 /* Used as an accumulator (with | operator) of successive values of
1545 pad_vertically. The trick is to set pad_vertically
1546 to zero before each run through the inner loop, then after that
1547 loop, it tells us whether a line was actually printed (whether a
1548 newline needs to be output -- or two for double spacing). But those
1549 values have to be accumulated (in pv) so we can invoke pad_down
1550 properly after the outer loop completes. */
1555 if (cols_ready_to_print () == 0)
1559 print_a_header
= TRUE
;
1561 /* Don't pad unless we know a page was printed. */
1562 pad_vertically
= FALSE
;
1565 lines_left_on_page
= lines_per_body
;
1567 lines_left_on_page
*= 2;
1569 while (lines_left_on_page
> 0 && cols_ready_to_print () > 0)
1571 output_position
= 0;
1572 spaces_not_printed
= 0;
1573 separators_not_printed
= 0;
1574 pad_vertically
= FALSE
;
1575 align_empty_cols
= FALSE
;
1578 for (j
= 1, p
= column_vector
; j
<= columns
; ++j
, ++p
)
1581 if (p
->lines_to_print
> 0 || p
->status
== FF_FOUND
)
1584 padding_not_printed
= p
->start_position
;
1585 if (!(p
->print_func
) (p
))
1586 read_rest_of_line (p
);
1587 pv
|= pad_vertically
;
1589 --p
->lines_to_print
;
1590 if (p
->lines_to_print
<= 0)
1592 if (cols_ready_to_print () <= 0)
1596 /* File p changed its status to ON_HOLD or CLOSED */
1597 if (parallel_files
&& p
->status
!= OPEN
)
1600 align_empty_cols
= TRUE
;
1601 else if (p
->status
== CLOSED
||
1602 (p
->status
== ON_HOLD
&& FF_only
))
1606 else if (parallel_files
)
1608 /* File status ON_HOLD or CLOSED */
1610 align_empty_cols
= TRUE
;
1615 /* We need it also with an empty column */
1616 if (use_col_separator
)
1617 ++separators_not_printed
;
1623 --lines_left_on_page
;
1626 if (cols_ready_to_print () <= 0 && !extremities
)
1629 if (double_space
&& pv
)
1632 --lines_left_on_page
;
1636 if (lines_left_on_page
== 0)
1637 for (j
= 1, p
= column_vector
; j
<= columns
; ++j
, ++p
)
1638 if (p
->status
== OPEN
)
1639 p
->full_page_printed
= TRUE
;
1641 pad_vertically
= pv
;
1643 if (pad_vertically
&& extremities
)
1644 pad_down (lines_left_on_page
+ lines_per_footer
);
1645 else if (keep_FF
&& print_a_FF
)
1651 if (last_page_number
&& page_number
> last_page_number
)
1652 return FALSE
; /* Stop printing with LAST_PAGE */
1654 reset_status (); /* Change ON_HOLD to OPEN. */
1656 return TRUE
; /* More pages to go. */
1659 /* Allocate space for storing columns.
1661 This is necessary when printing multiple columns from a single file.
1662 Lines are stored consecutively in buff, separated by '\0'.
1664 The following doesn't apply any longer - any tuning possible?
1665 (We can't use a fixed offset since with the '-s' flag lines aren't
1668 We maintain a list (line_vector) of pointers to the beginnings
1669 of lines in buff. We allocate one more than the number of lines
1670 because the last entry tells us the index of the last character,
1671 which we need to know in order to print the last line in buff. */
1674 init_store_cols (void)
1676 int total_lines
= lines_per_body
* columns
;
1677 int chars_if_truncate
= total_lines
* (chars_per_column
+ 1);
1679 if (line_vector
!= NULL
)
1680 free ((int *) line_vector
);
1681 /* FIXME: here's where it was allocated. */
1682 line_vector
= (int *) xmalloc ((total_lines
+ 1) * sizeof (int *));
1684 if (end_vector
!= NULL
)
1685 free ((int *) end_vector
);
1686 end_vector
= (int *) xmalloc (total_lines
* sizeof (int *));
1690 buff_allocated
= (use_col_separator
1691 ? 2 * chars_if_truncate
1692 : chars_if_truncate
); /* Tune this. */
1693 buff
= (char *) xmalloc (buff_allocated
);
1696 /* Store all but the rightmost column.
1697 (Used when printing a single file in multiple downward columns)
1700 set p->current_line to be the index in line_vector of the
1701 first line in the column
1702 For each line in the column
1703 store the line in buff
1704 add to line_vector the index of the line's first char
1705 buff_start is the index in buff of the first character in the
1709 store_columns (void)
1714 int last_col
; /* The rightmost column which will be saved in buff */
1720 if (balance_columns
)
1723 last_col
= columns
- 1;
1725 for (i
= 1, p
= column_vector
; i
<= last_col
; ++i
, ++p
)
1726 p
->lines_stored
= 0;
1728 for (i
= 1, p
= column_vector
; i
<= last_col
&& files_ready_to_read
;
1731 p
->current_line
= line
;
1732 for (j
= lines_per_body
; j
&& files_ready_to_read
; --j
)
1734 if (p
->status
== OPEN
) /* Redundant. Clean up. */
1739 read_rest_of_line (p
);
1741 if (p
->status
== OPEN
1742 || buff_start
!= buff_current
)
1745 line_vector
[line
] = buff_start
;
1746 end_vector
[line
++] = input_position
;
1747 buff_start
= buff_current
;
1752 /* Keep track of the location of the last char in buff. */
1753 line_vector
[line
] = buff_start
;
1755 if (balance_columns
&& p
->lines_stored
!= lines_per_body
)
1760 balance (int total_stored
)
1766 for (i
= 1, p
= column_vector
; i
<= columns
; ++i
, ++p
)
1768 lines
= total_stored
/ columns
;
1769 if (i
<= total_stored
% columns
)
1772 p
->lines_stored
= lines
;
1773 p
->current_line
= first_line
;
1775 first_line
+= lines
;
1779 /* Store a character in the buffer. */
1784 if (buff_current
>= buff_allocated
)
1786 /* May be too generous. */
1787 buff_allocated
= 2 * buff_allocated
;
1788 buff
= (char *) xrealloc (buff
, buff_allocated
* sizeof (char));
1790 buff
[buff_current
++] = (char) c
;
1794 add_line_number (COLUMN
*p
)
1799 sprintf (number_buff
, "%*d", chars_per_number
, line_number
++);
1801 for (i
= chars_per_number
; i
> 0; i
--)
1802 (p
->char_func
) ((int) *s
++);
1804 if (number_separator
== input_tab_char
)
1806 i
= number_width
- chars_per_number
;
1808 (p
->char_func
) ((int) ' ');
1811 (p
->char_func
) ((int) number_separator
);
1813 if (truncate_lines
&& !parallel_files
)
1814 input_position
+= number_width
;
1817 /* Print (or store) padding until the current horizontal position
1821 pad_across_to (int position
)
1823 register int h
= output_position
;
1826 spaces_not_printed
= position
- output_position
;
1829 while (++h
<= position
)
1831 output_position
= position
;
1835 /* Pad to the bottom of the page.
1837 If the user has requested a formfeed, use one.
1838 Otherwise, use newlines. */
1841 pad_down (int lines
)
1848 for (i
= lines
; i
; --i
)
1852 /* Read the rest of the line.
1854 Read from the current column's file until an end of line is
1855 hit. Used when we've truncated a line and we no longer need
1856 to print or store its characters. */
1859 read_rest_of_line (COLUMN
*p
)
1864 while ((c
= getc (f
)) != '\n')
1868 if ((c
= getc (f
)) != '\n')
1883 /* Read a line with skip_to_page.
1885 Read from the current column's file until an end of line is
1886 hit. Used when we read full lines to skip pages.
1887 With skip_to_page we have to check for FF-coincidence which is done
1888 in function read_line otherwise.
1889 Count lines of skipped pages to find the line number of 1st page
1890 printed relative to 1st line of input file (start_line_num). */
1893 skip_read (COLUMN
*p
, int column_number
)
1897 int i
, single_ff
= FALSE
;
1900 /* Read 1st character in a line or any character succeeding a FF */
1901 if ((c
= getc (f
)) == '\f' && p
->full_page_printed
)
1902 /* A FF-coincidence with a previous full_page_printed.
1903 To avoid an additional empty page, eliminate the FF */
1904 if ((c
= getc (f
)) == '\n')
1907 p
->full_page_printed
= FALSE
;
1909 /* 1st character a FF means a single FF without any printable
1910 characters. Don't count it as a line with -n option. */
1914 /* Preparing for a FF-coincidence: Maybe we finish that page
1915 without a FF found */
1917 p
->full_page_printed
= TRUE
;
1923 /* No FF-coincidence possible,
1924 no catching up of a FF-coincidence with next page */
1927 if (!parallel_files
)
1928 for (q
= column_vector
, i
= columns
; i
; ++q
, --i
)
1929 q
->full_page_printed
= FALSE
;
1931 p
->full_page_printed
= FALSE
;
1934 if ((c
= getc (f
)) != '\n')
1948 if ((!parallel_files
|| column_number
== 1) && !single_ff
)
1952 /* If we're tabifying output,
1954 When print_char encounters white space it keeps track
1955 of our desired horizontal position and delays printing
1956 until this function is called. */
1959 print_white_space (void)
1962 register int h_old
= output_position
;
1963 register int goal
= h_old
+ spaces_not_printed
;
1965 while (goal
- h_old
> 1
1966 && (h_new
= POS_AFTER_TAB (chars_per_output_tab
, h_old
)) <= goal
)
1968 putchar (output_tab_char
);
1971 while (++h_old
<= goal
)
1974 output_position
= goal
;
1975 spaces_not_printed
= 0;
1978 /* Print column separators.
1980 We keep a count until we know that we'll be printing a line,
1981 then print_sep_string() is called. */
1987 int l
= col_sep_length
;
1991 if (spaces_not_printed
> 0)
1992 print_white_space ();
1994 for (; separators_not_printed
> 0; --separators_not_printed
)
1998 output_position
+= col_sep_length
;
2002 /* Print (or store, depending on p->char_func) a clump of N
2006 print_clump (COLUMN
*p
, int n
, int *clump
)
2009 (p
->char_func
) (*clump
++);
2012 /* Print a character.
2014 Update the following comment: process-char hasn't been used any
2016 If we're tabifying, all tabs have been converted to spaces by
2017 process_char(). Keep a count of consecutive spaces, and when
2018 a nonspace is encountered, call print_white_space() to print the
2019 required number of tabs and spaces. */
2028 ++spaces_not_printed
;
2031 else if (spaces_not_printed
> 0)
2032 print_white_space ();
2034 /* Nonprintables are assumed to have width 0, except '\b'. */
2046 /* Skip to page PAGE before printing. */
2049 skip_to_page (int page
)
2054 for (n
= 1; n
< page
; ++n
)
2056 for (i
= 1; i
< lines_per_body
; ++i
)
2058 for (j
= 1, p
= column_vector
; j
<= columns
; ++j
, ++p
)
2059 if (p
->status
== OPEN
)
2063 for (j
= 1, p
= column_vector
; j
<= columns
; ++j
, ++p
)
2064 if (p
->status
== OPEN
)
2067 if (storing_columns
) /* change FF_FOUND to ON_HOLD */
2068 for (j
= 1, p
= column_vector
; j
<= columns
; ++j
, ++p
)
2069 p
->status
= ON_HOLD
;
2074 return files_ready_to_read
> 0;
2079 Formfeeds are assumed to use up two lines at the beginning of
2086 fprintf (stdout
, "\n\n");
2088 output_position
= 0;
2089 pad_across_to (chars_per_margin
);
2090 print_white_space ();
2092 if (!standard_header
&& *custom_header
== '\0')
2093 fprintf (stdout
, "%s\n\n\n", header
);
2095 fprintf (stdout
, "%s%5d\n\n\n", header
, page_number
++);
2097 print_a_header
= FALSE
;
2098 output_position
= 0;
2101 /* Print (or store, if p->char_func is store_char()) a line.
2103 Read a character to determine whether we have a line or not.
2104 (We may hit EOF, \n, or \f)
2106 Once we know we have a line,
2107 set pad_vertically = TRUE, meaning it's safe
2108 to pad down at the end of the page, since we do have a page.
2109 print a header if needed.
2110 pad across to padding_not_printed if needed.
2111 print any separators which need to be printed.
2112 print a line number if it needs to be printed.
2114 Print the clump which corresponds to the first character.
2116 Enter a loop and keep printing until an end of line condition
2117 exists, or until we exceed chars_per_column.
2119 Return FALSE if we exceed chars_per_column before reading
2120 an end of line character, TRUE otherwise. */
2123 read_line (COLUMN
*p
)
2125 register int c
, chars
;
2126 int last_input_position
;
2130 /* Suppress `used before initialized' warning. */
2135 /* read 1st character in each line or any character succeeding a FF: */
2138 last_input_position
= input_position
;
2140 if (c
== '\f' && p
->full_page_printed
)
2141 if ((c
= getc (p
->fp
)) == '\n')
2143 p
->full_page_printed
= FALSE
;
2148 if ((c
= getc (p
->fp
)) != '\n')
2151 if (print_a_header
&& !storing_columns
)
2153 pad_vertically
= TRUE
;
2166 chars
= char_to_clump (c
);
2169 if (truncate_lines
&& input_position
> chars_per_column
)
2171 input_position
= last_input_position
;
2175 if (p
->char_func
!= store_char
)
2177 pad_vertically
= TRUE
;
2179 if (print_a_header
&& !storing_columns
)
2182 if (parallel_files
&& align_empty_cols
)
2184 /* We have to align empty columns at the beginning of a line. */
2185 k
= separators_not_printed
;
2186 separators_not_printed
= 0;
2187 for (j
= 1, q
= column_vector
; j
<= k
; ++j
, ++q
)
2190 separators_not_printed
+= 1;
2192 padding_not_printed
= p
->start_position
;
2194 spaces_not_printed
= chars_per_column
;
2196 spaces_not_printed
= 0;
2197 align_empty_cols
= FALSE
;
2200 if (padding_not_printed
- col_sep_length
> 0)
2202 pad_across_to (padding_not_printed
- col_sep_length
);
2203 padding_not_printed
= ANYWHERE
;
2206 if (use_col_separator
)
2207 print_sep_string ();
2211 add_line_number (p
);
2217 print_clump (p
, chars
, clump_buff
);
2228 if ((c
= getc (p
->fp
)) != '\n')
2239 last_input_position
= input_position
;
2240 chars
= char_to_clump (c
);
2241 if (truncate_lines
&& input_position
> chars_per_column
)
2243 input_position
= last_input_position
;
2247 print_clump (p
, chars
, clump_buff
);
2251 /* Print a line from buff.
2253 If this function has been called, we know we have "something to
2254 print". But it remains to be seen whether we have a real text page
2255 or an empty page (a single form feed) with/without a header only.
2256 Therefore first we set pad_vertically to TRUE and print a header
2258 If FF_FOUND and we are using -t|-T option we omit any newline by
2259 setting pad_vertically to FALSE (see print_page).
2260 Otherwise we pad across if necessary, print separators if necessary
2261 and text of COLUMN *p.
2263 Return TRUE, meaning there is no need to call read_rest_of_line. */
2266 print_stored (COLUMN
*p
)
2271 int line
= p
->current_line
++;
2272 register char *first
= &buff
[line_vector
[line
]];
2274 UMR: Uninitialized memory read:
2275 * This is occurring while in:
2276 print_stored [pr.c:2239]
2277 * Reading 4 bytes from 0x5148c in the heap.
2278 * Address 0x5148c is 4 bytes into a malloc'd block at 0x51488 of 676 bytes
2279 * This block was allocated from:
2281 xmalloc [xmalloc.c:94]
2282 init_store_cols [pr.c:1648]
2284 register char *last
= &buff
[line_vector
[line
+ 1]];
2286 pad_vertically
= TRUE
;
2291 if (p
->status
== FF_FOUND
)
2293 for (i
= 1, q
= column_vector
; i
<= columns
; ++i
, ++q
)
2294 q
->status
= ON_HOLD
;
2295 if (column_vector
->lines_to_print
<= 0)
2298 pad_vertically
= FALSE
;
2299 return TRUE
; /* print a header only */
2303 if (padding_not_printed
- col_sep_length
> 0)
2305 pad_across_to (padding_not_printed
- col_sep_length
);
2306 padding_not_printed
= ANYWHERE
;
2309 if (use_col_separator
)
2310 print_sep_string ();
2312 while (first
!= last
)
2313 print_char (*first
++);
2315 if (spaces_not_printed
== 0)
2317 output_position
= p
->start_position
+ end_vector
[line
];
2318 if (p
->start_position
- col_sep_length
== chars_per_margin
)
2319 output_position
-= col_sep_length
;
2325 /* Convert a character to the proper format and return the number of
2326 characters in the resulting clump. Increment input_position by
2327 the width of the clump.
2329 Tabs are converted to clumps of spaces.
2330 Nonprintable characters may be converted to clumps of escape
2331 sequences or control prefixes.
2333 Note: the width of a clump is not necessarily equal to the number of
2334 characters in clump_buff. (e.g, the width of '\b' is -1, while the
2335 number of characters is 1.) */
2338 char_to_clump (int c
)
2340 register int *s
= clump_buff
;
2346 if (c
== input_tab_char
)
2348 width
= TAB_WIDTH (chars_per_input_tab
, input_position
);
2352 for (i
= width
; i
; --i
)
2363 else if (!ISPRINT (c
))
2365 if (use_esc_sequence
)
2370 sprintf (esc_buff
, "%03o", c
);
2371 for (i
= 0; i
<= 2; ++i
)
2372 *s
++ = (int) esc_buff
[i
];
2374 else if (use_cntrl_prefix
)
2388 sprintf (esc_buff
, "%03o", c
);
2389 for (i
= 0; i
<= 2; ++i
)
2390 *s
++ = (int) esc_buff
[i
];
2413 input_position
+= width
;
2417 /* We've just printed some files and need to clean up things before
2418 looking for more options and printing the next batch of files.
2420 Free everything we've xmalloc'ed, except `header'. */
2430 free (column_vector
);
2439 /* Complain, print a usage message, and die. */
2445 fprintf (stderr
, _("Try `%s --help' for more information.\n"),
2450 Usage: %s [OPTION]... [FILE]...\n\
2455 Paginate or columnate FILE(s) for printing.\n\
2457 +FIRST_PAGE[:LAST_PAGE]\n\
2458 --pages=FIRST_PAGE[:LAST_PAGE]\n\
2459 begin [stop] printing with page FIRST_[LAST_]PAGE\n\
2461 --columns=COLUMN produce COLUMN-column output and print columns down,\n\
2462 unless -a is used. Balance number of lines in the\n\
2463 columns on each page.\n\
2464 -a, --across print columns across rather than down, used together\n\
2466 -c, --show-control-chars\n\
2467 use hat notation (^G) and octal backslash notation\n\
2468 -d, --double-space\n\
2469 double space the output\n\
2470 -e, --expand-tabs[=CHAR[WIDTH]]\n\
2471 expand input CHARs (TABs) to tab WIDTH (8)\n\
2472 -F, -f, --form-feed\n\
2473 use form feeds instead of newlines to separate pages\n\
2474 (by a 3-line page header with -f or a 5-line header\n\
2475 and trailer without -f)\n\
2476 -h, --header=HEADER\n\
2477 use a centered HEADER instead of filename in page headers\n\
2478 with long headers left-hand-side truncation may occur\n\
2479 -h \"\" prints a blank line. Don't use -h\"\"\n\
2480 -i, --output-tabs[=CHAR[WIDTH]]\n\
2481 replace spaces with CHARs (TABs) to tab WIDTH (8)\n\
2482 -j, --join-lines merge full lines, turns off -w line truncation, no column\n\
2483 alignment, -s[STRING] sets separators\n\
2484 -l, --length PAGE_LENGTH\n\
2485 set the page length to PAGE_LENGTH (66) lines\n\
2486 (default number of lines of text 56, with -f 63)\n"));
2488 -m, --merge print all files in parallel, one in each column,\n\
2489 truncate lines, but join lines of full length with -j\n\
2490 -n, --number-lines[=SEP[DIGITS]]\n\
2491 number lines, use DIGITS (5) digits, then SEP (TAB)\n\
2492 default counting starts with 1st line of input file\n\
2493 -N, --first-line-number=NUMBER\n\
2494 start counting with NUMBER at 1st line of first\n\
2495 page printed (see +FIRST_PAGE)\n\
2496 -o, --indent=MARGIN\n\
2497 offset each line with MARGIN spaces (do not affect -w)\n\
2498 -r, --no-file-warnings\n\
2499 inhibit warning when a file cannot be opened\n\
2500 -s, --separator[=STRING]\n\
2501 separate columns by an optional STRING, don't use\n\
2502 -s \"STRING\", -s only: No separator used (same as -s\"\"),\n\
2503 without -s: Default separator \'TAB\' with -j and \'space\'\n\
2504 otherwise (same as -s\" \")\n\
2505 -t, --omit-header inhibit page headers and trailers\n\
2506 -T, --omit-pagination\n\
2507 inhibit page headers and trailers, eliminate any page\n\
2508 layout by form feeds set in input files\n\
2509 -v, --show-nonprinting\n\
2510 use octal backslash notation\n\
2511 -w, --width=PAGE_WIDTH\n\
2512 set page width to PAGE_WIDTH (72) columns, truncate\n\
2513 lines (see also -j option)\n\
2514 --help display this help and exit\n\
2515 --version output version information and exit\n\
2517 -T implied by -l nn when nn <= 10 or <= 3 with -f. With no FILE, or when\n\
2518 FILE is -, read standard input.\n\
2520 puts (_("\nReport bugs to <bug-textutils@gnu.org>."));
2522 exit (status
== 0 ? EXIT_SUCCESS
: EXIT_FAILURE
);