diff options
author | Gregor Kleen <kleen@cip.ifi.lmu.de> | 2016-11-03 13:05:49 +0100 |
---|---|---|
committer | Gregor Kleen <kleen@cip.ifi.lmu.de> | 2016-11-03 13:05:49 +0100 |
commit | 78603c50f61f74624218459ad6d8e212d36e681f (patch) | |
tree | 07e8472c192cdec09b3f86087a3f929ad3bc2e14 | |
download | sysprak.exc-78603c50f61f74624218459ad6d8e212d36e681f.tar sysprak.exc-78603c50f61f74624218459ad6d8e212d36e681f.tar.gz sysprak.exc-78603c50f61f74624218459ad6d8e212d36e681f.tar.bz2 sysprak.exc-78603c50f61f74624218459ad6d8e212d36e681f.tar.xz sysprak.exc-78603c50f61f74624218459ad6d8e212d36e681f.zip |
temperaturUmrechner
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | Makefile | 15 | ||||
-rw-r--r-- | default.nix | 10 | ||||
-rw-r--r-- | temperaturUmrechner.c | 139 |
4 files changed, 165 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..41fbeb0 --- /dev/null +++ b/.gitignore | |||
@@ -0,0 +1 @@ | |||
**/result | |||
diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..ae2159d --- /dev/null +++ b/Makefile | |||
@@ -0,0 +1,15 @@ | |||
1 | CC = gcc | ||
2 | CCFLAGS = -owall | ||
3 | INCLUDES = | ||
4 | PREFIX = /usr/local | ||
5 | |||
6 | .PHONY: all install | ||
7 | |||
8 | all: temperaturUmrechner | ||
9 | |||
10 | install: | ||
11 | mkdir -p $(PREFIX)/bin | ||
12 | install -m 0755 -t $(PREFIX)/bin temperaturUmrechner | ||
13 | |||
14 | temperaterUmrechner: | ||
15 | $(CC) $(INCLUDES) $(CCFLAGS) -o temperaturUmrechner temperaturUmrechner.c | ||
diff --git a/default.nix b/default.nix new file mode 100644 index 0000000..665253c --- /dev/null +++ b/default.nix | |||
@@ -0,0 +1,10 @@ | |||
1 | { stdenv | ||
2 | }: | ||
3 | |||
4 | stdenv.mkDerivation { | ||
5 | name = "sysprak.exc"; | ||
6 | src = ./.; | ||
7 | preInstall = '' | ||
8 | sed -i s,/usr/local,$out, Makefile | ||
9 | ''; | ||
10 | } | ||
diff --git a/temperaturUmrechner.c b/temperaturUmrechner.c new file mode 100644 index 0000000..25ecc31 --- /dev/null +++ b/temperaturUmrechner.c | |||
@@ -0,0 +1,139 @@ | |||
1 | #include <stdlib.h> | ||
2 | #include <stdio.h> | ||
3 | #include <string.h> | ||
4 | #include <ctype.h> | ||
5 | #include <getopt.h> | ||
6 | |||
7 | /* Supported units and string conversion */ | ||
8 | typedef enum TemperatureUnit { CELSIUS, DELISLE, FARENHEIT, KELVIN, RANKINE } TemperatureUnit; | ||
9 | const TemperatureUnit temperatureUnits[] = { CELSIUS, DELISLE, FARENHEIT, KELVIN, RANKINE }; | ||
10 | const char* temperatureUnitNames[] = { "Celsius", "Delisle", "Farenheit", "Kelvin", "Rankine" }; | ||
11 | |||
12 | /* Conversion table to kelvin */ | ||
13 | const double kelvinMult[] = {1., -2. / 3., 5. / 9., 1, 5. / 9.}; | ||
14 | const double kelvinAdd[] = {273.15, 373.15, 255.37, 0, 0}; | ||
15 | |||
16 | static int const maxUnitLength = 31; // Maximum Length of members of temperatureUnitNames (not counting trailing \0) | ||
17 | static int const unknownUnit = -1; // Ugh. | ||
18 | |||
19 | void printUsage() | ||
20 | { | ||
21 | printf("usage: temperaturUmrechner {-f|--from} <UNIT> {-t|--to} <UNIT> [<VALUE> [...]]\n" | ||
22 | ); | ||
23 | } | ||
24 | |||
25 | TemperatureUnit parseUnit(char str[]) | ||
26 | { | ||
27 | char lowerUnit[maxUnitLength + 1]; | ||
28 | |||
29 | char lowerStr[maxUnitLength + 1]; | ||
30 | memset(lowerStr, '\0', maxUnitLength + 1); | ||
31 | strncpy(lowerStr, str, maxUnitLength); | ||
32 | |||
33 | for (int i = 0; i < maxUnitLength; i++) | ||
34 | { | ||
35 | if (lowerStr[i] == '\0') | ||
36 | break; | ||
37 | |||
38 | lowerStr[i] = tolower(lowerStr[i]); | ||
39 | } | ||
40 | |||
41 | |||
42 | for (int unit = 0; unit < (int)( sizeof(temperatureUnits) / sizeof(TemperatureUnit) ); unit++) | ||
43 | { | ||
44 | memset(lowerUnit, '\0', maxUnitLength + 1); | ||
45 | for (int i = 0; i < maxUnitLength; i++) | ||
46 | { | ||
47 | if (temperatureUnitNames[unit][i] == '\0') | ||
48 | break; | ||
49 | |||
50 | lowerUnit[i] = tolower(temperatureUnitNames[unit][i]); | ||
51 | } | ||
52 | |||
53 | if (strcmp(lowerUnit, lowerStr) == 0) | ||
54 | return temperatureUnits[unit]; | ||
55 | } | ||
56 | |||
57 | return unknownUnit; | ||
58 | } | ||
59 | |||
60 | double convert(double value, TemperatureUnit fromUnit, TemperatureUnit toUnit) | ||
61 | { | ||
62 | int fromUnitIndex = -1; | ||
63 | int toUnitIndex = -1; | ||
64 | |||
65 | for (int unit = 0; unit < (int)( sizeof(temperatureUnits) / sizeof(TemperatureUnit) ); unit++) | ||
66 | { | ||
67 | if (temperatureUnits[unit] == fromUnit) | ||
68 | fromUnitIndex = unit; | ||
69 | |||
70 | if (temperatureUnits[unit] == toUnit) | ||
71 | toUnitIndex = unit; | ||
72 | |||
73 | if (fromUnitIndex != -1 && toUnitIndex != -1) | ||
74 | break; | ||
75 | } | ||
76 | |||
77 | if (fromUnitIndex == -1 || toUnitIndex == -1) | ||
78 | abort(); | ||
79 | |||
80 | return (value * kelvinMult[fromUnitIndex] + kelvinAdd[fromUnitIndex]) / kelvinMult[toUnitIndex] - kelvinAdd[toUnitIndex]; | ||
81 | } | ||
82 | |||
83 | void main(int argc, char* argv[]) | ||
84 | { | ||
85 | TemperatureUnit fromUnit = unknownUnit; | ||
86 | TemperatureUnit toUnit = unknownUnit; | ||
87 | |||
88 | while (1) { | ||
89 | int c; | ||
90 | int optionIndex = 0; | ||
91 | |||
92 | static struct option longOptions[] = { | ||
93 | {"from", required_argument, 0, 'f'}, | ||
94 | {"to", required_argument, 0, 't'}, | ||
95 | {"help", no_argument, 0, 'h'}, | ||
96 | {0, 0, 0, 0} | ||
97 | }; | ||
98 | |||
99 | c = getopt_long(argc, argv, "f:t:h", longOptions, &optionIndex); | ||
100 | |||
101 | if (c == -1) | ||
102 | break; | ||
103 | |||
104 | switch (c) | ||
105 | { | ||
106 | case 'f': | ||
107 | fromUnit = parseUnit(optarg); | ||
108 | break; | ||
109 | case 't': | ||
110 | toUnit = parseUnit(optarg); | ||
111 | break; | ||
112 | case 'h': | ||
113 | printUsage(); | ||
114 | exit(0); | ||
115 | break; | ||
116 | default: | ||
117 | printUsage(); | ||
118 | } | ||
119 | } | ||
120 | |||
121 | if (fromUnit == unknownUnit) | ||
122 | fprintf(stderr, "Unknown (or unset) unit to convert from\n"); | ||
123 | if (toUnit == unknownUnit) | ||
124 | fprintf(stderr, "Unknown (or unset) unit to convert to\n"); | ||
125 | |||
126 | if (toUnit == unknownUnit || fromUnit == unknownUnit) | ||
127 | { | ||
128 | printUsage(); | ||
129 | exit(2); | ||
130 | } | ||
131 | |||
132 | for (double value;optind < argc;optind++) | ||
133 | { | ||
134 | sscanf(argv[optind], "%lf", &value); | ||
135 | printf("%.3g\n", convert(value, fromUnit, toUnit)); | ||
136 | } | ||
137 | |||
138 | exit(0); | ||
139 | } | ||