diff options
author | hoek <hoek@FreeBSD.org> | 1998-07-29 00:46:13 +0000 |
---|---|---|
committer | hoek <hoek@FreeBSD.org> | 1998-07-29 00:46:13 +0000 |
commit | eb80fc954a91302e6a1ddcfced0528aaa621355f (patch) | |
tree | 930c063482f30ff1022446b3692a99dd2817c70b /bin | |
parent | d4df58a7bc400f4d07b99cf44dd6e94c8b806de3 (diff) | |
download | FreeBSD-src-eb80fc954a91302e6a1ddcfced0528aaa621355f.zip FreeBSD-src-eb80fc954a91302e6a1ddcfced0528aaa621355f.tar.gz |
Allow env. variable LS_COLWIDTHS to specify minimum column widths,
effectively overriding the dynamically-sized-column feature. This
is mostly useful for non-interactive use, where it may be necessary
to ensure that listings taken at different times have columns that
line-up correctly. I have been assured that at least one large,
well-known program will soon be taking advantage of this. :-)
PR: bin/7011
Submitted by: Joel Ray Holveck <joelh@gnu.org>
Diffstat (limited to 'bin')
-rw-r--r-- | bin/ls/ls.1 | 10 | ||||
-rw-r--r-- | bin/ls/ls.c | 80 | ||||
-rw-r--r-- | bin/ls/ls.h | 3 | ||||
-rw-r--r-- | bin/ls/print.c | 17 |
4 files changed, 97 insertions, 13 deletions
diff --git a/bin/ls/ls.1 b/bin/ls/ls.1 index 94f86ef..0ace911 100644 --- a/bin/ls/ls.1 +++ b/bin/ls/ls.1 @@ -33,7 +33,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)ls.1 8.7 (Berkeley) 7/29/94 -.\" $Id: ls.1,v 1.22 1998/05/13 07:57:03 phk Exp $ +.\" $Id: ls.1,v 1.23 1998/05/15 06:22:30 charnier Exp $ .\" .Dd July 29, 1994 .Dt LS 1 @@ -373,6 +373,14 @@ The timezone to use when displaying dates. See .Xr environ 7 for more information. +.It Ev LS_COLWIDTHS +If this variable is set, it is considered to be a +colon-delimited list of minimum column widths. Unreasonable +and insufficient widths are ignored (thus zero signifies +a dynamically sized column). Not all +columns have changable widths. The fields are, +in order: inode, block count, number of links, user name, +group name, flags, file size, file name. .El .Sh COMPATIBILITY The group field is now automatically included in the long listing for diff --git a/bin/ls/ls.c b/bin/ls/ls.c index 82ba154..cde9c9f 100644 --- a/bin/ls/ls.c +++ b/bin/ls/ls.c @@ -45,7 +45,7 @@ static const char copyright[] = static char sccsid[] = "@(#)ls.c 8.5 (Berkeley) 4/2/94"; #else static const char rcsid[] = - "$Id: ls.c,v 1.20 1998/04/24 12:43:26 des Exp $"; + "$Id: ls.c,v 1.21 1998/04/24 20:15:42 des Exp $"; #endif #endif /* not lint */ @@ -67,6 +67,7 @@ static const char rcsid[] = #include "extern.h" static void display __P((FTSENT *, FTSENT *)); +static u_quad_t makenines __P((u_long)); static int mastercmp __P((const FTSENT **, const FTSENT **)); static void traverse __P((int, char **, int)); @@ -95,6 +96,7 @@ int f_sectime; /* print the real time for all files */ int f_singlecol; /* use single column output */ int f_size; /* list size in short listing */ int f_statustime; /* use time of last mode change */ +int f_notabs; /* don't use tab-separated multi-col output */ int f_timesort; /* sort by time vice name */ int f_type; /* add type character for non-regular files */ int f_whiteout; /* show whiteout entries */ @@ -396,6 +398,7 @@ display(p, list) u_quad_t maxsize; u_long btotal, maxblock, maxinode, maxlen, maxnlink; int bcfile, flen, glen, ulen, maxflags, maxgroup, maxuser; + char *initmax; int entries, needstats; char *user, *group, *flags, buf[20]; /* 32 bits == 10 digits */ @@ -411,11 +414,58 @@ display(p, list) needstats = f_inode || f_longform || f_size; flen = 0; - btotal = maxblock = maxinode = maxlen = maxnlink = 0; + btotal = 0; + initmax = getenv("LS_COLWIDTHS"); + /* Fields match -lios order. New ones should be added at the end. */ + if (initmax != NULL && *initmax != '\0') { + char *initmax2, *jinitmax; + int ninitmax; + + /* Fill-in "::" as "0:0:0" for the sake of scanf. */ + jinitmax = initmax2 = malloc(strlen(initmax) * 2 + 2); + if (jinitmax == NULL) + err(1, NULL); + if (*initmax == ':') + strcpy(initmax2, "0:"), initmax2 += 2; + else + *initmax2++ = *initmax, *initmax2 = '\0'; + for (initmax++; *initmax != '\0'; initmax++) { + if (initmax[-1] == ':' && initmax[0] == ':') { + *initmax2++ = '0'; + *initmax2++ = initmax[0]; + initmax2[1] = '\0'; + } else { + *initmax2++ = initmax[0]; + initmax2[1] = '\0'; + } + } + if (initmax2[-1] == ':') strcpy(initmax2, "0"); + + ninitmax = sscanf(jinitmax, + " %lu : %lu : %lu : %i : %i : %i : %qu : %lu ", + &maxinode, &maxblock, &maxnlink, &maxuser, + &maxgroup, &maxflags, &maxsize, &maxlen); + f_notabs = 1; + switch (ninitmax) { + case 0: maxinode = 0; + case 1: maxblock = 0; + case 2: maxnlink = 0; + case 3: maxuser = 0; + case 4: maxgroup = 0; + case 5: maxflags = 0; + case 6: maxsize = 0; + case 7: maxlen = 0, f_notabs = 0; + } + maxinode = makenines(maxinode); + maxblock = makenines(maxblock); + maxnlink = makenines(maxnlink); + maxsize = makenines(maxsize); + } + if (initmax == NULL || *initmax == '\0') + maxblock = maxinode = maxlen = maxnlink = + maxuser = maxgroup = maxflags = maxsize = 0; bcfile = 0; - maxuser = maxgroup = maxflags = 0; flags = NULL; - maxsize = 0; for (cur = list, entries = 0; cur; cur = cur->fts_link) { if (cur->fts_info == FTS_ERR || cur->fts_info == FTS_NS) { warnx("%s: %s", @@ -449,7 +499,7 @@ display(p, list) if (f_octal || f_octal_escape) { int t = len_octal(cur->fts_name, cur->fts_namelen); if (t > maxlen) maxlen = t; - } + } if (needstats) { sp = cur->fts_statp; if (sp->st_blocks > maxblock) @@ -561,3 +611,23 @@ mastercmp(a, b) } return (sortfcn(*a, *b)); } + +/* + * Makenines() returns (10**n)-1. This is useful for converting a width + * into a number that wide in decimal. + */ +static u_quad_t +makenines(n) + u_long n; +{ + u_long i; + u_quad_t reg; + + reg = 1; + /* Use a loop instead of pow(), since all values of n are small. */ + for (i = 0; i < n; i++) + reg *= 10; + reg--; + + return reg; +} diff --git a/bin/ls/ls.h b/bin/ls/ls.h index eb13c61..b064d18 100644 --- a/bin/ls/ls.h +++ b/bin/ls/ls.h @@ -35,7 +35,7 @@ * SUCH DAMAGE. * * from: @(#)ls.h 8.1 (Berkeley) 5/31/93 - * $Id: ls.h,v 1.8 1998/04/21 22:02:00 des Exp $ + * $Id: ls.h,v 1.9 1998/04/24 07:49:49 des Exp $ */ #define NO_PRINT 1 @@ -51,6 +51,7 @@ extern int f_octal_escape; /* like f_octal but use C escapes if possible */ extern int f_sectime; /* print the real time for all files */ extern int f_size; /* list size in short listing */ 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 */ typedef struct { diff --git a/bin/ls/print.c b/bin/ls/print.c index 84e0fe9..8153171 100644 --- a/bin/ls/print.c +++ b/bin/ls/print.c @@ -39,7 +39,7 @@ static char sccsid[] = "@(#)print.c 8.4 (Berkeley) 4/17/94"; #else static const char rcsid[] = - "$Id: print.c,v 1.15 1998/04/21 22:02:01 des Exp $"; + "$Id: print.c,v 1.16 1998/04/24 07:49:50 des Exp $"; #endif #endif /* not lint */ @@ -137,8 +137,6 @@ printlong(dp) } } -#define TAB 8 - void printcol(dp) DISPLAY *dp; @@ -149,6 +147,12 @@ printcol(dp) FTSENT *p; int base, chcnt, cnt, col, colwidth, num; int endcol, numcols, numrows, row; + int tabwidth; + + if (f_notabs) + tabwidth = 1; + else + tabwidth = 8; /* * Have to do random access in the linked list -- build a table @@ -174,7 +178,7 @@ printcol(dp) if (f_type) colwidth += 1; - colwidth = (colwidth + TAB) & ~(TAB - 1); + colwidth = (colwidth + tabwidth) & ~(tabwidth - 1); if (termwidth < 2 * colwidth) { printscol(dp); return; @@ -194,8 +198,9 @@ printcol(dp) dp->s_block); if ((base += numrows) >= num) break; - while ((cnt = ((chcnt + TAB) & ~(TAB - 1))) <= endcol){ - (void)putchar('\t'); + while ((cnt = ((chcnt + tabwidth) & ~(tabwidth - 1))) + <= endcol){ + (void)putchar(f_notabs ? ' ' : '\t'); chcnt = cnt; } endcol += colwidth; |