From owner-freebsd-standards Tue Mar 5 20:49:36 2002 Delivered-To: freebsd-standards@freebsd.org Received: from marvin.idsi.net (66-168-58-99.jvl.wi.charter.com [66.168.58.99]) by hub.freebsd.org (Postfix) with ESMTP id 62E6C37B402 for ; Tue, 5 Mar 2002 20:49:18 -0800 (PST) Received: from marvin.idsi.net (localhost [127.0.0.1]) by marvin.idsi.net (8.12.2/8.12.2) with ESMTP id g264mw29001548; Tue, 5 Mar 2002 22:49:01 -0600 (CST) (envelope-from mkm@marvin.idsi.net) Received: (from mkm@localhost) by marvin.idsi.net (8.12.2/8.12.2/Submit) id g264muwJ001547; Tue, 5 Mar 2002 22:48:56 -0600 (CST) Date: Tue, 5 Mar 2002 22:48:56 -0600 From: Kyle Martin To: "Tim J. Robbins" Cc: freebsd-standards@freebsd.org Subject: Re: ls(1) patch for review Message-ID: <20020305224856.A1397@marvin.idsi.net> References: <20020305030632.A1990@marvin.idsi.net> <20020305205733.A31150@descent.robbins.dropbear.id.au> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.2.5.1i 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 +1100 Sender: owner-freebsd-standards@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG 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 To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-standards" in the body of the message