xref: /freebsd/lib/libc/string/strtok.c (revision 3fb3b97c)
14681597dSMike Barcroft /*-
2b1e12513SWes Peters  * Copyright (c) 1998 Softweyr LLC.  All rights reserved.
3b1e12513SWes Peters  *
4b1e12513SWes Peters  * strtok_r, from Berkeley strtok
5b1e12513SWes Peters  * Oct 13, 1998 by Wes Peters <wes@softweyr.com>
6b1e12513SWes Peters  *
758f0484fSRodney W. Grimes  * Copyright (c) 1988, 1993
858f0484fSRodney W. Grimes  *	The Regents of the University of California.  All rights reserved.
958f0484fSRodney W. Grimes  *
1058f0484fSRodney W. Grimes  * Redistribution and use in source and binary forms, with or without
1158f0484fSRodney W. Grimes  * modification, are permitted provided that the following conditions
1258f0484fSRodney W. Grimes  * are met:
1358f0484fSRodney W. Grimes  * 1. Redistributions of source code must retain the above copyright
14b1e12513SWes Peters  *    notices, this list of conditions and the following disclaimer.
1558f0484fSRodney W. Grimes  * 2. Redistributions in binary form must reproduce the above copyright
16b1e12513SWes Peters  *    notices, this list of conditions and the following disclaimer in the
1758f0484fSRodney W. Grimes  *    documentation and/or other materials provided with the distribution.
183fb3b97cSEd Maste  * 3. Neither the name of the University nor the names of its contributors
1958f0484fSRodney W. Grimes  *    may be used to endorse or promote products derived from this software
2058f0484fSRodney W. Grimes  *    without specific prior written permission.
2158f0484fSRodney W. Grimes  *
22b1e12513SWes Peters  * THIS SOFTWARE IS PROVIDED BY SOFTWEYR LLC, THE REGENTS AND CONTRIBUTORS
23b1e12513SWes Peters  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24b1e12513SWes Peters  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
25b1e12513SWes Peters  * PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL SOFTWEYR LLC, THE
26b1e12513SWes Peters  * REGENTS, OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27b1e12513SWes Peters  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
28b1e12513SWes Peters  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29b1e12513SWes Peters  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30b1e12513SWes Peters  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31b1e12513SWes Peters  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32b1e12513SWes Peters  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3358f0484fSRodney W. Grimes  */
3458f0484fSRodney W. Grimes 
354681597dSMike Barcroft #if defined(LIBC_SCCS) && !defined(lint)
364681597dSMike Barcroft static char sccsid[] = "@(#)strtok.c	8.1 (Berkeley) 6/4/93";
374681597dSMike Barcroft #endif /* LIBC_SCCS and not lint */
38333fc21eSDavid E. O'Brien #include <sys/cdefs.h>
39333fc21eSDavid E. O'Brien __FBSDID("$FreeBSD$");
404681597dSMike Barcroft 
4158f0484fSRodney W. Grimes #include <stddef.h>
421936b2c8SMike Barcroft #ifdef DEBUG_STRTOK
431936b2c8SMike Barcroft #include <stdio.h>
441936b2c8SMike Barcroft #endif
4558f0484fSRodney W. Grimes #include <string.h>
4658f0484fSRodney W. Grimes 
4791bd11adSTim J. Robbins char	*__strtok_r(char *, const char *, char **);
4891bd11adSTim J. Robbins 
4991bd11adSTim J. Robbins __weak_reference(__strtok_r, strtok_r);
5091bd11adSTim J. Robbins 
5158f0484fSRodney W. Grimes char *
5291bd11adSTim J. Robbins __strtok_r(char *s, const char *delim, char **last)
5358f0484fSRodney W. Grimes {
544681597dSMike Barcroft 	char *spanp, *tok;
55b1e12513SWes Peters 	int c, sc;
5658f0484fSRodney W. Grimes 
57b1e12513SWes Peters 	if (s == NULL && (s = *last) == NULL)
58f601b5baSMike Barcroft 		return (NULL);
5958f0484fSRodney W. Grimes 
6058f0484fSRodney W. Grimes 	/*
6158f0484fSRodney W. Grimes 	 * Skip (span) leading delimiters (s += strspn(s, delim), sort of).
6258f0484fSRodney W. Grimes 	 */
6358f0484fSRodney W. Grimes cont:
6458f0484fSRodney W. Grimes 	c = *s++;
654681597dSMike Barcroft 	for (spanp = (char *)delim; (sc = *spanp++) != 0;) {
6658f0484fSRodney W. Grimes 		if (c == sc)
6758f0484fSRodney W. Grimes 			goto cont;
684681597dSMike Barcroft 	}
6958f0484fSRodney W. Grimes 
70f601b5baSMike Barcroft 	if (c == 0) {		/* no non-delimiter characters */
71b1e12513SWes Peters 		*last = NULL;
72f601b5baSMike Barcroft 		return (NULL);
7358f0484fSRodney W. Grimes 	}
7458f0484fSRodney W. Grimes 	tok = s - 1;
7558f0484fSRodney W. Grimes 
7658f0484fSRodney W. Grimes 	/*
7758f0484fSRodney W. Grimes 	 * Scan token (scan for delimiters: s += strcspn(s, delim), sort of).
7858f0484fSRodney W. Grimes 	 * Note that delim must have one NUL; we stop if we see that, too.
7958f0484fSRodney W. Grimes 	 */
80f601b5baSMike Barcroft 	for (;;) {
8158f0484fSRodney W. Grimes 		c = *s++;
8258f0484fSRodney W. Grimes 		spanp = (char *)delim;
83f601b5baSMike Barcroft 		do {
84f601b5baSMike Barcroft 			if ((sc = *spanp++) == c) {
8558f0484fSRodney W. Grimes 				if (c == 0)
8658f0484fSRodney W. Grimes 					s = NULL;
874681597dSMike Barcroft 				else
884681597dSMike Barcroft 					s[-1] = '\0';
89b1e12513SWes Peters 				*last = s;
90f601b5baSMike Barcroft 				return (tok);
91b1e12513SWes Peters 			}
92f601b5baSMike Barcroft 		} while (sc != 0);
9358f0484fSRodney W. Grimes 	}
9458f0484fSRodney W. Grimes 	/* NOTREACHED */
9558f0484fSRodney W. Grimes }
96b1e12513SWes Peters 
97b1e12513SWes Peters char *
98b1e12513SWes Peters strtok(char *s, const char *delim)
99b1e12513SWes Peters {
100b1e12513SWes Peters 	static char *last;
101b1e12513SWes Peters 
10291bd11adSTim J. Robbins 	return (__strtok_r(s, delim, &last));
103b1e12513SWes Peters }
104b1e12513SWes Peters 
105f601b5baSMike Barcroft #ifdef DEBUG_STRTOK
106b1e12513SWes Peters /*
107b1e12513SWes Peters  * Test the tokenizer.
108b1e12513SWes Peters  */
109b1e12513SWes Peters int
110f601b5baSMike Barcroft main(void)
111b1e12513SWes Peters {
1121936b2c8SMike Barcroft 	char blah[80], test[80];
1131936b2c8SMike Barcroft 	char *brkb, *brkt, *phrase, *sep, *word;
1141936b2c8SMike Barcroft 
1151936b2c8SMike Barcroft 	sep = "\\/:;=-";
1161936b2c8SMike Barcroft 	phrase = "foo";
117b1e12513SWes Peters 
118b1e12513SWes Peters 	printf("String tokenizer test:\n");
119b1e12513SWes Peters 	strcpy(test, "This;is.a:test:of=the/string\\tokenizer-function.");
120f601b5baSMike Barcroft 	for (word = strtok(test, sep); word; word = strtok(NULL, sep))
121b1e12513SWes Peters 		printf("Next word is \"%s\".\n", word);
122b1e12513SWes Peters 	strcpy(test, "This;is.a:test:of=the/string\\tokenizer-function.");
123b1e12513SWes Peters 
124f601b5baSMike Barcroft 	for (word = strtok_r(test, sep, &brkt); word;
125f601b5baSMike Barcroft 	    word = strtok_r(NULL, sep, &brkt)) {
126b1e12513SWes Peters 		strcpy(blah, "blah:blat:blab:blag");
127b1e12513SWes Peters 
128f601b5baSMike Barcroft 		for (phrase = strtok_r(blah, sep, &brkb); phrase;
129b1e12513SWes Peters 		    phrase = strtok_r(NULL, sep, &brkb))
130b1e12513SWes Peters 			printf("So far we're at %s:%s\n", word, phrase);
131b1e12513SWes Peters 	}
132b1e12513SWes Peters 
133f601b5baSMike Barcroft 	return (0);
134b1e12513SWes Peters }
135b1e12513SWes Peters 
136b1e12513SWes Peters #endif /* DEBUG_STRTOK */
137