diff options
author | Jim Meyering <meyering@redhat.com> | 2008-03-23 12:31:07 +0100 |
---|---|---|
committer | Jim Meyering <meyering@redhat.com> | 2008-03-25 19:10:10 +0100 |
commit | da9f5e7fdffbb31f5c5949d5f931e757aa65e7c7 (patch) | |
tree | f8c6b60224a1642b90435f8a07863915496c27b5 | |
parent | 157a274da5c092886e7c2d845bf87ebec0fca40c (diff) | |
download | coreutils-da9f5e7fdffbb31f5c5949d5f931e757aa65e7c7.tar.xz |
join bug fix: adapt keycmp to work with new order-checking feature
* src/join.c (keycmp): Add two join-field parameters.
(check_order, join): Update callers.
Reported by Dmitry V. Levin in
http://thread.gmane.org/gmane.comp.gnu.coreutils.bugs/12731/focus=13017
* tests/join/Test.pm (chkodr-7): New test for this fix.
-rw-r--r-- | src/join.c | 27 | ||||
-rw-r--r-- | tests/join/Test.pm | 6 |
2 files changed, 21 insertions, 12 deletions
diff --git a/src/join.c b/src/join.c index 8f0d43667..23ab78c16 100644 --- a/src/join.c +++ b/src/join.c @@ -300,7 +300,8 @@ freeline (struct line *line) Report an error and exit if the comparison fails. */ static int -keycmp (struct line const *line1, struct line const *line2) +keycmp (struct line const *line1, struct line const *line2, + size_t jf_1, size_t jf_2) { /* Start of field to compare in each file. */ char *beg1; @@ -310,10 +311,10 @@ keycmp (struct line const *line1, struct line const *line2) size_t len2; /* Length of fields to compare. */ int diff; - if (join_field_1 < line1->nfields) + if (jf_1 < line1->nfields) { - beg1 = line1->fields[join_field_1].beg; - len1 = line1->fields[join_field_1].len; + beg1 = line1->fields[jf_1].beg; + len1 = line1->fields[jf_1].len; } else { @@ -321,10 +322,10 @@ keycmp (struct line const *line1, struct line const *line2) len1 = 0; } - if (join_field_2 < line2->nfields) + if (jf_2 < line2->nfields) { - beg2 = line2->fields[join_field_2].beg; - len2 = line2->fields[join_field_2].len; + beg2 = line2->fields[jf_2].beg; + len2 = line2->fields[jf_2].len; } else { @@ -376,7 +377,8 @@ check_order (const struct line *prev, { if (!issued_disorder_warning[whatfile-1]) { - if (keycmp (prev, current) > 0) + size_t join_field = whatfile == 1 ? join_field_1 : join_field_2; + if (keycmp (prev, current, join_field, join_field) > 0) { error ((check_input_order == CHECK_ORDER_ENABLED ? EXIT_FAILURE : 0), @@ -605,7 +607,8 @@ join (FILE *fp1, FILE *fp2) while (seq1.count && seq2.count) { size_t i; - diff = keycmp (&seq1.lines[0], &seq2.lines[0]); + diff = keycmp (&seq1.lines[0], &seq2.lines[0], + join_field_1, join_field_2); if (diff < 0) { if (print_unpairables_1) @@ -633,7 +636,8 @@ join (FILE *fp1, FILE *fp2) ++seq1.count; break; } - while (!keycmp (&seq1.lines[seq1.count - 1], &seq2.lines[0])); + while (!keycmp (&seq1.lines[seq1.count - 1], &seq2.lines[0], + join_field_1, join_field_2)); /* Keep reading lines from file2 as long as they continue to match the current line from file1. */ @@ -645,7 +649,8 @@ join (FILE *fp1, FILE *fp2) ++seq2.count; break; } - while (!keycmp (&seq1.lines[0], &seq2.lines[seq2.count - 1])); + while (!keycmp (&seq1.lines[0], &seq2.lines[seq2.count - 1], + join_field_1, join_field_2)); if (print_pairables) { diff --git a/tests/join/Test.pm b/tests/join/Test.pm index 6d91908f4..74fb32628 100644 --- a/tests/join/Test.pm +++ b/tests/join/Test.pm @@ -169,7 +169,11 @@ my @tv = ( # --nocheck-order option had any effect. We don't actually want to # guarantee that join produces this output on stdout. ['chkodr-6', '--nocheck-order', - [" b 1\n a 2\n", " b Y\n c Z\n"], "b 1 Y\n", 0] + [" b 1\n a 2\n", " b Y\n c Z\n"], "b 1 Y\n", 0], + +# Before 6.10.143, this would mistakenly fail with the diagnostic: +# join: File 1 is not in sorted order +['chkodr-7', '-12', ["2 a\n1 b\n", ""], "", 0], ) ; |