xref: /reactos/sdk/lib/ucrt/mbstring/mbstok_s.cpp (revision b09b5584)
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 
17 unsigned 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 **)
148