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>
This commit is contained in:
parent
57308494ec
commit
545f583c55
10
bin/ls/ls.1
10
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
|
||||
|
80
bin/ls/ls.c
80
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;
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user