|
Kamil Dudka |
59a39f |
(sb) lin18nux/lsb compliance - cut - not stable enough, not applied
|
|
Kamil Dudka |
59a39f |
|
|
Ondrej Oprala |
01067b |
--- coreutils-8.24/src/cut.c 2015-06-26 19:05:22.000000000 +0200
|
|
Ondrej Oprala |
01067b |
+++ cut.c 2016-01-15 10:15:04.863804121 +0100
|
|
Ondrej Oprala |
01067b |
@@ -28,6 +28,11 @@
|
|
Ondrej Oprala |
01067b |
#include <assert.h>
|
|
Ondrej Oprala |
01067b |
#include <getopt.h>
|
|
Ondrej Oprala |
01067b |
#include <sys/types.h>
|
|
Ondrej Oprala |
01067b |
+
|
|
Ondrej Oprala |
01067b |
+#include <mbfile.h>
|
|
Ondrej Oprala |
01067b |
+#include <mbiter.h>
|
|
Ondrej Oprala |
01067b |
+#include <string.h>
|
|
Ondrej Oprala |
01067b |
+
|
|
Ondrej Oprala |
01067b |
#include "system.h"
|
|
Ondrej Oprala |
01067b |
|
|
Ondrej Oprala |
01067b |
#include "error.h"
|
|
Kamil Dudka |
d3849c |
@@ -61,25 +66,16 @@
|
|
Ondřej Vašík |
7d9c9a |
CURRENT_RP.HI then we make CURRENT_RP to point to the next range pair. */
|
|
Ondřej Vašík |
7d9c9a |
static struct field_range_pair *current_rp;
|
|
Ondrej Oprala |
01067b |
|
|
Ondrej Oprala |
01067b |
-/* This buffer is used to support the semantics of the -s option
|
|
Ondrej Oprala |
01067b |
- (or lack of same) when the specified field list includes (does
|
|
Ondrej Oprala |
01067b |
- not include) the first field. In both of those cases, the entire
|
|
Ondrej Oprala |
01067b |
- first field must be read into this buffer to determine whether it
|
|
Ondrej Oprala |
01067b |
- is followed by a delimiter or a newline before any of it may be
|
|
Ondrej Oprala |
01067b |
- output. Otherwise, cut_fields can do the job without using this
|
|
Ondrej Oprala |
01067b |
- buffer. */
|
|
Ondrej Oprala |
01067b |
-static char *field_1_buffer;
|
|
Ondrej Oprala |
01067b |
-
|
|
Ondrej Oprala |
01067b |
-/* The number of bytes allocated for FIELD_1_BUFFER. */
|
|
Ondrej Oprala |
01067b |
-static size_t field_1_bufsize;
|
|
Ondrej Oprala |
01067b |
-
|
|
Ondrej Oprala |
01067b |
enum operating_mode
|
|
Ondrej Oprala |
01067b |
{
|
|
Ondrej Oprala |
01067b |
undefined_mode,
|
|
Ondrej Oprala |
01067b |
|
|
Ondrej Oprala |
01067b |
- /* Output characters that are in the given bytes. */
|
|
Ondrej Oprala |
01067b |
+ /* Output the given bytes. */
|
|
Ondrej Oprala |
01067b |
byte_mode,
|
|
Ondrej Oprala |
01067b |
|
|
Ondrej Oprala |
01067b |
+ /* Output characters that are in the given positions . */
|
|
Ondrej Oprala |
01067b |
+ char_mode,
|
|
Ondrej Oprala |
01067b |
+
|
|
Ondrej Oprala |
01067b |
/* Output the given delimiter-separated fields. */
|
|
Ondrej Oprala |
01067b |
field_mode
|
|
Ondrej Oprala |
01067b |
};
|
|
Kamil Dudka |
d3849c |
@@ -91,12 +87,16 @@ static enum operating_mode operating_mode;
|
|
Ondrej Oprala |
01067b |
with field mode. */
|
|
Ondrej Oprala |
01067b |
static bool suppress_non_delimited;
|
|
Ondrej Oprala |
01067b |
|
|
Ondrej Oprala |
01067b |
+/* Unless true, we do not recognize multibyte characters in byte-splitting
|
|
Ondrej Oprala |
01067b |
+ mode. */
|
|
Ondrej Oprala |
01067b |
+static bool no_break_mb_chars;
|
|
Ondrej Oprala |
01067b |
+
|
|
Ondrej Oprala |
01067b |
/* If true, print all bytes, characters, or fields _except_
|
|
Ondrej Oprala |
01067b |
those that were specified. */
|
|
Ondrej Oprala |
01067b |
static bool complement;
|
|
Ondrej Oprala |
01067b |
|
|
Ondrej Oprala |
01067b |
/* The delimiter character for field mode. */
|
|
Ondrej Oprala |
01067b |
-static unsigned char delim;
|
|
Ondrej Oprala |
01067b |
+static mbf_char_t delim;
|
|
Ondrej Oprala |
01067b |
|
|
Ondřej Vašík |
7d9c9a |
/* The delimiter for each line/record. */
|
|
Ondřej Vašík |
7d9c9a |
static unsigned char line_delim = '\n';
|
|
Kamil Dudka |
d3849c |
@@ -109,7 +109,7 @@ static size_t output_delimiter_length;
|
|
Ondrej Oprala |
01067b |
|
|
Ondrej Oprala |
01067b |
/* The output field separator string. Defaults to the 1-character
|
|
Ondrej Oprala |
01067b |
string consisting of the input delimiter. */
|
|
Ondrej Oprala |
01067b |
-static char *output_delimiter_string;
|
|
Ondrej Oprala |
01067b |
+static char const *output_delimiter_string;
|
|
Ondrej Oprala |
01067b |
|
|
Ondrej Oprala |
01067b |
/* True if we have ever read standard input. */
|
|
Ondrej Oprala |
01067b |
static bool have_read_stdin;
|
|
Kamil Dudka |
d3849c |
@@ -164,7 +164,7 @@ Print selected parts of lines from each FILE to standard output.\n\
|
|
Ondrej Oprala |
01067b |
-f, --fields=LIST select only these fields; also print any line\n\
|
|
Ondrej Oprala |
01067b |
that contains no delimiter character, unless\n\
|
|
Ondrej Oprala |
01067b |
the -s option is specified\n\
|
|
Ondrej Oprala |
01067b |
- -n (ignored)\n\
|
|
Ondrej Oprala |
01067b |
+ -n with -b, don't split multibyte characters\n\
|
|
Ondrej Oprala |
01067b |
"), stdout);
|
|
Ondrej Oprala |
01067b |
fputs (_("\
|
|
Ondrej Oprala |
01067b |
--complement complement the set of selected bytes, characters\n\
|
|
Kamil Dudka |
d3849c |
@@ -211,6 +211,12 @@ next_item (size_t *item_idx)
|
|
Ondrej Oprala |
01067b |
current_rp++;
|
|
Ondrej Oprala |
01067b |
}
|
|
Ondrej Oprala |
01067b |
|
|
Ondrej Oprala |
01067b |
+static inline void
|
|
Ondrej Oprala |
01067b |
+next_item_n (size_t *item_idx, size_t n)
|
|
Ondrej Oprala |
01067b |
+{
|
|
Ondrej Oprala |
01067b |
+ while (n-- > 0)
|
|
Ondrej Oprala |
01067b |
+ next_item (item_idx);
|
|
Ondrej Oprala |
01067b |
+}
|
|
Ondrej Oprala |
01067b |
/* Return nonzero if the K'th field or byte is printable. */
|
|
Ondrej Oprala |
01067b |
|
|
Ondrej Oprala |
01067b |
static inline bool
|
|
Kamil Dudka |
d3849c |
@@ -219,6 +225,15 @@ print_kth (size_t k)
|
|
Ondrej Oprala |
01067b |
return current_rp->lo <= k;
|
|
Ondrej Oprala |
01067b |
}
|
|
Ondrej Oprala |
01067b |
|
|
Ondrej Oprala |
01067b |
+/* The lo and hi params should be used for the current characters byte position
|
|
Ondrej Oprala |
01067b |
+ * and byte size, respectively. */
|
|
Ondrej Oprala |
01067b |
+static inline bool
|
|
Ondrej Oprala |
01067b |
+rp_intersect (size_t lo, size_t hi)
|
|
Ondrej Oprala |
01067b |
+{
|
|
Ondrej Oprala |
01067b |
+ return ((current_rp->lo <= lo && current_rp->hi >= lo)
|
|
Ondrej Oprala |
01067b |
+ || (current_rp->lo <= hi && current_rp->hi >= hi));
|
|
Ondrej Oprala |
01067b |
+}
|
|
Ondrej Oprala |
01067b |
+
|
|
Ondrej Oprala |
01067b |
/* Return nonzero if K'th byte is the beginning of a range. */
|
|
Ondrej Oprala |
01067b |
|
|
Ondrej Oprala |
01067b |
static inline bool
|
|
Kamil Dudka |
d3849c |
@@ -281,23 +296,215 @@ cut_bytes (FILE *stream)
|
|
Ondrej Oprala |
01067b |
}
|
|
Ondrej Oprala |
01067b |
|
|
Ondrej Oprala |
01067b |
/* Read from stream STREAM, printing to standard output any selected fields. */
|
|
Ondrej Oprala |
01067b |
+extern ssize_t
|
|
Ondrej Oprala |
01067b |
+mb_getndelim2 (mbf_char_t **lineptr, size_t *linesize, size_t nmax,
|
|
Ondrej Oprala |
01067b |
+ mbf_char_t delim1, mbf_char_t delim2, mb_file_t *stream)
|
|
Ondrej Oprala |
01067b |
+{
|
|
Ondrej Oprala |
01067b |
+/* The maximum value that getndelim2 can return without suffering from
|
|
Ondrej Oprala |
01067b |
+ overflow problems, either internally (because of pointer
|
|
Ondrej Oprala |
01067b |
+ subtraction overflow) or due to the API (because of ssize_t). */
|
|
Ondrej Oprala |
01067b |
+#define GETNDELIM2_MAXIMUM (PTRDIFF_MAX < SSIZE_MAX ? PTRDIFF_MAX : SSIZE_MAX)
|
|
Ondrej Oprala |
01067b |
+
|
|
Ondrej Oprala |
01067b |
+/* Try to add at least this many bytes when extending the buffer.
|
|
Ondrej Oprala |
01067b |
+ MIN_CHUNK must be no greater than GETNDELIM2_MAXIMUM. */
|
|
Ondrej Oprala |
01067b |
+#define MIN_CHUNK 64
|
|
Ondrej Oprala |
01067b |
+ size_t nchars_avail; /* Allocated but unused chars in *LINEPTR. */
|
|
Ondrej Oprala |
01067b |
+ mbf_char_t *read_pos; /* Where we're reading into *LINEPTR. */
|
|
Ondrej Oprala |
01067b |
+ ssize_t chars_stored = -1;
|
|
Ondrej Oprala |
01067b |
+ mbf_char_t *ptr = *lineptr;
|
|
Ondrej Oprala |
01067b |
+ size_t size = *linesize;
|
|
Ondrej Oprala |
01067b |
+ bool found_delimiter;
|
|
Ondrej Oprala |
01067b |
+
|
|
Ondrej Oprala |
01067b |
+ if (!ptr)
|
|
Ondrej Oprala |
01067b |
+ {
|
|
Ondrej Oprala |
01067b |
+ size = nmax < MIN_CHUNK ? nmax : MIN_CHUNK;
|
|
Ondrej Oprala |
01067b |
+ ptr = malloc (size * sizeof (mbf_char_t));
|
|
Ondrej Oprala |
01067b |
+ if (!ptr)
|
|
Ondrej Oprala |
01067b |
+ return -1;
|
|
Ondrej Oprala |
01067b |
+ }
|
|
Ondrej Oprala |
01067b |
+
|
|
Ondrej Oprala |
01067b |
+ if (size < 0)
|
|
Ondrej Oprala |
01067b |
+ goto done;
|
|
Ondrej Oprala |
01067b |
+
|
|
Ondrej Oprala |
01067b |
+ nchars_avail = size;
|
|
Ondrej Oprala |
01067b |
+ read_pos = ptr;
|
|
Ondrej Oprala |
01067b |
+
|
|
Ondrej Oprala |
01067b |
+ if (nchars_avail == 0 && nmax <= size)
|
|
Ondrej Oprala |
01067b |
+ goto done;
|
|
Ondrej Oprala |
01067b |
+
|
|
Ondrej Oprala |
01067b |
+ /* Normalize delimiters, since memchr2 doesn't handle EOF. */
|
|
Ondrej Oprala |
01067b |
+ if (mb_iseof (delim1))
|
|
Ondrej Oprala |
01067b |
+ mb_copy (&delim1, &delim2);
|
|
Ondrej Oprala |
01067b |
+ else if (mb_iseof (delim2))
|
|
Ondrej Oprala |
01067b |
+ mb_copy (&delim2, &delim1);
|
|
Ondrej Oprala |
01067b |
+
|
|
Ondrej Oprala |
01067b |
+ flockfile (stream);
|
|
Ondrej Oprala |
01067b |
+
|
|
Ondrej Oprala |
01067b |
+ found_delimiter = false;
|
|
Ondrej Oprala |
01067b |
+ do
|
|
Ondrej Oprala |
01067b |
+ {
|
|
Ondrej Oprala |
01067b |
+ /* Here always ptr + size == read_pos + nchars_avail.
|
|
Ondrej Oprala |
01067b |
+ Also nchars_avail > 0 || size < nmax. */
|
|
Ondrej Oprala |
01067b |
+
|
|
Ondrej Oprala |
01067b |
+ mbf_char_t c IF_LINT (= 0);
|
|
Ondrej Oprala |
01067b |
+ {
|
|
Ondrej Oprala |
01067b |
+ mbf_getc (c, *stream);
|
|
Ondrej Oprala |
01067b |
+ if (mb_iseof (c))
|
|
Ondrej Oprala |
01067b |
+ {
|
|
Ondrej Oprala |
01067b |
+ /* Return partial line, if any. */
|
|
Ondrej Oprala |
01067b |
+ if (read_pos == ptr)
|
|
Ondrej Oprala |
01067b |
+ goto unlock_done;
|
|
Ondrej Oprala |
01067b |
+ else
|
|
Ondrej Oprala |
01067b |
+ break;
|
|
Ondrej Oprala |
01067b |
+ }
|
|
Ondrej Oprala |
01067b |
+ if (mb_equal (c, delim1) || mb_equal (c, delim2))
|
|
Ondrej Oprala |
01067b |
+ found_delimiter = true;
|
|
Ondrej Oprala |
01067b |
+ }
|
|
Ondrej Oprala |
01067b |
+
|
|
Ondrej Oprala |
01067b |
+ /* We always want at least one byte left in the buffer, since we
|
|
Ondrej Oprala |
01067b |
+ always (unless we get an error while reading the first byte)
|
|
Ondrej Oprala |
01067b |
+ NUL-terminate the line buffer. */
|
|
Ondrej Oprala |
01067b |
+
|
|
Ondrej Oprala |
01067b |
+ if (!nchars_avail)
|
|
Ondrej Oprala |
01067b |
+ {
|
|
Ondrej Oprala |
01067b |
+ /* Grow size proportionally, not linearly, to avoid O(n^2)
|
|
Ondrej Oprala |
01067b |
+ running time. */
|
|
Ondrej Oprala |
01067b |
+ size_t newsize = size < MIN_CHUNK ? size + MIN_CHUNK : 2 * size;
|
|
Ondrej Oprala |
01067b |
+ mbf_char_t *newptr;
|
|
Ondrej Oprala |
01067b |
+
|
|
Ondrej Oprala |
01067b |
+ /* Respect nmax. This handles possible integer overflow. */
|
|
Ondrej Oprala |
01067b |
+ if (! (size < newsize && newsize <= nmax))
|
|
Ondrej Oprala |
01067b |
+ newsize = nmax;
|
|
Ondrej Oprala |
01067b |
+
|
|
Ondrej Oprala |
01067b |
+ if (GETNDELIM2_MAXIMUM < newsize)
|
|
Ondrej Oprala |
01067b |
+ {
|
|
Ondrej Oprala |
01067b |
+ size_t newsizemax = GETNDELIM2_MAXIMUM + 1;
|
|
Ondrej Oprala |
01067b |
+ if (size == newsizemax)
|
|
Ondrej Oprala |
01067b |
+ goto unlock_done;
|
|
Ondrej Oprala |
01067b |
+ newsize = newsizemax;
|
|
Ondrej Oprala |
01067b |
+ }
|
|
Ondrej Oprala |
01067b |
+ nchars_avail = newsize - (read_pos - ptr);
|
|
Ondrej Oprala |
01067b |
+ newptr = realloc (ptr, newsize * sizeof (mbf_char_t));
|
|
Ondrej Oprala |
01067b |
+ if (!newptr)
|
|
Ondrej Oprala |
01067b |
+ goto unlock_done;
|
|
Ondrej Oprala |
01067b |
+ ptr = newptr;
|
|
Ondrej Oprala |
01067b |
+ size = newsize;
|
|
Ondrej Oprala |
01067b |
+ read_pos = size - nchars_avail + ptr;
|
|
Ondrej Oprala |
01067b |
+ }
|
|
Ondrej Oprala |
01067b |
+
|
|
Ondrej Oprala |
01067b |
+ /* Here, if size < nmax, nchars_avail >= buffer_len + 1.
|
|
Ondrej Oprala |
01067b |
+ If size == nmax, nchars_avail > 0. */
|
|
Ondrej Oprala |
01067b |
+
|
|
Ondřej Vašík |
06a5ca |
+ if (1 < nchars_avail--)
|
|
Ondrej Oprala |
01067b |
+ {
|
|
Ondrej Oprala |
01067b |
+ mb_copy(read_pos++, &c);
|
|
Ondrej Oprala |
01067b |
+ }
|
|
Ondrej Oprala |
01067b |
+
|
|
Ondrej Oprala |
01067b |
+ }
|
|
Ondrej Oprala |
01067b |
+ while (!found_delimiter);
|
|
Ondrej Oprala |
01067b |
+
|
|
Ondrej Oprala |
01067b |
+ chars_stored = (read_pos - ptr);
|
|
Ondrej Oprala |
01067b |
+
|
|
Ondrej Oprala |
01067b |
+ unlock_done:
|
|
Ondrej Oprala |
01067b |
+ funlockfile (stream);
|
|
Ondrej Oprala |
01067b |
+
|
|
Ondrej Oprala |
01067b |
+ done:
|
|
Ondrej Oprala |
01067b |
+ *lineptr = ptr;
|
|
Ondrej Oprala |
01067b |
+ *linesize = size;
|
|
Ondrej Oprala |
01067b |
+ return chars_stored;
|
|
Ondrej Oprala |
01067b |
+}
|
|
Ondrej Oprala |
01067b |
+
|
|
Ondrej Oprala |
01067b |
+static void
|
|
Ondrej Oprala |
01067b |
+cut_chars (FILE *stream)
|
|
Ondrej Oprala |
01067b |
+{
|
|
Ondrej Oprala |
01067b |
+ size_t char_idx; /* Number of chars in the line so far. */
|
|
Ondrej Oprala |
01067b |
+ bool print_delimiter;
|
|
Ondrej Oprala |
01067b |
+ mbf_char_t c;
|
|
Ondrej Oprala |
01067b |
+ mb_file_t mbf;
|
|
Ondrej Oprala |
01067b |
+
|
|
Ondrej Oprala |
01067b |
+ print_delimiter = false;
|
|
Ondrej Oprala |
01067b |
+ char_idx = 0;
|
|
Ondřej Vašík |
7d9c9a |
+ current_rp = frp;
|
|
Ondrej Oprala |
01067b |
+
|
|
Ondrej Oprala |
01067b |
+ mbf_init (mbf, stream);
|
|
Ondrej Oprala |
01067b |
+ while (true)
|
|
Ondrej Oprala |
01067b |
+ {
|
|
Ondrej Oprala |
01067b |
+ mbf_getc (c, mbf);
|
|
Ondrej Oprala |
01067b |
+
|
|
Ondřej Vašík |
7d9c9a |
+ if (mb_iseq (c, line_delim))
|
|
Ondrej Oprala |
01067b |
+ {
|
|
Ondřej Vašík |
7d9c9a |
+ putc (line_delim, stdout);
|
|
Ondrej Oprala |
01067b |
+ char_idx = 0;
|
|
Ondrej Oprala |
01067b |
+ print_delimiter = false;
|
|
Ondřej Vašík |
7d9c9a |
+ current_rp = frp;
|
|
Ondrej Oprala |
01067b |
+ }
|
|
Ondrej Oprala |
01067b |
+ else if (mb_iseof (c))
|
|
Ondrej Oprala |
01067b |
+ {
|
|
Ondrej Oprala |
01067b |
+ if (char_idx > 0)
|
|
Ondřej Vašík |
7d9c9a |
+ putc (line_delim, stdout);
|
|
Ondrej Oprala |
01067b |
+ break;
|
|
Ondrej Oprala |
01067b |
+ }
|
|
Ondrej Oprala |
01067b |
+ else
|
|
Ondrej Oprala |
01067b |
+ {
|
|
Ondrej Oprala |
01067b |
+ /* Forward by one byte. */
|
|
Ondrej Oprala |
01067b |
+ next_item (&char_idx);
|
|
Ondrej Oprala |
01067b |
+
|
|
Ondrej Oprala |
01067b |
+ /* Check if the current characters byte range is within
|
|
Ondrej Oprala |
01067b |
+ * the argument list. */
|
|
Ondrej Oprala |
01067b |
+ if (rp_intersect (char_idx, char_idx + mb_len (c) - 1))
|
|
Ondrej Oprala |
01067b |
+ {
|
|
Ondrej Oprala |
01067b |
+ if (output_delimiter_specified)
|
|
Ondrej Oprala |
01067b |
+ {
|
|
Ondrej Oprala |
01067b |
+ if (print_delimiter && is_range_start_index (char_idx))
|
|
Ondrej Oprala |
01067b |
+ {
|
|
Ondrej Oprala |
01067b |
+ fwrite (output_delimiter_string, sizeof (char),
|
|
Ondrej Oprala |
01067b |
+ output_delimiter_length, stdout);
|
|
Ondrej Oprala |
01067b |
+ }
|
|
Ondrej Oprala |
01067b |
+ print_delimiter = true;
|
|
Ondrej Oprala |
01067b |
+ }
|
|
Ondrej Oprala |
01067b |
+ mb_putc (c, stdout);
|
|
Ondrej Oprala |
01067b |
+ }
|
|
Ondrej Oprala |
01067b |
+
|
|
Ondrej Oprala |
01067b |
+ /* Byte mode with multibyte characters uncut (-b -n). */
|
|
Ondrej Oprala |
01067b |
+ if (no_break_mb_chars)
|
|
Ondrej Oprala |
01067b |
+ /* Forward by an additional byte_length (c) - 1. */
|
|
Ondrej Oprala |
01067b |
+ next_item_n (&char_idx, mb_len (c) - 1);
|
|
Ondrej Oprala |
01067b |
+ }
|
|
Ondrej Oprala |
01067b |
+ }
|
|
Ondrej Oprala |
01067b |
+}
|
|
Ondrej Oprala |
01067b |
|
|
Ondrej Oprala |
01067b |
static void
|
|
Ondrej Oprala |
01067b |
cut_fields (FILE *stream)
|
|
Ondrej Oprala |
01067b |
{
|
|
Ondrej Oprala |
01067b |
- int c;
|
|
Ondrej Oprala |
01067b |
+
|
|
Ondrej Oprala |
01067b |
+ /* This buffer is used to support the semantics of the -s option
|
|
Ondrej Oprala |
01067b |
+ (or lack of same) when the specified field list includes (does
|
|
Ondrej Oprala |
01067b |
+ not include) the first field. In both of those cases, the entire
|
|
Ondrej Oprala |
01067b |
+ first field must be read into this buffer to determine whether it
|
|
Ondrej Oprala |
01067b |
+ is followed by a delimiter or a newline before any of it may be
|
|
Ondrej Oprala |
01067b |
+ output. Otherwise, cut_fields can do the job without using this
|
|
Ondrej Oprala |
01067b |
+ buffer. */
|
|
Ondrej Oprala |
01067b |
+ mbf_char_t *field_1_buffer = 0;
|
|
Ondrej Oprala |
01067b |
+ /* The number of bytes allocated for FIELD_1_BUFFER. */
|
|
Ondrej Oprala |
01067b |
+ size_t field_1_bufsize;
|
|
Ondrej Oprala |
01067b |
+
|
|
Ondrej Oprala |
01067b |
+
|
|
Ondrej Oprala |
01067b |
+ mbf_char_t c, d;
|
|
Ondrej Oprala |
01067b |
+ mb_file_t mbf;
|
|
Ondrej Oprala |
01067b |
size_t field_idx = 1;
|
|
Ondrej Oprala |
01067b |
bool found_any_selected_field = false;
|
|
Ondrej Oprala |
01067b |
bool buffer_first_field;
|
|
Ondrej Oprala |
01067b |
|
|
Ondřej Vašík |
7d9c9a |
current_rp = frp;
|
|
Ondrej Oprala |
01067b |
|
|
Ondrej Oprala |
01067b |
- c = getc (stream);
|
|
Ondrej Oprala |
01067b |
- if (c == EOF)
|
|
Ondrej Oprala |
01067b |
+ mbf_init (mbf, stream);
|
|
Ondrej Oprala |
01067b |
+ mbf_getc (c, mbf);
|
|
Ondrej Oprala |
01067b |
+ if (mb_iseof (c))
|
|
Ondrej Oprala |
01067b |
return;
|
|
Ondrej Oprala |
01067b |
|
|
Ondrej Oprala |
01067b |
- ungetc (c, stream);
|
|
Ondrej Oprala |
01067b |
- c = 0;
|
|
Ondrej Oprala |
01067b |
+ mbf_ungetc (c, mbf);
|
|
Ondrej Oprala |
01067b |
+ mb_setascii (&c, 0);
|
|
Ondrej Oprala |
01067b |
+ mb_copy (&d, &delim);
|
|
Ondrej Oprala |
01067b |
|
|
Ondrej Oprala |
01067b |
/* To support the semantics of the -s flag, we may have to buffer
|
|
Ondrej Oprala |
01067b |
all of the first field to determine whether it is 'delimited.'
|
|
Kamil Dudka |
d3849c |
@@ -312,10 +519,14 @@ cut_fields (FILE *stream)
|
|
Ondrej Oprala |
01067b |
if (field_idx == 1 && buffer_first_field)
|
|
Ondrej Oprala |
01067b |
{
|
|
Ondrej Oprala |
01067b |
ssize_t len;
|
|
Ondrej Oprala |
01067b |
- size_t n_bytes;
|
|
Ondrej Oprala |
01067b |
+ size_t n_chars;
|
|
Ondrej Oprala |
01067b |
+ mbf_char_t nl;
|
|
Ondřej Vašík |
7d9c9a |
+ mb_setascii (&nl, line_delim);
|
|
Ondrej Oprala |
01067b |
+
|
|
Ondrej Oprala |
01067b |
+ len = mb_getndelim2 (&field_1_buffer, &field_1_bufsize,
|
|
Ondrej Oprala |
01067b |
+ GETNLINE_NO_LIMIT, d, nl, &mbf);
|
|
Ondrej Oprala |
01067b |
+
|
|
Ondrej Oprala |
01067b |
|
|
Ondrej Oprala |
01067b |
- len = getndelim2 (&field_1_buffer, &field_1_bufsize, 0,
|
|
Ondřej Vašík |
7d9c9a |
- GETNLINE_NO_LIMIT, delim, line_delim, stream);
|
|
Ondrej Oprala |
01067b |
if (len < 0)
|
|
Ondrej Oprala |
01067b |
{
|
|
Ondrej Oprala |
01067b |
free (field_1_buffer);
|
|
Kamil Dudka |
d3849c |
@@ -325,15 +536,15 @@ cut_fields (FILE *stream)
|
|
Ondrej Oprala |
01067b |
xalloc_die ();
|
|
Ondrej Oprala |
01067b |
}
|
|
Ondrej Oprala |
01067b |
|
|
Ondrej Oprala |
01067b |
- n_bytes = len;
|
|
Ondrej Oprala |
01067b |
- assert (n_bytes != 0);
|
|
Ondrej Oprala |
01067b |
+ n_chars = len;
|
|
Ondrej Oprala |
01067b |
+ //assert (n_chars != 0);
|
|
Ondrej Oprala |
01067b |
|
|
Ondrej Oprala |
01067b |
- c = 0;
|
|
Ondrej Oprala |
01067b |
+ mb_setascii (&c, 0);
|
|
Ondrej Oprala |
01067b |
|
|
Ondrej Oprala |
01067b |
/* If the first field extends to the end of line (it is not
|
|
Ondrej Oprala |
01067b |
delimited) and we are printing all non-delimited lines,
|
|
Ondrej Oprala |
01067b |
print this one. */
|
|
Ondrej Oprala |
01067b |
- if (to_uchar (field_1_buffer[n_bytes - 1]) != delim)
|
|
Ondrej Oprala |
01067b |
+ if (!mb_equal (field_1_buffer[n_chars - 1], d))
|
|
Ondrej Oprala |
01067b |
{
|
|
Ondrej Oprala |
01067b |
if (suppress_non_delimited)
|
|
Ondrej Oprala |
01067b |
{
|
|
Kamil Dudka |
d3849c |
@@ -341,26 +552,30 @@ cut_fields (FILE *stream)
|
|
Ondrej Oprala |
01067b |
}
|
|
Ondrej Oprala |
01067b |
else
|
|
Ondrej Oprala |
01067b |
{
|
|
Ondrej Oprala |
01067b |
- fwrite (field_1_buffer, sizeof (char), n_bytes, stdout);
|
|
Ondrej Oprala |
01067b |
+ for (int i = 0; i < n_chars; ++i)
|
|
Ondrej Oprala |
01067b |
+ mb_putc (field_1_buffer[i], stdout);
|
|
Ondrej Oprala |
01067b |
+
|
|
Ondrej Oprala |
01067b |
/* Make sure the output line is newline terminated. */
|
|
Ondřej Vašík |
7d9c9a |
- if (field_1_buffer[n_bytes - 1] != line_delim)
|
|
Ondřej Vašík |
7d9c9a |
+ if (!mb_iseq (field_1_buffer[n_chars - 1], line_delim))
|
|
Ondřej Vašík |
7d9c9a |
putchar (line_delim);
|
|
Ondřej Vašík |
7d9c9a |
- c = line_delim;
|
|
Ondřej Vašík |
7d9c9a |
+ mb_setascii (&c, line_delim);
|
|
Ondrej Oprala |
01067b |
}
|
|
Ondrej Oprala |
01067b |
continue;
|
|
Ondrej Oprala |
01067b |
}
|
|
Ondrej Oprala |
01067b |
if (print_kth (1))
|
|
Ondrej Oprala |
01067b |
{
|
|
Ondrej Oprala |
01067b |
/* Print the field, but not the trailing delimiter. */
|
|
Ondrej Oprala |
01067b |
- fwrite (field_1_buffer, sizeof (char), n_bytes - 1, stdout);
|
|
Ondrej Oprala |
01067b |
+ for (int i = 0; i < n_chars - 1; ++i)
|
|
Ondrej Oprala |
01067b |
+ mb_putc (field_1_buffer[i], stdout);
|
|
Ondrej Oprala |
01067b |
|
|
Ondrej Oprala |
01067b |
/* With -d$'\n' don't treat the last '\n' as a delimiter. */
|
|
Ondřej Vašík |
7d9c9a |
- if (delim == line_delim)
|
|
Ondřej Vašík |
7d9c9a |
+ if (mb_iseq (d, line_delim))
|
|
Ondrej Oprala |
01067b |
{
|
|
Ondrej Oprala |
01067b |
- int last_c = getc (stream);
|
|
Ondrej Oprala |
01067b |
- if (last_c != EOF)
|
|
Ondrej Oprala |
01067b |
+ mbf_char_t last_c;
|
|
Ondrej Oprala |
01067b |
+ mbf_getc (last_c, mbf);
|
|
Ondrej Oprala |
01067b |
+ if (!mb_iseof (last_c))
|
|
Ondrej Oprala |
01067b |
{
|
|
Ondrej Oprala |
01067b |
- ungetc (last_c, stream);
|
|
Ondrej Oprala |
01067b |
+ mbf_ungetc (last_c, mbf);
|
|
Ondrej Oprala |
01067b |
found_any_selected_field = true;
|
|
Ondrej Oprala |
01067b |
}
|
|
Ondrej Oprala |
01067b |
}
|
|
Kamil Dudka |
d3849c |
@@ -370,7 +585,8 @@ cut_fields (FILE *stream)
|
|
Ondrej Oprala |
01067b |
next_item (&field_idx);
|
|
Ondrej Oprala |
01067b |
}
|
|
Ondrej Oprala |
01067b |
|
|
Ondrej Oprala |
01067b |
- int prev_c = c;
|
|
Ondrej Oprala |
01067b |
+ mbf_char_t prev_c;
|
|
Ondrej Oprala |
01067b |
+ mb_copy (&prev_c, &c);
|
|
Ondrej Oprala |
01067b |
|
|
Ondrej Oprala |
01067b |
if (print_kth (field_idx))
|
|
Ondrej Oprala |
01067b |
{
|
|
Kamil Dudka |
d3849c |
@@ -381,42 +597,46 @@ cut_fields (FILE *stream)
|
|
Ondrej Oprala |
01067b |
}
|
|
Ondrej Oprala |
01067b |
found_any_selected_field = true;
|
|
Ondrej Oprala |
01067b |
|
|
Ondřej Vašík |
7d9c9a |
- while ((c = getc (stream)) != delim && c != line_delim && c != EOF)
|
|
Ondrej Oprala |
01067b |
+ mbf_getc (c, mbf);
|
|
Ondřej Vašík |
7d9c9a |
+ while (!mb_equal (c, d) && !mb_iseq (c, line_delim) && !mb_iseof (c))
|
|
Ondrej Oprala |
01067b |
{
|
|
Ondrej Oprala |
01067b |
- putchar (c);
|
|
Ondrej Oprala |
01067b |
- prev_c = c;
|
|
Ondrej Oprala |
01067b |
+ mb_putc (c, stdout);
|
|
Ondrej Oprala |
01067b |
+ mb_copy (&prev_c, &c);
|
|
Ondrej Oprala |
01067b |
+ mbf_getc (c, mbf);
|
|
Ondrej Oprala |
01067b |
}
|
|
Ondrej Oprala |
01067b |
}
|
|
Ondrej Oprala |
01067b |
else
|
|
Ondrej Oprala |
01067b |
{
|
|
Ondřej Vašík |
7d9c9a |
- while ((c = getc (stream)) != delim && c != line_delim && c != EOF)
|
|
Ondrej Oprala |
01067b |
+ mbf_getc (c, mbf);
|
|
Ondřej Vašík |
7d9c9a |
+ while (!mb_equal (c, d) && !mb_iseq (c, line_delim) && !mb_iseof (c))
|
|
Ondrej Oprala |
01067b |
{
|
|
Ondrej Oprala |
01067b |
- prev_c = c;
|
|
Ondrej Oprala |
01067b |
+ mb_copy (&prev_c, &c);
|
|
Ondrej Oprala |
01067b |
+ mbf_getc (c, mbf);
|
|
Ondrej Oprala |
01067b |
}
|
|
Ondrej Oprala |
01067b |
}
|
|
Ondrej Oprala |
01067b |
|
|
Ondrej Oprala |
01067b |
/* With -d$'\n' don't treat the last '\n' as a delimiter. */
|
|
Ondřej Vašík |
7d9c9a |
- if (delim == line_delim && c == delim)
|
|
Ondřej Vašík |
7d9c9a |
+ if (mb_iseq (d, line_delim) && mb_equal (c, d))
|
|
Ondrej Oprala |
01067b |
{
|
|
Ondrej Oprala |
01067b |
- int last_c = getc (stream);
|
|
Ondrej Oprala |
01067b |
- if (last_c != EOF)
|
|
Ondrej Oprala |
01067b |
- ungetc (last_c, stream);
|
|
Ondrej Oprala |
01067b |
+ mbf_char_t last_c;
|
|
Ondrej Oprala |
01067b |
+ mbf_getc (last_c, mbf);
|
|
Ondrej Oprala |
01067b |
+ if (!mb_iseof (last_c))
|
|
Ondrej Oprala |
01067b |
+ mbf_ungetc (last_c, mbf);
|
|
Ondrej Oprala |
01067b |
else
|
|
Ondrej Oprala |
01067b |
- c = last_c;
|
|
Ondrej Oprala |
01067b |
+ mb_copy (&c, &last_c);
|
|
Ondrej Oprala |
01067b |
}
|
|
Ondrej Oprala |
01067b |
|
|
Ondrej Oprala |
01067b |
- if (c == delim)
|
|
Ondrej Oprala |
01067b |
+ if (mb_equal (c, d))
|
|
Ondrej Oprala |
01067b |
next_item (&field_idx);
|
|
Ondřej Vašík |
7d9c9a |
- else if (c == line_delim || c == EOF)
|
|
Ondřej Vašík |
7d9c9a |
+ else if (mb_iseq (c, line_delim) || mb_iseof (c))
|
|
Ondrej Oprala |
01067b |
{
|
|
Ondrej Oprala |
01067b |
if (found_any_selected_field
|
|
Ondrej Oprala |
01067b |
|| !(suppress_non_delimited && field_idx == 1))
|
|
Ondrej Oprala |
01067b |
{
|
|
Ondřej Vašík |
7d9c9a |
- if (c == line_delim || prev_c != line_delim
|
|
Ondřej Vašík |
7d9c9a |
- || delim == line_delim)
|
|
Ondřej Vašík |
7d9c9a |
+ if (mb_iseq (c, line_delim) || !mb_iseq (prev_c, line_delim) || mb_iseq (d, line_delim))
|
|
Ondřej Vašík |
7d9c9a |
putchar (line_delim);
|
|
Ondrej Oprala |
01067b |
}
|
|
Ondrej Oprala |
01067b |
- if (c == EOF)
|
|
Ondrej Oprala |
01067b |
+ if (mb_iseof (c))
|
|
Ondrej Oprala |
01067b |
break;
|
|
Ondrej Oprala |
01067b |
field_idx = 1;
|
|
Ondřej Vašík |
7d9c9a |
current_rp = frp;
|
|
Kamil Dudka |
d3849c |
@@ -429,7 +649,14 @@ static void
|
|
Ondrej Oprala |
01067b |
cut_stream (FILE *stream)
|
|
Ondrej Oprala |
01067b |
{
|
|
Ondrej Oprala |
01067b |
if (operating_mode == byte_mode)
|
|
Ondrej Oprala |
01067b |
- cut_bytes (stream);
|
|
Ondrej Oprala |
01067b |
+ {
|
|
Ondrej Oprala |
01067b |
+ if (no_break_mb_chars)
|
|
Ondrej Oprala |
01067b |
+ cut_chars (stream);
|
|
Ondrej Oprala |
01067b |
+ else
|
|
Ondrej Oprala |
01067b |
+ cut_bytes (stream);
|
|
Ondrej Oprala |
01067b |
+ }
|
|
Ondrej Oprala |
01067b |
+ else if (operating_mode == char_mode)
|
|
Ondrej Oprala |
01067b |
+ cut_chars (stream);
|
|
Ondrej Oprala |
01067b |
else
|
|
Ondrej Oprala |
01067b |
cut_fields (stream);
|
|
Ondrej Oprala |
01067b |
}
|
|
Kamil Dudka |
d3849c |
@@ -483,6 +710,7 @@ main (int argc, char **argv)
|
|
Ondrej Oprala |
01067b |
bool ok;
|
|
Ondrej Oprala |
01067b |
bool delim_specified = false;
|
|
Ondrej Oprala |
01067b |
char *spec_list_string IF_LINT ( = NULL);
|
|
Ondrej Oprala |
01067b |
+ mbi_iterator_t iter;
|
|
Ondrej Oprala |
01067b |
|
|
Ondrej Oprala |
01067b |
initialize_main (&argc, &argv);
|
|
Ondrej Oprala |
01067b |
set_program_name (argv[0]);
|
|
Kamil Dudka |
d3849c |
@@ -496,8 +724,10 @@ main (int argc, char **argv)
|
|
Ondrej Oprala |
01067b |
|
|
Ondrej Oprala |
01067b |
/* By default, all non-delimited lines are printed. */
|
|
Ondrej Oprala |
01067b |
suppress_non_delimited = false;
|
|
Ondrej Oprala |
01067b |
+ /* Default behaviour for -b, unless -n is also specified. */
|
|
Ondrej Oprala |
01067b |
+ no_break_mb_chars = false;
|
|
Ondrej Oprala |
01067b |
|
|
Ondrej Oprala |
01067b |
- delim = '\0';
|
|
Ondrej Oprala |
01067b |
+ mb_setascii (&delim, '\0');
|
|
Ondrej Oprala |
01067b |
have_read_stdin = false;
|
|
Ondrej Oprala |
01067b |
|
|
Ondřej Vašík |
7d9c9a |
while ((optc = getopt_long (argc, argv, "b:c:d:f:nsz", longopts, NULL)) != -1)
|
|
Kamil Dudka |
d3849c |
@@ -505,7 +735,6 @@ main (int argc, char **argv)
|
|
Ondrej Oprala |
01067b |
switch (optc)
|
|
Ondrej Oprala |
01067b |
{
|
|
Ondrej Oprala |
01067b |
case 'b':
|
|
Ondrej Oprala |
01067b |
- case 'c':
|
|
Ondrej Oprala |
01067b |
/* Build the byte list. */
|
|
Ondrej Oprala |
01067b |
if (operating_mode != undefined_mode)
|
|
Ondrej Oprala |
01067b |
FATAL_ERROR (_("only one type of list may be specified"));
|
|
Kamil Dudka |
d3849c |
@@ -513,6 +742,14 @@ main (int argc, char **argv)
|
|
Ondrej Oprala |
01067b |
spec_list_string = optarg;
|
|
Ondrej Oprala |
01067b |
break;
|
|
Ondrej Oprala |
01067b |
|
|
Ondrej Oprala |
01067b |
+ case 'c':
|
|
Ondrej Oprala |
01067b |
+ /* Build the char list. */
|
|
Ondrej Oprala |
01067b |
+ if (operating_mode != undefined_mode)
|
|
Ondrej Oprala |
01067b |
+ FATAL_ERROR (_("only one type of list may be specified"));
|
|
Ondrej Oprala |
01067b |
+ operating_mode = char_mode;
|
|
Ondrej Oprala |
01067b |
+ spec_list_string = optarg;
|
|
Ondrej Oprala |
01067b |
+ break;
|
|
Ondrej Oprala |
01067b |
+
|
|
Ondrej Oprala |
01067b |
case 'f':
|
|
Ondrej Oprala |
01067b |
/* Build the field list. */
|
|
Ondrej Oprala |
01067b |
if (operating_mode != undefined_mode)
|
|
Kamil Dudka |
d3849c |
@@ -524,9 +761,17 @@ main (int argc, char **argv)
|
|
Ondrej Oprala |
01067b |
case 'd':
|
|
Ondrej Oprala |
01067b |
/* New delimiter. */
|
|
Ondrej Oprala |
01067b |
/* Interpret -d '' to mean 'use the NUL byte as the delimiter.' */
|
|
Ondrej Oprala |
01067b |
- if (optarg[0] != '\0' && optarg[1] != '\0')
|
|
Ondrej Oprala |
01067b |
+ mbi_init (iter, optarg, strlen (optarg));
|
|
Ondrej Oprala |
01067b |
+ if (!mbi_avail (iter))
|
|
Ondrej Oprala |
01067b |
+ mb_setascii (&delim, '\0');
|
|
Ondrej Oprala |
01067b |
+ else
|
|
Ondrej Oprala |
11e5aa |
+ {
|
|
Ondrej Oprala |
11e5aa |
+ mb_copy (&delim, &mbi_cur (iter));
|
|
Ondrej Oprala |
01067b |
+
|
|
Ondrej Oprala |
11e5aa |
+ mbi_advance (iter);
|
|
Ondrej Oprala |
11e5aa |
+ if (mbi_avail (iter))
|
|
Ondrej Oprala |
01067b |
FATAL_ERROR (_("the delimiter must be a single character"));
|
|
Ondrej Oprala |
01067b |
- delim = optarg[0];
|
|
Kamil Dudka |
d3849c |
+ }
|
|
Ondrej Oprala |
01067b |
delim_specified = true;
|
|
Ondrej Oprala |
01067b |
break;
|
|
Ondrej Oprala |
01067b |
|
|
Kamil Dudka |
d3849c |
@@ -540,6 +785,7 @@ main (int argc, char **argv)
|
|
Ondrej Oprala |
01067b |
break;
|
|
Ondrej Oprala |
01067b |
|
|
Ondrej Oprala |
01067b |
case 'n':
|
|
Ondrej Oprala |
01067b |
+ no_break_mb_chars = true;
|
|
Ondrej Oprala |
01067b |
break;
|
|
Ondrej Oprala |
01067b |
|
|
Ondrej Oprala |
01067b |
case 's':
|
|
Kamil Dudka |
d3849c |
@@ -579,15 +825,12 @@ main (int argc, char **argv)
|
|
Ondřej Vašík |
7d9c9a |
| (complement ? SETFLD_COMPLEMENT : 0) );
|
|
Ondrej Oprala |
01067b |
|
|
Ondrej Oprala |
01067b |
if (!delim_specified)
|
|
Ondrej Oprala |
01067b |
- delim = '\t';
|
|
Ondrej Oprala |
01067b |
+ mb_setascii (&delim, '\t');
|
|
Ondrej Oprala |
01067b |
|
|
Ondrej Oprala |
01067b |
if (output_delimiter_string == NULL)
|
|
Ondrej Oprala |
01067b |
{
|
|
Ondrej Oprala |
01067b |
- static char dummy[2];
|
|
Ondrej Oprala |
01067b |
- dummy[0] = delim;
|
|
Ondrej Oprala |
01067b |
- dummy[1] = '\0';
|
|
Ondrej Oprala |
01067b |
- output_delimiter_string = dummy;
|
|
Ondrej Oprala |
01067b |
- output_delimiter_length = 1;
|
|
Ondrej Oprala |
01067b |
+ output_delimiter_string = mb_ptr (delim);
|
|
Ondrej Oprala |
01067b |
+ output_delimiter_length = mb_len (delim);
|
|
Ondrej Oprala |
01067b |
}
|
|
Ondrej Oprala |
01067b |
|
|
Ondrej Oprala |
01067b |
if (optind == argc)
|