diff options
| author | Ron Yorston <rmy@pobox.com> | 2026-07-03 14:54:13 +0100 |
|---|---|---|
| committer | Ron Yorston <rmy@pobox.com> | 2026-07-03 14:54:13 +0100 |
| commit | d58fec2ae013f00f86dee5ce26b259761c63fffd (patch) | |
| tree | d89a004d81ba8f77df9dbb11f661afa0e22048fe | |
| parent | 696758b57738090390df9c2619c3cc5206e74146 (diff) | |
| download | busybox-w32-join2.tar.gz busybox-w32-join2.tar.bz2 busybox-w32-join2.zip | |
join: code shrink (4)join2
The user supplies field numbers with the -o, -1 and -2 options.
It feels more natural to convert these to 0-based field indices
in the code.
Saves 32-48 bytes.
Signed-off-by: Ron Yorston <rmy@pobox.com>
| -rw-r--r-- | coreutils/join.c | 51 |
1 files changed, 26 insertions, 25 deletions
diff --git a/coreutils/join.c b/coreutils/join.c index 7265452cd..370003d21 100644 --- a/coreutils/join.c +++ b/coreutils/join.c | |||
| @@ -53,12 +53,12 @@ typedef struct { | |||
| 53 | 53 | ||
| 54 | typedef struct { | 54 | typedef struct { |
| 55 | FILE *fp; | 55 | FILE *fp; |
| 56 | int idx; | 56 | int idx; /* index of join field in fields array */ |
| 57 | const char *field; /* this is a pointer to lines[0].fields[idx - 1] or "" */ | 57 | const char *field; /* pointer to lines[0].fields[idx] or "" */ |
| 58 | LINE *lines; | 58 | LINE *lines; |
| 59 | LINE pushback; | 59 | LINE pushback; |
| 60 | int linecount; | 60 | int linecount; /* number of lines currently cached */ |
| 61 | int linecap; | 61 | int linecap; /* current capacity of lines array */ |
| 62 | } FDAT; | 62 | } FDAT; |
| 63 | 63 | ||
| 64 | static int field_split(char *s, char sep, char ***fields) | 64 | static int field_split(char *s, char sep, char ***fields) |
| @@ -153,10 +153,10 @@ static void readfields(char sep, FDAT *f) | |||
| 153 | } | 153 | } |
| 154 | 154 | ||
| 155 | /* Ensure strcmp() matches on first pass through loop */ | 155 | /* Ensure strcmp() matches on first pass through loop */ |
| 156 | if (f->idx > curr.fieldcount) | 156 | if (f->idx >= curr.fieldcount) |
| 157 | field2 = ""; | 157 | field2 = ""; |
| 158 | else | 158 | else |
| 159 | field2 = (curr.fields)[f->idx - 1]; | 159 | field2 = (curr.fields)[f->idx]; |
| 160 | 160 | ||
| 161 | if (first) | 161 | if (first) |
| 162 | f->field = field2; | 162 | f->field = field2; |
| @@ -192,7 +192,7 @@ static void printfields(int *format, const char *empty_str, char sep, FDAT *f1, | |||
| 192 | int linef2; | 192 | int linef2; |
| 193 | int fn; | 193 | int fn; |
| 194 | int format_fl; | 194 | int format_fl; |
| 195 | int format_no; | 195 | int format_idx; |
| 196 | bool first; | 196 | bool first; |
| 197 | 197 | ||
| 198 | LINE *l1; | 198 | LINE *l1; |
| @@ -221,16 +221,16 @@ static void printfields(int *format, const char *empty_str, char sep, FDAT *f1, | |||
| 221 | bb_putchar(sep); | 221 | bb_putchar(sep); |
| 222 | 222 | ||
| 223 | format_fl = format[0]; | 223 | format_fl = format[0]; |
| 224 | format_no = format[1]; | 224 | format_idx = format[1]; |
| 225 | 225 | ||
| 226 | if (format_fl == 1) { | 226 | if (format_fl == 1) { |
| 227 | if (l1 != NULL && l1->fieldcount >= format_no && format_no > 0) | 227 | if (l1 != NULL && l1->fieldcount > format_idx) |
| 228 | fputs_stdout(fieldorempty(l1->fields[format_no - 1], empty_str)); | 228 | fputs_stdout(fieldorempty(l1->fields[format_idx], empty_str)); |
| 229 | else | 229 | else |
| 230 | fputs_stdout(empty_str); | 230 | fputs_stdout(empty_str); |
| 231 | } else if (format_fl == 2) { | 231 | } else if (format_fl == 2) { |
| 232 | if (l2 != NULL && l2->fieldcount >= format_no && format_no > 0) | 232 | if (l2 != NULL && l2->fieldcount > format_idx) |
| 233 | fputs_stdout(fieldorempty(l2->fields[format_no - 1], empty_str)); | 233 | fputs_stdout(fieldorempty(l2->fields[format_idx], empty_str)); |
| 234 | else | 234 | else |
| 235 | fputs_stdout(empty_str); | 235 | fputs_stdout(empty_str); |
| 236 | } else | 236 | } else |
| @@ -241,22 +241,22 @@ static void printfields(int *format, const char *empty_str, char sep, FDAT *f1, | |||
| 241 | } else { | 241 | } else { |
| 242 | fputs_stdout(fieldorempty(field, empty_str)); | 242 | fputs_stdout(fieldorempty(field, empty_str)); |
| 243 | 243 | ||
| 244 | fn = 1; | 244 | fn = 0; |
| 245 | if (l1 != NULL) | 245 | if (l1 != NULL) |
| 246 | while (l1->fields[fn - 1]) { | 246 | while (l1->fields[fn]) { |
| 247 | if (fn != f1->idx) { | 247 | if (fn != f1->idx) { |
| 248 | bb_putchar(sep); | 248 | bb_putchar(sep); |
| 249 | fputs_stdout(fieldorempty(l1->fields[fn - 1], empty_str)); | 249 | fputs_stdout(fieldorempty(l1->fields[fn], empty_str)); |
| 250 | } | 250 | } |
| 251 | fn++; | 251 | fn++; |
| 252 | } | 252 | } |
| 253 | 253 | ||
| 254 | fn = 1; | 254 | fn = 0; |
| 255 | if (l2 != NULL) | 255 | if (l2 != NULL) |
| 256 | while (l2->fields[fn - 1]) { | 256 | while (l2->fields[fn]) { |
| 257 | if (fn != f2->idx) { | 257 | if (fn != f2->idx) { |
| 258 | bb_putchar(sep); | 258 | bb_putchar(sep); |
| 259 | fputs_stdout(fieldorempty(l2->fields[fn - 1], empty_str)); | 259 | fputs_stdout(fieldorempty(l2->fields[fn], empty_str)); |
| 260 | } | 260 | } |
| 261 | fn++; | 261 | fn++; |
| 262 | } | 262 | } |
| @@ -269,7 +269,7 @@ static void printfields(int *format, const char *empty_str, char sep, FDAT *f1, | |||
| 269 | static void parsejformat(int **format_p, const char *format_str) | 269 | static void parsejformat(int **format_p, const char *format_str) |
| 270 | { | 270 | { |
| 271 | int *format; | 271 | int *format; |
| 272 | int field_no; | 272 | int field_idx; |
| 273 | 273 | ||
| 274 | char scache[20] = { 0 }; | 274 | char scache[20] = { 0 }; |
| 275 | 275 | ||
| @@ -306,11 +306,11 @@ static void parsejformat(int **format_p, const char *format_str) | |||
| 306 | bb_simple_error_msg_and_die("field specifier too large"); | 306 | bb_simple_error_msg_and_die("field specifier too large"); |
| 307 | memcpy(scache, format_str + 2, sn - 2); | 307 | memcpy(scache, format_str + 2, sn - 2); |
| 308 | scache[sn - 2] = '\0'; | 308 | scache[sn - 2] = '\0'; |
| 309 | field_no = xatoi_positive(scache); | 309 | field_idx = xatoi_positive(scache); |
| 310 | if (field_no <= 0) | 310 | if (--field_idx < 0) |
| 311 | bb_simple_error_msg_and_die("field number can't be 0"); | 311 | bb_simple_error_msg_and_die("field number can't be 0"); |
| 312 | format[n * 2] = *format_str - '0'; | 312 | format[n * 2] = *format_str - '0'; |
| 313 | format[n * 2 + 1] = field_no; | 313 | format[n * 2 + 1] = field_idx; |
| 314 | } else { | 314 | } else { |
| 315 | bb_simple_error_msg_and_die("field specifier must be 0, 1.x or 2.x"); | 315 | bb_simple_error_msg_and_die("field specifier must be 0, 1.x or 2.x"); |
| 316 | } | 316 | } |
| @@ -337,7 +337,7 @@ int join_main(int argc, char **argv) | |||
| 337 | 337 | ||
| 338 | FDAT f1 = { | 338 | FDAT f1 = { |
| 339 | .fp = NULL, | 339 | .fp = NULL, |
| 340 | .idx = 1, | 340 | .idx = 0, |
| 341 | .field = NULL, | 341 | .field = NULL, |
| 342 | .lines = NULL, | 342 | .lines = NULL, |
| 343 | .pushback = { .fields = NULL, .fieldcount = 0 }, | 343 | .pushback = { .fields = NULL, .fieldcount = 0 }, |
| @@ -346,7 +346,7 @@ int join_main(int argc, char **argv) | |||
| 346 | }; | 346 | }; |
| 347 | FDAT f2 = { | 347 | FDAT f2 = { |
| 348 | .fp = NULL, | 348 | .fp = NULL, |
| 349 | .idx = 1, | 349 | .idx = 0, |
| 350 | .field = NULL, | 350 | .field = NULL, |
| 351 | .lines = NULL, | 351 | .lines = NULL, |
| 352 | .pushback = { .fields = NULL, .fieldcount = 0 }, | 352 | .pushback = { .fields = NULL, .fieldcount = 0 }, |
| @@ -389,7 +389,8 @@ int join_main(int argc, char **argv) | |||
| 389 | } | 389 | } |
| 390 | } | 390 | } |
| 391 | 391 | ||
| 392 | if (f1.idx < 1 || f2.idx < 1) | 392 | if (((opts & FLAG_FIELD_1) && --f1.idx < 0) || |
| 393 | ((opts & FLAG_FIELD_2) && --f2.idx < 0)) | ||
| 393 | bb_simple_error_msg_and_die("field 0 doesn't exist"); | 394 | bb_simple_error_msg_and_die("field 0 doesn't exist"); |
| 394 | 395 | ||
| 395 | if (opts & FLAG_SEP_USED) { | 396 | if (opts & FLAG_SEP_USED) { |
