ReactOS 0.4.16-dev-336-gb667d82
string.c
Go to the documentation of this file.
1/*
2 * String manipulation functions
3 *
4 * Copyright 1998 Eric Kohl
5 * 1998 Juergen Schmied <j.schmied@metronet.de>
6 * 2000 Eric Kohl for CodeWeavers
7 * Copyright 2002 Jon Griffiths
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 *
23 */
24
25#include <stdarg.h>
26#include <string.h>
27#include <stdlib.h> /* atoi */
28
29#include "windef.h"
30#include "winbase.h"
31#include "winuser.h"
32#include "winnls.h"
33
34#include "comctl32.h"
35
36
37#include "wine/debug.h"
38
40
41/*************************************************************************
42 * COMCTL32_ChrCmpHelperA
43 *
44 * Internal helper for ChrCmpA/COMCTL32_ChrCmpIA.
45 *
46 * NOTES
47 * Both this function and its Unicode counterpart are very inefficient. To
48 * fix this, CompareString must be completely implemented and optimised
49 * first. Then the core character test can be taken out of that function and
50 * placed here, so that it need never be called at all. Until then, do not
51 * attempt to optimise this code unless you are willing to test that it
52 * still performs correctly.
53 */
55{
56 char str1[3], str2[3];
57
58 str1[0] = LOBYTE(ch1);
59 if (IsDBCSLeadByte(str1[0]))
60 {
61 str1[1] = HIBYTE(ch1);
62 str1[2] = '\0';
63 }
64 else
65 str1[1] = '\0';
66
67 str2[0] = LOBYTE(ch2);
68 if (IsDBCSLeadByte(str2[0]))
69 {
70 str2[1] = HIBYTE(ch2);
71 str2[2] = '\0';
72 }
73 else
74 str2[1] = '\0';
75
76 return CompareStringA(GetThreadLocale(), dwFlags, str1, -1, str2, -1) - CSTR_EQUAL;
77}
78
79/*************************************************************************
80 * COMCTL32_ChrCmpA (internal)
81 *
82 * Internal helper function.
83 */
85{
86 return COMCTL32_ChrCmpHelperA(ch1, ch2, 0);
87}
88
89/*************************************************************************
90 * COMCTL32_ChrCmpIA (internal)
91 *
92 * Compare two characters, ignoring case.
93 *
94 * PARAMS
95 * ch1 [I] First character to compare
96 * ch2 [I] Second character to compare
97 *
98 * RETURNS
99 * FALSE, if the characters are equal.
100 * Non-zero otherwise.
101 */
103{
104 TRACE("(%d,%d)\n", ch1, ch2);
105
106 return COMCTL32_ChrCmpHelperA(ch1, ch2, NORM_IGNORECASE);
107}
108
109/*************************************************************************
110 * COMCTL32_ChrCmpIW
111 *
112 * Internal helper function.
113 */
114static inline BOOL COMCTL32_ChrCmpIW(WCHAR ch1, WCHAR ch2)
115{
116 return CompareStringW(GetThreadLocale(), NORM_IGNORECASE, &ch1, 1, &ch2, 1) - CSTR_EQUAL;
117}
118
119/**************************************************************************
120 * Str_GetPtrA [COMCTL32.233]
121 *
122 * Copies a string into a destination buffer.
123 *
124 * PARAMS
125 * lpSrc [I] Source string
126 * lpDest [O] Destination buffer
127 * nMaxLen [I] Size of buffer in characters
128 *
129 * RETURNS
130 * The number of characters copied.
131 */
132INT WINAPI Str_GetPtrA (LPCSTR lpSrc, LPSTR lpDest, INT nMaxLen)
133{
134 INT len;
135
136 TRACE("(%p %p %d)\n", lpSrc, lpDest, nMaxLen);
137
138 if ((!lpDest || nMaxLen == 0) && lpSrc)
139 return (strlen(lpSrc) + 1);
140
141 if (nMaxLen == 0)
142 return 0;
143
144 if (lpSrc == NULL) {
145 lpDest[0] = '\0';
146 return 0;
147 }
148
149 len = strlen(lpSrc) + 1;
150 if (len >= nMaxLen)
151 len = nMaxLen;
152
153 RtlMoveMemory (lpDest, lpSrc, len - 1);
154 lpDest[len - 1] = '\0';
155
156 return len;
157}
158
159/**************************************************************************
160 * Str_SetPtrA [COMCTL32.234]
161 *
162 * Makes a copy of a string, allocating memory if necessary.
163 *
164 * PARAMS
165 * lppDest [O] Pointer to destination string
166 * lpSrc [I] Source string
167 *
168 * RETURNS
169 * Success: TRUE
170 * Failure: FALSE
171 *
172 * NOTES
173 * Set lpSrc to NULL to free the memory allocated by a previous call
174 * to this function.
175 */
177{
178 TRACE("(%p %p)\n", lppDest, lpSrc);
179
180 if (lpSrc) {
181 LPSTR ptr = ReAlloc (*lppDest, strlen (lpSrc) + 1);
182 if (!ptr)
183 return FALSE;
184 strcpy (ptr, lpSrc);
185 *lppDest = ptr;
186 }
187 else {
188 Free (*lppDest);
189 *lppDest = NULL;
190 }
191
192 return TRUE;
193}
194
195/**************************************************************************
196 * Str_GetPtrW [COMCTL32.235]
197 *
198 * See Str_GetPtrA.
199 */
200INT WINAPI Str_GetPtrW (LPCWSTR lpSrc, LPWSTR lpDest, INT nMaxLen)
201{
202 INT len;
203
204 TRACE("(%p %p %d)\n", lpSrc, lpDest, nMaxLen);
205
206 if (!lpDest && lpSrc)
207 return lstrlenW (lpSrc);
208
209 if (nMaxLen == 0)
210 return 0;
211
212 if (lpSrc == NULL) {
213 lpDest[0] = '\0';
214 return 0;
215 }
216
217 len = lstrlenW (lpSrc);
218 if (len >= nMaxLen)
219 len = nMaxLen - 1;
220
221 RtlMoveMemory (lpDest, lpSrc, len*sizeof(WCHAR));
222 lpDest[len] = '\0';
223
224 return len;
225}
226
227/**************************************************************************
228 * Str_SetPtrW [COMCTL32.236]
229 *
230 * See Str_SetPtrA.
231 */
233{
234 TRACE("(%p %s)\n", lppDest, debugstr_w(lpSrc));
235
236 if (lpSrc) {
237 INT len = lstrlenW (lpSrc) + 1;
238 LPWSTR ptr = ReAlloc (*lppDest, len * sizeof(WCHAR));
239 if (!ptr)
240 return FALSE;
241 lstrcpyW (ptr, lpSrc);
242 *lppDest = ptr;
243 }
244 else {
245 Free (*lppDest);
246 *lppDest = NULL;
247 }
248
249 return TRUE;
250}
251
252/**************************************************************************
253 * StrChrA [COMCTL32.350]
254 *
255 * Find a given character in a string.
256 *
257 * PARAMS
258 * lpszStr [I] String to search in.
259 * ch [I] Character to search for.
260 *
261 * RETURNS
262 * Success: A pointer to the first occurrence of ch in lpszStr, or NULL if
263 * not found.
264 * Failure: NULL, if any arguments are invalid.
265 */
267{
268 TRACE("(%s,%i)\n", debugstr_a(lpszStr), ch);
269
270 if (lpszStr)
271 {
272 while (*lpszStr)
273 {
274 if (!COMCTL32_ChrCmpA(*lpszStr, ch))
275 return (LPSTR)lpszStr;
276 lpszStr = CharNextA(lpszStr);
277 }
278 }
279 return NULL;
280}
281
282/**************************************************************************
283 * StrCmpNIA [COMCTL32.353]
284 *
285 * Compare two strings, up to a maximum length, ignoring case.
286 *
287 * PARAMS
288 * lpszStr [I] First string to compare
289 * lpszComp [I] Second string to compare
290 * iLen [I] Number of chars to compare
291 *
292 * RETURNS
293 * An integer less than, equal to or greater than 0, indicating that
294 * lpszStr is less than, the same, or greater than lpszComp.
295 */
296INT WINAPI StrCmpNIA(LPCSTR lpszStr, LPCSTR lpszComp, INT iLen)
297{
298 TRACE("(%s,%s,%i)\n", debugstr_a(lpszStr), debugstr_a(lpszComp), iLen);
299 return CompareStringA(GetThreadLocale(), NORM_IGNORECASE, lpszStr, iLen, lpszComp, iLen) - CSTR_EQUAL;
300}
301
302/*************************************************************************
303 * StrCmpNIW [COMCTL32.361]
304 *
305 * See StrCmpNIA.
306 */
307INT WINAPI StrCmpNIW(LPCWSTR lpszStr, LPCWSTR lpszComp, INT iLen)
308{
309 TRACE("(%s,%s,%i)\n", debugstr_w(lpszStr), debugstr_w(lpszComp), iLen);
310 return CompareStringW(GetThreadLocale(), NORM_IGNORECASE, lpszStr, iLen, lpszComp, iLen) - CSTR_EQUAL;
311}
312
313/*************************************************************************
314 * COMCTL32_StrStrHelperA
315 *
316 * Internal implementation of StrStrA/StrStrIA
317 */
318static LPSTR COMCTL32_StrStrHelperA(LPCSTR lpszStr, LPCSTR lpszSearch,
319 INT (WINAPI *pStrCmpFn)(LPCSTR,LPCSTR,INT))
320{
321 size_t iLen;
322 LPCSTR end;
323
324 if (!lpszStr || !lpszSearch || !*lpszSearch)
325 return NULL;
326
327 iLen = strlen(lpszSearch);
328 end = lpszStr + strlen(lpszStr);
329
330 while (lpszStr + iLen <= end)
331 {
332 if (!pStrCmpFn(lpszStr, lpszSearch, iLen))
333 return (LPSTR)lpszStr;
334 lpszStr = CharNextA(lpszStr);
335 }
336 return NULL;
337}
338
339/**************************************************************************
340 * StrStrIA [COMCTL32.355]
341 *
342 * Find a substring within a string, ignoring case.
343 *
344 * PARAMS
345 * lpszStr [I] String to search in
346 * lpszSearch [I] String to look for
347 *
348 * RETURNS
349 * The start of lpszSearch within lpszStr, or NULL if not found.
350 */
351LPSTR WINAPI StrStrIA(LPCSTR lpszStr, LPCSTR lpszSearch)
352{
353 TRACE("(%s,%s)\n", debugstr_a(lpszStr), debugstr_a(lpszSearch));
354
355 return COMCTL32_StrStrHelperA(lpszStr, lpszSearch, StrCmpNIA);
356}
357
358/**************************************************************************
359 * StrToIntA [COMCTL32.357]
360 *
361 * Read a signed integer from a string.
362 *
363 * PARAMS
364 * lpszStr [I] String to read integer from
365 *
366 * RETURNS
367 * The signed integer value represented by the string, or 0 if no integer is
368 * present.
369 */
371{
372 return atoi(lpszStr);
373}
374
375/**************************************************************************
376 * StrStrIW [COMCTL32.363]
377 *
378 * See StrStrIA.
379 */
381{
382 int iLen;
383 LPCWSTR end;
384
385 TRACE("(%s,%s)\n", debugstr_w(lpszStr), debugstr_w(lpszSearch));
386
387 if (!lpszStr || !lpszSearch || !*lpszSearch)
388 return NULL;
389
390 iLen = lstrlenW(lpszSearch);
391 end = lpszStr + lstrlenW(lpszStr);
392
393 while (lpszStr + iLen <= end)
394 {
395 if (!StrCmpNIW(lpszStr, lpszSearch, iLen))
396 return (LPWSTR)lpszStr;
397 lpszStr++;
398 }
399 return NULL;
400}
401
402/**************************************************************************
403 * StrToIntW [COMCTL32.365]
404 *
405 * See StrToIntA.
406 */
408{
409 return wcstol(lpString, NULL, 10);
410}
411
412/*************************************************************************
413 * COMCTL32_StrSpnHelperA (internal)
414 *
415 * Internal implementation of StrSpnA/StrCSpnA/StrCSpnIA
416 */
417static int COMCTL32_StrSpnHelperA(LPCSTR lpszStr, LPCSTR lpszMatch,
418 LPSTR (WINAPI *pStrChrFn)(LPCSTR,WORD),
420{
421 LPCSTR lpszRead = lpszStr;
422 if (lpszStr && *lpszStr && lpszMatch)
423 {
424 while (*lpszRead)
425 {
426 LPCSTR lpszTest = pStrChrFn(lpszMatch, *lpszRead);
427
428 if (!bInvert && !lpszTest)
429 break;
430 if (bInvert && lpszTest)
431 break;
432 lpszRead = CharNextA(lpszRead);
433 };
434 }
435 return lpszRead - lpszStr;
436}
437
438/**************************************************************************
439 * StrCSpnA [COMCTL32.356]
440 *
441 * Find the length of the start of a string that does not contain certain
442 * characters.
443 *
444 * PARAMS
445 * lpszStr [I] String to search
446 * lpszMatch [I] Characters that cannot be in the substring
447 *
448 * RETURNS
449 * The length of the part of lpszStr containing only chars not in lpszMatch,
450 * or 0 if any parameter is invalid.
451 */
452int WINAPI StrCSpnA(LPCSTR lpszStr, LPCSTR lpszMatch)
453{
454 TRACE("(%s,%s)\n",debugstr_a(lpszStr), debugstr_a(lpszMatch));
455
456 return COMCTL32_StrSpnHelperA(lpszStr, lpszMatch, StrChrA, TRUE);
457}
458
459/**************************************************************************
460 * StrChrW [COMCTL32.358]
461 *
462 * See StrChrA.
463 */
465{
466 LPWSTR lpszRet = NULL;
467
468 TRACE("(%s,%i)\n", debugstr_w(lpszStr), ch);
469
470 if (lpszStr)
471 lpszRet = wcschr(lpszStr, ch);
472 return lpszRet;
473}
474
475/**************************************************************************
476 * StrCmpNA [COMCTL32.352]
477 *
478 * Compare two strings, up to a maximum length.
479 *
480 * PARAMS
481 * lpszStr [I] First string to compare
482 * lpszComp [I] Second string to compare
483 * iLen [I] Number of chars to compare
484 *
485 * RETURNS
486 * An integer less than, equal to or greater than 0, indicating that
487 * lpszStr is less than, the same, or greater than lpszComp.
488 */
489INT WINAPI StrCmpNA(LPCSTR lpszStr, LPCSTR lpszComp, INT iLen)
490{
491 TRACE("(%s,%s,%i)\n", debugstr_a(lpszStr), debugstr_a(lpszComp), iLen);
492 return CompareStringA(GetThreadLocale(), 0, lpszStr, iLen, lpszComp, iLen) - CSTR_EQUAL;
493}
494
495/**************************************************************************
496 * StrCmpNW [COMCTL32.360]
497 *
498 * See StrCmpNA.
499 */
500INT WINAPI StrCmpNW(LPCWSTR lpszStr, LPCWSTR lpszComp, INT iLen)
501{
502 TRACE("(%s,%s,%i)\n", debugstr_w(lpszStr), debugstr_w(lpszComp), iLen);
503 return CompareStringW(GetThreadLocale(), 0, lpszStr, iLen, lpszComp, iLen) - CSTR_EQUAL;
504}
505
506/**************************************************************************
507 * StrRChrA [COMCTL32.351]
508 *
509 * Find the last occurrence of a character in string.
510 *
511 * PARAMS
512 * lpszStr [I] String to search in
513 * lpszEnd [I] Place to end search, or NULL to search until the end of lpszStr
514 * ch [I] Character to search for.
515 *
516 * RETURNS
517 * Success: A pointer to the last occurrence of ch in lpszStr before lpszEnd,
518 * or NULL if not found.
519 * Failure: NULL, if any arguments are invalid.
520 */
521LPSTR WINAPI StrRChrA(LPCSTR lpszStr, LPCSTR lpszEnd, WORD ch)
522{
523 LPCSTR lpszRet = NULL;
524
525 TRACE("(%s,%s,%x)\n", debugstr_a(lpszStr), debugstr_a(lpszEnd), ch);
526
527 if (lpszStr)
528 {
529 WORD ch2;
530
531 if (!lpszEnd)
532 lpszEnd = lpszStr + lstrlenA(lpszStr);
533
534 while (*lpszStr && lpszStr <= lpszEnd)
535 {
536 ch2 = IsDBCSLeadByte(*lpszStr)? *lpszStr << 8 | lpszStr[1] : *lpszStr;
537
538 if (!COMCTL32_ChrCmpA(ch, ch2))
539 lpszRet = lpszStr;
540 lpszStr = CharNextA(lpszStr);
541 }
542 }
543 return (LPSTR)lpszRet;
544}
545
546
547/**************************************************************************
548 * StrRChrW [COMCTL32.359]
549 *
550 * See StrRChrA.
551 */
553{
554 WCHAR *ret = NULL;
555
556 if (!str) return NULL;
557 if (!end) end = str + lstrlenW(str);
558 while (str < end)
559 {
560 if (*str == ch) ret = (WCHAR *)str;
561 str++;
562 }
563 return ret;
564}
565
566/**************************************************************************
567 * StrStrA [COMCTL32.354]
568 *
569 * Find a substring within a string.
570 *
571 * PARAMS
572 * lpszStr [I] String to search in
573 * lpszSearch [I] String to look for
574 *
575 * RETURNS
576 * The start of lpszSearch within lpszStr, or NULL if not found.
577 */
578LPSTR WINAPI StrStrA(LPCSTR lpszStr, LPCSTR lpszSearch)
579{
580 TRACE("(%s,%s)\n", debugstr_a(lpszStr), debugstr_a(lpszSearch));
581
582 return COMCTL32_StrStrHelperA(lpszStr, lpszSearch, StrCmpNA);
583}
584
585/**************************************************************************
586 * StrStrW [COMCTL32.362]
587 *
588 * See StrStrA.
589 */
590LPWSTR WINAPI StrStrW(LPCWSTR lpszStr, LPCWSTR lpszSearch)
591{
592 if (!lpszStr || !lpszSearch) return NULL;
593 return wcsstr( lpszStr, lpszSearch );
594}
595
596/*************************************************************************
597 * StrChrIA [COMCTL32.366]
598 *
599 * Find a given character in a string, ignoring case.
600 *
601 * PARAMS
602 * lpszStr [I] String to search in.
603 * ch [I] Character to search for.
604 *
605 * RETURNS
606 * Success: A pointer to the first occurrence of ch in lpszStr, or NULL if
607 * not found.
608 * Failure: NULL, if any arguments are invalid.
609 */
611{
612 TRACE("(%s,%i)\n", debugstr_a(lpszStr), ch);
613
614 if (lpszStr)
615 {
616 while (*lpszStr)
617 {
618 if (!COMCTL32_ChrCmpIA(*lpszStr, ch))
619 return (LPSTR)lpszStr;
620 lpszStr = CharNextA(lpszStr);
621 }
622 }
623 return NULL;
624}
625
626/*************************************************************************
627 * StrChrIW [COMCTL32.367]
628 *
629 * See StrChrA.
630 */
632{
633 TRACE("(%s,%i)\n", debugstr_w(lpszStr), ch);
634
635 if (lpszStr)
636 {
637 ch = towupper(ch);
638 while (*lpszStr)
639 {
640 if (towupper(*lpszStr) == ch)
641 return (LPWSTR)lpszStr;
642 lpszStr++;
643 }
644 lpszStr = NULL;
645 }
646 return (LPWSTR)lpszStr;
647}
648
649/*************************************************************************
650 * StrRStrIA [COMCTL32.372]
651 *
652 * Find the last occurrence of a substring within a string.
653 *
654 * PARAMS
655 * lpszStr [I] String to search in
656 * lpszEnd [I] End of lpszStr
657 * lpszSearch [I] String to look for
658 *
659 * RETURNS
660 * The last occurrence lpszSearch within lpszStr, or NULL if not found.
661 */
662LPSTR WINAPI StrRStrIA(LPCSTR lpszStr, LPCSTR lpszEnd, LPCSTR lpszSearch)
663{
664 LPSTR lpszRet = NULL;
665 WORD ch1, ch2;
666 INT iLen;
667
668 TRACE("(%s,%s)\n", debugstr_a(lpszStr), debugstr_a(lpszSearch));
669
670 if (!lpszStr || !lpszSearch || !*lpszSearch)
671 return NULL;
672
673 if (IsDBCSLeadByte(*lpszSearch))
674 ch1 = *lpszSearch << 8 | (UCHAR)lpszSearch[1];
675 else
676 ch1 = *lpszSearch;
677 iLen = lstrlenA(lpszSearch);
678
679 if (!lpszEnd)
680 lpszEnd = lpszStr + lstrlenA(lpszStr);
681 else /* reproduce the broken behaviour on Windows */
682 lpszEnd += min(iLen - 1, lstrlenA(lpszEnd));
683
684 while (lpszStr + iLen <= lpszEnd && *lpszStr)
685 {
686 ch2 = IsDBCSLeadByte(*lpszStr)? *lpszStr << 8 | (UCHAR)lpszStr[1] : *lpszStr;
687 if (!COMCTL32_ChrCmpIA(ch1, ch2))
688 {
689 if (!StrCmpNIA(lpszStr, lpszSearch, iLen))
690 lpszRet = (LPSTR)lpszStr;
691 }
692 lpszStr = CharNextA(lpszStr);
693 }
694 return lpszRet;
695}
696
697/*************************************************************************
698 * StrRStrIW [COMCTL32.373]
699 *
700 * See StrRStrIA.
701 */
702LPWSTR WINAPI StrRStrIW(LPCWSTR lpszStr, LPCWSTR lpszEnd, LPCWSTR lpszSearch)
703{
704 LPWSTR lpszRet = NULL;
705 INT iLen;
706
707 TRACE("(%s,%s)\n", debugstr_w(lpszStr), debugstr_w(lpszSearch));
708
709 if (!lpszStr || !lpszSearch || !*lpszSearch)
710 return NULL;
711
712 iLen = lstrlenW(lpszSearch);
713
714 if (!lpszEnd)
715 lpszEnd = lpszStr + lstrlenW(lpszStr);
716 else /* reproduce the broken behaviour on Windows */
717 lpszEnd += min(iLen - 1, lstrlenW(lpszEnd));
718
719
720 while (lpszStr + iLen <= lpszEnd && *lpszStr)
721 {
722 if (!COMCTL32_ChrCmpIW(*lpszSearch, *lpszStr))
723 {
724 if (!StrCmpNIW(lpszStr, lpszSearch, iLen))
725 lpszRet = (LPWSTR)lpszStr;
726 }
727 lpszStr++;
728 }
729 return lpszRet;
730}
731
732/*************************************************************************
733 * StrCSpnIA [COMCTL32.374]
734 *
735 * Find the length of the start of a string that does not contain certain
736 * characters, ignoring case.
737 *
738 * PARAMS
739 * lpszStr [I] String to search
740 * lpszMatch [I] Characters that cannot be in the substring
741 *
742 * RETURNS
743 * The length of the part of lpszStr containing only chars not in lpszMatch,
744 * or 0 if any parameter is invalid.
745 */
746int WINAPI StrCSpnIA(LPCSTR lpszStr, LPCSTR lpszMatch)
747{
748 TRACE("(%s,%s)\n",debugstr_a(lpszStr), debugstr_a(lpszMatch));
749
750 return COMCTL32_StrSpnHelperA(lpszStr, lpszMatch, StrChrIA, TRUE);
751}
752
753/*************************************************************************
754 * StrCSpnIW [COMCTL32.375]
755 *
756 * See StrCSpnIA.
757 */
758int WINAPI StrCSpnIW(LPCWSTR lpszStr, LPCWSTR lpszMatch)
759{
760 LPCWSTR lpszRead = lpszStr;
761
762 TRACE("(%s,%s)\n",debugstr_w(lpszStr), debugstr_w(lpszMatch));
763
764 if (lpszStr && *lpszStr && lpszMatch)
765 {
766 while (*lpszRead)
767 {
768 if (StrChrIW(lpszMatch, *lpszRead)) break;
769 lpszRead++;
770 }
771 }
772 return lpszRead - lpszStr;
773}
774
775/**************************************************************************
776 * StrRChrIA [COMCTL32.368]
777 *
778 * Find the last occurrence of a character in string, ignoring case.
779 *
780 * PARAMS
781 * lpszStr [I] String to search in
782 * lpszEnd [I] Place to end search, or NULL to search until the end of lpszStr
783 * ch [I] Character to search for.
784 *
785 * RETURNS
786 * Success: A pointer to the last occurrence of ch in lpszStr before lpszEnd,
787 * or NULL if not found.
788 * Failure: NULL, if any arguments are invalid.
789 */
790LPSTR WINAPI StrRChrIA(LPCSTR lpszStr, LPCSTR lpszEnd, WORD ch)
791{
792 LPCSTR lpszRet = NULL;
793
794 TRACE("(%s,%s,%x)\n", debugstr_a(lpszStr), debugstr_a(lpszEnd), ch);
795
796 if (lpszStr)
797 {
798 WORD ch2;
799
800 if (!lpszEnd)
801 lpszEnd = lpszStr + lstrlenA(lpszStr);
802
803 while (*lpszStr && lpszStr <= lpszEnd)
804 {
805 ch2 = IsDBCSLeadByte(*lpszStr)? *lpszStr << 8 | lpszStr[1] : *lpszStr;
806
807 if (ch == ch2)
808 lpszRet = lpszStr;
809 lpszStr = CharNextA(lpszStr);
810 }
811 }
812 return (LPSTR)lpszRet;
813}
814
815/**************************************************************************
816 * StrRChrIW [COMCTL32.369]
817 *
818 * See StrRChrIA.
819 */
821{
822 WCHAR *ret = NULL;
823
824 if (!str) return NULL;
825 if (!end) end = str + lstrlenW(str);
826 while (str < end)
827 {
828 if (!COMCTL32_ChrCmpIW(*str, ch)) ret = (WCHAR *)str;
829 str++;
830 }
831 return ret;
832}
833
834/*************************************************************************
835 * StrCSpnW [COMCTL32.364]
836 *
837 * See StrCSpnA.
838 */
839int WINAPI StrCSpnW(LPCWSTR lpszStr, LPCWSTR lpszMatch)
840{
841 if (!lpszStr || !lpszMatch) return 0;
842 return wcscspn( lpszStr, lpszMatch );
843}
844
845/*************************************************************************
846 * IntlStrEqWorkerA [COMCTL32.376]
847 *
848 * Compare two strings.
849 *
850 * PARAMS
851 * bCase [I] Whether to compare case sensitively
852 * lpszStr [I] First string to compare
853 * lpszComp [I] Second string to compare
854 * iLen [I] Length to compare
855 *
856 * RETURNS
857 * TRUE If the strings are equal.
858 * FALSE Otherwise.
859 */
860BOOL WINAPI IntlStrEqWorkerA(BOOL bCase, LPCSTR lpszStr, LPCSTR lpszComp,
861 int iLen)
862{
864 int iRet;
865
866 TRACE("(%d,%s,%s,%d)\n", bCase,
867 debugstr_a(lpszStr), debugstr_a(lpszComp), iLen);
868
869 /* FIXME: This flag is undocumented and unknown by our CompareString.
870 */
872 if (!bCase) dwFlags |= NORM_IGNORECASE;
873
875 dwFlags, lpszStr, iLen, lpszComp, iLen);
876
877 if (!iRet)
878 iRet = CompareStringA(2048, dwFlags, lpszStr, iLen, lpszComp, iLen);
879
880 return iRet == CSTR_EQUAL;
881}
882
883/*************************************************************************
884 * IntlStrEqWorkerW [COMCTL32.377]
885 *
886 * See IntlStrEqWorkerA.
887 */
889 int iLen)
890{
892 int iRet;
893
894 TRACE("(%d,%s,%s,%d)\n", bCase,
895 debugstr_w(lpszStr),debugstr_w(lpszComp), iLen);
896
897 /* FIXME: This flag is undocumented and unknown by our CompareString.
898 */
900 if (!bCase) dwFlags |= NORM_IGNORECASE;
901
903 dwFlags, lpszStr, iLen, lpszComp, iLen);
904
905 if (!iRet)
906 iRet = CompareStringW(2048, dwFlags, lpszStr, iLen, lpszComp, iLen);
907
908 return iRet == CSTR_EQUAL;
909}
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
PVOID ReAlloc(IN DWORD dwFlags, IN PVOID lpMem, IN SIZE_T dwBytes)
Definition: main.c:76
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
INT WINAPI StrToIntW(LPCWSTR lpString)
Definition: string.c:407
static BOOL COMCTL32_ChrCmpA(WORD ch1, WORD ch2)
Definition: string.c:84
BOOL WINAPI IntlStrEqWorkerA(BOOL bCase, LPCSTR lpszStr, LPCSTR lpszComp, int iLen)
Definition: string.c:860
LPWSTR WINAPI StrChrIW(LPCWSTR lpszStr, WCHAR ch)
Definition: string.c:631
LPSTR WINAPI StrRStrIA(LPCSTR lpszStr, LPCSTR lpszEnd, LPCSTR lpszSearch)
Definition: string.c:662
int WINAPI StrCSpnIA(LPCSTR lpszStr, LPCSTR lpszMatch)
Definition: string.c:746
int WINAPI StrCSpnW(LPCWSTR lpszStr, LPCWSTR lpszMatch)
Definition: string.c:839
LPWSTR WINAPI StrChrW(LPCWSTR lpszStr, WCHAR ch)
Definition: string.c:464
LPWSTR WINAPI StrRChrW(LPCWSTR str, LPCWSTR end, WORD ch)
Definition: string.c:552
INT WINAPI Str_GetPtrA(LPCSTR lpSrc, LPSTR lpDest, INT nMaxLen)
Definition: string.c:132
LPSTR WINAPI StrStrIA(LPCSTR lpszStr, LPCSTR lpszSearch)
Definition: string.c:351
LPSTR WINAPI StrRChrIA(LPCSTR lpszStr, LPCSTR lpszEnd, WORD ch)
Definition: string.c:790
BOOL WINAPI Str_SetPtrW(LPWSTR *lppDest, LPCWSTR lpSrc)
Definition: string.c:232
static int COMCTL32_StrSpnHelperA(LPCSTR lpszStr, LPCSTR lpszMatch, LPSTR(WINAPI *pStrChrFn)(LPCSTR, WORD), BOOL bInvert)
Definition: string.c:417
static BOOL COMCTL32_ChrCmpIA(WORD ch1, WORD ch2)
Definition: string.c:102
INT WINAPI StrCmpNIA(LPCSTR lpszStr, LPCSTR lpszComp, INT iLen)
Definition: string.c:296
BOOL WINAPI Str_SetPtrA(LPSTR *lppDest, LPCSTR lpSrc)
Definition: string.c:176
BOOL WINAPI IntlStrEqWorkerW(BOOL bCase, LPCWSTR lpszStr, LPCWSTR lpszComp, int iLen)
Definition: string.c:888
LPSTR WINAPI StrChrIA(LPCSTR lpszStr, WORD ch)
Definition: string.c:610
LPWSTR WINAPI StrRChrIW(LPCWSTR str, LPCWSTR end, WORD ch)
Definition: string.c:820
LPWSTR WINAPI StrStrW(LPCWSTR lpszStr, LPCWSTR lpszSearch)
Definition: string.c:590
LPSTR WINAPI StrRChrA(LPCSTR lpszStr, LPCSTR lpszEnd, WORD ch)
Definition: string.c:521
INT WINAPI StrToIntA(LPCSTR lpszStr)
Definition: string.c:370
int WINAPI StrCSpnIW(LPCWSTR lpszStr, LPCWSTR lpszMatch)
Definition: string.c:758
LPSTR WINAPI StrChrA(LPCSTR lpszStr, WORD ch)
Definition: string.c:266
INT WINAPI Str_GetPtrW(LPCWSTR lpSrc, LPWSTR lpDest, INT nMaxLen)
Definition: string.c:200
INT WINAPI StrCmpNIW(LPCWSTR lpszStr, LPCWSTR lpszComp, INT iLen)
Definition: string.c:307
LPWSTR WINAPI StrStrIW(LPCWSTR lpszStr, LPCWSTR lpszSearch)
Definition: string.c:380
static BOOL COMCTL32_ChrCmpIW(WCHAR ch1, WCHAR ch2)
Definition: string.c:114
int WINAPI StrCSpnA(LPCSTR lpszStr, LPCSTR lpszMatch)
Definition: string.c:452
static LPSTR COMCTL32_StrStrHelperA(LPCSTR lpszStr, LPCSTR lpszSearch, INT(WINAPI *pStrCmpFn)(LPCSTR, LPCSTR, INT))
Definition: string.c:318
INT WINAPI StrCmpNW(LPCWSTR lpszStr, LPCWSTR lpszComp, INT iLen)
Definition: string.c:500
static BOOL COMCTL32_ChrCmpHelperA(WORD ch1, WORD ch2, DWORD dwFlags)
Definition: string.c:54
LPSTR WINAPI StrStrA(LPCSTR lpszStr, LPCSTR lpszSearch)
Definition: string.c:578
LPWSTR WINAPI StrRStrIW(LPCWSTR lpszStr, LPCWSTR lpszEnd, LPCWSTR lpszSearch)
Definition: string.c:702
INT WINAPI StrCmpNA(LPCSTR lpszStr, LPCSTR lpszComp, INT iLen)
Definition: string.c:489
#define wcschr
Definition: compat.h:17
#define lstrcpyW
Definition: compat.h:749
#define lstrlenW
Definition: compat.h:750
LCID WINAPI GetThreadLocale(void)
Definition: locale.c:2801
BOOL WINAPI IsDBCSLeadByte(BYTE testchar)
Definition: locale.c:2124
INT WINAPI CompareStringA(LCID lcid, DWORD flags, LPCSTR str1, INT len1, LPCSTR str2, INT len2)
Definition: locale.c:4083
INT WINAPI CompareStringW(LCID lcid, DWORD flags, LPCWSTR str1, INT len1, LPCWSTR str2, INT len2)
Definition: locale.c:4014
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
GLuint GLuint end
Definition: gl.h:1545
GLenum GLsizei len
Definition: glext.h:6722
_Check_return_ long __cdecl wcstol(_In_z_ const wchar_t *_Str, _Out_opt_ _Deref_post_z_ wchar_t **_EndPtr, _In_ int _Radix)
_Check_return_ int __cdecl atoi(_In_z_ const char *_Str)
_CONST_RETURN wchar_t *__cdecl wcsstr(_In_z_ const wchar_t *_Str, _In_z_ const wchar_t *_SubStr)
#define LOBYTE(W)
Definition: jmemdos.c:487
#define HIBYTE(W)
Definition: jmemdos.c:486
#define debugstr_a
Definition: kernel32.h:31
#define debugstr_w
Definition: kernel32.h:32
int WINAPI lstrlenA(LPCSTR lpString)
Definition: lstring.c:145
static PVOID ptr
Definition: dispmode.c:27
#define min(a, b)
Definition: monoChain.cc:55
const WCHAR * str
_Check_return_ _CRTIMP size_t __cdecl wcscspn(_In_z_ const wchar_t *_Str, _In_z_ const wchar_t *_Control)
#define TRACE(s)
Definition: solgame.cpp:4
#define towupper(c)
Definition: wctype.h:99
int32_t INT
Definition: typedefs.h:58
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
int ret
static BOOL bInvert
Definition: win.c:51
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1176
#define WINAPI
Definition: msvc.h:6
#define NORM_IGNORECASE
Definition: winnls.h:178
#define CSTR_EQUAL
Definition: winnls.h:458
#define LOCALE_RETURN_GENITIVE_NAMES
Definition: winnls.h:24
LPSTR WINAPI CharNextA(_In_ LPCSTR)
_In_opt_ PALLOCATE_FUNCTION _In_opt_ PFREE_FUNCTION Free
Definition: exfuncs.h:815
const char * LPCSTR
Definition: xmlstorage.h:183
char * LPSTR
Definition: xmlstorage.h:182
unsigned char UCHAR
Definition: xmlstorage.h:181
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185