Blame


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