Remove unneeded malloc with -q, iterate and check for non-printable
characters instead. I also moved the printing of the name to a single
point in the function.
---
 ls.c | 54 +++++++++++++++++++++++++-----------------------------
 1 file changed, 25 insertions(+), 29 deletions(-)

diff --git a/ls.c b/ls.c
index 7c97558..5476e91 100644
--- a/ls.c
+++ b/ls.c
@@ -119,35 +119,17 @@ output(const struct entry *ent)
        struct group *gr;
        struct passwd *pw;
        ssize_t len;
-       size_t l;
-       char *name, *c, *u, *fmt, buf[BUFSIZ],
+       char *fmt, buf[BUFSIZ],
             pwname[_SC_LOGIN_NAME_MAX], grname[_SC_LOGIN_NAME_MAX],
             mode[] = "----------";
+       const char * c;
        Rune r;
 
-       if (qflag) {
-               name = emalloc(strlen(ent->name) + 1);
-
-               for (c = name, u = ent->name; *u; u += l) {
-                       l = chartorune(&r, u);
-                       if (isprintrune(r)) {
-                               memcpy(c, u, l);
-                               c += l;
-                       } else {
-                               *c++ = '?';
-                       }
-               }
-               *c = '\0';
-       } else {
-               name = ent->name;
-       }
-
        if (iflag)
                printf("%lu ", (unsigned long)ent->ino);
-       if (!lflag) {
-               printf("%s%s\n", name, indicator(ent->mode));
-               goto cleanup;
-       }
+       if (!lflag)
+               goto outputname;
+
        if (S_ISREG(ent->mode))
                mode[0] = '-';
        else if (S_ISBLK(ent->mode))
@@ -203,18 +185,32 @@ output(const struct entry *ent)
                printf("%10s ", humansize(ent->size));
        else
                printf("%10lu ", (unsigned long)ent->size);
-       printf("%s %s%s", buf, ent->name, indicator(ent->mode));
-       if (S_ISLNK(ent->mode)) {
+
+       printf("%s ", buf);
+
+outputname:
+       if (!qflag) {
+               printf("%s", ent->name);
+       } else {
+               for (c = ent->name; *c; c += len) {
+                       len = chartorune(&r, c);
+                       if (isprintrune(r))
+                               printf("%.*s", (int)len, c);
+                       else
+                               printf("?");
+               }
+       }
+
+       printf("%s", indicator(ent->mode));
+
+       if (lflag && S_ISLNK(ent->mode)) {
                if ((len = readlink(ent->name, buf, sizeof(buf) - 1)) < 0)
                        eprintf("readlink %s:", ent->name);
                buf[len] = '\0';
                printf(" -> %s%s", buf, indicator(ent->tmode));
        }
-       putchar('\n');
 
-cleanup:
-       if (qflag)
-               free(name);
+       putchar('\n');
 }
 
 static int
-- 
2.1.4


Reply via email to