4 * Implementation of "re-entrant" version of ISO-C strtok() function.
8 * Written by Keith Marshall <keithmarshall@users.sourceforge.net>
9 * Copyright (C) 2017, MinGW.org Project.
12 * Permission is hereby granted, free of charge, to any person obtaining a
13 * copy of this software and associated documentation files (the "Software"),
14 * to deal in the Software without restriction, including without limitation
15 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
16 * and/or sell copies of the Software, and to permit persons to whom the
17 * Software is furnished to do so, subject to the following conditions:
19 * The above copyright notice and this permission notice (including the next
20 * paragraph) shall be included in all copies or substantial portions of the
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29 * DEALINGS IN THE SOFTWARE.
35 (char *__restrict__ s, const char *__restrict__ sep, char **__restrict__ state)
37 /* "Re-entrant" version of ISO-C strtok() function; maintains state
38 * via caller provided pointer variable, to avoid interference between
39 * concurrent invocations on distinct source strings. Requires initial
40 * call with non-NULL "s", to retrieve the first token and initialize
41 * "state", followed by repeated calls with "s" == NULL, to retrieve
45 /* Non-initialization call; retrieve previously saved state.
49 /* Step over any leading separator characters, at the beginning of "s";
50 * check that this didn't take us all the way to the terminating NUL...
52 if( *(s += strspn (s, sep)) == '\0' )
54 /* ...or if it did, initialize/reset "state", to indicate that there
55 * are no (more) tokens to retrieve; return NULL token, to indicate
56 * that there are none available.
61 /* Locate the first separator charactor, if any, following the current
62 * token; reset "state" to mark its position, then, ensuring that we
63 * never advance beyond the terminal NUL of "s"...
65 if( *(*state = s + strcspn (s, sep)) != '\0' )
66 /* ...when an actual separator has been identified, replace it with
67 * NUL, to terminate the token, and advance "state" to the point at
68 * which scanning for any potential "next" token should resume.
75 /* $RCSfile$: end of file */