This source file includes following definitions.
- empty_input_string
- bad_input_string
- trailing_chars
- typical_case
- double_overflow
- double_underflow
- main
1 #include <float.h>
2 #include <math.h>
3
4 #include <glib.h>
5
6 #include <crm_internal.h>
7
8
9 #define LOCAL_BUF_SIZE 2 * DBL_MAX_10_EXP
10
11
12
13
14
15 #define ASSERT_DBL_EQ(d1, d2) g_assert_cmpfloat(fabs(d1 - d2), \
16 <, DBL_EPSILON);
17
18 static void
19 empty_input_string(void)
20 {
21 double result;
22
23
24 g_assert_cmpint(pcmk__scan_double(NULL, &result, NULL, NULL), ==, EINVAL);
25 ASSERT_DBL_EQ(result, PCMK__PARSE_DBL_DEFAULT);
26
27 g_assert_cmpint(pcmk__scan_double("", &result, NULL, NULL), ==, EINVAL);
28 ASSERT_DBL_EQ(result, PCMK__PARSE_DBL_DEFAULT);
29
30
31 g_assert_cmpint(pcmk__scan_double(NULL, &result, "2.0", NULL), ==,
32 pcmk_rc_ok);
33 ASSERT_DBL_EQ(result, 2.0);
34
35 g_assert_cmpint(pcmk__scan_double("", &result, "2.0", NULL), ==, EINVAL);
36 ASSERT_DBL_EQ(result, PCMK__PARSE_DBL_DEFAULT);
37 }
38
39 static void
40 bad_input_string(void)
41 {
42 double result;
43
44
45 g_assert_cmpint(pcmk__scan_double("asdf", &result, NULL, NULL), ==, EINVAL);
46 ASSERT_DBL_EQ(result, PCMK__PARSE_DBL_DEFAULT);
47
48 g_assert_cmpint(pcmk__scan_double("as2.0", &result, NULL, NULL), ==,
49 EINVAL);
50 ASSERT_DBL_EQ(result, PCMK__PARSE_DBL_DEFAULT);
51
52
53 g_assert_cmpint(pcmk__scan_double("asdf", &result, "2.0", NULL), ==,
54 EINVAL);
55 ASSERT_DBL_EQ(result, PCMK__PARSE_DBL_DEFAULT);
56
57 g_assert_cmpint(pcmk__scan_double("as2.0", &result, "2.0", NULL), ==,
58 EINVAL);
59 ASSERT_DBL_EQ(result, PCMK__PARSE_DBL_DEFAULT);
60 }
61
62 static void
63 trailing_chars(void)
64 {
65 double result;
66
67 g_assert_cmpint(pcmk__scan_double("2.0asdf", &result, NULL, NULL), ==,
68 pcmk_rc_ok);
69 ASSERT_DBL_EQ(result, 2.0);
70 }
71
72 static void
73 typical_case(void)
74 {
75 char str[LOCAL_BUF_SIZE];
76 double result;
77
78 g_assert_cmpint(pcmk__scan_double("0.0", &result, NULL, NULL), ==,
79 pcmk_rc_ok);
80 ASSERT_DBL_EQ(result, 0.0);
81
82 g_assert_cmpint(pcmk__scan_double("1.0", &result, NULL, NULL), ==,
83 pcmk_rc_ok);
84 ASSERT_DBL_EQ(result, 1.0);
85
86 g_assert_cmpint(pcmk__scan_double("-1.0", &result, NULL, NULL), ==,
87 pcmk_rc_ok);
88 ASSERT_DBL_EQ(result, -1.0);
89
90 snprintf(str, LOCAL_BUF_SIZE, "%f", DBL_MAX);
91 g_assert_cmpint(pcmk__scan_double(str, &result, NULL, NULL), ==,
92 pcmk_rc_ok);
93 ASSERT_DBL_EQ(result, DBL_MAX);
94
95 snprintf(str, LOCAL_BUF_SIZE, "%f", -DBL_MAX);
96 g_assert_cmpint(pcmk__scan_double(str, &result, NULL, NULL), ==,
97 pcmk_rc_ok);
98 ASSERT_DBL_EQ(result, -DBL_MAX);
99 }
100
101 static void
102 double_overflow(void)
103 {
104 char str[LOCAL_BUF_SIZE];
105 double result;
106
107
108
109
110
111 snprintf(str, LOCAL_BUF_SIZE, "1e%d", DBL_MAX_10_EXP + 1);
112 g_assert_cmpint(pcmk__scan_double(str, &result, NULL, NULL), ==, EOVERFLOW);
113 g_assert_cmpfloat(result, >, DBL_MAX);
114
115 snprintf(str, LOCAL_BUF_SIZE, "-1e%d", DBL_MAX_10_EXP + 1);
116 g_assert_cmpint(pcmk__scan_double(str, &result, NULL, NULL), ==, EOVERFLOW);
117 g_assert_cmpfloat(result, <, -DBL_MAX);
118 }
119
120 static void
121 double_underflow(void)
122 {
123 char str[LOCAL_BUF_SIZE];
124 double result;
125
126
127
128
129
130
131
132 snprintf(str, LOCAL_BUF_SIZE, "1e%d", DBL_MIN_10_EXP - 1);
133 g_assert_cmpint(pcmk__scan_double(str, &result, NULL, NULL), ==,
134 pcmk_rc_underflow);
135 g_assert_cmpfloat(result, >=, 0.0);
136 g_assert_cmpfloat(result, <=, DBL_MIN);
137
138 snprintf(str, LOCAL_BUF_SIZE, "-1e%d", DBL_MIN_10_EXP - 1);
139 g_assert_cmpint(pcmk__scan_double(str, &result, NULL, NULL), ==,
140 pcmk_rc_underflow);
141 g_assert_cmpfloat(result, <=, 0.0);
142 g_assert_cmpfloat(result, >=, -DBL_MIN);
143 }
144
145 int main(int argc, char **argv)
146 {
147 g_test_init(&argc, &argv, NULL);
148
149
150 g_test_add_func("/common/strings/double/empty_input", empty_input_string);
151 g_test_add_func("/common/strings/double/bad_input", bad_input_string);
152 g_test_add_func("/common/strings/double/trailing_chars", trailing_chars);
153
154
155 g_test_add_func("/common/strings/double/typical", typical_case);
156 g_test_add_func("/common/strings/double/overflow", double_overflow);
157 g_test_add_func("/common/strings/double/underflow", double_underflow);
158
159 return g_test_run();
160 }
161