When the last entry in the file was deleted, cfg_del_section() would loop
forever because *p was never set to NULL by svec_del(). (Alternatively,
it could segfault because we were accessing freed memory.)
This better implementation is also O(N) instead of O(N**2).
ds_put_char(§ion, '.');
va_end(args);
- for (p = cfg.names; *p; ) { /* XXX this is inefficient */
+ for (p = cfg.names; *p; p++) {
if (!strncmp(section.string, *p, section.length)) {
- /* Delete this matching entry in-place, so don't move on to
- * the next entry. */
- svec_del(&cfg, *p);
- } else {
- /* Move onto the next entry. */
- p++;
+ free(*p);
+ *p = NULL;
}
}
+ svec_compact(&cfg);
+ svec_terminate(&cfg);
+
ds_destroy(§ion);
dirty = true;
}
}
}
+void
+svec_compact(struct svec *svec)
+{
+ size_t i, j;
+
+ for (i = j = 0; i < svec->n; i++) {
+ if (svec->names[i] != NULL) {
+ svec->names[j++] = svec->names[i];
+ }
+ }
+ svec->n = j;
+}
+
void
svec_diff(const struct svec *a, const struct svec *b,
struct svec *a_only, struct svec *both, struct svec *b_only)
void svec_sort(struct svec *);
void svec_sort_unique(struct svec *);
void svec_unique(struct svec *);
+void svec_compact(struct svec *);
void svec_diff(const struct svec *a, const struct svec *b,
struct svec *a_only, struct svec *both, struct svec *b_only);
bool svec_contains(const struct svec *, const char *);