/src/util-linux/include/strutils.h
Line | Count | Source |
1 | | /* |
2 | | * No copyright is claimed. This code is in the public domain; do with |
3 | | * it what you wish. |
4 | | */ |
5 | | #ifndef UTIL_LINUX_STRUTILS |
6 | | #define UTIL_LINUX_STRUTILS |
7 | | |
8 | | #include <stdlib.h> |
9 | | #include <inttypes.h> |
10 | | #include <string.h> |
11 | | #include <strings.h> |
12 | | #include <sys/types.h> |
13 | | #include <ctype.h> |
14 | | #include <stdio.h> |
15 | | #include <errno.h> |
16 | | #include <time.h> |
17 | | #include <stdbool.h> |
18 | | |
19 | | #include "c.h" |
20 | | |
21 | | /* initialize a custom exit code for all *_or_err functions */ |
22 | | extern void strutils_set_exitcode(int exit_code); |
23 | | |
24 | | extern int ul_parse_size(const char *str, uintmax_t *res, int *power); |
25 | | extern int strtosize(const char *str, uintmax_t *res); |
26 | | extern uintmax_t strtosize_or_err(const char *str, const char *errmesg); |
27 | | |
28 | | extern int ul_strtos64(const char *str, int64_t *num, int base); |
29 | | extern int ul_strtou64(const char *str, uint64_t *num, int base); |
30 | | extern int ul_strtos32(const char *str, int32_t *num, int base); |
31 | | extern int ul_strtou32(const char *str, uint32_t *num, int base); |
32 | | extern int ul_strtou16(const char *str, uint16_t *num, int base); |
33 | | |
34 | | extern int ul_strtold(const char *str, long double *num); |
35 | | |
36 | | extern int64_t str2num_or_err(const char *str, int base, const char *errmesg, int64_t low, int64_t up); |
37 | | extern uint64_t str2unum_or_err(const char *str, int base, const char *errmesg, uint64_t up); |
38 | | |
39 | 0 | #define strtos64_or_err(_s, _e) str2num_or_err(_s, 10, _e, 0, 0) |
40 | | #define strtou64_or_err(_s, _e) str2unum_or_err(_s, 10, _e, 0) |
41 | | #define strtox64_or_err(_s, _e) str2unum_or_err(_s, 16, _e, 0) |
42 | | |
43 | | #define strtos32_or_err(_s, _e) (int32_t) str2num_or_err(_s, 10, _e, INT32_MIN, INT32_MAX) |
44 | | #define strtou32_or_err(_s, _e) (uint32_t) str2unum_or_err(_s, 10, _e, UINT32_MAX) |
45 | | #define strtox32_or_err(_s, _e) (uint32_t) str2unum_or_err(_s, 16, _e, UINT32_MAX) |
46 | | |
47 | | #define strtos16_or_err(_s, _e) (int16_t) str2num_or_err(_s, 10, _e, INT16_MIN, INT16_MAX) |
48 | | #define strtou16_or_err(_s, _e) (uint16_t) str2unum_or_err(_s, 10, _e, UINT16_MAX) |
49 | | #define strtox16_or_err(_s, _e) (uint16_t) str2unum_or_err(_s, 16, _e, UINT16_MAX) |
50 | | |
51 | | extern double strtod_or_err(const char *str, const char *errmesg); |
52 | | extern long double strtold_or_err(const char *str, const char *errmesg); |
53 | | |
54 | | #define strtol_or_err(_s, _e) (long) str2num_or_err(_s, 10, _e, LONG_MIN, LONG_MAX) |
55 | | #define strtopid_or_err(_s, _e) (pid_t) str2num_or_err(_s, 10, _e, 1, SINT_MAX(pid_t)) |
56 | | #define strtoul_or_err(_s, _e) (unsigned long) str2unum_or_err(_s, 10, _e, ULONG_MAX) |
57 | | |
58 | | extern void strtotimeval_or_err(const char *str, struct timeval *tv, |
59 | | const char *errmesg); |
60 | | extern void strtotimespec_or_err(const char *str, struct timespec *ts, |
61 | | const char *errmesg); |
62 | | extern time_t strtotime_or_err(const char *str, const char *errmesg); |
63 | | |
64 | | extern bool hyperlinkwanted(const char *mode); |
65 | | extern bool annotationwanted(const char *mode); |
66 | | |
67 | | extern int isdigit_strend(const char *str, const char **end); |
68 | | #define isdigit_string(_s) isdigit_strend(_s, NULL) |
69 | | |
70 | | extern int isxdigit_strend(const char *str, const char **end); |
71 | | #define isxdigit_string(_s) isxdigit_strend(_s, NULL) |
72 | | |
73 | | |
74 | | extern int ul_parse_switch(const char *arg, ...); |
75 | | |
76 | | #ifndef HAVE_MEMPCPY |
77 | | extern void *mempcpy(void *restrict dest, const void *restrict src, size_t n); |
78 | | #endif |
79 | | #ifndef HAVE_STRNLEN |
80 | | extern size_t strnlen(const char *s, size_t maxlen); |
81 | | #endif |
82 | | #ifndef HAVE_STRNDUP |
83 | | extern char *strndup(const char *s, size_t n); |
84 | | #endif |
85 | | #ifndef HAVE_STRNCHR |
86 | | extern char *strnchr(const char *s, size_t maxlen, int c); |
87 | | #endif |
88 | | |
89 | | /* caller guarantees n > 0 */ |
90 | | static inline int xstrncpy(char *dest, const char *src, size_t n) |
91 | 0 | { |
92 | 0 | size_t len = src ? strlen(src) : 0; |
93 | |
|
94 | 0 | if (!len) |
95 | 0 | return 0; |
96 | 0 | len = min(len, n - 1); |
97 | 0 | memcpy(dest, src, len); |
98 | 0 | dest[len] = 0; |
99 | 0 | return len; |
100 | 0 | } Unexecuted instantiation: gen_uuid.c:xstrncpy Unexecuted instantiation: probe.c:xstrncpy Unexecuted instantiation: partitions.c:xstrncpy Unexecuted instantiation: path.c:xstrncpy Unexecuted instantiation: sysfs.c:xstrncpy Unexecuted instantiation: devname.c:xstrncpy Unexecuted instantiation: devno.c:xstrncpy Unexecuted instantiation: buffer.c:xstrncpy Unexecuted instantiation: canonicalize.c:xstrncpy Unexecuted instantiation: mbsalign.c:xstrncpy Unexecuted instantiation: strv.c:xstrncpy Unexecuted instantiation: strutils.c:xstrncpy |
101 | | |
102 | | /* This is like strncpy(), but based on memcpy(), so compilers and static |
103 | | * analyzers do not complain when sizeof(destination) is the same as 'n' and |
104 | | * result is not terminated by zero. |
105 | | * |
106 | | * Use this function to copy string to logs with fixed sizes (wtmp/utmp. ...) |
107 | | * where string terminator is optional. |
108 | | */ |
109 | | static inline void * __attribute__((nonnull (1))) |
110 | | str2memcpy(void *dest, const char *src, size_t n) |
111 | 0 | { |
112 | 0 | size_t bytes = strlen(src) + 1; |
113 | 0 |
|
114 | 0 | if (bytes > n) |
115 | 0 | bytes = n; |
116 | 0 |
|
117 | 0 | memcpy(dest, src, bytes); |
118 | 0 | return dest; |
119 | 0 | } Unexecuted instantiation: gen_uuid.c:str2memcpy Unexecuted instantiation: probe.c:str2memcpy Unexecuted instantiation: partitions.c:str2memcpy Unexecuted instantiation: path.c:str2memcpy Unexecuted instantiation: sysfs.c:str2memcpy Unexecuted instantiation: devname.c:str2memcpy Unexecuted instantiation: devno.c:str2memcpy Unexecuted instantiation: buffer.c:str2memcpy Unexecuted instantiation: canonicalize.c:str2memcpy Unexecuted instantiation: mbsalign.c:str2memcpy Unexecuted instantiation: strv.c:str2memcpy Unexecuted instantiation: strutils.c:str2memcpy |
120 | | |
121 | | static inline char * __attribute__((nonnull (1))) |
122 | | mem2strcpy(char *dest, const void *src, size_t n, size_t nmax) |
123 | 0 | { |
124 | 0 | if (n + 1 > nmax) |
125 | 0 | n = nmax - 1; |
126 | 0 |
|
127 | 0 | memset(dest, '\0', nmax); |
128 | 0 | memcpy(dest, src, n); |
129 | 0 | return dest; |
130 | 0 | } Unexecuted instantiation: gen_uuid.c:mem2strcpy Unexecuted instantiation: probe.c:mem2strcpy Unexecuted instantiation: partitions.c:mem2strcpy Unexecuted instantiation: path.c:mem2strcpy Unexecuted instantiation: sysfs.c:mem2strcpy Unexecuted instantiation: devname.c:mem2strcpy Unexecuted instantiation: devno.c:mem2strcpy Unexecuted instantiation: buffer.c:mem2strcpy Unexecuted instantiation: canonicalize.c:mem2strcpy Unexecuted instantiation: mbsalign.c:mem2strcpy Unexecuted instantiation: strv.c:mem2strcpy Unexecuted instantiation: strutils.c:mem2strcpy |
131 | | |
132 | | /* Reallocate @str according to @newstr and copy @newstr to @str; returns new @str. |
133 | | * The @str is not modified if reallocation failed (like classic realloc()). |
134 | | */ |
135 | | static inline char * __attribute__((warn_unused_result)) |
136 | | strrealloc(char *str, const char *newstr) |
137 | 0 | { |
138 | 0 | size_t nsz, osz; |
139 | 0 |
|
140 | 0 | if (!str) |
141 | 0 | return newstr ? strdup(newstr) : NULL; |
142 | 0 | if (!newstr) |
143 | 0 | return NULL; |
144 | 0 |
|
145 | 0 | osz = strlen(str); |
146 | 0 | nsz = strlen(newstr); |
147 | 0 |
|
148 | 0 | if (nsz > osz) |
149 | 0 | str = realloc(str, nsz + 1); |
150 | 0 | if (str) |
151 | 0 | memcpy(str, newstr, nsz + 1); |
152 | 0 | return str; |
153 | 0 | } Unexecuted instantiation: gen_uuid.c:strrealloc Unexecuted instantiation: probe.c:strrealloc Unexecuted instantiation: partitions.c:strrealloc Unexecuted instantiation: path.c:strrealloc Unexecuted instantiation: sysfs.c:strrealloc Unexecuted instantiation: devname.c:strrealloc Unexecuted instantiation: devno.c:strrealloc Unexecuted instantiation: buffer.c:strrealloc Unexecuted instantiation: canonicalize.c:strrealloc Unexecuted instantiation: mbsalign.c:strrealloc Unexecuted instantiation: strv.c:strrealloc Unexecuted instantiation: strutils.c:strrealloc |
154 | | |
155 | | /* Copy string @str to struct @stru to member addressed by @offset */ |
156 | | static inline int strdup_to_offset(void *stru, size_t offset, const char *str) |
157 | 0 | { |
158 | 0 | char **o; |
159 | 0 | char *p = NULL; |
160 | 0 |
|
161 | 0 | if (!stru) |
162 | 0 | return -EINVAL; |
163 | 0 |
|
164 | 0 | o = (char **) ((char *) stru + offset); |
165 | 0 | if (str) { |
166 | 0 | p = strdup(str); |
167 | 0 | if (!p) |
168 | 0 | return -ENOMEM; |
169 | 0 | } |
170 | 0 |
|
171 | 0 | free(*o); |
172 | 0 | *o = p; |
173 | 0 | return 0; |
174 | 0 | } Unexecuted instantiation: gen_uuid.c:strdup_to_offset Unexecuted instantiation: probe.c:strdup_to_offset Unexecuted instantiation: partitions.c:strdup_to_offset Unexecuted instantiation: path.c:strdup_to_offset Unexecuted instantiation: sysfs.c:strdup_to_offset Unexecuted instantiation: devname.c:strdup_to_offset Unexecuted instantiation: devno.c:strdup_to_offset Unexecuted instantiation: buffer.c:strdup_to_offset Unexecuted instantiation: canonicalize.c:strdup_to_offset Unexecuted instantiation: mbsalign.c:strdup_to_offset Unexecuted instantiation: strv.c:strdup_to_offset Unexecuted instantiation: strutils.c:strdup_to_offset |
175 | | |
176 | | /* Copy string __str to struct member _m of the struct _s */ |
177 | | #define strdup_to_struct_member(_s, _m, _str) \ |
178 | | strdup_to_offset((void *) _s, offsetof(__typeof__(*(_s)), _m), _str) |
179 | | |
180 | | /* Copy string addressed by @offset between two structs */ |
181 | | static inline int strdup_between_offsets(void *stru_dst, void *stru_src, size_t offset) |
182 | 0 | { |
183 | 0 | char **src; |
184 | 0 | char **dst; |
185 | 0 | char *p = NULL; |
186 | 0 |
|
187 | 0 | if (!stru_src || !stru_dst) |
188 | 0 | return -EINVAL; |
189 | 0 |
|
190 | 0 | src = (char **) ((char *) stru_src + offset); |
191 | 0 | dst = (char **) ((char *) stru_dst + offset); |
192 | 0 |
|
193 | 0 | if (*src) { |
194 | 0 | p = strdup(*src); |
195 | 0 | if (!p) |
196 | 0 | return -ENOMEM; |
197 | 0 | } |
198 | 0 |
|
199 | 0 | free(*dst); |
200 | 0 | *dst = p; |
201 | 0 | return 0; |
202 | 0 | } Unexecuted instantiation: gen_uuid.c:strdup_between_offsets Unexecuted instantiation: probe.c:strdup_between_offsets Unexecuted instantiation: partitions.c:strdup_between_offsets Unexecuted instantiation: path.c:strdup_between_offsets Unexecuted instantiation: sysfs.c:strdup_between_offsets Unexecuted instantiation: devname.c:strdup_between_offsets Unexecuted instantiation: devno.c:strdup_between_offsets Unexecuted instantiation: buffer.c:strdup_between_offsets Unexecuted instantiation: canonicalize.c:strdup_between_offsets Unexecuted instantiation: mbsalign.c:strdup_between_offsets Unexecuted instantiation: strv.c:strdup_between_offsets Unexecuted instantiation: strutils.c:strdup_between_offsets |
203 | | |
204 | | /* Copy string addressed by struct member between two instances of the same |
205 | | * struct type */ |
206 | | #define strdup_between_structs(_dst, _src, _m) \ |
207 | | strdup_between_offsets((void *)_dst, (void *)_src, offsetof(__typeof__(*(_src)), _m)) |
208 | | |
209 | | static inline int is_nonnull_offset(const void *stru, size_t offset) |
210 | 0 | { |
211 | 0 | const char **o; |
212 | 0 |
|
213 | 0 | if (!stru) |
214 | 0 | return -EINVAL; |
215 | 0 |
|
216 | 0 | o = (const char **) ((const char *) stru + offset); |
217 | 0 | return *o != NULL; |
218 | 0 | } Unexecuted instantiation: gen_uuid.c:is_nonnull_offset Unexecuted instantiation: probe.c:is_nonnull_offset Unexecuted instantiation: partitions.c:is_nonnull_offset Unexecuted instantiation: path.c:is_nonnull_offset Unexecuted instantiation: sysfs.c:is_nonnull_offset Unexecuted instantiation: devname.c:is_nonnull_offset Unexecuted instantiation: devno.c:is_nonnull_offset Unexecuted instantiation: buffer.c:is_nonnull_offset Unexecuted instantiation: canonicalize.c:is_nonnull_offset Unexecuted instantiation: mbsalign.c:is_nonnull_offset Unexecuted instantiation: strv.c:is_nonnull_offset Unexecuted instantiation: strutils.c:is_nonnull_offset |
219 | | |
220 | | #define is_nonnull_member(_stru, _m) \ |
221 | | is_nonnull_offset((void *) _stru, offsetof(__typeof__(*(_stru)), _m)) |
222 | | |
223 | | static inline int strcmp_offsets(const void *sa, const void *sb, size_t offset) |
224 | 0 | { |
225 | 0 | const char **a = (const char **) ((const char *) sa + offset), |
226 | 0 | **b = (const char **) ((const char *) sb + offset); |
227 | 0 |
|
228 | 0 | if (!*a && !*b) |
229 | 0 | return 0; |
230 | 0 | if (!*a) |
231 | 0 | return -1; |
232 | 0 | if (!*b) |
233 | 0 | return 1; |
234 | 0 | return strcmp(*a, *b); |
235 | 0 | } Unexecuted instantiation: gen_uuid.c:strcmp_offsets Unexecuted instantiation: probe.c:strcmp_offsets Unexecuted instantiation: partitions.c:strcmp_offsets Unexecuted instantiation: path.c:strcmp_offsets Unexecuted instantiation: sysfs.c:strcmp_offsets Unexecuted instantiation: devname.c:strcmp_offsets Unexecuted instantiation: devno.c:strcmp_offsets Unexecuted instantiation: buffer.c:strcmp_offsets Unexecuted instantiation: canonicalize.c:strcmp_offsets Unexecuted instantiation: mbsalign.c:strcmp_offsets Unexecuted instantiation: strv.c:strcmp_offsets Unexecuted instantiation: strutils.c:strcmp_offsets |
236 | | |
237 | | #define strcmp_members(_a, _b, _m) \ |
238 | | strcmp_offsets((void *) _a, (void *) _b, offsetof(__typeof__(*(_a)), _m)) |
239 | | |
240 | | extern char *xstrmode(mode_t mode, char *str); |
241 | | |
242 | | /* Options for size_to_human_string() */ |
243 | | enum |
244 | | { |
245 | | SIZE_SUFFIX_1LETTER = 0, |
246 | | SIZE_SUFFIX_3LETTER = (1 << 0), |
247 | | SIZE_SUFFIX_SPACE = (1 << 1), |
248 | | SIZE_DECIMAL_2DIGITS = (1 << 2) |
249 | | }; |
250 | | |
251 | | extern char *size_to_human_string(int options, uint64_t bytes); |
252 | | |
253 | | extern int string_to_idarray(const char *list, int ary[], size_t arysz, |
254 | | int (name2id)(const char *, size_t)); |
255 | | extern int string_add_to_idarray(const char *list, int ary[], |
256 | | size_t arysz, size_t *ary_pos, |
257 | | int (name2id)(const char *, size_t)); |
258 | | |
259 | | extern int string_to_bitarray(const char *list, char *ary, |
260 | | int (*name2bit)(const char *, size_t), |
261 | | size_t allow_range); |
262 | | |
263 | | extern int string_to_bitmask(const char *list, |
264 | | unsigned long *mask, |
265 | | long (*name2flag)(const char *, size_t)); |
266 | | extern int ul_parse_range(const char *str, int *lower, int *upper, int def); |
267 | | |
268 | | extern int streq_paths(const char *a, const char *b); |
269 | | |
270 | | /* |
271 | | * Match string beginning. |
272 | | */ |
273 | | static inline const char *ul_startswith(const char *s, const char *prefix) |
274 | 0 | { |
275 | 0 | size_t sz = prefix ? strlen(prefix) : 0; |
276 | |
|
277 | 0 | if (s && sz && strncmp(s, prefix, sz) == 0) |
278 | 0 | return s + sz; |
279 | 0 | return NULL; |
280 | 0 | } Unexecuted instantiation: gen_uuid.c:ul_startswith Unexecuted instantiation: probe.c:ul_startswith Unexecuted instantiation: partitions.c:ul_startswith Unexecuted instantiation: path.c:ul_startswith Unexecuted instantiation: sysfs.c:ul_startswith Unexecuted instantiation: devname.c:ul_startswith Unexecuted instantiation: devno.c:ul_startswith Unexecuted instantiation: buffer.c:ul_startswith Unexecuted instantiation: canonicalize.c:ul_startswith Unexecuted instantiation: mbsalign.c:ul_startswith Unexecuted instantiation: strv.c:ul_startswith Unexecuted instantiation: strutils.c:ul_startswith |
281 | | |
282 | | /* |
283 | | * Case insensitive match string beginning. |
284 | | */ |
285 | | static inline const char *startswith_no_case(const char *s, const char *prefix) |
286 | 0 | { |
287 | 0 | size_t sz = prefix ? strlen(prefix) : 0; |
288 | 0 |
|
289 | 0 | if (s && sz && strncasecmp(s, prefix, sz) == 0) |
290 | 0 | return s + sz; |
291 | 0 | return NULL; |
292 | 0 | } Unexecuted instantiation: gen_uuid.c:startswith_no_case Unexecuted instantiation: probe.c:startswith_no_case Unexecuted instantiation: partitions.c:startswith_no_case Unexecuted instantiation: path.c:startswith_no_case Unexecuted instantiation: sysfs.c:startswith_no_case Unexecuted instantiation: devname.c:startswith_no_case Unexecuted instantiation: devno.c:startswith_no_case Unexecuted instantiation: buffer.c:startswith_no_case Unexecuted instantiation: canonicalize.c:startswith_no_case Unexecuted instantiation: mbsalign.c:startswith_no_case Unexecuted instantiation: strv.c:startswith_no_case Unexecuted instantiation: strutils.c:startswith_no_case |
293 | | |
294 | | /* |
295 | | * Match path beginning |
296 | | */ |
297 | | static inline const char *startswithpath(const char *s, const char *prefix) |
298 | 0 | { |
299 | 0 | const char *p = ul_startswith(s, prefix); |
300 | 0 |
|
301 | 0 | if (p && (*p == '/' || *p == '\0')) |
302 | 0 | return p; |
303 | 0 |
|
304 | 0 | return NULL; |
305 | 0 | } Unexecuted instantiation: gen_uuid.c:startswithpath Unexecuted instantiation: probe.c:startswithpath Unexecuted instantiation: partitions.c:startswithpath Unexecuted instantiation: path.c:startswithpath Unexecuted instantiation: sysfs.c:startswithpath Unexecuted instantiation: devname.c:startswithpath Unexecuted instantiation: devno.c:startswithpath Unexecuted instantiation: buffer.c:startswithpath Unexecuted instantiation: canonicalize.c:startswithpath Unexecuted instantiation: mbsalign.c:startswithpath Unexecuted instantiation: strv.c:startswithpath Unexecuted instantiation: strutils.c:startswithpath |
306 | | |
307 | | /* |
308 | | * Match string ending. |
309 | | */ |
310 | | static inline const char *ul_endswith(const char *s, const char *postfix) |
311 | 0 | { |
312 | 0 | size_t sl = s ? strlen(s) : 0; |
313 | 0 | size_t pl = postfix ? strlen(postfix) : 0; |
314 | 0 |
|
315 | 0 | if (pl == 0) |
316 | 0 | return s + sl; |
317 | 0 | if (sl < pl) |
318 | 0 | return NULL; |
319 | 0 | if (memcmp(s + sl - pl, postfix, pl) != 0) |
320 | 0 | return NULL; |
321 | 0 | return s + sl - pl; |
322 | 0 | } Unexecuted instantiation: gen_uuid.c:ul_endswith Unexecuted instantiation: probe.c:ul_endswith Unexecuted instantiation: partitions.c:ul_endswith Unexecuted instantiation: path.c:ul_endswith Unexecuted instantiation: sysfs.c:ul_endswith Unexecuted instantiation: devname.c:ul_endswith Unexecuted instantiation: devno.c:ul_endswith Unexecuted instantiation: buffer.c:ul_endswith Unexecuted instantiation: canonicalize.c:ul_endswith Unexecuted instantiation: mbsalign.c:ul_endswith Unexecuted instantiation: strv.c:ul_endswith Unexecuted instantiation: strutils.c:ul_endswith |
323 | | |
324 | | /* |
325 | | * Skip leading white space. |
326 | | */ |
327 | | static inline const char *skip_space(const char *p) |
328 | 0 | { |
329 | 0 | while (isspace(*p)) |
330 | 0 | ++p; |
331 | 0 | return p; |
332 | 0 | } Unexecuted instantiation: gen_uuid.c:skip_space Unexecuted instantiation: probe.c:skip_space Unexecuted instantiation: partitions.c:skip_space Unexecuted instantiation: path.c:skip_space Unexecuted instantiation: sysfs.c:skip_space Unexecuted instantiation: devname.c:skip_space Unexecuted instantiation: devno.c:skip_space Unexecuted instantiation: buffer.c:skip_space Unexecuted instantiation: canonicalize.c:skip_space Unexecuted instantiation: mbsalign.c:skip_space Unexecuted instantiation: strv.c:skip_space Unexecuted instantiation: strutils.c:skip_space |
333 | | |
334 | | static inline const char *skip_blank(const char *p) |
335 | 0 | { |
336 | 0 | while (isblank(*p)) |
337 | 0 | ++p; |
338 | 0 | return p; |
339 | 0 | } Unexecuted instantiation: gen_uuid.c:skip_blank Unexecuted instantiation: probe.c:skip_blank Unexecuted instantiation: partitions.c:skip_blank Unexecuted instantiation: path.c:skip_blank Unexecuted instantiation: sysfs.c:skip_blank Unexecuted instantiation: devname.c:skip_blank Unexecuted instantiation: devno.c:skip_blank Unexecuted instantiation: buffer.c:skip_blank Unexecuted instantiation: canonicalize.c:skip_blank Unexecuted instantiation: mbsalign.c:skip_blank Unexecuted instantiation: strv.c:skip_blank Unexecuted instantiation: strutils.c:skip_blank |
340 | | |
341 | | |
342 | | /* Removes whitespace from the right-hand side of a string (trailing |
343 | | * whitespace). |
344 | | * |
345 | | * Returns size of the new string (without \0). |
346 | | */ |
347 | | static inline size_t rtrim_whitespace(unsigned char *str) |
348 | 0 | { |
349 | 0 | size_t i; |
350 | |
|
351 | 0 | if (!str) |
352 | 0 | return 0; |
353 | 0 | i = strlen((char *) str); |
354 | 0 | while (i) { |
355 | 0 | i--; |
356 | 0 | if (!isspace(str[i])) { |
357 | 0 | i++; |
358 | 0 | break; |
359 | 0 | } |
360 | 0 | } |
361 | 0 | str[i] = '\0'; |
362 | 0 | return i; |
363 | 0 | } Unexecuted instantiation: gen_uuid.c:rtrim_whitespace Unexecuted instantiation: probe.c:rtrim_whitespace Unexecuted instantiation: partitions.c:rtrim_whitespace Unexecuted instantiation: path.c:rtrim_whitespace Unexecuted instantiation: sysfs.c:rtrim_whitespace Unexecuted instantiation: devname.c:rtrim_whitespace Unexecuted instantiation: devno.c:rtrim_whitespace Unexecuted instantiation: buffer.c:rtrim_whitespace Unexecuted instantiation: canonicalize.c:rtrim_whitespace Unexecuted instantiation: mbsalign.c:rtrim_whitespace Unexecuted instantiation: strv.c:rtrim_whitespace Unexecuted instantiation: strutils.c:rtrim_whitespace |
364 | | |
365 | | /* Removes whitespace from the left-hand side of a string. |
366 | | * |
367 | | * Returns size of the new string (without \0). |
368 | | */ |
369 | | static inline size_t ltrim_whitespace(unsigned char *str) |
370 | 0 | { |
371 | 0 | size_t len; |
372 | 0 | unsigned char *p; |
373 | |
|
374 | 0 | if (!str) |
375 | 0 | return 0; |
376 | 0 | for (p = str; *p && isspace(*p); p++); |
377 | |
|
378 | 0 | len = strlen((char *) p); |
379 | |
|
380 | 0 | if (p > str) |
381 | 0 | memmove(str, p, len + 1); |
382 | |
|
383 | 0 | return len; |
384 | 0 | } Unexecuted instantiation: gen_uuid.c:ltrim_whitespace Unexecuted instantiation: probe.c:ltrim_whitespace Unexecuted instantiation: partitions.c:ltrim_whitespace Unexecuted instantiation: path.c:ltrim_whitespace Unexecuted instantiation: sysfs.c:ltrim_whitespace Unexecuted instantiation: devname.c:ltrim_whitespace Unexecuted instantiation: devno.c:ltrim_whitespace Unexecuted instantiation: buffer.c:ltrim_whitespace Unexecuted instantiation: canonicalize.c:ltrim_whitespace Unexecuted instantiation: mbsalign.c:ltrim_whitespace Unexecuted instantiation: strv.c:ltrim_whitespace Unexecuted instantiation: strutils.c:ltrim_whitespace |
385 | | |
386 | | /* Removes left-hand, right-hand and repeating whitespaces. |
387 | | */ |
388 | | static inline size_t __normalize_whitespace( |
389 | | const unsigned char *src, |
390 | | size_t sz, |
391 | | unsigned char *dst, |
392 | | size_t len) |
393 | 0 | { |
394 | 0 | size_t i, x = 0; |
395 | 0 | int nsp = 0, intext = 0; |
396 | 0 |
|
397 | 0 | if (!sz) |
398 | 0 | goto done; |
399 | 0 |
|
400 | 0 | for (i = 0, x = 0; i < sz && x < len - 1; ) { |
401 | 0 | if (isspace(src[i])) |
402 | 0 | nsp++; |
403 | 0 | else |
404 | 0 | nsp = 0, intext = 1; |
405 | 0 |
|
406 | 0 | if (nsp > 1 || (nsp && !intext)) |
407 | 0 | i++; |
408 | 0 | else |
409 | 0 | dst[x++] = src[i++]; |
410 | 0 | } |
411 | 0 | if (nsp && x > 0) /* trailing space */ |
412 | 0 | x--; |
413 | 0 | done: |
414 | 0 | dst[x] = '\0'; |
415 | 0 | return x; |
416 | 0 | } Unexecuted instantiation: gen_uuid.c:__normalize_whitespace Unexecuted instantiation: probe.c:__normalize_whitespace Unexecuted instantiation: partitions.c:__normalize_whitespace Unexecuted instantiation: path.c:__normalize_whitespace Unexecuted instantiation: sysfs.c:__normalize_whitespace Unexecuted instantiation: devname.c:__normalize_whitespace Unexecuted instantiation: devno.c:__normalize_whitespace Unexecuted instantiation: buffer.c:__normalize_whitespace Unexecuted instantiation: canonicalize.c:__normalize_whitespace Unexecuted instantiation: mbsalign.c:__normalize_whitespace Unexecuted instantiation: strv.c:__normalize_whitespace Unexecuted instantiation: strutils.c:__normalize_whitespace |
417 | | |
418 | | static inline size_t normalize_whitespace(unsigned char *str) |
419 | 0 | { |
420 | 0 | size_t sz = strlen((char *) str); |
421 | 0 | return __normalize_whitespace(str, sz, str, sz + 1); |
422 | 0 | } Unexecuted instantiation: gen_uuid.c:normalize_whitespace Unexecuted instantiation: probe.c:normalize_whitespace Unexecuted instantiation: partitions.c:normalize_whitespace Unexecuted instantiation: path.c:normalize_whitespace Unexecuted instantiation: sysfs.c:normalize_whitespace Unexecuted instantiation: devname.c:normalize_whitespace Unexecuted instantiation: devno.c:normalize_whitespace Unexecuted instantiation: buffer.c:normalize_whitespace Unexecuted instantiation: canonicalize.c:normalize_whitespace Unexecuted instantiation: mbsalign.c:normalize_whitespace Unexecuted instantiation: strv.c:normalize_whitespace Unexecuted instantiation: strutils.c:normalize_whitespace |
423 | | |
424 | | static inline void ul_strrep(char *s, int find, int replace) |
425 | 0 | { |
426 | 0 | while (s && *s && (s = strchr(s, find)) != NULL) |
427 | 0 | *s++ = replace; |
428 | 0 | } Unexecuted instantiation: gen_uuid.c:ul_strrep Unexecuted instantiation: probe.c:ul_strrep Unexecuted instantiation: partitions.c:ul_strrep Unexecuted instantiation: path.c:ul_strrep Unexecuted instantiation: sysfs.c:ul_strrep Unexecuted instantiation: devname.c:ul_strrep Unexecuted instantiation: devno.c:ul_strrep Unexecuted instantiation: buffer.c:ul_strrep Unexecuted instantiation: canonicalize.c:ul_strrep Unexecuted instantiation: mbsalign.c:ul_strrep Unexecuted instantiation: strv.c:ul_strrep Unexecuted instantiation: strutils.c:ul_strrep |
429 | | |
430 | | static inline void ul_strrem(char *s, int rem) |
431 | 0 | { |
432 | 0 | char *p; |
433 | 0 |
|
434 | 0 | if (!s) |
435 | 0 | return; |
436 | 0 | for (p = s; *s; s++) { |
437 | 0 | if (*s != rem) |
438 | 0 | *p++ = *s; |
439 | 0 | } |
440 | 0 | *p = '\0'; |
441 | 0 | } Unexecuted instantiation: gen_uuid.c:ul_strrem Unexecuted instantiation: probe.c:ul_strrem Unexecuted instantiation: partitions.c:ul_strrem Unexecuted instantiation: path.c:ul_strrem Unexecuted instantiation: sysfs.c:ul_strrem Unexecuted instantiation: devname.c:ul_strrem Unexecuted instantiation: devno.c:ul_strrem Unexecuted instantiation: buffer.c:ul_strrem Unexecuted instantiation: canonicalize.c:ul_strrem Unexecuted instantiation: mbsalign.c:ul_strrem Unexecuted instantiation: strv.c:ul_strrem Unexecuted instantiation: strutils.c:ul_strrem |
442 | | |
443 | | /* returns next string after \0 if before @end */ |
444 | | static inline char *ul_next_string(char *p, char *end) |
445 | 0 | { |
446 | 0 | char *last; |
447 | 0 |
|
448 | 0 | if (!p || !end || p >= end) |
449 | 0 | return NULL; |
450 | 0 |
|
451 | 0 | for (last = p; p < end; p++) { |
452 | 0 | if (*last == '\0' && p != last) |
453 | 0 | return p; |
454 | 0 | last = p; |
455 | 0 | } |
456 | 0 |
|
457 | 0 | return NULL; |
458 | 0 | } Unexecuted instantiation: gen_uuid.c:ul_next_string Unexecuted instantiation: probe.c:ul_next_string Unexecuted instantiation: partitions.c:ul_next_string Unexecuted instantiation: path.c:ul_next_string Unexecuted instantiation: sysfs.c:ul_next_string Unexecuted instantiation: devname.c:ul_next_string Unexecuted instantiation: devno.c:ul_next_string Unexecuted instantiation: buffer.c:ul_next_string Unexecuted instantiation: canonicalize.c:ul_next_string Unexecuted instantiation: mbsalign.c:ul_next_string Unexecuted instantiation: strv.c:ul_next_string Unexecuted instantiation: strutils.c:ul_next_string |
459 | | |
460 | | extern char *ul_strnconcat(const char *s, const char *suffix, size_t b); |
461 | | extern char *ul_strconcat(const char *s, const char *suffix); |
462 | | extern char *ul_strfconcat(const char *s, const char *format, ...) |
463 | | __attribute__ ((__format__ (__printf__, 2, 3))); |
464 | | |
465 | | extern int ul_strappend(char **a, const char *b); |
466 | | extern int strfappend(char **a, const char *format, ...) |
467 | | __attribute__ ((__format__ (__printf__, 2, 3))); |
468 | | extern int ul_strvfappend(char **a, const char *format, va_list ap) |
469 | | __attribute__ ((__format__ (__printf__, 2, 0))); |
470 | | |
471 | | extern const char *ul_split(const char **state, size_t *l, const char *separator, int quoted); |
472 | | |
473 | | extern char *ul_strchr_escaped(const char *s, int c); |
474 | | |
475 | | extern int skip_fline(FILE *fp); |
476 | | extern int ul_stralnumcmp(const char *p1, const char *p2); |
477 | | |
478 | | extern int ul_optstr_next(char **optstr, char **name, size_t *namesz, char **value, size_t *valsz); |
479 | | extern int ul_optstr_is_valid(const char *optstr); |
480 | | extern char *ul_optstr_get_value(const char *optstr, const char *key); |
481 | | |
482 | | #endif /* UTIL_LINUX_STRUTILS */ |