Coverage Report

Created: 2024-05-21 06:33

/src/util-linux/include/strutils.h
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * No copyright is claimed.  This code is in the public domain; do with
3
 * it what you wish.
4
 */
5
#ifndef UTIL_LINUX_STRUTILS
6
#define UTIL_LINUX_STRUTILS
7
8
#include <stdlib.h>
9
#include <inttypes.h>
10
#include <string.h>
11
#include <strings.h>
12
#include <sys/types.h>
13
#include <ctype.h>
14
#include <stdio.h>
15
#include <errno.h>
16
#include <time.h>
17
18
#include "c.h"
19
20
/* initialize a custom exit code for all *_or_err functions */
21
extern void strutils_set_exitcode(int exit_code);
22
23
extern int parse_size(const char *str, uintmax_t *res, int *power);
24
extern int strtosize(const char *str, uintmax_t *res);
25
extern uintmax_t strtosize_or_err(const char *str, const char *errmesg);
26
27
extern int ul_strtos64(const char *str, int64_t *num, int base);
28
extern int ul_strtou64(const char *str, uint64_t *num, int base);
29
extern int ul_strtos32(const char *str, int32_t *num, int base);
30
extern int ul_strtou32(const char *str, uint32_t *num, int base);
31
extern int ul_strtold(const char *str, long double *num);
32
33
extern int64_t str2num_or_err(const char *str, int base, const char *errmesg, int64_t low, int64_t up);
34
extern uint64_t str2unum_or_err(const char *str, int base, const char *errmesg, uint64_t up);
35
36
#define strtos64_or_err(_s, _e) str2num_or_err(_s, 10, _e, 0, 0)
37
#define strtou64_or_err(_s, _e) str2unum_or_err(_s, 10, _e, 0)
38
#define strtox64_or_err(_s, _e) str2unum_or_err(_s, 16, _e, 0)
39
40
#define strtos32_or_err(_s, _e) (int32_t) str2num_or_err(_s, 10, _e, INT32_MIN, INT32_MAX)
41
#define strtou32_or_err(_s, _e) (uint32_t) str2unum_or_err(_s, 10, _e, UINT32_MAX)
42
#define strtox32_or_err(_s, _e) (uint32_t) str2unum_or_err(_s, 16, _e, UINT32_MAX)
43
44
#define strtos16_or_err(_s, _e) (int16_t) str2num_or_err(_s, 10, _e, INT16_MIN, INT16_MAX)
45
#define strtou16_or_err(_s, _e) (uint16_t) str2unum_or_err(_s, 10, _e, UINT16_MAX)
46
#define strtox16_or_err(_s, _e) (uint16_t) str2unum_or_err(_s, 16, _e, UINT16_MAX)
47
48
extern double strtod_or_err(const char *str, const char *errmesg);
49
extern long double strtold_or_err(const char *str, const char *errmesg);
50
51
#define strtol_or_err(_s, _e) (long) str2num_or_err(_s, 10, _e, LONG_MIN, LONG_MAX)
52
#define strtopid_or_err(_s, _e) (pid_t) str2num_or_err(_s, 10, _e, 1, SINT_MAX(pid_t))
53
#define strtoul_or_err(_s, _e)  (unsigned long) str2unum_or_err(_s, 10, _e, ULONG_MAX)
54
55
extern void strtotimeval_or_err(const char *str, struct timeval *tv,
56
    const char *errmesg);
57
extern void strtotimespec_or_err(const char *str, struct timespec *ts,
58
    const char *errmesg);
59
extern time_t strtotime_or_err(const char *str, const char *errmesg);
60
61
extern int isdigit_strend(const char *str, const char **end);
62
#define isdigit_string(_s)  isdigit_strend(_s, NULL)
63
64
extern int isxdigit_strend(const char *str, const char **end);
65
#define isxdigit_string(_s) isxdigit_strend(_s, NULL)
66
67
68
extern int parse_switch(const char *arg, const char *errmesg, ...);
69
70
#ifndef HAVE_MEMPCPY
71
extern void *mempcpy(void *restrict dest, const void *restrict src, size_t n);
72
#endif
73
#ifndef HAVE_STRNLEN
74
extern size_t strnlen(const char *s, size_t maxlen);
75
#endif
76
#ifndef HAVE_STRNDUP
77
extern char *strndup(const char *s, size_t n);
78
#endif
79
#ifndef HAVE_STRNCHR
80
extern char *strnchr(const char *s, size_t maxlen, int c);
81
#endif
82
83
/* caller guarantees n > 0 */
84
static inline void xstrncpy(char *dest, const char *src, size_t n)
85
0
{
86
0
  size_t len = src ? strlen(src) : 0;
87
88
0
  if (!len)
89
0
    return;
90
0
  len = min(len, n - 1);
91
0
  memcpy(dest, src, len);
92
0
  dest[len] = 0;
93
0
}
Unexecuted instantiation: gen_uuid.c:xstrncpy
Unexecuted instantiation: probe.c:xstrncpy
Unexecuted instantiation: partitions.c:xstrncpy
Unexecuted instantiation: path.c:xstrncpy
Unexecuted instantiation: sysfs.c:xstrncpy
Unexecuted instantiation: devname.c:xstrncpy
Unexecuted instantiation: devno.c:xstrncpy
Unexecuted instantiation: buffer.c:xstrncpy
Unexecuted instantiation: canonicalize.c:xstrncpy
Unexecuted instantiation: mbsalign.c:xstrncpy
94
95
/* This is like strncpy(), but based on memcpy(), so compilers and static
96
 * analyzers do not complain when sizeof(destination) is the same as 'n' and
97
 * result is not terminated by zero.
98
 *
99
 * Use this function to copy string to logs with fixed sizes (wtmp/utmp. ...)
100
 * where string terminator is optional.
101
 */
102
static inline void * __attribute__((nonnull (1)))
103
str2memcpy(void *dest, const char *src, size_t n)
104
0
{
105
0
  size_t bytes = strlen(src) + 1;
106
0
107
0
  if (bytes > n)
108
0
    bytes = n;
109
0
110
0
  memcpy(dest, src, bytes);
111
0
  return dest;
112
0
}
Unexecuted instantiation: gen_uuid.c:str2memcpy
Unexecuted instantiation: probe.c:str2memcpy
Unexecuted instantiation: partitions.c:str2memcpy
Unexecuted instantiation: path.c:str2memcpy
Unexecuted instantiation: sysfs.c:str2memcpy
Unexecuted instantiation: devname.c:str2memcpy
Unexecuted instantiation: devno.c:str2memcpy
Unexecuted instantiation: buffer.c:str2memcpy
Unexecuted instantiation: canonicalize.c:str2memcpy
Unexecuted instantiation: mbsalign.c:str2memcpy
113
114
static inline char * __attribute__((nonnull (1)))
115
mem2strcpy(char *dest, const void *src, size_t n, size_t nmax)
116
0
{
117
0
  if (n + 1 > nmax)
118
0
    n = nmax - 1;
119
0
120
0
  memset(dest, '\0', nmax);
121
0
  memcpy(dest, src, n);
122
0
  return dest;
123
0
}
Unexecuted instantiation: gen_uuid.c:mem2strcpy
Unexecuted instantiation: probe.c:mem2strcpy
Unexecuted instantiation: partitions.c:mem2strcpy
Unexecuted instantiation: path.c:mem2strcpy
Unexecuted instantiation: sysfs.c:mem2strcpy
Unexecuted instantiation: devname.c:mem2strcpy
Unexecuted instantiation: devno.c:mem2strcpy
Unexecuted instantiation: buffer.c:mem2strcpy
Unexecuted instantiation: canonicalize.c:mem2strcpy
Unexecuted instantiation: mbsalign.c:mem2strcpy
124
125
/* Reallocate @str according to @newstr and copy @newstr to @str; returns new @str.
126
 * The @str is not modified if reallocation failed (like classic realloc()).
127
 */
128
static inline char * __attribute__((warn_unused_result))
129
strrealloc(char *str, const char *newstr)
130
0
{
131
0
  size_t nsz, osz;
132
0
133
0
  if (!str)
134
0
    return newstr ? strdup(newstr) : NULL;
135
0
  if (!newstr)
136
0
    return NULL;
137
0
138
0
  osz = strlen(str);
139
0
  nsz = strlen(newstr);
140
0
141
0
  if (nsz > osz)
142
0
    str = realloc(str, nsz + 1);
143
0
  if (str)
144
0
    memcpy(str, newstr, nsz + 1);
145
0
  return str;
146
0
}
Unexecuted instantiation: gen_uuid.c:strrealloc
Unexecuted instantiation: probe.c:strrealloc
Unexecuted instantiation: partitions.c:strrealloc
Unexecuted instantiation: path.c:strrealloc
Unexecuted instantiation: sysfs.c:strrealloc
Unexecuted instantiation: devname.c:strrealloc
Unexecuted instantiation: devno.c:strrealloc
Unexecuted instantiation: buffer.c:strrealloc
Unexecuted instantiation: canonicalize.c:strrealloc
Unexecuted instantiation: mbsalign.c:strrealloc
147
148
/* Copy string @str to struct @stru to member addressed by @offset */
149
static inline int strdup_to_offset(void *stru, size_t offset, const char *str)
150
0
{
151
0
  char **o;
152
0
  char *p = NULL;
153
0
154
0
  if (!stru)
155
0
    return -EINVAL;
156
0
157
0
  o = (char **) ((char *) stru + offset);
158
0
  if (str) {
159
0
    p = strdup(str);
160
0
    if (!p)
161
0
      return -ENOMEM;
162
0
  }
163
0
164
0
  free(*o);
165
0
  *o = p;
166
0
  return 0;
167
0
}
Unexecuted instantiation: gen_uuid.c:strdup_to_offset
Unexecuted instantiation: probe.c:strdup_to_offset
Unexecuted instantiation: partitions.c:strdup_to_offset
Unexecuted instantiation: path.c:strdup_to_offset
Unexecuted instantiation: sysfs.c:strdup_to_offset
Unexecuted instantiation: devname.c:strdup_to_offset
Unexecuted instantiation: devno.c:strdup_to_offset
Unexecuted instantiation: buffer.c:strdup_to_offset
Unexecuted instantiation: canonicalize.c:strdup_to_offset
Unexecuted instantiation: mbsalign.c:strdup_to_offset
168
169
/* Copy string __str to struct member _m of the struct _s */
170
#define strdup_to_struct_member(_s, _m, _str) \
171
    strdup_to_offset((void *) _s, offsetof(__typeof__(*(_s)), _m), _str)
172
173
/* Copy string addressed by @offset between two structs */
174
static inline int strdup_between_offsets(void *stru_dst, void *stru_src, size_t offset)
175
0
{
176
0
  char **src;
177
0
  char **dst;
178
0
  char *p = NULL;
179
0
180
0
  if (!stru_src || !stru_dst)
181
0
    return -EINVAL;
182
0
183
0
  src = (char **) ((char *) stru_src + offset);
184
0
  dst = (char **) ((char *) stru_dst + offset);
185
0
186
0
  if (*src) {
187
0
    p = strdup(*src);
188
0
    if (!p)
189
0
      return -ENOMEM;
190
0
  }
191
0
192
0
  free(*dst);
193
0
  *dst = p;
194
0
  return 0;
195
0
}
Unexecuted instantiation: gen_uuid.c:strdup_between_offsets
Unexecuted instantiation: probe.c:strdup_between_offsets
Unexecuted instantiation: partitions.c:strdup_between_offsets
Unexecuted instantiation: path.c:strdup_between_offsets
Unexecuted instantiation: sysfs.c:strdup_between_offsets
Unexecuted instantiation: devname.c:strdup_between_offsets
Unexecuted instantiation: devno.c:strdup_between_offsets
Unexecuted instantiation: buffer.c:strdup_between_offsets
Unexecuted instantiation: canonicalize.c:strdup_between_offsets
Unexecuted instantiation: mbsalign.c:strdup_between_offsets
196
197
/* Copy string addressed by struct member between two instances of the same
198
 * struct type */
199
#define strdup_between_structs(_dst, _src, _m) \
200
    strdup_between_offsets((void *)_dst, (void *)_src, offsetof(__typeof__(*(_src)), _m))
201
202
203
extern char *xstrmode(mode_t mode, char *str);
204
205
/* Options for size_to_human_string() */
206
enum
207
{
208
  SIZE_SUFFIX_1LETTER  = 0,
209
  SIZE_SUFFIX_3LETTER  = (1 << 0),
210
  SIZE_SUFFIX_SPACE    = (1 << 1),
211
  SIZE_DECIMAL_2DIGITS = (1 << 2)
212
};
213
214
extern char *size_to_human_string(int options, uint64_t bytes);
215
216
extern int string_to_idarray(const char *list, int ary[], size_t arysz,
217
         int (name2id)(const char *, size_t));
218
extern int string_add_to_idarray(const char *list, int ary[],
219
         size_t arysz, size_t *ary_pos,
220
         int (name2id)(const char *, size_t));
221
222
extern int string_to_bitarray(const char *list, char *ary,
223
          int (*name2bit)(const char *, size_t),
224
          size_t allow_range);
225
226
extern int string_to_bitmask(const char *list,
227
           unsigned long *mask,
228
           long (*name2flag)(const char *, size_t));
229
extern int parse_range(const char *str, int *lower, int *upper, int def);
230
231
extern int streq_paths(const char *a, const char *b);
232
233
/*
234
 * Match string beginning.
235
 */
236
static inline const char *startswith(const char *s, const char *prefix)
237
0
{
238
0
  size_t sz = prefix ? strlen(prefix) : 0;
239
240
0
        if (s && sz && strncmp(s, prefix, sz) == 0)
241
0
                return s + sz;
242
0
  return NULL;
243
0
}
Unexecuted instantiation: gen_uuid.c:startswith
Unexecuted instantiation: probe.c:startswith
Unexecuted instantiation: partitions.c:startswith
Unexecuted instantiation: path.c:startswith
Unexecuted instantiation: sysfs.c:startswith
Unexecuted instantiation: devname.c:startswith
Unexecuted instantiation: devno.c:startswith
Unexecuted instantiation: buffer.c:startswith
Unexecuted instantiation: canonicalize.c:startswith
Unexecuted instantiation: mbsalign.c:startswith
244
245
/*
246
 * Case insensitive match string beginning.
247
 */
248
static inline const char *startswith_no_case(const char *s, const char *prefix)
249
0
{
250
0
  size_t sz = prefix ? strlen(prefix) : 0;
251
0
252
0
        if (s && sz && strncasecmp(s, prefix, sz) == 0)
253
0
                return s + sz;
254
0
  return NULL;
255
0
}
Unexecuted instantiation: gen_uuid.c:startswith_no_case
Unexecuted instantiation: probe.c:startswith_no_case
Unexecuted instantiation: partitions.c:startswith_no_case
Unexecuted instantiation: path.c:startswith_no_case
Unexecuted instantiation: sysfs.c:startswith_no_case
Unexecuted instantiation: devname.c:startswith_no_case
Unexecuted instantiation: devno.c:startswith_no_case
Unexecuted instantiation: buffer.c:startswith_no_case
Unexecuted instantiation: canonicalize.c:startswith_no_case
Unexecuted instantiation: mbsalign.c:startswith_no_case
256
257
/*
258
 * Match string ending.
259
 */
260
static inline const char *endswith(const char *s, const char *postfix)
261
0
{
262
0
  size_t sl = s ? strlen(s) : 0;
263
0
  size_t pl = postfix ? strlen(postfix) : 0;
264
0
265
0
  if (pl == 0)
266
0
    return s + sl;
267
0
  if (sl < pl)
268
0
    return NULL;
269
0
  if (memcmp(s + sl - pl, postfix, pl) != 0)
270
0
    return NULL;
271
0
  return s + sl - pl;
272
0
}
Unexecuted instantiation: gen_uuid.c:endswith
Unexecuted instantiation: probe.c:endswith
Unexecuted instantiation: partitions.c:endswith
Unexecuted instantiation: path.c:endswith
Unexecuted instantiation: sysfs.c:endswith
Unexecuted instantiation: devname.c:endswith
Unexecuted instantiation: devno.c:endswith
Unexecuted instantiation: buffer.c:endswith
Unexecuted instantiation: canonicalize.c:endswith
Unexecuted instantiation: mbsalign.c:endswith
273
274
/*
275
 * Skip leading white space.
276
 */
277
static inline const char *skip_space(const char *p)
278
0
{
279
0
  while (isspace(*p))
280
0
    ++p;
281
0
  return p;
282
0
}
Unexecuted instantiation: gen_uuid.c:skip_space
Unexecuted instantiation: probe.c:skip_space
Unexecuted instantiation: partitions.c:skip_space
Unexecuted instantiation: path.c:skip_space
Unexecuted instantiation: sysfs.c:skip_space
Unexecuted instantiation: devname.c:skip_space
Unexecuted instantiation: devno.c:skip_space
Unexecuted instantiation: buffer.c:skip_space
Unexecuted instantiation: canonicalize.c:skip_space
Unexecuted instantiation: mbsalign.c:skip_space
283
284
static inline const char *skip_blank(const char *p)
285
0
{
286
0
  while (isblank(*p))
287
0
    ++p;
288
0
  return p;
289
0
}
Unexecuted instantiation: gen_uuid.c:skip_blank
Unexecuted instantiation: probe.c:skip_blank
Unexecuted instantiation: partitions.c:skip_blank
Unexecuted instantiation: path.c:skip_blank
Unexecuted instantiation: sysfs.c:skip_blank
Unexecuted instantiation: devname.c:skip_blank
Unexecuted instantiation: devno.c:skip_blank
Unexecuted instantiation: buffer.c:skip_blank
Unexecuted instantiation: canonicalize.c:skip_blank
Unexecuted instantiation: mbsalign.c:skip_blank
290
291
292
/* Removes whitespace from the right-hand side of a string (trailing
293
 * whitespace).
294
 *
295
 * Returns size of the new string (without \0).
296
 */
297
static inline size_t rtrim_whitespace(unsigned char *str)
298
0
{
299
0
  size_t i;
300
301
0
  if (!str)
302
0
    return 0;
303
0
  i = strlen((char *) str);
304
0
  while (i) {
305
0
    i--;
306
0
    if (!isspace(str[i])) {
307
0
      i++;
308
0
      break;
309
0
    }
310
0
  }
311
0
  str[i] = '\0';
312
0
  return i;
313
0
}
Unexecuted instantiation: gen_uuid.c:rtrim_whitespace
Unexecuted instantiation: probe.c:rtrim_whitespace
Unexecuted instantiation: partitions.c:rtrim_whitespace
Unexecuted instantiation: path.c:rtrim_whitespace
Unexecuted instantiation: sysfs.c:rtrim_whitespace
Unexecuted instantiation: devname.c:rtrim_whitespace
Unexecuted instantiation: devno.c:rtrim_whitespace
Unexecuted instantiation: buffer.c:rtrim_whitespace
Unexecuted instantiation: canonicalize.c:rtrim_whitespace
Unexecuted instantiation: mbsalign.c:rtrim_whitespace
314
315
/* Removes whitespace from the left-hand side of a string.
316
 *
317
 * Returns size of the new string (without \0).
318
 */
319
static inline size_t ltrim_whitespace(unsigned char *str)
320
0
{
321
0
  size_t len;
322
0
  unsigned char *p;
323
324
0
  if (!str)
325
0
    return 0;
326
0
  for (p = str; *p && isspace(*p); p++);
327
328
0
  len = strlen((char *) p);
329
330
0
  if (p > str)
331
0
    memmove(str, p, len + 1);
332
333
0
  return len;
334
0
}
Unexecuted instantiation: gen_uuid.c:ltrim_whitespace
Unexecuted instantiation: probe.c:ltrim_whitespace
Unexecuted instantiation: partitions.c:ltrim_whitespace
Unexecuted instantiation: path.c:ltrim_whitespace
Unexecuted instantiation: sysfs.c:ltrim_whitespace
Unexecuted instantiation: devname.c:ltrim_whitespace
Unexecuted instantiation: devno.c:ltrim_whitespace
Unexecuted instantiation: buffer.c:ltrim_whitespace
Unexecuted instantiation: canonicalize.c:ltrim_whitespace
Unexecuted instantiation: mbsalign.c:ltrim_whitespace
335
336
/* Removes left-hand, right-hand and repeating whitespaces.
337
 */
338
static inline size_t __normalize_whitespace(
339
        const unsigned char *src,
340
        size_t sz,
341
        unsigned char *dst,
342
        size_t len)
343
0
{
344
0
  size_t i, x = 0;
345
0
  int nsp = 0, intext = 0;
346
0
347
0
  if (!sz)
348
0
    goto done;
349
0
350
0
  for (i = 0, x = 0; i < sz && x < len - 1;  ) {
351
0
    if (isspace(src[i]))
352
0
      nsp++;
353
0
    else
354
0
      nsp = 0, intext = 1;
355
0
356
0
    if (nsp > 1 || (nsp && !intext))
357
0
      i++;
358
0
    else
359
0
      dst[x++] = src[i++];
360
0
  }
361
0
  if (nsp && x > 0)   /* tailing space */
362
0
    x--;
363
0
done:
364
0
  dst[x] = '\0';
365
0
  return x;
366
0
}
Unexecuted instantiation: gen_uuid.c:__normalize_whitespace
Unexecuted instantiation: probe.c:__normalize_whitespace
Unexecuted instantiation: partitions.c:__normalize_whitespace
Unexecuted instantiation: path.c:__normalize_whitespace
Unexecuted instantiation: sysfs.c:__normalize_whitespace
Unexecuted instantiation: devname.c:__normalize_whitespace
Unexecuted instantiation: devno.c:__normalize_whitespace
Unexecuted instantiation: buffer.c:__normalize_whitespace
Unexecuted instantiation: canonicalize.c:__normalize_whitespace
Unexecuted instantiation: mbsalign.c:__normalize_whitespace
367
368
static inline size_t normalize_whitespace(unsigned char *str)
369
0
{
370
0
  size_t sz = strlen((char *) str);
371
0
  return __normalize_whitespace(str, sz, str, sz + 1);
372
0
}
Unexecuted instantiation: gen_uuid.c:normalize_whitespace
Unexecuted instantiation: probe.c:normalize_whitespace
Unexecuted instantiation: partitions.c:normalize_whitespace
Unexecuted instantiation: path.c:normalize_whitespace
Unexecuted instantiation: sysfs.c:normalize_whitespace
Unexecuted instantiation: devname.c:normalize_whitespace
Unexecuted instantiation: devno.c:normalize_whitespace
Unexecuted instantiation: buffer.c:normalize_whitespace
Unexecuted instantiation: canonicalize.c:normalize_whitespace
Unexecuted instantiation: mbsalign.c:normalize_whitespace
373
374
static inline void strrep(char *s, int find, int replace)
375
0
{
376
0
  while (s && *s && (s = strchr(s, find)) != NULL)
377
0
    *s++ = replace;
378
0
}
Unexecuted instantiation: gen_uuid.c:strrep
Unexecuted instantiation: probe.c:strrep
Unexecuted instantiation: partitions.c:strrep
Unexecuted instantiation: path.c:strrep
Unexecuted instantiation: sysfs.c:strrep
Unexecuted instantiation: devname.c:strrep
Unexecuted instantiation: devno.c:strrep
Unexecuted instantiation: buffer.c:strrep
Unexecuted instantiation: canonicalize.c:strrep
Unexecuted instantiation: mbsalign.c:strrep
379
380
static inline void strrem(char *s, int rem)
381
0
{
382
0
  char *p;
383
0
384
0
  if (!s)
385
0
    return;
386
0
  for (p = s; *s; s++) {
387
0
    if (*s != rem)
388
0
      *p++ = *s;
389
0
  }
390
0
  *p = '\0';
391
0
}
Unexecuted instantiation: gen_uuid.c:strrem
Unexecuted instantiation: probe.c:strrem
Unexecuted instantiation: partitions.c:strrem
Unexecuted instantiation: path.c:strrem
Unexecuted instantiation: sysfs.c:strrem
Unexecuted instantiation: devname.c:strrem
Unexecuted instantiation: devno.c:strrem
Unexecuted instantiation: buffer.c:strrem
Unexecuted instantiation: canonicalize.c:strrem
Unexecuted instantiation: mbsalign.c:strrem
392
393
/* returns next string after \0 if before @end */
394
static inline char *ul_next_string(char *p, char *end)
395
0
{
396
0
  char *last;
397
0
398
0
  if (!p || !end || p >= end)
399
0
    return NULL;
400
0
401
0
  for (last = p; p < end; p++) {
402
0
    if (*last == '\0' && p != last)
403
0
      return p;
404
0
    last = p;
405
0
  }
406
0
407
0
  return NULL;
408
0
}
Unexecuted instantiation: gen_uuid.c:ul_next_string
Unexecuted instantiation: probe.c:ul_next_string
Unexecuted instantiation: partitions.c:ul_next_string
Unexecuted instantiation: path.c:ul_next_string
Unexecuted instantiation: sysfs.c:ul_next_string
Unexecuted instantiation: devname.c:ul_next_string
Unexecuted instantiation: devno.c:ul_next_string
Unexecuted instantiation: buffer.c:ul_next_string
Unexecuted instantiation: canonicalize.c:ul_next_string
Unexecuted instantiation: mbsalign.c:ul_next_string
409
410
extern char *strnconcat(const char *s, const char *suffix, size_t b);
411
extern char *strconcat(const char *s, const char *suffix);
412
extern char *strfconcat(const char *s, const char *format, ...)
413
     __attribute__ ((__format__ (__printf__, 2, 3)));
414
415
extern int strappend(char **a, const char *b);
416
extern int strfappend(char **a, const char *format, ...)
417
     __attribute__ ((__format__ (__printf__, 2, 3)));
418
extern int strvfappend(char **a, const char *format, va_list ap)
419
     __attribute__ ((__format__ (__printf__, 2, 0)));
420
421
extern const char *split(const char **state, size_t *l, const char *separator, int quoted);
422
423
extern char *ul_strchr_escaped(const char *s, int c);
424
425
extern int skip_fline(FILE *fp);
426
extern int ul_stralnumcmp(const char *p1, const char *p2);
427
428
extern int ul_optstr_next(char **optstr, char **name, size_t *namesz, char **value, size_t *valsz);
429
430
#endif