xref: /qemu/util/cutils.c (revision b6d003db)
1baacf047SPaolo Bonzini /*
2baacf047SPaolo Bonzini  * Simple C functions to supplement the C library
3baacf047SPaolo Bonzini  *
4baacf047SPaolo Bonzini  * Copyright (c) 2006 Fabrice Bellard
5baacf047SPaolo Bonzini  *
6baacf047SPaolo Bonzini  * Permission is hereby granted, free of charge, to any person obtaining a copy
7baacf047SPaolo Bonzini  * of this software and associated documentation files (the "Software"), to deal
8baacf047SPaolo Bonzini  * in the Software without restriction, including without limitation the rights
9baacf047SPaolo Bonzini  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10baacf047SPaolo Bonzini  * copies of the Software, and to permit persons to whom the Software is
11baacf047SPaolo Bonzini  * furnished to do so, subject to the following conditions:
12baacf047SPaolo Bonzini  *
13baacf047SPaolo Bonzini  * The above copyright notice and this permission notice shall be included in
14baacf047SPaolo Bonzini  * all copies or substantial portions of the Software.
15baacf047SPaolo Bonzini  *
16baacf047SPaolo Bonzini  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17baacf047SPaolo Bonzini  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18baacf047SPaolo Bonzini  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19baacf047SPaolo Bonzini  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20baacf047SPaolo Bonzini  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21baacf047SPaolo Bonzini  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22baacf047SPaolo Bonzini  * THE SOFTWARE.
23baacf047SPaolo Bonzini  */
24856dfd8aSMarkus Armbruster 
25aafd7584SPeter Maydell #include "qemu/osdep.h"
26baacf047SPaolo Bonzini #include "qemu/host-utils.h"
27baacf047SPaolo Bonzini #include <math.h>
28baacf047SPaolo Bonzini 
29a8d25326SMarkus Armbruster #include "qemu-common.h"
30baacf047SPaolo Bonzini #include "qemu/sockets.h"
31baacf047SPaolo Bonzini #include "qemu/iov.h"
324297c8eeSAlexey Kardashevskiy #include "net/net.h"
33856dfd8aSMarkus Armbruster #include "qemu/ctype.h"
34f348b6d1SVeronia Bahaa #include "qemu/cutils.h"
3505cb8ed5SAlistair Francis #include "qemu/error-report.h"
36baacf047SPaolo Bonzini 
37baacf047SPaolo Bonzini void strpadcpy(char *buf, int buf_size, const char *str, char pad)
38baacf047SPaolo Bonzini {
39baacf047SPaolo Bonzini     int len = qemu_strnlen(str, buf_size);
40baacf047SPaolo Bonzini     memcpy(buf, str, len);
41baacf047SPaolo Bonzini     memset(buf + len, pad, buf_size - len);
42baacf047SPaolo Bonzini }
43baacf047SPaolo Bonzini 
44baacf047SPaolo Bonzini void pstrcpy(char *buf, int buf_size, const char *str)
45baacf047SPaolo Bonzini {
46baacf047SPaolo Bonzini     int c;
47baacf047SPaolo Bonzini     char *q = buf;
48baacf047SPaolo Bonzini 
49baacf047SPaolo Bonzini     if (buf_size <= 0)
50baacf047SPaolo Bonzini         return;
51baacf047SPaolo Bonzini 
52baacf047SPaolo Bonzini     for(;;) {
53baacf047SPaolo Bonzini         c = *str++;
54baacf047SPaolo Bonzini         if (c == 0 || q >= buf + buf_size - 1)
55baacf047SPaolo Bonzini             break;
56baacf047SPaolo Bonzini         *q++ = c;
57baacf047SPaolo Bonzini     }
58baacf047SPaolo Bonzini     *q = '\0';
59baacf047SPaolo Bonzini }
60baacf047SPaolo Bonzini 
61baacf047SPaolo Bonzini /* strcat and truncate. */
62baacf047SPaolo Bonzini char *pstrcat(char *buf, int buf_size, const char *s)
63baacf047SPaolo Bonzini {
64baacf047SPaolo Bonzini     int len;
65baacf047SPaolo Bonzini     len = strlen(buf);
66baacf047SPaolo Bonzini     if (len < buf_size)
67baacf047SPaolo Bonzini         pstrcpy(buf + len, buf_size - len, s);
68baacf047SPaolo Bonzini     return buf;
69baacf047SPaolo Bonzini }
70baacf047SPaolo Bonzini 
71baacf047SPaolo Bonzini int strstart(const char *str, const char *val, const char **ptr)
72baacf047SPaolo Bonzini {
73baacf047SPaolo Bonzini     const char *p, *q;
74baacf047SPaolo Bonzini     p = str;
75baacf047SPaolo Bonzini     q = val;
76baacf047SPaolo Bonzini     while (*q != '\0') {
77baacf047SPaolo Bonzini         if (*p != *q)
78baacf047SPaolo Bonzini             return 0;
79baacf047SPaolo Bonzini         p++;
80baacf047SPaolo Bonzini         q++;
81baacf047SPaolo Bonzini     }
82baacf047SPaolo Bonzini     if (ptr)
83baacf047SPaolo Bonzini         *ptr = p;
84baacf047SPaolo Bonzini     return 1;
85baacf047SPaolo Bonzini }
86baacf047SPaolo Bonzini 
87baacf047SPaolo Bonzini int stristart(const char *str, const char *val, const char **ptr)
88baacf047SPaolo Bonzini {
89baacf047SPaolo Bonzini     const char *p, *q;
90baacf047SPaolo Bonzini     p = str;
91baacf047SPaolo Bonzini     q = val;
92baacf047SPaolo Bonzini     while (*q != '\0') {
93baacf047SPaolo Bonzini         if (qemu_toupper(*p) != qemu_toupper(*q))
94baacf047SPaolo Bonzini             return 0;
95baacf047SPaolo Bonzini         p++;
96baacf047SPaolo Bonzini         q++;
97baacf047SPaolo Bonzini     }
98baacf047SPaolo Bonzini     if (ptr)
99baacf047SPaolo Bonzini         *ptr = p;
100baacf047SPaolo Bonzini     return 1;
101baacf047SPaolo Bonzini }
102baacf047SPaolo Bonzini 
103baacf047SPaolo Bonzini /* XXX: use host strnlen if available ? */
104baacf047SPaolo Bonzini int qemu_strnlen(const char *s, int max_len)
105baacf047SPaolo Bonzini {
106baacf047SPaolo Bonzini     int i;
107baacf047SPaolo Bonzini 
108baacf047SPaolo Bonzini     for(i = 0; i < max_len; i++) {
109baacf047SPaolo Bonzini         if (s[i] == '\0') {
110baacf047SPaolo Bonzini             break;
111baacf047SPaolo Bonzini         }
112baacf047SPaolo Bonzini     }
113baacf047SPaolo Bonzini     return i;
114baacf047SPaolo Bonzini }
115baacf047SPaolo Bonzini 
116a38ed811SKevin Wolf char *qemu_strsep(char **input, const char *delim)
117a38ed811SKevin Wolf {
118a38ed811SKevin Wolf     char *result = *input;
119a38ed811SKevin Wolf     if (result != NULL) {
120a38ed811SKevin Wolf         char *p;
121a38ed811SKevin Wolf 
122a38ed811SKevin Wolf         for (p = result; *p != '\0'; p++) {
123a38ed811SKevin Wolf             if (strchr(delim, *p)) {
124a38ed811SKevin Wolf                 break;
125a38ed811SKevin Wolf             }
126a38ed811SKevin Wolf         }
127a38ed811SKevin Wolf         if (*p == '\0') {
128a38ed811SKevin Wolf             *input = NULL;
129a38ed811SKevin Wolf         } else {
130a38ed811SKevin Wolf             *p = '\0';
131a38ed811SKevin Wolf             *input = p + 1;
132a38ed811SKevin Wolf         }
133a38ed811SKevin Wolf     }
134a38ed811SKevin Wolf     return result;
135a38ed811SKevin Wolf }
136a38ed811SKevin Wolf 
137baacf047SPaolo Bonzini time_t mktimegm(struct tm *tm)
138baacf047SPaolo Bonzini {
139baacf047SPaolo Bonzini     time_t t;
140baacf047SPaolo Bonzini     int y = tm->tm_year + 1900, m = tm->tm_mon + 1, d = tm->tm_mday;
141baacf047SPaolo Bonzini     if (m < 3) {
142baacf047SPaolo Bonzini         m += 12;
143baacf047SPaolo Bonzini         y--;
144baacf047SPaolo Bonzini     }
145baacf047SPaolo Bonzini     t = 86400ULL * (d + (153 * m - 457) / 5 + 365 * y + y / 4 - y / 100 +
146baacf047SPaolo Bonzini                  y / 400 - 719469);
147baacf047SPaolo Bonzini     t += 3600 * tm->tm_hour + 60 * tm->tm_min + tm->tm_sec;
148baacf047SPaolo Bonzini     return t;
149baacf047SPaolo Bonzini }
150baacf047SPaolo Bonzini 
151baacf047SPaolo Bonzini /*
152baacf047SPaolo Bonzini  * Make sure data goes on disk, but if possible do not bother to
153baacf047SPaolo Bonzini  * write out the inode just for timestamp updates.
154baacf047SPaolo Bonzini  *
155baacf047SPaolo Bonzini  * Unfortunately even in 2009 many operating systems do not support
156baacf047SPaolo Bonzini  * fdatasync and have to fall back to fsync.
157baacf047SPaolo Bonzini  */
158baacf047SPaolo Bonzini int qemu_fdatasync(int fd)
159baacf047SPaolo Bonzini {
160baacf047SPaolo Bonzini #ifdef CONFIG_FDATASYNC
161baacf047SPaolo Bonzini     return fdatasync(fd);
162baacf047SPaolo Bonzini #else
163baacf047SPaolo Bonzini     return fsync(fd);
164baacf047SPaolo Bonzini #endif
165baacf047SPaolo Bonzini }
166baacf047SPaolo Bonzini 
16761c490e2SBeata Michalska /**
16861c490e2SBeata Michalska  * Sync changes made to the memory mapped file back to the backing
16961c490e2SBeata Michalska  * storage. For POSIX compliant systems this will fallback
17061c490e2SBeata Michalska  * to regular msync call. Otherwise it will trigger whole file sync
17161c490e2SBeata Michalska  * (including the metadata case there is no support to skip that otherwise)
17261c490e2SBeata Michalska  *
17361c490e2SBeata Michalska  * @addr   - start of the memory area to be synced
17461c490e2SBeata Michalska  * @length - length of the are to be synced
17561c490e2SBeata Michalska  * @fd     - file descriptor for the file to be synced
17661c490e2SBeata Michalska  *           (mandatory only for POSIX non-compliant systems)
17761c490e2SBeata Michalska  */
17861c490e2SBeata Michalska int qemu_msync(void *addr, size_t length, int fd)
17961c490e2SBeata Michalska {
18061c490e2SBeata Michalska #ifdef CONFIG_POSIX
18161c490e2SBeata Michalska     size_t align_mask = ~(qemu_real_host_page_size - 1);
18261c490e2SBeata Michalska 
18361c490e2SBeata Michalska     /**
18461c490e2SBeata Michalska      * There are no strict reqs as per the length of mapping
18561c490e2SBeata Michalska      * to be synced. Still the length needs to follow the address
18661c490e2SBeata Michalska      * alignment changes. Additionally - round the size to the multiple
18761c490e2SBeata Michalska      * of PAGE_SIZE
18861c490e2SBeata Michalska      */
18961c490e2SBeata Michalska     length += ((uintptr_t)addr & (qemu_real_host_page_size - 1));
19061c490e2SBeata Michalska     length = (length + ~align_mask) & align_mask;
19161c490e2SBeata Michalska 
19261c490e2SBeata Michalska     addr = (void *)((uintptr_t)addr & align_mask);
19361c490e2SBeata Michalska 
19461c490e2SBeata Michalska     return msync(addr, length, MS_SYNC);
19561c490e2SBeata Michalska #else /* CONFIG_POSIX */
19661c490e2SBeata Michalska     /**
19761c490e2SBeata Michalska      * Perform the sync based on the file descriptor
19861c490e2SBeata Michalska      * The sync range will most probably be wider than the one
19961c490e2SBeata Michalska      * requested - but it will still get the job done
20061c490e2SBeata Michalska      */
20161c490e2SBeata Michalska     return qemu_fdatasync(fd);
20261c490e2SBeata Michalska #endif /* CONFIG_POSIX */
20361c490e2SBeata Michalska }
20461c490e2SBeata Michalska 
205baacf047SPaolo Bonzini #ifndef _WIN32
206baacf047SPaolo Bonzini /* Sets a specific flag */
207baacf047SPaolo Bonzini int fcntl_setfl(int fd, int flag)
208baacf047SPaolo Bonzini {
209baacf047SPaolo Bonzini     int flags;
210baacf047SPaolo Bonzini 
211baacf047SPaolo Bonzini     flags = fcntl(fd, F_GETFL);
212baacf047SPaolo Bonzini     if (flags == -1)
213baacf047SPaolo Bonzini         return -errno;
214baacf047SPaolo Bonzini 
215baacf047SPaolo Bonzini     if (fcntl(fd, F_SETFL, flags | flag) == -1)
216baacf047SPaolo Bonzini         return -errno;
217baacf047SPaolo Bonzini 
218baacf047SPaolo Bonzini     return 0;
219baacf047SPaolo Bonzini }
220baacf047SPaolo Bonzini #endif
221baacf047SPaolo Bonzini 
222baacf047SPaolo Bonzini static int64_t suffix_mul(char suffix, int64_t unit)
223baacf047SPaolo Bonzini {
224baacf047SPaolo Bonzini     switch (qemu_toupper(suffix)) {
22517f94256SMarkus Armbruster     case 'B':
226baacf047SPaolo Bonzini         return 1;
22717f94256SMarkus Armbruster     case 'K':
228baacf047SPaolo Bonzini         return unit;
22917f94256SMarkus Armbruster     case 'M':
230baacf047SPaolo Bonzini         return unit * unit;
23117f94256SMarkus Armbruster     case 'G':
232baacf047SPaolo Bonzini         return unit * unit * unit;
23317f94256SMarkus Armbruster     case 'T':
234baacf047SPaolo Bonzini         return unit * unit * unit * unit;
23517f94256SMarkus Armbruster     case 'P':
2365e00984aSKevin Wolf         return unit * unit * unit * unit * unit;
23717f94256SMarkus Armbruster     case 'E':
2385e00984aSKevin Wolf         return unit * unit * unit * unit * unit * unit;
239baacf047SPaolo Bonzini     }
240baacf047SPaolo Bonzini     return -1;
241baacf047SPaolo Bonzini }
242baacf047SPaolo Bonzini 
243baacf047SPaolo Bonzini /*
244cf923b78SEric Blake  * Convert size string to bytes.
245cf923b78SEric Blake  *
246cf923b78SEric Blake  * The size parsing supports the following syntaxes
247cf923b78SEric Blake  * - 12345 - decimal, scale determined by @default_suffix and @unit
248cf923b78SEric Blake  * - 12345{bBkKmMgGtTpPeE} - decimal, scale determined by suffix and @unit
249cf923b78SEric Blake  * - 12345.678{kKmMgGtTpPeE} - decimal, scale determined by suffix, and
250cf923b78SEric Blake  *   fractional portion is truncated to byte
251cf923b78SEric Blake  * - 0x7fEE - hexadecimal, unit determined by @default_suffix
252cf923b78SEric Blake  *
253f174cd33SEric Blake  * The following cause a deprecation warning, and may be removed in the future
254f174cd33SEric Blake  * - 0xabc{kKmMgGtTpP} - hex with scaling suffix
255f174cd33SEric Blake  *
256cf923b78SEric Blake  * The following are intentionally not supported
257cf923b78SEric Blake  * - octal, such as 08
258cf923b78SEric Blake  * - fractional hex, such as 0x1.8
259cf923b78SEric Blake  * - floating point exponents, such as 1e3
260cf923b78SEric Blake  *
261cf923b78SEric Blake  * The end pointer will be returned in *end, if not NULL.  If there is
262cf923b78SEric Blake  * no fraction, the input can be decimal or hexadecimal; if there is a
263cf923b78SEric Blake  * fraction, then the input must be decimal and there must be a suffix
264cf923b78SEric Blake  * (possibly by @default_suffix) larger than Byte, and the fractional
265cf923b78SEric Blake  * portion may suffer from precision loss or rounding.  The input must
266cf923b78SEric Blake  * be positive.
267cf923b78SEric Blake  *
268cf923b78SEric Blake  * Return -ERANGE on overflow (with *@end advanced), and -EINVAL on
269cf923b78SEric Blake  * other error (with *@end left unchanged).
270baacf047SPaolo Bonzini  */
271af02f4c5SDavid Hildenbrand static int do_strtosz(const char *nptr, const char **end,
272f17fd4fdSMarkus Armbruster                       const char default_suffix, int64_t unit,
273f46bfdbfSMarkus Armbruster                       uint64_t *result)
274baacf047SPaolo Bonzini {
275f17fd4fdSMarkus Armbruster     int retval;
276cf923b78SEric Blake     const char *endptr, *f;
277baacf047SPaolo Bonzini     unsigned char c;
2787625a1edSRichard Henderson     bool hex = false;
2797625a1edSRichard Henderson     uint64_t val, valf = 0;
280cf923b78SEric Blake     int64_t mul;
281baacf047SPaolo Bonzini 
282cf923b78SEric Blake     /* Parse integral portion as decimal. */
283cf923b78SEric Blake     retval = qemu_strtou64(nptr, &endptr, 10, &val);
284af02f4c5SDavid Hildenbrand     if (retval) {
2854fcdf65aSMarkus Armbruster         goto out;
286baacf047SPaolo Bonzini     }
287cf923b78SEric Blake     if (memchr(nptr, '-', endptr - nptr) != NULL) {
288cf923b78SEric Blake         endptr = nptr;
2894fcdf65aSMarkus Armbruster         retval = -EINVAL;
2904fcdf65aSMarkus Armbruster         goto out;
291baacf047SPaolo Bonzini     }
292cf923b78SEric Blake     if (val == 0 && (*endptr == 'x' || *endptr == 'X')) {
293cf923b78SEric Blake         /* Input looks like hex, reparse, and insist on no fraction. */
294cf923b78SEric Blake         retval = qemu_strtou64(nptr, &endptr, 16, &val);
295cf923b78SEric Blake         if (retval) {
296cf923b78SEric Blake             goto out;
297cf923b78SEric Blake         }
298cf923b78SEric Blake         if (*endptr == '.') {
299cf923b78SEric Blake             endptr = nptr;
300cf923b78SEric Blake             retval = -EINVAL;
301cf923b78SEric Blake             goto out;
302cf923b78SEric Blake         }
303f174cd33SEric Blake         hex = true;
304cf923b78SEric Blake     } else if (*endptr == '.') {
305f46bfdbfSMarkus Armbruster         /*
306cf923b78SEric Blake          * Input looks like a fraction.  Make sure even 1.k works
307cf923b78SEric Blake          * without fractional digits.  If we see an exponent, treat
308cf923b78SEric Blake          * the entire input as invalid instead.
309f46bfdbfSMarkus Armbruster          */
3107625a1edSRichard Henderson         double fraction;
3117625a1edSRichard Henderson 
312cf923b78SEric Blake         f = endptr;
313cf923b78SEric Blake         retval = qemu_strtod_finite(f, &endptr, &fraction);
314cf923b78SEric Blake         if (retval) {
315cf923b78SEric Blake             endptr++;
316cf923b78SEric Blake         } else if (memchr(f, 'e', endptr - f) || memchr(f, 'E', endptr - f)) {
317cf923b78SEric Blake             endptr = nptr;
318cf923b78SEric Blake             retval = -EINVAL;
319cf923b78SEric Blake             goto out;
3207625a1edSRichard Henderson         } else {
3217625a1edSRichard Henderson             /* Extract into a 64-bit fixed-point fraction. */
3227625a1edSRichard Henderson             valf = (uint64_t)(fraction * 0x1p64);
323cf923b78SEric Blake         }
324cf923b78SEric Blake     }
325cf923b78SEric Blake     c = *endptr;
326cf923b78SEric Blake     mul = suffix_mul(c, unit);
327cf923b78SEric Blake     if (mul > 0) {
328f174cd33SEric Blake         if (hex) {
329f174cd33SEric Blake             warn_report("Using a multiplier suffix on hex numbers "
330f174cd33SEric Blake                         "is deprecated: %s", nptr);
331f174cd33SEric Blake         }
332cf923b78SEric Blake         endptr++;
333cf923b78SEric Blake     } else {
334cf923b78SEric Blake         mul = suffix_mul(default_suffix, unit);
335cf923b78SEric Blake         assert(mul > 0);
336cf923b78SEric Blake     }
3377625a1edSRichard Henderson     if (mul == 1) {
3387625a1edSRichard Henderson         /* When a fraction is present, a scale is required. */
3397625a1edSRichard Henderson         if (valf != 0) {
340cf923b78SEric Blake             endptr = nptr;
341cf923b78SEric Blake             retval = -EINVAL;
342cf923b78SEric Blake             goto out;
343cf923b78SEric Blake         }
3447625a1edSRichard Henderson     } else {
3457625a1edSRichard Henderson         uint64_t valh, tmp;
3467625a1edSRichard Henderson 
3477625a1edSRichard Henderson         /* Compute exact result: 64.64 x 64.0 -> 128.64 fixed point */
3487625a1edSRichard Henderson         mulu64(&val, &valh, val, mul);
3497625a1edSRichard Henderson         mulu64(&valf, &tmp, valf, mul);
3507625a1edSRichard Henderson         val += tmp;
3517625a1edSRichard Henderson         valh += val < tmp;
3527625a1edSRichard Henderson 
3537625a1edSRichard Henderson         /* Round 0.5 upward. */
3547625a1edSRichard Henderson         tmp = valf >> 63;
3557625a1edSRichard Henderson         val += tmp;
3567625a1edSRichard Henderson         valh += val < tmp;
3577625a1edSRichard Henderson 
3587625a1edSRichard Henderson         /* Report overflow. */
3597625a1edSRichard Henderson         if (valh != 0) {
360baacf047SPaolo Bonzini             retval = -ERANGE;
3614fcdf65aSMarkus Armbruster             goto out;
362baacf047SPaolo Bonzini         }
3637625a1edSRichard Henderson     }
3647625a1edSRichard Henderson 
365f17fd4fdSMarkus Armbruster     retval = 0;
366baacf047SPaolo Bonzini 
3674fcdf65aSMarkus Armbruster out:
368baacf047SPaolo Bonzini     if (end) {
369baacf047SPaolo Bonzini         *end = endptr;
3704fcdf65aSMarkus Armbruster     } else if (*endptr) {
3714fcdf65aSMarkus Armbruster         retval = -EINVAL;
372baacf047SPaolo Bonzini     }
373061d7909SEric Blake     if (retval == 0) {
374061d7909SEric Blake         *result = val;
375061d7909SEric Blake     }
376baacf047SPaolo Bonzini 
377baacf047SPaolo Bonzini     return retval;
378baacf047SPaolo Bonzini }
379baacf047SPaolo Bonzini 
380af02f4c5SDavid Hildenbrand int qemu_strtosz(const char *nptr, const char **end, uint64_t *result)
381baacf047SPaolo Bonzini {
382f17fd4fdSMarkus Armbruster     return do_strtosz(nptr, end, 'B', 1024, result);
383baacf047SPaolo Bonzini }
384baacf047SPaolo Bonzini 
385af02f4c5SDavid Hildenbrand int qemu_strtosz_MiB(const char *nptr, const char **end, uint64_t *result)
386baacf047SPaolo Bonzini {
387f17fd4fdSMarkus Armbruster     return do_strtosz(nptr, end, 'M', 1024, result);
388baacf047SPaolo Bonzini }
389baacf047SPaolo Bonzini 
390af02f4c5SDavid Hildenbrand int qemu_strtosz_metric(const char *nptr, const char **end, uint64_t *result)
391d2734d26SMarkus Armbruster {
392f17fd4fdSMarkus Armbruster     return do_strtosz(nptr, end, 'B', 1000, result);
393d2734d26SMarkus Armbruster }
394d2734d26SMarkus Armbruster 
395e3f9fe2dSEduardo Habkost /**
396717adf96SMarkus Armbruster  * Helper function for error checking after strtol() and the like
397764e0fa4SCarlos L. Torres  */
398717adf96SMarkus Armbruster static int check_strtox_error(const char *nptr, char *ep,
3996162f7daSEric Blake                               const char **endptr, bool check_zero,
4006162f7daSEric Blake                               int libc_errno)
401764e0fa4SCarlos L. Torres {
40253a90b97SEric Blake     assert(ep >= nptr);
4036162f7daSEric Blake 
4046162f7daSEric Blake     /* Windows has a bug in that it fails to parse 0 from "0x" in base 16 */
4056162f7daSEric Blake     if (check_zero && ep == nptr && libc_errno == 0) {
4066162f7daSEric Blake         char *tmp;
4076162f7daSEric Blake 
4086162f7daSEric Blake         errno = 0;
4096162f7daSEric Blake         if (strtol(nptr, &tmp, 10) == 0 && errno == 0 &&
4106162f7daSEric Blake             (*tmp == 'x' || *tmp == 'X')) {
4116162f7daSEric Blake             ep = tmp;
4126162f7daSEric Blake         }
4136162f7daSEric Blake     }
4146162f7daSEric Blake 
415717adf96SMarkus Armbruster     if (endptr) {
416717adf96SMarkus Armbruster         *endptr = ep;
417764e0fa4SCarlos L. Torres     }
4184baef267SMarkus Armbruster 
4194baef267SMarkus Armbruster     /* Turn "no conversion" into an error */
4204baef267SMarkus Armbruster     if (libc_errno == 0 && ep == nptr) {
4214baef267SMarkus Armbruster         return -EINVAL;
4224baef267SMarkus Armbruster     }
4234baef267SMarkus Armbruster 
4244baef267SMarkus Armbruster     /* Fail when we're expected to consume the string, but didn't */
4254baef267SMarkus Armbruster     if (!endptr && *ep) {
4264baef267SMarkus Armbruster         return -EINVAL;
4274baef267SMarkus Armbruster     }
4284baef267SMarkus Armbruster 
429717adf96SMarkus Armbruster     return -libc_errno;
430764e0fa4SCarlos L. Torres }
431764e0fa4SCarlos L. Torres 
432764e0fa4SCarlos L. Torres /**
433473a2a33SDaniel P. Berrange  * Convert string @nptr to an integer, and store it in @result.
434473a2a33SDaniel P. Berrange  *
435473a2a33SDaniel P. Berrange  * This is a wrapper around strtol() that is harder to misuse.
436473a2a33SDaniel P. Berrange  * Semantics of @nptr, @endptr, @base match strtol() with differences
437473a2a33SDaniel P. Berrange  * noted below.
438473a2a33SDaniel P. Berrange  *
439473a2a33SDaniel P. Berrange  * @nptr may be null, and no conversion is performed then.
440473a2a33SDaniel P. Berrange  *
441473a2a33SDaniel P. Berrange  * If no conversion is performed, store @nptr in *@endptr and return
442473a2a33SDaniel P. Berrange  * -EINVAL.
443473a2a33SDaniel P. Berrange  *
444473a2a33SDaniel P. Berrange  * If @endptr is null, and the string isn't fully converted, return
445473a2a33SDaniel P. Berrange  * -EINVAL.  This is the case when the pointer that would be stored in
446473a2a33SDaniel P. Berrange  * a non-null @endptr points to a character other than '\0'.
447473a2a33SDaniel P. Berrange  *
448473a2a33SDaniel P. Berrange  * If the conversion overflows @result, store INT_MAX in @result,
449473a2a33SDaniel P. Berrange  * and return -ERANGE.
450473a2a33SDaniel P. Berrange  *
451473a2a33SDaniel P. Berrange  * If the conversion underflows @result, store INT_MIN in @result,
452473a2a33SDaniel P. Berrange  * and return -ERANGE.
453473a2a33SDaniel P. Berrange  *
454473a2a33SDaniel P. Berrange  * Else store the converted value in @result, and return zero.
455473a2a33SDaniel P. Berrange  */
456473a2a33SDaniel P. Berrange int qemu_strtoi(const char *nptr, const char **endptr, int base,
457473a2a33SDaniel P. Berrange                 int *result)
458473a2a33SDaniel P. Berrange {
459473a2a33SDaniel P. Berrange     char *ep;
460473a2a33SDaniel P. Berrange     long long lresult;
461473a2a33SDaniel P. Berrange 
46253a90b97SEric Blake     assert((unsigned) base <= 36 && base != 1);
463473a2a33SDaniel P. Berrange     if (!nptr) {
464473a2a33SDaniel P. Berrange         if (endptr) {
465473a2a33SDaniel P. Berrange             *endptr = nptr;
466473a2a33SDaniel P. Berrange         }
467473a2a33SDaniel P. Berrange         return -EINVAL;
468473a2a33SDaniel P. Berrange     }
469473a2a33SDaniel P. Berrange 
470473a2a33SDaniel P. Berrange     errno = 0;
471473a2a33SDaniel P. Berrange     lresult = strtoll(nptr, &ep, base);
472473a2a33SDaniel P. Berrange     if (lresult < INT_MIN) {
473473a2a33SDaniel P. Berrange         *result = INT_MIN;
474473a2a33SDaniel P. Berrange         errno = ERANGE;
475473a2a33SDaniel P. Berrange     } else if (lresult > INT_MAX) {
476473a2a33SDaniel P. Berrange         *result = INT_MAX;
477473a2a33SDaniel P. Berrange         errno = ERANGE;
478473a2a33SDaniel P. Berrange     } else {
479473a2a33SDaniel P. Berrange         *result = lresult;
480473a2a33SDaniel P. Berrange     }
4816162f7daSEric Blake     return check_strtox_error(nptr, ep, endptr, lresult == 0, errno);
482473a2a33SDaniel P. Berrange }
483473a2a33SDaniel P. Berrange 
484473a2a33SDaniel P. Berrange /**
485473a2a33SDaniel P. Berrange  * Convert string @nptr to an unsigned integer, and store it in @result.
486473a2a33SDaniel P. Berrange  *
487473a2a33SDaniel P. Berrange  * This is a wrapper around strtoul() that is harder to misuse.
488473a2a33SDaniel P. Berrange  * Semantics of @nptr, @endptr, @base match strtoul() with differences
489473a2a33SDaniel P. Berrange  * noted below.
490473a2a33SDaniel P. Berrange  *
491473a2a33SDaniel P. Berrange  * @nptr may be null, and no conversion is performed then.
492473a2a33SDaniel P. Berrange  *
493473a2a33SDaniel P. Berrange  * If no conversion is performed, store @nptr in *@endptr and return
494473a2a33SDaniel P. Berrange  * -EINVAL.
495473a2a33SDaniel P. Berrange  *
496473a2a33SDaniel P. Berrange  * If @endptr is null, and the string isn't fully converted, return
497473a2a33SDaniel P. Berrange  * -EINVAL.  This is the case when the pointer that would be stored in
498473a2a33SDaniel P. Berrange  * a non-null @endptr points to a character other than '\0'.
499473a2a33SDaniel P. Berrange  *
500473a2a33SDaniel P. Berrange  * If the conversion overflows @result, store UINT_MAX in @result,
501473a2a33SDaniel P. Berrange  * and return -ERANGE.
502473a2a33SDaniel P. Berrange  *
503473a2a33SDaniel P. Berrange  * Else store the converted value in @result, and return zero.
504473a2a33SDaniel P. Berrange  *
505473a2a33SDaniel P. Berrange  * Note that a number with a leading minus sign gets converted without
506473a2a33SDaniel P. Berrange  * the minus sign, checked for overflow (see above), then negated (in
507473a2a33SDaniel P. Berrange  * @result's type).  This is exactly how strtoul() works.
508473a2a33SDaniel P. Berrange  */
509473a2a33SDaniel P. Berrange int qemu_strtoui(const char *nptr, const char **endptr, int base,
510473a2a33SDaniel P. Berrange                  unsigned int *result)
511473a2a33SDaniel P. Berrange {
512473a2a33SDaniel P. Berrange     char *ep;
513473a2a33SDaniel P. Berrange     long long lresult;
514473a2a33SDaniel P. Berrange 
51553a90b97SEric Blake     assert((unsigned) base <= 36 && base != 1);
516473a2a33SDaniel P. Berrange     if (!nptr) {
517473a2a33SDaniel P. Berrange         if (endptr) {
518473a2a33SDaniel P. Berrange             *endptr = nptr;
519473a2a33SDaniel P. Berrange         }
520473a2a33SDaniel P. Berrange         return -EINVAL;
521473a2a33SDaniel P. Berrange     }
522473a2a33SDaniel P. Berrange 
523473a2a33SDaniel P. Berrange     errno = 0;
524473a2a33SDaniel P. Berrange     lresult = strtoull(nptr, &ep, base);
525473a2a33SDaniel P. Berrange 
526473a2a33SDaniel P. Berrange     /* Windows returns 1 for negative out-of-range values.  */
527473a2a33SDaniel P. Berrange     if (errno == ERANGE) {
528473a2a33SDaniel P. Berrange         *result = -1;
529473a2a33SDaniel P. Berrange     } else {
530473a2a33SDaniel P. Berrange         if (lresult > UINT_MAX) {
531473a2a33SDaniel P. Berrange             *result = UINT_MAX;
532473a2a33SDaniel P. Berrange             errno = ERANGE;
533473a2a33SDaniel P. Berrange         } else if (lresult < INT_MIN) {
534473a2a33SDaniel P. Berrange             *result = UINT_MAX;
535473a2a33SDaniel P. Berrange             errno = ERANGE;
536473a2a33SDaniel P. Berrange         } else {
537473a2a33SDaniel P. Berrange             *result = lresult;
538473a2a33SDaniel P. Berrange         }
539473a2a33SDaniel P. Berrange     }
5406162f7daSEric Blake     return check_strtox_error(nptr, ep, endptr, lresult == 0, errno);
541473a2a33SDaniel P. Berrange }
542473a2a33SDaniel P. Berrange 
543473a2a33SDaniel P. Berrange /**
5444295f879SMarkus Armbruster  * Convert string @nptr to a long integer, and store it in @result.
545764e0fa4SCarlos L. Torres  *
5464295f879SMarkus Armbruster  * This is a wrapper around strtol() that is harder to misuse.
5474295f879SMarkus Armbruster  * Semantics of @nptr, @endptr, @base match strtol() with differences
5484295f879SMarkus Armbruster  * noted below.
549764e0fa4SCarlos L. Torres  *
5504295f879SMarkus Armbruster  * @nptr may be null, and no conversion is performed then.
551764e0fa4SCarlos L. Torres  *
5524295f879SMarkus Armbruster  * If no conversion is performed, store @nptr in *@endptr and return
5534295f879SMarkus Armbruster  * -EINVAL.
554764e0fa4SCarlos L. Torres  *
5554295f879SMarkus Armbruster  * If @endptr is null, and the string isn't fully converted, return
5564295f879SMarkus Armbruster  * -EINVAL.  This is the case when the pointer that would be stored in
5574295f879SMarkus Armbruster  * a non-null @endptr points to a character other than '\0'.
5584295f879SMarkus Armbruster  *
5594295f879SMarkus Armbruster  * If the conversion overflows @result, store LONG_MAX in @result,
5604295f879SMarkus Armbruster  * and return -ERANGE.
5614295f879SMarkus Armbruster  *
5624295f879SMarkus Armbruster  * If the conversion underflows @result, store LONG_MIN in @result,
5634295f879SMarkus Armbruster  * and return -ERANGE.
5644295f879SMarkus Armbruster  *
5654295f879SMarkus Armbruster  * Else store the converted value in @result, and return zero.
566764e0fa4SCarlos L. Torres  */
567764e0fa4SCarlos L. Torres int qemu_strtol(const char *nptr, const char **endptr, int base,
568764e0fa4SCarlos L. Torres                 long *result)
569764e0fa4SCarlos L. Torres {
570717adf96SMarkus Armbruster     char *ep;
5714baef267SMarkus Armbruster 
57253a90b97SEric Blake     assert((unsigned) base <= 36 && base != 1);
573764e0fa4SCarlos L. Torres     if (!nptr) {
574764e0fa4SCarlos L. Torres         if (endptr) {
575764e0fa4SCarlos L. Torres             *endptr = nptr;
576764e0fa4SCarlos L. Torres         }
5774baef267SMarkus Armbruster         return -EINVAL;
5784baef267SMarkus Armbruster     }
5794baef267SMarkus Armbruster 
580764e0fa4SCarlos L. Torres     errno = 0;
581717adf96SMarkus Armbruster     *result = strtol(nptr, &ep, base);
5826162f7daSEric Blake     return check_strtox_error(nptr, ep, endptr, *result == 0, errno);
583764e0fa4SCarlos L. Torres }
584c817c015SCarlos L. Torres 
585c817c015SCarlos L. Torres /**
5864295f879SMarkus Armbruster  * Convert string @nptr to an unsigned long, and store it in @result.
587c817c015SCarlos L. Torres  *
5884295f879SMarkus Armbruster  * This is a wrapper around strtoul() that is harder to misuse.
5894295f879SMarkus Armbruster  * Semantics of @nptr, @endptr, @base match strtoul() with differences
5904295f879SMarkus Armbruster  * noted below.
591c817c015SCarlos L. Torres  *
5924295f879SMarkus Armbruster  * @nptr may be null, and no conversion is performed then.
593c817c015SCarlos L. Torres  *
5944295f879SMarkus Armbruster  * If no conversion is performed, store @nptr in *@endptr and return
5954295f879SMarkus Armbruster  * -EINVAL.
5964295f879SMarkus Armbruster  *
5974295f879SMarkus Armbruster  * If @endptr is null, and the string isn't fully converted, return
5984295f879SMarkus Armbruster  * -EINVAL.  This is the case when the pointer that would be stored in
5994295f879SMarkus Armbruster  * a non-null @endptr points to a character other than '\0'.
6004295f879SMarkus Armbruster  *
6014295f879SMarkus Armbruster  * If the conversion overflows @result, store ULONG_MAX in @result,
6024295f879SMarkus Armbruster  * and return -ERANGE.
6034295f879SMarkus Armbruster  *
6044295f879SMarkus Armbruster  * Else store the converted value in @result, and return zero.
6054295f879SMarkus Armbruster  *
6064295f879SMarkus Armbruster  * Note that a number with a leading minus sign gets converted without
6074295f879SMarkus Armbruster  * the minus sign, checked for overflow (see above), then negated (in
6084295f879SMarkus Armbruster  * @result's type).  This is exactly how strtoul() works.
609c817c015SCarlos L. Torres  */
610c817c015SCarlos L. Torres int qemu_strtoul(const char *nptr, const char **endptr, int base,
611c817c015SCarlos L. Torres                  unsigned long *result)
612c817c015SCarlos L. Torres {
613717adf96SMarkus Armbruster     char *ep;
6144baef267SMarkus Armbruster 
61553a90b97SEric Blake     assert((unsigned) base <= 36 && base != 1);
616c817c015SCarlos L. Torres     if (!nptr) {
617c817c015SCarlos L. Torres         if (endptr) {
618c817c015SCarlos L. Torres             *endptr = nptr;
619c817c015SCarlos L. Torres         }
6204baef267SMarkus Armbruster         return -EINVAL;
6214baef267SMarkus Armbruster     }
6224baef267SMarkus Armbruster 
623c817c015SCarlos L. Torres     errno = 0;
624717adf96SMarkus Armbruster     *result = strtoul(nptr, &ep, base);
62547d4be12SPaolo Bonzini     /* Windows returns 1 for negative out-of-range values.  */
62647d4be12SPaolo Bonzini     if (errno == ERANGE) {
62747d4be12SPaolo Bonzini         *result = -1;
62847d4be12SPaolo Bonzini     }
6296162f7daSEric Blake     return check_strtox_error(nptr, ep, endptr, *result == 0, errno);
630c817c015SCarlos L. Torres }
631c817c015SCarlos L. Torres 
632764e0fa4SCarlos L. Torres /**
6334295f879SMarkus Armbruster  * Convert string @nptr to an int64_t.
6348ac4df40SCarlos L. Torres  *
6354295f879SMarkus Armbruster  * Works like qemu_strtol(), except it stores INT64_MAX on overflow,
636369276ebSMarkus Armbruster  * and INT64_MIN on underflow.
6378ac4df40SCarlos L. Torres  */
638b30d1886SMarkus Armbruster int qemu_strtoi64(const char *nptr, const char **endptr, int base,
6398ac4df40SCarlos L. Torres                  int64_t *result)
6408ac4df40SCarlos L. Torres {
641717adf96SMarkus Armbruster     char *ep;
6424baef267SMarkus Armbruster 
64353a90b97SEric Blake     assert((unsigned) base <= 36 && base != 1);
6448ac4df40SCarlos L. Torres     if (!nptr) {
6458ac4df40SCarlos L. Torres         if (endptr) {
6468ac4df40SCarlos L. Torres             *endptr = nptr;
6478ac4df40SCarlos L. Torres         }
6484baef267SMarkus Armbruster         return -EINVAL;
6494baef267SMarkus Armbruster     }
6504baef267SMarkus Armbruster 
651369276ebSMarkus Armbruster     /* This assumes int64_t is long long TODO relax */
652369276ebSMarkus Armbruster     QEMU_BUILD_BUG_ON(sizeof(int64_t) != sizeof(long long));
6538ac4df40SCarlos L. Torres     errno = 0;
654717adf96SMarkus Armbruster     *result = strtoll(nptr, &ep, base);
6556162f7daSEric Blake     return check_strtox_error(nptr, ep, endptr, *result == 0, errno);
6568ac4df40SCarlos L. Torres }
6578ac4df40SCarlos L. Torres 
6588ac4df40SCarlos L. Torres /**
6594295f879SMarkus Armbruster  * Convert string @nptr to an uint64_t.
6603904e6bfSCarlos L. Torres  *
6614295f879SMarkus Armbruster  * Works like qemu_strtoul(), except it stores UINT64_MAX on overflow.
6623904e6bfSCarlos L. Torres  */
663b30d1886SMarkus Armbruster int qemu_strtou64(const char *nptr, const char **endptr, int base,
6643904e6bfSCarlos L. Torres                   uint64_t *result)
6653904e6bfSCarlos L. Torres {
666717adf96SMarkus Armbruster     char *ep;
6674baef267SMarkus Armbruster 
66853a90b97SEric Blake     assert((unsigned) base <= 36 && base != 1);
6693904e6bfSCarlos L. Torres     if (!nptr) {
6703904e6bfSCarlos L. Torres         if (endptr) {
6713904e6bfSCarlos L. Torres             *endptr = nptr;
6723904e6bfSCarlos L. Torres         }
6734baef267SMarkus Armbruster         return -EINVAL;
6744baef267SMarkus Armbruster     }
6754baef267SMarkus Armbruster 
676369276ebSMarkus Armbruster     /* This assumes uint64_t is unsigned long long TODO relax */
677369276ebSMarkus Armbruster     QEMU_BUILD_BUG_ON(sizeof(uint64_t) != sizeof(unsigned long long));
6783904e6bfSCarlos L. Torres     errno = 0;
679717adf96SMarkus Armbruster     *result = strtoull(nptr, &ep, base);
68047d4be12SPaolo Bonzini     /* Windows returns 1 for negative out-of-range values.  */
68147d4be12SPaolo Bonzini     if (errno == ERANGE) {
68247d4be12SPaolo Bonzini         *result = -1;
68347d4be12SPaolo Bonzini     }
6846162f7daSEric Blake     return check_strtox_error(nptr, ep, endptr, *result == 0, errno);
6853904e6bfSCarlos L. Torres }
6863904e6bfSCarlos L. Torres 
6873904e6bfSCarlos L. Torres /**
688ca28f548SDavid Hildenbrand  * Convert string @nptr to a double.
689ca28f548SDavid Hildenbrand   *
690ca28f548SDavid Hildenbrand  * This is a wrapper around strtod() that is harder to misuse.
691ca28f548SDavid Hildenbrand  * Semantics of @nptr and @endptr match strtod() with differences
692ca28f548SDavid Hildenbrand  * noted below.
693ca28f548SDavid Hildenbrand  *
694ca28f548SDavid Hildenbrand  * @nptr may be null, and no conversion is performed then.
695ca28f548SDavid Hildenbrand  *
696ca28f548SDavid Hildenbrand  * If no conversion is performed, store @nptr in *@endptr and return
697ca28f548SDavid Hildenbrand  * -EINVAL.
698ca28f548SDavid Hildenbrand  *
699ca28f548SDavid Hildenbrand  * If @endptr is null, and the string isn't fully converted, return
700ca28f548SDavid Hildenbrand  * -EINVAL. This is the case when the pointer that would be stored in
701ca28f548SDavid Hildenbrand  * a non-null @endptr points to a character other than '\0'.
702ca28f548SDavid Hildenbrand  *
703ca28f548SDavid Hildenbrand  * If the conversion overflows, store +/-HUGE_VAL in @result, depending
704ca28f548SDavid Hildenbrand  * on the sign, and return -ERANGE.
705ca28f548SDavid Hildenbrand  *
706ca28f548SDavid Hildenbrand  * If the conversion underflows, store +/-0.0 in @result, depending on the
707ca28f548SDavid Hildenbrand  * sign, and return -ERANGE.
708ca28f548SDavid Hildenbrand  *
709ca28f548SDavid Hildenbrand  * Else store the converted value in @result, and return zero.
710ca28f548SDavid Hildenbrand  */
711ca28f548SDavid Hildenbrand int qemu_strtod(const char *nptr, const char **endptr, double *result)
712ca28f548SDavid Hildenbrand {
713ca28f548SDavid Hildenbrand     char *ep;
714ca28f548SDavid Hildenbrand 
715ca28f548SDavid Hildenbrand     if (!nptr) {
716ca28f548SDavid Hildenbrand         if (endptr) {
717ca28f548SDavid Hildenbrand             *endptr = nptr;
718ca28f548SDavid Hildenbrand         }
719ca28f548SDavid Hildenbrand         return -EINVAL;
720ca28f548SDavid Hildenbrand     }
721ca28f548SDavid Hildenbrand 
722ca28f548SDavid Hildenbrand     errno = 0;
723ca28f548SDavid Hildenbrand     *result = strtod(nptr, &ep);
7246162f7daSEric Blake     return check_strtox_error(nptr, ep, endptr, false, errno);
725ca28f548SDavid Hildenbrand }
726ca28f548SDavid Hildenbrand 
727ca28f548SDavid Hildenbrand /**
728ca28f548SDavid Hildenbrand  * Convert string @nptr to a finite double.
729ca28f548SDavid Hildenbrand  *
730ca28f548SDavid Hildenbrand  * Works like qemu_strtod(), except that "NaN" and "inf" are rejected
731ca28f548SDavid Hildenbrand  * with -EINVAL and no conversion is performed.
732ca28f548SDavid Hildenbrand  */
733ca28f548SDavid Hildenbrand int qemu_strtod_finite(const char *nptr, const char **endptr, double *result)
734ca28f548SDavid Hildenbrand {
735ca28f548SDavid Hildenbrand     double tmp;
736ca28f548SDavid Hildenbrand     int ret;
737ca28f548SDavid Hildenbrand 
738ca28f548SDavid Hildenbrand     ret = qemu_strtod(nptr, endptr, &tmp);
739ca28f548SDavid Hildenbrand     if (!ret && !isfinite(tmp)) {
740ca28f548SDavid Hildenbrand         if (endptr) {
741ca28f548SDavid Hildenbrand             *endptr = nptr;
742ca28f548SDavid Hildenbrand         }
743ca28f548SDavid Hildenbrand         ret = -EINVAL;
744ca28f548SDavid Hildenbrand     }
745ca28f548SDavid Hildenbrand 
746ca28f548SDavid Hildenbrand     if (ret != -EINVAL) {
747ca28f548SDavid Hildenbrand         *result = tmp;
748ca28f548SDavid Hildenbrand     }
749ca28f548SDavid Hildenbrand     return ret;
750ca28f548SDavid Hildenbrand }
751ca28f548SDavid Hildenbrand 
752ca28f548SDavid Hildenbrand /**
7535c99fa37SKeno Fischer  * Searches for the first occurrence of 'c' in 's', and returns a pointer
7545c99fa37SKeno Fischer  * to the trailing null byte if none was found.
7555c99fa37SKeno Fischer  */
7565c99fa37SKeno Fischer #ifndef HAVE_STRCHRNUL
7575c99fa37SKeno Fischer const char *qemu_strchrnul(const char *s, int c)
7585c99fa37SKeno Fischer {
7595c99fa37SKeno Fischer     const char *e = strchr(s, c);
7605c99fa37SKeno Fischer     if (!e) {
7615c99fa37SKeno Fischer         e = s + strlen(s);
7625c99fa37SKeno Fischer     }
7635c99fa37SKeno Fischer     return e;
7645c99fa37SKeno Fischer }
7655c99fa37SKeno Fischer #endif
7665c99fa37SKeno Fischer 
7675c99fa37SKeno Fischer /**
768e3f9fe2dSEduardo Habkost  * parse_uint:
769e3f9fe2dSEduardo Habkost  *
770e3f9fe2dSEduardo Habkost  * @s: String to parse
771e3f9fe2dSEduardo Habkost  * @value: Destination for parsed integer value
772e3f9fe2dSEduardo Habkost  * @endptr: Destination for pointer to first character not consumed
773e3f9fe2dSEduardo Habkost  * @base: integer base, between 2 and 36 inclusive, or 0
774e3f9fe2dSEduardo Habkost  *
775e3f9fe2dSEduardo Habkost  * Parse unsigned integer
776e3f9fe2dSEduardo Habkost  *
777e3f9fe2dSEduardo Habkost  * Parsed syntax is like strtoull()'s: arbitrary whitespace, a single optional
778e3f9fe2dSEduardo Habkost  * '+' or '-', an optional "0x" if @base is 0 or 16, one or more digits.
779e3f9fe2dSEduardo Habkost  *
780e3f9fe2dSEduardo Habkost  * If @s is null, or @base is invalid, or @s doesn't start with an
781e3f9fe2dSEduardo Habkost  * integer in the syntax above, set *@value to 0, *@endptr to @s, and
782e3f9fe2dSEduardo Habkost  * return -EINVAL.
783e3f9fe2dSEduardo Habkost  *
784e3f9fe2dSEduardo Habkost  * Set *@endptr to point right beyond the parsed integer (even if the integer
785e3f9fe2dSEduardo Habkost  * overflows or is negative, all digits will be parsed and *@endptr will
786e3f9fe2dSEduardo Habkost  * point right beyond them).
787e3f9fe2dSEduardo Habkost  *
788e3f9fe2dSEduardo Habkost  * If the integer is negative, set *@value to 0, and return -ERANGE.
789e3f9fe2dSEduardo Habkost  *
790e3f9fe2dSEduardo Habkost  * If the integer overflows unsigned long long, set *@value to
791e3f9fe2dSEduardo Habkost  * ULLONG_MAX, and return -ERANGE.
792e3f9fe2dSEduardo Habkost  *
793e3f9fe2dSEduardo Habkost  * Else, set *@value to the parsed integer, and return 0.
794e3f9fe2dSEduardo Habkost  */
795e3f9fe2dSEduardo Habkost int parse_uint(const char *s, unsigned long long *value, char **endptr,
796e3f9fe2dSEduardo Habkost                int base)
797e3f9fe2dSEduardo Habkost {
798e3f9fe2dSEduardo Habkost     int r = 0;
799e3f9fe2dSEduardo Habkost     char *endp = (char *)s;
800e3f9fe2dSEduardo Habkost     unsigned long long val = 0;
801e3f9fe2dSEduardo Habkost 
80253a90b97SEric Blake     assert((unsigned) base <= 36 && base != 1);
803e3f9fe2dSEduardo Habkost     if (!s) {
804e3f9fe2dSEduardo Habkost         r = -EINVAL;
805e3f9fe2dSEduardo Habkost         goto out;
806e3f9fe2dSEduardo Habkost     }
807e3f9fe2dSEduardo Habkost 
808e3f9fe2dSEduardo Habkost     errno = 0;
809e3f9fe2dSEduardo Habkost     val = strtoull(s, &endp, base);
810e3f9fe2dSEduardo Habkost     if (errno) {
811e3f9fe2dSEduardo Habkost         r = -errno;
812e3f9fe2dSEduardo Habkost         goto out;
813e3f9fe2dSEduardo Habkost     }
814e3f9fe2dSEduardo Habkost 
815e3f9fe2dSEduardo Habkost     if (endp == s) {
816e3f9fe2dSEduardo Habkost         r = -EINVAL;
817e3f9fe2dSEduardo Habkost         goto out;
818e3f9fe2dSEduardo Habkost     }
819e3f9fe2dSEduardo Habkost 
820e3f9fe2dSEduardo Habkost     /* make sure we reject negative numbers: */
821db3d11eeSMarkus Armbruster     while (qemu_isspace(*s)) {
822e3f9fe2dSEduardo Habkost         s++;
823e3f9fe2dSEduardo Habkost     }
824e3f9fe2dSEduardo Habkost     if (*s == '-') {
825e3f9fe2dSEduardo Habkost         val = 0;
826e3f9fe2dSEduardo Habkost         r = -ERANGE;
827e3f9fe2dSEduardo Habkost         goto out;
828e3f9fe2dSEduardo Habkost     }
829e3f9fe2dSEduardo Habkost 
830e3f9fe2dSEduardo Habkost out:
831e3f9fe2dSEduardo Habkost     *value = val;
832e3f9fe2dSEduardo Habkost     *endptr = endp;
833e3f9fe2dSEduardo Habkost     return r;
834e3f9fe2dSEduardo Habkost }
835e3f9fe2dSEduardo Habkost 
836e3f9fe2dSEduardo Habkost /**
837e3f9fe2dSEduardo Habkost  * parse_uint_full:
838e3f9fe2dSEduardo Habkost  *
839e3f9fe2dSEduardo Habkost  * @s: String to parse
840e3f9fe2dSEduardo Habkost  * @value: Destination for parsed integer value
841e3f9fe2dSEduardo Habkost  * @base: integer base, between 2 and 36 inclusive, or 0
842e3f9fe2dSEduardo Habkost  *
843e3f9fe2dSEduardo Habkost  * Parse unsigned integer from entire string
844e3f9fe2dSEduardo Habkost  *
845e3f9fe2dSEduardo Habkost  * Have the same behavior of parse_uint(), but with an additional check
846e3f9fe2dSEduardo Habkost  * for additional data after the parsed number. If extra characters are present
847e3f9fe2dSEduardo Habkost  * after the parsed number, the function will return -EINVAL, and *@v will
848e3f9fe2dSEduardo Habkost  * be set to 0.
849e3f9fe2dSEduardo Habkost  */
850e3f9fe2dSEduardo Habkost int parse_uint_full(const char *s, unsigned long long *value, int base)
851e3f9fe2dSEduardo Habkost {
852e3f9fe2dSEduardo Habkost     char *endp;
853e3f9fe2dSEduardo Habkost     int r;
854e3f9fe2dSEduardo Habkost 
855e3f9fe2dSEduardo Habkost     r = parse_uint(s, value, &endp, base);
856e3f9fe2dSEduardo Habkost     if (r < 0) {
857e3f9fe2dSEduardo Habkost         return r;
858e3f9fe2dSEduardo Habkost     }
859e3f9fe2dSEduardo Habkost     if (*endp) {
860e3f9fe2dSEduardo Habkost         *value = 0;
861e3f9fe2dSEduardo Habkost         return -EINVAL;
862e3f9fe2dSEduardo Habkost     }
863e3f9fe2dSEduardo Habkost 
864e3f9fe2dSEduardo Habkost     return 0;
865e3f9fe2dSEduardo Habkost }
866e3f9fe2dSEduardo Habkost 
867baacf047SPaolo Bonzini int qemu_parse_fd(const char *param)
868baacf047SPaolo Bonzini {
869e9c5c1f4SLaszlo Ersek     long fd;
870e9c5c1f4SLaszlo Ersek     char *endptr;
871baacf047SPaolo Bonzini 
872e9c5c1f4SLaszlo Ersek     errno = 0;
873baacf047SPaolo Bonzini     fd = strtol(param, &endptr, 10);
874e9c5c1f4SLaszlo Ersek     if (param == endptr /* no conversion performed */                    ||
875e9c5c1f4SLaszlo Ersek         errno != 0      /* not representable as long; possibly others */ ||
876e9c5c1f4SLaszlo Ersek         *endptr != '\0' /* final string not empty */                     ||
877e9c5c1f4SLaszlo Ersek         fd < 0          /* invalid as file descriptor */                 ||
878e9c5c1f4SLaszlo Ersek         fd > INT_MAX    /* not representable as int */) {
879baacf047SPaolo Bonzini         return -1;
880baacf047SPaolo Bonzini     }
881baacf047SPaolo Bonzini     return fd;
882baacf047SPaolo Bonzini }
883baacf047SPaolo Bonzini 
884baacf047SPaolo Bonzini /*
885baacf047SPaolo Bonzini  * Implementation of  ULEB128 (http://en.wikipedia.org/wiki/LEB128)
886baacf047SPaolo Bonzini  * Input is limited to 14-bit numbers
887baacf047SPaolo Bonzini  */
888baacf047SPaolo Bonzini int uleb128_encode_small(uint8_t *out, uint32_t n)
889baacf047SPaolo Bonzini {
890baacf047SPaolo Bonzini     g_assert(n <= 0x3fff);
891baacf047SPaolo Bonzini     if (n < 0x80) {
8927c960d61SWei Yang         *out = n;
893baacf047SPaolo Bonzini         return 1;
894baacf047SPaolo Bonzini     } else {
895baacf047SPaolo Bonzini         *out++ = (n & 0x7f) | 0x80;
8967c960d61SWei Yang         *out = n >> 7;
897baacf047SPaolo Bonzini         return 2;
898baacf047SPaolo Bonzini     }
899baacf047SPaolo Bonzini }
900baacf047SPaolo Bonzini 
901baacf047SPaolo Bonzini int uleb128_decode_small(const uint8_t *in, uint32_t *n)
902baacf047SPaolo Bonzini {
903baacf047SPaolo Bonzini     if (!(*in & 0x80)) {
9047c960d61SWei Yang         *n = *in;
905baacf047SPaolo Bonzini         return 1;
906baacf047SPaolo Bonzini     } else {
907baacf047SPaolo Bonzini         *n = *in++ & 0x7f;
908baacf047SPaolo Bonzini         /* we exceed 14 bit number */
909baacf047SPaolo Bonzini         if (*in & 0x80) {
910baacf047SPaolo Bonzini             return -1;
911baacf047SPaolo Bonzini         }
9127c960d61SWei Yang         *n |= *in << 7;
913baacf047SPaolo Bonzini         return 2;
914baacf047SPaolo Bonzini     }
915baacf047SPaolo Bonzini }
916b16352acSAlon Levy 
917b16352acSAlon Levy /*
918b16352acSAlon Levy  * helper to parse debug environment variables
919b16352acSAlon Levy  */
920b16352acSAlon Levy int parse_debug_env(const char *name, int max, int initial)
921b16352acSAlon Levy {
922b16352acSAlon Levy     char *debug_env = getenv(name);
923b16352acSAlon Levy     char *inv = NULL;
924cc5d0e04SPaolo Bonzini     long debug;
925b16352acSAlon Levy 
926b16352acSAlon Levy     if (!debug_env) {
927b16352acSAlon Levy         return initial;
928b16352acSAlon Levy     }
929cc5d0e04SPaolo Bonzini     errno = 0;
930b16352acSAlon Levy     debug = strtol(debug_env, &inv, 10);
931b16352acSAlon Levy     if (inv == debug_env) {
932b16352acSAlon Levy         return initial;
933b16352acSAlon Levy     }
934cc5d0e04SPaolo Bonzini     if (debug < 0 || debug > max || errno != 0) {
93505cb8ed5SAlistair Francis         warn_report("%s not in [0, %d]", name, max);
936b16352acSAlon Levy         return initial;
937b16352acSAlon Levy     }
938b16352acSAlon Levy     return debug;
939b16352acSAlon Levy }
9404297c8eeSAlexey Kardashevskiy 
9414297c8eeSAlexey Kardashevskiy /*
9424297c8eeSAlexey Kardashevskiy  * Helper to print ethernet mac address
9434297c8eeSAlexey Kardashevskiy  */
9444297c8eeSAlexey Kardashevskiy const char *qemu_ether_ntoa(const MACAddr *mac)
9454297c8eeSAlexey Kardashevskiy {
9464297c8eeSAlexey Kardashevskiy     static char ret[18];
9474297c8eeSAlexey Kardashevskiy 
9484297c8eeSAlexey Kardashevskiy     snprintf(ret, sizeof(ret), "%02x:%02x:%02x:%02x:%02x:%02x",
9494297c8eeSAlexey Kardashevskiy              mac->a[0], mac->a[1], mac->a[2], mac->a[3], mac->a[4], mac->a[5]);
9504297c8eeSAlexey Kardashevskiy 
9514297c8eeSAlexey Kardashevskiy     return ret;
9524297c8eeSAlexey Kardashevskiy }
95322951aaaSPeter Xu 
95422951aaaSPeter Xu /*
95522951aaaSPeter Xu  * Return human readable string for size @val.
95622951aaaSPeter Xu  * @val can be anything that uint64_t allows (no more than "16 EiB").
95722951aaaSPeter Xu  * Use IEC binary units like KiB, MiB, and so forth.
95822951aaaSPeter Xu  * Caller is responsible for passing it to g_free().
95922951aaaSPeter Xu  */
96022951aaaSPeter Xu char *size_to_str(uint64_t val)
96122951aaaSPeter Xu {
96222951aaaSPeter Xu     static const char *suffixes[] = { "", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei" };
963754da867SEric Blake     uint64_t div;
96422951aaaSPeter Xu     int i;
96522951aaaSPeter Xu 
96622951aaaSPeter Xu     /*
96722951aaaSPeter Xu      * The exponent (returned in i) minus one gives us
96822951aaaSPeter Xu      * floor(log2(val * 1024 / 1000).  The correction makes us
96922951aaaSPeter Xu      * switch to the higher power when the integer part is >= 1000.
97022951aaaSPeter Xu      * (see e41b509d68afb1f for more info)
97122951aaaSPeter Xu      */
97222951aaaSPeter Xu     frexp(val / (1000.0 / 1024.0), &i);
97322951aaaSPeter Xu     i = (i - 1) / 10;
97422951aaaSPeter Xu     div = 1ULL << (i * 10);
97522951aaaSPeter Xu 
97622951aaaSPeter Xu     return g_strdup_printf("%0.3g %sB", (double)val / div, suffixes[i]);
97722951aaaSPeter Xu }
97885e33a28SMarc-André Lureau 
979709616c7SPhilippe Mathieu-Daudé char *freq_to_str(uint64_t freq_hz)
980709616c7SPhilippe Mathieu-Daudé {
981709616c7SPhilippe Mathieu-Daudé     static const char *const suffixes[] = { "", "K", "M", "G", "T", "P", "E" };
982709616c7SPhilippe Mathieu-Daudé     double freq = freq_hz;
983709616c7SPhilippe Mathieu-Daudé     size_t idx = 0;
984709616c7SPhilippe Mathieu-Daudé 
9856d7ccc57SPhilippe Mathieu-Daudé     while (freq >= 1000.0) {
986709616c7SPhilippe Mathieu-Daudé         freq /= 1000.0;
987709616c7SPhilippe Mathieu-Daudé         idx++;
988709616c7SPhilippe Mathieu-Daudé     }
9896d7ccc57SPhilippe Mathieu-Daudé     assert(idx < ARRAY_SIZE(suffixes));
990709616c7SPhilippe Mathieu-Daudé 
991709616c7SPhilippe Mathieu-Daudé     return g_strdup_printf("%0.3g %sHz", freq, suffixes[idx]);
992709616c7SPhilippe Mathieu-Daudé }
993709616c7SPhilippe Mathieu-Daudé 
99485e33a28SMarc-André Lureau int qemu_pstrcmp0(const char **str1, const char **str2)
99585e33a28SMarc-André Lureau {
99685e33a28SMarc-André Lureau     return g_strcmp0(*str1, *str2);
99785e33a28SMarc-André Lureau }
998f4f5ed2cSPaolo Bonzini 
999f4f5ed2cSPaolo Bonzini static inline bool starts_with_prefix(const char *dir)
1000f4f5ed2cSPaolo Bonzini {
1001f4f5ed2cSPaolo Bonzini     size_t prefix_len = strlen(CONFIG_PREFIX);
1002f4f5ed2cSPaolo Bonzini     return !memcmp(dir, CONFIG_PREFIX, prefix_len) &&
1003f4f5ed2cSPaolo Bonzini         (!dir[prefix_len] || G_IS_DIR_SEPARATOR(dir[prefix_len]));
1004f4f5ed2cSPaolo Bonzini }
1005f4f5ed2cSPaolo Bonzini 
1006f4f5ed2cSPaolo Bonzini /* Return the next path component in dir, and store its length in *p_len.  */
1007f4f5ed2cSPaolo Bonzini static inline const char *next_component(const char *dir, int *p_len)
1008f4f5ed2cSPaolo Bonzini {
1009f4f5ed2cSPaolo Bonzini     int len;
1010342e3a4fSStefan Weil     while ((*dir && G_IS_DIR_SEPARATOR(*dir)) ||
1011342e3a4fSStefan Weil            (*dir == '.' && (G_IS_DIR_SEPARATOR(dir[1]) || dir[1] == '\0'))) {
1012f4f5ed2cSPaolo Bonzini         dir++;
1013f4f5ed2cSPaolo Bonzini     }
1014f4f5ed2cSPaolo Bonzini     len = 0;
1015f4f5ed2cSPaolo Bonzini     while (dir[len] && !G_IS_DIR_SEPARATOR(dir[len])) {
1016f4f5ed2cSPaolo Bonzini         len++;
1017f4f5ed2cSPaolo Bonzini     }
1018f4f5ed2cSPaolo Bonzini     *p_len = len;
1019f4f5ed2cSPaolo Bonzini     return dir;
1020f4f5ed2cSPaolo Bonzini }
1021f4f5ed2cSPaolo Bonzini 
1022f4f5ed2cSPaolo Bonzini char *get_relocated_path(const char *dir)
1023f4f5ed2cSPaolo Bonzini {
1024f4f5ed2cSPaolo Bonzini     size_t prefix_len = strlen(CONFIG_PREFIX);
1025f4f5ed2cSPaolo Bonzini     const char *bindir = CONFIG_BINDIR;
1026f4f5ed2cSPaolo Bonzini     const char *exec_dir = qemu_get_exec_dir();
1027f4f5ed2cSPaolo Bonzini     GString *result;
1028f4f5ed2cSPaolo Bonzini     int len_dir, len_bindir;
1029f4f5ed2cSPaolo Bonzini 
1030f4f5ed2cSPaolo Bonzini     /* Fail if qemu_init_exec_dir was not called.  */
1031f4f5ed2cSPaolo Bonzini     assert(exec_dir[0]);
1032f4f5ed2cSPaolo Bonzini     if (!starts_with_prefix(dir) || !starts_with_prefix(bindir)) {
1033090afdc5SPaolo Bonzini         return g_strdup(dir);
1034f4f5ed2cSPaolo Bonzini     }
1035f4f5ed2cSPaolo Bonzini 
1036f4f5ed2cSPaolo Bonzini     result = g_string_new(exec_dir);
1037f4f5ed2cSPaolo Bonzini 
1038f4f5ed2cSPaolo Bonzini     /* Advance over common components.  */
1039f4f5ed2cSPaolo Bonzini     len_dir = len_bindir = prefix_len;
1040f4f5ed2cSPaolo Bonzini     do {
1041f4f5ed2cSPaolo Bonzini         dir += len_dir;
1042f4f5ed2cSPaolo Bonzini         bindir += len_bindir;
1043f4f5ed2cSPaolo Bonzini         dir = next_component(dir, &len_dir);
1044f4f5ed2cSPaolo Bonzini         bindir = next_component(bindir, &len_bindir);
10457a3b7f6bSSunil Muthuswamy     } while (len_dir && len_dir == len_bindir && !memcmp(dir, bindir, len_dir));
1046f4f5ed2cSPaolo Bonzini 
1047f4f5ed2cSPaolo Bonzini     /* Ascend from bindir to the common prefix with dir.  */
1048f4f5ed2cSPaolo Bonzini     while (len_bindir) {
1049f4f5ed2cSPaolo Bonzini         bindir += len_bindir;
1050f4f5ed2cSPaolo Bonzini         g_string_append(result, "/..");
1051f4f5ed2cSPaolo Bonzini         bindir = next_component(bindir, &len_bindir);
1052f4f5ed2cSPaolo Bonzini     }
1053f4f5ed2cSPaolo Bonzini 
1054f4f5ed2cSPaolo Bonzini     if (*dir) {
1055f4f5ed2cSPaolo Bonzini         assert(G_IS_DIR_SEPARATOR(dir[-1]));
1056f4f5ed2cSPaolo Bonzini         g_string_append(result, dir - 1);
1057f4f5ed2cSPaolo Bonzini     }
1058*b6d003dbSStefano Garzarella     return g_string_free(result, false);
1059f4f5ed2cSPaolo Bonzini }
1060