xref: /freebsd/lib/libc/string/strtok.c (revision dc36d6f9)
14681597dSMike Barcroft /*-
28a16b7a1SPedro F. Giffuni  * SPDX-License-Identifier: BSD-3-Clause
38a16b7a1SPedro F. Giffuni  *
4b1e12513SWes Peters  * Copyright (c) 1998 Softweyr LLC.  All rights reserved.
5b1e12513SWes Peters  *
6b1e12513SWes Peters  * strtok_r, from Berkeley strtok
7b1e12513SWes Peters  * Oct 13, 1998 by Wes Peters <wes@softweyr.com>
8b1e12513SWes Peters  *
958f0484fSRodney W. Grimes  * Copyright (c) 1988, 1993
1058f0484fSRodney W. Grimes  *	The Regents of the University of California.  All rights reserved.
1158f0484fSRodney W. Grimes  *
1258f0484fSRodney W. Grimes  * Redistribution and use in source and binary forms, with or without
1358f0484fSRodney W. Grimes  * modification, are permitted provided that the following conditions
1458f0484fSRodney W. Grimes  * are met:
1558f0484fSRodney W. Grimes  * 1. Redistributions of source code must retain the above copyright
16b1e12513SWes Peters  *    notices, this list of conditions and the following disclaimer.
1758f0484fSRodney W. Grimes  * 2. Redistributions in binary form must reproduce the above copyright
18b1e12513SWes Peters  *    notices, this list of conditions and the following disclaimer in the
1958f0484fSRodney W. Grimes  *    documentation and/or other materials provided with the distribution.
203fb3b97cSEd Maste  * 3. Neither the name of the University nor the names of its contributors
2158f0484fSRodney W. Grimes  *    may be used to endorse or promote products derived from this software
2258f0484fSRodney W. Grimes  *    without specific prior written permission.
2358f0484fSRodney W. Grimes  *
24b1e12513SWes Peters  * THIS SOFTWARE IS PROVIDED BY SOFTWEYR LLC, THE REGENTS AND CONTRIBUTORS
25b1e12513SWes Peters  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26b1e12513SWes Peters  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
27b1e12513SWes Peters  * PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL SOFTWEYR LLC, THE
28b1e12513SWes Peters  * REGENTS, OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29b1e12513SWes Peters  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
30b1e12513SWes Peters  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
31b1e12513SWes Peters  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
32b1e12513SWes Peters  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
33b1e12513SWes Peters  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
34b1e12513SWes Peters  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3558f0484fSRodney W. Grimes  */
3658f0484fSRodney W. Grimes 
3758f0484fSRodney W. Grimes #include <stddef.h>
381936b2c8SMike Barcroft #ifdef DEBUG_STRTOK
391936b2c8SMike Barcroft #include <stdio.h>
401936b2c8SMike Barcroft #endif
4158f0484fSRodney W. Grimes #include <string.h>
4258f0484fSRodney W. Grimes 
4391bd11adSTim J. Robbins char	*__strtok_r(char *, const char *, char **);
4491bd11adSTim J. Robbins 
4591bd11adSTim J. Robbins __weak_reference(__strtok_r, strtok_r);
4691bd11adSTim J. Robbins 
4758f0484fSRodney W. Grimes char *
__strtok_r(char * s,const char * delim,char ** last)4891bd11adSTim J. Robbins __strtok_r(char *s, const char *delim, char **last)
4958f0484fSRodney W. Grimes {
504681597dSMike Barcroft 	char *spanp, *tok;
51b1e12513SWes Peters 	int c, sc;
5258f0484fSRodney W. Grimes 
53b1e12513SWes Peters 	if (s == NULL && (s = *last) == NULL)
54f601b5baSMike Barcroft 		return (NULL);
5558f0484fSRodney W. Grimes 
5658f0484fSRodney W. Grimes 	/*
5758f0484fSRodney W. Grimes 	 * Skip (span) leading delimiters (s += strspn(s, delim), sort of).
5858f0484fSRodney W. Grimes 	 */
5958f0484fSRodney W. Grimes cont:
6058f0484fSRodney W. Grimes 	c = *s++;
614681597dSMike Barcroft 	for (spanp = (char *)delim; (sc = *spanp++) != 0;) {
6258f0484fSRodney W. Grimes 		if (c == sc)
6358f0484fSRodney W. Grimes 			goto cont;
644681597dSMike Barcroft 	}
6558f0484fSRodney W. Grimes 
66f601b5baSMike Barcroft 	if (c == 0) {		/* no non-delimiter characters */
67b1e12513SWes Peters 		*last = NULL;
68f601b5baSMike Barcroft 		return (NULL);
6958f0484fSRodney W. Grimes 	}
7058f0484fSRodney W. Grimes 	tok = s - 1;
7158f0484fSRodney W. Grimes 
7258f0484fSRodney W. Grimes 	/*
7358f0484fSRodney W. Grimes 	 * Scan token (scan for delimiters: s += strcspn(s, delim), sort of).
7458f0484fSRodney W. Grimes 	 * Note that delim must have one NUL; we stop if we see that, too.
7558f0484fSRodney W. Grimes 	 */
76f601b5baSMike Barcroft 	for (;;) {
7758f0484fSRodney W. Grimes 		c = *s++;
7858f0484fSRodney W. Grimes 		spanp = (char *)delim;
79f601b5baSMike Barcroft 		do {
80f601b5baSMike Barcroft 			if ((sc = *spanp++) == c) {
8158f0484fSRodney W. Grimes 				if (c == 0)
8258f0484fSRodney W. Grimes 					s = NULL;
834681597dSMike Barcroft 				else
844681597dSMike Barcroft 					s[-1] = '\0';
85b1e12513SWes Peters 				*last = s;
86f601b5baSMike Barcroft 				return (tok);
87b1e12513SWes Peters 			}
88f601b5baSMike Barcroft 		} while (sc != 0);
8958f0484fSRodney W. Grimes 	}
9058f0484fSRodney W. Grimes 	/* NOTREACHED */
9158f0484fSRodney W. Grimes }
92b1e12513SWes Peters 
93b1e12513SWes Peters char *
strtok(char * s,const char * delim)94b1e12513SWes Peters strtok(char *s, const char *delim)
95b1e12513SWes Peters {
96b1e12513SWes Peters 	static char *last;
97b1e12513SWes Peters 
9891bd11adSTim J. Robbins 	return (__strtok_r(s, delim, &last));
99b1e12513SWes Peters }
100b1e12513SWes Peters 
101f601b5baSMike Barcroft #ifdef DEBUG_STRTOK
102b1e12513SWes Peters /*
103b1e12513SWes Peters  * Test the tokenizer.
104b1e12513SWes Peters  */
105b1e12513SWes Peters int
main(void)106f601b5baSMike Barcroft main(void)
107b1e12513SWes Peters {
1081936b2c8SMike Barcroft 	char blah[80], test[80];
1091936b2c8SMike Barcroft 	char *brkb, *brkt, *phrase, *sep, *word;
1101936b2c8SMike Barcroft 
1111936b2c8SMike Barcroft 	sep = "\\/:;=-";
1121936b2c8SMike Barcroft 	phrase = "foo";
113b1e12513SWes Peters 
114b1e12513SWes Peters 	printf("String tokenizer test:\n");
115b1e12513SWes Peters 	strcpy(test, "This;is.a:test:of=the/string\\tokenizer-function.");
116f601b5baSMike Barcroft 	for (word = strtok(test, sep); word; word = strtok(NULL, sep))
117b1e12513SWes Peters 		printf("Next word is \"%s\".\n", word);
118b1e12513SWes Peters 	strcpy(test, "This;is.a:test:of=the/string\\tokenizer-function.");
119b1e12513SWes Peters 
120f601b5baSMike Barcroft 	for (word = strtok_r(test, sep, &brkt); word;
121f601b5baSMike Barcroft 	    word = strtok_r(NULL, sep, &brkt)) {
122b1e12513SWes Peters 		strcpy(blah, "blah:blat:blab:blag");
123b1e12513SWes Peters 
124f601b5baSMike Barcroft 		for (phrase = strtok_r(blah, sep, &brkb); phrase;
125b1e12513SWes Peters 		    phrase = strtok_r(NULL, sep, &brkb))
126b1e12513SWes Peters 			printf("So far we're at %s:%s\n", word, phrase);
127b1e12513SWes Peters 	}
128b1e12513SWes Peters 
129f601b5baSMike Barcroft 	return (0);
130b1e12513SWes Peters }
131b1e12513SWes Peters 
132b1e12513SWes Peters #endif /* DEBUG_STRTOK */
133