1 /* pr -- convert text files for printing.
2 Copyright (C) 1988, 1991, 1995, 1996 Free Software Foundation, Inc.
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
18 /* Author: Pete TerMaat. */
20 /* Things to watch: Sys V screws up on ...
21 pr -n -3 -s: /usr/dict/words
22 pr -m -o10 -n /usr/dict/words{,,,}
23 pr -6 -a -n -o5 /usr/dict/words
27 Keep a things_to_do list of functions to call when we know we have
28 something to print. Cleaner than current series of checks.
30 Improve the printing of control prefixes.
35 +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 'space' s used,
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>
189 #define UINT_MAX ((unsigned int) ~(unsigned int) 0)
193 #define INT_MAX ((int) (UINT_MAX >> 1))
201 /* Used with start_position in the struct COLUMN described below.
202 If start_position == ANYWHERE, we aren't truncating columns and
203 can begin printing a column anywhere. Otherwise we must pad to
204 the horizontal position start_position. */
207 /* Each column has one of these structures allocated for it.
208 If we're only dealing with one file, fp is the same for all
211 The general strategy is to spend time setting up these column
212 structures (storing columns if necessary), after which printing
213 is a matter of flitting from column to column and calling
216 Parallel files, single files printing across in multiple
217 columns, and single files printing down in multiple columns all
218 fit the same printing loop.
220 print_func Function used to print lines in this column.
221 If we're storing this column it will be
222 print_stored(), Otherwise it will be read_line().
224 char_func Function used to process characters in this column.
225 If we're storing this column it will be store_char(),
226 otherwise it will be print_char().
228 current_line Index of the current entry in line_vector, which
229 contains the index of the first character of the
230 current line in buff[].
232 lines_stored Number of lines in this column which are stored in
235 lines_to_print If we're storing this column, lines_to_print is
236 the number of stored_lines which remain to be
237 printed. Otherwise it is the number of lines
238 we can print without exceeding lines_per_body.
240 start_position The horizontal position we want to be in before we
241 print the first character in this column.
243 numbered True means precede this column with a line number. */
247 FILE *fp
; /* Input stream for this column. */
248 char *name
; /* File name. */
252 FF_FOUND
, /* used with -b option, set with \f, changed
253 to ON_HOLD after print_header */
254 ON_HOLD
, /* Hit a form feed. */
257 status
; /* Status of the file pointer. */
258 int (*print_func
) (); /* Func to print lines in this col. */
259 void (*char_func
) (); /* Func to print/store chars in this col. */
260 int current_line
; /* Index of current place in line_vector. */
261 int lines_stored
; /* Number of lines stored in buff. */
262 int lines_to_print
; /* No. lines stored or space left on page. */
263 int start_position
; /* Horizontal position of first char. */
265 int full_page_printed
; /* True means printed without a FF found. */
267 /* p->full_page_printed controls a special case of "FF set by hand":
268 True means a full page has been printed without FF found. To avoid an
269 additional empty page we have to ignore a FF immediately following in
273 typedef struct COLUMN COLUMN
;
275 #define NULLCOL (COLUMN *)0
277 static int char_to_clump
__P ((int c
));
278 static int read_line
__P ((COLUMN
*p
));
279 static int print_page
__P ((void));
280 static int print_stored
__P ((COLUMN
*p
));
281 static int open_file
__P ((char *name
, COLUMN
*p
));
282 static int skip_to_page
__P ((int page
));
283 static void print_header
__P ((void));
284 static void pad_across_to
__P ((int position
));
285 static void number
__P ((COLUMN
*p
));
286 static void getoptarg
__P ((char *arg
, char switch_char
, char *character
, int *number
));
287 static void usage
__P ((int status
));
288 static void print_files
__P ((int number_of_files
, char **av
));
289 static void init_parameters
__P ((int number_of_files
));
290 static void init_header
__P ((char *filename
, int desc
));
291 static void init_store_cols
__P ((void));
292 static void store_columns
__P ((void));
293 static void balance
__P ((int total_stored
));
294 static void store_char
__P ((int c
));
295 static void pad_down
__P ((int lines
));
296 static void read_rest_of_line
__P ((COLUMN
*p
));
297 static void skip_read
__P ((COLUMN
*p
, int column_number
));
298 static void print_char
__P ((int c
));
299 static void cleanup
__P ((void));
300 static void first_last_page
__P ((char *pages
));
301 static void print_sep_string
__P ((void));
302 static void separator_string
__P ((const char *optarg_S
));
304 /* The name under which this program was invoked. */
307 /* All of the columns to print. */
308 static COLUMN
*column_vector
;
310 /* When printing a single file in multiple downward columns,
311 we store the leftmost columns contiguously in buff.
312 To print a line from buff, get the index of the first character
313 from line_vector[i], and print up to line_vector[i + 1]. */
316 /* Index of the position in buff where the next character
318 static int buff_current
;
320 /* The number of characters in buff.
321 Used for allocation of buff and to detect overflow of buff. */
322 static int buff_allocated
;
324 /* Array of indices into buff.
325 Each entry is an index of the first character of a line.
326 This is used when storing lines to facilitate shuffling when
327 we do column balancing on the last page. */
328 static int *line_vector
;
330 /* Array of horizonal positions.
331 For each line in line_vector, end_vector[line] is the horizontal
332 position we are in after printing that line. We keep track of this
333 so that we know how much we need to pad to prepare for the next
335 static int *end_vector
;
337 /* (-m) True means we're printing multiple files in parallel. */
338 static int parallel_files
= FALSE
;
340 /* (-m) True means a line starts with some empty columns (some files
341 already CLOSED or ON_HOLD) which we have to align. */
342 static int align_empty_cols
;
344 /* (-m) True means we have not yet found any printable column in a line.
345 align_empty_cols = TRUE has to be maintained. */
346 static int empty_line
;
348 /* (-m) False means printable column output precedes a form feed found.
349 Column align is done only once. No additional action with that form
351 True means we found only a form feed in a column. Maybe we have to do
352 some column align with that form feed. */
355 /* (-[0-9]+) True means we're given an option explicitly specifying
356 number of columns. Used to detect when this option is used with -m. */
357 static int explicit_columns
= FALSE
;
359 /* (-t|-T) False means we aren't printing headers and footers. */
360 static int extremities
= TRUE
;
362 /* (-t) True means we retain all FF set by hand in input files.
363 False is set with -T option. */
364 static int keep_FF
= FALSE
;
365 static int print_a_FF
= FALSE
;
367 /* True means we need to print a header as soon as we know we've got input
368 to print after it. */
369 static int print_a_header
;
371 /* (-h) True means we're using the standard header rather than a
372 customized one specified by the -h flag. */
373 static int standard_header
= TRUE
;
375 /* (-f) True means use formfeeds instead of newlines to separate pages. */
376 static int use_form_feed
= FALSE
;
378 /* True means we have read the standard input. */
379 static int have_read_stdin
= FALSE
;
381 /* True means the -a flag has been given. */
382 static int print_across_flag
= FALSE
;
384 /* True means we're printing one file in multiple (>1) downward columns. */
385 static int storing_columns
= TRUE
;
387 /* (-b) True means balance columns on the last page as Sys V does. */
388 /* That's no longer an independent option. With storing_columns = TRUE
389 balance_columns = TRUE is used too (s. function init_parameters).
390 We get a consistent formulation with "FF set by hand" in input files. */
391 static int balance_columns
= FALSE
;
393 /* (-l) Number of lines on a page, including header and footer lines. */
394 static int lines_per_page
= 66;
396 /* Number of lines in the header and footer can be reset to 0 using
398 static int lines_per_header
= 5;
399 static int lines_per_body
;
400 static int lines_per_footer
= 5;
402 /* (-w) Width in characters of the page. Does not include the width of
404 static int chars_per_line
= 72;
406 /* (-w) True means we truncate lines longer than chars_per_column. */
407 static int truncate_lines
= FALSE
;
409 /* (-j) True means we join lines without any line truncation. -j
410 dominates -w option. */
411 static int join_lines
= FALSE
;
413 /* Number of characters in a column. Based on col_sep_length and
415 static int chars_per_column
;
417 /* (-e) True means convert tabs to spaces on input. */
418 static int untabify_input
= FALSE
;
420 /* (-e) The input tab character. */
421 static char input_tab_char
= '\t';
423 /* (-e) Tabstops are at chars_per_tab, 2*chars_per_tab, 3*chars_per_tab, ...
424 where the leftmost column is 1. */
425 static int chars_per_input_tab
= 8;
427 /* (-i) True means convert spaces to tabs on output. */
428 static int tabify_output
= FALSE
;
430 /* (-i) The output tab character. */
431 static char output_tab_char
= '\t';
433 /* (-i) The width of the output tab. */
434 static int chars_per_output_tab
= 8;
436 /* Keeps track of pending white space. When we hit a nonspace
437 character after some whitespace, we print whitespace, tabbing
438 if necessary to get to output_position + spaces_not_printed. */
439 static int spaces_not_printed
;
441 /* (-o) Number of spaces in the left margin (tabs used when possible). */
442 static int chars_per_margin
= 0;
444 /* Position where the next character will fall.
445 Leftmost position is 0 + chars_per_margin.
446 Rightmost position is chars_per_margin + chars_per_line - 1.
447 This is important for converting spaces to tabs on output. */
448 static int output_position
;
450 /* Horizontal position relative to the current file.
451 (output_position depends on where we are on the page;
452 input_position depends on where we are in the file.)
453 Important for converting tabs to spaces on input. */
454 static int input_position
;
456 /* Count number of failed opens so we can exit with nonzero
457 status if there were any. */
458 static int failed_opens
= 0;
460 /* The horizontal position we'll be at after printing a tab character
461 of width c_ from the position h_. */
462 #define pos_after_tab(c_, h_) h_ - h_ % c_ + c_
464 /* The number of spaces taken up if we print a tab character with width
465 c_ from position h_. */
466 #define tab_width(c_, h_) - h_ % c_ + c_
468 /* (-NNN) Number of columns of text to print. */
469 static int columns
= 1;
471 /* (+NNN:MMM) Page numbers on which to begin and stop printing. */
472 static int first_page_number
= 1;
473 static int last_page_number
= 0;
475 /* Number of files open (not closed, not on hold). */
476 static int files_ready_to_read
= 0;
478 /* Current page number. Displayed in header. */
479 static int page_number
;
481 /* Current line number. Displayed when -n flag is specified.
483 When printing files in parallel (-m flag), line numbering is as follows:
487 When printing files across (-a flag), ...
491 Otherwise, line numbering is as follows:
494 static int line_number
;
496 /* (-n) True means lines should be preceded by numbers. */
497 static int numbered_lines
= FALSE
;
499 /* (-n) Character which follows each line number. */
500 static char number_separator
= '\t';
502 /* (-n) line counting starts with 1st line of input file (not with 1st
503 line of 1st page printed). */
504 static int line_count
= 1;
506 /* (-n) True means counting of skipped lines starts with 1st line of
507 input file. False means -N option is used in addition, counting of
508 skipped lines not required. */
509 static int skip_count
= TRUE
;
511 /* (-N) Counting starts with start_line_number = NUMBER at 1st line of
512 first page printed, usually not 1st page of input file. */
513 static int start_line_num
= 1;
515 /* (-n) Width in characters of a line number. */
516 static int chars_per_number
= 5;
518 /* Used when widening the first column to accommodate numbers -- only
519 needed when printing files in parallel. Includes width of both the
520 number and the number_separator. */
521 static int number_width
;
523 /* Buffer sprintf uses to format a line number. */
524 static char *number_buff
;
526 /* (-v) True means unprintable characters are printed as escape sequences.
527 control-g becomes \007. */
528 static int use_esc_sequence
= FALSE
;
530 /* (-c) True means unprintable characters are printed as control prefixes.
531 control-g becomes ^G. */
532 static int use_cntrl_prefix
= FALSE
;
534 /* (-d) True means output is double spaced. */
535 static int double_space
= FALSE
;
537 /* Number of files opened initially in init_files. Should be 1
538 unless we're printing multiple files in parallel. */
539 static int total_files
= 0;
541 /* (-r) True means don't complain if we can't open a file. */
542 static int ignore_failed_opens
= FALSE
;
544 /* (-s) True means we separate columns with a specified string.
545 -s option does not affect line truncation nor column alignment. */
546 static int use_col_separator
= FALSE
;
548 /* String used to separate columns if the -s option has been specified.
549 Default value with -s is a space. */
550 static char *col_sep_string
;
551 static int col_sep_length
= 0;
552 static char *column_separator
= " ";
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
, NULL
) != 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
, NULL
) != 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
, NULL
) != 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
, NULL
) != 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
, NULL
) != 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
, NULL
) != 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
, NULL
) != 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 col_sep_string
= column_separator
;
979 use_col_separator
= TRUE
;
982 truncate_lines
= TRUE
;
983 untabify_input
= TRUE
;
984 tabify_output
= TRUE
;
987 storing_columns
= FALSE
;
989 /* -j dominates -w in any case */
991 truncate_lines
= FALSE
;
995 line_count
= start_line_num
;
996 if (number_separator
== input_tab_char
)
998 number_width
= chars_per_number
+
999 tab_width (chars_per_input_tab
,
1000 (chars_per_margin
+ chars_per_number
));
1003 number_width
= chars_per_number
+ 1;
1004 /* The number is part of the column width unless we are
1005 printing files in parallel. */
1007 chars_used_by_number
= number_width
;
1010 chars_per_column
= (chars_per_line
- chars_used_by_number
-
1011 (columns
- 1) * col_sep_length
) / columns
;
1013 if (chars_per_column
< 1)
1014 error (EXIT_FAILURE
, 0, _("page width too narrow"));
1018 if (number_buff
!= NULL
)
1020 number_buff
= (char *) xmalloc (2 * chars_per_number
);
1023 /* Pick the maximum between the tab width and the width of an
1025 if (clump_buff
!= NULL
)
1027 clump_buff
= (int *) xmalloc ((chars_per_input_tab
> 4
1028 ? chars_per_input_tab
: 4) * sizeof (int));
1031 /* Open the necessary files,
1032 maintaining a COLUMN structure for each column.
1034 With multiple files, each column p has a different p->fp.
1035 With single files, each column p has the same p->fp.
1036 Return 1 if (number_of_files > 0) and no files can be opened,
1039 With each column/file p, p->full_page_printed is initialized,
1040 see also open_file. */
1043 init_fps (int number_of_files
, char **av
)
1052 if (column_vector
!= NULLCOL
)
1053 free ((char *) column_vector
);
1054 column_vector
= (COLUMN
*) xmalloc (columns
* sizeof (COLUMN
));
1058 files_left
= number_of_files
;
1059 for (p
= column_vector
; files_left
--; ++p
, ++av
)
1061 if (open_file (*av
, p
) == 0)
1069 init_header ("", -1);
1074 if (number_of_files
> 0)
1076 if (open_file (*av
, p
) == 0)
1078 init_header (*av
, fileno (p
->fp
));
1082 p
->name
= _("standard input");
1084 have_read_stdin
= TRUE
;
1086 p
->full_page_printed
= FALSE
;
1088 init_header ("", -1);
1091 firstname
= p
->name
;
1093 for (i
= columns
- 1, ++p
; i
; --i
, ++p
)
1095 p
->name
= firstname
;
1098 p
->full_page_printed
= FALSE
;
1101 files_ready_to_read
= total_files
;
1105 /* Determine print_func and char_func, the functions
1106 used by each column for printing and/or storing.
1108 Determine the horizontal position desired when we begin
1109 printing a column (p->start_position). */
1117 h
= chars_per_margin
;
1119 if (!truncate_lines
)
1123 /* When numbering lines of parallel files, we enlarge the
1124 first column to accomodate the number. Looks better than
1125 the Sys V approach. */
1126 if (parallel_files
&& numbered_lines
)
1127 h_next
= h
+ chars_per_column
+ number_width
;
1129 h_next
= h
+ chars_per_column
;
1132 /* Enlarge p->start_position of first column to use the same form of
1133 padding_not_printed with all columns. */
1134 h
= h
+ col_sep_length
;
1136 /* This loop takes care of all but the rightmost column. */
1138 for (p
= column_vector
, i
= 1; i
< columns
; ++p
, ++i
)
1140 if (storing_columns
) /* One file, multi columns down. */
1142 p
->char_func
= store_char
;
1143 p
->print_func
= print_stored
;
1146 /* One file, multi columns across; or parallel files. */
1148 p
->char_func
= print_char
;
1149 p
->print_func
= read_line
;
1152 /* Number only the first column when printing files in
1154 p
->numbered
= numbered_lines
&& (!parallel_files
|| i
== 1);
1155 p
->start_position
= h
;
1157 /* If we don't truncate lines, all start_positions are
1158 ANYWHERE, except the first column's start_position when
1161 if (!truncate_lines
)
1168 h
= h_next
+ col_sep_length
;
1169 h_next
= h
+ chars_per_column
;
1173 /* The rightmost column.
1175 Doesn't need to be stored unless we intend to balance
1176 columns on the last page. */
1177 if (storing_columns
&& balance_columns
)
1179 p
->char_func
= store_char
;
1180 p
->print_func
= print_stored
;
1184 p
->char_func
= print_char
;
1185 p
->print_func
= read_line
;
1188 p
->numbered
= numbered_lines
&& (!parallel_files
|| i
== 1);
1189 p
->start_position
= h
;
1192 /* Open a file. Return nonzero if successful, zero if failed.
1194 With each file p, p->full_page_printed is initialized,
1195 see also init_fps. */
1198 open_file (char *name
, COLUMN
*p
)
1200 if (!strcmp (name
, "-"))
1202 p
->name
= _("standard input");
1204 have_read_stdin
= 1;
1209 p
->fp
= fopen (name
, "r");
1214 if (!ignore_failed_opens
)
1215 error (0, errno
, "%s", name
);
1219 p
->full_page_printed
= FALSE
;
1224 /* Close the file in P.
1226 If we aren't dealing with multiple files in parallel, we change
1227 the status of all columns in the column list to reflect the close. */
1230 close_file (COLUMN
*p
)
1235 if (p
->status
== CLOSED
)
1238 error (EXIT_FAILURE
, errno
, "%s", p
->name
);
1239 if (p
->fp
!= stdin
&& fclose (p
->fp
) == EOF
)
1240 error (EXIT_FAILURE
, errno
, "%s", p
->name
);
1242 if (!parallel_files
)
1244 for (q
= column_vector
, i
= columns
; i
; ++q
, --i
)
1247 if (q
->lines_stored
== 0)
1249 q
->lines_to_print
= 0;
1256 p
->lines_to_print
= 0;
1259 --files_ready_to_read
;
1262 /* Put a file on hold until we start a new page,
1263 since we've hit a form feed.
1265 If we aren't dealing with parallel files, we must change the
1266 status of all columns in the column list. */
1269 hold_file (COLUMN
*p
)
1274 if (!parallel_files
)
1275 for (q
= column_vector
, i
= columns
; i
; ++q
, --i
)
1277 if (storing_columns
)
1278 q
->status
= FF_FOUND
;
1280 q
->status
= ON_HOLD
;
1283 p
->status
= ON_HOLD
;
1285 p
->lines_to_print
= 0;
1286 --files_ready_to_read
;
1289 /* Undo hold_file -- go through the column list and change any
1290 ON_HOLD columns to OPEN. Used at the end of each page. */
1298 for (p
= column_vector
; i
; --i
, ++p
)
1299 if (p
->status
== ON_HOLD
)
1302 files_ready_to_read
++;
1305 if (storing_columns
)
1306 files_ready_to_read
= 1;
1309 /* Print a single file, or multiple files in parallel.
1311 Set up the list of columns, opening the necessary files.
1312 Allocate space for storing columns, if necessary.
1313 Skip to first_page_number, if user has asked to skip leading pages.
1314 Determine which functions are appropriate to store/print lines
1316 Print the file(s). */
1319 print_files (int number_of_files
, char **av
)
1321 init_parameters (number_of_files
);
1322 if (init_fps (number_of_files
, av
))
1324 if (storing_columns
)
1327 if (first_page_number
> 1)
1329 if (!skip_to_page (first_page_number
))
1332 page_number
= first_page_number
;
1339 line_number
= line_count
;
1340 while (print_page ())
1344 /* Estimate the number of characters taken up by a short format date and
1345 time: "yy-mm-dd HH:MM" and: "Page NNNN". */
1346 #define CHARS_FOR_DATE_AND_PAGE 23
1348 /* Initialize header information.
1349 If DESC is non-negative, it is a file descriptor open to
1350 FILENAME for reading.
1352 Allocate space for a header string,
1353 Determine the time, insert file name or user-specified string.
1354 Make use of a centered header with left-hand-side truncation marked by
1355 a '*` in front, if necessary. */
1358 init_header (char *filename
, int desc
)
1360 int chars_per_middle
, chars_free
, lhs_blanks
, rhs_blanks
;
1362 char *no_middle
= "";
1363 char *header_text
, *t_buf
;
1366 char *datim
= "- Date/Time --";
1368 if (filename
== NULL
)
1373 header
= (char *) xmalloc (chars_per_line
+ 1);
1375 if (!standard_header
&& *custom_header
== '\0')
1376 sprintf (header
, "%s", " "); /* blank line header */
1379 /* If parallel files or standard input, use current time. */
1380 if (desc
< 0 || !strcmp (filename
, "-") || fstat (desc
, &st
))
1381 st
.st_mtime
= time (NULL
);
1384 size_t t_buf_size
= 15;
1385 const char *fmt
= "%y-%m-%d %H:%M"; /* date/time short format */
1387 t_buf
= (char *) xmalloc (t_buf_size
);
1388 tmptr
= localtime (&st
.st_mtime
);
1389 strftime (t_buf
, t_buf_size
, fmt
, tmptr
);
1392 chars_per_middle
= chars_per_line
- CHARS_FOR_DATE_AND_PAGE
;
1393 if (chars_per_middle
< 3)
1395 header_text
= no_middle
; /* Nothing free for a heading */
1401 header_text
= standard_header
? f
: custom_header
;
1402 chars_free
= chars_per_middle
- (int) strlen (header_text
);
1405 lhs_blanks
= chars_free
/ 2; /* text not truncated */
1406 rhs_blanks
= chars_free
- lhs_blanks
;
1409 { /* lhs truncation */
1410 header_text
= header_text
- chars_free
+ 2;
1417 sprintf (header
, _("%s%*s%s%*sPage"), (test_suite
? datim
: t_buf
),
1418 lhs_blanks
, " ", header_text
, rhs_blanks
, " ");
1422 /* Set things up for printing a page
1424 Scan through the columns ...
1425 Determine which are ready to print
1426 (i.e., which have lines stored or open files)
1427 Set p->lines_to_print appropriately
1428 (to p->lines_stored if we're storing, or lines_per_body
1429 if we're reading straight from the file)
1430 Keep track of this total so we know when to stop printing */
1438 if (storing_columns
)
1441 for (j
= columns
- 1, p
= column_vector
; j
; --j
, ++p
)
1443 p
->lines_to_print
= p
->lines_stored
;
1447 if (balance_columns
)
1449 p
->lines_to_print
= p
->lines_stored
;
1451 /* Since we're not balancing columns, we don't need to store
1452 the rightmost column. Read it straight from the file. */
1455 if (p
->status
== OPEN
)
1457 p
->lines_to_print
= lines_per_body
;
1460 p
->lines_to_print
= 0;
1464 for (j
= columns
, p
= column_vector
; j
; --j
, ++p
)
1465 if (p
->status
== OPEN
)
1467 p
->lines_to_print
= lines_per_body
;
1470 p
->lines_to_print
= 0;
1473 /* Align empty columns and print separators.
1474 Empty columns will be formed by files with status ON_HOLD or CLOSED
1475 when printing multiple files in parallel. */
1478 align_column (COLUMN
*p
)
1480 padding_not_printed
= p
->start_position
;
1481 if (padding_not_printed
- col_sep_length
> 0)
1483 pad_across_to (padding_not_printed
- col_sep_length
);
1484 padding_not_printed
= ANYWHERE
;
1487 if (use_col_separator
)
1488 print_sep_string ();
1496 As long as there are lines left on the page and columns ready to print,
1497 Scan across the column list
1498 if the column has stored lines or the file is open
1499 pad to the appropriate spot
1501 pad the remainder of the page with \n or \f as requested
1502 reset the status of all files -- any files which where on hold because
1503 of formfeeds are now put back into the lineup. */
1509 int lines_left_on_page
;
1512 /* Used as an accumulator (with | operator) of successive values of
1513 pad_vertically. The trick is to set pad_vertically
1514 to zero before each run through the inner loop, then after that
1515 loop, it tells us whether a line was actually printed (whether a
1516 newline needs to be output -- or two for double spacing). But those
1517 values have to be accumulated (in pv) so we can invoke pad_down
1518 properly after the outer loop completes. */
1523 if (cols_ready_to_print () == 0)
1527 print_a_header
= TRUE
;
1529 /* Don't pad unless we know a page was printed. */
1530 pad_vertically
= FALSE
;
1533 lines_left_on_page
= lines_per_body
;
1535 lines_left_on_page
*= 2;
1537 while (lines_left_on_page
> 0 && cols_ready_to_print () > 0)
1539 output_position
= 0;
1540 spaces_not_printed
= 0;
1541 separators_not_printed
= 0;
1542 pad_vertically
= FALSE
;
1543 align_empty_cols
= FALSE
;
1546 for (j
= 1, p
= column_vector
; j
<= columns
; ++j
, ++p
)
1549 if (p
->lines_to_print
> 0 || p
->status
== FF_FOUND
)
1552 padding_not_printed
= p
->start_position
;
1553 if (!(p
->print_func
) (p
))
1554 read_rest_of_line (p
);
1555 pv
|= pad_vertically
;
1557 --p
->lines_to_print
;
1558 if (p
->lines_to_print
<= 0)
1560 if (cols_ready_to_print () <= 0)
1564 /* File p changed its status to ON_HOLD or CLOSED */
1565 if (parallel_files
&& p
->status
!= OPEN
)
1568 align_empty_cols
= TRUE
;
1569 else if (p
->status
== CLOSED
||
1570 (p
->status
== ON_HOLD
&& FF_only
))
1574 else if (parallel_files
)
1576 /* File status ON_HOLD or CLOSED */
1578 align_empty_cols
= TRUE
;
1583 /* We need it also with an empty column */
1584 if (use_col_separator
)
1585 ++separators_not_printed
;
1591 --lines_left_on_page
;
1594 if (double_space
&& pv
&& extremities
)
1597 --lines_left_on_page
;
1601 if (lines_left_on_page
== 0)
1602 for (j
= 1, p
= column_vector
; j
<= columns
; ++j
, ++p
)
1603 if (p
->status
== OPEN
)
1604 p
->full_page_printed
= TRUE
;
1606 pad_vertically
= pv
;
1608 if (pad_vertically
&& extremities
)
1609 pad_down (lines_left_on_page
+ lines_per_footer
);
1610 else if (keep_FF
&& print_a_FF
)
1616 if (last_page_number
&& page_number
> last_page_number
)
1617 return FALSE
; /* Stop printing with LAST_PAGE */
1619 reset_status (); /* Change ON_HOLD to OPEN. */
1621 return TRUE
; /* More pages to go. */
1624 /* Allocate space for storing columns.
1626 This is necessary when printing multiple columns from a single file.
1627 Lines are stored consecutively in buff, separated by '\0'.
1629 The following doesn't apply any longer - any tuning possible?
1630 (We can't use a fixed offset since with the '-s' flag lines aren't
1633 We maintain a list (line_vector) of pointers to the beginnings
1634 of lines in buff. We allocate one more than the number of lines
1635 because the last entry tells us the index of the last character,
1636 which we need to know in order to print the last line in buff. */
1639 init_store_cols (void)
1641 int total_lines
= lines_per_body
* columns
;
1642 int chars_if_truncate
= total_lines
* (chars_per_column
+ 1);
1644 if (line_vector
!= NULL
)
1645 free ((int *) line_vector
);
1646 line_vector
= (int *) xmalloc ((total_lines
+ 1) * sizeof (int *));
1648 if (end_vector
!= NULL
)
1649 free ((int *) end_vector
);
1650 end_vector
= (int *) xmalloc (total_lines
* sizeof (int *));
1654 buff_allocated
= (use_col_separator
1655 ? 2 * chars_if_truncate
1656 : chars_if_truncate
); /* Tune this. */
1657 buff
= (char *) xmalloc (buff_allocated
);
1660 /* Store all but the rightmost column.
1661 (Used when printing a single file in multiple downward columns)
1664 set p->current_line to be the index in line_vector of the
1665 first line in the column
1666 For each line in the column
1667 store the line in buff
1668 add to line_vector the index of the line's first char
1669 buff_start is the index in buff of the first character in the
1673 store_columns (void)
1678 int last_col
; /* The rightmost column which will be saved in buff */
1684 if (balance_columns
)
1687 last_col
= columns
- 1;
1689 for (i
= 1, p
= column_vector
; i
<= last_col
; ++i
, ++p
)
1690 p
->lines_stored
= 0;
1692 for (i
= 1, p
= column_vector
; i
<= last_col
&& files_ready_to_read
;
1695 p
->current_line
= line
;
1696 for (j
= lines_per_body
; j
&& files_ready_to_read
; --j
)
1698 if (p
->status
== OPEN
) /* Redundant. Clean up. */
1703 read_rest_of_line (p
);
1705 if (p
->status
== OPEN
1706 || buff_start
!= buff_current
)
1709 line_vector
[line
] = buff_start
;
1710 end_vector
[line
++] = input_position
;
1711 buff_start
= buff_current
;
1716 /* Keep track of the location of the last char in buff. */
1717 line_vector
[line
] = buff_start
;
1719 if (balance_columns
&& p
->lines_stored
!= lines_per_body
)
1724 balance (int total_stored
)
1730 for (i
= 1, p
= column_vector
; i
<= columns
; ++i
, ++p
)
1732 lines
= total_stored
/ columns
;
1733 if (i
<= total_stored
% columns
)
1736 p
->lines_stored
= lines
;
1737 p
->current_line
= first_line
;
1739 first_line
+= lines
;
1743 /* Store a character in the buffer. */
1748 if (buff_current
>= buff_allocated
)
1750 /* May be too generous. */
1751 buff_allocated
= 2 * buff_allocated
;
1752 buff
= (char *) xrealloc (buff
, buff_allocated
* sizeof (char));
1754 buff
[buff_current
++] = (char) c
;
1763 sprintf (number_buff
, "%*d", chars_per_number
, line_number
++);
1765 for (i
= chars_per_number
; i
> 0; i
--)
1766 (p
->char_func
) ((int) *s
++);
1768 if (number_separator
== input_tab_char
)
1770 i
= number_width
- chars_per_number
;
1772 (p
->char_func
) ((int) ' ');
1775 (p
->char_func
) ((int) number_separator
);
1777 if (truncate_lines
&& !parallel_files
)
1778 input_position
+= number_width
;
1781 /* Print (or store) padding until the current horizontal position
1785 pad_across_to (int position
)
1787 register int h
= output_position
;
1790 spaces_not_printed
= position
- output_position
;
1793 while (++h
<= position
)
1795 output_position
= position
;
1799 /* Pad to the bottom of the page.
1801 If the user has requested a formfeed, use one.
1802 Otherwise, use newlines. */
1805 pad_down (int lines
)
1812 for (i
= lines
; i
; --i
)
1816 /* Read the rest of the line.
1818 Read from the current column's file until an end of line is
1819 hit. Used when we've truncated a line and we no longer need
1820 to print or store its characters. */
1823 read_rest_of_line (COLUMN
*p
)
1828 while ((c
= getc (f
)) != '\n')
1832 if ((c
= getc (f
)) != '\n')
1847 /* Read a line with skip_to_page.
1849 Read from the current column's file until an end of line is
1850 hit. Used when we read full lines to skip pages.
1851 With skip_to_page we have to check for FF-coincidence which is done
1852 in function read_line otherwise.
1853 Count lines of skipped pages to find the line number of 1st page
1854 printed relative to 1st line of input file (start_line_num). */
1857 skip_read (COLUMN
*p
, int column_number
)
1861 int i
, single_ff
= FALSE
;
1864 /* Read 1st character in a line or any character succeeding a FF */
1865 if ((c
= getc (f
)) == '\f' && p
->full_page_printed
)
1866 /* A FF-coincidence with a previous full_page_printed.
1867 To avoid an additional empty page, eliminate the FF */
1868 if ((c
= getc (f
)) == '\n')
1871 p
->full_page_printed
= FALSE
;
1873 /* 1st character a FF means a single FF without any printable
1874 characters. Don't count it as a line with -n option. */
1878 /* Preparing for a FF-coincidence: Maybe we finish that page
1879 without a FF found */
1881 p
->full_page_printed
= TRUE
;
1887 /* No FF-coincidence possible,
1888 no catching up of a FF-coincidence with next page */
1891 if (!parallel_files
)
1892 for (q
= column_vector
, i
= columns
; i
; ++q
, --i
)
1893 q
->full_page_printed
= FALSE
;
1895 p
->full_page_printed
= FALSE
;
1898 if ((c
= getc (f
)) != '\n')
1912 if ((!parallel_files
|| column_number
== 1) && !single_ff
)
1916 /* If we're tabifying output,
1918 When print_char encounters white space it keeps track
1919 of our desired horizontal position and delays printing
1920 until this function is called. */
1923 print_white_space (void)
1926 register int h_old
= output_position
;
1927 register int goal
= h_old
+ spaces_not_printed
;
1929 while (goal
- h_old
> 1
1930 && (h_new
= pos_after_tab (chars_per_output_tab
, h_old
)) <= goal
)
1932 putchar (output_tab_char
);
1935 while (++h_old
<= goal
)
1938 output_position
= goal
;
1939 spaces_not_printed
= 0;
1942 /* Print column separators.
1944 We keep a count until we know that we'll be printing a line,
1945 then print_sep_string() is called. */
1951 int l
= col_sep_length
;
1955 if (spaces_not_printed
> 0)
1956 print_white_space ();
1958 for (; separators_not_printed
> 0; --separators_not_printed
)
1962 output_position
+= col_sep_length
;
1966 /* Print (or store, depending on p->char_func) a clump of N
1970 print_clump (COLUMN
*p
, int n
, int *clump
)
1973 (p
->char_func
) (*clump
++);
1976 /* Print a character.
1978 Update the following comment: process-char hasn't been used any
1980 If we're tabifying, all tabs have been converted to spaces by
1981 process_char(). Keep a count of consecutive spaces, and when
1982 a nonspace is encountered, call print_white_space() to print the
1983 required number of tabs and spaces. */
1992 ++spaces_not_printed
;
1995 else if (spaces_not_printed
> 0)
1996 print_white_space ();
1998 /* Nonprintables are assumed to have width 0, except '\b'. */
2010 /* Skip to page PAGE before printing. */
2013 skip_to_page (int page
)
2018 for (n
= 1; n
< page
; ++n
)
2020 for (i
= 1; i
< lines_per_body
; ++i
)
2022 for (j
= 1, p
= column_vector
; j
<= columns
; ++j
, ++p
)
2023 if (p
->status
== OPEN
)
2027 for (j
= 1, p
= column_vector
; j
<= columns
; ++j
, ++p
)
2028 if (p
->status
== OPEN
)
2031 if (storing_columns
) /* change FF_FOUND to ON_HOLD */
2032 for (j
= 1, p
= column_vector
; j
<= columns
; ++j
, ++p
)
2033 p
->status
= ON_HOLD
;
2038 return files_ready_to_read
> 0;
2043 Formfeeds are assumed to use up two lines at the beginning of
2050 fprintf (stdout
, "\n\n");
2052 output_position
= 0;
2053 pad_across_to (chars_per_margin
);
2054 print_white_space ();
2056 if (!standard_header
&& *custom_header
== '\0')
2057 fprintf (stdout
, "%s\n\n\n", header
);
2059 fprintf (stdout
, "%s%5d\n\n\n", header
, page_number
++);
2061 print_a_header
= FALSE
;
2062 output_position
= 0;
2065 /* Print (or store, if p->char_func is store_char()) a line.
2067 Read a character to determine whether we have a line or not.
2068 (We may hit EOF, \n, or \f)
2070 Once we know we have a line,
2071 set pad_vertically = TRUE, meaning it's safe
2072 to pad down at the end of the page, since we do have a page.
2073 print a header if needed.
2074 pad across to padding_not_printed if needed.
2075 print any separators which need to be printed.
2076 print a line number if it needs to be printed.
2078 Print the clump which corresponds to the first character.
2080 Enter a loop and keep printing until an end of line condition
2081 exists, or until we exceed chars_per_column.
2083 Return FALSE if we exceed chars_per_column before reading
2084 an end of line character, TRUE otherwise. */
2087 read_line (COLUMN
*p
)
2089 register int c
, chars
;
2090 int last_input_position
;
2094 /* Suppress `used before initialized' warning. */
2099 /* read 1st character in each line or any character succeeding a FF: */
2102 last_input_position
= input_position
;
2104 if (c
== '\f' && p
->full_page_printed
)
2105 if ((c
= getc (p
->fp
)) == '\n')
2107 p
->full_page_printed
= FALSE
;
2112 if ((c
= getc (p
->fp
)) != '\n')
2115 if (print_a_header
&& !storing_columns
)
2117 pad_vertically
= TRUE
;
2130 chars
= char_to_clump (c
);
2133 if (truncate_lines
&& input_position
> chars_per_column
)
2135 input_position
= last_input_position
;
2139 if (p
->char_func
!= store_char
)
2141 pad_vertically
= TRUE
;
2143 if (print_a_header
&& !storing_columns
)
2146 if (parallel_files
&& align_empty_cols
)
2148 /* We have to align empty columns at the beginning of a line. */
2149 k
= separators_not_printed
;
2150 separators_not_printed
= 0;
2151 for (j
= 1, q
= column_vector
; j
<= k
; ++j
, ++q
)
2154 separators_not_printed
+= 1;
2156 padding_not_printed
= p
->start_position
;
2158 spaces_not_printed
= chars_per_column
;
2160 spaces_not_printed
= 0;
2161 align_empty_cols
= FALSE
;
2164 if (padding_not_printed
- col_sep_length
> 0)
2166 pad_across_to (padding_not_printed
- col_sep_length
);
2167 padding_not_printed
= ANYWHERE
;
2170 if (use_col_separator
)
2171 print_sep_string ();
2181 print_clump (p
, chars
, clump_buff
);
2192 if ((c
= getc (p
->fp
)) != '\n')
2203 last_input_position
= input_position
;
2204 chars
= char_to_clump (c
);
2205 if (truncate_lines
&& input_position
> chars_per_column
)
2207 input_position
= last_input_position
;
2211 print_clump (p
, chars
, clump_buff
);
2215 /* Print a line from buff.
2217 If this function has been called, we know we have "something to
2218 print". But it remains to be seen whether we have a real text page
2219 or an empty page (a single form feed) with/without a header only.
2220 Therefore first we set pad_vertically to TRUE and print a header
2222 If FF_FOUND and we are using -t|-T option we omit any newline by
2223 setting pad_vertically to FALSE (see print_page).
2224 Otherwise we pad across if necessary, print separators if necessary
2225 and text of COLUMN *p.
2227 Return TRUE, meaning there is no need to call read_rest_of_line. */
2230 print_stored (COLUMN
*p
)
2235 int line
= p
->current_line
++;
2236 register char *first
= &buff
[line_vector
[line
]];
2237 register char *last
= &buff
[line_vector
[line
+ 1]];
2239 pad_vertically
= TRUE
;
2244 if (p
->status
== FF_FOUND
)
2246 for (i
= 1, q
= column_vector
; i
<= columns
; ++i
, ++q
)
2247 q
->status
= ON_HOLD
;
2248 if (column_vector
->lines_to_print
<= 0)
2251 pad_vertically
= FALSE
;
2252 return TRUE
; /* print a header only */
2256 if (padding_not_printed
- col_sep_length
> 0)
2258 pad_across_to (padding_not_printed
- col_sep_length
);
2259 padding_not_printed
= ANYWHERE
;
2262 if (use_col_separator
)
2263 print_sep_string ();
2265 while (first
!= last
)
2266 print_char (*first
++);
2268 if (spaces_not_printed
== 0)
2270 output_position
= p
->start_position
+ end_vector
[line
];
2271 if (p
->start_position
- col_sep_length
== chars_per_margin
)
2272 output_position
-= col_sep_length
;
2278 /* Convert a character to the proper format and return the number of
2279 characters in the resulting clump. Increment input_position by
2280 the width of the clump.
2282 Tabs are converted to clumps of spaces.
2283 Nonprintable characters may be converted to clumps of escape
2284 sequences or control prefixes.
2286 Note: the width of a clump is not necessarily equal to the number of
2287 characters in clump_buff. (e.g, the width of '\b' is -1, while the
2288 number of characters is 1.) */
2291 char_to_clump (int c
)
2293 register int *s
= clump_buff
;
2299 if (c
== input_tab_char
)
2301 width
= tab_width (chars_per_input_tab
, input_position
);
2305 for (i
= width
; i
; --i
)
2316 else if (!ISPRINT (c
))
2318 if (use_esc_sequence
)
2323 sprintf (esc_buff
, "%03o", c
);
2324 for (i
= 0; i
<= 2; ++i
)
2325 *s
++ = (int) esc_buff
[i
];
2327 else if (use_cntrl_prefix
)
2341 sprintf (esc_buff
, "%03o", c
);
2342 for (i
= 0; i
<= 2; ++i
)
2343 *s
++ = (int) esc_buff
[i
];
2366 input_position
+= width
;
2370 /* We've just printed some files and need to clean up things before
2371 looking for more options and printing the next batch of files.
2373 Free everything we've xmalloc'ed, except `header'. */
2383 free (column_vector
);
2392 /* Complain, print a usage message, and die. */
2398 fprintf (stderr
, _("Try `%s --help' for more information.\n"),
2403 Usage: %s [OPTION]... [FILE]...\n\
2408 Paginate or columnate FILE(s) for printing.\n\
2410 +FIRST_PAGE[:LAST_PAGE]\n\
2411 begin [stop] printing with page FIRST_[LAST_]PAGE\n\
2412 -COLUMN produce COLUMN-column output and print columns down,\n\
2413 unless -a is used. Balance number of lines in the\n\
2414 columns on each page.\n\
2415 -a print columns across rather than down, used together\n\
2417 -c use hat notation (^G) and octal backslash notation\n\
2418 -d double space the output\n\
2419 -e[CHAR[WIDTH]] expand input CHARs (TABs) to tab WIDTH (8)\n\
2420 -F, -f use form feeds instead of newlines to separate pages\n\
2421 (by a 3-line page header with -f or a 5-line header\n\
2422 and trailer without -f)\n\
2423 -h HEADER use a centered HEADER instead of filename in page headers\n\
2424 with long headers left-hand-side truncation may occur\n\
2425 -h \"\" prints a blank line. Don't use -h\"\"\n\
2426 -i[CHAR[WIDTH]] replace spaces with CHARs (TABs) to tab WIDTH (8)\n\
2427 -j merge full lines, turns off -w line truncation, no column\n\
2428 alignment, -s[STRING] sets separators\n\
2429 -l PAGE_LENGTH set the page length to PAGE_LENGTH (66) lines\n\
2430 (default number of lines of text 56, with -f 63)\n\
2431 -m print all files in parallel, one in each column,\n\
2432 truncate lines, but join lines of full length with -j\n\
2433 -n[SEP[DIGITS]] number lines, use DIGITS (5) digits, then SEP (TAB)\n\
2434 default counting starts with 1st line of input file\n\
2435 -N NUMBER start counting with NUMBER at 1st line of first\n\
2436 page printed (see +FIRST_PAGE)\n\
2437 -o MARGIN offset each line with MARGIN spaces (do not affect -w)\n\
2438 -r inhibit warning when a file cannot be opened\n\
2439 -s[STRING] separate columns by an optional STRING\n\
2440 don't use -s \"STRING\" \n\
2441 without -s: default sep. \'space\' used, same as -s\" \"\n\
2442 -s only: no separator used, same as -s\"\" \n\
2443 -t inhibit page headers and trailers\n\
2444 -T inhibit page headers and trailers, eliminate any page\n\
2445 layout by form feeds set in input files\n\
2446 -v use octal backslash notation\n\
2447 -w PAGE_WIDTH set page width to PAGE_WIDTH (72) columns, truncate\n\
2448 lines (see also -j option)\n\
2449 --help display this help and exit\n\
2450 --version output version information and exit\n\
2452 -T implied by -l nn when nn <= 10 or <= 3 with -f. With no FILE, or when\n\
2453 FILE is -, read standard input.\n\
2455 puts (_("\nReport bugs to textutils-bugs@gnu.ai.mit.edu"));
2457 exit (status
== 0 ? EXIT_SUCCESS
: EXIT_FAILURE
);