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