summaryrefslogtreecommitdiff
path: root/usr.bin/sort
diff options
context:
space:
mode:
authordsl <dsl@NetBSD.org>2009-08-15 21:26:32 +0000
committerdsl <dsl@NetBSD.org>2009-08-15 21:26:32 +0000
commit59ede5ae24cb88de52f7f04082c76c204f53ad01 (patch)
treef3c4e1687b06497568ae96f7ac90673722714a74 /usr.bin/sort
parente671c9cf085c83e0e9c10859c67d9131bac0b937 (diff)
Always add an REC_D char (usually \n) as the last sort key char - we
almost always need one. But do ADD it, instead of overwriting the last byte of the last key since that may be requesting the other end of the sort order. There is no need to check for space for the line after adding the key, but we might as well check before - just to optimise that case. This might fix some of the sort bugs - but not the one I'm looking at!
Diffstat (limited to 'usr.bin/sort')
-rw-r--r--usr.bin/sort/fields.c40
1 files changed, 21 insertions, 19 deletions
diff --git a/usr.bin/sort/fields.c b/usr.bin/sort/fields.c
index bf6d79719c9..9e626f29b0a 100644
--- a/usr.bin/sort/fields.c
+++ b/usr.bin/sort/fields.c
@@ -1,4 +1,4 @@
-/* $NetBSD: fields.c,v 1.22 2009/08/15 18:40:01 dsl Exp $ */
+/* $NetBSD: fields.c,v 1.23 2009/08/15 21:26:32 dsl Exp $ */
/*-
* Copyright (c) 2000-2003 The NetBSD Foundation, Inc.
@@ -66,7 +66,7 @@
#include "sort.h"
#ifndef lint
-__RCSID("$NetBSD: fields.c,v 1.22 2009/08/15 18:40:01 dsl Exp $");
+__RCSID("$NetBSD: fields.c,v 1.23 2009/08/15 21:26:32 dsl Exp $");
__SCCSID("@(#)fields.c 8.1 (Berkeley) 6/6/93");
#endif /* not lint */
@@ -136,30 +136,32 @@ enterkey(RECHEADER *keybuf, const u_char *keybuf_end, u_char *line_data, size_t
if (clist[0].start < line_data)
clist[0].start++;
+ /*
+ * We write the sort keys (concatenated) followed by the
+ * original line data (for output) as the 'keybuf' data.
+ * keybuf->length is the number of key bytes + data bytes.
+ * keybuf->offset is the number of key bytes.
+ * We add a record separator (usually \n) after the key in case
+ * (as is usual) we need to preserve the order of equal lines,
+ * and for 'sort -u'.
+ */
keypos = keybuf->data;
- endkey = keybuf_end - line_size;
- for (ftpos = fieldtable + 1; ftpos->icol.num; ftpos++)
+ endkey = keybuf_end - line_size - 1;
+ if (endkey <= keypos)
+ /* No room for any key bytes */
+ return 1;
+
+ for (ftpos = fieldtable + 1; ftpos->icol.num; ftpos++) {
if ((keypos = enterfield(keypos, endkey, ftpos,
fieldtable->flags)) == NULL)
return (1);
+ }
+ *keypos++ = REC_D;
keybuf->offset = keypos - keybuf->data;
keybuf->length = keybuf->offset + line_size;
- if (keybuf->data + keybuf->length > keybuf_end) {
- /* line too long for buffer */
- return (1);
- }
-
- /*
- * Make [s]radixsort() only sort by relevant part of key if:
- * 1. we want to choose unique items by relevant field[s]
- * 2. we want stable sort and so the items should be sorted only by
- * the relevant field[s]
- */
- if (UNIQUE || (stable_sort && keybuf->offset < line_size))
- keypos[-1] = REC_D;
- memcpy(keybuf->data + keybuf->offset, line_data, line_size);
+ memcpy(keypos, line_data, line_size);
return (0);
}
@@ -332,7 +334,7 @@ number(u_char *pos, const u_char *bufend, u_char *line, u_char *lineend, int Rfl
}
/* This forces a gap around the record delimiter
- * Thus fnum has vaues over (0,254) -> ((0,REC_D-1),(REC_D+1,255));
+ * Thus fnum has values over (0,254) -> ((0,REC_D-1),(REC_D+1,255));
* rnum over (0,254) -> (255,REC_D+1),(REC_D-1,0))
*/
void