summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/uniq.c66
1 files changed, 23 insertions, 43 deletions
diff --git a/src/uniq.c b/src/uniq.c
index 182a6332b..d76fa7ed2 100644
--- a/src/uniq.c
+++ b/src/uniq.c
@@ -23,7 +23,6 @@
#include "system.h"
#include "argmatch.h"
-#include "linebuffer.h"
#include "die.h"
#include "error.h"
#include "fadvise.h"
@@ -35,6 +34,8 @@
#include "memcasecmp.h"
#include "quote.h"
+#include "sort-uniq-keyfuncs.c"
+
/* The official name of this program (e.g., no 'g' prefix). */
#define PROGRAM_NAME "uniq"
@@ -45,7 +46,7 @@
#define SWAP_LINES(A, B) \
do \
{ \
- struct linebuffer *_tmp; \
+ struct line *_tmp; \
_tmp = (A); \
(A) = (B); \
(B) = _tmp; \
@@ -256,14 +257,14 @@ size_opt (char const *opt, char const *msgid)
return MIN (size, SIZE_MAX);
}
-/* Given a linebuffer LINE,
+/* Given a line LINE,
return a pointer to the beginning of the line's field to be compared. */
static char * _GL_ATTRIBUTE_PURE
-find_field (struct linebuffer const *line)
+find_field (struct line const *line)
{
size_t count;
- char const *lp = line->buffer;
+ char const *lp = line->text;
size_t size = line->length - 1;
size_t i = 0;
@@ -277,41 +278,17 @@ find_field (struct linebuffer const *line)
i += MIN (skip_chars, size - i);
- return line->buffer + i;
+ return line->text + i;
}
-/* Return false if two strings OLD and NEW match, true if not.
- OLD and NEW point not to the beginnings of the lines
- but rather to the beginnings of the fields to compare.
- OLDLEN and NEWLEN are their lengths. */
-
-static bool
-different (char *old, char *new, size_t oldlen, size_t newlen)
-{
- if (check_chars < oldlen)
- oldlen = check_chars;
- if (check_chars < newlen)
- newlen = check_chars;
-
- if (ignore_case)
- {
- /* FIXME: This should invoke strcoll somehow. */
- return oldlen != newlen || memcasecmp (old, new, oldlen);
- }
- else if (hard_LC_COLLATE)
- return xmemcoll (old, oldlen, new, newlen) != 0;
- else
- return oldlen != newlen || memcmp (old, new, oldlen);
-}
-
-/* Output the line in linebuffer LINE to standard output
+/* Output the line in line LINE to standard output
provided that the switches say it should be output.
MATCH is true if the line matches the previous line.
If requested, print the number of times it occurred, as well;
LINECOUNT + 1 is the number of times that the line occurred. */
static void
-writeline (struct linebuffer const *line,
+writeline (struct line const *line,
bool match, uintmax_t linecount)
{
if (! (linecount == 0 ? output_unique
@@ -322,7 +299,7 @@ writeline (struct linebuffer const *line,
if (countmode == count_occurrences)
printf ("%7" PRIuMAX " ", linecount + 1);
- fwrite (line->buffer, sizeof (char), line->length, stdout);
+ fwrite (line->text, sizeof (char), line->length, stdout);
}
/* Process input file INFILE with output to OUTFILE.
@@ -331,8 +308,8 @@ writeline (struct linebuffer const *line,
static void
check_file (const char *infile, const char *outfile, char delimiter)
{
- struct linebuffer lb1, lb2;
- struct linebuffer *thisline, *prevline;
+ struct buffer buf;
+ struct line *thisline, *prevline;
if (! (STREQ (infile, "-") || freopen (infile, "r", stdin)))
die (EXIT_FAILURE, errno, "%s", quotef (infile));
@@ -341,8 +318,11 @@ check_file (const char *infile, const char *outfile, char delimiter)
fadvise (stdin, FADVISE_SEQUENTIAL);
- thisline = &lb1;
- prevline = &lb2;
+ initbuf (&buf, sizeof (struct line),
+ MAX (merge_buffer_size, sort_size));
+
+ thisline = lb1.buf;
+ prevline = lb2.buf;
initbuffer (thisline);
initbuffer (prevline);
@@ -378,7 +358,7 @@ check_file (const char *infile, const char *outfile, char delimiter)
break;
thisfield = find_field (thisline);
- thislen = thisline->length - 1 - (thisfield - thisline->buffer);
+ thislen = thisline->length - 1 - (thisfield - thisline->text);
new_group = (prevline->length == 0
|| different (thisfield, prevfield, thislen, prevlen));
@@ -391,7 +371,7 @@ check_file (const char *infile, const char *outfile, char delimiter)
if (new_group || grouping != GM_NONE)
{
- fwrite (thisline->buffer, sizeof (char),
+ fwrite (thisline->text, sizeof (char),
thisline->length, stdout);
SWAP_LINES (prevline, thisline);
@@ -413,7 +393,7 @@ check_file (const char *infile, const char *outfile, char delimiter)
if (readlinebuffer_delim (prevline, stdin, delimiter) == 0)
goto closefiles;
prevfield = find_field (prevline);
- prevlen = prevline->length - 1 - (prevfield - prevline->buffer);
+ prevlen = prevline->length - 1 - (prevfield - prevline->text);
while (!feof (stdin))
{
@@ -427,7 +407,7 @@ check_file (const char *infile, const char *outfile, char delimiter)
break;
}
thisfield = find_field (thisline);
- thislen = thisline->length - 1 - (thisfield - thisline->buffer);
+ thislen = thisline->length - 1 - (thisfield - thisline->text);
match = !different (thisfield, prevfield, thislen, prevlen);
match_count += match;
@@ -474,8 +454,8 @@ check_file (const char *infile, const char *outfile, char delimiter)
/* stdout is handled via the atexit-invoked close_stdout function. */
- free (lb1.buffer);
- free (lb2.buffer);
+ free (lb1.text);
+ free (lb2.text);
}
enum Skip_field_option_type