1 /*
2  * Copyright (C) 2013 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <inttypes.h>
18 
19 #include <errno.h>
20 #include <gtest/gtest.h>
21 #include <stdio.h>
22 
23 #include "utils.h"
24 
25 #define PRINTF_TYPED(FMT_SUFFIX, TYPE_SUFFIX) \
26   do { \
27     char buf[512]; \
28     memset(buf, 0, sizeof(buf)); \
29     snprintf(buf, sizeof(buf), "%" PRId##FMT_SUFFIX, int##TYPE_SUFFIX(123)); \
30     EXPECT_STREQ("123", buf); \
31     memset(buf, 0, sizeof(buf)); \
32     snprintf(buf, sizeof(buf), "%" PRIi##FMT_SUFFIX, int##TYPE_SUFFIX(123)); \
33     EXPECT_STREQ("123", buf); \
34     memset(buf, 0, sizeof(buf)); \
35     snprintf(buf, sizeof(buf), "%" PRIo##FMT_SUFFIX, int##TYPE_SUFFIX(123)); \
36     EXPECT_STREQ("173", buf); \
37     memset(buf, 0, sizeof(buf)); \
38     snprintf(buf, sizeof(buf), "%" PRIu##FMT_SUFFIX, uint##TYPE_SUFFIX(123)); \
39     EXPECT_STREQ("123", buf); \
40     memset(buf, 0, sizeof(buf)); \
41     snprintf(buf, sizeof(buf), "%" PRIx##FMT_SUFFIX, uint##TYPE_SUFFIX(123)); \
42     EXPECT_STREQ("7b", buf); \
43     memset(buf, 0, sizeof(buf)); \
44     snprintf(buf, sizeof(buf), "%" PRIX##FMT_SUFFIX, uint##TYPE_SUFFIX(123)); \
45     EXPECT_STREQ("7B", buf); \
46   } while (false) \
47 
48 #define PRINTF_SIZED(WIDTH) \
49   PRINTF_TYPED(WIDTH, WIDTH##_t); \
50   PRINTF_TYPED(FAST##WIDTH, _fast##WIDTH##_t); \
51   PRINTF_TYPED(LEAST##WIDTH, _least##WIDTH##_t) \
52 
53 
54 #define SCANF_TYPED(FMT_SUFFIX, TYPE_SUFFIX) \
55   do { \
56     int##TYPE_SUFFIX dst_int##TYPE_SUFFIX = 0; \
57     uint##TYPE_SUFFIX dst_uint##TYPE_SUFFIX = 0u; \
58     \
59     sscanf("123", "%" SCNd##FMT_SUFFIX, &dst_int##TYPE_SUFFIX); \
60     EXPECT_EQ(123, dst_int##TYPE_SUFFIX); \
61     dst_int##TYPE_SUFFIX = 0; \
62     sscanf("123", "%" SCNi##FMT_SUFFIX, &dst_int##TYPE_SUFFIX); \
63     EXPECT_EQ(123, dst_int##TYPE_SUFFIX); \
64     dst_int##TYPE_SUFFIX = 0; \
65     sscanf("173", "%" SCNo##FMT_SUFFIX, &dst_int##TYPE_SUFFIX); \
66     EXPECT_EQ(123, dst_int##TYPE_SUFFIX); \
67     dst_int##TYPE_SUFFIX = 0; \
68     sscanf("123", "%" SCNu##FMT_SUFFIX, &dst_uint##TYPE_SUFFIX); \
69     EXPECT_EQ(123u, dst_uint##TYPE_SUFFIX); \
70     dst_uint##TYPE_SUFFIX = 0; \
71     sscanf("7B", "%" SCNx##FMT_SUFFIX, &dst_uint##TYPE_SUFFIX); \
72     EXPECT_EQ(123u, dst_uint##TYPE_SUFFIX); \
73     dst_uint##TYPE_SUFFIX = 0; \
74   } while (false) \
75 
76 #define SCANF_SIZED(SIZE) \
77   SCANF_TYPED(SIZE, SIZE##_t); \
78   SCANF_TYPED(FAST##SIZE, _fast##SIZE##_t); \
79   SCANF_TYPED(LEAST##SIZE, _least##SIZE##_t) \
80 
81 
TEST(inttypes,printf_macros)82 TEST(inttypes, printf_macros) {
83   PRINTF_SIZED(8);
84   PRINTF_SIZED(16);
85   PRINTF_SIZED(32);
86   PRINTF_SIZED(64);
87 
88   PRINTF_TYPED(MAX, max_t);
89   PRINTF_TYPED(PTR, ptr_t);
90 }
91 
TEST(inttypes,scanf_macros)92 TEST(inttypes, scanf_macros) {
93   SCANF_SIZED(8);
94   SCANF_SIZED(16);
95   SCANF_SIZED(32);
96   SCANF_SIZED(64);
97 
98   SCANF_TYPED(MAX, max_t);
99   SCANF_TYPED(PTR, ptr_t);
100 }
101 
TEST(inttypes,wcstoimax)102 TEST(inttypes, wcstoimax) {
103   wchar_t* end = nullptr;
104   EXPECT_EQ(123, wcstoimax(L"  +123x", &end, 10));
105   EXPECT_EQ(L'x', *end);
106 }
107 
TEST(inttypes,wcstoumax)108 TEST(inttypes, wcstoumax) {
109   wchar_t* end = nullptr;
110   EXPECT_EQ(123U, wcstoumax(L"  +123x", &end, 10));
111   EXPECT_EQ(L'x', *end);
112 }
113 
TEST(inttypes,strtoimax_dec)114 TEST(inttypes, strtoimax_dec) {
115   char* p;
116   EXPECT_EQ(-18737357, strtoimax("-18737357foobar12", &p, 10));
117   EXPECT_STREQ("foobar12", p);
118 }
119 
TEST(inttypes,strtoimax_hex)120 TEST(inttypes, strtoimax_hex) {
121   char* p;
122   EXPECT_EQ(-0x18737357f, strtoimax("-18737357foobar12", &p, 16));
123   EXPECT_STREQ("oobar12", p);
124 }
125 
TEST(inttypes,strtoimax_EINVAL)126 TEST(inttypes, strtoimax_EINVAL) {
127   errno = 0;
128   strtoimax("123", nullptr, -1);
129   ASSERT_ERRNO(EINVAL);
130   errno = 0;
131   strtoimax("123", nullptr, 1);
132   ASSERT_ERRNO(EINVAL);
133   errno = 0;
134   strtoimax("123", nullptr, 37);
135   ASSERT_ERRNO(EINVAL);
136 }
137 
TEST(inttypes,strtoumax_dec)138 TEST(inttypes, strtoumax_dec) {
139   char* p;
140   EXPECT_EQ(18737357U, strtoumax("18737357foobar12", &p, 10));
141   EXPECT_STREQ("foobar12", p);
142 }
143 
TEST(inttypes,strtoumax_hex)144 TEST(inttypes, strtoumax_hex) {
145   char* p;
146   EXPECT_EQ(0x18737357fU, strtoumax("18737357foobar12", &p, 16));
147   EXPECT_STREQ("oobar12", p);
148 }
149 
TEST(inttypes,strtoumax_negative)150 TEST(inttypes, strtoumax_negative) {
151   char* p;
152   EXPECT_EQ(UINTMAX_MAX - 18737357 + 1, strtoumax("-18737357foobar12", &p, 10));
153   EXPECT_STREQ("foobar12", p);
154 }
155 
TEST(inttypes,strtoumax_EINVAL)156 TEST(inttypes, strtoumax_EINVAL) {
157   errno = 0;
158   strtoumax("123", nullptr, -1);
159   ASSERT_ERRNO(EINVAL);
160   errno = 0;
161   strtoumax("123", nullptr, 1);
162   ASSERT_ERRNO(EINVAL);
163   errno = 0;
164   strtoumax("123", nullptr, 37);
165   ASSERT_ERRNO(EINVAL);
166 }
167 
TEST(inttypes,wcstoimax_EINVAL)168 TEST(inttypes, wcstoimax_EINVAL) {
169   errno = 0;
170   wcstoimax(L"123", nullptr, -1);
171   ASSERT_ERRNO(EINVAL);
172   errno = 0;
173   wcstoimax(L"123", nullptr, 1);
174   ASSERT_ERRNO(EINVAL);
175   errno = 0;
176   wcstoimax(L"123", nullptr, 37);
177   ASSERT_ERRNO(EINVAL);
178 }
179 
TEST(inttypes,wcstoumax_EINVAL)180 TEST(inttypes, wcstoumax_EINVAL) {
181   errno = 0;
182   wcstoumax(L"123", nullptr, -1);
183   ASSERT_ERRNO(EINVAL);
184   errno = 0;
185   wcstoumax(L"123", nullptr, 1);
186   ASSERT_ERRNO(EINVAL);
187   errno = 0;
188   wcstoumax(L"123", nullptr, 37);
189   ASSERT_ERRNO(EINVAL);
190 }
191 
TEST(inttypes,div)192 TEST(inttypes, div) {
193   div_t r;
194 
195   r = div(5, 3);
196   EXPECT_EQ(1, r.quot);
197   EXPECT_EQ(2, r.rem);
198 
199   r = div(5, -3);
200   EXPECT_EQ(-1, r.quot);
201   EXPECT_EQ(2, r.rem);
202 
203   r = div(-5, 3);
204   EXPECT_EQ(-1, r.quot);
205   EXPECT_EQ(-2, r.rem);
206 
207   r = div(-5, -3);
208   EXPECT_EQ(1, r.quot);
209   EXPECT_EQ(-2, r.rem);
210 }
211 
TEST(inttypes,ldiv)212 TEST(inttypes, ldiv) {
213   ldiv_t r;
214 
215   r = ldiv(5, 3);
216   EXPECT_EQ(1, r.quot);
217   EXPECT_EQ(2, r.rem);
218 
219   r = ldiv(5, -3);
220   EXPECT_EQ(-1, r.quot);
221   EXPECT_EQ(2, r.rem);
222 
223   r = ldiv(-5, 3);
224   EXPECT_EQ(-1, r.quot);
225   EXPECT_EQ(-2, r.rem);
226 
227   r = ldiv(-5, -3);
228   EXPECT_EQ(1, r.quot);
229   EXPECT_EQ(-2, r.rem);
230 }
231 
TEST(inttypes,lldiv)232 TEST(inttypes, lldiv) {
233   lldiv_t r;
234 
235   r = lldiv(5, 3);
236   EXPECT_EQ(1, r.quot);
237   EXPECT_EQ(2, r.rem);
238 
239   r = lldiv(5, -3);
240   EXPECT_EQ(-1, r.quot);
241   EXPECT_EQ(2, r.rem);
242 
243   r = lldiv(-5, 3);
244   EXPECT_EQ(-1, r.quot);
245   EXPECT_EQ(-2, r.rem);
246 
247   r = lldiv(-5, -3);
248   EXPECT_EQ(1, r.quot);
249   EXPECT_EQ(-2, r.rem);
250 }
251 
TEST(inttypes,imaxdiv)252 TEST(inttypes, imaxdiv) {
253   imaxdiv_t r;
254 
255   r = imaxdiv(5, 3);
256   EXPECT_EQ(1, r.quot);
257   EXPECT_EQ(2, r.rem);
258 
259   r = imaxdiv(5, -3);
260   EXPECT_EQ(-1, r.quot);
261   EXPECT_EQ(2, r.rem);
262 
263   r = imaxdiv(-5, 3);
264   EXPECT_EQ(-1, r.quot);
265   EXPECT_EQ(-2, r.rem);
266 
267   r = imaxdiv(-5, -3);
268   EXPECT_EQ(1, r.quot);
269   EXPECT_EQ(-2, r.rem);
270 }
271 
TEST(inttypes,imaxabs)272 TEST(inttypes, imaxabs) {
273   EXPECT_EQ(672423489, imaxabs(672423489));
274   EXPECT_EQ(672423489, imaxabs(-672423489));
275   EXPECT_EQ(INTMAX_MAX, imaxabs(-INTMAX_MAX));
276   EXPECT_EQ(INTMAX_MAX, imaxabs(INTMAX_MAX));
277 }
278