summaryrefslogtreecommitdiff
path: root/temp.c
blob: 56bbe745b77b3f31406db6a1df436ce9d410f4ee (plain)
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);
}