Subject: bin/7540: Suggested improvement to "ls"
To: None <gnats-bugs@gnats.netbsd.org>
From: None <mac@wireless.com>
List: netbsd-bugs
Date: 05/09/1999 12:21:52
>Number:         7540
>Category:       bin
>Synopsis:       Suggested improvement to "ls"
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    bin-bug-people (Utility Bug People)
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Sun May  9 12:05:00 1999
>Last-Modified:
>Originator:     User mac
>Organization:
	
>Release:        NetBSD-1.4_BETA
>Environment:
	486/16MB
System: NetBSD NetBSD 1.4_BETA NetBSD 1.4_BETA (GENERIC) #1: Wed Apr 21 09:17:06 PDT 1999 root@struis:/usr/src/sys/arch/i386/compile/GENERIC i386


>Description:
	When doing "ls -l" where files are large, it's difficult quickly
	parse the size, e.g.
	 -rwxr-xr-x  1 root  wheel  45199899 May  9 00:44 foo

	It's easier to read when it's like this:
	 -rwxr-xr-x  1 root  wheel  45,199,899 May  9 00:44 foo

>How-To-Repeat:
	"ls -l" on large files
>Fix:
Here are the diffs to ls.h, ls.c, and print.c for the /usr/src/bin/ls/
directory.  I added the "-M" switch (for coMMas) that also forces "-l".
Note, I did -not- update the documentation, but will if asked.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--- ls.original.h	Sun May  9 00:45:22 1999
+++ ls.h	Sun May  9 00:44:02 1999
@@ -51,6 +51,7 @@
 extern int f_statustime;	/* use time of last mode change */
 extern int f_type;		/* add type character for non-regular files */
 extern int f_typedir;		/* add type character for directories */
+extern int f_commas;		/* nonzero if you want commas in filesizes */
 
 typedef struct {
 	FTSENT *list;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--- ls.original.c	Sat May  8 00:26:50 1999
+++ ls.c	Sat May  8 22:06:23 1999
@@ -108,6 +108,7 @@
 int f_type;			/* add type character for non-regular files */
 int f_typedir;			/* add type character for directories */
 int f_whiteout;			/* show whiteout entries */
+int f_commas;			/* show numbers with commas; implies -l */
 
 int
 main(argc, argv)
@@ -136,7 +137,8 @@
 		f_listdot = 1;
 
 	fts_options = FTS_PHYSICAL;
-	while ((ch = getopt(argc, argv, "1ACFLRSTWacdfgiklmnopqrstux")) != -1) {
+	f_commas = 0; /* Normally, no commas */
+	while ((ch = getopt(argc, argv, "1ACFLMRSTWacdfgiklmnopqrstux")) != -1) {
 		switch (ch) {
 		/*
 		 * The -1, -C, -l, -m and -x options all override each other so
@@ -151,6 +153,8 @@
 			f_columnacross = f_longform = f_singlecol = f_stream =
 			    0;
 			break;
+		case 'M':
+			f_commas = 1;
 		case 'l':
 			f_longform = 1;
 			f_column = f_columnacross = f_singlecol = f_stream = 0;
@@ -558,6 +562,8 @@
 		d.s_nlink = strlen(buf);
 		(void)snprintf(buf, sizeof(buf), "%llu", (long long)maxsize);
 		d.s_size = strlen(buf);
+		if(f_commas)
+			d.s_size += (d.s_size - 1) / 3; /* space for commas */
 		d.s_user = maxuser;
 		if (bcfile) {
 			(void)snprintf(buf, sizeof(buf), "%u", maxmajor);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--- print.original.c	Sat May  8 00:26:54 1999
+++ print.c	Sun May  9 00:41:54 1999
@@ -68,6 +68,7 @@
 static void	printlink __P((FTSENT *));
 static void	printtime __P((time_t));
 static int	printtype __P((u_int));
+static void     commas(char *);
 
 static time_t	now;
 
@@ -94,7 +95,7 @@
 	struct stat *sp;
 	FTSENT *p;
 	NAMES *np;
-	char buf[20];
+	char buf[27]; /* Was 20; More room, in case commas are used */
 
 	now = time(NULL);
 
@@ -123,9 +124,12 @@
 			(void)printf("%*u, %*u ",
 			    dp->s_major, major(sp->st_rdev), dp->s_minor,
 			    minor(sp->st_rdev));
-		else
-			(void)printf("%*llu ", dp->s_size,
-			    (long long)sp->st_size);
+		else {
+		  sprintf(buf,"%llu",(long long)sp->st_size);
+		  if(f_commas) commas(buf);
+		  (void)printf("%*s ", dp->s_size, buf);
+		}
+
 		if (f_accesstime)
 			printtime(sp->st_atime);
 		else if (f_statustime)
@@ -380,4 +384,39 @@
 	}
 	path[lnklen] = '\0';
 	(void)printf(" -> %s", path);
+}
+
+/*
+ * Return a string with commas every 3 positions.
+ * the original string is replace with the string with commas.
+ *
+ * The caller must be sure that there is enough room for the resultant
+ * string.
+ *
+ *
+ * Mike Cheponis   4 Dec 87
+ */
+static void
+commas(char *destination){
+
+  char *source, *core; /* Place holder for malloc */
+  unsigned int comma_counter;	/* The comma counter */
+  unsigned int length;
+
+  length = strlen(destination);/* Make copy, so we can change return value */
+  core = source = strdup(destination);
+  if(core == NULL){
+    *destination = '\0';/* We lost, so return null string */
+    return;
+  }
+  comma_counter = (length-1)%3 + 1;	/* Tells us when to insert a comma */
+
+  while(*source){
+    *destination++ = *source++;
+    if( --comma_counter == 0  &&  *source ){
+      *destination++ = ','; comma_counter = 3;
+    }
+  }
+  free(core);
+  *destination = '\0';
 }
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>Audit-Trail:
>Unformatted: