]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/basic/strxcpyx.c
46712ed67deefaba402fb98e823c5fe1d873abc9
[thirdparty/systemd.git] / src / basic / strxcpyx.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2 /***
3 Copyright © 2013 Kay Sievers
4 ***/
5
6 /*
7 * Concatenates/copies strings. In any case, terminates in all cases
8 * with '\0' and moves the @dest pointer forward to the added '\0'.
9 * Returns the remaining size, and 0 if the string was truncated.
10 *
11 * Due to the intended usage, these helpers silently noop invocations
12 * having zero size. This is technically an exception to the above
13 * statement "terminates in all cases". It's unexpected for such calls to
14 * occur outside of a loop where this is the preferred behavior.
15 */
16
17 #include <stdarg.h>
18 #include <stdio.h>
19 #include <string.h>
20
21 #include "strxcpyx.h"
22
23 size_t strpcpy(char **dest, size_t size, const char *src) {
24 size_t len;
25
26 assert(dest);
27 assert(src);
28
29 if (size == 0)
30 return 0;
31
32 len = strlen(src);
33 if (len >= size) {
34 if (size > 1)
35 *dest = mempcpy(*dest, src, size-1);
36 size = 0;
37 } else {
38 if (len > 0) {
39 *dest = mempcpy(*dest, src, len);
40 size -= len;
41 }
42 }
43 *dest[0] = '\0';
44 return size;
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 }
65 va_end(va);
66 return size;
67 }
68
69 size_t strpcpyl(char **dest, size_t size, const char *src, ...) {
70 va_list va;
71
72 assert(dest);
73 assert(src);
74
75 va_start(va, src);
76 do {
77 size = strpcpy(dest, size, src);
78 src = va_arg(va, char *);
79 } while (src != NULL);
80 va_end(va);
81 return size;
82 }
83
84 size_t strscpy(char *dest, size_t size, const char *src) {
85 char *s;
86
87 assert(dest);
88 assert(src);
89
90 s = dest;
91 return strpcpy(&s, size, src);
92 }
93
94 size_t strscpyl(char *dest, size_t size, const char *src, ...) {
95 va_list va;
96 char *s;
97
98 assert(dest);
99 assert(src);
100
101 va_start(va, src);
102 s = dest;
103 do {
104 size = strpcpy(&s, size, src);
105 src = va_arg(va, char *);
106 } while (src != NULL);
107 va_end(va);
108
109 return size;
110 }