aboutsummaryrefslogtreecommitdiffstats
path: root/src/dirvec.c
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2008-10-08 06:55:10 +0200
committerMax Kellermann <max@duempel.org>2008-10-08 06:55:10 +0200
commit4cfd356e1266ccf4ebb4082ca62e978dc827adc0 (patch)
tree7159de4784159f5ad8b853408aedf5c0f9d83feb /src/dirvec.c
parentb42974eee12414e28157f53b0d7095515b788785 (diff)
downloadmpd-4cfd356e1266ccf4ebb4082ca62e978dc827adc0.tar.gz
mpd-4cfd356e1266ccf4ebb4082ca62e978dc827adc0.tar.xz
mpd-4cfd356e1266ccf4ebb4082ca62e978dc827adc0.zip
dirvec: moved code to dirvec.c
Having all functions as static (non-inline) functions generates GCC warnings, and duplicates binary code across several object files. Most of dirvec's methods are too complex for becoming inline functions. Move them all to dirvec.c and publish the prototypes in dirvec.h.
Diffstat (limited to '')
-rw-r--r--src/dirvec.c69
1 files changed, 69 insertions, 0 deletions
diff --git a/src/dirvec.c b/src/dirvec.c
new file mode 100644
index 000000000..f84aa37fc
--- /dev/null
+++ b/src/dirvec.c
@@ -0,0 +1,69 @@
+#include "dirvec.h"
+#include "os_compat.h"
+#include "utils.h"
+
+static size_t dv_size(struct dirvec *dv)
+{
+ return dv->nr * sizeof(Directory *);
+}
+
+/* Only used for sorting/searching a dirvec, not general purpose compares */
+static int dirvec_cmp(const void *d1, const void *d2)
+{
+ const Directory *a = ((const Directory * const *)d1)[0];
+ const Directory *b = ((const Directory * const *)d2)[0];
+ return strcmp(a->path, b->path);
+}
+
+void dirvec_sort(struct dirvec *dv)
+{
+ qsort(dv->base, dv->nr, sizeof(Directory *), dirvec_cmp);
+}
+
+Directory *dirvec_find(struct dirvec *dv, const char *path)
+{
+ int i;
+
+ for (i = dv->nr; --i >= 0; )
+ if (!strcmp(dv->base[i]->path, path))
+ return dv->base[i];
+ return NULL;
+}
+
+int dirvec_delete(struct dirvec *dv, Directory *del)
+{
+ int i;
+
+ for (i = dv->nr; --i >= 0; ) {
+ if (dv->base[i] != del)
+ continue;
+ /* we _don't_ call freeDirectory() here */
+ if (!--dv->nr) {
+ free(dv->base);
+ dv->base = NULL;
+ } else {
+ memmove(&dv->base[i], &dv->base[i + 1],
+ (dv->nr - i + 1) * sizeof(Directory *));
+ dv->base = xrealloc(dv->base, dv_size(dv));
+ }
+ return i;
+ }
+
+ return -1; /* not found */
+}
+
+void dirvec_add(struct dirvec *dv, Directory *add)
+{
+ ++dv->nr;
+ dv->base = xrealloc(dv->base, dv_size(dv));
+ dv->base[dv->nr - 1] = add;
+}
+
+void dirvec_destroy(struct dirvec *dv)
+{
+ if (dv->base) {
+ free(dv->base);
+ dv->base = NULL;
+ }
+ dv->nr = 0;
+}