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>
This commit is contained in:
Denys Vlasenko 2009-10-03 01:15:47 +02:00
parent 87c150c7cc
commit 76c7d9500a

View File

@ -232,19 +232,17 @@ static const unsigned opt_flags[] = {
/* /*
* a directory entry and its stat info are stored here * a directory entry and its stat info are stored here
*/ */
struct dnode { /* the basic node */ struct dnode {
const char *name; /* the dir entry name */ const char *name; /* the dir entry name */
const char *fullname; /* the dir entry name */ const char *fullname; /* the dir entry name */
int allocated; struct dnode *next; /* point at the next node */
smallint fname_allocated;
struct stat dstat; /* the file stat info */ struct stat dstat; /* the file stat info */
IF_SELINUX(security_context_t sid;) IF_SELINUX(security_context_t sid;)
struct dnode *next; /* point at the next node */
}; };
static struct dnode **list_dir(const char *); static struct dnode **list_dir(const char *, unsigned *);
static struct dnode **dnalloc(int); static unsigned list_single(const struct dnode *);
static int list_single(const struct dnode *);
struct globals { struct globals {
#if ENABLE_FEATURE_LS_COLOR #if ENABLE_FEATURE_LS_COLOR
@ -318,7 +316,7 @@ static struct dnode *my_stat(const char *fullname, const char *name, int force_f
} }
} }
cur = xmalloc(sizeof(struct dnode)); cur = xmalloc(sizeof(*cur));
cur->fullname = fullname; cur->fullname = fullname;
cur->name = name; cur->name = name;
cur->dstat = dstat; cur->dstat = dstat;
@ -391,9 +389,9 @@ static char append_char(mode_t mode)
#define countdirs(A, B) count_dirs((A), (B), 1) #define countdirs(A, B) count_dirs((A), (B), 1)
#define countsubdirs(A, B) count_dirs((A), (B), 0) #define countsubdirs(A, B) count_dirs((A), (B), 0)
static int count_dirs(struct dnode **dn, int nfiles, int notsubdirs) static unsigned count_dirs(struct dnode **dn, unsigned nfiles, int notsubdirs)
{ {
int i, dirs; unsigned i, dirs;
if (!dn) if (!dn)
return 0; return 0;
@ -404,7 +402,7 @@ static int count_dirs(struct dnode **dn, int nfiles, int notsubdirs)
continue; continue;
name = dn[i]->name; name = dn[i]->name;
if (notsubdirs if (notsubdirs
|| name[0]!='.' || (name[1] && (name[1]!='.' || name[2])) || name[0] != '.' || (name[1] && (name[1] != '.' || name[2]))
) { ) {
dirs++; dirs++;
} }
@ -412,22 +410,8 @@ static int count_dirs(struct dnode **dn, int nfiles, int notsubdirs)
return dirs; return dirs;
} }
static int countfiles(struct dnode **dnp)
{
int nfiles;
struct dnode *cur;
if (dnp == NULL)
return 0;
nfiles = 0;
for (cur = dnp[0]; cur->next; cur = cur->next)
nfiles++;
nfiles++;
return nfiles;
}
/* get memory to hold an array of pointers */ /* get memory to hold an array of pointers */
static struct dnode **dnalloc(int num) static struct dnode **dnalloc(unsigned num)
{ {
if (num < 1) if (num < 1)
return NULL; return NULL;
@ -436,16 +420,16 @@ static struct dnode **dnalloc(int num)
} }
#if ENABLE_FEATURE_LS_RECURSIVE #if ENABLE_FEATURE_LS_RECURSIVE
static void dfree(struct dnode **dnp, int nfiles) static void dfree(struct dnode **dnp, unsigned nfiles)
{ {
int i; unsigned i;
if (dnp == NULL) if (dnp == NULL)
return; return;
for (i = 0; i < nfiles; i++) { for (i = 0; i < nfiles; i++) {
struct dnode *cur = dnp[i]; struct dnode *cur = dnp[i];
if (cur->allocated) if (cur->fname_allocated)
free((char*)cur->fullname); /* free the filename */ free((char*)cur->fullname); /* free the filename */
free(cur); /* free the dnode */ free(cur); /* free the dnode */
} }
@ -455,12 +439,12 @@ static void dfree(struct dnode **dnp, int nfiles)
#define dfree(...) ((void)0) #define dfree(...) ((void)0)
#endif #endif
static struct dnode **splitdnarray(struct dnode **dn, int nfiles, int which) static struct dnode **splitdnarray(struct dnode **dn, unsigned nfiles, int which)
{ {
int dncnt, i, d; unsigned dncnt, i, d;
struct dnode **dnp; struct dnode **dnp;
if (dn == NULL || nfiles < 1) if (dn == NULL)
return NULL; return NULL;
/* count how many dirs and regular files there are */ /* count how many dirs and regular files there are */
@ -540,15 +524,17 @@ static void dnsort(struct dnode **dn, int size)
#endif #endif
static void showfiles(struct dnode **dn, int nfiles) static void showfiles(struct dnode **dn, unsigned nfiles)
{ {
int i, ncols, nrows, row, nc; unsigned i, ncols, nrows, row, nc;
int column = 0; unsigned column = 0;
int nexttab = 0; unsigned nexttab = 0;
int column_width = 0; /* for STYLE_LONG and STYLE_SINGLE not used */ unsigned column_width = 0; /* for STYLE_LONG and STYLE_SINGLE not used */
/* Never happens:
if (dn == NULL || nfiles < 1) if (dn == NULL || nfiles < 1)
return; return;
*/
if (all_fmt & STYLE_LONG) { if (all_fmt & STYLE_LONG) {
ncols = 1; ncols = 1;
@ -615,15 +601,18 @@ static off_t calculate_blocks(struct dnode **dn, int nfiles)
#endif #endif
static void showdirs(struct dnode **dn, int ndirs, int first) static void showdirs(struct dnode **dn, unsigned ndirs, int first)
{ {
int i, nfiles; unsigned i, nfiles;
struct dnode **subdnp; struct dnode **subdnp;
int dndirs; unsigned dndirs;
struct dnode **dnd; struct dnode **dnd;
if (dn == NULL || ndirs < 1) /* Never happens:
if (dn == NULL || ndirs < 1) {
return; return;
}
*/
for (i = 0; i < ndirs; i++) { for (i = 0; i < ndirs; i++) {
if (all_fmt & (DISP_DIRNAME | DISP_RECURSIVE)) { if (all_fmt & (DISP_DIRNAME | DISP_RECURSIVE)) {
@ -632,8 +621,7 @@ static void showdirs(struct dnode **dn, int ndirs, int first)
first = 0; first = 0;
printf("%s:\n", dn[i]->fullname); printf("%s:\n", dn[i]->fullname);
} }
subdnp = list_dir(dn[i]->fullname); subdnp = list_dir(dn[i]->fullname, &nfiles);
nfiles = countfiles(subdnp);
#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, nfiles));
@ -662,23 +650,26 @@ static void showdirs(struct dnode **dn, int ndirs, int first)
} }
static struct dnode **list_dir(const char *path) static struct dnode **list_dir(const char *path, unsigned *nfiles_p)
{ {
struct dnode *dn, *cur, **dnp; struct dnode *dn, *cur, **dnp;
struct dirent *entry; struct dirent *entry;
DIR *dir; DIR *dir;
int i, nfiles; unsigned i, nfiles;
/* Never happens:
if (path == NULL) if (path == NULL)
return NULL; return NULL;
*/
dn = NULL; *nfiles_p = 0;
nfiles = 0;
dir = warn_opendir(path); dir = warn_opendir(path);
if (dir == NULL) { if (dir == NULL) {
exit_code = EXIT_FAILURE; exit_code = EXIT_FAILURE;
return NULL; /* could not open the dir */ return NULL; /* could not open the dir */
} }
dn = NULL;
nfiles = 0;
while ((entry = readdir(dir)) != NULL) { while ((entry = readdir(dir)) != NULL) {
char *fullname; char *fullname;
@ -698,22 +689,26 @@ static struct dnode **list_dir(const char *path)
free(fullname); free(fullname);
continue; continue;
} }
cur->allocated = 1; cur->fname_allocated = 1;
cur->next = dn; cur->next = dn;
dn = cur; dn = cur;
nfiles++; nfiles++;
} }
closedir(dir); closedir(dir);
if (dn == NULL)
return NULL;
/* now that we know how many files there are /* now that we know how many files there are
* allocate memory for an array to hold dnode pointers * allocate memory for an array to hold dnode pointers
*/ */
if (dn == NULL) *nfiles_p = nfiles;
return NULL;
dnp = dnalloc(nfiles); dnp = dnalloc(nfiles);
for (i = 0, cur = dn; i < nfiles; i++) { for (i = 0; /* i < nfiles - detected via !dn below */; i++) {
dnp[i] = cur; /* save pointer to node in array */ dnp[i] = dn; /* save pointer to node in array */
cur = cur->next; dn = dn->next;
if (!dn)
break;
} }
return dnp; return dnp;
@ -724,9 +719,9 @@ static int print_name(const char *name)
{ {
if (option_mask32 & OPT_Q) { if (option_mask32 & OPT_Q) {
#if ENABLE_FEATURE_ASSUME_UNICODE #if ENABLE_FEATURE_ASSUME_UNICODE
int len = 2 + bb_mbstrlen(name); unsigned len = 2 + bb_mbstrlen(name);
#else #else
int len = 2; unsigned len = 2;
#endif #endif
putchar('"'); putchar('"');
while (*name) { while (*name) {
@ -751,9 +746,9 @@ static int print_name(const char *name)
} }
static int list_single(const struct dnode *dn) static NOINLINE unsigned list_single(const struct dnode *dn)
{ {
int column = 0; unsigned column = 0;
char *lpath = lpath; /* for compiler */ char *lpath = lpath; /* for compiler */
#if ENABLE_FEATURE_LS_TIMESTAMPS #if ENABLE_FEATURE_LS_TIMESTAMPS
char *filetime; char *filetime;
@ -764,8 +759,10 @@ static int list_single(const struct dnode *dn)
char append; char append;
#endif #endif
/* Never happens:
if (dn->fullname == NULL) if (dn->fullname == NULL)
return 0; return 0;
*/
#if ENABLE_FEATURE_LS_TIMESTAMPS #if ENABLE_FEATURE_LS_TIMESTAMPS
ttime = dn->dstat.st_mtime; /* the default time */ ttime = dn->dstat.st_mtime; /* the default time */
@ -909,10 +906,10 @@ int ls_main(int argc UNUSED_PARAM, char **argv)
struct dnode *dn; struct dnode *dn;
struct dnode *cur; struct dnode *cur;
unsigned opt; unsigned opt;
int nfiles; unsigned nfiles;
int dnfiles; unsigned dnfiles;
int dndirs; unsigned dndirs;
int i; unsigned i;
#if ENABLE_FEATURE_LS_COLOR #if ENABLE_FEATURE_LS_COLOR
/* colored LS support by JaWi, janwillem.janssen@lxtreme.nl */ /* colored LS support by JaWi, janwillem.janssen@lxtreme.nl */
/* coreutils 6.10: /* coreutils 6.10:
@ -1039,25 +1036,30 @@ int ls_main(int argc UNUSED_PARAM, char **argv)
argv++; argv++;
if (!cur) if (!cur)
continue; continue;
cur->allocated = 0; cur->fname_allocated = 0;
cur->next = dn; cur->next = dn;
dn = cur; dn = cur;
nfiles++; nfiles++;
} while (*argv); } while (*argv);
/* nfiles _may_ be 0 here - try "ls doesnt_exist" */
if (nfiles == 0)
return exit_code;
/* now that we know how many files there are /* now that we know how many files there are
* allocate memory for an array to hold dnode pointers * allocate memory for an array to hold dnode pointers
*/ */
dnp = dnalloc(nfiles); dnp = dnalloc(nfiles);
for (i = 0, cur = dn; i < nfiles; i++) { for (i = 0; /* i < nfiles - detected via !dn below */; i++) {
dnp[i] = cur; /* save pointer to node in array */ dnp[i] = dn; /* save pointer to node in array */
cur = cur->next; dn = dn->next;
if (!dn)
break;
} }
if (all_fmt & DISP_NOLIST) { if (all_fmt & DISP_NOLIST) {
dnsort(dnp, nfiles); dnsort(dnp, nfiles);
if (nfiles > 0) showfiles(dnp, nfiles);
showfiles(dnp, nfiles);
} else { } else {
dnd = splitdnarray(dnp, nfiles, SPLIT_DIR); dnd = splitdnarray(dnp, nfiles, SPLIT_DIR);
dnf = splitdnarray(dnp, nfiles, SPLIT_FILE); dnf = splitdnarray(dnp, nfiles, SPLIT_FILE);