-
Notifications
You must be signed in to change notification settings - Fork 1
/
str.c
93 lines (74 loc) · 2.45 KB
/
str.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
/*
* Copyright (c) 2015-2016, Fred Morcos <fred.morcos@gmail.com>
*
* Permission to use, copy, modify, and/or distribute this software
* for any purpose with or without fee is hereby granted, provided
* that the above copyright notice and this permission notice appear
* in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <assert.h>
#include <stdarg.h>
#include <stdio.h>
#include "mem.h"
#include "str.h"
int xasprintf(size_t *const l, char **const s, const char *const f, ...) {
assert(s != NULL);
assert(f != NULL);
va_list ap;
int len_i = 0;
size_t len_st = 0;
va_start(ap, f);
len_i = vsnprintf(NULL, 0, f, ap);
va_end(ap);
if (len_i < 0)
return -1; /* errno is set */
len_st = (size_t) len_i;
if (!xrealloc((void **) s, len_st + 1, sizeof(char)))
return -2; /* errno is set */
va_start(ap, f);
len_i = vsnprintf(*s, len_st + 1, f, ap);
va_end(ap);
if (len_i < 0 || (size_t) len_i != len_st) {
free(*s);
return -1; /* errno is set */
}
if (l != NULL)
*l = len_st;
return 0;
}
/*
* Copy string src to buffer dst of size dsize. At most dsize - 1
* chars will be copied. Always NUL terminates (unless dsize == 0).
* Returns strlen(src); if retval >= dsize, truncation occurred.
*/
size_t xstrlcpy(char *dst, const char *src, const size_t dsize) {
assert(dst != NULL);
assert(src != NULL);
const char *osrc = src;
size_t nleft = dsize;
/* Copy as many bytes as will fit. */
if (nleft != 0) {
while (--nleft != 0) {
if ((*dst++ = *src++) == '\0')
break;
}
}
/* Not enough room in dst, add NUL and traverse rest of src. */
if (nleft == 0) {
if (dsize != 0)
*dst = '\0'; /* NUL-terminate dst */
while (*src++)
;
}
assert(src - osrc >= 0);
return ((size_t) (src - osrc) - 1); /* count does not include NUL */
}