diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2009-10-03 11:43:48 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2009-10-03 11:43:48 +0200 |
commit | cae409c6aa2bc649be5a76639b242f672bc2a86e (patch) | |
tree | 4e8d6bd98b52de5d0514a45fa96081e6757ef46d /coreutils | |
parent | ffd4774ad256628cb50894277ad27a6bd7db4716 (diff) | |
download | busybox-w32-cae409c6aa2bc649be5a76639b242f672bc2a86e.tar.gz busybox-w32-cae409c6aa2bc649be5a76639b242f672bc2a86e.tar.bz2 busybox-w32-cae409c6aa2bc649be5a76639b242f672bc2a86e.zip |
ls: code shrink
function old new delta
count_dirs 81 86 +5
dnalloc 13 17 +4
showfiles 372 370 -2
ls_main 833 825 -8
showdirs 505 489 -16
splitdnarray 189 120 -69
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/4 up/down: 9/-95) Total: -86 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'coreutils')
-rw-r--r-- | coreutils/ls.c | 88 |
1 files changed, 44 insertions, 44 deletions
diff --git a/coreutils/ls.c b/coreutils/ls.c index d1521529f..f8416898b 100644 --- a/coreutils/ls.c +++ b/coreutils/ls.c | |||
@@ -385,27 +385,29 @@ static char append_char(mode_t mode) | |||
385 | } | 385 | } |
386 | #endif | 386 | #endif |
387 | 387 | ||
388 | #define countdirs(A, B) count_dirs((A), (B), 1) | 388 | static unsigned count_dirs(struct dnode **dn, int which) |
389 | #define countsubdirs(A, B) count_dirs((A), (B), 0) | ||
390 | static unsigned count_dirs(struct dnode **dn, unsigned nfiles, int notsubdirs) | ||
391 | { | 389 | { |
392 | unsigned i, dirs; | 390 | unsigned dirs, all; |
393 | 391 | ||
394 | if (!dn) | 392 | if (!dn) |
395 | return 0; | 393 | return 0; |
396 | dirs = 0; | 394 | |
397 | for (i = 0; i < nfiles; i++) { | 395 | dirs = all = 0; |
396 | for (; *dn; dn++) { | ||
398 | const char *name; | 397 | const char *name; |
399 | if (!S_ISDIR(dn[i]->dstat.st_mode)) | 398 | |
399 | all++; | ||
400 | if (!S_ISDIR((*dn)->dstat.st_mode)) | ||
400 | continue; | 401 | continue; |
401 | name = dn[i]->name; | 402 | name = (*dn)->name; |
402 | if (notsubdirs | 403 | if (which != SPLIT_SUBDIR /* if not requested to skip . / .. */ |
404 | /* or if it's not . or .. */ | ||
403 | || name[0] != '.' || (name[1] && (name[1] != '.' || name[2])) | 405 | || name[0] != '.' || (name[1] && (name[1] != '.' || name[2])) |
404 | ) { | 406 | ) { |
405 | dirs++; | 407 | dirs++; |
406 | } | 408 | } |
407 | } | 409 | } |
408 | return dirs; | 410 | return which != SPLIT_FILE ? dirs : all - dirs; |
409 | } | 411 | } |
410 | 412 | ||
411 | /* get memory to hold an array of pointers */ | 413 | /* get memory to hold an array of pointers */ |
@@ -414,18 +416,19 @@ static struct dnode **dnalloc(unsigned num) | |||
414 | if (num < 1) | 416 | if (num < 1) |
415 | return NULL; | 417 | return NULL; |
416 | 418 | ||
419 | num++; /* so that we have terminating NULL */ | ||
417 | return xzalloc(num * sizeof(struct dnode *)); | 420 | return xzalloc(num * sizeof(struct dnode *)); |
418 | } | 421 | } |
419 | 422 | ||
420 | #if ENABLE_FEATURE_LS_RECURSIVE | 423 | #if ENABLE_FEATURE_LS_RECURSIVE |
421 | static void dfree(struct dnode **dnp, unsigned nfiles) | 424 | static void dfree(struct dnode **dnp) |
422 | { | 425 | { |
423 | unsigned i; | 426 | unsigned i; |
424 | 427 | ||
425 | if (dnp == NULL) | 428 | if (dnp == NULL) |
426 | return; | 429 | return; |
427 | 430 | ||
428 | for (i = 0; i < nfiles; i++) { | 431 | for (i = 0; dnp[i]; i++) { |
429 | struct dnode *cur = dnp[i]; | 432 | struct dnode *cur = dnp[i]; |
430 | if (cur->fname_allocated) | 433 | if (cur->fname_allocated) |
431 | free((char*)cur->fullname); | 434 | free((char*)cur->fullname); |
@@ -437,40 +440,36 @@ static void dfree(struct dnode **dnp, unsigned nfiles) | |||
437 | #define dfree(...) ((void)0) | 440 | #define dfree(...) ((void)0) |
438 | #endif | 441 | #endif |
439 | 442 | ||
440 | static struct dnode **splitdnarray(struct dnode **dn, unsigned nfiles, int which) | 443 | /* Returns NULL-terminated malloced vector of pointers (or NULL) */ |
444 | static struct dnode **splitdnarray(struct dnode **dn, int which) | ||
441 | { | 445 | { |
442 | unsigned dncnt, i, d; | 446 | unsigned dncnt, d; |
443 | struct dnode **dnp; | 447 | struct dnode **dnp; |
444 | 448 | ||
445 | if (dn == NULL) | 449 | if (dn == NULL) |
446 | return NULL; | 450 | return NULL; |
447 | 451 | ||
448 | /* count how many dirs and regular files there are */ | 452 | /* count how many dirs or files there are */ |
449 | if (which == SPLIT_SUBDIR) | 453 | dncnt = count_dirs(dn, which); |
450 | dncnt = countsubdirs(dn, nfiles); | ||
451 | else { | ||
452 | dncnt = countdirs(dn, nfiles); /* assume we are looking for dirs */ | ||
453 | if (which == SPLIT_FILE) | ||
454 | dncnt = nfiles - dncnt; /* looking for files */ | ||
455 | } | ||
456 | 454 | ||
457 | /* allocate a file array and a dir array */ | 455 | /* allocate a file array and a dir array */ |
458 | dnp = dnalloc(dncnt); | 456 | dnp = dnalloc(dncnt); |
459 | 457 | ||
460 | /* copy the entrys into the file or dir array */ | 458 | /* copy the entrys into the file or dir array */ |
461 | for (d = i = 0; i < nfiles; i++) { | 459 | for (d = 0; *dn; dn++) { |
462 | if (S_ISDIR(dn[i]->dstat.st_mode)) { | 460 | if (S_ISDIR((*dn)->dstat.st_mode)) { |
463 | const char *name; | 461 | const char *name; |
462 | |||
464 | if (!(which & (SPLIT_DIR|SPLIT_SUBDIR))) | 463 | if (!(which & (SPLIT_DIR|SPLIT_SUBDIR))) |
465 | continue; | 464 | continue; |
466 | name = dn[i]->name; | 465 | name = (*dn)->name; |
467 | if ((which & SPLIT_DIR) | 466 | if ((which & SPLIT_DIR) |
468 | || name[0]!='.' || (name[1] && (name[1]!='.' || name[2])) | 467 | || name[0]!='.' || (name[1] && (name[1]!='.' || name[2])) |
469 | ) { | 468 | ) { |
470 | dnp[d++] = dn[i]; | 469 | dnp[d++] = *dn; |
471 | } | 470 | } |
472 | } else if (!(which & (SPLIT_DIR|SPLIT_SUBDIR))) { | 471 | } else if (!(which & (SPLIT_DIR|SPLIT_SUBDIR))) { |
473 | dnp[d++] = dn[i]; | 472 | dnp[d++] = *dn; |
474 | } | 473 | } |
475 | } | 474 | } |
476 | return dnp; | 475 | return dnp; |
@@ -538,7 +537,7 @@ static void showfiles(struct dnode **dn, unsigned nfiles) | |||
538 | ncols = 1; | 537 | ncols = 1; |
539 | } else { | 538 | } else { |
540 | /* find the longest file name, use that as the column width */ | 539 | /* find the longest file name, use that as the column width */ |
541 | for (i = 0; i < nfiles; i++) { | 540 | for (i = 0; dn[i]; i++) { |
542 | int len = bb_mbstrlen(dn[i]->name); | 541 | int len = bb_mbstrlen(dn[i]->name); |
543 | if (column_width < len) | 542 | if (column_width < len) |
544 | column_width = len; | 543 | column_width = len; |
@@ -610,11 +609,11 @@ static off_t calculate_blocks(struct dnode **dn, int nfiles) | |||
610 | #endif | 609 | #endif |
611 | 610 | ||
612 | 611 | ||
613 | static void showdirs(struct dnode **dn, unsigned ndirs, int first) | 612 | static void showdirs(struct dnode **dn, int first) |
614 | { | 613 | { |
615 | unsigned i, nfiles; | 614 | unsigned nfiles; |
616 | struct dnode **subdnp; | ||
617 | unsigned dndirs; | 615 | unsigned dndirs; |
616 | struct dnode **subdnp; | ||
618 | struct dnode **dnd; | 617 | struct dnode **dnd; |
619 | 618 | ||
620 | /* Never happens: | 619 | /* Never happens: |
@@ -623,17 +622,17 @@ static void showdirs(struct dnode **dn, unsigned ndirs, int first) | |||
623 | } | 622 | } |
624 | */ | 623 | */ |
625 | 624 | ||
626 | for (i = 0; i < ndirs; i++) { | 625 | for (; *dn; dn++) { |
627 | if (all_fmt & (DISP_DIRNAME | DISP_RECURSIVE)) { | 626 | if (all_fmt & (DISP_DIRNAME | DISP_RECURSIVE)) { |
628 | if (!first) | 627 | if (!first) |
629 | bb_putchar('\n'); | 628 | bb_putchar('\n'); |
630 | first = 0; | 629 | first = 0; |
631 | printf("%s:\n", dn[i]->fullname); | 630 | printf("%s:\n", (*dn)->fullname); |
632 | } | 631 | } |
633 | subdnp = list_dir(dn[i]->fullname, &nfiles); | 632 | subdnp = list_dir((*dn)->fullname, &nfiles); |
634 | #if ENABLE_DESKTOP | 633 | #if ENABLE_DESKTOP |
635 | if (all_fmt & STYLE_LONG) | 634 | if (all_fmt & STYLE_LONG) |
636 | printf("total %"OFF_FMT"u\n", calculate_blocks(subdnp, nfiles)); | 635 | printf("total %"OFF_FMT"u\n", calculate_blocks(subdnp)); |
637 | #endif | 636 | #endif |
638 | if (nfiles > 0) { | 637 | if (nfiles > 0) { |
639 | /* list all files at this level */ | 638 | /* list all files at this level */ |
@@ -643,22 +642,23 @@ static void showdirs(struct dnode **dn, unsigned ndirs, int first) | |||
643 | && (all_fmt & DISP_RECURSIVE) | 642 | && (all_fmt & DISP_RECURSIVE) |
644 | ) { | 643 | ) { |
645 | /* recursive - list the sub-dirs */ | 644 | /* recursive - list the sub-dirs */ |
646 | dnd = splitdnarray(subdnp, nfiles, SPLIT_SUBDIR); | 645 | dnd = splitdnarray(subdnp, SPLIT_SUBDIR); |
647 | dndirs = countsubdirs(subdnp, nfiles); | 646 | dndirs = count_dirs(subdnp, SPLIT_SUBDIR); |
648 | if (dndirs > 0) { | 647 | if (dndirs > 0) { |
649 | dnsort(dnd, dndirs); | 648 | dnsort(dnd, dndirs); |
650 | showdirs(dnd, dndirs, 0); | 649 | showdirs(dnd, 0); |
651 | /* free the array of dnode pointers to the dirs */ | 650 | /* free the array of dnode pointers to the dirs */ |
652 | free(dnd); | 651 | free(dnd); |
653 | } | 652 | } |
654 | } | 653 | } |
655 | /* free the dnodes and the fullname mem */ | 654 | /* free the dnodes and the fullname mem */ |
656 | dfree(subdnp, nfiles); | 655 | dfree(subdnp); |
657 | } | 656 | } |
658 | } | 657 | } |
659 | } | 658 | } |
660 | 659 | ||
661 | 660 | ||
661 | /* Returns NULL-terminated malloced vector of pointers (or NULL) */ | ||
662 | static struct dnode **list_dir(const char *path, unsigned *nfiles_p) | 662 | static struct dnode **list_dir(const char *path, unsigned *nfiles_p) |
663 | { | 663 | { |
664 | struct dnode *dn, *cur, **dnp; | 664 | struct dnode *dn, *cur, **dnp; |
@@ -1070,9 +1070,9 @@ int ls_main(int argc UNUSED_PARAM, char **argv) | |||
1070 | dnsort(dnp, nfiles); | 1070 | dnsort(dnp, nfiles); |
1071 | showfiles(dnp, nfiles); | 1071 | showfiles(dnp, nfiles); |
1072 | } else { | 1072 | } else { |
1073 | dnd = splitdnarray(dnp, nfiles, SPLIT_DIR); | 1073 | dnd = splitdnarray(dnp, SPLIT_DIR); |
1074 | dnf = splitdnarray(dnp, nfiles, SPLIT_FILE); | 1074 | dnf = splitdnarray(dnp, SPLIT_FILE); |
1075 | dndirs = countdirs(dnp, nfiles); | 1075 | dndirs = count_dirs(dnp, SPLIT_DIR); |
1076 | dnfiles = nfiles - dndirs; | 1076 | dnfiles = nfiles - dndirs; |
1077 | if (dnfiles > 0) { | 1077 | if (dnfiles > 0) { |
1078 | dnsort(dnf, dnfiles); | 1078 | dnsort(dnf, dnfiles); |
@@ -1082,12 +1082,12 @@ int ls_main(int argc UNUSED_PARAM, char **argv) | |||
1082 | } | 1082 | } |
1083 | if (dndirs > 0) { | 1083 | if (dndirs > 0) { |
1084 | dnsort(dnd, dndirs); | 1084 | dnsort(dnd, dndirs); |
1085 | showdirs(dnd, dndirs, dnfiles == 0); | 1085 | showdirs(dnd, dnfiles == 0); |
1086 | if (ENABLE_FEATURE_CLEAN_UP) | 1086 | if (ENABLE_FEATURE_CLEAN_UP) |
1087 | free(dnd); | 1087 | free(dnd); |
1088 | } | 1088 | } |
1089 | } | 1089 | } |
1090 | if (ENABLE_FEATURE_CLEAN_UP) | 1090 | if (ENABLE_FEATURE_CLEAN_UP) |
1091 | dfree(dnp, nfiles); | 1091 | dfree(dnp); |
1092 | return exit_code; | 1092 | return exit_code; |
1093 | } | 1093 | } |