Reactos
1/***
2*mbstok_s.c - Break string into tokens (MBCS)
3*
4* Copyright (c) Microsoft Corporation. All rights reserved.
5*
6*Purpose:
7* Break string into tokens (MBCS)
8*
9*******************************************************************************/
10#ifndef _MBCS
11 #error This file should only be compiled with _MBCS defined
12#endif
13
14#include <corecrt_internal_mbstring.h>
15#include <corecrt_internal_securecrt.h>
16
17unsigned char * __cdecl _mbstok_s_l(unsigned char *_String, const unsigned char *_Control, unsigned char **_Context, _LOCALE_ARG_DECL)
18{
19 unsigned char *token;
20 const unsigned char *ctl;
21 int dbc;
22
23 /* validation section */
24 _VALIDATE_POINTER_ERROR_RETURN(_Context, EINVAL, nullptr);
25 _VALIDATE_POINTER_ERROR_RETURN(_Control, EINVAL, nullptr);
26 _VALIDATE_CONDITION_ERROR_RETURN(_String != nullptr || *_Context != nullptr, EINVAL, nullptr);
27
28 _LOCALE_UPDATE;
29 if (_LOCALE_SHORTCUT_TEST)
30 {
31 return (unsigned char*)strtok_s((char *)_String, (const char *)_Control, (char **)_Context);
32 }
33
34 /* If string==nullptr, continue with previous string */
35 if (!_String)
36 {
37 _String = *_Context;
38 }
39
40 /* Find beginning of token (skip over leading delimiters). Note that
41 * there is no token iff this loop sets string to point to the terminal null. */
42 for ( ; *_String != 0; _String++)
43 {
44 for (ctl = _Control; *ctl != 0; ctl++)
45 {
46 if (_ISMBBLEAD(*ctl))
47 {
48 if (ctl[1] == 0)
49 {
50 ctl++;
51 _SET_MBCS_ERROR;
52 break;
53 }
54 if (*ctl == *_String && ctl[1] == _String[1])
55 {
56 break;
57 }
58 ctl++;
59 }
60 else
61 {
62 if (*ctl == *_String)
63 {
64 break;
65 }
66 }
67 }
68 if (*ctl == 0)
69 {
70 break;
71 }
72 if (_ISMBBLEAD(*_String))
73 {
74 _String++;
75 if (*_String == 0)
76 {
77 _SET_MBCS_ERROR;
78 break;
79 }
80 }
81 }
82
83 token = _String;
84
85 /* Find the end of the token. If it is not the end of the string,
86 * put a null there. */
87 for ( ; *_String != 0; _String++)
88 {
89 for (ctl = _Control, dbc = 0; *ctl != 0; ctl++)
90 {
91 if (_ISMBBLEAD(*ctl))
92 {
93 if (ctl[1] == 0)
94 {
95 ctl++;
96 break;
97 }
98 if (ctl[0] == _String[0] && ctl[1] == _String[1])
99 {
100 dbc = 1;
101 break;
102 }
103 ctl++;
104 }
105 else
106 {
107 if (*ctl == *_String)
108 {
109 break;
110 }
111 }
112 }
113 if (*ctl != 0)
114 {
115 *_String++ = 0;
116 if (dbc)
117 {
118 *_String++ = 0;
119 }
120 break;
121 }
122 if (_ISMBBLEAD(_String[0]))
123 {
124 if (_String[1] == 0)
125 {
126 *_String = 0;
127 break;
128 }
129 _String++;
130 }
131 }
132
133 /* Update the context */
134 *_Context = _String;
135
136 /* Determine if a token has been found. */
137 if (token == _String)
138 {
139 return nullptr;
140 }
141 else
142 {
143 return token;
144 }
145}
146
147_REDIRECT_TO_L_VERSION_3(unsigned char *, _mbstok_s, unsigned char *, const unsigned char *, unsigned char **)