Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/usr.bin/units Add -l and -L options to units(1). "-l" simpl...
details: https://anonhg.NetBSD.org/src/rev/15fa2037a2d0
branches: trunk
changeset: 783616:15fa2037a2d0
user: apb <apb%NetBSD.org@localhost>
date: Tue Jan 01 11:51:55 2013 +0000
description:
Add -l and -L options to units(1). "-l" simply lists all unit
definitions, while "-L" alsoreduces them to depend only on a few
primitive units (such as m, kg, sec).
diffstat:
usr.bin/units/units.1 | 22 +++++-
usr.bin/units/units.c | 174 ++++++++++++++++++++++++++++++++++++++++++++-----
2 files changed, 175 insertions(+), 21 deletions(-)
diffs (truncated from 343 to 300 lines):
diff -r b48ee207f549 -r 15fa2037a2d0 usr.bin/units/units.1
--- a/usr.bin/units/units.1 Tue Jan 01 11:44:00 2013 +0000
+++ b/usr.bin/units/units.1 Tue Jan 01 11:51:55 2013 +0000
@@ -1,4 +1,4 @@
-.\" $NetBSD: units.1,v 1.18 2012/12/28 13:25:25 apb Exp $
+.\" $NetBSD: units.1,v 1.19 2013/01/01 11:51:55 apb Exp $
.Dd December 28, 2012
.Dt UNITS 1
.Os
@@ -8,7 +8,7 @@
.Sh SYNOPSIS
.Nm
.Op Fl f Ar filename
-.Op Fl qv
+.Op Fl lLqv
.Oo
.Op Ar count
.Ar from-unit to-unit
@@ -25,6 +25,24 @@
.Bl -tag -width "-fXfilenameX" -offset indent
.It Fl f Ar filename
Specifies the name of the units data file to load.
+.It Fl l No or Fl L
+List all unit definitions to the standard output,
+instead of performing any conversions.
+The result may include error messages and comments, beginning with
+.Ql \&/ .
+.Pp
+With the
+.Fl l
+option, unit definitions will be listed in a format
+almost identical to the the units data file that was loaded,
+except that comments will be removed, spacing may be changed,
+and lines may be re-ordered.
+.Pp
+With the
+.Fl L
+option, all unit definitions will be reduced to a form that
+depends on only a few primitive units (such as
+.Sy m , kg , sec ) .
.It Fl q
Suppresses prompting of the user for units and the display of statistics
about the number of units loaded.
diff -r b48ee207f549 -r 15fa2037a2d0 usr.bin/units/units.c
--- a/usr.bin/units/units.c Tue Jan 01 11:44:00 2013 +0000
+++ b/usr.bin/units/units.c Tue Jan 01 11:51:55 2013 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: units.c,v 1.20 2013/01/01 11:44:00 apb Exp $ */
+/* $NetBSD: units.c,v 1.21 2013/01/01 11:51:55 apb Exp $ */
/*
* units.c Copyright (c) 1993 by Adrian Mariano (adrian%cam.cornell.edu@localhost)
@@ -19,6 +19,7 @@
#include <ctype.h>
#include <err.h>
+#include <float.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
@@ -39,6 +40,13 @@
#define PRIMITIVECHAR '!'
+static int precision = 8; /* for printf with "%.*g" format */
+
+static const char *errprefix = NULL; /* if not NULL, then prepend this
+ * to error messages and send them to
+ * stdout instead of stderr.
+ */
+
static const char *powerstring = "^";
static struct {
@@ -98,9 +106,27 @@
static void
+mywarnx(const char *fmt, ...)
+{
+ va_list args;
+
+ va_start(args, fmt);
+ if (errprefix) {
+ /* warn to stdout, with errprefix prepended */
+ printf("%s", errprefix);
+ vprintf(fmt, args);
+ printf("%s", "\n");
+ } else {
+ /* warn to stderr */
+ vwarnx(fmt, args);
+ }
+ va_end(args);
+}
+
+static void
readerror(int linenum)
{
- warnx("Error in units file '%s' line %d", UNITSFILE, linenum);
+ mywarnx("Error in units file '%s' line %d", UNITSFILE, linenum);
}
@@ -168,8 +194,9 @@
continue;
if (lineptr[strlen(lineptr) - 1] == '-') { /* it's a prefix */
if (prefixcount == MAXPREFIXES) {
- warnx("Memory for prefixes exceeded in line %d",
- linenum);
+ mywarnx(
+ "Memory for prefixes exceeded in line %d",
+ linenum);
continue;
}
lineptr[strlen(lineptr) - 1] = 0;
@@ -181,7 +208,7 @@
}
}
if (isdup) {
- warnx(
+ mywarnx(
"Redefinition of prefix '%s' on line %d ignored",
lineptr, linenum);
continue;
@@ -199,7 +226,7 @@
}
else { /* it's not a prefix */
if (unitcount == MAXUNITS) {
- warnx("Memory for units exceeded in line %d",
+ mywarnx("Memory for units exceeded in line %d",
linenum);
continue;
}
@@ -210,7 +237,7 @@
}
}
if (isdup) {
- warnx(
+ mywarnx(
"Redefinition of unit '%s' on line %d ignored",
lineptr, linenum);
continue;
@@ -244,7 +271,7 @@
for (ptr = product; *ptr && *ptr != NULLUNIT; ptr++);
if (ptr >= product + MAXSUBUNITS) {
- warnx("Memory overflow in unit reduction");
+ mywarnx("Memory overflow in unit reduction");
return 1;
}
if (!*ptr)
@@ -260,7 +287,7 @@
int printedslash;
int counter = 1;
- printf("\t%.8g", theunit->factor);
+ printf("\t%.*g", precision, theunit->factor);
for (ptr = theunit->numerator; *ptr; ptr++) {
if (ptr > theunit->numerator && **ptr &&
!strcmp(*ptr, *(ptr - 1)))
@@ -301,7 +328,7 @@
static void
zeroerror(void)
{
- warnx("Unit reduces to zero");
+ mywarnx("Unit reduces to zero");
}
/*
@@ -347,8 +374,7 @@
}
if (endptr != divider) {
/* "6foo|2" is an error */
- warnx("Junk between number "
- "and '|'");
+ mywarnx("Junk before '|'");
return 1;
}
if (doingtop ^ flip)
@@ -562,7 +588,7 @@
break;
toadd = lookupunit(*product);
if (!toadd) {
- printf("unknown unit '%s'\n", *product);
+ mywarnx("Unknown unit '%s'", *product);
return ERROR;
}
if (strchr(toadd, PRIMITIVECHAR))
@@ -660,15 +686,109 @@
showunit(want);
} else {
printf("\treciprocal conversion\n");
- printf("\t* %.8g\n\t/ %.8g\n", 1 / (have->factor * want->factor),
- want->factor * have->factor);
+ printf("\t* %.*g\n\t/ %.*g\n",
+ precision, 1 / (have->factor * want->factor),
+ precision, want->factor * have->factor);
}
}
else
- printf("\t* %.8g\n\t/ %.8g\n", have->factor / want->factor,
- want->factor / have->factor);
+ printf("\t* %.*g\n\t/ %.*g\n",
+ precision, have->factor / want->factor,
+ precision, want->factor / have->factor);
}
+static int
+listunits(int expand)
+{
+ struct unittype theunit;
+ const char *thename;
+ const char *thedefn;
+ int errors = 0;
+ int i;
+ int printexpansion;
+
+ /*
+ * send error and warning messages to stdout,
+ * and make them look like comments.
+ */
+ errprefix = "/ ";
+
+#if 0 /* debug */
+ printf("/ expand=%d precision=%d unitcount=%d prefixcount=%d\n",
+ expand, precision, unitcount, prefixcount);
+#endif
+
+ /* 1. Dump all primitive units, e.g. "m !a!", "kg !b!", ... */
+ printf("/ Primitive units\n");
+ for (i = 0; i < unitcount; i++) {
+ thename = unittable[i].uname;
+ thedefn = unittable[i].uval;
+ if (thedefn[0] == PRIMITIVECHAR) {
+ printf("%s\t%s\n", thename, thedefn);
+ }
+ }
+
+ /* 2. Dump all prefixes, e.g. "yotta- 1e24", "zetta- 1e21", ... */
+ printf("/ Prefixes\n");
+ for (i = 0; i < prefixcount; i++) {
+ printexpansion = expand;
+ thename = prefixtable[i].prefixname;
+ thedefn = prefixtable[i].prefixval;
+ if (expand) {
+ /*
+ * prefix names are sometimes identical to unit
+ * names, so we have to expand thedefn instead of
+ * expanding thename.
+ */
+ initializeunit(&theunit);
+ if (addunit(&theunit, thedefn, 0) != 0
+ || completereduce(&theunit) != 0) {
+ errors++;
+ printexpansion = 0;
+ mywarnx("Error in prefix '%s-'", thename);
+ }
+ }
+ if (printexpansion) {
+ printf("%s-", thename);
+ showunit(&theunit);
+ } else
+ printf("%s-\t%s\n", thename, thedefn);
+ }
+
+ /* 3. Dump all other units. */
+ printf("/ Other units\n");
+ for (i = 0; i < unitcount; i++) {
+ printexpansion = expand;
+ thename = unittable[i].uname;
+ thedefn = unittable[i].uval;
+ if (thedefn[0] == PRIMITIVECHAR)
+ continue;
+ if (expand) {
+ /*
+ * expand thename, not thedefn, so that
+ * we can catch errors in the name itself.
+ * e.g. a name that contains a hyphen
+ * will be interpreted
+ */
+ initializeunit(&theunit);
+ if (addunit(&theunit, thedefn/*XXX*/, 0) != 0
+ || completereduce(&theunit) != 0) {
+ errors++;
+ printexpansion = 0;
+ mywarnx("Error in unit '%s'", thename);
+ }
+ }
+ if (printexpansion) {
+ printf("%s", thename);
+ showunit(&theunit);
+ } else
+ printf("%s\t%s\n", thename, thedefn);
+ }
+
+ if (errors)
+ mywarnx("Definitions with errors: %d", errors);
+ return (errors ? 1 : 0);
+}
Home |
Main Index |
Thread Index |
Old Index