master xplshn/aruu / cmd / dev / ninqu / strlist.c
 1#include "ninqu.h"
 2#include "wexec.h"
 3
 4#include <ctype.h>
 5#include <stdio.h>
 6#include <string.h>
 7
 8void
 9sl_push(struct StrList *sl, const char *s)
10{
11  GROW(sl->v, sl->n, sl->cap, 8);
12  sl->v[sl->n++] = estrdup(s);
13}
14
15int
16sl_has(struct StrList *sl, const char *s)
17{
18  int i;
19  for (i = 0; i < sl->n; i++)
20    if (strcmp(sl->v[i], s) == 0)
21      return 1;
22  return 0;
23}
24
25void
26sl_split(struct StrList *sl, const char *s)
27{
28  const char *p = s;
29
30  sl->n = 0;
31  while (*p) {
32    const char *start;
33    char        buf[4096];
34    size_t      len;
35
36    while (*p && isspace((unsigned char)*p))
37      p++;
38    if (!*p)
39      break;
40    start = p;
41    while (*p && !isspace((unsigned char)*p))
42      p++;
43    len = (size_t)(p - start);
44    if (len >= sizeof buf)
45      len = sizeof buf - 1;
46    memcpy(buf, start, len);
47    buf[len] = '\0';
48    sl_push(sl, buf);
49  }
50}
51
52char *
53sl_join(struct StrList *sl)
54{
55  size_t cap = 64, len = 0;
56  char  *out = emalloc(cap);
57  int    i;
58
59  out[0] = '\0';
60  for (i = 0; i < sl->n; i++) {
61    size_t addlen = strlen(sl->v[i]) + 1;
62    while (len + addlen + 1 > cap) {
63      cap *= 2;
64      out = erealloc(out, cap);
65    }
66    if (i > 0)
67      out[len++] = ' ';
68    memcpy(out + len, sl->v[i], strlen(sl->v[i]));
69    len += strlen(sl->v[i]);
70    out[len] = '\0';
71  }
72  return out;
73}
74
75const char *
76base_of(const char *path)
77{
78  const char *p = strrchr(path, '/');
79  return p ? p + 1 : path;
80}
81
82/* null-terminate the array so wexecvp stops scanning */
83char **
84sl_argv(struct StrList *sl)
85{
86  char **av = emalloc((size_t)(sl->n + 1) * sizeof *av);
87  int    i;
88  for (i = 0; i < sl->n; i++)
89    av[i] = sl->v[i];
90  av[sl->n] = NULL;
91  return av;
92}
93
94/* noreturn so callers do not guard the dead path after fork */
95void
96child_execvp(char **av)
97{
98  wexecvp_self(av[0], av);
99}