src/string.c

changeset 1667
608cc0b25352
parent 1652
db8299984bfe
child 1668
3ffdfe1776b4
equal deleted inserted replaced
1665:b79405fbf91d 1667:608cc0b25352
97 va_end(ap); 97 va_end(ap);
98 98
99 return size; 99 return size;
100 } 100 }
101 101
102 cxmutstr cx_strcat_ma( 102 int cx_strcat_a(
103 const CxAllocator *alloc, 103 const CxAllocator *alloc,
104 cxmutstr str, 104 cxmutstr *str,
105 size_t count, 105 size_t count,
106 ... 106 ...
107 ) { 107 ) {
108 if (count == 0) return str; 108 if (count == 0) return 0;
109 va_list ap; 109 va_list ap;
110 va_start(ap, count); 110 va_start(ap, count);
111 va_list ap2; 111 va_list ap2;
112 va_copy(ap2, ap); 112 va_copy(ap2, ap);
113 113
114 // compute overall length 114 // compute overall length
115 bool overflow = false; 115 bool overflow = false;
116 size_t slen = str.length; 116 size_t slen = str->length;
117 for (size_t i = 0; i < count; i++) { 117 for (size_t i = 0; i < count; i++) {
118 cxstring s = va_arg(ap, cxstring); 118 cxstring s = va_arg(ap, cxstring);
119 if (slen > SIZE_MAX - s.length) overflow = true; 119 if (slen > SIZE_MAX - s.length) overflow = true;
120 slen += s.length; 120 slen += s.length;
121 } 121 }
123 123
124 // abort in case of overflow 124 // abort in case of overflow
125 if (overflow) { 125 if (overflow) {
126 va_end(ap2); 126 va_end(ap2);
127 errno = EOVERFLOW; 127 errno = EOVERFLOW;
128 return (cxmutstr) { NULL, 0 }; 128 return -1;
129 } 129 }
130 130
131 // reallocate or create new string 131 // reallocate or create new string
132 char *newstr; 132 if (cxReallocate(alloc, &str->ptr, slen + 1)) {
133 if (str.ptr == NULL) { 133 // LCOV_EXCL_START
134 newstr = cxMalloc(alloc, slen + 1);
135 } else {
136 newstr = cxRealloc(alloc, str.ptr, slen + 1);
137 }
138 if (newstr == NULL) { // LCOV_EXCL_START
139 va_end(ap2); 134 va_end(ap2);
140 return (cxmutstr) {NULL, 0}; 135 return -1;
141 } // LCOV_EXCL_STOP 136 // LCOV_EXCL_STOP
142 str.ptr = newstr; 137 }
143 138
144 // concatenate strings 139 // concatenate strings
145 size_t pos = str.length; 140 size_t pos = str->length;
146 str.length = slen; 141 str->length = slen;
147 for (size_t i = 0; i < count; i++) { 142 for (size_t i = 0; i < count; i++) {
148 cxstring s = va_arg(ap2, cxstring); 143 cxstring s = va_arg(ap2, cxstring);
149 memcpy(str.ptr + pos, s.ptr, s.length); 144 memcpy(str->ptr + pos, s.ptr, s.length);
150 pos += s.length; 145 pos += s.length;
151 } 146 }
152 va_end(ap2); 147 va_end(ap2);
153 148
154 // terminate string 149 // terminate string
155 str.ptr[str.length] = '\0'; 150 str->ptr[str->length] = '\0';
156 151
157 return str; 152 return 0;
158 } 153 }
159 154
160 cxstring cx_strsubs( 155 cxstring cx_strsubs(
161 cxstring string, 156 cxstring string,
162 size_t start 157 size_t start

mercurial