715aaf5e2b65a3bc394804861c9354e75c94ff68
[mmh] / sbr / brkstring.c
1
2 /*
3  * brkstring.c -- (destructively) split a string into
4  *             -- an array of substrings
5  *
6  * $Id$
7  */
8
9 #include <h/mh.h>
10
11 /* allocate this number of pointers at a time */
12 #define NUMBROKEN 256
13
14 static char **broken = NULL;    /* array of substring start addresses */
15 static int len = 0;             /* current size of "broken"           */
16
17 /*
18  * static prototypes
19  */
20 static int brkany (char, char *);
21
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         if (!(broken = (char **) malloc ((size_t) (len * sizeof(*broken)))))
33             adios (NULL, "unable to malloc array in brkstring");
34     }
35
36     /*
37      * scan string, replacing separators with zeroes
38      * and enter start addresses in "broken".
39      */
40     s = str;
41
42     for (i = 0;; i++) {
43
44         /* enlarge pointer array, if necessary */
45         if (i >= len) {
46             len += NUMBROKEN;
47             if (!(broken = realloc (broken, (size_t) (len * sizeof(*broken)))))
48                 adios (NULL, "unable to realloc array in brkstring");
49         }
50
51         while (brkany (c = *s, brksep))
52             *s++ = '\0';
53
54         /*
55          * we are either at the end of the string, or the
56          * terminator found has been found, so finish up.
57          */
58         if (!c || brkany (c, brkterm)) {
59             *s = '\0';
60             broken[i] = NULL;
61             return broken;
62         }
63
64         /* set next start addr */
65         broken[i] = s;
66
67         while ((c = *++s) && !brkany (c, brksep) && !brkany (c, brkterm))
68             ;   /* empty body */
69     }
70
71     return broken;      /* NOT REACHED */
72 }
73
74
75 /*
76  * If the character is in the string,
77  * return 1, else return 0.
78  */
79
80 static int
81 brkany (char c, char *str)
82 {
83     char *s;
84
85     if (str) {
86         for (s = str; *s; s++)
87             if (c == *s)
88                 return 1;
89     }
90     return 0;
91 }