summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJim Meyering <jim@meyering.net>2005-03-06 19:34:07 +0000
committerJim Meyering <jim@meyering.net>2005-03-06 19:34:07 +0000
commit048a5ce26c306b69d0b18966220e3e658f1c045f (patch)
treea98bbc0ab787ca1ab6fa0af67ae1c3aca81cf3b8
parent825846682a31ec1ea4d08e2c46d410c849c4fd60 (diff)
downloadcoreutils-048a5ce26c306b69d0b18966220e3e658f1c045f.tar.xz
Factor out column-count processing.
Include "inttostr.h". (parse_column_count): New function. (main): Use the new function for both old-style, -9, and long, --columns=-9, options.
-rw-r--r--src/pr.c54
1 files changed, 36 insertions, 18 deletions
diff --git a/src/pr.c b/src/pr.c
index e87479de7..44fa6788c 100644
--- a/src/pr.c
+++ b/src/pr.c
@@ -317,6 +317,7 @@
#include "system.h"
#include "error.h"
#include "hard-locale.h"
+#include "inttostr.h"
#include "mbswidth.h"
#include "posixver.h"
#include "xstrtol.h"
@@ -832,6 +833,23 @@ first_last_page (char const *pages)
return true;
}
+/* 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, return false. */
+static bool
+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))
+ return false;
+
+ columns = tmp_long;
+ explicit_columns = true;
+ return true;
+}
+
/* Estimate length of col_sep_string with option -S. */
static void
@@ -846,12 +864,22 @@ int
main (int argc, char **argv)
{
int c;
- int accum = 0;
int n_files;
bool old_options = false;
bool old_w = false;
bool old_s = false;
char **file_names;
+
+ /* Use this buffer to accumulate the digits of old-style options like -99.
+ Make it one byte larger than the size required for the largest value;
+ if the user-supplied string would overflow, we'll discover that fact
+ (and fail) when accumulating the first additional byte.
+ FIXME: we're using INT_BUFSIZE_BOUND (uintmax_t) here already, in
+ anticipation of the clean-up that changes the type of `columns'
+ from int to size_t. */
+ char column_count_string[1 + INT_BUFSIZE_BOUND (uintmax_t)];
+ size_t n_digits = 0;
+
char const *short_options = (posix2_version () < 200112
? COMMON_SHORT_OPTIONS "S::"
: COMMON_SHORT_OPTIONS "S:");
@@ -874,17 +902,14 @@ main (int argc, char **argv)
{
if (ISDIGIT (c))
{
- int new_c = accum * 10 + c - '0';
- if (INT_MAX / 10 < accum || new_c < 0)
+ column_count_string[n_digits++] = c;
+ column_count_string[n_digits] = 0;
+ if ( ! parse_column_count (column_count_string))
error (EXIT_FAILURE, 0, _("column count too large"));
- accum = new_c;
- columns = accum;
- explicit_columns = true;
continue;
}
- if (accum > 0) /* reset for subsequent params */
- accum = 0;
+ n_digits = 0;
switch (c)
{
@@ -907,16 +932,9 @@ main (int argc, char **argv)
case COLUMNS_OPTION: /* --columns=COLUMN */
{
- long int tmp_long;
- if (xstrtol (optarg, NULL, 10, &tmp_long, "") != LONGINT_OK
- || tmp_long <= 0 || tmp_long > INT_MAX)
- {
- error (EXIT_FAILURE, 0,
- _("`--columns=COLUMN' invalid number of columns: `%s'"),
- optarg);
- }
- columns = tmp_long;
- explicit_columns = true;
+ if ( ! parse_column_count (optarg))
+ error (EXIT_FAILURE, 0,
+ _("invalid number of columns: `%s'"), optarg);
break;
}