xref: /reactos/sdk/lib/ucrt/mbstring/mbsspn.cpp (revision b09b5584)
1 /***
2 *mbsspn.c - Search for init substring of chars from control string (MBCS).
3 *
4 *       Copyright (c) Microsoft Corporation.  All rights reserved.
5 *
6 *Purpose:
7 *       Search for init substring of chars from control string (MBCS).
8 *
9 *******************************************************************************/
10 #ifndef _MBCS
11     #error This file should only be compiled with _MBCS defined
12 #endif
13 
14 #include <corecrt_internal.h>
15 #include <corecrt_internal_mbstring.h>
16 #include <locale.h>
17 #include <stddef.h>
18 #include <string.h>
19 
20 /***
21 *ifndef _RETURN_PTR
22 * _mbsspn - Find first string char not in charset (MBCS)
23 *else
24 * _mbsspnp - Find first string char not in charset, return pointer (MBCS)
25 *endif
26 *
27 *Purpose:
28 *       Returns maximum leading segment of string consisting solely
29 *       of characters from charset.  Handles MBCS characters correctly.
30 *
31 *Entry:
32 *       unsigned char *string = string to search in
33 *       unsigned char *charset = set of characters to scan over
34 *
35 *Exit:
36 *
37 *ifndef _RETURN_PTR
38 *       Returns index of first char in string not in control.
39 *       Returns 0, if string begins with a character not in charset.
40 *else
41 *       Returns pointer to first character not in charset.
42 *       Returns nullptr if string consists entirely of characters from charset.
43 *endif
44 *
45 *Exceptions:
46 *       Input parameters are validated. Refer to the validation section of the function.
47 *
48 *******************************************************************************/
49 
50 #ifndef _RETURN_PTR
51 extern "C" size_t __cdecl _mbsspn_l
52 #else  /* _RETURN_PTR */
53 extern "C" unsigned char * __cdecl _mbsspnp_l
54 #endif  /* _RETURN_PTR */
55         (
56         const unsigned char *string,
57         const unsigned char *charset,
58         _locale_t plocinfo
59         )
60 {
61         unsigned char *p, *q;
62         _LocaleUpdate _loc_update(plocinfo);
63 
64         if (_loc_update.GetLocaleT()->mbcinfo->ismbcodepage == 0)
65 #ifndef _RETURN_PTR
66             return strspn((const char *)string, (const char *)charset);
67 #else  /* _RETURN_PTR */
68         {
69             size_t retval;
70             retval = strspn((const char *)string, (const char *)charset);
71             return (unsigned char *)(*(string + retval) ? string + retval : nullptr);
72         }
73 #endif  /* _RETURN_PTR */
74 
75         /* validation section */
76 #ifndef _RETURN_PTR
77         _VALIDATE_RETURN(string != nullptr, EINVAL, 0);
78         _VALIDATE_RETURN(charset != nullptr, EINVAL, 0);
79 #else  /* _RETURN_PTR */
80         _VALIDATE_RETURN(string != nullptr, EINVAL, nullptr);
81         _VALIDATE_RETURN(charset != nullptr, EINVAL, nullptr);
82 #endif  /* _RETURN_PTR */
83 
84         /* loop through the string to be inspected */
85         for (q = (unsigned char *)string; *q; q++) {
86 
87             /* loop through the charset */
88             for (p = (unsigned char *)charset; *p; p++) {
89                 if ( _ismbblead_l(*p, _loc_update.GetLocaleT()) ) {
90                     if (((*p == *q) && (p[1] == q[1])) || p[1] == '\0')
91                         break;
92                     p++;
93                 }
94                 else
95                     if (*p == *q)
96                         break;
97             }
98 
99             if (*p == '\0')         /* end of charset? */
100                 break;              /* yes, no match on this char */
101 
102             if ( _ismbblead_l(*q, _loc_update.GetLocaleT()) )
103                 if (*++q == '\0')
104                     break;
105         }
106 
107 #ifndef _RETURN_PTR
108         return((size_t) (q - string));          /* index */
109 #else  /* _RETURN_PTR */
110         return((*q) ? q : nullptr);        /* pointer */
111 #endif  /* _RETURN_PTR */
112 
113 }
114 
115 #ifndef _RETURN_PTR
116 extern "C" size_t (__cdecl _mbsspn)
117 #else  /* _RETURN_PTR */
118 extern "C" unsigned char * (__cdecl _mbsspnp)
119 #endif  /* _RETURN_PTR */
120         (
121         const unsigned char *string,
122         const unsigned char *charset
123         )
124 {
125 #ifndef _RETURN_PTR
126         return _mbsspn_l(string, charset, nullptr);
127 #else  /* _RETURN_PTR */
128         return _mbsspnp_l(string, charset, nullptr);
129 #endif  /* _RETURN_PTR */
130 }
131