2 * Utilities to convert strings to integers
4 * Copyright 2016, Dario Lombardo
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * SPDX-License-Identifier: GPL-2.0-or-later
20 #include <wsutil/ws_assert.h>
22 bool ws_strtoi64(const char* str
, const char** endptr
, int64_t* cint
)
35 val
= g_ascii_strtoll(str
, &end
, 10);
36 if ((val
== 0 && end
== str
) || (endptr
== NULL
&& *end
!= '\0')) {
43 if ((val
== INT64_MAX
|| val
== INT64_MIN
) && errno
== ERANGE
) {
45 * Return the value, so our caller knows whether to
46 * report the value as "too small" or "too large".
51 /* errno is already set */
60 #define DEFINE_WS_STRTOI_BITS(bits) \
61 bool ws_strtoi##bits(const char* str, const char** endptr, int##bits##_t* cint) \
64 if (!ws_strtoi64(str, endptr, &val)) { \
66 * For ERANGE, return either INT##bits##_MIN or \
67 * INT##bits##_MAX so our caller knows whether \
68 * to report the value as "too small" or "too \
71 * For other errors, return 0, for parallelism \
72 * with ws_strtoi64(). \
74 if (errno == ERANGE) { \
76 *cint = INT##bits##_MIN; \
78 *cint = INT##bits##_MAX; \
83 if (val < INT##bits##_MIN) { \
85 * Return INT##bits##_MIN so our caller knows whether to \
86 * report the value as "too small" or "too large". \
88 *cint = INT##bits##_MIN; \
92 if (val > INT##bits##_MAX) { \
94 * Return INT##bits##_MAX so our caller knows whether to \
95 * report the value as "too small" or "too large". \
97 *cint = INT##bits##_MAX; \
101 *cint = (int##bits##_t)val; \
105 DEFINE_WS_STRTOI_BITS(32)
106 DEFINE_WS_STRTOI_BITS(16)
107 DEFINE_WS_STRTOI_BITS(8)
109 bool ws_strtoi(const char* str
, const char** endptr
, int* cint
)
112 if (!ws_strtoi64(str
, endptr
, &val
)) {
114 * For ERANGE, return either INT_MIN or
115 * INT_MAX so our caller knows whether
116 * to report the value as "too small" or "too
119 * For other errors, return 0, for parallelism
120 * with ws_strtoi64().
122 if (errno
== ERANGE
) {
133 * Return INT_MIN so our caller knows whether to
134 * report the value as "too small" or "too large".
142 * Return INT_MAX so our caller knows whether to
143 * report the value as "too small" or "too large".
153 bool ws_basestrtou64(const char* str
, const char** endptr
, uint64_t* cint
, int base
)
165 if (str
[0] == '-' || str
[0] == '+') {
167 * Unsigned numbers don't have a sign.
176 val
= g_ascii_strtoull(str
, &end
, base
);
177 if ((val
== 0 && end
== str
) || (endptr
== NULL
&& *end
!= '\0')) {
184 if (val
== UINT64_MAX
&& errno
== ERANGE
) {
186 * Return the value, because ws_strtoi64() does.
191 /* errno is already set */
200 bool ws_strtou64(const char* str
, const char** endptr
, uint64_t* cint
)
202 return ws_basestrtou64(str
, endptr
, cint
, 10);
205 bool ws_hexstrtou64(const char* str
, const char** endptr
, uint64_t* cint
)
207 return ws_basestrtou64(str
, endptr
, cint
, 16);
210 #define DEFINE_WS_STRTOU_BITS(bits) \
211 bool ws_basestrtou##bits(const char* str, const char** endptr, uint##bits##_t* cint, int base) \
214 if (!ws_basestrtou64(str, endptr, &val, base)) { \
216 * For ERANGE, return UINT##bits##_MAX for parallelism \
217 * with ws_strtoi##bits(). \
219 * For other errors, return 0, for parallelism \
220 * with ws_basestrtou64(). \
222 if (errno == ERANGE) \
223 *cint = UINT##bits##_MAX; \
228 if (val > UINT##bits##_MAX) { \
230 * Return UINT##bits##_MAX for parallelism with \
231 * ws_strtoi##bits(). \
233 *cint = UINT##bits##_MAX; \
237 *cint = (uint##bits##_t)val; \
241 bool ws_strtou##bits(const char* str, const char** endptr, uint##bits##_t* cint) \
243 return ws_basestrtou##bits(str, endptr, cint, 10); \
246 bool ws_hexstrtou##bits(const char* str, const char** endptr, uint##bits##_t* cint) \
248 return ws_basestrtou##bits(str, endptr, cint, 16); \
251 DEFINE_WS_STRTOU_BITS(32)
252 DEFINE_WS_STRTOU_BITS(16)
253 DEFINE_WS_STRTOU_BITS(8)
255 bool ws_basestrtou(const char* str
, const char** endptr
, unsigned* cint
, int base
)
258 if (!ws_basestrtou64(str
, endptr
, &val
, base
)) {
260 * For ERANGE, return UINT_MAX for parallelism
263 * For other errors, return 0, for parallelism
264 * with ws_basestrtou64().
272 if (val
> UINT_MAX
) {
274 * Return UINT_MAX for parallelism with
281 *cint
= (unsigned)val
;
285 bool ws_strtou(const char* str
, const char** endptr
, unsigned* cint
)
287 return ws_basestrtou(str
, endptr
, cint
, 10);
290 bool ws_hexstrtou(const char* str
, const char** endptr
, unsigned* cint
)
292 return ws_basestrtou(str
, endptr
, cint
, 16);
296 * Editor modelines - https://www.wireshark.org/tools/modelines.html
301 * indent-tabs-mode: t
304 * vi: set shiftwidth=4 tabstop=8 noexpandtab:
305 * :indentSize=4:tabSize=8:noTabs=false: