stringbuilder: Functions for joining strings.
[ccan] / ccan / stringbuilder / stringbuilder.c
1 /* CC0 (Public domain) - see LICENSE file for details */
2 #include <ccan/stringbuilder/stringbuilder.h>
3 #include <string.h>
4 #include <errno.h>
5
6 int stringbuilder_args(char* str, size_t str_sz, const char* delim, ...)
7 {
8         int res;
9         va_list ap;
10         va_start(ap, delim);
11         res = stringbuilder_va(str, str_sz, delim, ap);
12         va_end(ap);
13         return res;
14 }
15
16 static int stringbuilder_cpy(
17                 char** str, size_t* str_sz, const char* s, size_t s_len)
18 {
19         if (!s)
20                 return 0;
21
22         if (*str != s) {
23                 if (!s_len)
24                         s_len = strlen(s);
25                 if (s_len > *str_sz)
26                         return EMSGSIZE;
27                 strcpy(*str, s);
28         }
29         *str += s_len;
30         *str_sz -= s_len;
31         return 0;
32 }
33
34 int stringbuilder_va(char* str, size_t str_sz, const char* delim, va_list ap)
35 {
36         int res = 0;
37         size_t delim_len = 0;
38         const char* s = va_arg(ap, const char*);
39
40         if (delim)
41                 delim_len = strlen(delim);
42
43         res = stringbuilder_cpy(&str, &str_sz, s, 0);
44         s = va_arg(ap, const char*);
45         while(s && !res) {
46                 res = stringbuilder_cpy(&str, &str_sz,
47                                 delim, delim_len);
48                 if (!res) {
49                         res = stringbuilder_cpy(&str, &str_sz,
50                                                 s, 0);
51                         s = va_arg(ap, const char*);
52                 }
53         }
54         return res;
55 }
56
57 int stringbuilder_array(char* str, size_t str_sz, const char* delim,
58                 size_t n_strings, const char** strings)
59 {
60         int res = 0;
61         size_t delim_len = 0;
62
63         if (delim)
64                 delim_len = strlen(delim);
65
66         res = stringbuilder_cpy(&str, &str_sz,
67                         *(strings++), 0);
68         while(--n_strings && !res) {
69                 res = stringbuilder_cpy(&str, &str_sz,
70                                 delim, delim_len);
71                 if (!res)
72                         res = stringbuilder_cpy(&str, &str_sz,
73                                         *(strings++), 0);
74         }
75         return res;
76
77 }