diff options
-rw-r--r-- | deg.c | 95 | ||||
-rw-r--r-- | deg.man | 27 | ||||
-rw-r--r-- | mkfile | 7 | ||||
-rw-r--r-- | temp.c | 113 | ||||
-rw-r--r-- | temp.man | 35 |
5 files changed, 277 insertions, 0 deletions
@@ -0,0 +1,95 @@ +#include <u.h> +#include <libc.h> + +typedef struct DMS DMS; +struct DMS +{ + vlong d; /* degrees (°) */ + vlong m; /* minutes (') */ + double s; /* seconds (") */ +}; + +#pragma varargck type "D" DMS +int +Dfmt(Fmt *f) +{ + DMS dms; + + dms = va_arg(f->args, DMS); + if(dms.d < 0){ + dms.m = -dms.m; + dms.s = -dms.s; + } + return fmtprint(f, "%lld°%lld'%g\"", dms.d, dms.m, dms.s); +} + +DMS +deg2dms(double deg) +{ + DMS dms; + + dms.d = deg; + deg -= dms.d; + dms.m = deg = deg*60; + deg -= dms.m; + dms.s = deg*60; + return dms; +} + +double +dms2deg(DMS dms) +{ + return dms.d + dms.m/60.0 + dms.s/3600.0; +} + +void +usage(void) +{ + fprint(2, "usage: %s deg\n", argv0); + exits("usage"); +} + +void +main(int argc, char *argv[]) +{ + DMS dms; + Rune r; + char *s; + double degs; + + fmtinstall('D', Dfmt); + ARGBEGIN{ + default: usage(); + }ARGEND; + if(argc != 1) + usage(); + s = argv[0]; + degs = strtod(s, &s); + if(*s != 0){ + memset(&dms, 0, sizeof(DMS)); + while(*s != 0){ + s += chartorune(&r, s); + switch(r){ + case L'°': + dms.d = degs; + degs = strtod(s, &s); + break; + case '\'': + dms.m = dms.d < 0? -degs: degs; + degs = strtod(s, &s); + break; + case '\"': + dms.s = dms.d < 0? -degs: degs; + break; + default: + sysfatal("unknown format"); + } + } + degs = dms2deg(dms); + print("%g°\n", degs); + }else{ + dms = deg2dms(degs); + print("%D\n", dms); + } + exits(0); +} @@ -0,0 +1,27 @@ +.TH DEG 1 +.SH NAME +deg \- degree format converter +.SH SYNOPSIS +.B conv/deg +.I degrees +.SH DESCRIPTION +.I Deg +is a format converter that translates from decimal to +sexagesimal +.B degrees +and vice versa. +.SH EXAMPLES +.IP +.EX +% conv/deg 25.243294234 +25°14'35.8592" + +% conv/deg 25°14''''35.8592" +25.2433° +.EE +.SH SOURCE +.B /sys/src/cmd/conv +.SH NOTES +Beware of +.IR rc(1) 's +quoting behavior. @@ -0,0 +1,7 @@ +</$objtype/mkfile + +BIN=/$objtype/bin/conv +TARG=temp\ + deg + +</sys/src/cmd/mkmany @@ -0,0 +1,113 @@ +#include <u.h> +#include <libc.h> + +enum { + C, /* celsius */ + F, /* fahrenheit */ + K /* kelvin */ +}; + +int iscale = F; +int oscale = C; + +double +c2f(double T) +{ + return T * 9/5 + 32; +} + +double +c2k(double T) +{ + return T + 273.15; +} + +double +f2c(double T) +{ + return (T-32) * 5/9; +} + +double +f2k(double T) +{ + return c2k(f2c(T)); +} + +double +k2c(double T) +{ + return T - 273.15; +} + +double +k2f(double T) +{ + return c2f(k2c(T)); +} + +double +ident(double T) +{ + return T; +} + +double (*convtab[3][3])(double) = { + [C][C] ident, + [C][F] c2f, + [C][K] c2k, + [F][C] f2c, + [F][F] ident, + [F][K] f2k, + [K][C] k2c, + [K][F] k2f, + [K][K] ident +}; + +int +getscale(char c) +{ + switch(c){ + case 'C': return C; + case 'F': return F; + case 'K': return K; + } + return -1; +} + +void +usage(void) +{ + fprint(2, "usage: %s [-i scale] [-o scale] temp\n", argv0); + exits("usage"); +} + +void +main(int argc, char *argv[]) +{ + char *s; + double iT, oT; + + ARGBEGIN{ + case 'i': + s = EARGF(usage()); + iscale = getscale(*s); + if(iscale < 0) + sysfatal("uknown input scale"); + break; + case 'o': + s = EARGF(usage()); + oscale = getscale(*s); + if(oscale < 0) + sysfatal("uknown output scale"); + break; + default: usage(); + }ARGEND; + + if(argc < 1) + usage(); + iT = strtod(*argv, nil); + oT = (*convtab[iscale][oscale])(iT); + print("%g\n", oT); + exits(0); +} diff --git a/temp.man b/temp.man new file mode 100644 index 0000000..4c3f6f1 --- /dev/null +++ b/temp.man @@ -0,0 +1,35 @@ +.TH TEMP 1 +.SH NAME +temp \- temperature converter +.SH SYNOPSIS +.B conv/temp +[ +.B -i +.I scale +] +[ +.B -o +.I scale +] +.I temp +.SH DESCRIPTION +.I Temp +is a basic temperature converter. +.PP +.I Scale +can be one of C(elsius), F(ahrenheit) and K(elvin). If none is +specified +.B temp +will use the default F for input, C for output scales. +.SH EXAMPLES +.PP +Convert from celsius to fahrenheit +.IP +.EX +% conv/temp -iC -oF 234.78 +454.604 +.EE +.SH SOURCE +.B /sys/src/cmd/conv +.SH BUGS +.IR none . |