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 115 : size_t strnpcpy(char **dest, size_t size, const char *src, size_t len) {
21 115 : assert(dest);
22 115 : assert(src);
23 :
24 115 : if (size == 0)
25 0 : return 0;
26 :
27 115 : if (len >= size) {
28 1 : if (size > 1)
29 0 : *dest = mempcpy(*dest, src, size-1);
30 1 : size = 0;
31 114 : } else if (len > 0) {
32 114 : *dest = mempcpy(*dest, src, len);
33 114 : size -= len;
34 : }
35 :
36 115 : *dest[0] = '\0';
37 115 : return size;
38 : }
39 :
40 21 : size_t strpcpy(char **dest, size_t size, const char *src) {
41 21 : assert(dest);
42 21 : assert(src);
43 :
44 21 : return strnpcpy(dest, size, src, strlen(src));
45 : }
46 :
47 136 : size_t strpcpyf(char **dest, size_t size, const char *src, ...) {
48 : va_list va;
49 : int i;
50 :
51 136 : assert(dest);
52 136 : assert(src);
53 :
54 136 : if (size == 0)
55 0 : return 0;
56 :
57 136 : va_start(va, src);
58 136 : i = vsnprintf(*dest, size, src, va);
59 136 : if (i < (int)size) {
60 135 : *dest += i;
61 135 : size -= i;
62 : } else
63 1 : size = 0;
64 136 : va_end(va);
65 136 : return size;
66 : }
67 :
68 2 : size_t strpcpyl(char **dest, size_t size, const char *src, ...) {
69 : va_list va;
70 :
71 2 : assert(dest);
72 2 : assert(src);
73 :
74 2 : va_start(va, src);
75 : do {
76 4 : size = strpcpy(dest, size, src);
77 4 : src = va_arg(va, char *);
78 4 : } while (src);
79 2 : va_end(va);
80 2 : return size;
81 : }
82 :
83 94 : size_t strnscpy(char *dest, size_t size, const char *src, size_t len) {
84 : char *s;
85 :
86 94 : assert(dest);
87 94 : assert(src);
88 :
89 94 : s = dest;
90 94 : return strnpcpy(&s, size, src, len);
91 : }
92 :
93 94 : size_t strscpy(char *dest, size_t size, const char *src) {
94 94 : assert(dest);
95 94 : assert(src);
96 :
97 94 : return strnscpy(dest, size, src, strlen(src));
98 : }
99 :
100 5 : size_t strscpyl(char *dest, size_t size, const char *src, ...) {
101 : va_list va;
102 : char *s;
103 :
104 5 : assert(dest);
105 5 : assert(src);
106 :
107 5 : va_start(va, src);
108 5 : s = dest;
109 : do {
110 11 : size = strpcpy(&s, size, src);
111 11 : src = va_arg(va, char *);
112 11 : } while (src);
113 5 : va_end(va);
114 :
115 5 : return size;
116 : }
|