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); |