From owner-freebsd-bugs Tue Apr 16 04:40:06 1996 Return-Path: owner-bugs Received: (from root@localhost) by freefall.freebsd.org (8.7.3/8.7.3) id EAA05420 for bugs-outgoing; Tue, 16 Apr 1996 04:40:06 -0700 (PDT) Received: (from gnats@localhost) by freefall.freebsd.org (8.7.3/8.7.3) id EAA05382 Tue, 16 Apr 1996 04:40:03 -0700 (PDT) Resent-Date: Tue, 16 Apr 1996 04:40:03 -0700 (PDT) Resent-Message-Id: <199604161140.EAA05382@freefall.freebsd.org> Resent-From: gnats (GNATS Management) Resent-To: freebsd-bugs Resent-Reply-To: FreeBSD-gnats@freefall.FreeBSD.org, jez@netcraft.co.uk Received: from ns0.netcraft.co.uk (ns0.netcraft.co.uk [194.72.238.4]) by freefall.freebsd.org (8.7.3/8.7.3) with ESMTP id EAA05287 for ; Tue, 16 Apr 1996 04:38:19 -0700 (PDT) Received: (from jez@localhost) by ns0.netcraft.co.uk (8.7.5/8.6.9) id MAA18313; Tue, 16 Apr 1996 12:37:58 +0100 (BST) Message-Id: <199604161137.MAA18313@ns0.netcraft.co.uk> Date: Tue, 16 Apr 1996 12:37:58 +0100 (BST) From: jez@netcraft.co.uk (Jeremy Prior) Reply-To: jez@netcraft.co.uk To: FreeBSD-gnats-submit@freebsd.org X-Send-Pr-Version: 3.2 Subject: bin/1147: units(1) command missing Sender: owner-bugs@freebsd.org X-Loop: FreeBSD.org Precedence: bulk >Number: 1147 >Category: bin >Synopsis: units(1) missing from FreeBSD -current and -stable >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-bugs >State: open >Class: change-request >Submitter-Id: current-users >Arrival-Date: Tue Apr 16 04:40:02 PDT 1996 >Last-Modified: >Originator: Jeremy Prior >Organization: Netcraft Ltd >Release: FreeBSD 2.1-STABLE i386 >Environment: FreeBSD -current or less >Description: FreeBSD is missing units(1) - Not sure why! >How-To-Repeat: % units units: Command not found. >Fix: Here's the one from NetBSD, written by Adrian Mariano (adrian@cam.cornell.edu or mariano@geom.umn.edu). Installs no problem. [The only thing missing is the caveat in the bugs section of the man page (you know;, the one about not basing financial plans on the currency conversions :-)] -- Cut Here -- # This is a shell archive. Save it in a file, remove anything before # this line, and then unpack it by entering "sh file". Note, it may # create directories; files and directories will be owned by you and # have default permissions. # # This archive contains: # # Makefile # pathnames.h # README # units.1 # units.c # units.lib # echo x - Makefile sed 's/^X//' >Makefile << 'END-of-Makefile' X# $NetBSD: Makefile,v 1.2 1996/04/06 06:00:58 thorpej Exp $ X XPROG= units X Xbeforeinstall: X install -c -o ${BINOWN} -g ${BINGRP} -m 444 \ X ${.CURDIR}/units.lib ${DESTDIR}/usr/share/misc X X.include END-of-Makefile echo x - pathnames.h sed 's/^X//' >pathnames.h << 'END-of-pathnames.h' X/* $NetBSD: pathnames.h,v 1.3 1996/04/06 06:01:00 thorpej Exp $ */ X X/* X * Copyright (c) 1993 Christopher G. Demetriou X * All rights reserved. X * X * Redistribution and use in source and binary forms, with or without X * modification, are permitted provided that the following conditions X * are met: X * 1. Redistributions of source code must retain the above copyright X * notice, this list of conditions and the following disclaimer. X * 2. Redistributions in binary form must reproduce the above copyright X * notice, this list of conditions and the following disclaimer in the X * documentation and/or other materials provided with the distribution. X * 3. All advertising materials mentioning features or use of this software X * must display the following acknowledgement: X * This product includes software developed by Christopher G. Demetriou. X * 4. The name of the author may not be used to endorse or promote products X * derived from this software without specific prior written permission X * X * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR X * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES X * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. X * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, X * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT X * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, X * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY X * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT X * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF X * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. X */ X X#define _PATH_UNITSLIB "/usr/share/misc/units.lib" END-of-pathnames.h echo x - README sed 's/^X//' >README << 'END-of-README' X# $NetBSD: README,v 1.2 1996/04/06 06:00:59 thorpej Exp $ X XThis is a program which I wrote as a clone of the UNIX 'units' Xcommand. I threw it together in a couple days, but it seems to work, Xwith some restrictions. I have tested it under DOS with Borland C and XUltrix 4.2, and SunOS 4.1. X XThis program differs from the unix units program in the following Xways: X it can gracefully handle exponents larger than 9 in output X it uses 'e' to denote exponentiation in numbers X prefixes are listed in the units file X it tries both -s and -es plurals X it allows use of * for multiply and ^ for exponentiation in the input X the output format is somewhat different X XAdrian Mariano (adrian@cam.cornell.edu or mariano@geom.umn.edu) X END-of-README echo x - units.1 sed 's/^X//' >units.1 << 'END-of-units.1' X.\" $NetBSD: units.1,v 1.6 1996/04/06 06:01:02 thorpej Exp $ X.TH UNITS 1 "14 July 1993" X.SH NAME Xunits - conversion program X.SH SYNTAX X.B units X[-f filename] [-qv] [from-unit to-unit] X.SH SUMMARY X.TP 4 X.B -f filename XSpecifies the name of the units data file to load. X.LP X.TP 4 X.B -q XSuppresses prompting of the user for units and the display of statistics Xabout the number of units loaded. X.LP X.TP 4 X.B -v XPrints the version number. X.LP X.TP 4 X.B from-unit to-unit XAllows a single unit conversion to be done directly from the command Xline. No prompting will occur. The units program will print out Xonly the result of this single conversion. X X.SH DESCRIPTION XThe units program converts quantities expression in various scales to Xtheir equivalents in other scales. The units program can only Xhandle multiplicative scale changes. It cannot convert Centigrade Xto Fahrenheit, for example. It works interactively by prompting Xthe user for input: X.nf X X You have: meters X You want: feet X * 3.2808399 X / 0.3048 X X You have: cm^3 X You want: gallons X * 0.00026417205 X / 3785.4118 X X.fi XPowers of units can be specified using the '^' character as shown in Xthe example, or by simple concatenation: 'cm3' is equivalent to 'cm^3'. XMultiplication of units can be specified by using spaces, a dash or Xan asterisk. Division of units is indicated by the slash ('/'). XNote that multiplication has a higher precedence than division, Xso 'm/s/s' is the same as 'm/s^2' or 'm/s s'. XIf the user enters incompatible unit types, the units program will Xprint a message indicating that the units are not conformable and Xit will display the reduced form for each unit: X.nf X X You have: ergs/hour X You want: fathoms kg^2 / day X conformability error X 2.7777778e-11 kg m^2 / sec^3 X 2.1166667e-05 kg^2 m / sec X X.fi X.LP XThe conversion information is read from a units data file. The default Xfile includes definitions for most familiar units, abbreviations and Xmetric prefixes. Some constants of nature included are: X.in +4m X.ta X.ta 9m + X.nf X Xpi ratio of circumference to diameter Xc speed of light Xe charge on an electron Xg acceleration of gravity Xforce same as g Xmole Avogadro's number Xwater pressure per unit height of water Xmercury pressure per unit height of mercury Xau astronomical unit X X.fi X.in -4m X\'Pound' is a unit of mass. Compound names are run together Xso 'poundforce' is a unit of force. British units that differ from their XUS counterparts are prefixed with 'br', and currency is prefixed with Xits country name: 'belgiumfranc', 'britainpound'. When searching for Xa unit, if the specified string does not appear exactly as a unit Xname, then the units program will try to remove a trailing 's' or Xa trailing 'es' and check again for a match. X.LP XAll of these definitions can be read in the standard units file, or you Xcan supply your own file. A unit is specified on a single line by Xgiving its name and an equivalence. One should be careful to define Xnew units in terms of old ones so that a reduction leads to the Xprimitive units which are marked with '!' characters. XThe units program will not detect infinite loops that could be caused Xby careless unit definitions. X.LP XPrefixes are defined in the same was as standard units, but with Xa trailing dash at the end of the prefix name. X.SH BUGS X.LP XThe effect of including a '/' in a prefix is surprising. X.LP XExponents entered by the user can be only one digit. XYou can work around this by multiplying several terms. X.LP XThe user must use | to indicate division of numbers and / to Xindicate division of symbols. This distinction should not Xbe necessary. X.LP XThe program contains various arbitrary limits on the length Xof the units converted and on the length of the data file. X.LP XThe program should use a hash table to store units so that Xit doesn't take so long to load the units list and check Xfor duplication. X.SH FILES X/usr/share/misc/units.lib - the standard units library X.SH AUTHOR XAdrian Mariano (adrian@cam.cornell.edu or mariano@geom.umn.edu) END-of-units.1 echo x - units.c sed 's/^X//' >units.c << 'END-of-units.c' X/* $NetBSD: units.c,v 1.6 1996/04/06 06:01:03 thorpej Exp $ */ X X/* X * units.c Copyright (c) 1993 by Adrian Mariano (adrian@cam.cornell.edu) X * X * Redistribution and use in source and binary forms, with or without X * modification, are permitted provided that the following conditions X * are met: X * 1. Redistributions of source code must retain the above copyright X * notice, this list of conditions and the following disclaimer. X * 2. The name of the author may not be used to endorse or promote products X * derived from this software without specific prior written permission. X * Disclaimer: This software is provided by the author "as is". The author X * shall not be liable for any damages caused in any way by this software. X * X * I would appreciate (though I do not require) receiving a copy of any X * improvements you might make to this program. X */ X X#include X#include X#include X#include X X#include "pathnames.h" X X#define VERSION "1.0" X X#ifndef UNITSFILE X#define UNITSFILE _PATH_UNITSLIB X#endif X X#define MAXUNITS 1000 X#define MAXPREFIXES 50 X X#define MAXSUBUNITS 500 X X#define PRIMITIVECHAR '!' X Xchar *powerstring = "^"; X Xstruct { X char *uname; X char *uval; X} unittable[MAXUNITS]; X Xstruct unittype { X char *numerator[MAXSUBUNITS]; X char *denominator[MAXSUBUNITS]; X double factor; X}; X Xstruct { X char *prefixname; X char *prefixval; X} prefixtable[MAXPREFIXES]; X X Xchar *NULLUNIT = ""; X Xint unitcount; Xint prefixcount; X X Xchar * Xdupstr(char *str) X{ X char *ret; X X ret = malloc(strlen(str) + 1); X if (!ret) { X fprintf(stderr, "Memory allocation error\n"); X exit(3); X } X strcpy(ret, str); X return (ret); X} X X Xvoid Xreaderror(int linenum) X{ X fprintf(stderr, "Error in units file '%s' line %d\n", UNITSFILE, X linenum); X} X X Xvoid Xreadunits(char *userfile) X{ X FILE *unitfile; X char line[80], *lineptr; X int len, linenum, i; X X unitcount = 0; X linenum = 0; X X if (userfile) { X unitfile = fopen(userfile, "rt"); X if (!unitfile) { X fprintf(stderr, "Unable to open units file '%s'\n", X userfile); X exit(1); X } X } X else { X unitfile = fopen(UNITSFILE, "rt"); X if (!unitfile) { X char *direc, *env; X char filename[1000]; X char separator[2]; X X env = getenv("PATH"); X if (env) { X if (strchr(env, ';')) X strcpy(separator, ";"); X else X strcpy(separator, ":"); X direc = strtok(env, separator); X while (direc) { X strcpy(filename, ""); X strncat(filename, direc, 999); X strncat(filename, "/", X 999 - strlen(filename)); X strncat(filename, UNITSFILE, X 999 - strlen(filename)); X unitfile = fopen(filename, "rt"); X if (unitfile) X break; X direc = strtok(NULL, separator); X } X } X if (!unitfile) { X fprintf(stderr, "Can't find units file '%s'\n", X UNITSFILE); X exit(1); X } X } X } X while (!feof(unitfile)) { X if (!fgets(line, 79, unitfile)) X break; X linenum++; X lineptr = line; X if (*lineptr == '/') X continue; X lineptr += strspn(lineptr, " \n\t"); X len = strcspn(lineptr, " \n\t"); X lineptr[len] = 0; X if (!strlen(lineptr)) X continue; X if (lineptr[strlen(lineptr) - 1] == '-') { /* it's a prefix */ X if (prefixcount == MAXPREFIXES) { X fprintf(stderr, "Memory for prefixes exceeded in line %d\n", X linenum); X continue; X } X lineptr[strlen(lineptr) - 1] = 0; X prefixtable[prefixcount].prefixname = dupstr(lineptr); X for (i = 0; i < prefixcount; i++) X if (!strcmp(prefixtable[i].prefixname, lineptr)) { X fprintf(stderr, "Redefinition of prefix '%s' on line %d ignored\n", X lineptr, linenum); X continue; X } X lineptr += len + 1; X if (!strlen(lineptr)) { X readerror(linenum); X continue; X } X lineptr += strspn(lineptr, " \n\t"); X len = strcspn(lineptr, "\n\t"); X lineptr[len] = 0; X prefixtable[prefixcount++].prefixval = dupstr(lineptr); X } X else { /* it's not a prefix */ X if (unitcount == MAXUNITS) { X fprintf(stderr, "Memory for units exceeded in line %d\n", X linenum); X continue; X } X unittable[unitcount].uname = dupstr(lineptr); X for (i = 0; i < unitcount; i++) X if (!strcmp(unittable[i].uname, lineptr)) { X fprintf(stderr, "Redefinition of unit '%s' on line %d ignored\n", X lineptr, linenum); X continue; X } X lineptr += len + 1; X lineptr += strspn(lineptr, " \n\t"); X if (!strlen(lineptr)) { X readerror(linenum); X continue; X } X len = strcspn(lineptr, "\n\t"); X lineptr[len] = 0; X unittable[unitcount++].uval = dupstr(lineptr); X } X } X fclose(unitfile); X} X Xvoid Xinitializeunit(struct unittype * theunit) X{ X theunit->factor = 1.0; X theunit->numerator[0] = theunit->denominator[0] = NULL; X} X X Xint Xaddsubunit(char *product[], char *toadd) X{ X char **ptr; X X for (ptr = product; *ptr && *ptr != NULLUNIT; ptr++); X if (ptr >= product + MAXSUBUNITS) { X fprintf(stderr, "Memory overflow in unit reduction\n"); X return 1; X } X if (!*ptr) X *(ptr + 1) = 0; X *ptr = dupstr(toadd); X return 0; X} X X Xvoid Xshowunit(struct unittype * theunit) X{ X char **ptr; X int printedslash; X int counter = 1; X X printf("\t%.8g", theunit->factor); X for (ptr = theunit->numerator; *ptr; ptr++) { X if (ptr > theunit->numerator && **ptr && X !strcmp(*ptr, *(ptr - 1))) X counter++; X else { X if (counter > 1) X printf("%s%d", powerstring, counter); X if (**ptr) X printf(" %s", *ptr); X counter = 1; X } X } X if (counter > 1) X printf("%s%d", powerstring, counter); X counter = 1; X printedslash = 0; X for (ptr = theunit->denominator; *ptr; ptr++) { X if (ptr > theunit->denominator && **ptr && X !strcmp(*ptr, *(ptr - 1))) X counter++; X else { X if (counter > 1) X printf("%s%d", powerstring, counter); X if (**ptr) { X if (!printedslash) X printf(" /"); X printedslash = 1; X printf(" %s", *ptr); X } X counter = 1; X } X } X if (counter > 1) X printf("%s%d", powerstring, counter); X printf("\n"); X} X X Xvoid Xzeroerror() X{ X fprintf(stderr, "Unit reduces to zero\n"); X} X X/* X Adds the specified string to the unit. X Flip is 0 for adding normally, 1 for adding reciprocal. X X Returns 0 for successful addition, nonzero on error. X*/ X Xint Xaddunit(struct unittype * theunit, char *toadd, int flip) X{ X char *scratch, *savescr; X char *item; X char *divider, *slash; X int doingtop; X X savescr = scratch = dupstr(toadd); X for (slash = scratch + 1; *slash; slash++) X if (*slash == '-' && X (tolower(*(slash - 1)) != 'e' || X !strchr(".0123456789", *(slash + 1)))) X *slash = ' '; X slash = strchr(scratch, '/'); X if (slash) X *slash = 0; X doingtop = 1; X do { X item = strtok(scratch, " *\t\n/"); X while (item) { X if (strchr("0123456789.", *item)) { /* item is a number */ X double num; X X divider = strchr(item, '|'); X if (divider) { X *divider = 0; X num = atof(item); X if (!num) { X zeroerror(); X return 1; X } X if (doingtop ^ flip) X theunit->factor *= num; X else X theunit->factor /= num; X num = atof(divider + 1); X if (!num) { X zeroerror(); X return 1; X } X if (doingtop ^ flip) X theunit->factor /= num; X else X theunit->factor *= num; X } X else { X num = atof(item); X if (!num) { X zeroerror(); X return 1; X } X if (doingtop ^ flip) X theunit->factor *= num; X else X theunit->factor /= num; X X } X } X else { /* item is not a number */ X int repeat = 1; X X if (strchr("23456789", X item[strlen(item) - 1])) { X repeat = item[strlen(item) - 1] - '0'; X item[strlen(item) - 1] = 0; X } X for (; repeat; repeat--) X if (addsubunit(doingtop ^ flip ? theunit->numerator : theunit->denominator, item)) X return 1; X } X item = strtok(NULL, " *\t/\n"); X } X doingtop--; X if (slash) { X scratch = slash + 1; X } X else X doingtop--; X } while (doingtop >= 0); X free(savescr); X return 0; X} X X Xint Xcompare(const void *item1, const void *item2) X{ X return strcmp(*(char **) item1, *(char **) item2); X} X X Xvoid Xsortunit(struct unittype * theunit) X{ X char **ptr; X int count; X X for (count = 0, ptr = theunit->numerator; *ptr; ptr++, count++); X qsort(theunit->numerator, count, sizeof(char *), compare); X for (count = 0, ptr = theunit->denominator; *ptr; ptr++, count++); X qsort(theunit->denominator, count, sizeof(char *), compare); X} X X Xvoid Xcancelunit(struct unittype * theunit) X{ X char **den, **num; X int comp; X X den = theunit->denominator; X num = theunit->numerator; X X while (*num && *den) { X comp = strcmp(*den, *num); X if (!comp) { X/* if (*den!=NULLUNIT) free(*den); X if (*num!=NULLUNIT) free(*num);*/ X *den++ = NULLUNIT; X *num++ = NULLUNIT; X } X else if (comp < 0) X den++; X else X num++; X } X} X X X X X/* X Looks up the definition for the specified unit. X Returns a pointer to the definition or a null pointer X if the specified unit does not appear in the units table. X*/ X Xstatic char buffer[100]; /* buffer for lookupunit answers with X prefixes */ X Xchar * Xlookupunit(char *unit) X{ X int i; X char *copy; X X for (i = 0; i < unitcount; i++) { X if (!strcmp(unittable[i].uname, unit)) X return unittable[i].uval; X } X X if (unit[strlen(unit) - 1] == '^') { X copy = dupstr(unit); X copy[strlen(copy) - 1] = 0; X for (i = 0; i < unitcount; i++) { X if (!strcmp(unittable[i].uname, copy)) { X strcpy(buffer, copy); X free(copy); X return buffer; X } X } X free(copy); X } X if (unit[strlen(unit) - 1] == 's') { X copy = dupstr(unit); X copy[strlen(copy) - 1] = 0; X for (i = 0; i < unitcount; i++) { X if (!strcmp(unittable[i].uname, copy)) { X strcpy(buffer, copy); X free(copy); X return buffer; X } X } X if (copy[strlen(copy) - 1] == 'e') { X copy[strlen(copy) - 1] = 0; X for (i = 0; i < unitcount; i++) { X if (!strcmp(unittable[i].uname, copy)) { X strcpy(buffer, copy); X free(copy); X return buffer; X } X } X } X free(copy); X } X for (i = 0; i < prefixcount; i++) { X if (!strncmp(prefixtable[i].prefixname, unit, X strlen(prefixtable[i].prefixname))) { X unit += strlen(prefixtable[i].prefixname); X if (!strlen(unit) || lookupunit(unit)) { X strcpy(buffer, prefixtable[i].prefixval); X strcat(buffer, " "); X strcat(buffer, unit); X return buffer; X } X } X } X return 0; X} X X X X/* X reduces a product of symbolic units to primitive units. X The three low bits are used to return flags: X X bit 0 (1) set on if reductions were performed without error. X bit 1 (2) set on if no reductions are performed. X bit 2 (4) set on if an unknown unit is discovered. X*/ X X X#define ERROR 4 X Xint Xreduceproduct(struct unittype * theunit, int flip) X{ X X char *toadd; X char **product; X int didsomething = 2; X X if (flip) X product = theunit->denominator; X else X product = theunit->numerator; X X for (; *product; product++) { X X for (;;) { X if (!strlen(*product)) X break; X toadd = lookupunit(*product); X if (!toadd) { X printf("unknown unit '%s'\n", *product); X return ERROR; X } X if (strchr(toadd, PRIMITIVECHAR)) X break; X didsomething = 1; X if (*product != NULLUNIT) { X free(*product); X *product = NULLUNIT; X } X if (addunit(theunit, toadd, flip)) X return ERROR; X } X } X return didsomething; X} X X X/* X Reduces numerator and denominator of the specified unit. X Returns 0 on success, or 1 on unknown unit error. X*/ X Xint Xreduceunit(struct unittype * theunit) X{ X int ret; X X ret = 1; X while (ret & 1) { X ret = reduceproduct(theunit, 0) | reduceproduct(theunit, 1); X if (ret & 4) X return 1; X } X return 0; X} X X Xint Xcompareproducts(char **one, char **two) X{ X while (*one || *two) { X if (!*one && *two != NULLUNIT) X return 1; X if (!*two && *one != NULLUNIT) X return 1; X if (*one == NULLUNIT) X one++; X else if (*two == NULLUNIT) X two++; X else if (strcmp(*one, *two)) X return 1; X else X one++, two++; X } X return 0; X} X X X/* Return zero if units are compatible, nonzero otherwise */ X Xint Xcompareunits(struct unittype * first, struct unittype * second) X{ X return X compareproducts(first->numerator, second->numerator) || X compareproducts(first->denominator, second->denominator); X} X X Xint Xcompletereduce(struct unittype * unit) X{ X if (reduceunit(unit)) X return 1; X sortunit(unit); X cancelunit(unit); X return 0; X} X X Xvoid Xshowanswer(struct unittype * have, struct unittype * want) X{ X if (compareunits(have, want)) { X printf("conformability error\n"); X showunit(have); X showunit(want); X } X else X printf("\t* %.8g\n\t/ %.8g\n", have->factor / want->factor, X want->factor / have->factor); X} X X Xvoid Xusage() X{ X fprintf(stderr, "\nunits [-f unitsfile] [-q] [-v] [from-unit to-unit]\n"); X fprintf(stderr, "\n -f specify units file\n"); X fprintf(stderr, " -q supress prompting (quiet)\n"); X fprintf(stderr, " -v print version number\n"); X exit(3); X} X X Xint Xmain(int argc, char **argv) X{ X X struct unittype have, want; X char havestr[81], wantstr[81]; X int optchar; X char *userfile = 0; X int quiet = 0; X X extern char *optarg; X extern int optind; X X while ((optchar = getopt(argc, argv, "vqf:")) != -1) { X switch (optchar) { X case 'f': X userfile = optarg; X break; X case 'q': X quiet = 1; X break; X case 'v': X fprintf(stderr, "\n units version %s Copyright (c) 1993 by Adrian Mariano\n", X VERSION); X fprintf(stderr, " This program may be freely distributed\n"); X usage(); X default: X usage(); X break; X } X } X X if (optind != argc - 2 && optind != argc) X usage(); X X readunits(userfile); X X if (optind == argc - 2) { X strcpy(havestr, argv[optind]); X strcpy(wantstr, argv[optind + 1]); X initializeunit(&have); X addunit(&have, havestr, 0); X completereduce(&have); X initializeunit(&want); X addunit(&want, wantstr, 0); X completereduce(&want); X showanswer(&have, &want); X } X else { X if (!quiet) X printf("%d units, %d prefixes\n\n", unitcount, X prefixcount); X for (;;) { X do { X initializeunit(&have); X if (!quiet) X printf("You have: "); X if (!fgets(havestr, 80, stdin)) { X if (!quiet); X putchar('\n'); X exit(0); X } X } while (addunit(&have, havestr, 0) || X completereduce(&have)); X do { X initializeunit(&want); X if (!quiet) X printf("You want: "); X if (!fgets(wantstr, 80, stdin)) { X if (!quiet) X putchar('\n'); X exit(0); X } X } while (addunit(&want, wantstr, 0) || X completereduce(&want)); X showanswer(&have, &want); X } X } X} END-of-units.c echo x - units.lib sed 's/^X//' >units.lib << 'END-of-units.lib' X/ $NetBSD: units.lib,v 1.3 1996/04/06 06:01:04 thorpej Exp $ X X/ primitive units X Xm !a! Xkg !b! Xsec !c! Xcoul !d! Xcandela !e! Xdollar !f! Xbit !h! Xerlang !i! XK !j! X X/ prefixes X Xyotta- 1e24 Xzetta- 1e21 Xexa- 1e18 Xpeta- 1e15 Xtera- 1e12 Xgiga- 1e9 Xmega- 1e6 Xmyria- 1e4 Xkilo- 1e3 Xhecto- 1e2 Xdeka- 1e1 Xdeci- 1e-1 Xcenti- 1e-2 Xmilli- 1e-3 Xmicro- 1e-6 Xnano- 1e-9 Xpico- 1e-12 Xfemto- 1e-15 Xatto- 1e-18 Xzopto- 1e-21 Xyocto- 1e-24 X Xsemi- .5 Xdemi- .5 X XY- yotta XZ- zetta XE- exa XP- peta XT- tera XG- giga XM- mega Xk- kilo Xh- hecto Xda- deka Xd- deci Xc- centi Xm- milli Xp- pico Xf- femto Xa- atto Xz- zopto Xy- yocto X X/ constants X Xfuzz 1 Xpi 3.14159265358979323846 Xc 2.99792458e+8 m/sec fuzz Xg 9.80665 m/sec2 Xau 1.49597871e+11 m fuzz Xmole 6.022169e+23 fuzz Xe 1.6021917e-19 coul fuzz Xenergy c2 Xforce g Xmercury 1.33322e+5 kg/m2-sec2 Xhg mercury X X/ dimensionless X Xradian .5 / pi Xdegree 1|180 pi-radian Xcircle 2 pi-radian Xturn 2 pi-radian Xrevolution turn Xrev turn Xgrade .9 degree Xarcdeg 1 degree Xarcmin 1|60 arcdeg Xccs 1|36 erlang Xarcsec 1|60 arcmin X Xsteradian radian2 Xsphere 4 pi-steradian Xsr steradian X X/ Time X Xsecond sec Xs sec Xminute 60 sec Xmin minute Xhour 60 min Xhr hour Xday 24 hr Xda day Xweek 7 day Xyear 365.24219879 day fuzz Xyr year Xmonth 1|12 year Xms millisec Xus microsec X X/ Mass X Xgram millikg Xgm gram Xmg milligram Xmetricton kilokg X X/ Avoirdupois X Xlb .45359237 kg Xpound lb Xlbf lb g Xounce 1|16 lb Xoz ounce Xdram 1|16 oz Xdr dram Xgrain 1|7000 lb Xgr grain Xshortton 2000 lb Xton shortton Xlongton 2240 lb X X/ Apothecary X Xscruple 20 grain Xapdram 60 grain Xapounce 480 grain Xappound 5760 grain Xtroypound appound X X/ Length X Xmeter m Xcm centimeter Xmm millimeter Xkm kilometer Xnm nanometer Xmicron micrometer Xangstrom decinanometer X Xinch 2.54 cm Xin inch Xfoot 12 in Xfeet foot Xft foot Xyard 3 ft Xyd yard Xrod 5.5 yd Xrd rod Xmile 5280 ft Xmi mile X Xbritish 1200|3937 m/ft Xnmile 1852 m X Xacre 4840 yd2 X Xcc cm3 Xliter kilocc Xml milliliter X X/ US Liquid X Xgallon 231 in3 Ximperial 1.20095 Xgal gallon Xquart 1|4 gal Xqt quart Xpint 1|2 qt Xpt pint X Xfloz 1|16 pt Xfldr 1|8 floz X X/ US Dry X Xdry 268.8025 in3/gallon fuzz Xpeck 8 dry-quart Xpk peck Xbushel 4 peck Xbu bushel Xchaldron 36 bushel X X/ British X Xbrgallon 277.420 in3 fuzz Xbrquart 1|4 brgallon Xbrpint 1|2 brquart Xbrfloz 1|20 brpint Xbrpeck 554.84 in3 fuzz Xbrbushel 4 brpeck X X/ Energy Work X Xnewton kg-m/sec2 Xnt newton XN newton Xjoule nt-m Xcal 4.1868 joule X X/ Electrical X Xcoulomb coul XC coul Xampere coul/sec Xamp ampere Xwatt joule/sec Xvolt watt/amp Xohm volt/amp Xmho /ohm Xfarad coul/volt Xhenry sec2/farad Xweber volt-sec X X/ Light X Xcd candela Xlumen cd sr Xlux cd sr/m2 X X/ Wall Street Journal, July 2, 1993 X X$ dollar Xargentinapeso $ Xaustraliadollar .66 $ Xaustriaschilling .83 $ Xbahraindinar 2.6522 $ Xbelgiumfranc .028 $ Xbrazilcruzeiro .000019 $ Xbritainpound 1.49 $ Xcanadadollar .77 $ Xczechkoruna .034 $ Xchilepeso .0025 $ Xchinarenminbi .174856 $ Xcolombiapeso .001495 $ Xdenmarkkrone .15 $ Xecuadorsucre .000539 $ Xfinlandmarkka .17 $ Xfrancefranc .17 $ Xgermanymark .58 $ Xgreatbritainpound britainpound Xgreecedrachma .0043 $ Xhongkongdollar .13 $ Xhungaryforint .011 $ Xindiarupee .03211 $ Xindonesiarupiah .0004782 $ Xirelandpunt 1.43 $ Xisraelshekel .3642 $ Xitalylira .00064 $ Xjapanyen .0093 $ Xjordandinar 1.4682 $ Xkuwaitdinar 3.3173 $ Xlebanonpound .000578 $ Xmalaysiaringgit .338 $ Xmaltalira 2.6042 $ Xmexicopeso .3205128 $ Xnetherlandguilder .52 $ Xnewzealanddollar .539 $ Xnorwaykrone .139 $ Xpakistanrupee .037 $ Xperunewsol .5065 $ Xphilippinespeso .03738 $ Xpolandzloty .000059 $ Xportugalescudo .00617 $ Xsaudiarabiariyal .26702 $ Xsingaporedollar .6157 $ Xslovakkoruna .034 $ Xsouthamericarand .21 $ Xsouthkoreawon .001 $ Xspainpeseta .007 $ Xswedenkrona .13 $ Xswitzerlandfranc .66 $ Xtaiwandollar .038285 $ Xthailandbaht .03962 $ Xturkeylira .0000929 $ Xunitedarabdirham .2723 $ Xuruguaynewpeso .246852 $ Xvenezuelabolivar .011 $ X Xmark germanymark Xbolivar venezuelabolivar Xpeseta spainpeseta Xrand southafricarand Xescudo portugalescudo Xsol perusol Xguilder netherlandsguilder Xhollandguilder netherlandsguilder Xpeso mexicopeso Xyen japanyen Xlira italylira Xrupee indiarupee Xdrachma greecedrachma Xfranc francefranc Xmarkka finlandmarkka Xsucre ecuadorsucre Xpoundsterling britainpound Xcruzeiro brazilcruzeiro X X/ computer X Xbaud bit/sec Xbyte 8 bit Xblock 512 byte Xkbyte 1024 byte Xmegabyte 1024 kbyte Xgigabyte 1024 megabyte Xmeg megabyte X X X/ Trivia X X% 1|100 Xadmiraltyknot 6080 ft/hr Xapostilb cd/pi-m2 Xare 1e+2 m2 Xarpentcan 27.52 mi Xarpentlin 191.835 ft Xastronomicalunit au Xatmosphere 1.01325e+5 nt/m2 Xatm atmosphere Xatomicmassunit 1.66044e-27 kg fuzz Xamu atomicmassunit Xbag 94 lb Xbakersdozen 13 Xbar 1e+5 nt/m2 Xbarie 1e-1 nt/m2 Xbarleycorn 1|3 in Xbarn 1e-28 m2 Xbarrel 42 gal Xbarye 1e-1 nt/m2 Xbev 1e+9 e-volt Xbiot 10 amp Xblondel cd/pi-m2 Xboardfoot 144 in3 Xbolt 40 yd Xbottommeasure 1|40 in Xbritishthermalunit 1.05506e+3 joule fuzz Xbtu britishthermalunit Xrefrigeration 12000 btu/ton-hour Xbuck dollar Xcable 720 ft Xcaliber 1e-2 in Xcalorie cal Xcarat 205 mg Xcaratgold 1|24 Xcent centidollar Xcental 100 lb Xcentesimalminute 1e-2 grade Xcentesimalsecond 1e-4 grade Xcentury 100 year Xcfs ft3/sec Xchain 66 ft Xcircularinch 1|4 pi-in2 Xcircularmil 1e-6|4 pi-in2 Xclusec 1e-8 mm-hg m3/s Xcoomb 4 bu Xcord 128 ft3 Xcordfoot cord Xcrith 9.06e-2 gm Xcubit 18 in Xcup 1|2 pt Xcurie 3.7e+10 /sec Xdalton amu Xdecade 10 yr Xdipotre /m Xdisplacementton 35 ft3 Xdoppelzentner 100 kg Xdozen 12 Xdrop .03 cm3 Xdyne cm-gm/sec2 Xelectronvolt e-volt Xell 45 in Xengineerschain 100 ft Xengineerslink 100|100 ft Xequivalentfootcandle lumen/pi-ft2 Xequivalentlux lumen/pi-m2 Xequivalentphot cd/pi-cm2 Xerg cm2-gm/sec2 Xev e-volt Xfaraday 9.652e+4 coul Xfathom 6 ft Xfermi 1e-15 m Xfifth 4|5 qt Xfin 5 dollar Xfinger 7|8 in Xfirkin 9 gal Xfootcandle lumen/ft2 Xfootlambert cd/pi-ft2 Xfortnight 14 da Xfranklin 3.33564e-10 coul Xfrigorie kilocal Xfurlong 220 yd Xgalileo 1e-2 m/sec2 Xgamma 1e-9 weber/m2 Xgauss 1e-4 weber/m2 Xgeodeticfoot british-ft Xgeographicalmile 1852 m Xgilbert 7.95775e-1 amp Xgill 1|4 pt Xgross 144 Xgunterschain 22 yd Xhand 4 in Xhectare 1e+4 m2 Xhefnercandle .92 cd Xhertz /sec XHz hertz Xhogshead 2 barrel Xhd hogshead Xhomestead 1|4 mi2 Xhorsepower 550 ft-lb-g/sec Xhp horsepower Xhyl gm force sec2/m Xhz /sec Ximaginarycubicfoot 1.4 ft3 Xjeroboam 4|5 gal Xkarat 1|24 Xkcal kilocal Xkcalorie kilocal Xkev 1e+3 e-volt Xkey kg Xkhz 1e+3 /sec Xkilderkin 18 gal Xknot nmile/hr Xlambert cd/pi-cm2 Xlangley cal/cm2 Xlast 80 bu Xleague 3 mi Xlightyear c-yr Xline 1|12 in Xlink 66|100 ft Xlonghundredweight 112 lb Xlongquarter 28 lb Xlusec 1e-6 mm-hg m3/s Xmach 331.46 m/sec Xmagnum 2 qt Xmarineleague 3 nmile Xmaxwell 1e-8 weber Xmetriccarat 200 mg Xmgd megagal/day Xmh millihenry Xmhz 1e+6 /sec Xmil 1e-3 in Xmillenium 1000 year Xminersinch 1.5 ft3/min Xminim 1|60 fldr Xmo month Xmpg mile/gal Xmph mile/hr Xnail 1|16 yd Xnauticalmile nmile Xnit cd/m2 Xnoggin 1|8 qt Xnox 1e-3 lux Xns nanosec Xoersted 2.5e+2 pi-amp/m Xoe oersted Xpace 36 in Xpalm 3 in Xparasang 3.5 mi Xparsec au-radian/arcsec Xpascal nt/m2 Xpc parsec Xpennyweight 1|20 oz Xpwt pennyweight Xpercent % Xperch rd Xpf picofarad Xphot lumen/cm2 Xpica 1|6 in Xpieze 1e+3 nt/m2 Xpipe 4 barrel Xpoint 1|72 in Xpoise gm/cm-sec Xpole rd Xpoundal ft-lb/sec2 Xpdl poundal Xproof 1|200 Xpsi lb-g/in2 Xquarter 9 in Xquartersection 1|4 mi2 Xquintal 100 kg Xquire 25 Xrad 100 erg/gm Xream 500 Xregisterton 100 ft3 Xrehoboam 156 floz Xrhe 10 m2/nt-sec Xrontgen 2.58e-4 curie/kg Xrood 1.21e+3 yd Xrope 20 ft Xrutherford 1e+6 /sec Xrydberg 1.36054e+1 ev Xsabin 1 ft2 Xsack 3 bu Xseam 8 bu Xsection mi2 Xshippington 40 ft3 Xshorthundredweight 100 lb Xshortquarter 25 lb Xsiemens /ohm Xsigma microsec Xskein 120 yd Xskot 1e-3 apostilb Xslug lb-g-sec2/ft Xspan 9 in Xspat 4 pi sr Xspindle 14400 yd Xsquare 100 ft2 Xstere m3 Xsthene 1e+3 nt Xstilb cd/cm2 Xstoke 1e-4 m2/sec Xstone 14 lb Xstrike 2 bu Xsurveyfoot british-ft Xsurveyyard 3 surveyfoot Xsurveyorschain 66 ft Xsurveyorslink 66|100 ft Xtablespoon 4 fldr Xteaspoon 4|3 fldr Xtesla weber/m2 Xtherm 1e+5 btu Xthermie 1e+6 cal Xtimberfoot ft3 Xtnt 4.6e+6 m2/sec2 Xtonne 1e+6 gm Xtorr mm hg Xtownship 36 mi2 Xtun 8 barrel Xwater gram g / cc Xwey 40 bu Xweymass 252 lb XXunit 1.00202e-13 m Xk 1.38047e-16 erg/degC X X XdegC K Xkelvin K Xbrewster 1e-12 m2/newton XdegF 5|9 degC Xdegreesrankine degF Xdegrankine degreesrankine Xdegreerankine degF Xdegreaumur 10|8 degC Xdrachm 60 grain Xponcelet 100 kg m g / sec Xdenier .05|450 gram / m Xtex .001 gram / m Xenglishell 45 inch Xscottishell 37.2 inch Xflemishell 27 inch Xplanck 6.626e-34 joule-sec Xhbar 1.055e-34 joule-sec Xelectronmass 9.1095e-31 kg Xprotonmass 1.6726e-27 kg Xneutronmass 1.6606e-27 kg XV volt XeV e V Xbohrradius hbar2-C2/8.988e9 N m2-e2-electronmass Xbecquerel 1|3.7e10 curie Xfresnel 1e12 hertz Xstatcoul 1|2.99792458e9 coul Xstatamp 1|2.99792458e9 amp Xstatvolt 2.99792458e2 volt Xstatcoulomb statcoul Xstatampere statamp Xdebye 3.336e-30 coul-m Xpulsatance 2 pi/sec Xrpm rev/minute Xrps rev/sec Xkilohm kiloohm Xmegohm megaohm Xsiderealyear 365.256360417 day Xsiderealday 23.934469444 hour Xsiderealhour 1|24 sidereal day Xlunarmonth 29.5305555 day Xsynodicmonth lunarmonth Xsiderealmonth 27.32152777 day Xtropicalyear year Xsolaryear year Xlunaryear 12 lunarmonth Xcran 37.5 brgallon Xkip 1000 lbf Xfrenchfoot 16|15 ft Xfrenchfeet frenchfoot Xtoise 6 frenchfeet Xsievert 8.4 rontgen Xcandle 1.02 candela Xmilitarypace 2.5 feet Xmetre meter Xlitre liter Xgramme gram Xiudiptheria 62.8 microgram Xiupenicillin .6 microgram Xiuinsulin 41.67 microgram Xcottonyarncount 2520 ft/pound Xlinenyarncount 900 ft/pound Xworstedyarncount 1680 ft/pound Xmetricyarncount meter/gram Xjewlerspoint 2 milligram X END-of-units.lib exit >Audit-Trail: >Unformatted: