On Sat, 16 Apr 2022 21:13:02 +0200 tito <farmat...@tiscali.it> wrote:
> On Sat, 16 Apr 2022 16:54:19 +0000 > Roger Knecht <rkne...@pm.me> wrote: > > > Adds the tree program to list directories and files in a tree structure. > > > > function old new delta > > static.tree_print - 352 +352 > > .rodata 95677 95756 +79 > > tree_main - 69 +69 > > globals - 24 +24 > > applet_main 3192 3200 +8 > > applet_names 2747 2752 +5 > > packed_usage 34414 34396 -18 > > ------------------------------------------------------------------------------ > > (add/remove: 4/0 grow/shrink: 3/1 up/down: 537/-18) Total: 519 > > bytes > > --- > > As Ron pointed out V1 was overwriting the find help text and therefore > > invalidating > > the bloatcheck. V1 added 1171 bytes (not 349 bytes as originally mentioned). > > > > V2 is reducing the size by using scandir(), chdir() and avoiding string > > concatenations. > > > > Changelog: > > > > V2: > > - Fixed tree help text > > - Reduced size by 652 bytes > > Hi, > just out of curiosity, for fun and to refresh my C skills I wrote > an alternative version of tree that is somewhat similar to yours > in using scandir. > > One problem I see in your V2 is that unlike real tree it does not > handle multiple paths as command line args: > > tree dir dir2 dirn > > Also the use of DT_DIR is problematic as only some filesystems > have full support. On more minor glitch is that file and dir count differs from original tree program when links are involved. For example: ./busybox_unstripped tree ../../test/ ../../test/ ├── test1 │ └── a ├── test2 │ ├── b │ ├── c │ ├── k │ └── test3 ├── test4 ├── test5 ├── test6 └── test7 4 directories, 7 files tree ../../test/ ../../test/ ├── test1 │ └── a ├── test2 │ ├── b │ ├── c │ ├── k -> b │ └── test3 ├── test4 -> test2 ├── test5 ├── test6 -> test7 └── test7 -> test6 5 directories, 6 files Ciao, Tito > > Bloatcheck is: > > function old new delta > tree - 501 +501 > tree_main - 125 +125 > .rodata 99024 99106 +82 > packed_usage 34414 34448 +34 > applet_main 3192 3200 +8 > applet_names 2747 2752 +5 > ------------------------------------------------------------------------------ > (add/remove: 3/0 grow/shrink: 4/0 up/down: 755/0) Total: 755 bytes > text data bss dec hex filename > 1002271 16403 1848 1020522 f926a busybox_old > 1003180 16427 1848 1021455 f960f busybox_unstripped > > Features are: > 1) correct link handling: > > ./busybox tree ../../test/ > ../../test/ > ├── test1 > │ └── a > ├── test2 > │ ├── b > │ ├── c > │ └── test3 > ├── test4 -> test2 > └── test5 > > 2) Uses scandir and passes the testsuite. > 3) It is worth mentioning that by using alphasort > as sorting algorithm the output of complex trees > is somewhat different in the ordering of files > ( for example uppercase , lowercase) > as the real tree program. > > For easier review code is attached as patch and > also in the mail body. > > #include "libbb.h" > > #define HIDDEN(s) ((s)[0] == '.') > > #define CHILD "├── " > #define LAST_CHILD "└── " > #define GRAND_CHILD "│ " > #define LAST_GRAND_CHILD " " > > #define MAX_CHILD_SIZE (MAX(MAX(MAX((sizeof(CHILD)), \ > > (sizeof(LAST_CHILD))), \ > > (sizeof(GRAND_CHILD))), \ > > (sizeof(LAST_GRAND_CHILD)))) > > static void tree(char *path, int *dcount, int *fcount, char **list) > { > int i = 0; > int n; > int l; > char *fullpath = NULL; > char *linkname = NULL; > struct dirent **namelist; > > if ((n = scandir(path, &namelist, NULL, alphasort)) < 0) { > printf("%s [error opening dir]\n", path); > return; > } else if (!**list) { > printf("%s\n", path); > } > > l = strlen(*list); > > while (i < n) { > if (!DOT_OR_DOTDOT(namelist[i]->d_name) && > !HIDDEN(namelist[i]->d_name)) { > *list = xrealloc(*list, l + MAX_CHILD_SIZE); > strcpy(*list + l, (i == (n - 1)) ? LAST_CHILD : CHILD); > printf("%s%s", *list, namelist[i]->d_name); > fullpath = concat_path_file(path, namelist[i]->d_name); > if((linkname = xmalloc_readlink(fullpath)) != NULL) { > printf(" -> %s", linkname); > } > bb_putchar('\n'); > if (is_directory(fullpath, /*followLinks*/ 1)) { > (*dcount)++; > strcpy(*list + l, (i == (n - 1)) ? > LAST_GRAND_CHILD : GRAND_CHILD); > if (linkname == NULL) { > tree(fullpath, dcount, fcount, list); > } > } else { > (*fcount)++; > } > free(linkname); > free(fullpath); > } > free(namelist[i]); > i++; > } > strcpy(*list + l, ""); > free(namelist); > } > > int tree_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; > int tree_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) > { > int dircount = 0; > int filecount = 0; > char *list = xzalloc(1); > > if (argc == 1) { > *argv = (char *) "."; > } else { > argv++; > } > > do { > tree(*argv, &dircount, &filecount, &list); > } while (*++argv); > printf("\n%d directories, %d files\n", dircount, filecount); > if (ENABLE_FEATURE_CLEAN_UP) { > free(list); > } > return EXIT_SUCCESS; > } > > Hints on how to shrink it even more, improvements and critics are welcome! > Enjoy. > > Ciao, > Tito > _______________________________________________ busybox mailing list busybox@busybox.net http://lists.busybox.net/mailman/listinfo/busybox