sbr/brkstring.c: replaced static brkany() with call to strchr(); plus cleanups
[mmh] / sbr / brkstring.c
1 /*
2 ** brkstring.c -- (destructively) split a string into
3 **             -- an array of substrings
4 **
5 ** This code is Copyright (c) 2002, by the authors of nmh.  See the
6 ** COPYRIGHT file in the root directory of the nmh distribution for
7 ** complete copyright information.
8 */
9
10 #include <h/mh.h>
11 #include <h/utils.h>
12
13 /* allocate this number of pointers at a time */
14 #define NUMBROKEN 256
15
16 static char **broken = NULL;    /* array of substring start addresses */
17 static int len = 0;             /* current size of "broken"           */
18
19
20 /*
21 ** returns pointer to static memory
22 */
23 char **
24 brkstring(char *str, char *brksep, char *brkterm)
25 {
26         int i;
27         char c, *s;
28
29         /* allocate initial space for pointers on first call */
30         if (!broken) {
31                 len = NUMBROKEN;
32                 broken = (char **)mh_xmalloc((size_t)(len * sizeof(*broken)));
33         }
34
35         /*
36         ** scan string, replacing separators with zeroes
37         ** and enter start addresses in "broken".
38         */
39         s = str;
40         for (i = 0;; i++) {
41                 /* enlarge pointer array, if necessary */
42                 if (i >= len) {
43                         len += NUMBROKEN;
44                         broken = mh_xrealloc(broken,
45                                         (size_t)(len * sizeof(*broken)));
46                 }
47
48                 /* handle separators */
49                 while (strchr(brksep, c = *s)) {
50                         *s++ = '\0';
51                 }
52
53                 /*
54                 ** we are either at the end of the string, or the
55                 ** terminator found has been found, so finish up.
56                 */
57                 if (!c || strchr(brkterm, c)) {
58                         *s = '\0';
59                         broken[i] = NULL;
60                         return broken;
61                 }
62
63                 /* set next start addr and walk over word */
64                 broken[i] = s;
65                 while ((c=*++s) && !strchr(brksep, c) && !strchr(brkterm, c)) {
66                         continue;
67                 }
68         }
69         adios("brkstring()", "reached unreachable point");
70 }