summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--po/POTFILES.in1
-rw-r--r--src/cut.c257
-rw-r--r--src/local.mk3
-rw-r--r--src/set-fields.c322
-rw-r--r--src/set-fields.h49
-rwxr-xr-xtests/misc/cut.pl27
6 files changed, 403 insertions, 256 deletions
diff --git a/po/POTFILES.in b/po/POTFILES.in
index abec10961..b3fe66866 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -109,6 +109,7 @@ src/rmdir.c
src/runcon.c
src/selinux.c
src/seq.c
+src/set-fields.c
src/shred.c
src/shuf.c
src/sleep.c
diff --git a/src/cut.c b/src/cut.c
index 4f80ebd45..aac91ef5e 100644
--- a/src/cut.c
+++ b/src/cut.c
@@ -34,9 +34,10 @@
#include "fadvise.h"
#include "getndelim2.h"
#include "hash.h"
-#include "quote.h"
#include "xstrndup.h"
+#include "set-fields.h"
+
/* The official name of this program (e.g., no 'g' prefix). */
#define PROGRAM_NAME "cut"
@@ -54,41 +55,11 @@
while (0)
-struct range_pair
- {
- size_t lo;
- size_t hi;
- };
-
-/* Array of `struct range_pair' holding all the finite ranges. */
-static struct range_pair *rp;
-
/* Pointer inside RP. When checking if a byte or field is selected
by a finite range, we check if it is between CURRENT_RP.LO
and CURRENT_RP.HI. If the byte or field index is greater than
CURRENT_RP.HI then we make CURRENT_RP to point to the next range pair. */
-static struct range_pair *current_rp;
-
-/* Number of finite ranges specified by the user. */
-static size_t n_rp;
-
-/* Number of `struct range_pair's allocated. */
-static size_t n_rp_allocated;
-
-
-/* Append LOW, HIGH to the list RP of range pairs, allocating additional
- space if necessary. Update global variable N_RP. When allocating,
- update global variable N_RP_ALLOCATED. */
-
-static void
-add_range_pair (size_t lo, size_t hi)
-{
- if (n_rp == n_rp_allocated)
- rp = X2NREALLOC (rp, &n_rp_allocated);
- rp[n_rp].lo = lo;
- rp[n_rp].hi = hi;
- ++n_rp;
-}
+static struct field_range_pair *current_rp;
/* This buffer is used to support the semantics of the -s option
(or lack of same) when the specified field list includes (does
@@ -221,208 +192,6 @@ Each range is one of:\n\
exit (status);
}
-/* Comparison function for qsort to order the list of
- struct range_pairs. */
-static int
-compare_ranges (const void *a, const void *b)
-{
- int a_start = ((const struct range_pair *) a)->lo;
- int b_start = ((const struct range_pair *) b)->lo;
- return a_start < b_start ? -1 : a_start > b_start;
-}
-
-/* Reallocate Range Pair entries, with corresponding
- entries outside the range of each specified entry. */
-
-static void
-complement_rp (void)
-{
- if (complement)
- {
- struct range_pair *c = rp;
- size_t n = n_rp;
- size_t i;
-
- rp = NULL;
- n_rp = 0;
- n_rp_allocated = 0;
-
- if (c[0].lo > 1)
- add_range_pair (1, c[0].lo - 1);
-
- for (i = 1; i < n; ++i)
- {
- if (c[i-1].hi + 1 == c[i].lo)
- continue;
-
- add_range_pair (c[i-1].hi + 1, c[i].lo - 1);
- }
-
- if (c[n-1].hi < SIZE_MAX)
- add_range_pair (c[n-1].hi + 1, SIZE_MAX);
-
- free (c);
- }
-}
-
-/* Given the list of field or byte range specifications FIELDSTR,
- allocate and initialize the RP array. FIELDSTR should
- be composed of one or more numbers or ranges of numbers, separated
- by blanks or commas. Incomplete ranges may be given: '-m' means '1-m';
- 'n-' means 'n' through end of line.
- Return true if FIELDSTR contains at least one field specification,
- false otherwise. */
-
-static bool
-set_fields (const char *fieldstr)
-{
- size_t initial = 1; /* Value of first number in a range. */
- size_t value = 0; /* If nonzero, a number being accumulated. */
- bool lhs_specified = false;
- bool rhs_specified = false;
- bool dash_found = false; /* True if a '-' is found in this field. */
- bool field_found = false; /* True if at least one field spec
- has been processed. */
-
- size_t i;
- bool in_digits = false;
-
- /* Collect and store in RP the range end points. */
-
- while (true)
- {
- if (*fieldstr == '-')
- {
- in_digits = false;
- /* Starting a range. */
- if (dash_found)
- FATAL_ERROR (_("invalid byte, character or field list"));
- dash_found = true;
- fieldstr++;
-
- if (lhs_specified && !value)
- FATAL_ERROR (_("fields and positions are numbered from 1"));
-
- initial = (lhs_specified ? value : 1);
- value = 0;
- }
- else if (*fieldstr == ','
- || isblank (to_uchar (*fieldstr)) || *fieldstr == '\0')
- {
- in_digits = false;
- /* Ending the string, or this field/byte sublist. */
- if (dash_found)
- {
- dash_found = false;
-
- if (!lhs_specified && !rhs_specified)
- FATAL_ERROR (_("invalid range with no endpoint: -"));
-
- /* A range. Possibilities: -n, m-n, n-.
- In any case, 'initial' contains the start of the range. */
- if (!rhs_specified)
- {
- /* 'n-'. From 'initial' to end of line. */
- add_range_pair (initial, SIZE_MAX);
- field_found = true;
- }
- else
- {
- /* 'm-n' or '-n' (1-n). */
- if (value < initial)
- FATAL_ERROR (_("invalid decreasing range"));
-
- add_range_pair (initial, value);
- field_found = true;
- }
- value = 0;
- }
- else
- {
- /* A simple field number, not a range. */
- if (value == 0)
- FATAL_ERROR (_("fields and positions are numbered from 1"));
- add_range_pair (value, value);
- value = 0;
- field_found = true;
- }
-
- if (*fieldstr == '\0')
- break;
-
- fieldstr++;
- lhs_specified = false;
- rhs_specified = false;
- }
- else if (ISDIGIT (*fieldstr))
- {
- /* Record beginning of digit string, in case we have to
- complain about it. */
- static char const *num_start;
- if (!in_digits || !num_start)
- num_start = fieldstr;
- in_digits = true;
-
- if (dash_found)
- rhs_specified = 1;
- else
- lhs_specified = 1;
-
- /* Detect overflow. */
- if (!DECIMAL_DIGIT_ACCUMULATE (value, *fieldstr - '0', size_t)
- || value == SIZE_MAX)
- {
- /* In case the user specified -c$(echo 2^64|bc),22,
- complain only about the first number. */
- /* Determine the length of the offending number. */
- size_t len = strspn (num_start, "0123456789");
- char *bad_num = xstrndup (num_start, len);
- if (operating_mode == byte_mode)
- error (0, 0,
- _("byte offset %s is too large"), quote (bad_num));
- else
- error (0, 0,
- _("field number %s is too large"), quote (bad_num));
- free (bad_num);
- exit (EXIT_FAILURE);
- }
-
- fieldstr++;
- }
- else
- FATAL_ERROR (_("invalid byte, character or field list"));
- }
-
- qsort (rp, n_rp, sizeof (rp[0]), compare_ranges);
-
- /* Merge range pairs (e.g. `2-5,3-4' becomes `2-5'). */
- for (i = 0; i < n_rp; ++i)
- {
- for (size_t j = i + 1; j < n_rp; ++j)
- {
- if (rp[j].lo <= rp[i].hi)
- {
- rp[i].hi = MAX (rp[j].hi, rp[i].hi);
- memmove (rp + j, rp + j + 1, (n_rp - j - 1) * sizeof *rp);
- n_rp--;
- j--;
- }
- else
- break;
- }
- }
-
- complement_rp ();
-
- /* After merging, reallocate RP so we release memory to the system.
- Also add a sentinel at the end of RP, to avoid out of bounds access
- and for performance reasons. */
- ++n_rp;
- rp = xrealloc (rp, n_rp * sizeof (struct range_pair));
- rp[n_rp - 1].lo = rp[n_rp - 1].hi = SIZE_MAX;
-
- return field_found;
-}
/* Increment *ITEM_IDX (i.e., a field or byte index),
and if required CURRENT_RP. */
@@ -463,7 +232,7 @@ cut_bytes (FILE *stream)
byte_idx = 0;
print_delimiter = false;
- current_rp = rp;
+ current_rp = frp;
while (true)
{
int c; /* Each character from the file. */
@@ -475,7 +244,7 @@ cut_bytes (FILE *stream)
putchar ('\n');
byte_idx = 0;
print_delimiter = false;
- current_rp = rp;
+ current_rp = frp;
}
else if (c == EOF)
{
@@ -514,7 +283,7 @@ cut_fields (FILE *stream)
bool found_any_selected_field = false;
bool buffer_first_field;
- current_rp = rp;
+ current_rp = frp;
c = getc (stream);
if (c == EOF)
@@ -642,7 +411,7 @@ cut_fields (FILE *stream)
if (c == EOF)
break;
field_idx = 1;
- current_rp = rp;
+ current_rp = frp;
found_any_selected_field = false;
}
}
@@ -793,13 +562,9 @@ main (int argc, char **argv)
FATAL_ERROR (_("suppressing non-delimited lines makes sense\n\
\tonly when operating on fields"));
- if (! set_fields (spec_list_string))
- {
- if (operating_mode == field_mode)
- FATAL_ERROR (_("missing list of fields"));
- else
- FATAL_ERROR (_("missing list of positions"));
- }
+ set_fields (spec_list_string,
+ ( (operating_mode == field_mode) ? 0 : SETFLD_ERRMSG_USE_POS)
+ | (complement ? SETFLD_COMPLEMENT : 0) );
if (!delim_specified)
delim = '\t';
@@ -826,5 +591,7 @@ main (int argc, char **argv)
ok = false;
}
+ IF_LINT (reset_fields ());
+
return ok ? EXIT_SUCCESS : EXIT_FAILURE;
}
diff --git a/src/local.mk b/src/local.mk
index d0ceae4bd..5fb4d3733 100644
--- a/src/local.mk
+++ b/src/local.mk
@@ -55,6 +55,7 @@ noinst_HEADERS = \
src/operand2sig.h \
src/prog-fprintf.h \
src/remove.h \
+ src/set-fields.h \
src/system.h \
src/uname.h
@@ -387,6 +388,8 @@ src_stat_SOURCES = src/stat.c src/find-mount-point.c
src_uname_SOURCES = src/uname.c src/uname-uname.c
src_arch_SOURCES = src/uname.c src/uname-arch.c
+src_cut_SOURCES = src/cut.c src/set-fields.c
+
src_md5sum_CPPFLAGS = -DHASH_ALGO_MD5=1 $(AM_CPPFLAGS)
src_sha1sum_SOURCES = src/md5sum.c
src_sha1sum_CPPFLAGS = -DHASH_ALGO_SHA1=1 $(AM_CPPFLAGS)
diff --git a/src/set-fields.c b/src/set-fields.c
new file mode 100644
index 000000000..847c812a5
--- /dev/null
+++ b/src/set-fields.c
@@ -0,0 +1,322 @@
+/* set-fields.c -- common functions for parsing field list
+ Copyright (C) 2015 Free Software Foundation, Inc.
+
+ 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 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
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ 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, see <http://www.gnu.org/licenses/>. */
+
+/* Extracted from cut.c by Assaf Gordon */
+
+#include <config.h>
+
+#include "system.h"
+#include "error.h"
+#include "quote.h"
+#include "xstrndup.h"
+#include "set-fields.h"
+
+/* Array of `struct field_range_pair' holding all the finite ranges. */
+struct field_range_pair *frp;
+
+/* Number of finite ranges specified by the user. */
+size_t n_frp;
+
+/* Number of `struct field_range_pair's allocated. */
+static size_t n_frp_allocated;
+
+#define FATAL_ERROR(Message) \
+ do \
+ { \
+ error (0, 0, (Message)); \
+ usage (EXIT_FAILURE); \
+ } \
+ while (0)
+
+/* Append LOW, HIGH to the list RP of range pairs, allocating additional
+ space if necessary. Update global variable N_FRP. When allocating,
+ update global variable N_FRP_ALLOCATED. */
+static void
+add_range_pair (size_t lo, size_t hi)
+{
+ if (n_frp == n_frp_allocated)
+ frp = X2NREALLOC (frp, &n_frp_allocated);
+ frp[n_frp].lo = lo;
+ frp[n_frp].hi = hi;
+ ++n_frp;
+}
+
+
+/* Comparison function for qsort to order the list of
+ struct range_pairs. */
+static int
+compare_ranges (const void *a, const void *b)
+{
+ int a_start = ((const struct field_range_pair *) a)->lo;
+ int b_start = ((const struct field_range_pair *) b)->lo;
+ return a_start < b_start ? -1 : a_start > b_start;
+}
+
+/* Reallocate Range Pair entries, with corresponding
+ entries outside the range of each specified entry. */
+
+static void
+complement_rp (void)
+{
+ struct field_range_pair *c = frp;
+ size_t n = n_frp;
+ size_t i;
+
+ frp = NULL;
+ n_frp = 0;
+ n_frp_allocated = 0;
+
+ if (c[0].lo > 1)
+ add_range_pair (1, c[0].lo - 1);
+
+ for (i = 1; i < n; ++i)
+ {
+ if (c[i-1].hi + 1 == c[i].lo)
+ continue;
+
+ add_range_pair (c[i-1].hi + 1, c[i].lo - 1);
+ }
+
+ if (c[n-1].hi < SIZE_MAX)
+ add_range_pair (c[n-1].hi + 1, SIZE_MAX);
+
+ free (c);
+}
+
+/* Given the list of field or byte range specifications FIELDSTR,
+ allocate and initialize the FRP array. FIELDSTR should
+ be composed of one or more numbers or ranges of numbers, separated
+ by blanks or commas. Incomplete ranges may be given: '-m' means '1-m';
+ 'n-' means 'n' through end of line.
+ n=0 and n>=SIZE_MAX values will trigger an error.
+
+ if SETFLD_ALLOW_DASH option is used, a single '-' means all fields
+ (otherwise a single dash triggers an error).
+
+ if SETFLD_COMPLEMENT option is used, the specified field list
+ is complemented (e.g. '1-3' will result in fields '4-').
+
+ if SETFLD_ERRMSG_USE_POS option is used, error messages
+ will say 'position' (or 'byte/character positions')
+ instead of fields (used with cut -b/-c).
+
+ The function terminates on failure.
+
+ Upon return, the FRP array is initialized to contain
+ a non-overlapping, increasing list of field ranges.
+
+ N_FRP holds the number of field ranges in the FRP array.
+
+ The first field is stored as 1 (zero is not used).
+ An open-ended range (i.e., until the last field of the input line)
+ is indicated with hi = SIZE_MAX.
+
+ A sentinel of SIZE_MAX/SIZE_MAX is always added as the last
+ field range pair.
+
+ Examples:
+ given '1-2,4', frp = [ { .lo = 1, .hi = 2 },
+ { .lo = 4, .hi = 4 },
+ { .lo = SIZE_MAX, .hi = SIZE_MAX } ];
+
+ given '3-', frp = [ { .lo = 3, .hi = SIZE_MAX },
+ { .lo = SIZE_MAX, .hi = SIZE_MAX } ];
+*/
+void
+set_fields (const char *fieldstr, unsigned int options)
+{
+ size_t initial = 1; /* Value of first number in a range. */
+ size_t value = 0; /* If nonzero, a number being accumulated. */
+ bool lhs_specified = false;
+ bool rhs_specified = false;
+ bool dash_found = false; /* True if a '-' is found in this field. */
+
+ size_t i;
+ bool in_digits = false;
+
+ /* Collect and store in RP the range end points. */
+
+ /* Special case: '--field=-' means all fields, emulate '--field=1-' . */
+ if ((options & SETFLD_ALLOW_DASH) && STREQ (fieldstr,"-"))
+ {
+ value = 1;
+ lhs_specified = true;
+ dash_found = true;
+ fieldstr++;
+ }
+
+ while (true)
+ {
+ if (*fieldstr == '-')
+ {
+ in_digits = false;
+ /* Starting a range. */
+ if (dash_found)
+ FATAL_ERROR ( (options & SETFLD_ERRMSG_USE_POS)
+ ?_("invalid byte or character range")
+ :_("invalid field range"));
+
+ dash_found = true;
+ fieldstr++;
+
+ if (lhs_specified && !value)
+ FATAL_ERROR ( (options & SETFLD_ERRMSG_USE_POS)
+ ?_("byte/character positions are numbered from 1")
+ :_("fields are numbered from 1"));
+
+ initial = (lhs_specified ? value : 1);
+ value = 0;
+ }
+ else if (*fieldstr == ','
+ || isblank (to_uchar (*fieldstr)) || *fieldstr == '\0')
+ {
+ in_digits = false;
+ /* Ending the string, or this field/byte sublist. */
+ if (dash_found)
+ {
+ dash_found = false;
+
+ if (!lhs_specified && !rhs_specified)
+ {
+ /* if a lone dash is allowed, emulate '1-' for all fields */
+ if (options & SETFLD_ALLOW_DASH)
+ initial = 1;
+ else
+ FATAL_ERROR (_("invalid range with no endpoint: -"));
+ }
+
+ /* A range. Possibilities: -n, m-n, n-.
+ In any case, 'initial' contains the start of the range. */
+ if (!rhs_specified)
+ {
+ /* 'n-'. From 'initial' to end of line. */
+ add_range_pair (initial, SIZE_MAX);
+ }
+ else
+ {
+ /* 'm-n' or '-n' (1-n). */
+ if (value < initial)
+ FATAL_ERROR (_("invalid decreasing range"));
+
+ add_range_pair (initial, value);
+ }
+ value = 0;
+ }
+ else
+ {
+ /* A simple field number, not a range. */
+ if (value == 0)
+ FATAL_ERROR ( (options & SETFLD_ERRMSG_USE_POS)
+ ?_("byte/character positions are numbered from 1")
+ :_("fields are numbered from 1"));
+
+ add_range_pair (value, value);
+ value = 0;
+ }
+
+ if (*fieldstr == '\0')
+ break;
+
+ fieldstr++;
+ lhs_specified = false;
+ rhs_specified = false;
+ }
+ else if (ISDIGIT (*fieldstr))
+ {
+ /* Record beginning of digit string, in case we have to
+ complain about it. */
+ static char const *num_start;
+ if (!in_digits || !num_start)
+ num_start = fieldstr;
+ in_digits = true;
+
+ if (dash_found)
+ rhs_specified = 1;
+ else
+ lhs_specified = 1;
+
+ /* Detect overflow. */
+ if (!DECIMAL_DIGIT_ACCUMULATE (value, *fieldstr - '0', size_t)
+ || value == SIZE_MAX)
+ {
+ /* In case the user specified -c$(echo 2^64|bc),22,
+ complain only about the first number. */
+ /* Determine the length of the offending number. */
+ size_t len = strspn (num_start, "0123456789");
+ char *bad_num = xstrndup (num_start, len);
+ error (0, 0, (options & SETFLD_ERRMSG_USE_POS)
+ ?_("byte/character offset %s is too large")
+ :_("field number %s is too large"),
+ quote (bad_num));
+ free (bad_num);
+ usage (EXIT_FAILURE);
+ }
+
+ fieldstr++;
+ }
+ else
+ {
+ error (0, 0, (options & SETFLD_ERRMSG_USE_POS)
+ ?_("invalid byte/character position %s")
+ :_("invalid field value %s"),
+ quote (fieldstr));
+ usage (EXIT_FAILURE);
+ }
+ }
+
+ if (!n_frp)
+ FATAL_ERROR ( (options&SETFLD_ERRMSG_USE_POS)
+ ?_("missing list of byte/character positions")
+ :_("missing list of fields"));
+
+ qsort (frp, n_frp, sizeof (frp[0]), compare_ranges);
+
+ /* Merge range pairs (e.g. `2-5,3-4' becomes `2-5'). */
+ for (i = 0; i < n_frp; ++i)
+ {
+ for (size_t j = i + 1; j < n_frp; ++j)
+ {
+ if (frp[j].lo <= frp[i].hi)
+ {
+ frp[i].hi = MAX (frp[j].hi, frp[i].hi);
+ memmove (frp + j, frp + j + 1, (n_frp - j - 1) * sizeof *frp);
+ n_frp--;
+ j--;
+ }
+ else
+ break;
+ }
+ }
+
+ if (options & SETFLD_COMPLEMENT)
+ complement_rp ();
+
+ /* After merging, reallocate RP so we release memory to the system.
+ Also add a sentinel at the end of RP, to avoid out of bounds access
+ and for performance reasons. */
+ ++n_frp;
+ frp = xrealloc (frp, n_frp * sizeof (struct field_range_pair));
+ frp[n_frp - 1].lo = frp[n_frp - 1].hi = SIZE_MAX;
+}
+
+void
+reset_fields (void)
+{
+ n_frp = 0 ;
+ n_frp_allocated = 0;
+ free (frp);
+ frp = NULL;
+}
diff --git a/src/set-fields.h b/src/set-fields.h
new file mode 100644
index 000000000..2c55c2984
--- /dev/null
+++ b/src/set-fields.h
@@ -0,0 +1,49 @@
+/* set-fields.h -- parse field list argument
+
+ Copyright (C) 2015 Free Software Foundation, Inc.
+
+ 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 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
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ 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, see <http://www.gnu.org/licenses/>. */
+#ifndef SET_FIELDS_H
+# define SET_FIELDS_H
+
+struct field_range_pair
+ {
+ size_t lo;
+ size_t hi;
+ };
+
+/* Array of `struct range_pair' holding all the finite ranges. */
+extern struct field_range_pair *frp;
+
+/* Number of finite ranges specified by the user. */
+extern size_t n_frp;
+
+/* field list parsing options */
+enum
+{
+ SETFLD_ALLOW_DASH = 0x01, /* allow single dash meaning 'all fields' */
+ SETFLD_COMPLEMENT = 0x02, /* complement the field list */
+ SETFLD_ERRMSG_USE_POS = 0x04 /* when reporting errors, say 'position' instead
+ of 'field' (used with cut -b/-c) */
+};
+
+/* allocates and initializes the FRP array and N_FRP count */
+void
+set_fields (const char *fieldstr, unsigned int options);
+
+/* frees memory allocated by set_fields() */
+void
+reset_fields (void);
+
+#endif
diff --git a/tests/misc/cut.pl b/tests/misc/cut.pl
index 23e9ce36f..a6239d629 100755
--- a/tests/misc/cut.pl
+++ b/tests/misc/cut.pl
@@ -29,8 +29,10 @@ my $mb_locale = $ENV{LOCALE_FR_UTF8};
my $prog = 'cut';
my $try = "Try '$prog --help' for more information.\n";
-my $from_1 = "$prog: fields and positions are numbered from 1\n$try";
-my $inval = "$prog: invalid byte, character or field list\n$try";
+my $from_field1 = "$prog: fields are numbered from 1\n$try";
+my $from_pos1 = "$prog: byte/character positions are numbered from 1\n$try";
+my $inval_fld = "$prog: invalid field range\n$try";
+my $inval_pos = "$prog: invalid byte or character range\n$try";
my $no_endpoint = "$prog: invalid range with no endpoint: -\n$try";
my $nofield = "$prog: an input delimiter may be specified only when " .
"operating on fields\n$try";
@@ -42,16 +44,16 @@ my @Tests =
# This failed (as it should) even before coreutils-6.9.90,
# but cut from 6.9.90 produces a more useful diagnostic.
- ['zero-1', '-b0', {ERR=>$from_1}, {EXIT => 1} ],
+ ['zero-1', '-b0', {ERR=>$from_pos1}, {EXIT => 1} ],
# Up to coreutils-6.9, specifying a range of 0-2 was not an error.
# It was treated just like "-2".
- ['zero-2', '-f0-2', {ERR=>$from_1}, {EXIT => 1} ],
+ ['zero-2', '-f0-2', {ERR=>$from_field1}, {EXIT => 1} ],
# Up to coreutils-8.20, specifying a range of 0- was not an error.
- ['zero-3b', '-b0-', {ERR=>$from_1}, {EXIT => 1} ],
- ['zero-3c', '-c0-', {ERR=>$from_1}, {EXIT => 1} ],
- ['zero-3f', '-f0-', {ERR=>$from_1}, {EXIT => 1} ],
+ ['zero-3b', '-b0-', {ERR=>$from_pos1}, {EXIT => 1} ],
+ ['zero-3c', '-c0-', {ERR=>$from_pos1}, {EXIT => 1} ],
+ ['zero-3f', '-f0-', {ERR=>$from_field1}, {EXIT => 1} ],
['1', '-d:', '-f1,3-', {IN=>"a:b:c\n"}, {OUT=>"a:c\n"}],
['2', '-d:', '-f1,3-', {IN=>"a:b:c\n"}, {OUT=>"a:c\n"}],
@@ -101,13 +103,16 @@ my @Tests =
{ERR=>"$prog: you must specify a list of bytes, characters, or fields\n$try"}
],
# Empty field list
- ['empty-fl', qw(-f ''), {IN=>":\n"}, {OUT=>""}, {EXIT=>1}, {ERR=>$from_1}],
+ ['empty-fl', qw(-f ''), {IN=>":\n"}, {OUT=>""}, {EXIT=>1},
+ {ERR=>$from_field1}],
# Missing field list
- ['missing-fl', qw(-f --), {IN=>":\n"}, {OUT=>""}, {EXIT=>1}, {ERR=>$inval}],
+ ['missing-fl', qw(-f --), {IN=>":\n"}, {OUT=>""}, {EXIT=>1},
+ {ERR=>$inval_fld}],
# Empty byte list
- ['empty-bl', qw(-b ''), {IN=>":\n"}, {OUT=>""}, {EXIT=>1}, {ERR=>$from_1}],
+ ['empty-bl', qw(-b ''), {IN=>":\n"}, {OUT=>""}, {EXIT=>1}, {ERR=>$from_pos1}],
# Missing byte list
- ['missing-bl', qw(-b --), {IN=>":\n"}, {OUT=>""}, {EXIT=>1}, {ERR=>$inval}],
+ ['missing-bl', qw(-b --), {IN=>":\n"}, {OUT=>""}, {EXIT=>1},
+ {ERR=>$inval_pos}],
# This test fails with cut from textutils-1.22.
['empty-f1', '-f1', {IN=>""}, {OUT=>""}],