~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Wine Cross Reference
wine/dlls/comctl32/string.c

Version: ~ [ wine-1.1.33 ] ~ [ wine-1.1.32 ] ~ [ wine-1.1.31 ] ~ [ wine-1.1.30 ] ~ [ wine-1.1.29 ] ~ [ wine-1.1.28 ] ~ [ wine-1.1.27 ] ~ [ wine-1.1.26 ] ~ [ wine-1.1.25 ] ~ [ wine-1.1.24 ] ~ [ wine-1.1.23 ] ~ [ wine-1.1.22 ] ~ [ wine-1.1.21 ] ~ [ wine-1.1.20 ] ~ [ wine-1.1.19 ] ~ [ wine-1.1.18 ] ~ [ wine-1.1.17 ] ~ [ wine-1.1.16 ] ~ [ wine-1.1.15 ] ~ [ wine-1.1.14 ] ~ [ wine-1.1.13 ] ~ [ wine-1.1.12 ] ~ [ wine-1.1.11 ] ~ [ wine-1.1.10 ] ~ [ wine-1.1.9 ] ~ [ wine-1.1.8 ] ~ [ wine-1.1.7 ] ~ [ wine-1.0.1 ] ~ [ wine-1.1.6 ] ~ [ wine-1.1.5 ] ~ [ wine-1.1.4 ] ~ [ wine-1.1.3 ] ~ [ wine-1.1.2 ] ~ [ wine-1.1.1 ] ~ [ wine-1.1.0 ] ~ [ wine-1.0 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.