1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 #ifndef __LXC_STRING_UTILS_H
4 #define __LXC_STRING_UTILS_H
10 #include "initutils.h"
14 #include "include/strlcat.h"
17 /* convert variadic argument lists to arrays (for execl type argument lists) */
18 __hidden
extern char **lxc_va_arg_list_to_argv(va_list ap
, size_t skip
, int do_strdup
);
19 __hidden
extern const char **lxc_va_arg_list_to_argv_const(va_list ap
, size_t skip
);
22 * Some simple string functions; if they return pointers, they are allocated
25 __hidden
extern char *lxc_string_replace(const char *needle
, const char *replacement
,
26 const char *haystack
);
27 __hidden
extern bool lxc_string_in_array(const char *needle
, const char **haystack
);
28 __hidden
extern char *lxc_string_join(const char *sep
, const char **parts
, bool use_as_prefix
);
30 * Normalize and split path: Leading and trailing / are removed, multiple
31 * / are compactified, .. and . are resolved (.. on the top level is considered
35 * foo/../bar -> { bar, NULL }
37 * ./bar/baz/.. -> { bar, NULL }
38 * foo//bar -> { foo, bar, NULL }
40 __hidden
extern char **lxc_normalize_path(const char *path
);
42 /* remove multiple slashes from the path, e.g. ///foo//bar -> /foo/bar */
43 __hidden
extern char *lxc_deslashify(const char *path
);
44 __hidden
extern char *lxc_append_paths(const char *first
, const char *second
);
47 * Note: the following two functions use strtok(), so they will never
48 * consider an empty element, even if two delimiters are next to
51 __hidden
extern bool lxc_string_in_list(const char *needle
, const char *haystack
, char sep
);
52 __hidden
extern char **lxc_string_split(const char *string
, char sep
);
53 __hidden
extern char **lxc_string_split_and_trim(const char *string
, char sep
);
54 __hidden
extern char **lxc_string_split_quoted(char *string
);
56 /* Append string to NULL-terminated string array. */
57 __hidden
extern int lxc_append_string(char ***list
, char *entry
);
59 /* Some simple array manipulation utilities */
60 typedef void (*lxc_free_fn
)(void *);
61 typedef void *(*lxc_dup_fn
)(void *);
62 __hidden
extern int lxc_grow_array(void ***array
, size_t *capacity
, size_t new_size
,
63 size_t capacity_increment
);
64 __hidden
extern void lxc_free_array(void **array
, lxc_free_fn element_free_fn
);
65 __hidden
extern size_t lxc_array_len(void **array
);
67 __hidden
extern void **lxc_append_null_to_array(void **array
, size_t count
);
68 __hidden
extern void remove_trailing_newlines(char *l
);
70 /* Helper functions to parse numbers. */
71 __hidden
extern int lxc_safe_uint(const char *numstr
, unsigned int *converted
);
72 __hidden
extern int lxc_safe_int(const char *numstr
, int *converted
);
73 __hidden
extern int lxc_safe_long(const char *numstr
, long int *converted
);
74 __hidden
extern int lxc_safe_long_long(const char *numstr
, long long int *converted
);
75 __hidden
extern int lxc_safe_ulong(const char *numstr
, unsigned long *converted
);
76 __hidden
extern int lxc_safe_uint64(const char *numstr
, uint64_t *converted
, int base
);
77 __hidden
extern int lxc_safe_int64_residual(const char *numstr
, int64_t *converted
, int base
,
78 char *residual
, size_t residual_len
);
79 /* Handles B, kb, MB, GB. Detects overflows and reports -ERANGE. */
80 __hidden
extern int parse_byte_size_string(const char *s
, int64_t *converted
);
83 * Concatenate all passed-in strings into one path. Do not fail. If any piece
84 * is not prefixed with '/', add a '/'.
86 __hidden
__attribute__((sentinel
)) extern char *must_concat(size_t *len
, const char *first
, ...);
87 __hidden
__attribute__((sentinel
)) extern char *must_make_path(const char *first
, ...);
88 __hidden
__attribute__((sentinel
)) extern char *must_append_path(char *first
, ...);
90 #define must_make_path_relative(__first__, ...) \
93 if (*__first__ == '/') \
94 __ptr__ = must_make_path(".", __first__, __VA_ARGS__); \
96 __ptr__ = must_make_path(__first__, __VA_ARGS__); \
100 /* Return copy of string @entry. Do not fail. */
101 __hidden
extern char *must_copy_string(const char *entry
);
103 /* Re-allocate a pointer, do not fail */
104 __hidden
extern void *must_realloc(void *orig
, size_t sz
);
106 __hidden
extern int lxc_char_left_gc(const char *buffer
, size_t len
);
108 __hidden
extern int lxc_char_right_gc(const char *buffer
, size_t len
);
110 __hidden
extern char *lxc_trim_whitespace_in_place(char *buffer
);
112 __hidden
extern int lxc_is_line_empty(const char *line
);
113 __hidden
extern void remove_trailing_slashes(char *p
);
115 static inline bool is_empty_string(const char *s
)
117 return !s
|| strcmp(s
, "") == 0;
120 #define maybe_empty(s) ((!is_empty_string(s)) ? (s) : ("(null)"))
122 static inline ssize_t
safe_strlcat(char *src
, const char *append
, size_t len
)
126 new_len
= strlcat(src
, append
, len
);
128 return ret_errno(EINVAL
);
130 return (ssize_t
)new_len
;
133 static inline bool strnequal(const char *str
, const char *eq
, size_t len
)
135 return strncmp(str
, eq
, len
) == 0;
138 static inline bool strequal(const char *str
, const char *eq
)
140 return strcmp(str
, eq
) == 0;
143 #endif /* __LXC_STRING_UTILS_H */