/*
** brkstring.c -- (destructively) split a string into
**             -- an array of substrings
**
** This code is Copyright (c) 2002, by the authors of nmh.  See the
** COPYRIGHT file in the root directory of the nmh distribution for
** complete copyright information.
*/

#include <sysexits.h>
#include <h/mh.h>
#include <h/utils.h>

/* allocate this number of pointers at a time */
#define NUMBROKEN 256

static char **broken = NULL;    /* array of substring start addresses */
static int len = 0;             /* current size of "broken"           */


/*
** returns pointer to static memory
*/
char **
brkstring(char *str, char *brksep, char *brkterm)
{
	int i;
	char c, *s;

	/* allocate initial space for pointers on first call */
	if (!broken) {
		len = NUMBROKEN;
		broken = mh_xcalloc(len, sizeof(*broken));
	}

	/*
	** scan string, replacing separators with zeroes
	** and enter start addresses in "broken".
	*/
	s = str;
	for (i = 0;; i++) {
		/* enlarge pointer array, if necessary */
		if (i >= len) {
			len += NUMBROKEN;
			broken = mh_xrealloc(broken, len * sizeof(*broken));
		}

		/* handle separators */
		while ((c=*s) && brksep && strchr(brksep, c)) {
			*s++ = '\0';
		}

		/*
		** we are either at the end of the string, or the
		** terminator found has been found, so finish up.
		*/
		if (!c || (brkterm && strchr(brkterm, c))) {
			*s = '\0';
			broken[i] = NULL;
			return broken;
		}

		/* set next start addr and walk over word */
		broken[i] = s;
		while ((c = *++s)) {
			if (brksep && strchr(brksep, c)) {
				break;
			}
			if (brkterm && strchr(brkterm, c)) {
				break;
			}
		}
	}
	adios(EX_SOFTWARE, "brkstring()", "reached unreachable point");
}
