Blob


1 /*
2 * Copyright (c) 2022 Omar Polo <op@openbsd.org>
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
17 #include <ctype.h>
18 #include <string.h>
19 #include <stdlib.h>
21 #include "tokenize.h"
23 #ifndef WDELIMS
24 /* everything but a-zA-Z */
25 #define WDELIMS " \t\n!\"#$%&'()*+,-./0123456789:;<=>?@[\\]^_`{|}~"
26 #endif
28 char **
29 tokenize(const char *s)
30 {
31 char *d, *dup, *t, **tok = NULL;
32 void *newtok;
33 size_t cap = 0, len = 0, newcap;
35 if ((dup = strdup(s)) == NULL)
36 return NULL;
37 d = dup;
39 for (t = d; *t; ++t)
40 *t = tolower(*t);
42 while ((t = strsep(&d, WDELIMS)) != NULL) {
43 if (*t == '\0')
44 continue;
46 /* keep the space for a NULL terminator */
47 if (len+1 >= cap) {
48 newcap = cap * 1.5;
49 if (newcap == 0)
50 newcap = 8;
51 newtok = recallocarray(tok, cap, newcap,
52 sizeof(char *));
53 if (newtok == NULL)
54 goto err;
55 tok = newtok;
56 cap = newcap;
57 }
59 if ((tok[len++] = strdup(t)) == NULL)
60 goto err;
61 }
63 free(dup);
64 if (tok == NULL)
65 return calloc(1, sizeof(char *));
66 return tok;
68 err:
69 freetoks(tok);
70 free(dup);
71 return NULL;
72 }
74 void
75 freetoks(char **tok)
76 {
77 char **i;
79 if (tok == NULL)
80 return;
82 for (i = tok; *i != NULL; ++i)
83 free(*i);
84 free(tok);
85 }