]>
Commit | Line | Data |
---|---|---|
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 */ |
13 | extern void strutils_set_exitcode(int exit_code); | |
a99c9130 | 14 | |
23106a29 | 15 | extern int parse_size(const char *str, uintmax_t *res, int *power); |
8abcf290 | 16 | extern int strtosize(const char *str, uintmax_t *res); |
551dae40 KZ |
17 | extern uintmax_t strtosize_or_err(const char *str, const char *errmesg); |
18 | ||
19 | extern int16_t strtos16_or_err(const char *str, const char *errmesg); | |
20 | extern uint16_t strtou16_or_err(const char *str, const char *errmesg); | |
54394eab | 21 | extern uint16_t strtox16_or_err(const char *str, const char *errmesg); |
551dae40 KZ |
22 | |
23 | extern int32_t strtos32_or_err(const char *str, const char *errmesg); | |
24 | extern uint32_t strtou32_or_err(const char *str, const char *errmesg); | |
54394eab | 25 | extern uint32_t strtox32_or_err(const char *str, const char *errmesg); |
551dae40 KZ |
26 | |
27 | extern int64_t strtos64_or_err(const char *str, const char *errmesg); | |
28 | extern uint64_t strtou64_or_err(const char *str, const char *errmesg); | |
54394eab | 29 | extern uint64_t strtox64_or_err(const char *str, const char *errmesg); |
551dae40 | 30 | |
a9f97001 | 31 | extern double strtod_or_err(const char *str, const char *errmesg); |
551dae40 | 32 | |
8abcf290 | 33 | extern long strtol_or_err(const char *str, const char *errmesg); |
e53bc960 | 34 | extern unsigned long strtoul_or_err(const char *str, const char *errmesg); |
8abcf290 | 35 | |
477254da KZ |
36 | extern void strtotimeval_or_err(const char *str, struct timeval *tv, |
37 | const char *errmesg); | |
38 | ||
61cbc8a3 KZ |
39 | extern int isdigit_strend(const char *str, const char **end); |
40 | #define isdigit_string(_s) isdigit_strend(_s, NULL) | |
41 | ||
42 | extern int isxdigit_strend(const char *str, const char **end); | |
43 | #define isxdigit_string(_s) isxdigit_strend(_s, NULL) | |
44 | ||
416c43a9 | 45 | |
30b294c4 | 46 | extern int parse_switch(const char *arg, const char *errmesg, ...); |
e5cf1476 | 47 | |
02887b73 DT |
48 | #ifndef HAVE_MEMPCPY |
49 | extern void *mempcpy(void *restrict dest, const void *restrict src, size_t n); | |
50 | #endif | |
8abcf290 DB |
51 | #ifndef HAVE_STRNLEN |
52 | extern size_t strnlen(const char *s, size_t maxlen); | |
53 | #endif | |
54 | #ifndef HAVE_STRNDUP | |
55 | extern char *strndup(const char *s, size_t n); | |
56 | #endif | |
57 | #ifndef HAVE_STRNCHR | |
58 | extern char *strnchr(const char *s, size_t maxlen, int c); | |
59 | #endif | |
60 | ||
61 | /* caller guarantees n > 0 */ | |
62 | static 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 | |
deb1c903 | 68 | static inline int strdup_to_offset(void *stru, size_t offset, const char *str) |
23106a29 KZ |
69 | { |
70 | char *n = NULL; | |
deb1c903 | 71 | char **o; |
23106a29 | 72 | |
deb1c903 KZ |
73 | if (!stru) |
74 | return -EINVAL; | |
75 | ||
76 | o = (char **) ((char *) stru + offset); | |
23106a29 KZ |
77 | if (str) { |
78 | n = strdup(str); | |
79 | if (!n) | |
deb1c903 | 80 | return -ENOMEM; |
23106a29 KZ |
81 | } |
82 | ||
83 | free(*o); | |
84 | *o = n; | |
deb1c903 | 85 | return 0; |
23106a29 KZ |
86 | } |
87 | ||
88 | #define strdup_to_struct_member(_s, _m, _str) \ | |
89 | strdup_to_offset((void *) _s, offsetof(__typeof__(*(_s)), _m), _str) | |
90 | ||
5b82289b | 91 | extern char *xstrmode(mode_t mode, char *str); |
5d2a9849 FC |
92 | |
93 | /* Options for size_to_human_string() */ | |
94 | enum | |
95 | { | |
96 | SIZE_SUFFIX_1LETTER = 0, | |
97 | SIZE_SUFFIX_3LETTER = 1, | |
98 | SIZE_SUFFIX_SPACE = 2 | |
99 | }; | |
100 | ||
101 | extern char *size_to_human_string(int options, uint64_t bytes); | |
ce877f2d | 102 | |
c87638ad KZ |
103 | extern int string_to_idarray(const char *list, int ary[], size_t arysz, |
104 | int (name2id)(const char *, size_t)); | |
f5077b51 | 105 | extern int string_add_to_idarray(const char *list, int ary[], |
40b17508 | 106 | size_t arysz, size_t *ary_pos, |
f5077b51 MB |
107 | int (name2id)(const char *, size_t)); |
108 | ||
c87638ad KZ |
109 | extern int string_to_bitarray(const char *list, char *ary, |
110 | int (*name2bit)(const char *, size_t)); | |
111 | ||
5ef16771 KZ |
112 | extern int string_to_bitmask(const char *list, |
113 | unsigned long *mask, | |
114 | long (*name2flag)(const char *, size_t)); | |
af7df9ee | 115 | extern int parse_range(const char *str, int *lower, int *upper, int def); |
a883c634 | 116 | |
d4e89dea | 117 | extern int streq_paths(const char *a, const char *b); |
b106d052 | 118 | |
646e159a KZ |
119 | /* |
120 | * Match string beginning. | |
121 | */ | |
122 | static inline const char *startswith(const char *s, const char *prefix) | |
123 | { | |
124 | size_t sz = prefix ? strlen(prefix) : 0; | |
125 | ||
126 | if (s && sz && strncmp(s, prefix, sz) == 0) | |
127 | return s + sz; | |
128 | return NULL; | |
129 | } | |
130 | ||
131 | /* | |
132 | * Case insensitive match string beginning. | |
133 | */ | |
134 | static inline const char *startswith_no_case(const char *s, const char *prefix) | |
135 | { | |
136 | size_t sz = prefix ? strlen(prefix) : 0; | |
137 | ||
138 | if (s && sz && strncasecmp(s, prefix, sz) == 0) | |
139 | return s + sz; | |
140 | return NULL; | |
141 | } | |
142 | ||
143 | /* | |
144 | * Match string ending. | |
145 | */ | |
146 | static inline const char *endswith(const char *s, const char *postfix) | |
147 | { | |
148 | size_t sl = s ? strlen(s) : 0; | |
149 | size_t pl = postfix ? strlen(postfix) : 0; | |
150 | ||
151 | if (pl == 0) | |
8a7aeeda | 152 | return s + sl; |
646e159a KZ |
153 | if (sl < pl) |
154 | return NULL; | |
155 | if (memcmp(s + sl - pl, postfix, pl) != 0) | |
156 | return NULL; | |
8a7aeeda | 157 | return s + sl - pl; |
646e159a | 158 | } |
199e939d | 159 | |
675de3f5 OO |
160 | /* |
161 | * Skip leading white space. | |
162 | */ | |
163 | static inline const char *skip_space(const char *p) | |
164 | { | |
165 | while (isspace(*p)) | |
166 | ++p; | |
167 | return p; | |
168 | } | |
169 | ||
170 | static inline const char *skip_blank(const char *p) | |
171 | { | |
172 | while (isblank(*p)) | |
173 | ++p; | |
174 | return p; | |
175 | } | |
176 | ||
22e9e9c8 KZ |
177 | |
178 | /* Removes whitespace from the right-hand side of a string (trailing | |
179 | * whitespace). | |
180 | * | |
181 | * Returns size of the new string (without \0). | |
182 | */ | |
183 | static inline size_t rtrim_whitespace(unsigned char *str) | |
184 | { | |
0b404f08 | 185 | size_t i; |
22e9e9c8 | 186 | |
0b404f08 SK |
187 | if (!str) |
188 | return 0; | |
189 | i = strlen((char *) str); | |
2f8610ee SK |
190 | while (i) { |
191 | i--; | |
192 | if (!isspace(str[i])) { | |
193 | i++; | |
22e9e9c8 | 194 | break; |
2f8610ee | 195 | } |
22e9e9c8 | 196 | } |
2f8610ee | 197 | str[i] = '\0'; |
22e9e9c8 KZ |
198 | return i; |
199 | } | |
200 | ||
201 | /* Removes whitespace from the left-hand side of a string. | |
202 | * | |
203 | * Returns size of the new string (without \0). | |
204 | */ | |
205 | static inline size_t ltrim_whitespace(unsigned char *str) | |
206 | { | |
207 | size_t len; | |
208 | unsigned char *p; | |
209 | ||
0b404f08 SK |
210 | if (!str) |
211 | return 0; | |
212 | for (p = str; *p && isspace(*p); p++); | |
22e9e9c8 KZ |
213 | |
214 | len = strlen((char *) p); | |
215 | ||
6c183c28 | 216 | if (p > str) |
22e9e9c8 KZ |
217 | memmove(str, p, len + 1); |
218 | ||
219 | return len; | |
220 | } | |
221 | ||
548b9714 KZ |
222 | extern char *strnappend(const char *s, const char *suffix, size_t b); |
223 | extern char *strappend(const char *s, const char *suffix); | |
3c201431 KZ |
224 | extern char *strfappend(const char *s, const char *format, ...) |
225 | __attribute__ ((__format__ (__printf__, 2, 0))); | |
548b9714 KZ |
226 | extern const char *split(const char **state, size_t *l, const char *separator, int quoted); |
227 | ||
3e5a5455 SK |
228 | extern int skip_fline(FILE *fp); |
229 | ||
8abcf290 | 230 | #endif |