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