-static void dstr_reset(struct dstr *d) { d->len = 0; }
-
-static void dstr_ensure(struct dstr *d, size_t n)
-{
- size_t need = d->len + n, newsz;
-
- if (need <= d->sz) return;
- newsz = d->sz ? 2*d->sz : 16;
- while (newsz < need) newsz *= 2;
- d->p = xrealloc(d->p, newsz); d->sz = newsz;
-}
-
-static void dstr_release(struct dstr *d) { free(d->p); }
-
-static void dstr_putm(struct dstr *d, const void *p, size_t n)
- { dstr_ensure(d, n); memcpy(d->p + d->len, p, n); d->len += n; }
-
-static void dstr_puts(struct dstr *d, const char *p)
-{
- size_t n = strlen(p);
-
- dstr_ensure(d, n + 1);
- memcpy(d->p + d->len, p, n + 1);
- d->len += n;
-}
-
-static void dstr_putc(struct dstr *d, int ch)
- { dstr_ensure(d, 1); d->p[d->len++] = ch; }
-
-static void dstr_putz(struct dstr *d)
- { dstr_ensure(d, 1); d->p[d->len] = 0; }
-
-static int dstr_readline(struct dstr *d, FILE *fp)
-{
- size_t n;
- int any = 0;
-
- for (;;) {
- dstr_ensure(d, 2);
- if (!fgets(d->p + d->len, d->sz - d->len, fp)) break;
- n = strlen(d->p + d->len); assert(n > 0); any = 1;
- d->len += n;
- if (d->p[d->len - 1] == '\n') { d->p[--d->len] = 0; break; }
- }
-
- if (!any) return (-1);
- else return (0);
-}
-/*----- Dynamic vectors of strings ----------------------------------------*/
-
-struct argv {
- const char **v;
- size_t o, n, sz;
-};
-#define ARGV_INIT { 0, 0, 0, 0 }
-
-/*
-static void argv_init(struct argv *av)
- { av->v = 0; av->o = av->n = av->sz = 0; }
-*/
-
-/*
-static void argv_reset(struct argv *av) { av->o = av->n = 0; }
-*/
-
-static void argv_ensure(struct argv *av, size_t n)
-{
- size_t need = av->n + av->o + n, newsz;
-
- if (need <= av->sz) return;
- newsz = av->sz ? 2*av->sz : 8;
- while (newsz < need) newsz *= 2;
- av->v = xrealloc(av->v, newsz*sizeof(const char *)); av->sz = newsz;
-}
-
-static void argv_ensure_offset(struct argv *av, size_t n)
-{
- size_t newoff;
-
- /* Stupid version. We won't, in practice, be prepending lots of stuff, so
- * avoid the extra bookkeeping involved in trying to make a double-ended
- * extendable array asymptotically efficient.
- */
- if (av->o >= n) return;
- newoff = 16;
- while (newoff < n) newoff *= 2;
- argv_ensure(av, newoff - av->o);
- memmove(av->v + newoff, av->v + av->o, av->n*sizeof(const char *));
- av->o = newoff;
-}
-
-static void argv_release(struct argv *av) { free(av->v); }
-
-static void argv_append(struct argv *av, const char *p)
- { argv_ensure(av, 1); av->v[av->n++ + av->o] = p; }
-
-static void argv_appendz(struct argv *av)
- { argv_ensure(av, 1); av->v[av->n + av->o] = 0; }
-
-static void argv_appendn(struct argv *av, const char *const *v, size_t n)
-{
- argv_ensure(av, n);
- memcpy(av->v + av->n + av->o, v, n*sizeof(const char *));
- av->n += n;
-}
-
-/*
-static void argv_appendav(struct argv *av, const struct argv *bv)
- { argv_appendn(av, bv->v + bv->o, bv->n); }
-*/
-
-/*
-static void argv_appendv(struct argv *av, va_list ap)
-{
- const char *p;
-
- for (;;)
- { p = va_arg(ap, const char *); if (!p) break; argv_append(av, p); }
-}
-*/
-
-/*
-static EXECL_LIKE(0) void argv_appendl(struct argv *av, ...)
- { va_list ap; va_start(ap, av); argv_appendv(av, ap); va_end(ap); }
-*/
-
-static void argv_prepend(struct argv *av, const char *p)
- { argv_ensure_offset(av, 1); av->v[--av->o] = p; av->n++; }
-
-/*
-static void argv_prependn(struct argv *av, const char *const *v, size_t n)
-{
- argv_ensure_offset(av, 1);
- av->o -= n; av->n += n;
- memcpy(av->v + av->o, v, n*sizeof(const char *));
-}
-*/
-
-/*
-static void argv_prependav(struct argv *av, const struct argv *bv)
- { argv_prependn(av, bv->v + bv->o, bv->n); }
-*/
-
-static void argv_prependv(struct argv *av, va_list ap)
-{
- const char *p, **v;
- size_t n = 0;
-
- for (;;) {
- p = va_arg(ap, const char *); if (!p) break;
- argv_prepend(av, p); n++;
- }
- v = av->v + av->o;
- while (n >= 2) {
- p = v[0]; v[0] = v[n - 1]; v[n - 1] = p;
- v++; n -= 2;
- }
-}
-
-static EXECL_LIKE(0) void argv_prependl(struct argv *av, ...)
- { va_list ap; va_start(ap, av); argv_prependv(av, ap); va_end(ap); }
-
-/*----- Lisp system table (redux) -----------------------------------------*/