| 120 |
121 |
| 121 va_list ap; |
122 va_list ap; |
| 122 va_start(ap, count); |
123 va_start(ap, count); |
| 123 |
124 |
| 124 // get all args and overall length |
125 // get all args and overall length |
| |
126 bool overflow = false; |
| 125 size_t slen = str.length; |
127 size_t slen = str.length; |
| 126 for (size_t i = 0; i < count; i++) { |
128 for (size_t i = 0; i < count; i++) { |
| 127 cxstring s = va_arg (ap, cxstring); |
129 cxstring s = va_arg (ap, cxstring); |
| 128 strings[i] = s; |
130 strings[i] = s; |
| |
131 if (slen > SIZE_MAX - str.length) overflow = true; |
| 129 slen += s.length; |
132 slen += s.length; |
| 130 } |
133 } |
| 131 va_end(ap); |
134 va_end(ap); |
| |
135 |
| |
136 // abort in case of overflow |
| |
137 if (overflow) { |
| |
138 errno = EOVERFLOW; |
| |
139 if (strings != strings_stack) { |
| |
140 free(strings); |
| |
141 } |
| |
142 return (cxmutstr) { NULL, 0 }; |
| |
143 } |
| 132 |
144 |
| 133 // reallocate or create new string |
145 // reallocate or create new string |
| 134 char *newstr; |
146 char *newstr; |
| 135 if (str.ptr == NULL) { |
147 if (str.ptr == NULL) { |
| 136 newstr = cxMalloc(alloc, slen + 1); |
148 newstr = cxMalloc(alloc, slen + 1); |
| 137 } else { |
149 } else { |
| 138 newstr = cxRealloc(alloc, str.ptr, slen + 1); |
150 newstr = cxRealloc(alloc, str.ptr, slen + 1); |
| 139 } |
151 } |
| 140 if (newstr == NULL) { |
152 if (newstr == NULL) { |
| 141 free(strings); |
153 if (strings != strings_stack) { |
| |
154 free(strings); |
| |
155 } |
| 142 return (cxmutstr) {NULL, 0}; |
156 return (cxmutstr) {NULL, 0}; |
| 143 } |
157 } |
| 144 str.ptr = newstr; |
158 str.ptr = newstr; |
| 145 |
159 |
| 146 // concatenate strings |
160 // concatenate strings |