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