189400Smike/*-
241762Swes * Copyright (c) 1998 Softweyr LLC.  All rights reserved.
341762Swes *
441762Swes * strtok_r, from Berkeley strtok
541762Swes * Oct 13, 1998 by Wes Peters <wes@softweyr.com>
641762Swes *
71573Srgrimes * Copyright (c) 1988, 1993
81573Srgrimes *	The Regents of the University of California.  All rights reserved.
91573Srgrimes *
101573Srgrimes * Redistribution and use in source and binary forms, with or without
111573Srgrimes * modification, are permitted provided that the following conditions
121573Srgrimes * are met:
131573Srgrimes * 1. Redistributions of source code must retain the above copyright
1441762Swes *    notices, this list of conditions and the following disclaimer.
151573Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
1641762Swes *    notices, this list of conditions and the following disclaimer in the
171573Srgrimes *    documentation and/or other materials provided with the distribution.
18251069Semaste * 3. Neither the name of the University nor the names of its contributors
191573Srgrimes *    may be used to endorse or promote products derived from this software
201573Srgrimes *    without specific prior written permission.
211573Srgrimes *
2241762Swes * THIS SOFTWARE IS PROVIDED BY SOFTWEYR LLC, THE REGENTS AND CONTRIBUTORS
2341762Swes * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2441762Swes * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
2541762Swes * PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL SOFTWEYR LLC, THE
2641762Swes * REGENTS, OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2741762Swes * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
2841762Swes * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
2941762Swes * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
3041762Swes * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
3141762Swes * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
3241762Swes * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
331573Srgrimes */
341573Srgrimes
3589400Smike#if defined(LIBC_SCCS) && !defined(lint)
3689400Smikestatic char sccsid[] = "@(#)strtok.c	8.1 (Berkeley) 6/4/93";
3789400Smike#endif /* LIBC_SCCS and not lint */
3892986Sobrien#include <sys/cdefs.h>
3992986Sobrien__FBSDID("$FreeBSD$");
4089400Smike
411573Srgrimes#include <stddef.h>
4289387Smike#ifdef DEBUG_STRTOK
4389387Smike#include <stdio.h>
4489387Smike#endif
451573Srgrimes#include <string.h>
461573Srgrimes
47103057Stjrchar	*__strtok_r(char *, const char *, char **);
48103057Stjr
49103057Stjr__weak_reference(__strtok_r, strtok_r);
50103057Stjr
511573Srgrimeschar *
52103057Stjr__strtok_r(char *s, const char *delim, char **last)
531573Srgrimes{
5489400Smike	char *spanp, *tok;
5589385Smike	int c, sc;
561573Srgrimes
5789385Smike	if (s == NULL && (s = *last) == NULL)
5889385Smike		return (NULL);
591573Srgrimes
6089385Smike	/*
6189385Smike	 * Skip (span) leading delimiters (s += strspn(s, delim), sort of).
6289385Smike	 */
6341762Swescont:
6489385Smike	c = *s++;
6589400Smike	for (spanp = (char *)delim; (sc = *spanp++) != 0;) {
6689385Smike		if (c == sc)
6789385Smike			goto cont;
6889400Smike	}
6989385Smike
7089385Smike	if (c == 0) {		/* no non-delimiter characters */
7189385Smike		*last = NULL;
7289385Smike		return (NULL);
7341762Swes	}
7489385Smike	tok = s - 1;
751573Srgrimes
7689385Smike	/*
7789385Smike	 * Scan token (scan for delimiters: s += strcspn(s, delim), sort of).
7889385Smike	 * Note that delim must have one NUL; we stop if we see that, too.
7989385Smike	 */
8089385Smike	for (;;) {
8189385Smike		c = *s++;
8289385Smike		spanp = (char *)delim;
8389385Smike		do {
8489385Smike			if ((sc = *spanp++) == c) {
8589385Smike				if (c == 0)
8689385Smike					s = NULL;
8789400Smike				else
8889400Smike					s[-1] = '\0';
8989385Smike				*last = s;
9089385Smike				return (tok);
9189385Smike			}
9289385Smike		} while (sc != 0);
931573Srgrimes	}
9489385Smike	/* NOTREACHED */
9541762Swes}
961573Srgrimes
9741762Sweschar *
9841762Swesstrtok(char *s, const char *delim)
9941762Swes{
10089385Smike	static char *last;
10141762Swes
102103057Stjr	return (__strtok_r(s, delim, &last));
10341762Swes}
10441762Swes
10589385Smike#ifdef DEBUG_STRTOK
10641762Swes/*
10741762Swes * Test the tokenizer.
10841762Swes */
10941762Swesint
11089385Smikemain(void)
11141762Swes{
11289387Smike	char blah[80], test[80];
11389387Smike	char *brkb, *brkt, *phrase, *sep, *word;
11441762Swes
11589387Smike	sep = "\\/:;=-";
11689387Smike	phrase = "foo";
11789387Smike
11889385Smike	printf("String tokenizer test:\n");
11989385Smike	strcpy(test, "This;is.a:test:of=the/string\\tokenizer-function.");
12089385Smike	for (word = strtok(test, sep); word; word = strtok(NULL, sep))
12189385Smike		printf("Next word is \"%s\".\n", word);
12289385Smike	strcpy(test, "This;is.a:test:of=the/string\\tokenizer-function.");
12341762Swes
12489385Smike	for (word = strtok_r(test, sep, &brkt); word;
12589387Smike	    word = strtok_r(NULL, sep, &brkt)) {
12689385Smike		strcpy(blah, "blah:blat:blab:blag");
12741762Swes
12889385Smike		for (phrase = strtok_r(blah, sep, &brkb); phrase;
12989387Smike		    phrase = strtok_r(NULL, sep, &brkb))
13089385Smike			printf("So far we're at %s:%s\n", word, phrase);
1311573Srgrimes	}
1321573Srgrimes
13389385Smike	return (0);
1341573Srgrimes}
13541762Swes
13641762Swes#endif /* DEBUG_STRTOK */
137