[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: library/2570: new libutil function: humanize_number(3)
- To: bugs_(_at_)_openbsd_(_dot_)_org
- Subject: Re: library/2570: new libutil function: humanize_number(3)
- From: Nick Nauwelaerts <nick_(_at_)_wanadoo_(_dot_)_be>
- Date: Thu, 25 Apr 2002 15:00:49 +0200
On Thu, 25 Apr 2002 16:48:37 +0200 (CEST)
Tomas Svensson <tsn_(_at_)_gbdev_(_dot_)_net> wrote:
> >Number: 2570
> >Category: library
> >Synopsis: new libutil function: humanize_number(3)
> >Confidential: no
> >Severity: non-critical
> >Priority: medium
> >Responsible: bugs
> >State: open
> >Class: change-request
> >Submitter-Id: net
> >Arrival-Date: Thu Apr 25 06:50:01 MDT 2002
> >Last-Modified:
> >Originator: Tomas Svensson
> >Organization:
> net
> >Release: 3.1-current
> >Environment:
> System : OpenBSD 3.1
> Architecture: OpenBSD.i386
> Machine : i386
> >Description:
> New humanize function for libutil to be used instead of
> prthuman() in df/du and can also be used for ls/pkg_add etc.
>
> Direct improvement over prthuman would be that it it doesnt need
> libm and it can guarantee that max 3 digits will be used
> (as prthuman() was originally intended to work:
> http://www.openbsd.org/cgi-bin/cvsweb/src/bin/df/df.1.diff?r1=1.8&r2=1.9&f=h
> since "1000K" should be replaced with "1M" even if its not
> "correct").
>
> It can also be used to humanize numbers even more by using the
> same suffix for all numbers:
This seems very interesting. Me and a friend were working on a -h option
to ls as well. We coded up a semi working version. it's not yet
complete, current issues are that the total is incorrect when you
specify -h, and I suspect portability issues as well.
Here's the patch if you're interested in comparing (the patch isn't
really up to date, a new revision to ls has since been committed):
Index: cmp.c
===================================================================
RCS file: /cvs/src/bin/ls/cmp.c,v
retrieving revision 1.3
diff -u -r1.3 cmp.c
--- cmp.c 3 Jan 1997 22:36:07 -0000 1.3
+++ cmp.c 1 Mar 2002 09:46:56 -0000
@@ -54,23 +54,17 @@
#include "ls.h"
#include "extern.h"
-int
-namecmp(a, b)
- const FTSENT *a, *b;
+int namecmp(const FTSENT *a, const FTSENT *b)
{
return (strcmp(a->fts_name, b->fts_name));
}
-int
-revnamecmp(a, b)
- const FTSENT *a, *b;
+int revnamecmp(const FTSENT *a, const FTSENT *b)
{
return (strcmp(b->fts_name, a->fts_name));
}
-int
-modcmp(a, b)
- const FTSENT *a, *b;
+int modcmp(const FTSENT *a, const FTSENT *b)
{
if (b->fts_statp->st_mtime > a->fts_statp->st_mtime)
return (1);
@@ -84,9 +78,7 @@
return (namecmp(a, b));
}
-int
-revmodcmp(a, b)
- const FTSENT *a, *b;
+int revmodcmp(const FTSENT *a, const FTSENT *b)
{
if (b->fts_statp->st_mtime > a->fts_statp->st_mtime)
return (-1);
@@ -100,9 +92,7 @@
return (revnamecmp(a, b));
}
-int
-acccmp(a, b)
- const FTSENT *a, *b;
+int acccmp(const FTSENT *a, const FTSENT *b)
{
if (b->fts_statp->st_atime > a->fts_statp->st_atime)
return (1);
@@ -116,9 +106,7 @@
return (namecmp(a, b));
}
-int
-revacccmp(a, b)
- const FTSENT *a, *b;
+int revacccmp(const FTSENT *a, const FTSENT *b)
{
if (b->fts_statp->st_atime > a->fts_statp->st_atime)
return (-1);
@@ -132,9 +120,7 @@
return (revnamecmp(a, b));
}
-int
-statcmp(a, b)
- const FTSENT *a, *b;
+int statcmp(const FTSENT *a, const FTSENT *b)
{
if (b->fts_statp->st_ctime > a->fts_statp->st_ctime)
return (1);
@@ -148,9 +134,7 @@
return (namecmp(a, b));
}
-int
-revstatcmp(a, b)
- const FTSENT *a, *b;
+int revstatcmp(const FTSENT *a, const FTSENT *b)
{
if (b->fts_statp->st_ctime > a->fts_statp->st_ctime)
return (-1);
@@ -164,9 +148,7 @@
return (revnamecmp(a, b));
}
-int
-sizecmp(a, b)
- const FTSENT *a, *b;
+int sizecmp(const FTSENT *a, const FTSENT *b)
{
if (b->fts_statp->st_size > a->fts_statp->st_size)
return (1);
@@ -176,9 +158,7 @@
return (namecmp(a, b));
}
-int
-revsizecmp(a, b)
- const FTSENT *a, *b;
+int revsizecmp(const FTSENT *a, const FTSENT *b)
{
if (b->fts_statp->st_size > a->fts_statp->st_size)
return (-1);
Index: ls.1
===================================================================
RCS file: /cvs/src/bin/ls/ls.1,v
retrieving revision 1.33
diff -u -r1.33 ls.1
--- ls.1 11 Feb 2002 18:43:51 -0000 1.33
+++ ls.1 1 Mar 2002 09:46:56 -0000
@@ -129,6 +129,8 @@
.It Fl g
Does nothing; kept for compatibility with older versions of
.Xr ls 1 .
+.It Fl h
+Show filesize in human-readable format.
.It Fl i
For each file, print its inode number.
.It Fl k
@@ -213,6 +215,13 @@
The
.Fl f
option overrides any occurrence of either.
+.Pp
+The
+.Fl k
+and
+.Fl h
+options override each other; the last one specified determines
+the size option used.
.Pp
By default,
.Nm
Index: ls.c
===================================================================
RCS file: /cvs/src/bin/ls/ls.c,v
retrieving revision 1.16
diff -u -r1.16 ls.c
--- ls.c 16 Feb 2002 21:27:07 -0000 1.16
+++ ls.c 1 Mar 2002 09:46:56 -0000
@@ -90,6 +90,7 @@
int f_column; /* columnated format */
int f_columnacross; /* columnated format, sorted across */
int f_flags; /* show flags associated with a file */
+int f_human; /* list size in human readable form */
int f_inode; /* print inode */
int f_listdir; /* list actual directory, not contents */
int f_listdot; /* list files beginning with . */
@@ -112,15 +113,13 @@
int rval;
-int
-ls_main(argc, argv)
- int argc;
- char *argv[];
+int ls_main(int argc, char *argv[])
{
static char dot[] = ".", *dotav[] = { dot, NULL };
struct winsize win;
int ch, fts_options, notused;
int kflag = 0;
+ int hflag = 0;
char *p;
/* Terminal defaults to -Cq, non-terminal defaults to -1. */
@@ -139,7 +138,7 @@
f_listdot = 1;
fts_options = FTS_PHYSICAL;
- while ((ch = getopt(argc, argv, "1ACFLRSTWacdfgiklmnopqrstux")) != -1)
{+ while ((ch = getopt(argc, argv, "1ACFLRSTWacdfghiklmnopqrstux")) !=
-1) { switch (ch) {
/*
* The -1, -C and -l, -m and -x options all override each
@@ -207,12 +206,20 @@
break;
case 'g': /* Compatibility with 4.3BSD. */
break;
+ case 'h':
+ blocksize = 512;
+ f_human = 1;
+ kflag = 0;
+ hflag = 1;
+ break;
case 'i':
f_inode = 1;
break;
case 'k':
blocksize = 1024;
+ f_human = 0;
kflag = 1;
+ hflag = 0;
break;
case 'o':
f_flags = 1;
@@ -273,7 +280,7 @@
/* If -l or -s, figure out block size. */
if (f_longform || f_size) {
- if (!kflag)
+ if (!(kflag || hflag))
(void)getbsize(¬used, &blocksize);
blocksize /= 512;
}
@@ -342,10 +349,7 @@
* traversal it passes linked lists of structures to display() which
represent * a superset (may be exact set) of the files to be displayed.
*/
-static void
-traverse(argc, argv, options)
- int argc, options;
- char *argv[];
+static void traverse(int argc, char *argv[], int options)
{
FTS *ftsp;
FTSENT *p, *chp;
@@ -408,9 +412,7 @@
* along with any other necessary information to the print function. P
* points to the parent directory of the display list.
*/
-static void
-display(p, list)
- FTSENT *p, *list;
+static void display(FTSENT *p, FTSENT *list)
{
struct stat *sp;
DISPLAY d;
@@ -564,9 +566,7 @@
* as larger than directories. Within either group, use the sort
function. * All other levels use the sort function. Error entries
remain unsorted. */
-static int
-mastercmp(a, b)
- const FTSENT **a, **b;
+static int mastercmp(const FTSENT **a, const FTSENT **b)
{
int a_info, b_info;
Index: ls.h
===================================================================
RCS file: /cvs/src/bin/ls/ls.h,v
retrieving revision 1.4
diff -u -r1.4 ls.h
--- ls.h 1 May 1999 23:54:47 -0000 1.4
+++ ls.h 1 Mar 2002 09:46:56 -0000
@@ -50,6 +50,7 @@
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_human; /* list size in human readable form */
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 */
Index: main.c
===================================================================
RCS file: /cvs/src/bin/ls/main.c,v
retrieving revision 1.2
diff -u -r1.2 main.c
--- main.c 16 Feb 2002 21:27:07 -0000 1.2
+++ main.c 1 Mar 2002 09:46:56 -0000
@@ -8,10 +8,7 @@
int ls_main(int argc, char **argv);
-int
-main(argc, argv)
- int argc;
- char **argv;
+int main(int argc, char **argv)
{
return ls_main(argc, argv);
}
Index: print.c
===================================================================
RCS file: /cvs/src/bin/ls/print.c,v
retrieving revision 1.16
diff -u -r1.16 print.c
--- print.c 16 Feb 2002 21:27:07 -0000 1.16
+++ print.c 1 Mar 2002 09:46:56 -0000
@@ -69,12 +69,11 @@
static void printtime(time_t);
static int printtype(u_int);
static int compute_columns(DISPLAY *, int *);
+static void humanize (int, char*);
#define IS_NOPRINT(p) ((p)->fts_number == NO_PRINT)
-void
-printscol(dp)
- DISPLAY *dp;
+void printscol(DISPLAY *dp)
{
FTSENT *p;
@@ -86,14 +85,13 @@
}
}
-void
-printlong(dp)
- DISPLAY *dp;
+void printlong(DISPLAY *dp)
{
struct stat *sp;
FTSENT *p;
NAMES *np;
char buf[20];
+ char *human;
if (dp->list->fts_level != FTS_ROOTLEVEL && (f_longform ||
f_size)) (void)printf("total %lu\n", howmany(dp->btotal,
blocksize));@@ -120,7 +118,10 @@
else if (dp->bcfile)
(void)printf("%*s%*qd ",
8 - dp->s_size, "", dp->s_size, sp->st_size);
- else
+ else if (f_human) {
+ (void)humanize(sp->st_size, human);
+ (void)printf("%*qs ", dp->s_size, human);
+ } else
(void)printf("%*qd ", dp->s_size, sp->st_size);
if (f_accesstime)
printtime(sp->st_atime);
@@ -137,10 +138,7 @@
}
}
-static int
-compute_columns(dp, pnum)
- DISPLAY *dp;
- int *pnum;
+static int compute_columns (DISPLAY *dp, int *pnum)
{
int colwidth;
extern int termwidth;
@@ -166,9 +164,7 @@
return (mywidth / *pnum); /* spread out if possible */
}
-void
-printcol(dp)
- DISPLAY *dp;
+void printcol(DISPLAY *dp)
{
static FTSENT **array;
static int lastentries = -1;
@@ -222,10 +218,7 @@
* print [inode] [size] name
* return # of characters printed, no trailing characters.
*/
-static int
-printaname(p, inodefield, sizefield)
- FTSENT *p;
- u_long sizefield, inodefield;
+static int printaname(FTSENT *p, u_long sizefield, u_long inodefield)
{
struct stat *sp;
int chcnt;
@@ -243,9 +236,7 @@
return (chcnt);
}
-static void
-printtime(ftime)
- time_t ftime;
+static void printtime(time_t ftime)
{
int i;
char *longstring;
@@ -269,9 +260,7 @@
(void)putchar(' ');
}
-void
-printacol(dp)
- DISPLAY *dp;
+void printacol(DISPLAY *dp)
{
FTSENT *p;
int chcnt, col, colwidth;
@@ -300,9 +289,7 @@
(void)putchar('\n');
}
-void
-printstream(dp)
- DISPLAY *dp;
+void printstream(DISPLAY *dp)
{
extern int termwidth;
FTSENT *p;
@@ -332,9 +319,7 @@
(void)putchar('\n');
}
-static int
-printtype(mode)
- u_int mode;
+static int printtype(u_int mode)
{
switch (mode & S_IFMT) {
case S_IFDIR:
@@ -360,9 +345,7 @@
return (0);
}
-static void
-printlink(p)
- FTSENT *p;
+static void printlink(FTSENT *p)
{
int lnklen;
char name[MAXPATHLEN], path[MAXPATHLEN];
@@ -379,4 +362,49 @@
path[lnklen] = '\0';
(void)printf(" -> ");
(void)putname(path);
+}
+
+/*
+ * "human-readable" output: use 3 digits max.--put unit suffixes at
+ * the end. Makes output compact and easy-to-read.
+ * copied from du(1) source
+ */
+
+typedef enum { NONE = 0, KILO, MEGA, GIGA, TERA, PETA /* , EXA */ }
unit_t;+
+unit_t unit_adjust(int *val)
+{
+ int abval = (int)*val;
+ unit_t unit;
+
+ if (abval < 1024)
+ unit = NONE;
+ else if (abval < 1048576ULL) {
+ unit = KILO;
+ *val /= 1024;
+ } else if (abval < 1073741824ULL) {
+ unit = MEGA;
+ *val /= 1048576;
+ } else if (abval < 1099511627776ULL) {
+ unit = GIGA;
+ *val /= 1073741824ULL;
+ } else if (abval < 1125899906842624ULL) {
+ unit = TERA;
+ *val /= 1099511627776ULL;
+ } else /* if (abval < 1152921504606846976ULL) */ {
+ unit = PETA;
+ *val /= 1125899906842624ULL;
+ }
+ return (unit);
+}
+
+static void humanize(int size, char *result)
+{
+ int bytes;
+ unit_t unit;
+
+ bytes = size;
+ unit = unit_adjust(&bytes);
+
+ (void)sprintf(result, "%d%c", bytes, "BKMGTPE"[unit]);
}
Index: util.c
===================================================================
RCS file: /cvs/src/bin/ls/util.c,v
retrieving revision 1.7
diff -u -r1.7 util.c
--- util.c 6 Sep 2001 13:29:08 -0000 1.7
+++ util.c 1 Mar 2002 09:46:56 -0000
@@ -57,9 +57,7 @@
#include "ls.h"
#include "extern.h"
-int
-putname(name)
- char *name;
+int putname(char *name)
{
int len;
@@ -68,8 +66,7 @@
return len;
}
-void
-usage()
+void usage()
{
(void)fprintf(stderr,
"usage: %s [-1ACFLRSTWacdfiklmnopqrstux] [file ...]\n",
// nick
Visit your host, monkey.org