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>
This commit is contained in:
parent
ffd4774ad2
commit
cae409c6aa
@ -385,27 +385,29 @@ static char append_char(mode_t mode)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define countdirs(A, B) count_dirs((A), (B), 1)
|
static unsigned count_dirs(struct dnode **dn, int which)
|
||||||
#define countsubdirs(A, B) count_dirs((A), (B), 0)
|
|
||||||
static unsigned count_dirs(struct dnode **dn, unsigned nfiles, int notsubdirs)
|
|
||||||
{
|
{
|
||||||
unsigned i, dirs;
|
unsigned dirs, all;
|
||||||
|
|
||||||
if (!dn)
|
if (!dn)
|
||||||
return 0;
|
return 0;
|
||||||
dirs = 0;
|
|
||||||
for (i = 0; i < nfiles; i++) {
|
dirs = all = 0;
|
||||||
|
for (; *dn; dn++) {
|
||||||
const char *name;
|
const char *name;
|
||||||
if (!S_ISDIR(dn[i]->dstat.st_mode))
|
|
||||||
|
all++;
|
||||||
|
if (!S_ISDIR((*dn)->dstat.st_mode))
|
||||||
continue;
|
continue;
|
||||||
name = dn[i]->name;
|
name = (*dn)->name;
|
||||||
if (notsubdirs
|
if (which != SPLIT_SUBDIR /* if not requested to skip . / .. */
|
||||||
|
/* or if it's not . or .. */
|
||||||
|| name[0] != '.' || (name[1] && (name[1] != '.' || name[2]))
|
|| name[0] != '.' || (name[1] && (name[1] != '.' || name[2]))
|
||||||
) {
|
) {
|
||||||
dirs++;
|
dirs++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return dirs;
|
return which != SPLIT_FILE ? dirs : all - dirs;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get memory to hold an array of pointers */
|
/* get memory to hold an array of pointers */
|
||||||
@ -414,18 +416,19 @@ static struct dnode **dnalloc(unsigned num)
|
|||||||
if (num < 1)
|
if (num < 1)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
num++; /* so that we have terminating NULL */
|
||||||
return xzalloc(num * sizeof(struct dnode *));
|
return xzalloc(num * sizeof(struct dnode *));
|
||||||
}
|
}
|
||||||
|
|
||||||
#if ENABLE_FEATURE_LS_RECURSIVE
|
#if ENABLE_FEATURE_LS_RECURSIVE
|
||||||
static void dfree(struct dnode **dnp, unsigned nfiles)
|
static void dfree(struct dnode **dnp)
|
||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
|
||||||
if (dnp == NULL)
|
if (dnp == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (i = 0; i < nfiles; i++) {
|
for (i = 0; dnp[i]; i++) {
|
||||||
struct dnode *cur = dnp[i];
|
struct dnode *cur = dnp[i];
|
||||||
if (cur->fname_allocated)
|
if (cur->fname_allocated)
|
||||||
free((char*)cur->fullname);
|
free((char*)cur->fullname);
|
||||||
@ -437,40 +440,36 @@ static void dfree(struct dnode **dnp, unsigned nfiles)
|
|||||||
#define dfree(...) ((void)0)
|
#define dfree(...) ((void)0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static struct dnode **splitdnarray(struct dnode **dn, unsigned nfiles, int which)
|
/* Returns NULL-terminated malloced vector of pointers (or NULL) */
|
||||||
|
static struct dnode **splitdnarray(struct dnode **dn, int which)
|
||||||
{
|
{
|
||||||
unsigned dncnt, i, d;
|
unsigned dncnt, d;
|
||||||
struct dnode **dnp;
|
struct dnode **dnp;
|
||||||
|
|
||||||
if (dn == NULL)
|
if (dn == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* count how many dirs and regular files there are */
|
/* count how many dirs or files there are */
|
||||||
if (which == SPLIT_SUBDIR)
|
dncnt = count_dirs(dn, which);
|
||||||
dncnt = countsubdirs(dn, nfiles);
|
|
||||||
else {
|
|
||||||
dncnt = countdirs(dn, nfiles); /* assume we are looking for dirs */
|
|
||||||
if (which == SPLIT_FILE)
|
|
||||||
dncnt = nfiles - dncnt; /* looking for files */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* allocate a file array and a dir array */
|
/* allocate a file array and a dir array */
|
||||||
dnp = dnalloc(dncnt);
|
dnp = dnalloc(dncnt);
|
||||||
|
|
||||||
/* copy the entrys into the file or dir array */
|
/* copy the entrys into the file or dir array */
|
||||||
for (d = i = 0; i < nfiles; i++) {
|
for (d = 0; *dn; dn++) {
|
||||||
if (S_ISDIR(dn[i]->dstat.st_mode)) {
|
if (S_ISDIR((*dn)->dstat.st_mode)) {
|
||||||
const char *name;
|
const char *name;
|
||||||
|
|
||||||
if (!(which & (SPLIT_DIR|SPLIT_SUBDIR)))
|
if (!(which & (SPLIT_DIR|SPLIT_SUBDIR)))
|
||||||
continue;
|
continue;
|
||||||
name = dn[i]->name;
|
name = (*dn)->name;
|
||||||
if ((which & SPLIT_DIR)
|
if ((which & SPLIT_DIR)
|
||||||
|| name[0]!='.' || (name[1] && (name[1]!='.' || name[2]))
|
|| name[0]!='.' || (name[1] && (name[1]!='.' || name[2]))
|
||||||
) {
|
) {
|
||||||
dnp[d++] = dn[i];
|
dnp[d++] = *dn;
|
||||||
}
|
}
|
||||||
} else if (!(which & (SPLIT_DIR|SPLIT_SUBDIR))) {
|
} else if (!(which & (SPLIT_DIR|SPLIT_SUBDIR))) {
|
||||||
dnp[d++] = dn[i];
|
dnp[d++] = *dn;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return dnp;
|
return dnp;
|
||||||
@ -538,7 +537,7 @@ static void showfiles(struct dnode **dn, unsigned nfiles)
|
|||||||
ncols = 1;
|
ncols = 1;
|
||||||
} else {
|
} else {
|
||||||
/* find the longest file name, use that as the column width */
|
/* find the longest file name, use that as the column width */
|
||||||
for (i = 0; i < nfiles; i++) {
|
for (i = 0; dn[i]; i++) {
|
||||||
int len = bb_mbstrlen(dn[i]->name);
|
int len = bb_mbstrlen(dn[i]->name);
|
||||||
if (column_width < len)
|
if (column_width < len)
|
||||||
column_width = len;
|
column_width = len;
|
||||||
@ -610,11 +609,11 @@ static off_t calculate_blocks(struct dnode **dn, int nfiles)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static void showdirs(struct dnode **dn, unsigned ndirs, int first)
|
static void showdirs(struct dnode **dn, int first)
|
||||||
{
|
{
|
||||||
unsigned i, nfiles;
|
unsigned nfiles;
|
||||||
struct dnode **subdnp;
|
|
||||||
unsigned dndirs;
|
unsigned dndirs;
|
||||||
|
struct dnode **subdnp;
|
||||||
struct dnode **dnd;
|
struct dnode **dnd;
|
||||||
|
|
||||||
/* Never happens:
|
/* Never happens:
|
||||||
@ -623,17 +622,17 @@ static void showdirs(struct dnode **dn, unsigned ndirs, int first)
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
for (i = 0; i < ndirs; i++) {
|
for (; *dn; dn++) {
|
||||||
if (all_fmt & (DISP_DIRNAME | DISP_RECURSIVE)) {
|
if (all_fmt & (DISP_DIRNAME | DISP_RECURSIVE)) {
|
||||||
if (!first)
|
if (!first)
|
||||||
bb_putchar('\n');
|
bb_putchar('\n');
|
||||||
first = 0;
|
first = 0;
|
||||||
printf("%s:\n", dn[i]->fullname);
|
printf("%s:\n", (*dn)->fullname);
|
||||||
}
|
}
|
||||||
subdnp = list_dir(dn[i]->fullname, &nfiles);
|
subdnp = list_dir((*dn)->fullname, &nfiles);
|
||||||
#if ENABLE_DESKTOP
|
#if ENABLE_DESKTOP
|
||||||
if (all_fmt & STYLE_LONG)
|
if (all_fmt & STYLE_LONG)
|
||||||
printf("total %"OFF_FMT"u\n", calculate_blocks(subdnp, nfiles));
|
printf("total %"OFF_FMT"u\n", calculate_blocks(subdnp));
|
||||||
#endif
|
#endif
|
||||||
if (nfiles > 0) {
|
if (nfiles > 0) {
|
||||||
/* list all files at this level */
|
/* list all files at this level */
|
||||||
@ -643,22 +642,23 @@ static void showdirs(struct dnode **dn, unsigned ndirs, int first)
|
|||||||
&& (all_fmt & DISP_RECURSIVE)
|
&& (all_fmt & DISP_RECURSIVE)
|
||||||
) {
|
) {
|
||||||
/* recursive - list the sub-dirs */
|
/* recursive - list the sub-dirs */
|
||||||
dnd = splitdnarray(subdnp, nfiles, SPLIT_SUBDIR);
|
dnd = splitdnarray(subdnp, SPLIT_SUBDIR);
|
||||||
dndirs = countsubdirs(subdnp, nfiles);
|
dndirs = count_dirs(subdnp, SPLIT_SUBDIR);
|
||||||
if (dndirs > 0) {
|
if (dndirs > 0) {
|
||||||
dnsort(dnd, dndirs);
|
dnsort(dnd, dndirs);
|
||||||
showdirs(dnd, dndirs, 0);
|
showdirs(dnd, 0);
|
||||||
/* free the array of dnode pointers to the dirs */
|
/* free the array of dnode pointers to the dirs */
|
||||||
free(dnd);
|
free(dnd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* free the dnodes and the fullname mem */
|
/* free the dnodes and the fullname mem */
|
||||||
dfree(subdnp, nfiles);
|
dfree(subdnp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Returns NULL-terminated malloced vector of pointers (or NULL) */
|
||||||
static struct dnode **list_dir(const char *path, unsigned *nfiles_p)
|
static struct dnode **list_dir(const char *path, unsigned *nfiles_p)
|
||||||
{
|
{
|
||||||
struct dnode *dn, *cur, **dnp;
|
struct dnode *dn, *cur, **dnp;
|
||||||
@ -1070,9 +1070,9 @@ int ls_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
dnsort(dnp, nfiles);
|
dnsort(dnp, nfiles);
|
||||||
showfiles(dnp, nfiles);
|
showfiles(dnp, nfiles);
|
||||||
} else {
|
} else {
|
||||||
dnd = splitdnarray(dnp, nfiles, SPLIT_DIR);
|
dnd = splitdnarray(dnp, SPLIT_DIR);
|
||||||
dnf = splitdnarray(dnp, nfiles, SPLIT_FILE);
|
dnf = splitdnarray(dnp, SPLIT_FILE);
|
||||||
dndirs = countdirs(dnp, nfiles);
|
dndirs = count_dirs(dnp, SPLIT_DIR);
|
||||||
dnfiles = nfiles - dndirs;
|
dnfiles = nfiles - dndirs;
|
||||||
if (dnfiles > 0) {
|
if (dnfiles > 0) {
|
||||||
dnsort(dnf, dnfiles);
|
dnsort(dnf, dnfiles);
|
||||||
@ -1082,12 +1082,12 @@ int ls_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
}
|
}
|
||||||
if (dndirs > 0) {
|
if (dndirs > 0) {
|
||||||
dnsort(dnd, dndirs);
|
dnsort(dnd, dndirs);
|
||||||
showdirs(dnd, dndirs, dnfiles == 0);
|
showdirs(dnd, dnfiles == 0);
|
||||||
if (ENABLE_FEATURE_CLEAN_UP)
|
if (ENABLE_FEATURE_CLEAN_UP)
|
||||||
free(dnd);
|
free(dnd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ENABLE_FEATURE_CLEAN_UP)
|
if (ENABLE_FEATURE_CLEAN_UP)
|
||||||
dfree(dnp, nfiles);
|
dfree(dnp);
|
||||||
return exit_code;
|
return exit_code;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user