]> git.ipfire.org Git - thirdparty/util-linux.git/blob - include/strutils.h
Merge branch 'dana/column-x' of https://github.com/okdana/util-linux
[thirdparty/util-linux.git] / include / strutils.h
1 #ifndef UTIL_LINUX_STRUTILS
2 #define UTIL_LINUX_STRUTILS
3
4 #include <stdlib.h>
5 #include <inttypes.h>
6 #include <string.h>
7 #include <sys/types.h>
8 #include <ctype.h>
9 #include <stdio.h>
10 #include <errno.h>
11
12 /* initialize a custom exit code for all *_or_err functions */
13 extern void strutils_set_exitcode(int exit_code);
14
15 extern int parse_size(const char *str, uintmax_t *res, int *power);
16 extern int strtosize(const char *str, uintmax_t *res);
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);
21 extern uint16_t strtox16_or_err(const char *str, const char *errmesg);
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);
25 extern uint32_t strtox32_or_err(const char *str, const char *errmesg);
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);
29 extern uint64_t strtox64_or_err(const char *str, const char *errmesg);
30
31 extern double strtod_or_err(const char *str, const char *errmesg);
32
33 extern long strtol_or_err(const char *str, const char *errmesg);
34 extern unsigned long strtoul_or_err(const char *str, const char *errmesg);
35
36 extern void strtotimeval_or_err(const char *str, struct timeval *tv,
37 const char *errmesg);
38
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
45
46 extern int parse_switch(const char *arg, const char *errmesg, ...);
47
48 #ifndef HAVE_MEMPCPY
49 extern void *mempcpy(void *restrict dest, const void *restrict src, size_t n);
50 #endif
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 }
67
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 */
75 static 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
86 static 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
96 static inline int strdup_to_offset(void *stru, size_t offset, const char *str)
97 {
98 char *n = NULL;
99 char **o;
100
101 if (!stru)
102 return -EINVAL;
103
104 o = (char **) ((char *) stru + offset);
105 if (str) {
106 n = strdup(str);
107 if (!n)
108 return -ENOMEM;
109 }
110
111 free(*o);
112 *o = n;
113 return 0;
114 }
115
116 #define strdup_to_struct_member(_s, _m, _str) \
117 strdup_to_offset((void *) _s, offsetof(__typeof__(*(_s)), _m), _str)
118
119 extern char *xstrmode(mode_t mode, char *str);
120
121 /* Options for size_to_human_string() */
122 enum
123 {
124 SIZE_SUFFIX_1LETTER = 0,
125 SIZE_SUFFIX_3LETTER = (1 << 0),
126 SIZE_SUFFIX_SPACE = (1 << 1),
127 SIZE_DECIMAL_2DIGITS = (1 << 2)
128 };
129
130 extern char *size_to_human_string(int options, uint64_t bytes);
131
132 extern int string_to_idarray(const char *list, int ary[], size_t arysz,
133 int (name2id)(const char *, size_t));
134 extern int string_add_to_idarray(const char *list, int ary[],
135 size_t arysz, size_t *ary_pos,
136 int (name2id)(const char *, size_t));
137
138 extern int string_to_bitarray(const char *list, char *ary,
139 int (*name2bit)(const char *, size_t));
140
141 extern int string_to_bitmask(const char *list,
142 unsigned long *mask,
143 long (*name2flag)(const char *, size_t));
144 extern int parse_range(const char *str, int *lower, int *upper, int def);
145
146 extern int streq_paths(const char *a, const char *b);
147
148 /*
149 * Match string beginning.
150 */
151 static 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 */
163 static 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 */
175 static 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)
181 return s + sl;
182 if (sl < pl)
183 return NULL;
184 if (memcmp(s + sl - pl, postfix, pl) != 0)
185 return NULL;
186 return s + sl - pl;
187 }
188
189 /*
190 * Skip leading white space.
191 */
192 static inline const char *skip_space(const char *p)
193 {
194 while (isspace(*p))
195 ++p;
196 return p;
197 }
198
199 static inline const char *skip_blank(const char *p)
200 {
201 while (isblank(*p))
202 ++p;
203 return p;
204 }
205
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 */
212 static inline size_t rtrim_whitespace(unsigned char *str)
213 {
214 size_t i;
215
216 if (!str)
217 return 0;
218 i = strlen((char *) str);
219 while (i) {
220 i--;
221 if (!isspace(str[i])) {
222 i++;
223 break;
224 }
225 }
226 str[i] = '\0';
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 */
234 static inline size_t ltrim_whitespace(unsigned char *str)
235 {
236 size_t len;
237 unsigned char *p;
238
239 if (!str)
240 return 0;
241 for (p = str; *p && isspace(*p); p++);
242
243 len = strlen((char *) p);
244
245 if (p > str)
246 memmove(str, p, len + 1);
247
248 return len;
249 }
250
251 extern char *strnappend(const char *s, const char *suffix, size_t b);
252 extern char *strappend(const char *s, const char *suffix);
253 extern char *strfappend(const char *s, const char *format, ...)
254 __attribute__ ((__format__ (__printf__, 2, 0)));
255 extern const char *split(const char **state, size_t *l, const char *separator, int quoted);
256
257 extern int skip_fline(FILE *fp);
258
259 #endif