diff options
author | sjg <sjg@FreeBSD.org> | 2014-08-19 06:50:54 +0000 |
---|---|---|
committer | sjg <sjg@FreeBSD.org> | 2014-08-19 06:50:54 +0000 |
commit | d7cd1d425cc1ea9451fa235e3af9b6625c3e0de2 (patch) | |
tree | b04f4bd7cd887f50e7d98af35f46b9834ff86c80 /usr.bin/units | |
parent | 3c8e37b1d04827f33c0c9a7594bd1b1ef7cdb3d3 (diff) | |
parent | 4fbde208c6460d576f64d6dc3cdc6cab085a4283 (diff) | |
download | FreeBSD-src-d7cd1d425cc1ea9451fa235e3af9b6625c3e0de2.zip FreeBSD-src-d7cd1d425cc1ea9451fa235e3af9b6625c3e0de2.tar.gz |
Merge head from 7/28
Diffstat (limited to 'usr.bin/units')
-rw-r--r-- | usr.bin/units/Makefile | 10 | ||||
-rw-r--r-- | usr.bin/units/Makefile.depend | 2 | ||||
-rw-r--r-- | usr.bin/units/tests/Makefile | 9 | ||||
-rw-r--r-- | usr.bin/units/tests/basics_test.sh | 22 | ||||
-rw-r--r-- | usr.bin/units/units.1 | 32 | ||||
-rw-r--r-- | usr.bin/units/units.c | 147 | ||||
-rw-r--r-- | usr.bin/units/units.lib | 62 |
7 files changed, 191 insertions, 93 deletions
diff --git a/usr.bin/units/Makefile b/usr.bin/units/Makefile index ebd1e07..3757c85 100644 --- a/usr.bin/units/Makefile +++ b/usr.bin/units/Makefile @@ -1,10 +1,16 @@ # $FreeBSD$ +.include <src.opts.mk> + PROG= units FILES= units.lib FILESDIR= ${SHAREDIR}/misc -LDADD+=-ledit -ltermcap -DPADD+=${LIBEDIT} ${LIBTERMCAP} +LDADD+=-ledit -ltermcapw +DPADD+=${LIBEDIT} ${LIBTERMCAPW} + +.if ${MK_TESTS} != "no" +SUBDIR+= tests +.endif .include <bsd.prog.mk> diff --git a/usr.bin/units/Makefile.depend b/usr.bin/units/Makefile.depend index 6fc94a4..1ba7586 100644 --- a/usr.bin/units/Makefile.depend +++ b/usr.bin/units/Makefile.depend @@ -11,7 +11,7 @@ DIRDEPS = \ lib/libc \ lib/libcompiler_rt \ lib/libedit \ - lib/ncurses/ncurses \ + lib/ncurses/ncursesw \ .include <dirdeps.mk> diff --git a/usr.bin/units/tests/Makefile b/usr.bin/units/tests/Makefile new file mode 100644 index 0000000..0694eff --- /dev/null +++ b/usr.bin/units/tests/Makefile @@ -0,0 +1,9 @@ +# $FreeBSD$ + +.include <bsd.own.mk> + +TESTSDIR= ${TESTSBASE}/usr.bin/units + +TAP_TESTS_SH= basics_test + +.include <bsd.test.mk> diff --git a/usr.bin/units/tests/basics_test.sh b/usr.bin/units/tests/basics_test.sh new file mode 100644 index 0000000..adc28e0 --- /dev/null +++ b/usr.bin/units/tests/basics_test.sh @@ -0,0 +1,22 @@ +#!/bin/sh +# $FreeBSD$ + +base=`basename $0` + +echo "1..3" + +assert_equals() { + testnum="$1" + expected="$2" + fn="$3" + if [ "$expected" = "$($fn)" ] + then + echo "ok $testnum - $fn" + else + echo "not ok $testnum - $fn" + fi +} + +assert_equals 1 1 "units -t ft ft" +assert_equals 2 12 "units -t ft in" +assert_equals 3 0.083333333 "units -t in ft" diff --git a/usr.bin/units/units.1 b/usr.bin/units/units.1 index 83f2d9e..751d9ce 100644 --- a/usr.bin/units/units.1 +++ b/usr.bin/units/units.1 @@ -1,5 +1,5 @@ .\" $FreeBSD$ -.Dd April 14, 2014 +.Dd July 4, 2014 .Dt UNITS 1 .Os .Sh NAME @@ -13,17 +13,31 @@ .Sh OPTIONS The following options are available: .Bl -tag -width indent -.It Fl f Ar filename +.It Fl h No , Fl -help +Show an overview of options +.It Fl f Ar filename No , Fl -file Ar filename Specify the name of the units data file to load. -.It Fl q +.It Fl e , Fl -exponential +Behave as if -o '%6e' was typed. +.It Fl q No , Fl -quiet Suppress prompting of the user for units and the display of statistics about the number of units loaded. -.It Fl U -If the default unit file exists prints its location. If not, print +.It Fl U No , Fl -unitsfile +If the default unit file exists prints its location. +If not, print .Qo Units data file not found .Qc -.It Fl V +.It Fl t No , Fl -terse +Only print the result. This is used when calling +.Nm +from other programs for easy to parse results. +.It Fl v No , Fl -verbose +Print the units in the conversion output. +Be more verbose in general. +.It Fl o Ar format No , Fl -output-format Ar format +Select the output format string by which numbers are printed. +.It Fl V No , Fl -version Print the version number, usage, and then exit. .It Ar from-unit to-unit Allow a single unit conversion to be done directly from the command @@ -31,8 +45,6 @@ line. The program will not print prompts. It will print out the result of the single specified conversion. -.It Fl v -Print the units in the conversion output. Be more verbose in general. .El .Sh DESCRIPTION The @@ -141,7 +153,7 @@ The program will not detect infinite loops that could be caused by careless unit definitions. Comments in the unit definition file -begin with a '/' character at the beginning of a line. +begin with a '#' or '/' character at the beginning of a line. .Pp Prefixes are defined in the same was as standard units, but with a trailing dash at the end of the prefix name. @@ -170,7 +182,7 @@ units. the standard units library .El .Sh AUTHORS -.An Adrian Mariano Aq adrian@cam.cornell.edu +.An Adrian Mariano Aq Mt adrian@cam.cornell.edu .Sh BUGS The effect of including a '/' in a prefix is surprising. .Pp diff --git a/usr.bin/units/units.c b/usr.bin/units/units.c index 70bd9ec..3d39d0e 100644 --- a/usr.bin/units/units.c +++ b/usr.bin/units/units.c @@ -24,6 +24,7 @@ static const char rcsid[] = #include <err.h> #include <errno.h> #include <histedit.h> +#include <getopt.h> #include <stdbool.h> #include <stdio.h> #include <stdlib.h> @@ -68,19 +69,16 @@ static struct { static char NULLUNIT[] = ""; -#ifdef MSDOS -#define SEPARATOR ";" -#else #define SEPARATOR ":" -#endif static int unitcount; static int prefixcount; static bool verbose = false; +static bool terse = false; +static const char * outputformat; static const char * havestr; static const char * wantstr; - static int addsubunit(char *product[], char *toadd); static int addunit(struct unittype *theunit, const char *toadd, int flip, int quantity); static void cancelunit(struct unittype * theunit); @@ -106,20 +104,19 @@ static const char * prompt(EditLine *e __unused) { return promptstr; } -char * +static char * dupstr(const char *str) { char *ret; - ret = malloc(strlen(str) + 1); + ret = strdup(str); if (!ret) - errx(3, "memory allocation error"); - strcpy(ret, str); + err(3, "dupstr"); return (ret); } -void +static void readunits(const char *userfile) { FILE *unitfile; @@ -166,7 +163,7 @@ readunits(const char *userfile) break; linenum++; lineptr = line; - if (*lineptr == '/') + if (*lineptr == '/' || *lineptr == '#') continue; lineptr += strspn(lineptr, " \n\t"); len = strcspn(lineptr, " \n\t"); @@ -224,7 +221,7 @@ readunits(const char *userfile) fclose(unitfile); } -void +static void initializeunit(struct unittype * theunit) { theunit->numerator[0] = theunit->denominator[0] = NULL; @@ -234,7 +231,7 @@ initializeunit(struct unittype * theunit) } -int +static int addsubunit(char *product[], char *toadd) { char **ptr; @@ -251,7 +248,7 @@ addsubunit(char *product[], char *toadd) } -void +static void showunit(struct unittype * theunit) { char **ptr; @@ -293,7 +290,7 @@ showunit(struct unittype * theunit) counter = 1; } } - if ( counter > 1) + if (counter > 1) printf("%s%d", powerstring, counter); printf("\n"); } @@ -313,7 +310,7 @@ zeroerror(void) Returns 0 for successful addition, nonzero on error. */ -int +static int addunit(struct unittype * theunit, const char *toadd, int flip, int quantity) { char *scratch, *savescr; @@ -421,14 +418,14 @@ addunit(struct unittype * theunit, const char *toadd, int flip, int quantity) } -int +static int compare(const void *item1, const void *item2) { return strcmp(*(const char * const *)item1, *(const char * const *)item2); } -void +static void sortunit(struct unittype * theunit) { char **ptr; @@ -549,7 +546,7 @@ lookupunit(const char *unit) #define ERROR 4 -int +static int reduceproduct(struct unittype * theunit, int flip) { @@ -592,7 +589,7 @@ reduceproduct(struct unittype * theunit, int flip) Returns 0 on success, or 1 on unknown unit error. */ -int +static int reduceunit(struct unittype * theunit) { int ret; @@ -607,7 +604,7 @@ reduceunit(struct unittype * theunit) } -int +static int compareproducts(char **one, char **two) { while (*one || *two) { @@ -630,7 +627,7 @@ compareproducts(char **one, char **two) /* Return zero if units are compatible, nonzero otherwise */ -int +static int compareunits(struct unittype * first, struct unittype * second) { return @@ -639,7 +636,7 @@ compareunits(struct unittype * first, struct unittype * second) } -int +static int completereduce(struct unittype * unit) { if (reduceunit(unit)) @@ -649,32 +646,40 @@ completereduce(struct unittype * unit) return 0; } -void +static void showanswer(struct unittype * have, struct unittype * want) { double ans; + char* oformat; if (compareunits(have, want)) { printf("conformability error\n"); if (verbose) printf("\t%s = ", havestr); - else + else if (!terse) printf("\t"); showunit(have); - if (verbose) - printf("\t%s = ", wantstr); - else - printf("\t"); - showunit(want); + if (!terse) { + if (verbose) + printf("\t%s = ", wantstr); + else + printf("\t"); + showunit(want); + } } else if (have->offset != want->offset) { if (want->quantity) printf("WARNING: conversion of non-proportional quantities.\n"); - if (have->quantity) - printf("\t%.8g\n", + if (have->quantity) { + asprintf(&oformat, "\t%s\n", outputformat); + printf(oformat, (have->factor + have->offset-want->offset)/want->factor); + free(oformat); + } else { - printf("\t (-> x*%.8g %+.8g)\n\t (<- y*%.8g %+.8g)\n", + asprintf(&oformat, "\t (-> x*%sg %sg)\n\t (<- y*%sg %sg)\n", + outputformat, outputformat, outputformat, outputformat); + printf(oformat, have->factor / want->factor, (have->offset-want->offset)/want->factor, want->factor / have->factor, @@ -683,20 +688,38 @@ showanswer(struct unittype * have, struct unittype * want) } else { ans = have->factor / want->factor; - if (verbose) - printf("\t%s = %.8g * %s\n", havestr, ans, wantstr); - else - printf("\t* %.8g\n", ans); - if (verbose) - printf("\t%s = (1 / %.8g) * %s\n", havestr, 1/ans, wantstr); - else - printf("\t/ %.8g\n", 1/ans); + if (verbose) { + printf("\t%s = ", havestr); + printf(outputformat, ans); + printf(" * %s", wantstr); + printf("\n"); + } + else if (terse) { + printf(outputformat, ans); + printf("\n"); + } + else { + printf("\t* "); + printf(outputformat, ans); + printf("\n"); + } + + if (verbose) { + printf("\t%s = (1 / ", havestr); + printf(outputformat, 1/ans); + printf(") * %s\n", wantstr); + } + else if (!terse) { + printf("\t/ "); + printf(outputformat, 1/ans); + printf("\n"); + } } } -void +static void usage(void) { fprintf(stderr, @@ -704,6 +727,19 @@ usage(void) exit(3); } +static struct option longopts[] = { + {"help", no_argument, NULL, 'h'}, + {"exponential", no_argument, NULL, 'e'}, + {"file", required_argument, NULL, 'f'}, + {"output-format", required_argument, NULL, 'o'}, + {"quiet", no_argument, NULL, 'q'}, + {"terse", no_argument, NULL, 't'}, + {"unitsfile", no_argument, NULL, 'U'}, + {"verbose", no_argument, NULL, 'v'}, + {"version", no_argument, NULL, 'V'}, + { 0, 0, 0, 0 } +}; + int main(int argc, char **argv) @@ -720,8 +756,12 @@ main(int argc, char **argv) quiet = false; readfile = false; - while ((optchar = getopt(argc, argv, "fqvUV:")) != -1) { + outputformat = "%.8g"; + while ((optchar = getopt_long(argc, argv, "+ehf:oqtvUV", longopts, NULL)) != -1) { switch (optchar) { + case 'e': + outputformat = "%6e"; + break; case 'f': readfile = true; if (strlen(optarg) == 0) @@ -732,9 +772,18 @@ main(int argc, char **argv) case 'q': quiet = true; break; + case 't': + terse = true; + break; + case 'o': + outputformat = optarg; + break; case 'v': verbose = true; break; + case 'V': + fprintf(stderr, "FreeBSD units\n"); + /* FALLTHROUGH */ case 'U': if (access(UNITSFILE, F_OK) == 0) printf("%s\n", UNITSFILE); @@ -742,10 +791,9 @@ main(int argc, char **argv) printf("Units data file not found"); exit(0); break; - case 'V': - fprintf(stderr, "FreeBSD units\n"); - usage(); - break; + case 'h': + /* FALLTHROUGH */ + default: usage(); } @@ -763,7 +811,7 @@ main(int argc, char **argv) el_source(el, NULL); history(inhistory, &ev, H_SETSIZE, 800); if (inhistory == 0) - err(1, "Could not initalize history"); + err(1, "Could not initialize history"); if (cap_enter() < 0 && errno != ENOSYS) err(1, "unable to enter capability mode"); @@ -813,5 +861,6 @@ main(int argc, char **argv) } history_end(inhistory); - return(0); + el_end(el); + return (0); } diff --git a/usr.bin/units/units.lib b/usr.bin/units/units.lib index 4c48322..3efafd8 100644 --- a/usr.bin/units/units.lib +++ b/usr.bin/units/units.lib @@ -1,6 +1,6 @@ -/ $FreeBSD$ +# $FreeBSD$ -/ primitive units +# primitive units m !a! kg !b! @@ -13,7 +13,7 @@ bit !h! erlang !i! K !j! -/ prefixes +# prefixes yotta- 1e24 zetta- 1e21 @@ -68,7 +68,7 @@ a- atto z- zopto y- yocto -/ binary prefixes introduced in 1999 +# binary prefixes introduced in 1999 exbi- 1152921504606846976 pebi- 1125899906842624 tebi- 1099511627776 @@ -83,7 +83,7 @@ Gi- gibi Mi- mebi Ki- kibi -/ constants +# constants fuzz 1 pi 3.14159265358979323846 @@ -109,7 +109,7 @@ electronmass 9.1093821545-31 kg protonmass 1.6726217129-27 kg neutronmass 1.6749272928-27 kg -/ dimensionless +# dimensionless radian .5 / pi degree 1|180 pi-radian @@ -127,7 +127,7 @@ steradian radian2 sphere 4 pi-steradian sr steradian -/ Time +# Time second sec s sec @@ -143,13 +143,13 @@ yr year month 1|12 year us microsec -/ Mass +# Mass gram millikg gm gram metricton kilokg -/ Avoirdupois +# Avoirdupois lb .45359237 kg pound lb @@ -164,7 +164,7 @@ shortton 2000 lb ton shortton longton 2240 lb -/ Apothecary +# Apothecary scruple 20 grain apdram 60 grain @@ -172,7 +172,7 @@ apounce 480 grain appound 5760 grain troypound appound -/ Mining +# Mining troyounce apounce troz apounce @@ -180,7 +180,7 @@ pennyweight 1|20 troz pwt pennyweight dwt pennyweight -/ Length +# Length meter m micron micrometer @@ -208,7 +208,7 @@ cc cm3 liter kilocc ml milliliter -/ US Liquid +# US Liquid gallon 231 in3 imperial 1.20095 @@ -222,7 +222,7 @@ floz 1|16 pt fldr 1|8 floz shot 3|2 floz -/ US Dry +# US Dry dry 268.8025 in3/gallon fuzz peck 8 dry-quart @@ -231,7 +231,7 @@ bushel 4 peck bu bushel chaldron 36 bushel -/ British +# British brgallon 277.420 in3 fuzz brquart 1|4 brgallon @@ -241,10 +241,10 @@ brpeck 554.84 in3 fuzz brbushel 4 brpeck brhundredweight 112 lb -/ Bottles +# Bottles bottle 750 milliliter -/bottle fifth +#bottle fifth miniature 100 milliliter split 1|4 bottle @@ -258,7 +258,7 @@ balthazar 16 bottle nebuchadnezzar 20 bottle sovereign 34 bottle -/ Bottles - alternate names and spellings +# Bottles - alternate names and spellings pony split fillette half @@ -266,7 +266,7 @@ tappit-hen 3 imperial rheoboam rehoboam shalmaneser salmanazar -/ Russian +# Russian berkovets 10 pood pood 40 funt funt 0.40951 kg @@ -279,7 +279,7 @@ verst 1066.8 m sazhen 1|500 verst kosayasazhen 1|430.2 verst arshin 1|1500 verst -/ is not exactly defined +# is not exactly defined ruell 16.54 in liniya 1|10 in vershok 1.75 in @@ -296,7 +296,7 @@ sqverst 104.2 desyatina_state sqarshin 1|21600 desyatina_state sqfoot 1|117600 desyatina_state -/ Energy Work +# Energy Work newton kg-m/sec2 nt newton @@ -306,7 +306,7 @@ J joule cal 4.1868 joule ergon erg -/ Electrical +# Electrical coulomb coul C coul @@ -325,14 +325,14 @@ H henry weber volt-sec Wb weber -/ Light +# Light cd candela lumen cd sr lux cd sr/m2 -/ EMU currencies have constant exchange rate against Euro since 1.1.1999. -/ See http://en.wikipedia.org/wiki/Euro for details. +# EMU currencies have constant exchange rate against Euro since 1.1.1999. +# See http://en.wikipedia.org/wiki/Euro for details. austriaschilling 1|13.7603 euro belgiumfranc 1|40.3399 euro finlandmarkka 1|5.94573 euro @@ -350,8 +350,8 @@ cypriotpound 1|0.585274 euro malteselira 1|0.429300 euro slovakkoruna 1|30.1260 euro -/ These ones are pegged to the Euro -/ See http://en.wikipedia.org/wiki/Euro for details. +# These ones are pegged to the Euro +# See http://en.wikipedia.org/wiki/Euro for details. bosniaherzegovinamark 1|1.95583 euro bulgarianlev 1|1.95583 euro capeverdeanescudo 1|110.265 euro @@ -363,8 +363,8 @@ lithuanianlitas 1|3.45280 euro pacificfrancexchange 1|0.00838 euro westafricancfafranc 1|655.957 euro -/ These ones are pegged on the US Dollar -/ See http://en.wikipedia.org/wiki/USD for details. +# These ones are pegged on the US Dollar +# See http://en.wikipedia.org/wiki/USD for details. dollar usdollar arubanflorin 1|1.75 usdollar bahamiandollar 1|1 usdollar @@ -404,7 +404,7 @@ markka finlandmarkka peseta spainpeseta rand southafricarand -/ computer +# computer baud bit/sec nibble 4 bit @@ -424,7 +424,7 @@ kilobyte kbyte meg megabyte -/ Trivia +# Trivia % 1|100 abampere 10 ampere |