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 | } | ||
