Pass int instead of char to iscntrl() and isspace() because that's what they require...
[mmh] / sbr / brkstring.c
1
2 /*
3  * brkstring.c -- (destructively) split a string into
4  *             -- an array of substrings
5  *
6  * This code is Copyright (c) 2002, by the authors of nmh.  See the
7  * COPYRIGHT file in the root directory of the nmh distribution for
8  * complete copyright information.
9  */
10
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  * static prototypes
22  */
23 static int brkany (char, char *);
24
25
26 char **
27 brkstring (char *str, char *brksep, char *brkterm)
28 {
29     int i;
30     char c, *s;
31
32     /* allocate initial space for pointers on first call */
33     if (!broken) {
34         len = NUMBROKEN;
35         broken = (char **) mh_xmalloc ((size_t) (len * sizeof(*broken)));
36     }
37
38     /*
39      * scan string, replacing separators with zeroes
40      * and enter start addresses in "broken".
41      */
42     s = str;
43
44     for (i = 0;; i++) {
45
46         /* enlarge pointer array, if necessary */
47         if (i >= len) {
48             len += NUMBROKEN;
49             broken = mh_xrealloc (broken, (size_t) (len * sizeof(*broken)));
50         }
51
52         while (brkany (c = *s, brksep))
53             *s++ = '\0';
54
55         /*
56          * we are either at the end of the string, or the
57          * terminator found has been found, so finish up.
58          */
59         if (!c || brkany (c, brkterm)) {
60             *s = '\0';
61             broken[i] = NULL;
62             return broken;
63         }
64
65         /* set next start addr */
66         broken[i] = s;
67
68         while ((c = *++s) && !brkany (c, brksep) && !brkany (c, brkterm))
69             ;   /* empty body */
70     }
71
72     return broken;      /* NOT REACHED */
73 }
74
75
76 /*
77  * If the character is in the string,
78  * return 1, else return 0.
79  */
80
81 static int
82 brkany (char c, char *str)
83 {
84     char *s;
85
86     if (str) {
87         for (s = str; *s; s++)
88             if (c == *s)
89                 return 1;
90     }
91     return 0;
92 }