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