OSDN Git Service

87eebea364d8c5ad73fbbb17a7168fbd561198a6
[mingw/mingw-org-wsl.git] / mingwrt / mingwex / strtok_r.c
1 /*
2  * strtok_r.c
3  *
4  * Implementation of "re-entrant" version of ISO-C strtok() function.
5  *
6  * $Id$
7  *
8  * Written by Keith Marshall <keithmarshall@users.sourceforge.net>
9  * Copyright (C) 2017, MinGW.org Project.
10  *
11  *
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:
18  *
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
21  * Software.
22  *
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.
30  *
31  */
32 #include <string.h>
33
34 char *strtok_r
35 (char *__restrict__ s, const char *__restrict__ sep, char **__restrict__ state)
36 {
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
42    * subsequent tokens.
43    */
44   if( s == NULL )
45     /* Non-initialization call; retrieve previously saved state.
46      */
47     s = *state;
48
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...
51    */
52   if( *(s += strspn (s, sep)) == '\0' )
53   {
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.
57      */
58     *state = s;
59     return NULL;
60   }
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"...
64    */
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.
69      */
70     *(*state)++ = '\0';
71
72   return s;
73 }
74
75 /* $RCSfile$: end of file */