This repository was archived by the owner on Dec 27, 2020. It is now read-only.
forked from df7cb/postgresql-unit
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathunit.h
135 lines (105 loc) · 2.92 KB
/
unit.h
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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#ifndef _UNIT_H
#define _UNIT_H 1
#include <postgres.h>
#include <utils/hsearch.h>
/* indices */
#define UNIT_m 0 /* meter */
#define UNIT_kg 1 /* kilogram */
#define UNIT_s 2 /* second */
#define UNIT_A 3 /* ampere */
#define UNIT_K 4 /* kelvin */
#define UNIT_mol 5 /* mole */
#define UNIT_cd 6 /* candela */
#define UNIT_B 7 /* byte */
#define N_UNITS 8
/* defined units */
#define UNIT_NAME_LENGTH 32
/* longest unit names (without prefixes) observed in definitions.units:
* specificheat_glass_silica (25 chars)
* hardtranslucentarkansas (23 chars)
* venezuelanbolivarfuerte */
#define MIN_PLURAL_LENGTH 3
/* minimum length of input unit to consider stripping a trailing plural 's'
* lbs secs
*/
#define DBL_DIG 15
#define TIME_MINUTE 60
#define TIME_HOUR (60 * TIME_MINUTE)
#define TIME_DAY (24 * TIME_HOUR)
#define TIME_YEAR (365 * TIME_DAY)
#define TIME_YEAR_NAME "commonyear"
extern const char *base_units[N_UNITS]; /* names of base units */
struct derived_unit_t {
char *name;
signed char units[N_UNITS];
};
extern const struct derived_unit_t si_derived_units[];
/* type def */
typedef struct Unit {
double value;
signed char units[N_UNITS];
} Unit;
typedef struct UnitShift {
Unit unit;
double shift;
} UnitShift;
/* hash table and regex interface */
extern HTAB *unit_names;
typedef struct unit_names_t {
char name[UNIT_NAME_LENGTH];
UnitShift unit_shift;
} unit_names_t;
typedef struct unit_dimensions_t {
char units[N_UNITS];
char name[UNIT_NAME_LENGTH];
} unit_dimensions_t;
/* parser interface */
int unit_parse (char *s, UnitShift *unit); /* in unit.y */
char *unit_cstring (Unit *unit);
/* static functions */
/* test if two Units have the same dimension */
static inline void
test_same_dimension (char *op, Unit *a, Unit *b)
{
if (memcmp(a->units, b->units, N_UNITS))
ereport(ERROR,
(errcode(ERRCODE_DATA_EXCEPTION),
errmsg("dimension mismatch in \"%s\" operation: \"%s\", \"%s\"",
op, unit_cstring(a), unit_cstring(b))));
}
static inline void
unit_add_internal (Unit *a, Unit *b, Unit *result)
{
test_same_dimension("+", a, b);
result->value = a->value + b->value;
memcpy(result->units, a->units, N_UNITS);
}
static inline void
unit_sub_internal (Unit *a, Unit *b, Unit *result)
{
test_same_dimension("-", a, b);
result->value = a->value - b->value;
memcpy(result->units, a->units, N_UNITS);
}
static inline void
unit_mult_internal (Unit *a, Unit *b, Unit *result)
{
int i;
result->value = a->value * b->value;
for (i = 0; i < N_UNITS; i++)
result->units[i] = a->units[i] + b->units[i];
}
static inline void
unit_div_internal (Unit *a, Unit *b, Unit *result)
{
int i;
if (b->value == 0)
ereport(ERROR,
(errcode(ERRCODE_DIVISION_BY_ZERO),
errmsg("division by zero-valued unit: \"%s\"",
unit_cstring(b))));
result->value = a->value / b->value;
for (i = 0; i < N_UNITS; i++)
result->units[i] = a->units[i] - b->units[i];
}
#endif /* _UNIT_H */