]>
git.ipfire.org Git - thirdparty/util-linux.git/blob - include/strutils.h
2ee7c3e531e32eb7b6c7dedddc09bc7e11dbbeb4
2 * No copyright is claimed. This code is in the public domain; do with
5 #ifndef UTIL_LINUX_STRUTILS
6 #define UTIL_LINUX_STRUTILS
12 #include <sys/types.h>
21 /* initialize a custom exit code for all *_or_err functions */
22 extern void strutils_set_exitcode(int exit_code
);
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
);
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
);
34 extern int ul_strtold(const char *str
, long double *num
);
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
);
39 #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)
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)
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)
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
);
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)
58 extern void strtotimeval_or_err(const char *str
, struct timeval
*tv
,
60 extern void strtotimespec_or_err(const char *str
, struct timespec
*ts
,
62 extern time_t strtotime_or_err(const char *str
, const char *errmesg
);
64 extern bool hyperlinkwanted(const char *mode
);
66 extern int isdigit_strend(const char *str
, const char **end
);
67 #define isdigit_string(_s) isdigit_strend(_s, NULL)
69 extern int isxdigit_strend(const char *str
, const char **end
);
70 #define isxdigit_string(_s) isxdigit_strend(_s, NULL)
73 extern int ul_parse_switch(const char *arg
, ...);
76 extern void *mempcpy(void *restrict dest
, const void *restrict src
, size_t n
);
79 extern size_t strnlen(const char *s
, size_t maxlen
);
82 extern char *strndup(const char *s
, size_t n
);
85 extern char *strnchr(const char *s
, size_t maxlen
, int c
);
88 /* caller guarantees n > 0 */
89 static inline int xstrncpy(char *dest
, const char *src
, size_t n
)
91 size_t len
= src
? strlen(src
) : 0;
95 len
= min(len
, n
- 1);
96 memcpy(dest
, src
, len
);
101 /* This is like strncpy(), but based on memcpy(), so compilers and static
102 * analyzers do not complain when sizeof(destination) is the same as 'n' and
103 * result is not terminated by zero.
105 * Use this function to copy string to logs with fixed sizes (wtmp/utmp. ...)
106 * where string terminator is optional.
108 static inline void * __attribute__((nonnull (1)))
109 str2memcpy(void *dest
, const char *src
, size_t n
)
111 size_t bytes
= strlen(src
) + 1;
116 memcpy(dest
, src
, bytes
);
120 static inline char * __attribute__((nonnull (1)))
121 mem2strcpy(char *dest
, const void *src
, size_t n
, size_t nmax
)
126 memset(dest
, '\0', nmax
);
127 memcpy(dest
, src
, n
);
131 /* Reallocate @str according to @newstr and copy @newstr to @str; returns new @str.
132 * The @str is not modified if reallocation failed (like classic realloc()).
134 static inline char * __attribute__((warn_unused_result
))
135 strrealloc(char *str
, const char *newstr
)
140 return newstr
? strdup(newstr
) : NULL
;
145 nsz
= strlen(newstr
);
148 str
= realloc(str
, nsz
+ 1);
150 memcpy(str
, newstr
, nsz
+ 1);
154 /* Copy string @str to struct @stru to member addressed by @offset */
155 static inline int strdup_to_offset(void *stru
, size_t offset
, const char *str
)
163 o
= (char **) ((char *) stru
+ offset
);
175 /* Copy string __str to struct member _m of the struct _s */
176 #define strdup_to_struct_member(_s, _m, _str) \
177 strdup_to_offset((void *) _s, offsetof(__typeof__(*(_s)), _m), _str)
179 /* Copy string addressed by @offset between two structs */
180 static inline int strdup_between_offsets(void *stru_dst
, void *stru_src
, size_t offset
)
186 if (!stru_src
|| !stru_dst
)
189 src
= (char **) ((char *) stru_src
+ offset
);
190 dst
= (char **) ((char *) stru_dst
+ offset
);
203 /* Copy string addressed by struct member between two instances of the same
205 #define strdup_between_structs(_dst, _src, _m) \
206 strdup_between_offsets((void *)_dst, (void *)_src, offsetof(__typeof__(*(_src)), _m))
208 static inline int is_nonnull_offset(const void *stru
, size_t offset
)
215 o
= (const char **) ((const char *) stru
+ offset
);
219 #define is_nonnull_member(_stru, _m) \
220 is_nonnull_offset((void *) _stru, offsetof(__typeof__(*(_stru)), _m))
222 static inline int strcmp_offsets(const void *sa
, const void *sb
, size_t offset
)
224 const char **a
= (const char **) ((const char *) sa
+ offset
),
225 **b
= (const char **) ((const char *) sb
+ offset
);
233 return strcmp(*a
, *b
);
236 #define strcmp_members(_a, _b, _m) \
237 strcmp_offsets((void *) _a, (void *) _b, offsetof(__typeof__(*(_a)), _m))
239 extern char *xstrmode(mode_t mode
, char *str
);
241 /* Options for size_to_human_string() */
244 SIZE_SUFFIX_1LETTER
= 0,
245 SIZE_SUFFIX_3LETTER
= (1 << 0),
246 SIZE_SUFFIX_SPACE
= (1 << 1),
247 SIZE_DECIMAL_2DIGITS
= (1 << 2)
250 extern char *size_to_human_string(int options
, uint64_t bytes
);
252 extern int string_to_idarray(const char *list
, int ary
[], size_t arysz
,
253 int (name2id
)(const char *, size_t));
254 extern int string_add_to_idarray(const char *list
, int ary
[],
255 size_t arysz
, size_t *ary_pos
,
256 int (name2id
)(const char *, size_t));
258 extern int string_to_bitarray(const char *list
, char *ary
,
259 int (*name2bit
)(const char *, size_t),
262 extern int string_to_bitmask(const char *list
,
264 long (*name2flag
)(const char *, size_t));
265 extern int ul_parse_range(const char *str
, int *lower
, int *upper
, int def
);
267 extern int streq_paths(const char *a
, const char *b
);
270 * Match string beginning.
272 static inline const char *ul_startswith(const char *s
, const char *prefix
)
274 size_t sz
= prefix
? strlen(prefix
) : 0;
276 if (s
&& sz
&& strncmp(s
, prefix
, sz
) == 0)
282 * Case insensitive match string beginning.
284 static inline const char *startswith_no_case(const char *s
, const char *prefix
)
286 size_t sz
= prefix
? strlen(prefix
) : 0;
288 if (s
&& sz
&& strncasecmp(s
, prefix
, sz
) == 0)
294 * Match path beginning
296 static inline const char *startswithpath(const char *s
, const char *prefix
)
298 const char *p
= ul_startswith(s
, prefix
);
300 if (p
&& (*p
== '/' || *p
== '\0'))
307 * Match string ending.
309 static inline const char *ul_endswith(const char *s
, const char *postfix
)
311 size_t sl
= s
? strlen(s
) : 0;
312 size_t pl
= postfix
? strlen(postfix
) : 0;
318 if (memcmp(s
+ sl
- pl
, postfix
, pl
) != 0)
324 * Skip leading white space.
326 static inline const char *skip_space(const char *p
)
333 static inline const char *skip_blank(const char *p
)
341 /* Removes whitespace from the right-hand side of a string (trailing
344 * Returns size of the new string (without \0).
346 static inline size_t rtrim_whitespace(unsigned char *str
)
352 i
= strlen((char *) str
);
355 if (!isspace(str
[i
])) {
364 /* Removes whitespace from the left-hand side of a string.
366 * Returns size of the new string (without \0).
368 static inline size_t ltrim_whitespace(unsigned char *str
)
375 for (p
= str
; *p
&& isspace(*p
); p
++);
377 len
= strlen((char *) p
);
380 memmove(str
, p
, len
+ 1);
385 /* Removes left-hand, right-hand and repeating whitespaces.
387 static inline size_t __normalize_whitespace(
388 const unsigned char *src
,
394 int nsp
= 0, intext
= 0;
399 for (i
= 0, x
= 0; i
< sz
&& x
< len
- 1; ) {
405 if (nsp
> 1 || (nsp
&& !intext
))
410 if (nsp
&& x
> 0) /* trailing space */
417 static inline size_t normalize_whitespace(unsigned char *str
)
419 size_t sz
= strlen((char *) str
);
420 return __normalize_whitespace(str
, sz
, str
, sz
+ 1);
423 static inline void ul_strrep(char *s
, int find
, int replace
)
425 while (s
&& *s
&& (s
= strchr(s
, find
)) != NULL
)
429 static inline void ul_strrem(char *s
, int rem
)
435 for (p
= s
; *s
; s
++) {
442 /* returns next string after \0 if before @end */
443 static inline char *ul_next_string(char *p
, char *end
)
447 if (!p
|| !end
|| p
>= end
)
450 for (last
= p
; p
< end
; p
++) {
451 if (*last
== '\0' && p
!= last
)
459 extern char *ul_strnconcat(const char *s
, const char *suffix
, size_t b
);
460 extern char *ul_strconcat(const char *s
, const char *suffix
);
461 extern char *ul_strfconcat(const char *s
, const char *format
, ...)
462 __attribute__ ((__format__ (__printf__
, 2, 3)));
464 extern int ul_strappend(char **a
, const char *b
);
465 extern int strfappend(char **a
, const char *format
, ...)
466 __attribute__ ((__format__ (__printf__
, 2, 3)));
467 extern int ul_strvfappend(char **a
, const char *format
, va_list ap
)
468 __attribute__ ((__format__ (__printf__
, 2, 0)));
470 extern const char *ul_split(const char **state
, size_t *l
, const char *separator
, int quoted
);
472 extern char *ul_strchr_escaped(const char *s
, int c
);
474 extern int skip_fline(FILE *fp
);
475 extern int ul_stralnumcmp(const char *p1
, const char *p2
);
477 extern int ul_optstr_next(char **optstr
, char **name
, size_t *namesz
, char **value
, size_t *valsz
);
478 extern int ul_optstr_is_valid(const char *optstr
);