summaryrefslogtreecommitdiff
path: root/src/pr.c
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2016-01-20 10:55:18 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2016-01-20 10:55:18 +0000
commit70e9163c9c18e995515598085cb824e554eb7ae7 (patch)
treea42dc8b2a6c031354bf31472de888bfc8a060132 /src/pr.c
parentcbf5993c43f49281173f185863577d86bfac6eae (diff)
downloadcoreutils-tarball-70e9163c9c18e995515598085cb824e554eb7ae7.tar.gz
Diffstat (limited to 'src/pr.c')
-rw-r--r--src/pr.c1821
1 files changed, 888 insertions, 933 deletions
diff --git a/src/pr.c b/src/pr.c
index e0aea22..8885fff 100644
--- a/src/pr.c
+++ b/src/pr.c
@@ -1,10 +1,10 @@
/* pr -- convert text files for printing.
- Copyright (C) 88, 91, 1995-2007 Free Software Foundation, Inc.
+ Copyright (C) 1988-2016 Free Software Foundation, Inc.
- This program is free software; you can redistribute it and/or modify
+ This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -12,11 +12,10 @@
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* By Pete TerMaat, with considerable refinement by Roland Huebner. */
-
+
/* Things to watch: Sys V screws up on ...
pr -n -3 -s: /usr/dict/words
pr -m -o10 -n /usr/dict/words{,,,}
@@ -35,26 +34,26 @@
Concept:
If the input_tab_char differs from the default value TAB
- (`-e[CHAR[...]]' is used), any input text tab is expanded to the
+ ('-e[CHAR[...]]' is used), any input text tab is expanded to the
default width of 8 spaces (compare char_to_clump). - Same as SunOS
does.
The treatment of the number_separator (compare add_line_number):
- The default value TAB of the number_separator (`-n[SEP[...]]') doesn't
- be thought to be an input character. An optional `-e'-input has no
+ The default value TAB of the number_separator ('-n[SEP[...]]') doesn't
+ be thought to be an input character. An optional '-e'-input has no
effect.
- With single column output
only one POSIX requirement has to be met:
The default n-separator should be a TAB. The consequence is a
different width between the number and the text if the output position
- of the separator changes, i.e. it depends upon the left margin used.
+ of the separator changes, i.e., it depends upon the left margin used.
That's not nice but easy-to-use together with the defaults of other
utilities, e.g. sort or cut. - Same as SunOS does.
- With multicolumn output
two conflicting POSIX requirements exist:
- First `default n-separator is TAB', second `output text columns shall
- be of equal width'. Moreover POSIX specifies the number+separator a
- part of the column, together with `-COLUMN' and `-a -COLUMN'.
+ First "default n-separator is TAB", second "output text columns shall
+ be of equal width". Moreover POSIX specifies the number+separator a
+ part of the column, together with '-COLUMN' and '-a -COLUMN'.
(With -m output the number shall occupy each line only once. Exactly
the same situation as single column output exists.)
GNU pr gives priority to the 2nd requirement and observes POSIX
@@ -73,9 +72,9 @@
PAGE_WIDTH may occur.
The interference of the POSIX-compliant small letter options -w and -s:
- (`interference' means `setting a _separator_ with -s switches off the
- column sturctur and the default - not generally - page_width,
- acts on -w option')
+ ("interference" means "setting a _separator_ with -s switches off the
+ column structure and the default - not generally - page_width,
+ acts on -w option")
options: text form / separator: equivalent new options:
-w l -s[x]
--------------------------------------------------------------------
@@ -93,7 +92,7 @@
Options:
Including version 1.22i:
- Some SMALL LETTER options has been redefined with the object of a
+ Some SMALL LETTER options have been redefined with the object of a
better POSIX compliance. The output of some further cases has been
adapted to other UNIXes. A violation of downward compatibility has to
be accepted.
@@ -113,201 +112,200 @@
form feeds produce empty pages.
+FIRST_PAGE[:LAST_PAGE], --pages=FIRST_PAGE[:LAST_PAGE]
- begin [stop] printing with page FIRST_[LAST_]PAGE
+ begin [stop] printing with page FIRST_[LAST_]PAGE
-COLUMN, --columns=COLUMN
- Produce output that is COLUMN columns wide and
- print columns down, unless -a is used. Balance number of
- lines in the columns on each page.
+ Produce output that is COLUMN columns wide and
+ print columns down, unless -a is used. Balance number of
+ lines in the columns on each page.
-a, --across Print columns across rather than down, used
- together with -COLUMN. The input
- one
- two
- three
- four
- will be printed with `-a -3' as
- one two three
- four
+ together with -COLUMN. The input
+ one
+ two
+ three
+ four
+ will be printed with '-a -3' as
+ one two three
+ four
-b Balance columns on the last page.
- -b is no longer an independent option. It's always used
- together with -COLUMN (unless -a is used) to get a
- consistent formulation with "FF set by hand" in input
- files. Each formfeed found terminates the number of lines
- to be read with the actual page. The situation for
- printing columns down is equivalent to that on the last
- page. So we need a balancing.
-
- Keeping -b as an underground option guarantees some
- downward compatibility. Utilities using pr with -b
- (a most frequently used form) still work as usual.
+ -b is no longer an independent option. It's always used
+ together with -COLUMN (unless -a is used) to get a
+ consistent formulation with "FF set by hand" in input
+ files. Each formfeed found terminates the number of lines
+ to be read with the actual page. The situation for
+ printing columns down is equivalent to that on the last
+ page. So we need a balancing.
+
+ Keeping -b as an underground option guarantees some
+ downward compatibility. Utilities using pr with -b
+ (a most frequently used form) still work as usual.
-c, --show-control-chars
- Print unprintable characters as control prefixes.
- Control-g is printed as ^G (use hat notation) and
- octal backslash notation.
+ Print unprintable characters as control prefixes.
+ Control-g is printed as ^G (use hat notation) and
+ octal backslash notation.
-d, --double-space Double space the output.
-D FORMAT, --date-format=FORMAT Use FORMAT for the header date.
-e[CHAR[WIDTH]], --expand-tabs[=CHAR[WIDTH]]
- Expand tabs to spaces on input. Optional argument CHAR
- is the input TAB character. (Default is TAB). Optional
- argument WIDTH is the input TAB character's width.
- (Default is 8.)
+ Expand tabs to spaces on input. Optional argument CHAR
+ is the input TAB character. (Default is TAB). Optional
+ argument WIDTH is the input TAB character's width.
+ (Default is 8.)
-F, -f, --form-feed Use formfeeds instead of newlines to separate
- pages. A three line HEADER is used, no TRAILER with -F,
- without -F both HEADER and TRAILER are made of five lines.
+ pages. A three line HEADER is used, no TRAILER with -F,
+ without -F both HEADER and TRAILER are made of five lines.
-h HEADER, --header=HEADER
- Replace the filename in the header with the string HEADER.
- A centered header is used.
+ Replace the filename in the header with the string HEADER.
+ A centered header is used.
-i[CHAR[WIDTH]], --output-tabs[=CHAR[WIDTH]]
- Replace spaces with tabs on output. Optional argument
- CHAR is the output TAB character. (Default is TAB).
- Optional argument WIDTH is the output TAB character's
- width. (Default is 8)
+ Replace spaces with tabs on output. Optional argument
+ CHAR is the output TAB character. (Default is TAB).
+ Optional argument WIDTH is the output TAB character's
+ width. (Default is 8)
-J, --join-lines Merge lines of full length, turns off -W/-w
- line truncation, no column alignment, --sep-string[=STRING]
- sets separators, works with all column options
- (-COLUMN | -a -COLUMN | -m).
- -J has been introduced (together with -W and --sep-string) to
- disentangle the old (POSIX compliant) options -w, -s
- along with the 3 column options.
+ line truncation, no column alignment, --sep-string[=STRING]
+ sets separators, works with all column options
+ (-COLUMN | -a -COLUMN | -m).
+ -J has been introduced (together with -W and --sep-string) to
+ disentangle the old (POSIX compliant) options -w, -s
+ along with the 3 column options.
-l PAGE_LENGTH, --length=PAGE_LENGTH
- Set the page length to PAGE_LENGTH lines. Default is 66,
- including 5 lines of HEADER and 5 lines of TRAILER
- without -F, but only 3 lines of HEADER and no TRAILER
- with -F (i.e the number of text lines defaults to 56 or
- 63 respectively).
+ Set the page length to PAGE_LENGTH lines. Default is 66,
+ including 5 lines of HEADER and 5 lines of TRAILER
+ without -F, but only 3 lines of HEADER and no TRAILER
+ with -F (i.e the number of text lines defaults to 56 or
+ 63 respectively).
-m, --merge Print files in parallel; pad_across_to align
- columns; truncate lines and print separator strings;
- Do it also with empty columns to get a continuous line
- numbering and column marking by separators throughout
- the whole merged file.
+ columns; truncate lines and print separator strings;
+ Do it also with empty columns to get a continuous line
+ numbering and column marking by separators throughout
+ the whole merged file.
- Empty pages in some input files produce empty columns
- [marked by separators] in the merged pages. Completely
- empty merged pages show no column separators at all.
+ Empty pages in some input files produce empty columns
+ [marked by separators] in the merged pages. Completely
+ empty merged pages show no column separators at all.
- The layout of a merged page is ruled by the largest form
- feed distance of the single pages at that page. Shorter
- columns will be filled up with empty lines.
+ The layout of a merged page is ruled by the largest form
+ feed distance of the single pages at that page. Shorter
+ columns will be filled up with empty lines.
- Together with -J option join lines of full length and
- set separators when -S option is used.
+ Together with -J option join lines of full length and
+ set separators when -S option is used.
-n[SEP[DIGITS]], --number-lines[=SEP[DIGITS]]
- Provide DIGITS digit line numbering (default for DIGITS
- is 5). With multicolumn output the number occupies the
- first DIGITS column positions of each text column or only
- each line of -m output.
- With single column output the number precedes each line
- just as -m output.
- Optional argument SEP is the character appended to the
- line number to separate it from the text followed.
- The default separator is a TAB. In a strict sense a TAB
- is always printed with single column output only. The
- TAB-width varies with the TAB-position, e.g. with the
- left margin specified by -o option.
- With multicolumn output priority is given to `equal width
- of output columns' (a POSIX specification). The TAB-width
- is fixed to the value of the 1st column and does not
- change with different values of left margin. That means a
- fixed number of spaces is always printed in the place of
- a TAB. The tabification depends upon the output
- position.
-
- Default counting of the line numbers starts with 1st
- line of the input file (not the 1st line printed,
- compare the --page option and -N option).
+ Provide DIGITS digit line numbering (default for DIGITS
+ is 5). With multicolumn output the number occupies the
+ first DIGITS column positions of each text column or only
+ each line of -m output.
+ With single column output the number precedes each line
+ just as -m output.
+ Optional argument SEP is the character appended to the
+ line number to separate it from the text followed.
+ The default separator is a TAB. In a strict sense a TAB
+ is always printed with single column output only. The
+ TAB-width varies with the TAB-position, e.g. with the
+ left margin specified by -o option.
+ With multicolumn output priority is given to "equal width
+ of output columns" (a POSIX specification). The TAB-width
+ is fixed to the value of the 1st column and does not
+ change with different values of left margin. That means a
+ fixed number of spaces is always printed in the place of
+ a TAB. The tabification depends upon the output
+ position.
+
+ Default counting of the line numbers starts with 1st
+ line of the input file (not the 1st line printed,
+ compare the --page option and -N option).
-N NUMBER, --first-line-number=NUMBER
- Start line counting with the number NUMBER at the 1st
- line of first page printed (mostly not the 1st line of
- the input file).
+ Start line counting with the number NUMBER at the 1st
+ line of first page printed (mostly not the 1st line of
+ the input file).
-o MARGIN, --indent=MARGIN
- Offset each line with a margin MARGIN spaces wide.
- Total page width is the size of the margin plus the
- PAGE_WIDTH set with -W/-w option.
+ Offset each line with a margin MARGIN spaces wide.
+ Total page width is the size of the margin plus the
+ PAGE_WIDTH set with -W/-w option.
-r, --no-file-warnings
- Omit warning when a file cannot be opened.
+ Omit warning when a file cannot be opened.
-s[CHAR], --separator[=CHAR]
- Separate columns by a single character CHAR, default for
- CHAR is the TAB character without -w and 'no char' with -w.
- Without `-s' default separator `space' is set.
- -s[CHAR] turns off line truncation of all 3 column options
- (-COLUMN|-a -COLUMN|-m) except -w is set. That is a POSIX
- compliant formulation. The source code translates -s into
- the new options -S and -J, also -W if required.
-
- -S STRING, --sep-string[=STRING]
- Separate columns by any string STRING. The -S option
- doesn't react upon the -W/-w option (unlike -s option
- does). It defines a separator nothing else.
- Without -S: Default separator TAB is used with -J and
- `space' otherwise (same as -S" ").
- With -S "": No separator is used.
- Quotes should be used with blanks and some shell active
- characters.
- -S is problematic because in its obsolete form you
- cannot use -S "STRING", but in its standard form you
- must use -S "STRING" if STRING is empty. Use
- --sep-string to avoid the ambiguity.
+ Separate columns by a single character CHAR, default for
+ CHAR is the TAB character without -w and 'no char' with -w.
+ Without '-s' default separator 'space' is set.
+ -s[CHAR] turns off line truncation of all 3 column options
+ (-COLUMN|-a -COLUMN|-m) except -w is set. That is a POSIX
+ compliant formulation. The source code translates -s into
+ the new options -S and -J, also -W if required.
+
+ -S[STRING], --sep-string[=STRING]
+ Separate columns by any string STRING. The -S option
+ doesn't react upon the -W/-w option (unlike -s option
+ does). It defines a separator nothing else.
+ Without -S: Default separator TAB is used with -J and
+ 'space' otherwise (same as -S" ").
+ With -S "": No separator is used.
+ Quotes should be used with blanks and some shell active
+ characters.
+ -S is problematic because in its obsolete form you
+ cannot use -S "STRING", but in its standard form you
+ must use -S "STRING" if STRING is empty. Use
+ --sep-string to avoid the ambiguity.
-t, --omit-header Do not print headers or footers but retain form
- feeds set in the input files.
+ feeds set in the input files.
-T, --omit-pagination
- Do not print headers or footers, eliminate any pagination
- by form feeds set in the input files.
+ Do not print headers or footers, eliminate any pagination
+ by form feeds set in the input files.
-v, --show-nonprinting
- Print unprintable characters as escape sequences. Use
- octal backslash notation. Control-G becomes \007.
+ Print unprintable characters as escape sequences. Use
+ octal backslash notation. Control-G becomes \007.
-w PAGE_WIDTH, --width=PAGE_WIDTH
- Set page width to PAGE_WIDTH characters for multiple
- text-column output only (default for PAGE_WIDTH is 72).
- -s[CHAR] turns off the default page width and any line
- truncation. Lines of full length will be merged,
- regardless of the column options set. A POSIX compliant
- formulation.
+ Set page width to PAGE_WIDTH characters for multiple
+ text-column output only (default for PAGE_WIDTH is 72).
+ -s[CHAR] turns off the default page width and any line
+ truncation. Lines of full length will be merged,
+ regardless of the column options set. A POSIX compliant
+ formulation.
-W PAGE_WIDTH, --page-width=PAGE_WIDTH
- Set the page width to PAGE_WIDTH characters. That's valid
- with and without a column option. Text lines will be
- truncated, unless -J is used. Together with one of the
- column options (-COLUMN| -a -COLUMN| -m) column alignment
- is always used.
- Default is 72 characters.
- Without -W PAGE_WIDTH
- - but with one of the column options default truncation of
- 72 characters is used (to keep downward compatibility
- and to simplify most frequently met column tasks).
- Column alignment and column separators are used.
- - and without any of the column options NO line truncation
- is used (to keep downward compatibility and to meet most
- frequent tasks). That's equivalent to -W 72 -J .
-
- With/without -W PAGE_WIDTH the header line is always
- truncated to avoid line overflow.
-
- (In pr versions newer than 1.14 -S option does no longer
- affect -W option.)
+ Set the page width to PAGE_WIDTH characters. That's valid
+ with and without a column option. Text lines will be
+ truncated, unless -J is used. Together with one of the
+ column options (-COLUMN| -a -COLUMN| -m) column alignment
+ is always used.
+ Default is 72 characters.
+ Without -W PAGE_WIDTH
+ - but with one of the column options default truncation of
+ 72 characters is used (to keep downward compatibility
+ and to simplify most frequently met column tasks).
+ Column alignment and column separators are used.
+ - and without any of the column options NO line truncation
+ is used (to keep downward compatibility and to meet most
+ frequent tasks). That's equivalent to -W 72 -J .
+
+ With/without -W PAGE_WIDTH the header line is always
+ truncated to avoid line overflow.
+
+ (In pr versions newer than 1.14 -S option does no longer
+ affect -W option.)
*/
-
#include <config.h>
@@ -315,19 +313,22 @@
#include <sys/types.h>
#include "system.h"
#include "error.h"
+#include "fadvise.h"
#include "hard-locale.h"
-#include "inttostr.h"
#include "mbswidth.h"
#include "quote.h"
#include "stat-time.h"
#include "stdio--.h"
#include "strftime.h"
#include "xstrtol.h"
+#include "xdectoint.h"
-/* The official name of this program (e.g., no `g' prefix). */
+/* The official name of this program (e.g., no 'g' prefix). */
#define PROGRAM_NAME "pr"
-#define AUTHORS "Pete TerMaat", "Roland Huebner"
+#define AUTHORS \
+ proper_name ("Pete TerMaat"), \
+ proper_name ("Roland Huebner")
/* Used with start_position in the struct COLUMN described below.
If start_position == ANYWHERE, we aren't truncating columns and
@@ -349,27 +350,27 @@
fit the same printing loop.
print_func Function used to print lines in this column.
- If we're storing this column it will be
- print_stored(), Otherwise it will be read_line().
+ If we're storing this column it will be
+ print_stored(), Otherwise it will be read_line().
char_func Function used to process characters in this column.
- If we're storing this column it will be store_char(),
- otherwise it will be print_char().
+ If we're storing this column it will be store_char(),
+ otherwise it will be print_char().
current_line Index of the current entry in line_vector, which
- contains the index of the first character of the
- current line in buff[].
+ contains the index of the first character of the
+ current line in buff[].
lines_stored Number of lines in this column which are stored in
- buff.
+ buff.
lines_to_print If we're storing this column, lines_to_print is
- the number of stored_lines which remain to be
- printed. Otherwise it is the number of lines
- we can print without exceeding lines_per_body.
+ the number of stored_lines which remain to be
+ printed. Otherwise it is the number of lines
+ we can print without exceeding lines_per_body.
start_position The horizontal position we want to be in before we
- print the first character in this column.
+ print the first character in this column.
numbered True means precede this column with a line number. */
@@ -385,11 +386,11 @@ struct COLUMN
char const *name; /* File name. */
enum
{
- OPEN,
- FF_FOUND, /* used with -b option, set with \f, changed
- to ON_HOLD after print_header */
- ON_HOLD, /* Hit a form feed. */
- CLOSED
+ OPEN,
+ FF_FOUND, /* used with -b option, set with \f, changed
+ to ON_HOLD after print_header */
+ ON_HOLD, /* Hit a form feed. */
+ CLOSED
}
status; /* Status of the file pointer. */
@@ -414,8 +415,6 @@ struct COLUMN
typedef struct COLUMN COLUMN;
-#define NULLCOL (COLUMN *)0
-
static int char_to_clump (char c);
static bool read_line (COLUMN *p);
static bool print_page (void);
@@ -425,9 +424,10 @@ static bool skip_to_page (uintmax_t page);
static void print_header (void);
static void pad_across_to (int position);
static void add_line_number (COLUMN *p);
+static void getoptnum (const char *n_str, int min, int *num,
+ const char *errfmt);
static void getoptarg (char *arg, char switch_char, char *character,
- int *number);
-void usage (int status);
+ int *number);
static void print_files (int number_of_files, char **av);
static void init_parameters (int number_of_files);
static void init_header (char const *filename, int desc);
@@ -437,7 +437,7 @@ static void init_store_cols (void);
static void store_columns (void);
static void balance (int total_stored);
static void store_char (char c);
-static void pad_down (int lines);
+static void pad_down (unsigned int lines);
static void read_rest_of_line (COLUMN *p);
static void skip_read (COLUMN *p, int column_number);
static void print_char (char c);
@@ -445,9 +445,6 @@ static void cleanup (void);
static void print_sep_string (void);
static void separator_string (const char *optarg_S);
-/* The name under which this program was invoked. */
-char *program_name;
-
/* All of the columns to print. */
static COLUMN *column_vector;
@@ -459,7 +456,7 @@ static char *buff;
/* Index of the position in buff where the next character
will be stored. */
-static int buff_current;
+static unsigned int buff_current;
/* The number of characters in buff.
Used for allocation of buff and to detect overflow of buff. */
@@ -471,7 +468,7 @@ static size_t buff_allocated;
we do column balancing on the last page. */
static int *line_vector;
-/* Array of horizonal positions.
+/* Array of horizontal positions.
For each line in line_vector, end_vector[line] is the horizontal
position we are in after printing that line. We keep track of this
so that we know how much we need to pad to prepare for the next
@@ -536,9 +533,9 @@ static int lines_per_page = 66;
/* Number of lines in the header and footer can be reset to 0 using
the -t flag. */
-static int lines_per_header = 5;
+enum { lines_per_header = 5 };
static int lines_per_body;
-static int lines_per_footer = 5;
+enum { lines_per_footer = 5 };
/* (-w|-W) Width in characters of the page. Does not include the width of
the margin. */
@@ -635,10 +632,6 @@ static uintmax_t page_number;
2 moo 4 hoo 6 zoo */
static int line_number;
-/* With line_number overflow, we use power_10 to cut off the higher-order
- digits of the line_number */
-static int power_10;
-
/* (-n) True means lines should be preceded by numbers. */
static bool numbered_lines = false;
@@ -693,11 +686,11 @@ static bool use_col_separator = false;
/* String used to separate columns if the -S option has been specified.
Default without -S but together with one of the column options
- -a|COLUMN|-m is a `space' and with the -J option a `tab'. */
-static char *col_sep_string = "";
+ -a|COLUMN|-m is a 'space' and with the -J option a 'tab'. */
+static char *col_sep_string = (char *) "";
static int col_sep_length = 0;
-static char *column_separator = " ";
-static char *line_separator = "\t";
+static char *column_separator = (char *) " ";
+static char *line_separator = (char *) "\t";
/* Number of separator characters waiting to be printed as soon as we
know that we have any input remaining to be printed. */
@@ -777,18 +770,18 @@ static struct option const long_options[] =
/* Return the number of columns that have either an open file or
stored lines. */
-static int
+static unsigned int _GL_ATTRIBUTE_PURE
cols_ready_to_print (void)
{
COLUMN *q;
- int i;
- int n;
+ unsigned int i;
+ unsigned int n;
n = 0;
for (q = column_vector, i = 0; i < columns; ++q, ++i)
- if (q->status == OPEN ||
- q->status == FF_FOUND || /* With -b: To print a header only */
- (storing_columns && q->lines_stored > 0 && q->lines_to_print > 0))
+ if (q->status == OPEN
+ || q->status == FF_FOUND /* With -b: To print a header only */
+ || (storing_columns && q->lines_stored > 0 && q->lines_to_print > 0))
++n;
return n;
}
@@ -797,14 +790,14 @@ cols_ready_to_print (void)
using option +FIRST_PAGE:LAST_PAGE */
static bool
-first_last_page (char const *pages)
+first_last_page (int oi, char c, char const *pages)
{
char *p;
uintmax_t first;
uintmax_t last = UINTMAX_MAX;
strtol_error err = xstrtoumax (pages, &p, 10, &first, "");
if (err != LONGINT_OK && err != LONGINT_INVALID_SUFFIX_CHAR)
- _STRTOL_ERROR (EXIT_FAILURE, pages, _("page range"), err);
+ xstrtol_fatal (err, oi, c, long_options, pages);
if (p == pages || !first)
return false;
@@ -814,9 +807,9 @@ first_last_page (char const *pages)
char const *p1 = p + 1;
err = xstrtoumax (p1, &p, 10, &last, "");
if (err != LONGINT_OK)
- _STRTOL_ERROR (EXIT_FAILURE, pages, _("page range"), err);
+ xstrtol_fatal (err, oi, c, long_options, pages);
if (p1 == p || last < first)
- return false;
+ return false;
}
if (*p)
@@ -828,19 +821,13 @@ first_last_page (char const *pages)
}
/* Parse column count string S, and if it's valid (1 or larger and
- within range of the type of `columns') set the global variables
- columns and explicit_columns and return true.
- Otherwise, exit with a diagnostic. */
+ within range of the type of 'columns') set the global variables
+ columns and explicit_columns. Otherwise, exit with a diagnostic. */
+
static void
parse_column_count (char const *s)
{
- long int tmp_long;
- if (xstrtol (s, NULL, 10, &tmp_long, "") != LONGINT_OK
- || !(1 <= tmp_long && tmp_long <= INT_MAX))
- error (EXIT_FAILURE, 0,
- _("invalid number of columns: %s"), quote (s));
-
- columns = tmp_long;
+ getoptnum (s, 1, &columns, _("invalid number of columns"));
explicit_columns = true;
}
@@ -857,7 +844,6 @@ separator_string (const char *optarg_S)
int
main (int argc, char **argv)
{
- int c;
int n_files;
bool old_options = false;
bool old_w = false;
@@ -870,7 +856,7 @@ main (int argc, char **argv)
size_t n_alloc = 0;
initialize_main (&argc, &argv);
- program_name = argv[0];
+ set_program_name (argv[0]);
setlocale (LC_ALL, "");
bindtextdomain (PACKAGE, LOCALEDIR);
textdomain (PACKAGE);
@@ -879,207 +865,177 @@ main (int argc, char **argv)
n_files = 0;
file_names = (argc > 1
- ? xmalloc ((argc - 1) * sizeof (char *))
- : NULL);
+ ? xmalloc ((argc - 1) * sizeof (char *))
+ : NULL);
- while ((c = getopt_long (argc, argv, short_options, long_options, NULL))
- != -1)
+ while (true)
{
+ int oi = -1;
+ int c = getopt_long (argc, argv, short_options, long_options, &oi);
+ if (c == -1)
+ break;
+
if (ISDIGIT (c))
- {
- /* Accumulate column-count digits specified via old-style options. */
- if (n_digits + 1 >= n_alloc)
- column_count_string
- = X2REALLOC (column_count_string, &n_alloc);
- column_count_string[n_digits++] = c;
- column_count_string[n_digits] = '\0';
- continue;
- }
+ {
+ /* Accumulate column-count digits specified via old-style options. */
+ if (n_digits + 1 >= n_alloc)
+ column_count_string
+ = X2REALLOC (column_count_string, &n_alloc);
+ column_count_string[n_digits++] = c;
+ column_count_string[n_digits] = '\0';
+ continue;
+ }
n_digits = 0;
switch (c)
- {
- case 1: /* Non-option argument. */
- /* long option --page dominates old `+FIRST_PAGE ...'. */
- if (! (first_page_number == 0
- && *optarg == '+' && first_last_page (optarg + 1)))
- file_names[n_files++] = optarg;
- break;
-
- case PAGES_OPTION: /* --pages=FIRST_PAGE[:LAST_PAGE] */
- { /* dominates old opt +... */
- if (! optarg)
- error (EXIT_FAILURE, 0,
- _("`--pages=FIRST_PAGE[:LAST_PAGE]' missing argument"));
- else if (! first_last_page (optarg))
- error (EXIT_FAILURE, 0, _("Invalid page range %s"),
- quote (optarg));
- break;
- }
-
- case COLUMNS_OPTION: /* --columns=COLUMN */
- {
- parse_column_count (optarg);
-
- /* If there was a prior column count specified via the
- short-named option syntax, e.g., -9, ensure that this
- long-name-specified value overrides it. */
- free (column_count_string);
- column_count_string = NULL;
- n_alloc = 0;
- break;
- }
-
- case 'a':
- print_across_flag = true;
- storing_columns = false;
- break;
- case 'b':
- balance_columns = true;
- break;
- case 'c':
- use_cntrl_prefix = true;
- break;
- case 'd':
- double_space = true;
- break;
- case 'D':
- date_format = optarg;
- break;
- case 'e':
- if (optarg)
- getoptarg (optarg, 'e', &input_tab_char,
- &chars_per_input_tab);
- /* Could check tab width > 0. */
- untabify_input = true;
- break;
- case 'f':
- case 'F':
- use_form_feed = true;
- break;
- case 'h':
- custom_header = optarg;
- break;
- case 'i':
- if (optarg)
- getoptarg (optarg, 'i', &output_tab_char,
- &chars_per_output_tab);
- /* Could check tab width > 0. */
- tabify_output = true;
- break;
- case 'J':
- join_lines = true;
- break;
- case 'l':
- {
- long int tmp_long;
- if (xstrtol (optarg, NULL, 10, &tmp_long, "") != LONGINT_OK
- || tmp_long <= 0 || tmp_long > INT_MAX)
- {
- error (EXIT_FAILURE, 0,
- _("`-l PAGE_LENGTH' invalid number of lines: %s"),
- quote (optarg));
- }
- lines_per_page = tmp_long;
- break;
- }
- case 'm':
- parallel_files = true;
- storing_columns = false;
- break;
- case 'n':
- numbered_lines = true;
- if (optarg)
- getoptarg (optarg, 'n', &number_separator,
- &chars_per_number);
- break;
- case 'N':
- skip_count = false;
- {
- long int tmp_long;
- if (xstrtol (optarg, NULL, 10, &tmp_long, "") != LONGINT_OK
- || tmp_long > INT_MAX)
- {
- error (EXIT_FAILURE, 0,
- _("`-N NUMBER' invalid starting line number: %s"),
- quote (optarg));
- }
- start_line_num = tmp_long;
- break;
- }
- case 'o':
- {
- long int tmp_long;
- if (xstrtol (optarg, NULL, 10, &tmp_long, "") != LONGINT_OK
- || tmp_long < 0 || tmp_long > INT_MAX)
- error (EXIT_FAILURE, 0,
- _("`-o MARGIN' invalid line offset: %s"), quote (optarg));
- chars_per_margin = tmp_long;
- break;
- }
- case 'r':
- ignore_failed_opens = true;
- break;
- case 's':
- old_options = true;
- old_s = true;
- if (!use_col_separator && optarg)
- separator_string (optarg);
- break;
- case 'S':
- old_s = false;
- /* Reset an additional input of -s, -S dominates -s */
- col_sep_string = "";
- col_sep_length = 0;
- use_col_separator = true;
- if (optarg)
- separator_string (optarg);
- break;
- case 't':
- extremities = false;
- keep_FF = true;
- break;
- case 'T':
- extremities = false;
- keep_FF = false;
- break;
- case 'v':
- use_esc_sequence = true;
- break;
- case 'w':
- old_options = true;
- old_w = true;
- {
- long int tmp_long;
- if (xstrtol (optarg, NULL, 10, &tmp_long, "") != LONGINT_OK
- || tmp_long <= 0 || tmp_long > INT_MAX)
- error (EXIT_FAILURE, 0,
- _("`-w PAGE_WIDTH' invalid number of characters: %s"),
- quote (optarg));
- if (!truncate_lines)
- chars_per_line = tmp_long;
- break;
- }
- case 'W':
- old_w = false; /* dominates -w */
- truncate_lines = true;
- {
- long int tmp_long;
- if (xstrtol (optarg, NULL, 10, &tmp_long, "") != LONGINT_OK
- || tmp_long <= 0 || tmp_long > INT_MAX)
- error (EXIT_FAILURE, 0,
- _("`-W PAGE_WIDTH' invalid number of characters: %s"),
- quote (optarg));
- chars_per_line = tmp_long;
- break;
- }
- case_GETOPT_HELP_CHAR;
- case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
- default:
- usage (EXIT_FAILURE);
- break;
- }
+ {
+ case 1: /* Non-option argument. */
+ /* long option --page dominates old '+FIRST_PAGE ...'. */
+ if (! (first_page_number == 0
+ && *optarg == '+' && first_last_page (-2, '+', optarg + 1)))
+ file_names[n_files++] = optarg;
+ break;
+
+ case PAGES_OPTION: /* --pages=FIRST_PAGE[:LAST_PAGE] */
+ { /* dominates old opt +... */
+ if (! optarg)
+ error (EXIT_FAILURE, 0,
+ _("'--pages=FIRST_PAGE[:LAST_PAGE]' missing argument"));
+ else if (! first_last_page (oi, 0, optarg))
+ error (EXIT_FAILURE, 0, _("invalid page range %s"),
+ quote (optarg));
+ break;
+ }
+
+ case COLUMNS_OPTION: /* --columns=COLUMN */
+ {
+ parse_column_count (optarg);
+
+ /* If there was a prior column count specified via the
+ short-named option syntax, e.g., -9, ensure that this
+ long-name-specified value overrides it. */
+ free (column_count_string);
+ column_count_string = NULL;
+ n_alloc = 0;
+ break;
+ }
+
+ case 'a':
+ print_across_flag = true;
+ storing_columns = false;
+ break;
+ case 'b':
+ balance_columns = true;
+ break;
+ case 'c':
+ use_cntrl_prefix = true;
+ break;
+ case 'd':
+ double_space = true;
+ break;
+ case 'D':
+ date_format = optarg;
+ break;
+ case 'e':
+ if (optarg)
+ getoptarg (optarg, 'e', &input_tab_char,
+ &chars_per_input_tab);
+ /* Could check tab width > 0. */
+ untabify_input = true;
+ break;
+ case 'f':
+ case 'F':
+ use_form_feed = true;
+ break;
+ case 'h':
+ custom_header = optarg;
+ break;
+ case 'i':
+ if (optarg)
+ getoptarg (optarg, 'i', &output_tab_char,
+ &chars_per_output_tab);
+ /* Could check tab width > 0. */
+ tabify_output = true;
+ break;
+ case 'J':
+ join_lines = true;
+ break;
+ case 'l':
+ getoptnum (optarg, 1, &lines_per_page,
+ _("'-l PAGE_LENGTH' invalid number of lines"));
+ break;
+ case 'm':
+ parallel_files = true;
+ storing_columns = false;
+ break;
+ case 'n':
+ numbered_lines = true;
+ if (optarg)
+ getoptarg (optarg, 'n', &number_separator,
+ &chars_per_number);
+ break;
+ case 'N':
+ skip_count = false;
+ getoptnum (optarg, INT_MIN, &start_line_num,
+ _("'-N NUMBER' invalid starting line number"));
+ break;
+ case 'o':
+ getoptnum (optarg, 0, &chars_per_margin,
+ _("'-o MARGIN' invalid line offset"));
+ break;
+ case 'r':
+ ignore_failed_opens = true;
+ break;
+ case 's':
+ old_options = true;
+ old_s = true;
+ if (!use_col_separator && optarg)
+ separator_string (optarg);
+ break;
+ case 'S':
+ old_s = false;
+ /* Reset an additional input of -s, -S dominates -s */
+ col_sep_string = bad_cast ("");
+ col_sep_length = 0;
+ use_col_separator = true;
+ if (optarg)
+ separator_string (optarg);
+ break;
+ case 't':
+ extremities = false;
+ keep_FF = true;
+ break;
+ case 'T':
+ extremities = false;
+ keep_FF = false;
+ break;
+ case 'v':
+ use_esc_sequence = true;
+ break;
+ case 'w':
+ old_options = true;
+ old_w = true;
+ {
+ int tmp_cpl;
+ getoptnum (optarg, 1, &tmp_cpl,
+ _("'-w PAGE_WIDTH' invalid number of characters"));
+ if (! truncate_lines)
+ chars_per_line = tmp_cpl;
+ }
+ break;
+ case 'W':
+ old_w = false; /* dominates -w */
+ truncate_lines = true;
+ getoptnum (optarg, 1, &chars_per_line,
+ _("'-W PAGE_WIDTH' invalid number of characters"));
+ break;
+ case_GETOPT_HELP_CHAR;
+ case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
+ default:
+ usage (EXIT_FAILURE);
+ break;
+ }
}
if (column_count_string)
@@ -1090,20 +1046,20 @@ main (int argc, char **argv)
if (! date_format)
date_format = (getenv ("POSIXLY_CORRECT") && !hard_locale (LC_TIME)
- ? "%b %e %H:%M %Y"
- : "%Y-%m-%d %H:%M");
+ ? "%b %e %H:%M %Y"
+ : "%Y-%m-%d %H:%M");
/* Now we can set a reasonable initial value: */
if (first_page_number == 0)
first_page_number = 1;
- if (parallel_files & explicit_columns)
+ if (parallel_files && explicit_columns)
error (EXIT_FAILURE, 0,
- _("Cannot specify number of columns when printing in parallel."));
+ _("cannot specify number of columns when printing in parallel"));
- if (parallel_files & print_across_flag)
+ if (parallel_files && print_across_flag)
error (EXIT_FAILURE, 0,
- _("Cannot specify both printing across and printing in parallel."));
+ _("cannot specify both printing across and printing in parallel"));
/* Translate some old short options to new/long options.
To meet downward compatibility with other UNIX pr utilities
@@ -1113,41 +1069,41 @@ main (int argc, char **argv)
{
if (old_w)
{
- if (parallel_files | explicit_columns)
- {
- /* activate -W */
- truncate_lines = true;
- if (old_s)
- /* adapt HP-UX and SunOS: -s = no separator;
- activate -S */
- use_col_separator = true;
- }
- else
- /* old -w sets width with columns only
- activate -J */
- join_lines = true;
- }
+ if (parallel_files || explicit_columns)
+ {
+ /* activate -W */
+ truncate_lines = true;
+ if (old_s)
+ /* adapt HP-UX and SunOS: -s = no separator;
+ activate -S */
+ use_col_separator = true;
+ }
+ else
+ /* old -w sets width with columns only
+ activate -J */
+ join_lines = true;
+ }
else if (!use_col_separator)
{
- /* No -S option read */
- if (old_s & (parallel_files | explicit_columns))
- {
- if (!truncate_lines)
- {
- /* old -s (without -w and -W) annuls column alignment,
- uses fields, activate -J */
- join_lines = true;
- if (col_sep_length > 0)
- /* activate -S */
- use_col_separator = true;
- }
- else
- /* with -W */
- /* adapt HP-UX and SunOS: -s = no separator;
- activate -S */
- use_col_separator = true;
- }
- }
+ /* No -S option read */
+ if (old_s && (parallel_files || explicit_columns))
+ {
+ if (!truncate_lines)
+ {
+ /* old -s (without -w and -W) annuls column alignment,
+ uses fields, activate -J */
+ join_lines = true;
+ if (col_sep_length > 0)
+ /* activate -S */
+ use_col_separator = true;
+ }
+ else
+ /* with -W */
+ /* adapt HP-UX and SunOS: -s = no separator;
+ activate -S */
+ use_col_separator = true;
+ }
+ }
}
for (; optind < argc; optind++)
@@ -1163,22 +1119,30 @@ main (int argc, char **argv)
else
{
if (parallel_files)
- print_files (n_files, file_names);
+ print_files (n_files, file_names);
else
- {
- int i;
- for (i = 0; i < n_files; i++)
- print_files (1, &file_names[i]);
- }
+ {
+ unsigned int i;
+ for (i = 0; i < n_files; i++)
+ print_files (1, &file_names[i]);
+ }
}
cleanup ();
+ IF_LINT (free (file_names));
if (have_read_stdin && fclose (stdin) == EOF)
error (EXIT_FAILURE, errno, _("standard input"));
- if (failed_opens)
- exit (EXIT_FAILURE);
- exit (EXIT_SUCCESS);
+ return failed_opens ? EXIT_FAILURE : EXIT_SUCCESS;
+}
+
+/* Parse numeric arguments, ensuring MIN <= number <= INT_MAX. */
+
+static void
+getoptnum (const char *n_str, int min, int *num, const char *err)
+{
+ intmax_t tnum = xdectoimax (n_str, min, INT_MAX, "", err, 0);
+ *num = tnum;
}
/* Parse options of the form -scNNN.
@@ -1196,17 +1160,17 @@ getoptarg (char *arg, char switch_char, char *character, int *number)
{
long int tmp_long;
if (xstrtol (arg, NULL, 10, &tmp_long, "") != LONGINT_OK
- || tmp_long <= 0 || tmp_long > INT_MAX)
- {
- error (0, 0,
- _("`-%c' extra characters or invalid number in the argument: %s"),
- switch_char, quote (arg));
- usage (EXIT_FAILURE);
- }
+ || tmp_long <= 0 || INT_MAX < tmp_long)
+ {
+ error (0, INT_MAX < tmp_long ? EOVERFLOW : errno,
+ _("'-%c' extra characters or invalid number in the argument: %s"),
+ switch_char, quote (arg));
+ usage (EXIT_FAILURE);
+ }
*number = tmp_long;
}
}
-
+
/* Set parameters related to formatting. */
static void
@@ -1214,12 +1178,6 @@ init_parameters (int number_of_files)
{
int chars_used_by_number = 0;
- if (use_form_feed)
- {
- lines_per_header = 3;
- lines_per_footer = 0;
- }
-
lines_per_body = lines_per_page - lines_per_header - lines_per_footer;
if (lines_per_body <= 0)
{
@@ -1249,16 +1207,16 @@ init_parameters (int number_of_files)
if (columns > 1)
{
if (!use_col_separator)
- {
- /* Use default separator */
- if (join_lines)
- col_sep_string = line_separator;
- else
- col_sep_string = column_separator;
-
- col_sep_length = 1;
- use_col_separator = true;
- }
+ {
+ /* Use default separator */
+ if (join_lines)
+ col_sep_string = line_separator;
+ else
+ col_sep_string = column_separator;
+
+ col_sep_length = 1;
+ use_col_separator = true;
+ }
/* It's rather pointless to define a TAB separator with column
alignment */
else if (!join_lines && *col_sep_string == '\t')
@@ -1276,37 +1234,30 @@ init_parameters (int number_of_files)
if (numbered_lines)
{
- int tmp_i;
int chars_per_default_tab = 8;
line_count = start_line_num;
/* To allow input tab-expansion (-e sensitive) use:
- if (number_separator == input_tab_char)
- number_width = chars_per_number +
- TAB_WIDTH (chars_per_input_tab, chars_per_number); */
+ if (number_separator == input_tab_char)
+ number_width = chars_per_number
+ + TAB_WIDTH (chars_per_input_tab, chars_per_number); */
/* Estimate chars_per_text without any margin and keep it constant. */
if (number_separator == '\t')
- number_width = chars_per_number +
- TAB_WIDTH (chars_per_default_tab, chars_per_number);
+ number_width = (chars_per_number
+ + TAB_WIDTH (chars_per_default_tab, chars_per_number));
else
- number_width = chars_per_number + 1;
+ number_width = chars_per_number + 1;
/* The number is part of the column width unless we are
- printing files in parallel. */
+ printing files in parallel. */
if (parallel_files)
- chars_used_by_number = number_width;
-
- /* We use power_10 to cut off the higher-order digits of the
- line_number in function add_line_number */
- tmp_i = chars_per_number;
- for (power_10 = 1; tmp_i > 0; --tmp_i)
- power_10 = 10 * power_10;
+ chars_used_by_number = number_width;
}
- chars_per_column = (chars_per_line - chars_used_by_number -
- (columns - 1) * col_sep_length) / columns;
+ chars_per_column = (chars_per_line - chars_used_by_number
+ - (columns - 1) * col_sep_length) / columns;
if (chars_per_column < 1)
error (EXIT_FAILURE, 0, _("page width too narrow"));
@@ -1314,7 +1265,8 @@ init_parameters (int number_of_files)
if (numbered_lines)
{
free (number_buff);
- number_buff = xmalloc (2 * chars_per_number);
+ number_buff = xmalloc (MAX (chars_per_number,
+ INT_STRLEN_BOUND (line_number)) + 1);
}
/* Pick the maximum between the tab width and the width of an
@@ -1325,7 +1277,7 @@ init_parameters (int number_of_files)
free (clump_buff);
clump_buff = xmalloc (MAX (8, chars_per_input_tab));
}
-
+
/* Open the necessary files,
maintaining a COLUMN structure for each column.
@@ -1354,54 +1306,54 @@ init_fps (int number_of_files, char **av)
{
files_left = number_of_files;
for (p = column_vector; files_left--; ++p, ++av)
- {
- if (! open_file (*av, p))
- {
- --p;
- --columns;
- }
- }
+ {
+ if (! open_file (*av, p))
+ {
+ --p;
+ --columns;
+ }
+ }
if (columns == 0)
- return false;
+ return false;
init_header ("", -1);
}
else
{
p = column_vector;
if (number_of_files > 0)
- {
- if (! open_file (*av, p))
- return false;
- init_header (*av, fileno (p->fp));
- p->lines_stored = 0;
- }
+ {
+ if (! open_file (*av, p))
+ return false;
+ init_header (*av, fileno (p->fp));
+ p->lines_stored = 0;
+ }
else
- {
- p->name = _("standard input");
- p->fp = stdin;
- have_read_stdin = true;
- p->status = OPEN;
- p->full_page_printed = false;
- ++total_files;
- init_header ("", -1);
- p->lines_stored = 0;
- }
+ {
+ p->name = _("standard input");
+ p->fp = stdin;
+ have_read_stdin = true;
+ p->status = OPEN;
+ p->full_page_printed = false;
+ ++total_files;
+ init_header ("", -1);
+ p->lines_stored = 0;
+ }
firstname = p->name;
firstfp = p->fp;
for (i = columns - 1, ++p; i; --i, ++p)
- {
- p->name = firstname;
- p->fp = firstfp;
- p->status = OPEN;
- p->full_page_printed = false;
- p->lines_stored = 0;
- }
+ {
+ p->name = firstname;
+ p->fp = firstfp;
+ p->status = OPEN;
+ p->full_page_printed = false;
+ p->lines_stored = 0;
+ }
}
files_ready_to_read = total_files;
return true;
}
-
+
/* Determine print_func and char_func, the functions
used by each column for printing and/or storing.
@@ -1421,12 +1373,12 @@ init_funcs (void)
else
{
/* When numbering lines of parallel files, we enlarge the
- first column to accomodate the number. Looks better than
+ first column to accommodate the number. Looks better than
the Sys V approach. */
- if (parallel_files & numbered_lines)
- h_next = h + chars_per_column + number_width;
+ if (parallel_files && numbered_lines)
+ h_next = h + chars_per_column + number_width;
else
- h_next = h + chars_per_column;
+ h_next = h + chars_per_column;
}
/* Enlarge p->start_position of first column to use the same form of
@@ -1438,16 +1390,16 @@ init_funcs (void)
for (p = column_vector, i = 1; i < columns; ++p, ++i)
{
if (storing_columns) /* One file, multi columns down. */
- {
- p->char_func = store_char;
- p->print_func = print_stored;
- }
+ {
+ p->char_func = store_char;
+ p->print_func = print_stored;
+ }
else
- /* One file, multi columns across; or parallel files. */
- {
- p->char_func = print_char;
- p->print_func = read_line;
- }
+ /* One file, multi columns across; or parallel files. */
+ {
+ p->char_func = print_char;
+ p->print_func = read_line;
+ }
/* Number only the first column when printing files in
parallel. */
@@ -1459,22 +1411,22 @@ init_funcs (void)
using a margin. */
if (!truncate_lines)
- {
- h = ANYWHERE;
- h_next = ANYWHERE;
- }
+ {
+ h = ANYWHERE;
+ h_next = ANYWHERE;
+ }
else
- {
- h = h_next + col_sep_length;
- h_next = h + chars_per_column;
- }
+ {
+ h = h_next + col_sep_length;
+ h_next = h + chars_per_column;
+ }
}
/* The rightmost column.
Doesn't need to be stored unless we intend to balance
columns on the last page. */
- if (storing_columns & balance_columns)
+ if (storing_columns && balance_columns)
{
p->char_func = store_char;
p->print_func = print_stored;
@@ -1488,7 +1440,7 @@ init_funcs (void)
p->numbered = numbered_lines && (!parallel_files || i == 1);
p->start_position = h;
}
-
+
/* Open a file. Return true if successful.
With each file p, p->full_page_printed is initialized,
@@ -1512,9 +1464,10 @@ open_file (char *name, COLUMN *p)
{
failed_opens = true;
if (!ignore_failed_opens)
- error (0, errno, "%s", name);
+ error (0, errno, "%s", quotef (name));
return false;
}
+ fadvise (p->fp, FADVISE_SEQUENTIAL);
p->status = OPEN;
p->full_page_printed = false;
++total_files;
@@ -1535,20 +1488,20 @@ close_file (COLUMN *p)
if (p->status == CLOSED)
return;
if (ferror (p->fp))
- error (EXIT_FAILURE, errno, "%s", p->name);
+ error (EXIT_FAILURE, errno, "%s", quotef (p->name));
if (fileno (p->fp) != STDIN_FILENO && fclose (p->fp) != 0)
- error (EXIT_FAILURE, errno, "%s", p->name);
+ error (EXIT_FAILURE, errno, "%s", quotef (p->name));
if (!parallel_files)
{
for (q = column_vector, i = columns; i; ++q, --i)
- {
- q->status = CLOSED;
- if (q->lines_stored == 0)
- {
- q->lines_to_print = 0;
- }
- }
+ {
+ q->status = CLOSED;
+ if (q->lines_stored == 0)
+ {
+ q->lines_to_print = 0;
+ }
+ }
}
else
{
@@ -1574,10 +1527,10 @@ hold_file (COLUMN *p)
if (!parallel_files)
for (q = column_vector, i = columns; i; ++q, --i)
{
- if (storing_columns)
- q->status = FF_FOUND;
- else
- q->status = ON_HOLD;
+ if (storing_columns)
+ q->status = FF_FOUND;
+ else
+ q->status = ON_HOLD;
}
else
p->status = ON_HOLD;
@@ -1598,8 +1551,8 @@ reset_status (void)
for (p = column_vector; i; --i, ++p)
if (p->status == ON_HOLD)
{
- p->status = OPEN;
- files_ready_to_read++;
+ p->status = OPEN;
+ files_ready_to_read++;
}
if (storing_columns)
@@ -1611,7 +1564,7 @@ reset_status (void)
files_ready_to_read = 1;
}
}
-
+
/* Print a single file, or multiple files in parallel.
Set up the list of columns, opening the necessary files.
@@ -1633,9 +1586,9 @@ print_files (int number_of_files, char **av)
if (first_page_number > 1)
{
if (!skip_to_page (first_page_number))
- return;
+ return;
else
- page_number = first_page_number;
+ page_number = first_page_number;
}
else
page_number = 1;
@@ -1646,7 +1599,7 @@ print_files (int number_of_files, char **av)
while (print_page ())
;
}
-
+
/* Initialize header information.
If DESC is non-negative, it is a file descriptor open to
FILENAME for reading. */
@@ -1669,7 +1622,7 @@ init_header (char const *filename, int desc)
{
static struct timespec timespec;
if (! timespec.tv_sec)
- gettime (&timespec);
+ gettime (&timespec);
t = timespec;
}
@@ -1678,7 +1631,7 @@ init_header (char const *filename, int desc)
if (tm == NULL)
{
buf = xmalloc (INT_BUFSIZE_BOUND (long int)
- + MAX (10, INT_BUFSIZE_BOUND (int)));
+ + MAX (10, INT_BUFSIZE_BOUND (int)));
sprintf (buf, "%ld.%09d", (long int) t.tv_sec, ns);
}
else
@@ -1692,10 +1645,10 @@ init_header (char const *filename, int desc)
date_text = buf;
file_text = custom_header ? custom_header : desc < 0 ? "" : filename;
header_width_available = (chars_per_line
- - mbswidth (date_text, 0)
- - mbswidth (file_text, 0));
+ - mbswidth (date_text, 0)
+ - mbswidth (file_text, 0));
}
-
+
/* Set things up for printing a page
Scan through the columns ...
@@ -1716,35 +1669,35 @@ init_page (void)
{
store_columns ();
for (j = columns - 1, p = column_vector; j; --j, ++p)
- {
- p->lines_to_print = p->lines_stored;
- }
+ {
+ p->lines_to_print = p->lines_stored;
+ }
/* Last column. */
if (balance_columns)
- {
- p->lines_to_print = p->lines_stored;
- }
+ {
+ p->lines_to_print = p->lines_stored;
+ }
/* Since we're not balancing columns, we don't need to store
the rightmost column. Read it straight from the file. */
else
- {
- if (p->status == OPEN)
- {
- p->lines_to_print = lines_per_body;
- }
- else
- p->lines_to_print = 0;
- }
+ {
+ if (p->status == OPEN)
+ {
+ p->lines_to_print = lines_per_body;
+ }
+ else
+ p->lines_to_print = 0;
+ }
}
else
for (j = columns, p = column_vector; j; --j, ++p)
if (p->status == OPEN)
- {
- p->lines_to_print = lines_per_body;
- }
+ {
+ p->lines_to_print = lines_per_body;
+ }
else
- p->lines_to_print = 0;
+ p->lines_to_print = 0;
}
/* Align empty columns and print separators.
@@ -1821,86 +1774,86 @@ print_page (void)
empty_line = true;
for (j = 1, p = column_vector; j <= columns; ++j, ++p)
- {
- input_position = 0;
- if (p->lines_to_print > 0 || p->status == FF_FOUND)
- {
- FF_only = false;
- padding_not_printed = p->start_position;
- if (!(p->print_func) (p))
- read_rest_of_line (p);
- pv |= pad_vertically;
-
- --p->lines_to_print;
- if (p->lines_to_print <= 0)
- {
- if (cols_ready_to_print () <= 0)
- break;
- }
-
- /* File p changed its status to ON_HOLD or CLOSED */
- if (parallel_files && p->status != OPEN)
- {
- if (empty_line)
- align_empty_cols = true;
- else if (p->status == CLOSED ||
- (p->status == ON_HOLD && FF_only))
- align_column (p);
- }
- }
- else if (parallel_files)
- {
- /* File status ON_HOLD or CLOSED */
- if (empty_line)
- align_empty_cols = true;
- else
- align_column (p);
- }
-
- /* We need it also with an empty column */
- if (use_col_separator)
- ++separators_not_printed;
- }
+ {
+ input_position = 0;
+ if (p->lines_to_print > 0 || p->status == FF_FOUND)
+ {
+ FF_only = false;
+ padding_not_printed = p->start_position;
+ if (!(p->print_func) (p))
+ read_rest_of_line (p);
+ pv |= pad_vertically;
+
+ --p->lines_to_print;
+ if (p->lines_to_print <= 0)
+ {
+ if (cols_ready_to_print () == 0)
+ break;
+ }
+
+ /* File p changed its status to ON_HOLD or CLOSED */
+ if (parallel_files && p->status != OPEN)
+ {
+ if (empty_line)
+ align_empty_cols = true;
+ else if (p->status == CLOSED
+ || (p->status == ON_HOLD && FF_only))
+ align_column (p);
+ }
+ }
+ else if (parallel_files)
+ {
+ /* File status ON_HOLD or CLOSED */
+ if (empty_line)
+ align_empty_cols = true;
+ else
+ align_column (p);
+ }
+
+ /* We need it also with an empty column */
+ if (use_col_separator)
+ ++separators_not_printed;
+ }
if (pad_vertically)
- {
- putchar ('\n');
- --lines_left_on_page;
- }
-
- if (cols_ready_to_print () <= 0 && !extremities)
- break;
-
- if (double_space & pv)
- {
- putchar ('\n');
- --lines_left_on_page;
- }
+ {
+ putchar ('\n');
+ --lines_left_on_page;
+ }
+
+ if (cols_ready_to_print () == 0 && !extremities)
+ break;
+
+ if (double_space && pv)
+ {
+ putchar ('\n');
+ --lines_left_on_page;
+ }
}
if (lines_left_on_page == 0)
for (j = 1, p = column_vector; j <= columns; ++j, ++p)
if (p->status == OPEN)
- p->full_page_printed = true;
+ p->full_page_printed = true;
pad_vertically = pv;
- if (pad_vertically & extremities)
+ if (pad_vertically && extremities)
pad_down (lines_left_on_page + lines_per_footer);
- else if (keep_FF & print_a_FF)
+ else if (keep_FF && print_a_FF)
{
putchar ('\f');
print_a_FF = false;
}
- if (last_page_number < page_number)
+ if (last_page_number < ++page_number)
return false; /* Stop printing with LAST_PAGE */
reset_status (); /* Change ON_HOLD to OPEN. */
return true; /* More pages to go. */
}
-
+
/* Allocate space for storing columns.
This is necessary when printing multiple columns from a single file.
@@ -1923,15 +1876,15 @@ init_store_cols (void)
free (line_vector);
/* FIXME: here's where it was allocated. */
- line_vector = xmalloc ((total_lines + 1) * sizeof (int *));
+ line_vector = xmalloc ((total_lines + 1) * sizeof *line_vector);
free (end_vector);
- end_vector = xmalloc (total_lines * sizeof (int *));
+ end_vector = xmalloc (total_lines * sizeof *end_vector);
free (buff);
buff_allocated = (use_col_separator
- ? 2 * chars_if_truncate
- : chars_if_truncate); /* Tune this. */
+ ? 2 * chars_if_truncate
+ : chars_if_truncate); /* Tune this. */
buff = xmalloc (buff_allocated);
}
@@ -1951,8 +1904,8 @@ static void
store_columns (void)
{
int i, j;
- int line = 0;
- int buff_start;
+ unsigned int line = 0;
+ unsigned int buff_start;
int last_col; /* The rightmost column which will be saved in buff */
COLUMN *p;
@@ -1973,22 +1926,22 @@ store_columns (void)
p->current_line = line;
for (j = lines_per_body; j && files_ready_to_read; --j)
- if (p->status == OPEN) /* Redundant. Clean up. */
- {
- input_position = 0;
-
- if (!read_line (p))
- read_rest_of_line (p);
-
- if (p->status == OPEN
- || buff_start != buff_current)
- {
- ++p->lines_stored;
- line_vector[line] = buff_start;
- end_vector[line++] = input_position;
- buff_start = buff_current;
- }
- }
+ if (p->status == OPEN) /* Redundant. Clean up. */
+ {
+ input_position = 0;
+
+ if (!read_line (p))
+ read_rest_of_line (p);
+
+ if (p->status == OPEN
+ || buff_start != buff_current)
+ {
+ ++p->lines_stored;
+ line_vector[line] = buff_start;
+ end_vector[line++] = input_position;
+ buff_start = buff_current;
+ }
+ }
}
/* Keep track of the location of the last char in buff. */
@@ -2009,7 +1962,7 @@ balance (int total_stored)
{
lines = total_stored / columns;
if (i <= total_stored % columns)
- ++lines;
+ ++lines;
p->lines_stored = lines;
p->current_line = first_line;
@@ -2036,32 +1989,26 @@ add_line_number (COLUMN *p)
{
int i;
char *s;
- int left_cut;
+ int num_width;
/* Cutting off the higher-order digits is more informative than
- lower-order cut off*/
- if (line_number < power_10)
- sprintf (number_buff, "%*d", chars_per_number, line_number);
- else
- {
- left_cut = line_number % power_10;
- sprintf (number_buff, "%0*d", chars_per_number, left_cut);
- }
+ lower-order cut off. */
+ num_width = sprintf (number_buff, "%*d", chars_per_number, line_number);
line_number++;
- s = number_buff;
+ s = number_buff + (num_width - chars_per_number);
for (i = chars_per_number; i > 0; i--)
(p->char_func) (*s++);
if (columns > 1)
{
/* Tabification is assumed for multiple columns, also for n-separators,
- but `default n-separator = TAB' hasn't been given priority over
- equal column_width also specified by POSIX. */
+ but 'default n-separator = TAB' hasn't been given priority over
+ equal column_width also specified by POSIX. */
if (number_separator == '\t')
{
i = number_width - chars_per_number;
while (i-- > 0)
- (p->char_func) (' ');
+ (p->char_func) (' ');
}
else
(p->char_func) (number_separator);
@@ -2074,13 +2021,13 @@ add_line_number (COLUMN *p)
(p->char_func) (number_separator);
if (number_separator == '\t')
output_position = POS_AFTER_TAB (chars_per_output_tab,
- output_position);
+ output_position);
}
- if (truncate_lines & !parallel_files)
+ if (truncate_lines && !parallel_files)
input_position += number_width;
}
-
+
/* Print (or store) padding until the current horizontal position
is position. */
@@ -2094,7 +2041,7 @@ pad_across_to (int position)
else
{
while (++h <= position)
- putchar (' ');
+ putchar (' ');
output_position = position;
}
}
@@ -2105,9 +2052,9 @@ pad_across_to (int position)
Otherwise, use newlines. */
static void
-pad_down (int lines)
+pad_down (unsigned int lines)
{
- int i;
+ unsigned int i;
if (use_form_feed)
putchar ('\f');
@@ -2131,19 +2078,19 @@ read_rest_of_line (COLUMN *p)
while ((c = getc (f)) != '\n')
{
if (c == '\f')
- {
- if ((c = getc (f)) != '\n')
- ungetc (c, f);
- if (keep_FF)
- print_a_FF = true;
- hold_file (p);
- break;
- }
+ {
+ if ((c = getc (f)) != '\n')
+ ungetc (c, f);
+ if (keep_FF)
+ print_a_FF = true;
+ hold_file (p);
+ break;
+ }
else if (c == EOF)
- {
- close_file (p);
- break;
- }
+ {
+ close_file (p);
+ break;
+ }
}
}
@@ -2187,28 +2134,28 @@ skip_read (COLUMN *p, int column_number)
while (c != '\n')
{
if (c == '\f')
- {
- /* No FF-coincidence possible,
- no catching up of a FF-coincidence with next page */
- if (last_line)
- {
- if (!parallel_files)
- for (q = column_vector, i = columns; i; ++q, --i)
- q->full_page_printed = false;
- else
- p->full_page_printed = false;
- }
-
- if ((c = getc (f)) != '\n')
- ungetc (c, f);
- hold_file (p);
- break;
- }
+ {
+ /* No FF-coincidence possible,
+ no catching up of a FF-coincidence with next page */
+ if (last_line)
+ {
+ if (!parallel_files)
+ for (q = column_vector, i = columns; i; ++q, --i)
+ q->full_page_printed = false;
+ else
+ p->full_page_printed = false;
+ }
+
+ if ((c = getc (f)) != '\n')
+ ungetc (c, f);
+ hold_file (p);
+ break;
+ }
else if (c == EOF)
- {
- close_file (p);
- break;
- }
+ {
+ close_file (p);
+ break;
+ }
c = getc (f);
}
@@ -2216,7 +2163,7 @@ skip_read (COLUMN *p, int column_number)
if ((!parallel_files || column_number == 1) && !single_ff)
++line_count;
}
-
+
/* If we're tabifying output,
When print_char encounters white space it keeps track
@@ -2231,7 +2178,7 @@ print_white_space (void)
int goal = h_old + spaces_not_printed;
while (goal - h_old > 1
- && (h_new = POS_AFTER_TAB (chars_per_output_tab, h_old)) <= goal)
+ && (h_new = POS_AFTER_TAB (chars_per_output_tab, h_old)) <= goal)
{
putchar (output_tab_char);
h_old = h_new;
@@ -2260,35 +2207,35 @@ print_sep_string (void)
{
/* We'll be starting a line with chars_per_margin, anything else? */
if (spaces_not_printed > 0)
- print_white_space ();
+ print_white_space ();
}
else
{
for (; separators_not_printed > 0; --separators_not_printed)
- {
- while (l-- > 0)
- {
- /* 3 types of sep_strings: spaces only, spaces and chars,
- chars only */
- if (*s == ' ')
- {
- /* We're tabifying output; consecutive spaces in
- sep_string may have to be converted to tabs */
- s++;
- ++spaces_not_printed;
- }
- else
- {
- if (spaces_not_printed > 0)
- print_white_space ();
- putchar (*s++);
- ++output_position;
- }
- }
+ {
+ while (l-- > 0)
+ {
+ /* 3 types of sep_strings: spaces only, spaces and chars,
+ chars only */
+ if (*s == ' ')
+ {
+ /* We're tabifying output; consecutive spaces in
+ sep_string may have to be converted to tabs */
+ s++;
+ ++spaces_not_printed;
+ }
+ else
+ {
+ if (spaces_not_printed > 0)
+ print_white_space ();
+ putchar (*s++);
+ ++output_position;
+ }
+ }
/* sep_string ends with some spaces */
- if (spaces_not_printed > 0)
- print_white_space ();
- }
+ if (spaces_not_printed > 0)
+ print_white_space ();
+ }
}
}
@@ -2317,21 +2264,21 @@ print_char (char c)
if (tabify_output)
{
if (c == ' ')
- {
- ++spaces_not_printed;
- return;
- }
+ {
+ ++spaces_not_printed;
+ return;
+ }
else if (spaces_not_printed > 0)
- print_white_space ();
+ print_white_space ();
/* Nonprintables are assumed to have width 0, except '\b'. */
if (! isprint (to_uchar (c)))
- {
- if (c == '\b')
- --output_position;
- }
+ {
+ if (c == '\b')
+ --output_position;
+ }
else
- ++output_position;
+ ++output_position;
}
putchar (c);
}
@@ -2350,34 +2297,34 @@ skip_to_page (uintmax_t page)
for (n = 1; n < page; ++n)
{
for (i = 1; i < lines_per_body; ++i)
- {
- for (j = 1, p = column_vector; j <= columns; ++j, ++p)
- if (p->status == OPEN)
- skip_read (p, j);
- }
+ {
+ for (j = 1, p = column_vector; j <= columns; ++j, ++p)
+ if (p->status == OPEN)
+ skip_read (p, j);
+ }
last_line = true;
for (j = 1, p = column_vector; j <= columns; ++j, ++p)
- if (p->status == OPEN)
- skip_read (p, j);
+ if (p->status == OPEN)
+ skip_read (p, j);
if (storing_columns) /* change FF_FOUND to ON_HOLD */
- for (j = 1, p = column_vector; j <= columns; ++j, ++p)
- if (p->status != CLOSED)
- p->status = ON_HOLD;
+ for (j = 1, p = column_vector; j <= columns; ++j, ++p)
+ if (p->status != CLOSED)
+ p->status = ON_HOLD;
reset_status ();
last_line = false;
if (files_ready_to_read < 1)
{
- /* It's very helpful, normally the total number of pages is
- not known in advance. */
- error (0, 0,
- _("starting page number %"PRIuMAX
- " exceeds page count %"PRIuMAX),
- page, n);
+ /* It's very helpful, normally the total number of pages is
+ not known in advance. */
+ error (0, 0,
+ _("starting page number %"PRIuMAX
+ " exceeds page count %"PRIuMAX),
+ page, n);
break;
- }
+ }
}
return files_ready_to_read > 0;
}
@@ -2395,27 +2342,26 @@ print_header (void)
int lhs_spaces;
int rhs_spaces;
- if (!use_form_feed)
- printf ("\n\n");
-
output_position = 0;
pad_across_to (chars_per_margin);
print_white_space ();
if (page_number == 0)
- error (EXIT_FAILURE, 0, _("Page number overflow"));
+ error (EXIT_FAILURE, 0, _("page number overflow"));
/* The translator must ensure that formatting the translation of
"Page %"PRIuMAX does not generate more than (sizeof page_text - 1)
bytes. */
- sprintf (page_text, _("Page %"PRIuMAX), page_number++);
+ sprintf (page_text, _("Page %"PRIuMAX), page_number);
available_width = header_width_available - mbswidth (page_text, 0);
available_width = MAX (0, available_width);
lhs_spaces = available_width >> 1;
rhs_spaces = available_width - lhs_spaces;
- printf ("%s%*s%s%*s%s\n\n\n",
- date_text, lhs_spaces, " ", file_text, rhs_spaces, " ", page_text);
+ printf ("\n\n%*s%s%*s%s%*s%s\n\n\n",
+ chars_per_margin, "",
+ date_text, lhs_spaces, " ",
+ file_text, rhs_spaces, " ", page_text);
print_a_header = false;
output_position = 0;
@@ -2446,7 +2392,7 @@ static bool
read_line (COLUMN *p)
{
int c;
- int chars IF_LINT (= 0);
+ int chars IF_LINT ( = 0);
int last_input_position;
int j, k;
COLUMN *q;
@@ -2465,15 +2411,15 @@ read_line (COLUMN *p)
{
case '\f':
if ((c = getc (p->fp)) != '\n')
- ungetc (c, p->fp);
+ ungetc (c, p->fp);
FF_only = true;
- if (print_a_header & !storing_columns)
- {
- pad_vertically = true;
- print_header ();
- }
+ if (print_a_header && !storing_columns)
+ {
+ pad_vertically = true;
+ print_header ();
+ }
else if (keep_FF)
- print_a_FF = true;
+ print_a_FF = true;
hold_file (p);
return true;
case EOF:
@@ -2495,35 +2441,35 @@ read_line (COLUMN *p)
{
pad_vertically = true;
- if (print_a_header & !storing_columns)
- print_header ();
-
- if (parallel_files & align_empty_cols)
- {
- /* We have to align empty columns at the beginning of a line. */
- k = separators_not_printed;
- separators_not_printed = 0;
- for (j = 1, q = column_vector; j <= k; ++j, ++q)
- {
- align_column (q);
- separators_not_printed += 1;
- }
- padding_not_printed = p->start_position;
- if (truncate_lines)
- spaces_not_printed = chars_per_column;
- else
- spaces_not_printed = 0;
- align_empty_cols = false;
- }
+ if (print_a_header && !storing_columns)
+ print_header ();
+
+ if (parallel_files && align_empty_cols)
+ {
+ /* We have to align empty columns at the beginning of a line. */
+ k = separators_not_printed;
+ separators_not_printed = 0;
+ for (j = 1, q = column_vector; j <= k; ++j, ++q)
+ {
+ align_column (q);
+ separators_not_printed += 1;
+ }
+ padding_not_printed = p->start_position;
+ if (truncate_lines)
+ spaces_not_printed = chars_per_column;
+ else
+ spaces_not_printed = 0;
+ align_empty_cols = false;
+ }
if (padding_not_printed - col_sep_length > 0)
- {
- pad_across_to (padding_not_printed - col_sep_length);
- padding_not_printed = ANYWHERE;
- }
+ {
+ pad_across_to (padding_not_printed - col_sep_length);
+ padding_not_printed = ANYWHERE;
+ }
if (use_col_separator)
- print_sep_string ();
+ print_sep_string ();
}
if (p->numbered)
@@ -2535,33 +2481,33 @@ read_line (COLUMN *p)
print_clump (p, chars, clump_buff);
- for (;;)
+ while (true)
{
c = getc (p->fp);
switch (c)
- {
- case '\n':
- return true;
- case '\f':
- if ((c = getc (p->fp)) != '\n')
- ungetc (c, p->fp);
- if (keep_FF)
- print_a_FF = true;
- hold_file (p);
- return true;
- case EOF:
- close_file (p);
- return true;
- }
+ {
+ case '\n':
+ return true;
+ case '\f':
+ if ((c = getc (p->fp)) != '\n')
+ ungetc (c, p->fp);
+ if (keep_FF)
+ print_a_FF = true;
+ hold_file (p);
+ return true;
+ case EOF:
+ close_file (p);
+ return true;
+ }
last_input_position = input_position;
chars = char_to_clump (c);
if (truncate_lines && input_position > chars_per_column)
- {
- input_position = last_input_position;
- return false;
- }
+ {
+ input_position = last_input_position;
+ return false;
+ }
print_clump (p, chars, clump_buff);
}
@@ -2610,13 +2556,13 @@ print_stored (COLUMN *p)
if (p->status == FF_FOUND)
{
for (i = 1, q = column_vector; i <= columns; ++i, ++q)
- q->status = ON_HOLD;
+ q->status = ON_HOLD;
if (column_vector->lines_to_print <= 0)
- {
- if (!extremities)
- pad_vertically = false;
- return true; /* print a header only */
- }
+ {
+ if (!extremities)
+ pad_vertically = false;
+ return true; /* print a header only */
+ }
}
if (padding_not_printed - col_sep_length > 0)
@@ -2635,7 +2581,7 @@ print_stored (COLUMN *p)
{
output_position = p->start_position + end_vector[line];
if (p->start_position - col_sep_length == chars_per_margin)
- output_position -= col_sep_length;
+ output_position -= col_sep_length;
}
return true;
@@ -2672,60 +2618,60 @@ char_to_clump (char c)
width = TAB_WIDTH (chars_per_c, input_position);
if (untabify_input)
- {
- for (i = width; i; --i)
- *s++ = ' ';
- chars = width;
- }
+ {
+ for (i = width; i; --i)
+ *s++ = ' ';
+ chars = width;
+ }
else
- {
- *s = c;
- chars = 1;
- }
+ {
+ *s = c;
+ chars = 1;
+ }
}
else if (! isprint (uc))
{
if (use_esc_sequence)
- {
- width = 4;
- chars = 4;
- *s++ = '\\';
- sprintf (esc_buff, "%03o", uc);
- for (i = 0; i <= 2; ++i)
- *s++ = esc_buff[i];
- }
+ {
+ width = 4;
+ chars = 4;
+ *s++ = '\\';
+ sprintf (esc_buff, "%03o", uc);
+ for (i = 0; i <= 2; ++i)
+ *s++ = esc_buff[i];
+ }
else if (use_cntrl_prefix)
- {
- if (uc < 0200)
- {
- width = 2;
- chars = 2;
- *s++ = '^';
- *s++ = c ^ 0100;
- }
- else
- {
- width = 4;
- chars = 4;
- *s++ = '\\';
- sprintf (esc_buff, "%03o", uc);
- for (i = 0; i <= 2; ++i)
- *s++ = esc_buff[i];
- }
- }
+ {
+ if (uc < 0200)
+ {
+ width = 2;
+ chars = 2;
+ *s++ = '^';
+ *s = c ^ 0100;
+ }
+ else
+ {
+ width = 4;
+ chars = 4;
+ *s++ = '\\';
+ sprintf (esc_buff, "%03o", uc);
+ for (i = 0; i <= 2; ++i)
+ *s++ = esc_buff[i];
+ }
+ }
else if (c == '\b')
- {
- width = -1;
- chars = 1;
- *s = c;
- }
+ {
+ width = -1;
+ chars = 1;
+ *s = c;
+ }
else
- {
- width = 0;
- chars = 1;
- *s = c;
- }
+ {
+ width = 0;
+ chars = 1;
+ *s = c;
+ }
}
else
{
@@ -2734,14 +2680,24 @@ char_to_clump (char c)
*s = c;
}
- input_position += width;
+ /* Too many backspaces must put us in position 0 -- never negative. */
+ if (width < 0 && input_position == 0)
+ {
+ chars = 0;
+ input_position = 0;
+ }
+ else if (width < 0 && input_position <= -width)
+ input_position = 0;
+ else
+ input_position += width;
+
return chars;
}
/* We've just printed some files and need to clean up things before
looking for more options and printing the next batch of files.
- Free everything we've xmalloc'ed, except `header'. */
+ Free everything we've xmalloc'ed, except 'header'. */
static void
cleanup (void)
@@ -2753,36 +2709,35 @@ cleanup (void)
free (end_vector);
free (buff);
}
-
+
/* Complain, print a usage message, and die. */
void
usage (int status)
{
if (status != EXIT_SUCCESS)
- fprintf (stderr, _("Try `%s --help' for more information.\n"),
- program_name);
+ emit_try_help ();
else
{
printf (_("\
Usage: %s [OPTION]... [FILE]...\n\
"),
- program_name);
+ program_name);
fputs (_("\
Paginate or columnate FILE(s) for printing.\n\
-\n\
-"), stdout);
- fputs (_("\
-Mandatory arguments to long options are mandatory for short options too.\n\
"), stdout);
+
+ emit_stdin_note ();
+ emit_mandatory_arg_note ();
+
fputs (_("\
+FIRST_PAGE[:LAST_PAGE], --pages=FIRST_PAGE[:LAST_PAGE]\n\
begin [stop] printing with page FIRST_[LAST_]PAGE\n\
-COLUMN, --columns=COLUMN\n\
output COLUMN columns and print columns down,\n\
unless -a is used. Balance number of lines in the\n\
- columns on each page.\n\
+ columns on each page\n\
"), stdout);
fputs (_("\
-a, --across print columns across rather than down, used together\n\
@@ -2803,7 +2758,7 @@ Mandatory arguments to long options are mandatory for short options too.\n\
and trailer without -F)\n\
"), stdout);
fputs (_("\
- -h HEADER, --header=HEADER\n\
+ -h, --header=HEADER\n\
use a centered HEADER instead of filename in page header,\n\
-h \"\" prints a blank line, don't use -h\"\"\n\
-i[CHAR[WIDTH]], --output-tabs[=CHAR[WIDTH]]\n\
@@ -2812,9 +2767,12 @@ Mandatory arguments to long options are mandatory for short options too.\n\
alignment, --sep-string[=STRING] sets separators\n\
"), stdout);
fputs (_("\
- -l PAGE_LENGTH, --length=PAGE_LENGTH\n\
+ -l, --length=PAGE_LENGTH\n\
set the page length to PAGE_LENGTH (66) lines\n\
- (default number of lines of text 56, and with -F 63)\n\
+ (default number of lines of text 56, and with -F 63).\n\
+ implies -t if PAGE_LENGTH <= 10\n\
+"), stdout);
+ fputs (_("\
-m, --merge print all files in parallel, one in each column,\n\
truncate lines, but join lines of full length with -J\n\
"), stdout);
@@ -2822,32 +2780,34 @@ Mandatory arguments to long options are mandatory for short options too.\n\
-n[SEP[DIGITS]], --number-lines[=SEP[DIGITS]]\n\
number lines, use DIGITS (5) digits, then SEP (TAB),\n\
default counting starts with 1st line of input file\n\
- -N NUMBER, --first-line-number=NUMBER\n\
+ -N, --first-line-number=NUMBER\n\
start counting with NUMBER at 1st line of first\n\
page printed (see +FIRST_PAGE)\n\
"), stdout);
fputs (_("\
- -o MARGIN, --indent=MARGIN\n\
+ -o, --indent=MARGIN\n\
offset each line with MARGIN (zero) spaces, do not\n\
affect -w or -W, MARGIN will be added to PAGE_WIDTH\n\
-r, --no-file-warnings\n\
omit warning when a file cannot be opened\n\
"), stdout);
fputs (_("\
- -s[CHAR],--separator[=CHAR]\n\
+ -s[CHAR], --separator[=CHAR]\n\
separate columns by a single character, default for CHAR\n\
- is the <TAB> character without -w and \'no char\' with -w\n\
+ is the <TAB> character without -w and \'no char\' with -w.\
+\n\
-s[CHAR] turns off line truncation of all 3 column\n\
options (-COLUMN|-a -COLUMN|-m) except -w is set\n\
"), stdout);
fputs (_("\
- -SSTRING, --sep-string[=STRING]\n\
-"), stdout);
- fputs (_("\
+ -S[STRING], --sep-string[=STRING]\n\
separate columns by STRING,\n\
without -S: Default separator <TAB> with -J and <space>\n\
otherwise (same as -S\" \"), no effect on column options\n\
- -t, --omit-header omit page headers and trailers\n\
+"), stdout);
+ fputs (_("\
+ -t, --omit-header omit page headers and trailers;\n\
+ implied if PAGE_LENGTH <= 10\n\
"), stdout);
fputs (_("\
-T, --omit-pagination\n\
@@ -2855,24 +2815,19 @@ Mandatory arguments to long options are mandatory for short options too.\n\
by form feeds set in input files\n\
-v, --show-nonprinting\n\
use octal backslash notation\n\
- -w PAGE_WIDTH, --width=PAGE_WIDTH\n\
+ -w, --width=PAGE_WIDTH\n\
set page width to PAGE_WIDTH (72) characters for\n\
multiple text-column output only, -s[char] turns off (72)\n\
"), stdout);
fputs (_("\
- -W PAGE_WIDTH, --page-width=PAGE_WIDTH\n\
+ -W, --page-width=PAGE_WIDTH\n\
set page width to PAGE_WIDTH (72) characters always,\n\
truncate lines, except -J option is set, no interference\n\
with -S or -s\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- fputs (_("\
-\n\
--T implied by -l nn when nn <= 10 or <= 3 with -F. With no FILE, or when\n\
-FILE is -, read standard input.\n\
-"), stdout);
- printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}