1 /*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "securec.h"
17
SecFindBegin(char * strToken,const char * strDelimit)18 static char *SecFindBegin(char *strToken, const char *strDelimit)
19 {
20 /* Find beginning of token (skip over leading delimiters). Note that
21 * there is no token if this loop sets string to point to the terminal null.
22 */
23 char *token = strToken;
24 while (*token != 0) {
25 const char *ctl = strDelimit;
26 while (*ctl != 0 && *ctl != *token) {
27 ++ctl;
28 }
29
30 if (*ctl == 0) { /* don't find any delimiter in string header, break the loop */
31 break;
32 }
33 ++token;
34 }
35 return token;
36 }
37
SecFindRest(char * strToken,const char * strDelimit)38 static char *SecFindRest(char *strToken, const char *strDelimit)
39 {
40
41 /* Find the rest of the token. If it is not the end of the string,
42 * put a null there.
43 */
44 char *token = strToken;
45 while (*token != 0) {
46 const char *ctl = strDelimit;
47 while (*ctl != 0 && *ctl != *token) {
48 ++ctl;
49 }
50 if (*ctl != 0) { /* find a delimiter */
51 *token++ = 0; /* set string termintor */
52 break;
53 }
54 ++token;
55 }
56 return token;
57 }
58
59 /*******************************************************************************
60 * <FUNCTION DESCRIPTION>
61 * The strtok_s function parses a string into a sequence of tokens,
62 * On the first call to strtok_s the string to be parsed should be specified in strToken.
63 * In each subsequent call that should parse the same string, strToken should be NULL
64 *
65 * <INPUT PARAMETERS>
66 * strToken String containing token or tokens.
67 * strDelimit Set of delimiter characters.
68 * context Used to store position information between calls
69 * to strtok_s
70 *
71 * <OUTPUT PARAMETERS>
72 * context is updated
73 * <RETURN VALUE>
74 * Returns a pointer to the next token found in strToken.
75 * They return NULL when no more tokens are found.
76 * Each call modifies strToken by substituting a NULL character for the first
77 * delimiter that occurs after the returned token.
78 *
79 * return value condition
80 * NULL context is NULL, strDelimit is NULL, strToken is NULL
81 * and (*context) is NULL, or no token is found.
82 *******************************************************************************
83 */
strtok_s(char * strToken,const char * strDelimit,char ** context)84 char *strtok_s(char *strToken, const char *strDelimit, char **context)
85 {
86 char *orgToken = strToken;
87 /* validate delimiter and string context */
88 if (context == NULL || strDelimit == NULL) {
89 return NULL;
90 }
91
92 /* valid input string and string pointer from where to search */
93 if (orgToken == NULL && (*context) == NULL) {
94 return NULL;
95 }
96
97 /* If string is null, continue searching from previous string position stored in context */
98 if (orgToken == NULL) {
99 orgToken = *context;
100 }
101
102 orgToken = SecFindBegin(orgToken, strDelimit);
103
104 {
105 char *token = orgToken; /* point to updated position */
106
107 orgToken = SecFindRest(orgToken, strDelimit);
108
109 /* record string position for next search in the context */
110 *context = orgToken;
111
112 /* Determine if a token has been found. */
113 if (token == orgToken) {
114 token = NULL;
115 }
116 return token;
117 }
118 }
119
120
121