commit 808d5506ce033fee5b1e8b002e9d47a92355a582
parent 9ba593c97dddd8155ea8baa45884a7c763cd3c55
Author: Louis Burda <quent.burda@gmail.com>
Date: Sat, 3 Jun 2023 02:39:38 +0200
Add strvec_join and strvec_remove_str
Diffstat:
5 files changed, 79 insertions(+), 7 deletions(-)
diff --git a/build.jst.tmpl b/build.jst.tmpl
@@ -42,15 +42,15 @@ target lib/libdvec/build/libdvec.a
just lib/libdvec
target build/libstrvec.a
- liba src/strvec.c lib/libdvec/build/libdvec.a
- lib/liballoc/build/liballoc.a | build
+ liba src/strvec.c lib/libdvec/build/libdvec.a
+ lib/liballoc/build/liballoc.a | include/strvec.h libstrvec.api build
target build/libstrvec.so
libso src/strvec.c | build
target build/test
cc src/test.c build/libstrvec.a lib/liballoc/build/liballoc.a
- lib/libdvec/build/libdvec.a | build
+ lib/libdvec/build/libdvec.a | include/strvec.h libstrvec.lds build
command clean
rm -rf build
diff --git a/include/strvec.h b/include/strvec.h
@@ -58,6 +58,11 @@ const char **strvec_popn(struct strvec *strvec, size_t n);
static inline const char *strvec_pop(struct strvec *strvec);
void strvec_replace(struct strvec *strvec, size_t index, const char *str);
void strvec_remove(struct strvec *strvec, size_t index, size_t n);
+int strvec_remove_str(struct strvec *strvec, const char *str,
+ const struct allocator *allocator);
+
+char *strvec_join(struct strvec *strvec, const char *sep,
+ const struct allocator *allocator, int *rc);
const char **strvec_iter_fwd(const struct strvec *strvec, const char **p);
const char **strvec_iter_bwd(const struct strvec *strvec, const char **p);
diff --git a/libstrvec.api b/libstrvec.api
@@ -20,7 +20,9 @@ strvec_popn
strvec_replace
strvec_remove
+strvec_remove_str
+
+strvec_join
+
strvec_iter_fwd
strvec_iter_bwd
-
-strvec_dsize
diff --git a/libstrvec.lds b/libstrvec.lds
@@ -22,9 +22,11 @@ LIBSTRVEC_1.0.0 {
strvec_replace;
strvec_remove;
+ strvec_remove_str;
+
+ strvec_join;
+
strvec_iter_fwd;
strvec_iter_bwd;
-
- strvec_dsize;
local: *;
};
diff --git a/src/strvec.c b/src/strvec.c
@@ -203,6 +203,69 @@ strvec_remove(struct strvec *strvec, size_t index, size_t count)
dvec_rm(&strvec->vec, index, count);
}
+int
+strvec_remove_str(struct strvec *strvec, const char *str,
+ const struct allocator *allocator)
+{
+ const char **ent;
+ size_t i;
+ int rc;
+
+ LIBSTRVEC_ABORT_ON_ARGS(!strvec);
+
+ for (i = 0; i < strvec->vec.len; ) {
+ ent = strvec_at(strvec, i);
+ if (!str && !*ent || !strcmp(str, *ent)) {
+ if (allocator) {
+ rc = allocator->free(allocator, (char *) *ent);
+ if (rc) return -rc;
+ }
+ strvec_remove(strvec, i, 1);
+ } else {
+ i++;
+ }
+ }
+
+ return 0;
+}
+
+char *
+strvec_join(struct strvec *strvec, const char *sep,
+ const struct allocator *allocator, int *_rc)
+{
+ const char **ent;
+ size_t len, seplen;
+ char *str;
+
+ seplen = strlen(sep);
+
+ len = 0;
+ for (STRVEC_ITER(strvec, ent)) {
+ if (!*ent) continue;
+ if (len) len += seplen;
+ len += strlen(*ent);
+ }
+
+ str = allocator->alloc(allocator, len + 1, _rc);
+ if (!str && _rc) *_rc = -*_rc;
+ if (!str) return NULL;
+
+ len = 0;
+ for (STRVEC_ITER(strvec, ent)) {
+ if (!*ent) continue;
+
+ if (len) {
+ strcpy(str + len, sep);
+ len += seplen;
+ }
+
+ strcpy(str + len, *ent);
+ len += strlen(*ent);
+ }
+
+ return str;
+}
+
const char **
strvec_iter_fwd(const struct strvec *strvec, const char **p)
{