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