]> git.ipfire.org Git - thirdparty/util-linux.git/blame - include/strutils.h
libmount: fix comment referring to passno field
[thirdparty/util-linux.git] / include / strutils.h
CommitLineData
8abcf290
DB
1#ifndef UTIL_LINUX_STRUTILS
2#define UTIL_LINUX_STRUTILS
3
23106a29 4#include <stdlib.h>
8abcf290
DB
5#include <inttypes.h>
6#include <string.h>
ce877f2d 7#include <sys/types.h>
675de3f5 8#include <ctype.h>
3e5a5455 9#include <stdio.h>
deb1c903 10#include <errno.h>
8abcf290 11
9c8b9fba
RM
12/* initialize a custom exit code for all *_or_err functions */
13extern void strutils_set_exitcode(int exit_code);
a99c9130 14
23106a29 15extern int parse_size(const char *str, uintmax_t *res, int *power);
8abcf290 16extern int strtosize(const char *str, uintmax_t *res);
551dae40
KZ
17extern uintmax_t strtosize_or_err(const char *str, const char *errmesg);
18
19extern int16_t strtos16_or_err(const char *str, const char *errmesg);
20extern uint16_t strtou16_or_err(const char *str, const char *errmesg);
54394eab 21extern uint16_t strtox16_or_err(const char *str, const char *errmesg);
551dae40
KZ
22
23extern int32_t strtos32_or_err(const char *str, const char *errmesg);
24extern uint32_t strtou32_or_err(const char *str, const char *errmesg);
54394eab 25extern uint32_t strtox32_or_err(const char *str, const char *errmesg);
551dae40
KZ
26
27extern int64_t strtos64_or_err(const char *str, const char *errmesg);
28extern uint64_t strtou64_or_err(const char *str, const char *errmesg);
54394eab 29extern uint64_t strtox64_or_err(const char *str, const char *errmesg);
551dae40 30
a9f97001 31extern double strtod_or_err(const char *str, const char *errmesg);
551dae40 32
8abcf290 33extern long strtol_or_err(const char *str, const char *errmesg);
e53bc960 34extern unsigned long strtoul_or_err(const char *str, const char *errmesg);
8abcf290 35
477254da
KZ
36extern void strtotimeval_or_err(const char *str, struct timeval *tv,
37 const char *errmesg);
38
61cbc8a3
KZ
39extern int isdigit_strend(const char *str, const char **end);
40#define isdigit_string(_s) isdigit_strend(_s, NULL)
41
42extern int isxdigit_strend(const char *str, const char **end);
43#define isxdigit_string(_s) isxdigit_strend(_s, NULL)
44
416c43a9 45
30b294c4 46extern int parse_switch(const char *arg, const char *errmesg, ...);
e5cf1476 47
02887b73
DT
48#ifndef HAVE_MEMPCPY
49extern void *mempcpy(void *restrict dest, const void *restrict src, size_t n);
50#endif
8abcf290
DB
51#ifndef HAVE_STRNLEN
52extern size_t strnlen(const char *s, size_t maxlen);
53#endif
54#ifndef HAVE_STRNDUP
55extern char *strndup(const char *s, size_t n);
56#endif
57#ifndef HAVE_STRNCHR
58extern char *strnchr(const char *s, size_t maxlen, int c);
59#endif
60
61/* caller guarantees n > 0 */
62static inline void xstrncpy(char *dest, const char *src, size_t n)
63{
64 strncpy(dest, src, n-1);
65 dest[n-1] = 0;
66}
ce877f2d 67
a338eb4a
KZ
68/* This is like strncpy(), but based on memcpy(), so compilers and static
69 * analyzers do not complain when sizeof(destination) is the same as 'n' and
70 * result is not terminated by zero.
71 *
72 * Use this function to copy string to logs with fixed sizes (wtmp/utmp. ...)
73 * where string terminator is optional.
74 */
75static inline void *str2memcpy(void *dest, const char *src, size_t n)
76{
77 size_t bytes = strlen(src) + 1;
78
79 if (bytes > n)
80 bytes = n;
81
82 memcpy(dest, src, bytes);
83 return dest;
84}
85
86static inline char *mem2strcpy(char *dest, const void *src, size_t n, size_t nmax)
87{
88 if (n + 1 > nmax)
89 n = nmax - 1;
90
91 memcpy(dest, src, n);
92 dest[nmax-1] = '\0';
93 return dest;
94}
95
deb1c903 96static inline int strdup_to_offset(void *stru, size_t offset, const char *str)
23106a29
KZ
97{
98 char *n = NULL;
deb1c903 99 char **o;
23106a29 100
deb1c903
KZ
101 if (!stru)
102 return -EINVAL;
103
104 o = (char **) ((char *) stru + offset);
23106a29
KZ
105 if (str) {
106 n = strdup(str);
107 if (!n)
deb1c903 108 return -ENOMEM;
23106a29
KZ
109 }
110
111 free(*o);
112 *o = n;
deb1c903 113 return 0;
23106a29
KZ
114}
115
116#define strdup_to_struct_member(_s, _m, _str) \
117 strdup_to_offset((void *) _s, offsetof(__typeof__(*(_s)), _m), _str)
118
5b82289b 119extern char *xstrmode(mode_t mode, char *str);
5d2a9849
FC
120
121/* Options for size_to_human_string() */
122enum
123{
07b94c9f
KZ
124 SIZE_SUFFIX_1LETTER = 0,
125 SIZE_SUFFIX_3LETTER = (1 << 0),
126 SIZE_SUFFIX_SPACE = (1 << 1),
127 SIZE_DECIMAL_2DIGITS = (1 << 2)
5d2a9849
FC
128};
129
130extern char *size_to_human_string(int options, uint64_t bytes);
ce877f2d 131
c87638ad
KZ
132extern int string_to_idarray(const char *list, int ary[], size_t arysz,
133 int (name2id)(const char *, size_t));
f5077b51 134extern int string_add_to_idarray(const char *list, int ary[],
40b17508 135 size_t arysz, size_t *ary_pos,
f5077b51
MB
136 int (name2id)(const char *, size_t));
137
c87638ad
KZ
138extern int string_to_bitarray(const char *list, char *ary,
139 int (*name2bit)(const char *, size_t));
140
5ef16771
KZ
141extern int string_to_bitmask(const char *list,
142 unsigned long *mask,
143 long (*name2flag)(const char *, size_t));
af7df9ee 144extern int parse_range(const char *str, int *lower, int *upper, int def);
a883c634 145
d4e89dea 146extern int streq_paths(const char *a, const char *b);
b106d052 147
646e159a
KZ
148/*
149 * Match string beginning.
150 */
151static inline const char *startswith(const char *s, const char *prefix)
152{
153 size_t sz = prefix ? strlen(prefix) : 0;
154
155 if (s && sz && strncmp(s, prefix, sz) == 0)
156 return s + sz;
157 return NULL;
158}
159
160/*
161 * Case insensitive match string beginning.
162 */
163static inline const char *startswith_no_case(const char *s, const char *prefix)
164{
165 size_t sz = prefix ? strlen(prefix) : 0;
166
167 if (s && sz && strncasecmp(s, prefix, sz) == 0)
168 return s + sz;
169 return NULL;
170}
171
172/*
173 * Match string ending.
174 */
175static inline const char *endswith(const char *s, const char *postfix)
176{
177 size_t sl = s ? strlen(s) : 0;
178 size_t pl = postfix ? strlen(postfix) : 0;
179
180 if (pl == 0)
8a7aeeda 181 return s + sl;
646e159a
KZ
182 if (sl < pl)
183 return NULL;
184 if (memcmp(s + sl - pl, postfix, pl) != 0)
185 return NULL;
8a7aeeda 186 return s + sl - pl;
646e159a 187}
199e939d 188
675de3f5
OO
189/*
190 * Skip leading white space.
191 */
192static inline const char *skip_space(const char *p)
193{
194 while (isspace(*p))
195 ++p;
196 return p;
197}
198
199static inline const char *skip_blank(const char *p)
200{
201 while (isblank(*p))
202 ++p;
203 return p;
204}
205
22e9e9c8
KZ
206
207/* Removes whitespace from the right-hand side of a string (trailing
208 * whitespace).
209 *
210 * Returns size of the new string (without \0).
211 */
212static inline size_t rtrim_whitespace(unsigned char *str)
213{
0b404f08 214 size_t i;
22e9e9c8 215
0b404f08
SK
216 if (!str)
217 return 0;
218 i = strlen((char *) str);
2f8610ee
SK
219 while (i) {
220 i--;
221 if (!isspace(str[i])) {
222 i++;
22e9e9c8 223 break;
2f8610ee 224 }
22e9e9c8 225 }
2f8610ee 226 str[i] = '\0';
22e9e9c8
KZ
227 return i;
228}
229
230/* Removes whitespace from the left-hand side of a string.
231 *
232 * Returns size of the new string (without \0).
233 */
234static inline size_t ltrim_whitespace(unsigned char *str)
235{
236 size_t len;
237 unsigned char *p;
238
0b404f08
SK
239 if (!str)
240 return 0;
241 for (p = str; *p && isspace(*p); p++);
22e9e9c8
KZ
242
243 len = strlen((char *) p);
244
6c183c28 245 if (p > str)
22e9e9c8
KZ
246 memmove(str, p, len + 1);
247
248 return len;
249}
250
3c4ff2dc
KZ
251static inline void strrep(char *s, int find, int replace)
252{
253 while (s && *s && (s = strchr(s, find)) != NULL)
254 *s++ = replace;
255}
256
257static inline void strrem(char *s, int rem)
258{
259 char *p;
260
d2a1ee4e
SK
261 if (!s)
262 return;
263 for (p = s; *s; s++) {
3c4ff2dc
KZ
264 if (*s != rem)
265 *p++ = *s;
266 }
b94acada 267 *p = '\0';
3c4ff2dc
KZ
268}
269
548b9714
KZ
270extern char *strnappend(const char *s, const char *suffix, size_t b);
271extern char *strappend(const char *s, const char *suffix);
3c201431
KZ
272extern char *strfappend(const char *s, const char *format, ...)
273 __attribute__ ((__format__ (__printf__, 2, 0)));
548b9714
KZ
274extern const char *split(const char **state, size_t *l, const char *separator, int quoted);
275
3e5a5455
SK
276extern int skip_fline(FILE *fp);
277
8abcf290 278#endif