Branch data Line data Source code
1 : : /* SPDX-License-Identifier: LGPL-2.1+ */
2 : :
3 : : /*
4 : : * Concatenates/copies strings. In any case, terminates in all cases
5 : : * with '\0' and moves the @dest pointer forward to the added '\0'.
6 : : * Returns the remaining size, and 0 if the string was truncated.
7 : : *
8 : : * Due to the intended usage, these helpers silently noop invocations
9 : : * having zero size. This is technically an exception to the above
10 : : * statement "terminates in all cases". It's unexpected for such calls to
11 : : * occur outside of a loop where this is the preferred behavior.
12 : : */
13 : :
14 : : #include <stdarg.h>
15 : : #include <stdio.h>
16 : : #include <string.h>
17 : :
18 : : #include "strxcpyx.h"
19 : :
20 : 460 : size_t strnpcpy(char **dest, size_t size, const char *src, size_t len) {
21 [ - + ]: 460 : assert(dest);
22 [ - + ]: 460 : assert(src);
23 : :
24 [ - + ]: 460 : if (size == 0)
25 : 0 : return 0;
26 : :
27 [ + + ]: 460 : if (len >= size) {
28 [ - + ]: 4 : if (size > 1)
29 : 0 : *dest = mempcpy(*dest, src, size-1);
30 : 4 : size = 0;
31 [ + - ]: 456 : } else if (len > 0) {
32 : 456 : *dest = mempcpy(*dest, src, len);
33 : 456 : size -= len;
34 : : }
35 : :
36 : 460 : *dest[0] = '\0';
37 : 460 : return size;
38 : : }
39 : :
40 : 84 : size_t strpcpy(char **dest, size_t size, const char *src) {
41 [ - + ]: 84 : assert(dest);
42 [ - + ]: 84 : assert(src);
43 : :
44 : 84 : return strnpcpy(dest, size, src, strlen(src));
45 : : }
46 : :
47 : 544 : size_t strpcpyf(char **dest, size_t size, const char *src, ...) {
48 : : va_list va;
49 : : int i;
50 : :
51 [ - + ]: 544 : assert(dest);
52 [ - + ]: 544 : assert(src);
53 : :
54 [ - + ]: 544 : if (size == 0)
55 : 0 : return 0;
56 : :
57 : 544 : va_start(va, src);
58 : 544 : i = vsnprintf(*dest, size, src, va);
59 [ + + ]: 544 : if (i < (int)size) {
60 : 540 : *dest += i;
61 : 540 : size -= i;
62 : : } else
63 : 4 : size = 0;
64 : 544 : va_end(va);
65 : 544 : return size;
66 : : }
67 : :
68 : 8 : size_t strpcpyl(char **dest, size_t size, const char *src, ...) {
69 : : va_list va;
70 : :
71 [ - + ]: 8 : assert(dest);
72 [ - + ]: 8 : assert(src);
73 : :
74 : 8 : va_start(va, src);
75 : : do {
76 : 16 : size = strpcpy(dest, size, src);
77 : 16 : src = va_arg(va, char *);
78 [ + + ]: 16 : } while (src);
79 : 8 : va_end(va);
80 : 8 : return size;
81 : : }
82 : :
83 : 376 : size_t strnscpy(char *dest, size_t size, const char *src, size_t len) {
84 : : char *s;
85 : :
86 [ - + ]: 376 : assert(dest);
87 [ - + ]: 376 : assert(src);
88 : :
89 : 376 : s = dest;
90 : 376 : return strnpcpy(&s, size, src, len);
91 : : }
92 : :
93 : 376 : size_t strscpy(char *dest, size_t size, const char *src) {
94 [ - + ]: 376 : assert(dest);
95 [ - + ]: 376 : assert(src);
96 : :
97 : 376 : return strnscpy(dest, size, src, strlen(src));
98 : : }
99 : :
100 : 20 : size_t strscpyl(char *dest, size_t size, const char *src, ...) {
101 : : va_list va;
102 : : char *s;
103 : :
104 [ - + ]: 20 : assert(dest);
105 [ - + ]: 20 : assert(src);
106 : :
107 : 20 : va_start(va, src);
108 : 20 : s = dest;
109 : : do {
110 : 44 : size = strpcpy(&s, size, src);
111 : 44 : src = va_arg(va, char *);
112 [ + + ]: 44 : } while (src);
113 : 20 : va_end(va);
114 : :
115 : 20 : return size;
116 : : }
|