diff options
| author | Denys Vlasenko <vda.linux@googlemail.com> | 2009-10-03 01:15:47 +0200 |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2009-10-03 01:15:47 +0200 |
| commit | 76c7d9500a535ba7cfdf2c040324e72f17c803fe (patch) | |
| tree | bc4077fd4cd6a3fe2ae225135adf704330898a5b | |
| parent | 87c150c7cc6ac12ce3ce14f55148c65830a746fd (diff) | |
| download | busybox-w32-76c7d9500a535ba7cfdf2c040324e72f17c803fe.tar.gz busybox-w32-76c7d9500a535ba7cfdf2c040324e72f17c803fe.tar.bz2 busybox-w32-76c7d9500a535ba7cfdf2c040324e72f17c803fe.zip | |
ls: code shrink
function old new delta
list_single - 1006 +1006
print_name 211 209 -2
dnalloc 15 13 -2
splitdnarray 192 189 -3
ls_main 848 833 -15
showdirs 564 505 -59
showfiles 1460 372 -1088
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 0/6 up/down: 1006/-1169) Total: -163 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
| -rw-r--r-- | coreutils/ls.c | 140 |
1 files changed, 71 insertions, 69 deletions
diff --git a/coreutils/ls.c b/coreutils/ls.c index bb6165b39..7fb6b2cf7 100644 --- a/coreutils/ls.c +++ b/coreutils/ls.c | |||
| @@ -232,19 +232,17 @@ static const unsigned opt_flags[] = { | |||
| 232 | /* | 232 | /* |
| 233 | * a directory entry and its stat info are stored here | 233 | * a directory entry and its stat info are stored here |
| 234 | */ | 234 | */ |
| 235 | struct dnode { /* the basic node */ | 235 | struct dnode { |
| 236 | const char *name; /* the dir entry name */ | 236 | const char *name; /* the dir entry name */ |
| 237 | const char *fullname; /* the dir entry name */ | 237 | const char *fullname; /* the dir entry name */ |
| 238 | int allocated; | 238 | struct dnode *next; /* point at the next node */ |
| 239 | smallint fname_allocated; | ||
| 239 | struct stat dstat; /* the file stat info */ | 240 | struct stat dstat; /* the file stat info */ |
| 240 | IF_SELINUX(security_context_t sid;) | 241 | IF_SELINUX(security_context_t sid;) |
| 241 | struct dnode *next; /* point at the next node */ | ||
| 242 | }; | 242 | }; |
| 243 | 243 | ||
| 244 | static struct dnode **list_dir(const char *); | 244 | static struct dnode **list_dir(const char *, unsigned *); |
| 245 | static struct dnode **dnalloc(int); | 245 | static unsigned list_single(const struct dnode *); |
| 246 | static int list_single(const struct dnode *); | ||
| 247 | |||
| 248 | 246 | ||
| 249 | struct globals { | 247 | struct globals { |
| 250 | #if ENABLE_FEATURE_LS_COLOR | 248 | #if ENABLE_FEATURE_LS_COLOR |
| @@ -318,7 +316,7 @@ static struct dnode *my_stat(const char *fullname, const char *name, int force_f | |||
| 318 | } | 316 | } |
| 319 | } | 317 | } |
| 320 | 318 | ||
| 321 | cur = xmalloc(sizeof(struct dnode)); | 319 | cur = xmalloc(sizeof(*cur)); |
| 322 | cur->fullname = fullname; | 320 | cur->fullname = fullname; |
| 323 | cur->name = name; | 321 | cur->name = name; |
| 324 | cur->dstat = dstat; | 322 | cur->dstat = dstat; |
| @@ -391,9 +389,9 @@ static char append_char(mode_t mode) | |||
| 391 | 389 | ||
| 392 | #define countdirs(A, B) count_dirs((A), (B), 1) | 390 | #define countdirs(A, B) count_dirs((A), (B), 1) |
| 393 | #define countsubdirs(A, B) count_dirs((A), (B), 0) | 391 | #define countsubdirs(A, B) count_dirs((A), (B), 0) |
| 394 | static int count_dirs(struct dnode **dn, int nfiles, int notsubdirs) | 392 | static unsigned count_dirs(struct dnode **dn, unsigned nfiles, int notsubdirs) |
| 395 | { | 393 | { |
| 396 | int i, dirs; | 394 | unsigned i, dirs; |
| 397 | 395 | ||
| 398 | if (!dn) | 396 | if (!dn) |
| 399 | return 0; | 397 | return 0; |
| @@ -404,7 +402,7 @@ static int count_dirs(struct dnode **dn, int nfiles, int notsubdirs) | |||
| 404 | continue; | 402 | continue; |
| 405 | name = dn[i]->name; | 403 | name = dn[i]->name; |
| 406 | if (notsubdirs | 404 | if (notsubdirs |
| 407 | || name[0]!='.' || (name[1] && (name[1]!='.' || name[2])) | 405 | || name[0] != '.' || (name[1] && (name[1] != '.' || name[2])) |
| 408 | ) { | 406 | ) { |
| 409 | dirs++; | 407 | dirs++; |
| 410 | } | 408 | } |
| @@ -412,22 +410,8 @@ static int count_dirs(struct dnode **dn, int nfiles, int notsubdirs) | |||
| 412 | return dirs; | 410 | return dirs; |
| 413 | } | 411 | } |
| 414 | 412 | ||
| 415 | static int countfiles(struct dnode **dnp) | ||
| 416 | { | ||
| 417 | int nfiles; | ||
| 418 | struct dnode *cur; | ||
| 419 | |||
| 420 | if (dnp == NULL) | ||
| 421 | return 0; | ||
| 422 | nfiles = 0; | ||
| 423 | for (cur = dnp[0]; cur->next; cur = cur->next) | ||
| 424 | nfiles++; | ||
| 425 | nfiles++; | ||
| 426 | return nfiles; | ||
| 427 | } | ||
| 428 | |||
| 429 | /* get memory to hold an array of pointers */ | 413 | /* get memory to hold an array of pointers */ |
| 430 | static struct dnode **dnalloc(int num) | 414 | static struct dnode **dnalloc(unsigned num) |
| 431 | { | 415 | { |
| 432 | if (num < 1) | 416 | if (num < 1) |
| 433 | return NULL; | 417 | return NULL; |
| @@ -436,16 +420,16 @@ static struct dnode **dnalloc(int num) | |||
| 436 | } | 420 | } |
| 437 | 421 | ||
| 438 | #if ENABLE_FEATURE_LS_RECURSIVE | 422 | #if ENABLE_FEATURE_LS_RECURSIVE |
| 439 | static void dfree(struct dnode **dnp, int nfiles) | 423 | static void dfree(struct dnode **dnp, unsigned nfiles) |
| 440 | { | 424 | { |
| 441 | int i; | 425 | unsigned i; |
| 442 | 426 | ||
| 443 | if (dnp == NULL) | 427 | if (dnp == NULL) |
| 444 | return; | 428 | return; |
| 445 | 429 | ||
| 446 | for (i = 0; i < nfiles; i++) { | 430 | for (i = 0; i < nfiles; i++) { |
| 447 | struct dnode *cur = dnp[i]; | 431 | struct dnode *cur = dnp[i]; |
| 448 | if (cur->allocated) | 432 | if (cur->fname_allocated) |
| 449 | free((char*)cur->fullname); /* free the filename */ | 433 | free((char*)cur->fullname); /* free the filename */ |
| 450 | free(cur); /* free the dnode */ | 434 | free(cur); /* free the dnode */ |
| 451 | } | 435 | } |
| @@ -455,12 +439,12 @@ static void dfree(struct dnode **dnp, int nfiles) | |||
| 455 | #define dfree(...) ((void)0) | 439 | #define dfree(...) ((void)0) |
| 456 | #endif | 440 | #endif |
| 457 | 441 | ||
| 458 | static struct dnode **splitdnarray(struct dnode **dn, int nfiles, int which) | 442 | static struct dnode **splitdnarray(struct dnode **dn, unsigned nfiles, int which) |
| 459 | { | 443 | { |
| 460 | int dncnt, i, d; | 444 | unsigned dncnt, i, d; |
| 461 | struct dnode **dnp; | 445 | struct dnode **dnp; |
| 462 | 446 | ||
| 463 | if (dn == NULL || nfiles < 1) | 447 | if (dn == NULL) |
| 464 | return NULL; | 448 | return NULL; |
| 465 | 449 | ||
| 466 | /* count how many dirs and regular files there are */ | 450 | /* count how many dirs and regular files there are */ |
| @@ -540,15 +524,17 @@ static void dnsort(struct dnode **dn, int size) | |||
| 540 | #endif | 524 | #endif |
| 541 | 525 | ||
| 542 | 526 | ||
| 543 | static void showfiles(struct dnode **dn, int nfiles) | 527 | static void showfiles(struct dnode **dn, unsigned nfiles) |
| 544 | { | 528 | { |
| 545 | int i, ncols, nrows, row, nc; | 529 | unsigned i, ncols, nrows, row, nc; |
| 546 | int column = 0; | 530 | unsigned column = 0; |
| 547 | int nexttab = 0; | 531 | unsigned nexttab = 0; |
| 548 | int column_width = 0; /* for STYLE_LONG and STYLE_SINGLE not used */ | 532 | unsigned column_width = 0; /* for STYLE_LONG and STYLE_SINGLE not used */ |
| 549 | 533 | ||
| 534 | /* Never happens: | ||
| 550 | if (dn == NULL || nfiles < 1) | 535 | if (dn == NULL || nfiles < 1) |
| 551 | return; | 536 | return; |
| 537 | */ | ||
| 552 | 538 | ||
| 553 | if (all_fmt & STYLE_LONG) { | 539 | if (all_fmt & STYLE_LONG) { |
| 554 | ncols = 1; | 540 | ncols = 1; |
| @@ -615,15 +601,18 @@ static off_t calculate_blocks(struct dnode **dn, int nfiles) | |||
| 615 | #endif | 601 | #endif |
| 616 | 602 | ||
| 617 | 603 | ||
| 618 | static void showdirs(struct dnode **dn, int ndirs, int first) | 604 | static void showdirs(struct dnode **dn, unsigned ndirs, int first) |
| 619 | { | 605 | { |
| 620 | int i, nfiles; | 606 | unsigned i, nfiles; |
| 621 | struct dnode **subdnp; | 607 | struct dnode **subdnp; |
| 622 | int dndirs; | 608 | unsigned dndirs; |
| 623 | struct dnode **dnd; | 609 | struct dnode **dnd; |
| 624 | 610 | ||
| 625 | if (dn == NULL || ndirs < 1) | 611 | /* Never happens: |
| 612 | if (dn == NULL || ndirs < 1) { | ||
| 626 | return; | 613 | return; |
| 614 | } | ||
| 615 | */ | ||
| 627 | 616 | ||
| 628 | for (i = 0; i < ndirs; i++) { | 617 | for (i = 0; i < ndirs; i++) { |
| 629 | if (all_fmt & (DISP_DIRNAME | DISP_RECURSIVE)) { | 618 | if (all_fmt & (DISP_DIRNAME | DISP_RECURSIVE)) { |
| @@ -632,8 +621,7 @@ static void showdirs(struct dnode **dn, int ndirs, int first) | |||
| 632 | first = 0; | 621 | first = 0; |
| 633 | printf("%s:\n", dn[i]->fullname); | 622 | printf("%s:\n", dn[i]->fullname); |
| 634 | } | 623 | } |
| 635 | subdnp = list_dir(dn[i]->fullname); | 624 | subdnp = list_dir(dn[i]->fullname, &nfiles); |
| 636 | nfiles = countfiles(subdnp); | ||
| 637 | #if ENABLE_DESKTOP | 625 | #if ENABLE_DESKTOP |
| 638 | if (all_fmt & STYLE_LONG) | 626 | if (all_fmt & STYLE_LONG) |
| 639 | printf("total %"OFF_FMT"u\n", calculate_blocks(subdnp, nfiles)); | 627 | printf("total %"OFF_FMT"u\n", calculate_blocks(subdnp, nfiles)); |
| @@ -662,23 +650,26 @@ static void showdirs(struct dnode **dn, int ndirs, int first) | |||
| 662 | } | 650 | } |
| 663 | 651 | ||
| 664 | 652 | ||
| 665 | static struct dnode **list_dir(const char *path) | 653 | static struct dnode **list_dir(const char *path, unsigned *nfiles_p) |
| 666 | { | 654 | { |
| 667 | struct dnode *dn, *cur, **dnp; | 655 | struct dnode *dn, *cur, **dnp; |
| 668 | struct dirent *entry; | 656 | struct dirent *entry; |
| 669 | DIR *dir; | 657 | DIR *dir; |
| 670 | int i, nfiles; | 658 | unsigned i, nfiles; |
| 671 | 659 | ||
| 660 | /* Never happens: | ||
| 672 | if (path == NULL) | 661 | if (path == NULL) |
| 673 | return NULL; | 662 | return NULL; |
| 663 | */ | ||
| 674 | 664 | ||
| 675 | dn = NULL; | 665 | *nfiles_p = 0; |
| 676 | nfiles = 0; | ||
| 677 | dir = warn_opendir(path); | 666 | dir = warn_opendir(path); |
| 678 | if (dir == NULL) { | 667 | if (dir == NULL) { |
| 679 | exit_code = EXIT_FAILURE; | 668 | exit_code = EXIT_FAILURE; |
| 680 | return NULL; /* could not open the dir */ | 669 | return NULL; /* could not open the dir */ |
| 681 | } | 670 | } |
| 671 | dn = NULL; | ||
| 672 | nfiles = 0; | ||
| 682 | while ((entry = readdir(dir)) != NULL) { | 673 | while ((entry = readdir(dir)) != NULL) { |
| 683 | char *fullname; | 674 | char *fullname; |
| 684 | 675 | ||
| @@ -698,22 +689,26 @@ static struct dnode **list_dir(const char *path) | |||
| 698 | free(fullname); | 689 | free(fullname); |
| 699 | continue; | 690 | continue; |
| 700 | } | 691 | } |
| 701 | cur->allocated = 1; | 692 | cur->fname_allocated = 1; |
| 702 | cur->next = dn; | 693 | cur->next = dn; |
| 703 | dn = cur; | 694 | dn = cur; |
| 704 | nfiles++; | 695 | nfiles++; |
| 705 | } | 696 | } |
| 706 | closedir(dir); | 697 | closedir(dir); |
| 707 | 698 | ||
| 699 | if (dn == NULL) | ||
| 700 | return NULL; | ||
| 701 | |||
| 708 | /* now that we know how many files there are | 702 | /* now that we know how many files there are |
| 709 | * allocate memory for an array to hold dnode pointers | 703 | * allocate memory for an array to hold dnode pointers |
| 710 | */ | 704 | */ |
| 711 | if (dn == NULL) | 705 | *nfiles_p = nfiles; |
| 712 | return NULL; | ||
| 713 | dnp = dnalloc(nfiles); | 706 | dnp = dnalloc(nfiles); |
| 714 | for (i = 0, cur = dn; i < nfiles; i++) { | 707 | for (i = 0; /* i < nfiles - detected via !dn below */; i++) { |
| 715 | dnp[i] = cur; /* save pointer to node in array */ | 708 | dnp[i] = dn; /* save pointer to node in array */ |
| 716 | cur = cur->next; | 709 | dn = dn->next; |
| 710 | if (!dn) | ||
| 711 | break; | ||
| 717 | } | 712 | } |
| 718 | 713 | ||
| 719 | return dnp; | 714 | return dnp; |
| @@ -724,9 +719,9 @@ static int print_name(const char *name) | |||
| 724 | { | 719 | { |
| 725 | if (option_mask32 & OPT_Q) { | 720 | if (option_mask32 & OPT_Q) { |
| 726 | #if ENABLE_FEATURE_ASSUME_UNICODE | 721 | #if ENABLE_FEATURE_ASSUME_UNICODE |
| 727 | int len = 2 + bb_mbstrlen(name); | 722 | unsigned len = 2 + bb_mbstrlen(name); |
| 728 | #else | 723 | #else |
| 729 | int len = 2; | 724 | unsigned len = 2; |
| 730 | #endif | 725 | #endif |
| 731 | putchar('"'); | 726 | putchar('"'); |
| 732 | while (*name) { | 727 | while (*name) { |
| @@ -751,9 +746,9 @@ static int print_name(const char *name) | |||
| 751 | } | 746 | } |
| 752 | 747 | ||
| 753 | 748 | ||
| 754 | static int list_single(const struct dnode *dn) | 749 | static NOINLINE unsigned list_single(const struct dnode *dn) |
| 755 | { | 750 | { |
| 756 | int column = 0; | 751 | unsigned column = 0; |
| 757 | char *lpath = lpath; /* for compiler */ | 752 | char *lpath = lpath; /* for compiler */ |
| 758 | #if ENABLE_FEATURE_LS_TIMESTAMPS | 753 | #if ENABLE_FEATURE_LS_TIMESTAMPS |
| 759 | char *filetime; | 754 | char *filetime; |
| @@ -764,8 +759,10 @@ static int list_single(const struct dnode *dn) | |||
| 764 | char append; | 759 | char append; |
| 765 | #endif | 760 | #endif |
| 766 | 761 | ||
| 762 | /* Never happens: | ||
| 767 | if (dn->fullname == NULL) | 763 | if (dn->fullname == NULL) |
| 768 | return 0; | 764 | return 0; |
| 765 | */ | ||
| 769 | 766 | ||
| 770 | #if ENABLE_FEATURE_LS_TIMESTAMPS | 767 | #if ENABLE_FEATURE_LS_TIMESTAMPS |
| 771 | ttime = dn->dstat.st_mtime; /* the default time */ | 768 | ttime = dn->dstat.st_mtime; /* the default time */ |
| @@ -909,10 +906,10 @@ int ls_main(int argc UNUSED_PARAM, char **argv) | |||
| 909 | struct dnode *dn; | 906 | struct dnode *dn; |
| 910 | struct dnode *cur; | 907 | struct dnode *cur; |
| 911 | unsigned opt; | 908 | unsigned opt; |
| 912 | int nfiles; | 909 | unsigned nfiles; |
| 913 | int dnfiles; | 910 | unsigned dnfiles; |
| 914 | int dndirs; | 911 | unsigned dndirs; |
| 915 | int i; | 912 | unsigned i; |
| 916 | #if ENABLE_FEATURE_LS_COLOR | 913 | #if ENABLE_FEATURE_LS_COLOR |
| 917 | /* colored LS support by JaWi, janwillem.janssen@lxtreme.nl */ | 914 | /* colored LS support by JaWi, janwillem.janssen@lxtreme.nl */ |
| 918 | /* coreutils 6.10: | 915 | /* coreutils 6.10: |
| @@ -1039,25 +1036,30 @@ int ls_main(int argc UNUSED_PARAM, char **argv) | |||
| 1039 | argv++; | 1036 | argv++; |
| 1040 | if (!cur) | 1037 | if (!cur) |
| 1041 | continue; | 1038 | continue; |
| 1042 | cur->allocated = 0; | 1039 | cur->fname_allocated = 0; |
| 1043 | cur->next = dn; | 1040 | cur->next = dn; |
| 1044 | dn = cur; | 1041 | dn = cur; |
| 1045 | nfiles++; | 1042 | nfiles++; |
| 1046 | } while (*argv); | 1043 | } while (*argv); |
| 1047 | 1044 | ||
| 1045 | /* nfiles _may_ be 0 here - try "ls doesnt_exist" */ | ||
| 1046 | if (nfiles == 0) | ||
| 1047 | return exit_code; | ||
| 1048 | |||
| 1048 | /* now that we know how many files there are | 1049 | /* now that we know how many files there are |
| 1049 | * allocate memory for an array to hold dnode pointers | 1050 | * allocate memory for an array to hold dnode pointers |
| 1050 | */ | 1051 | */ |
| 1051 | dnp = dnalloc(nfiles); | 1052 | dnp = dnalloc(nfiles); |
| 1052 | for (i = 0, cur = dn; i < nfiles; i++) { | 1053 | for (i = 0; /* i < nfiles - detected via !dn below */; i++) { |
| 1053 | dnp[i] = cur; /* save pointer to node in array */ | 1054 | dnp[i] = dn; /* save pointer to node in array */ |
| 1054 | cur = cur->next; | 1055 | dn = dn->next; |
| 1056 | if (!dn) | ||
| 1057 | break; | ||
| 1055 | } | 1058 | } |
| 1056 | 1059 | ||
| 1057 | if (all_fmt & DISP_NOLIST) { | 1060 | if (all_fmt & DISP_NOLIST) { |
| 1058 | dnsort(dnp, nfiles); | 1061 | dnsort(dnp, nfiles); |
| 1059 | if (nfiles > 0) | 1062 | showfiles(dnp, nfiles); |
| 1060 | showfiles(dnp, nfiles); | ||
| 1061 | } else { | 1063 | } else { |
| 1062 | dnd = splitdnarray(dnp, nfiles, SPLIT_DIR); | 1064 | dnd = splitdnarray(dnp, nfiles, SPLIT_DIR); |
| 1063 | dnf = splitdnarray(dnp, nfiles, SPLIT_FILE); | 1065 | dnf = splitdnarray(dnp, nfiles, SPLIT_FILE); |
