1 | // Licensed to the .NET Foundation under one or more agreements. |
2 | // The .NET Foundation licenses this file to you under the MIT license. |
3 | // See the LICENSE file in the project root for more information. |
4 | |
5 | /*** |
6 | *tcstok_s.inl - general implementation of _tcstok_s |
7 | * |
8 | |
9 | * |
10 | *Purpose: |
11 | * This file contains the general algorithm for strtok_s and its variants. |
12 | * |
13 | ****/ |
14 | |
15 | _FUNC_PROLOGUE |
16 | _CHAR * __cdecl _FUNC_NAME(_CHAR *_String, const _CHAR *_Control, _CHAR **_Context) |
17 | { |
18 | _CHAR *token; |
19 | const _CHAR *ctl; |
20 | |
21 | /* validation section */ |
22 | _VALIDATE_POINTER_ERROR_RETURN(_Context, EINVAL, NULL); |
23 | _VALIDATE_POINTER_ERROR_RETURN(_Control, EINVAL, NULL); |
24 | _VALIDATE_CONDITION_ERROR_RETURN(_String != NULL || *_Context != NULL, EINVAL, NULL); |
25 | |
26 | /* If string==NULL, continue with previous string */ |
27 | if (!_String) |
28 | { |
29 | _String = *_Context; |
30 | } |
31 | |
32 | /* Find beginning of token (skip over leading delimiters). Note that |
33 | * there is no token iff this loop sets string to point to the terminal null. */ |
34 | for ( ; *_String != 0 ; _String++) |
35 | { |
36 | for (ctl = _Control; *ctl != 0 && *ctl != *_String; ctl++) |
37 | ; |
38 | if (*ctl == 0) |
39 | { |
40 | break; |
41 | } |
42 | } |
43 | |
44 | token = _String; |
45 | |
46 | /* Find the end of the token. If it is not the end of the string, |
47 | * put a null there. */ |
48 | for ( ; *_String != 0 ; _String++) |
49 | { |
50 | for (ctl = _Control; *ctl != 0 && *ctl != *_String; ctl++) |
51 | ; |
52 | if (*ctl != 0) |
53 | { |
54 | *_String++ = 0; |
55 | break; |
56 | } |
57 | } |
58 | |
59 | /* Update the context */ |
60 | *_Context = _String; |
61 | |
62 | /* Determine if a token has been found. */ |
63 | if (token == _String) |
64 | { |
65 | return NULL; |
66 | } |
67 | else |
68 | { |
69 | return token; |
70 | } |
71 | } |
72 | |