Factor trim format function out
[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 <sysexits.h>
11 #include <h/mh.h>
12 #include <h/utils.h>
13
14 /* allocate this number of pointers at a time */
15 #define NUMBROKEN 256
16
17 static char **broken = NULL;    /* array of substring start addresses */
18 static int len = 0;             /* current size of "broken"           */
19
20
21 /*
22 ** returns pointer to static memory
23 */
24 char **
25 brkstring(char *str, char *brksep, char *brkterm)
26 {
27         int i;
28         char c, *s;
29
30         /* allocate initial space for pointers on first call */
31         if (!broken) {
32                 len = NUMBROKEN;
33                 broken = mh_xcalloc(len, sizeof(*broken));
34         }
35
36         /*
37         ** scan string, replacing separators with zeroes
38         ** and enter start addresses in "broken".
39         */
40         s = str;
41         for (i = 0;; i++) {
42                 /* enlarge pointer array, if necessary */
43                 if (i >= len) {
44                         len += NUMBROKEN;
45                         broken = mh_xrealloc(broken, len * sizeof(*broken));
46                 }
47
48                 /* handle separators */
49                 while ((c=*s) && brksep && strchr(brksep, c)) {
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 || (brkterm && 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)) {
66                         if (brksep && strchr(brksep, c)) {
67                                 break;
68                         }
69                         if (brkterm && strchr(brkterm, c)) {
70                                 break;
71                         }
72                 }
73         }
74         adios(EX_SOFTWARE, "brkstring()", "reached unreachable point");
75 }