Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 5 Mar 2002 22:48:56 -0600
From:      Kyle Martin <mkm@ieee.org>
To:        "Tim J. Robbins" <tim@robbins.dropbear.id.au>
Cc:        freebsd-standards@freebsd.org
Subject:   Re: ls(1) patch for review
Message-ID:  <20020305224856.A1397@marvin.idsi.net>
In-Reply-To: <20020305205733.A31150@descent.robbins.dropbear.id.au>; from tim@robbins.dropbear.id.au on Tue, Mar 05, 2002 at 08:57:33PM %2B1100
References:  <20020305030632.A1990@marvin.idsi.net> <20020305205733.A31150@descent.robbins.dropbear.id.au>

next in thread | previous in thread | raw e-mail | index | archive | help
On Tue, Mar 05, 2002 at 08:57:33PM +1100, Tim J. Robbins wrote:
> It writes a /, and the \ confuses groff. How about this:

fixed.

> This line should be wrapped at 80 columns or less.
 
yeah, i should have proofread the manpage better. fixed.
 
> The lines output by the stream format must not exceed the width of
> the terminal. See GNU ls for an example.
 
ok, i had misunderstood the context, fixed.
 
> Wouldn't it be better to have a separate function for each of these two
> output functions instead of having one big `if' and almost nothing
> in common between the two?
 
i opted not to being that they have alot in common, including the use of
several variables within the scope of this function.

> I think there is also a problem with -x outputting tabs before newlines
> (\t\n) but I can't quite track it down. Different terminals handle this
> differently, it makes the output ugly on some.

hrmm, ive looked into this, havent seen what your experiencing on any of my
terminals, it uses the same algorithm as without -x so there should be _no_
difference. given that -x does look worse that without -x, it seems all
semantically correct as far as i can tell.

> else needs to go on the line with the closing brace.
 
cleaned it up.
 
> This default: is not needed and is possibily illegal. This wasn't added
> by your change, but should be fixed:
> "warning: ANSI C forbids label at end of compound statement"

fixed.
 
> Wouldn't it be better to have the -p and -F functionality split off
> into separate functions?
 
i suppose it could be done that way, but functionality wise i see -p as a 
subset of of -F *shrug*

> Keep up the good work. 

thanks

diff -r -U 5 /usr/src/bin/ls/extern.h ./extern.h
--- ls/extern.h.old	Sun Feb  3 13:11:32 2002
+++ ls/extern.h	Tue Mar  5 04:01:36 2002
@@ -44,10 +44,11 @@
 int	 revstatcmp(const FTSENT *, const FTSENT *);
 
 void	 printcol(DISPLAY *);
 void	 printlong(DISPLAY *);
 void	 printscol(DISPLAY *);
+void	 printstream(DISPLAY *);
 void	 usage(void);
 size_t	 len_octal(const char *, int);
 int	 prn_octal(const char *);
 int	 prn_printable(const char *);
 #ifdef COLORLS
diff -r -U 5 /usr/src/bin/ls/ls.1 ./ls.1
--- ls/ls.1.old	Wed Jan  9 07:29:39 2002
+++ ls/ls.1	Tue Mar  5 04:04:27 2002
@@ -186,19 +186,25 @@
 .Dq ell . )
 List in long format.
 (See below.)
 If the output is to a terminal, a total sum for all the file
 sizes is output on a line before the long listing.
+.It Fl m
+Stream output format; list files across the page, separated by commas.
 .It Fl n
 Display user and group IDs numerically rather than converting to a user
 or group name in a long
 .Pq Fl l
 output.
 .It Fl o
 Include the file flags in a long
 .Pq Fl l
 output.
+.It Fl p
+Write a slash
+.Pq Ql /
+after each filename if that file is a directory.
 .It Fl q
 Force printing of non-graphic characters in file names as
 the character
 .Ql \&? ;
 this is the default when output is to a terminal.
@@ -226,10 +232,13 @@
 .Pq Fl l .
 .It Fl w
 Force raw printing of non-printable characters.
 This is the default
 when output is not to a terminal.
+.It Fl x
+The same as -C, except that the multi-text-column output is produced with 
+entries sorted across, rather tahn down, the columns.
 .It Fl 1
 (The numeric digit
 .Dq one . )
 Force output to be
 one entry per line.
diff -r -U 5 /usr/src/bin/ls/ls.c ./ls.c
--- ls/ls.c.old	Mon Feb 18 18:05:50 2002
+++ ls/ls.c	Tue Mar  5 04:01:36 2002
@@ -111,11 +111,14 @@
 static int f_recursive;		/* ls subdirectories also */
 static int f_reversesort;	/* reverse whatever sort is used */
        int f_sectime;		/* print the real time for all files */
 static int f_singlecol;		/* use single column output */
        int f_size;		/* list size in short listing */
+       int f_slash;		/* similar to f_type, but only for dirs */
+       int f_sortacross;	/* sort across rows, not down columns */ 
        int f_statustime;	/* use time of last mode change */
+       int f_stream;		/* stream the output, seperate with commas */
 static int f_timesort;		/* sort by time vice name */
        int f_type;		/* add type character for non-regular files */
 static int f_whiteout;		/* show whiteout entries */
        int f_lomac;		/* show LOMAC attributes */
 #ifdef COLORLS
@@ -165,19 +168,21 @@
 	/* Root is -A automatically. */
 	if (!getuid())
 		f_listdot = 1;
 
 	fts_options = FTS_PHYSICAL;
- 	while ((ch = getopt(argc, argv, "1ABCFGHLPRTWZabcdfghiklnoqrstuw")) != -1) {
+ 	while ((ch = getopt(argc, argv, "1ABCFGHLPRTWZabcdfghiklmnopqrstuwx")) 
+	    != -1) {
 		switch (ch) {
 		/*
 		 * The -1, -C and -l options all override each other so shell
 		 * aliasing works right.
 		 */
 		case '1':
 			f_singlecol = 1;
 			f_longform = 0;
+			f_stream = 0;
 			break;
 		case 'B':
 			f_nonprint = 0;
 			f_octal = 1;
 			f_octal_escape = 0;
@@ -186,10 +191,11 @@
 			f_longform = f_singlecol = 0;
 			break;
 		case 'l':
 			f_longform = 1;
 			f_singlecol = 0;
+			f_stream = 0;
 			break;
 		/* The -c and -u options override each other. */
 		case 'c':
 			f_statustime = 1;
 			f_accesstime = 0;
@@ -198,10 +204,11 @@
 			f_accesstime = 1;
 			f_statustime = 0;
 			break;
 		case 'F':
 			f_type = 1;
+			f_slash = 0;
 			break;
 		case 'H':
 			fts_options |= FTS_COMFOLLOW;
 			break;
 		case 'G':
@@ -242,16 +249,25 @@
 			f_inode = 1;
 			break;
 		case 'k':
 			f_kblocks = 1;
 			break;
+		case 'm':
+			f_stream = 1;
+			f_singlecol = 0;
+			f_longform = 0;
+			break;
 		case 'n':
 			f_numericonly = 1;
 			break;
 		case 'o':
 			f_flags = 1;
 			break;
+		case 'p':
+			f_slash = 1;
+			f_type = 1;
+			break;
 		case 'q':
 			f_nonprint = 1;
 			f_octal = 0;
 			f_octal_escape = 0;
 			break;
@@ -281,10 +297,13 @@
 			f_octal_escape = 0;
 			break;
 		case 'Z':
 			f_lomac = 1;
 			break;
+		case 'x':
+			f_sortacross = 1;
+			break;
 		default:
 		case '?':
 			usage();
 		}
 	}
@@ -388,10 +407,12 @@
 	/* Select a print function. */
 	if (f_singlecol)
 		printfcn = printscol;
 	else if (f_longform)
 		printfcn = printlong;
+	else if (f_stream)
+		printfcn = printstream;
 	else
 		printfcn = printcol;
 
 	if (argc)
 		traverse(argc, argv, fts_options);
diff -r -U 5 /usr/src/bin/ls/ls.h ./ls.h
--- ls/ls.h.old	Sun Feb  3 13:11:32 2002
+++ ls/ls.h	Tue Mar  5 04:01:36 2002
@@ -51,10 +51,12 @@
 extern int f_octal;		/* print unprintables in octal */
 extern int f_octal_escape;	/* like f_octal but use C escapes if possible */
 extern int f_nonprint;		/* show unprintables as ? */
 extern int f_sectime;		/* print the real time for all files */
 extern int f_size;		/* list size in short listing */
+extern int f_slash;		/* append a '/' if the file is a directory */
+extern int f_sortacross;	/* sort across rows, not down columns */ 
 extern int f_statustime;	/* use time of last mode change */
 extern int f_notabs;		/* don't use tab-separated multi-col output */
 extern int f_type;		/* add type character for non-regular files */
 #ifdef COLORLS
 extern int f_color;		/* add type in color for non-regular files */
diff -r -U 5 /usr/src/bin/ls/print.c ./print.c
--- ls/print.c.old	Sun Feb 24 19:36:59 2002
+++ ls/print.c	Tue Mar  5 22:21:02 2002
@@ -221,10 +221,34 @@
 		(void)putchar('\n');
 	}
 }
 
 void
+printstream(DISPLAY *dp)
+{
+	FTSENT *p;
+	extern int termwidth;
+	int chcnt;
+
+	for (p = dp->list, chcnt = 0; p; p = p->fts_link) {
+		if (p->fts_number != NO_PRINT) {
+			if (strlen(p->fts_name) + chcnt + (p->fts_link ? 2 : 0) >= 
+			    termwidth) {
+				(void)putchar('\n');
+				chcnt = 0;
+			}		
+			chcnt += printaname(p, dp->s_inode, dp->s_block);
+			if (p->fts_link) {
+				(void)printf(", ");
+				chcnt +=  2;
+			}
+		}
+	}
+	(void)putchar('\n');
+}
+		
+void
 printcol(DISPLAY *dp)
 {
 	extern int termwidth;
 	static FTSENT **array;
 	static int lastentries = -1;
@@ -280,25 +304,46 @@
 	if (num % numcols)
 		++numrows;
 
 	if (dp->list->fts_level != FTS_ROOTLEVEL && (f_longform || f_size))
 		(void)printf("total %lu\n", howmany(dp->btotal, blocksize));
-	for (row = 0; row < numrows; ++row) {
-		endcol = colwidth;
-		for (base = row, chcnt = col = 0; col < numcols; ++col) {
-			chcnt += printaname(array[base], dp->s_inode,
-			    dp->s_block);
-			if ((base += numrows) >= num)
-				break;
-			while ((cnt = ((chcnt + tabwidth) & ~(tabwidth - 1)))
-			    <= endcol) {
-				(void)putchar(f_notabs ? ' ' : '\t');
-				chcnt = cnt;
+
+	if (f_sortacross) {
+		for (row = 0, base = 0;  row < numrows; ++row) {
+			endcol = colwidth;
+			for (col = 0, chcnt = 0; col < numcols; ++col) {
+				chcnt += printaname(array[base], 
+				    dp->s_inode, dp->s_block);
+				if (++base >= num)
+					break;
+				while ((cnt = ((chcnt + tabwidth) & 
+				    ~(tabwidth - 1))) <= endcol) {
+					(void)putchar(f_notabs ? ' ' : '\t');
+					chcnt = cnt;
+				}
+				endcol += colwidth;
 			}
-			endcol += colwidth;
+			(void)putchar('\n'); 
+		}
+	} else {
+		for (row = 0; row < numrows; ++row) {
+			endcol = colwidth;
+			for (base = row, chcnt = col = 0; 
+			    col < numcols; ++col) {
+				chcnt += printaname(array[base], 
+				    dp->s_inode, dp->s_block);
+				if ((base += numrows) >= num)
+					break;
+				while ((cnt = ((chcnt + tabwidth) & 
+				    ~(tabwidth - 1))) <= endcol) {
+					(void)putchar(f_notabs ? ' ' : '\t');
+					chcnt = cnt;
+				}
+				endcol += colwidth;
+			}
+			(void)putchar('\n');
 		}
-		(void)putchar('\n');
 	}
 }
 
 /*
  * print [inode] [size] name
@@ -362,33 +407,41 @@
 }
 
 static int
 printtype(u_int mode)
 {
-	switch (mode & S_IFMT) {
-	case S_IFDIR:
-		(void)putchar('/');
-		return (1);
-	case S_IFIFO:
-		(void)putchar('|');
-		return (1);
-	case S_IFLNK:
-		(void)putchar('@');
-		return (1);
-	case S_IFSOCK:
-		(void)putchar('=');
-		return (1);
-	case S_IFWHT:
-		(void)putchar('%');
-		return (1);
-	default:
-	}
-	if (mode & (S_IXUSR | S_IXGRP | S_IXOTH)) {
-		(void)putchar('*');
-		return (1);
+	if (f_slash) {
+		if ((mode & S_IFMT) == S_IFDIR) {
+			(void)putchar('/');
+			return (1);
+		} else
+			return (0);
+	} else {
+			switch (mode & S_IFMT) {
+			case S_IFDIR:
+				(void)putchar('/');
+				return (1);
+			case S_IFIFO:
+				(void)putchar('|');
+				return (1);
+			case S_IFLNK:
+				(void)putchar('@');
+				return (1);
+			case S_IFSOCK:
+				(void)putchar('=');
+				return (1);
+			case S_IFWHT:
+				(void)putchar('%');
+				return (1);
+			default:
+				if (mode & (S_IXUSR | S_IXGRP | S_IXOTH)) {
+					(void)putchar('*');
+					return (1);
+				}
+			}
+			return (0);
 	}
-	return (0);
 }
 
 #ifdef COLORLS
 static int
 putch(int c)

-- 
Kyle Martin 
<mkm@ieee.org>

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-standards" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20020305224856.A1397>