[hackers] [sbase] ls: print filenames on the fly rather than in a buffer

From: Quentin Rameau <quinq_AT_fifth.space>
Date: Thu, 6 Oct 2016 11:16:32 +0200

---
 ls.c | 48 ++++++++++++++++++++----------------------------
 1 file changed, 20 insertions(+), 28 deletions(-)
diff --git a/ls.c b/ls.c
index eeac64c..a1eadfa 100644
--- a/ls.c
+++ b/ls.c
_AT_@ -113,25 +113,20 @@ indicator(mode_t mode)
 	return "";
 }
 
-static char *
-makeprint(char *name)
+static void
+printname(char *name)
 {
-	char *c, *u, *print = emalloc(strlen(name) + 1);
+	char *c;
 	Rune r;
 	size_t l;
 
-	for (c = print, u = name; *u; u += l) {
-		l = chartorune(&r, u);
-		if (isprintrune(r)) {
-			memcpy(c, u, l);
-			c += l;
-		} else {
-			*c++ = '?';
-		}
+	for (c = name; *c; c += l) {
+		l = chartorune(&r, c);
+		if (!qflag || isprintrune(r))
+			fwrite(c, 1, l, stdout);
+		else
+			putchar('?');
 	}
-	*c = '\0';
-
-	return print;
 }
 
 static void
_AT_@ -142,14 +137,14 @@ output(const struct entry *ent)
 	struct tm *tm;
 	ssize_t len;
 	char *fmt, buf[BUFSIZ], pwname[_SC_LOGIN_NAME_MAX],
-	     grname[_SC_LOGIN_NAME_MAX], mode[] = "----------",
-	     *name = qflag ? makeprint(ent->name) : ent->name;
+	     grname[_SC_LOGIN_NAME_MAX], mode[] = "----------";
 
 	if (iflag)
 		printf("%lu ", (unsigned long)ent->ino);
 	if (!lflag) {
-		printf("%s%s\n", name, indicator(ent->mode));
-		goto cleanup;
+		printname(ent->name);
+		puts(indicator(ent->mode));
+		return;
 	}
 	if (S_ISREG(ent->mode))
 		mode[0] = '-';
_AT_@ -209,7 +204,9 @@ output(const struct entry *ent)
 		printf("%10s ", humansize(ent->size));
 	else
 		printf("%10lu ", (unsigned long)ent->size);
-	printf("%s %s%s", buf, name, indicator(ent->mode));
+	printf("%s ", buf);
+	printname(ent->name);
+	fputs(indicator(ent->mode), stdout);
 	if (S_ISLNK(ent->mode)) {
 		if ((len = readlink(ent->name, buf, sizeof(buf) - 1)) < 0)
 			eprintf("readlink %s:", ent->name);
_AT_@ -217,10 +214,6 @@ output(const struct entry *ent)
 		printf(" -> %s%s", buf, indicator(ent->tmode));
 	}
 	putchar('\n');
-
-cleanup:
-	if (qflag)
-		free(name);
 }
 
 static int
_AT_@ -252,7 +245,7 @@ lsdir(const char *path, const struct entry *dir)
 	struct entry *ent, *ents = NULL;
 	struct dirent *d;
 	size_t i, n = 0;
-	char prefix[PATH_MAX], *name;
+	char prefix[PATH_MAX];
 
 	if (!(dp = opendir(dir->name))) {
 		ret = 1;
_AT_@ -280,10 +273,9 @@ lsdir(const char *path, const struct entry *dir)
 		qsort(ents, n, sizeof(*ents), entcmp);
 
 	if (path[0] || showdirs) {
-		name = qflag ? makeprint(dir->name) : dir->name;
-		printf("%s%s:\n", path, name);
-		if (qflag)
-			free(name);
+		fputs(path, stdout);
+		printname(dir->name);
+		puts(":");
 	}
 	for (i = 0; i < n; i++)
 		output(&ents[i]);
-- 
2.10.0
Received on Thu Oct 06 2016 - 11:16:32 CEST

This archive was generated by hypermail 2.3.0 : Thu Oct 06 2016 - 11:24:15 CEST