2 * Copyright © 2008 Kristian Høgsberg
3 * Copyright © 2013-2015 Red Hat, Inc.
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
46 #include "util-macros.h"
49 streq(const char *str1, const char *str2)
51 /* one NULL, one not NULL is always false */
53 return strcmp(str1, str2) == 0;
58 strneq(const char *str1, const char *str2, int n)
60 /* one NULL, one not NULL is always false */
62 return strncmp(str1, str2, n) == 0;
71 /* We never need to alloc anything more than 1,5 MB so we can assume
72 * if we ever get above that something's going wrong */
73 if (size > 1536 * 1024)
74 assert(!"bug: internal malloc size limit exceeded");
84 * strdup guaranteed to succeed. If the input string is NULL, the output
85 * string is NULL. If the input string is a string pointer, we strdup or
89 safe_strdup(const char *str)
103 * Simple wrapper for asprintf that ensures the passed in-pointer is set
104 * to NULL upon error.
105 * The standard asprintf() call does not guarantee the passed in pointer
106 * will be NULL'ed upon failure, whereas this wrapper does.
108 * @param strp pointer to set to newly allocated string.
109 * This pointer should be passed to free() to release when done.
110 * @param fmt the format string to use for printing.
111 * @return The number of bytes printed (excluding the null byte terminator)
112 * upon success or -1 upon failure. In the case of failure the pointer is set
115 __attribute__ ((format (printf, 2, 3)))
117 xasprintf(char **strp, const char *fmt, ...)
123 rc = vasprintf(strp, fmt, args);
125 if ((rc == -1) && strp)
131 __attribute__ ((format (printf, 2, 0)))
133 xvasprintf(char **strp, const char *fmt, va_list args)
136 rc = vasprintf(strp, fmt, args);
137 if ((rc == -1) && strp)
144 safe_atoi_base(const char *str, int *val, int base)
149 assert(base == 10 || base == 16 || base == 8);
152 v = strtol(str, &endptr, base);
157 if (*str != '\0' && *endptr != '\0')
160 if (v >= INT_MAX || v <= INT_MIN)
168 safe_atoi(const char *str, int *val)
170 return safe_atoi_base(str, val, 10);
174 safe_atou_base(const char *str, unsigned int *val, int base)
179 assert(base == 10 || base == 16 || base == 8);
182 v = strtoul(str, &endptr, base);
187 if (*str != '\0' && *endptr != '\0')
198 safe_atou(const char *str, unsigned int *val)
200 return safe_atou_base(str, val, 10);
204 safe_atod(const char *str, double *val)
211 size_t slen = strlen(str);
213 /* We don't have a use-case where we want to accept hex for a double
214 * or any of the other values strtod can parse */
215 for (size_t i = 0; i < slen; i++) {
231 /* Create a "C" locale to force strtod to use '.' as separator */
232 c_locale = newlocale(LC_NUMERIC_MASK, "C", (locale_t)0);
233 if (c_locale == (locale_t)0)
237 v = strtod_l(str, &endptr, c_locale);
238 freelocale(c_locale);
240 /* No locale support in provided libc, assume it already uses '.' */
242 v = strtod(str, &endptr);
248 if (*str != '\0' && *endptr != '\0')
250 if (v != 0.0 && !isnormal(v))
257 char **strv_from_argv(int argc, char **argv);
258 char **strv_from_string(const char *in, const char *separator, size_t *num_elements);
259 char *strv_join(char **strv, const char *joiner);
262 strv_free(char **strv) {
270 *s = (char*)0x1; /* detect use-after-free */
277 struct key_value_str{
282 struct key_value_double {
287 static inline ssize_t
288 kv_double_from_string(const char *string,
289 const char *pair_separator,
290 const char *kv_separator,
291 struct key_value_double **result_out)
294 struct key_value_double *result = NULL;
296 if (!pair_separator || pair_separator[0] == '\0' ||
297 !kv_separator || kv_separator[0] == '\0')
301 char **pairs = strv_from_string(string, pair_separator, &npairs);
302 if (!pairs || npairs == 0)
305 result = zalloc(npairs * sizeof *result);
307 for (size_t idx = 0; idx < npairs; idx++) {
308 char *pair = pairs[idx];
310 char **kv = strv_from_string(pair, kv_separator, &nelem);
313 if (!kv || nelem != 2 ||
314 !safe_atod(kv[0], &k) ||
315 !safe_atod(kv[1], &v)) {
321 result[idx].value = v;
328 *result_out = result;
339 * Strip any of the characters in what from the beginning and end of the
342 * @return a newly allocated string with none of "what" at the beginning or
346 strstrip(const char *input, const char *what)
350 str = safe_strdup(&input[strspn(input, what)]);
354 for (char *c = str; *c != '\0'; c++) {
355 if (!strchr(what, *c))
365 * Return true if str ends in suffix, false otherwise. If the suffix is the
366 * empty string, strendswith() always returns false.
369 strendswith(const char *str, const char *suffix)
371 size_t slen = strlen(str);
372 size_t suffixlen = strlen(suffix);
375 if (slen == 0 || suffixlen == 0 || suffixlen > slen)
378 offset = slen - suffixlen;
379 return strneq(&str[offset], suffix, suffixlen);
383 strstartswith(const char *str, const char *prefix)
385 size_t prefixlen = strlen(prefix);
387 return prefixlen > 0 ? strneq(str, prefix, strlen(prefix)) : false;
391 safe_basename(const char *filename);
394 trunkname(const char *filename);
397 * Return a copy of str with all % converted to %% to make the string
398 * acceptable as printf format.
401 str_sanitize(const char *str)
406 if (!strchr(str, '%'))
409 size_t slen = min(strlen(str), 512);
410 char *sanitized = zalloc(2 * slen + 1);
411 const char *src = str;
412 char *dst = sanitized;
414 for (size_t i = 0; i < slen; i++) {