summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregor Kleen <kleen@cip.ifi.lmu.de>2016-11-03 13:05:49 +0100
committerGregor Kleen <kleen@cip.ifi.lmu.de>2016-11-03 13:05:49 +0100
commit78603c50f61f74624218459ad6d8e212d36e681f (patch)
tree07e8472c192cdec09b3f86087a3f929ad3bc2e14
downloadsysprak.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--.gitignore1
-rw-r--r--Makefile15
-rw-r--r--default.nix10
-rw-r--r--temperaturUmrechner.c139
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 @@
1CC = gcc
2CCFLAGS = -owall
3INCLUDES =
4PREFIX = /usr/local
5
6.PHONY: all install
7
8all: temperaturUmrechner
9
10install:
11 mkdir -p $(PREFIX)/bin
12 install -m 0755 -t $(PREFIX)/bin temperaturUmrechner
13
14temperaterUmrechner:
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
4stdenv.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 */
8typedef enum TemperatureUnit { CELSIUS, DELISLE, FARENHEIT, KELVIN, RANKINE } TemperatureUnit;
9const TemperatureUnit temperatureUnits[] = { CELSIUS, DELISLE, FARENHEIT, KELVIN, RANKINE };
10const char* temperatureUnitNames[] = { "Celsius", "Delisle", "Farenheit", "Kelvin", "Rankine" };
11
12/* Conversion table to kelvin */
13const double kelvinMult[] = {1., -2. / 3., 5. / 9., 1, 5. / 9.};
14const double kelvinAdd[] = {273.15, 373.15, 255.37, 0, 0};
15
16static int const maxUnitLength = 31; // Maximum Length of members of temperatureUnitNames (not counting trailing \0)
17static int const unknownUnit = -1; // Ugh.
18
19void printUsage()
20{
21 printf("usage: temperaturUmrechner {-f|--from} <UNIT> {-t|--to} <UNIT> [<VALUE> [...]]\n"
22 );
23}
24
25TemperatureUnit 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
60double 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
83void 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}