1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
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);
}
|