| 196 | } |
| 197 | |
| 198 | int parse_names(char *buf, int size, char ***out) |
| 199 | { |
| 200 | char **names = NULL; |
| 201 | size_t names_cap = 0; |
| 202 | size_t names_len = 0; |
| 203 | char *p = buf; |
| 204 | char *end = buf + size; |
| 205 | int err = 0; |
| 206 | |
| 207 | while (p < end) { |
| 208 | char *next = strchr(p, '\n'); |
| 209 | if (!next) { |
| 210 | err = REFTABLE_FORMAT_ERROR; |
| 211 | goto done; |
| 212 | } else if (next < end) { |
| 213 | *next = '\0'; |
| 214 | } else { |
| 215 | next = end; |
| 216 | } |
| 217 | |
| 218 | if (p < next) { |
| 219 | if (REFTABLE_ALLOC_GROW(names, names_len + 1, |
| 220 | names_cap)) { |
| 221 | err = REFTABLE_OUT_OF_MEMORY_ERROR; |
| 222 | goto done; |
| 223 | } |
| 224 | |
| 225 | names[names_len] = reftable_strdup(p); |
| 226 | if (!names[names_len++]) { |
| 227 | err = REFTABLE_OUT_OF_MEMORY_ERROR; |
| 228 | goto done; |
| 229 | } |
| 230 | } |
| 231 | p = next + 1; |
| 232 | } |
| 233 | |
| 234 | if (REFTABLE_ALLOC_GROW(names, names_len + 1, names_cap)) { |
| 235 | err = REFTABLE_OUT_OF_MEMORY_ERROR; |
| 236 | goto done; |
| 237 | } |
| 238 | names[names_len] = NULL; |
| 239 | |
| 240 | *out = names; |
| 241 | return 0; |
| 242 | done: |
| 243 | for (size_t i = 0; i < names_len; i++) |
| 244 | reftable_free(names[i]); |
| 245 | reftable_free(names); |
| 246 | return err; |
| 247 | } |
| 248 | |
| 249 | int names_equal(const char **a, const char **b) |
| 250 | { |