summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--deg.c95
-rw-r--r--deg.man27
-rw-r--r--mkfile7
-rw-r--r--temp.c113
-rw-r--r--temp.man35
5 files changed, 277 insertions, 0 deletions
diff --git a/deg.c b/deg.c
new file mode 100644
index 0000000..8a480e3
--- /dev/null
+++ b/deg.c
@@ -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);
+}
diff --git a/deg.man b/deg.man
new file mode 100644
index 0000000..ee5706d
--- /dev/null
+++ b/deg.man
@@ -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.
diff --git a/mkfile b/mkfile
new file mode 100644
index 0000000..4b5bf3c
--- /dev/null
+++ b/mkfile
@@ -0,0 +1,7 @@
+</$objtype/mkfile
+
+BIN=/$objtype/bin/conv
+TARG=temp\
+ deg
+
+</sys/src/cmd/mkmany
diff --git a/temp.c b/temp.c
new file mode 100644
index 0000000..56bbe74
--- /dev/null
+++ b/temp.c
@@ -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 .