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