source: trunk/src/shlwapi/string.c

Last change on this file was 21916, checked in by dmik, 14 years ago

Merge branch gcc-kmk to trunk.

File size: 16.3 KB
RevLine 
[8584]1/*
2 * Shlwapi string functions
3 *
4 * Copyright 1998 Juergen Schmied
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
[4081]21#include <ctype.h>
[8584]22#include <stdlib.h>
[4081]23#include <stdio.h>
24#include <string.h>
25
26#include "winerror.h"
[5618]27#include "windef.h"
28#include "winbase.h"
29#include "wingdi.h"
30#include "winuser.h"
[7820]31#include "winreg.h"
32#define NO_SHLWAPI_STREAM
[5618]33#include "shlwapi.h"
34#include "shlobj.h"
[4081]35#include "wine/unicode.h"
[8584]36#include "wine/debug.h"
[4081]37
[8584]38WINE_DEFAULT_DEBUG_CHANNEL(shell);
[4081]39
40/*************************************************************************
[7820]41 * ChrCmpIA [SHLWAPI.385]
42 *
43 * Note: Returns 0 (FALSE) if characters are equal (insensitive).
[4081]44 */
[7820]45BOOL WINAPI ChrCmpIA (WORD w1, WORD w2)
46{
47 TRACE("%c ? %c\n", w1, w2);
48 return (toupper(w1) != toupper(w2));
49}
50
51/*************************************************************************
52 * ChrCmpIW [SHLWAPI.386]
53 *
54 * Note: Returns 0 (FALSE) if characters are equal (insensitive).
55 */
56BOOL WINAPI ChrCmpIW (WCHAR w1, WCHAR w2)
57{
58 TRACE("%c ? %c\n", w1, w2);
59 return (toupperW(w1) != toupperW(w2));
60}
61
62/*************************************************************************
63 * StrChrA [SHLWAPI.@]
64 */
[4081]65LPSTR WINAPI StrChrA (LPCSTR str, WORD c)
66{
[6712]67 TRACE("%s %i\n", str,c);
68 return strchr(str, c);
[4081]69}
70
71/*************************************************************************
[7820]72 * StrChrW [SHLWAPI.@]
[4081]73 *
74 */
75LPWSTR WINAPI StrChrW (LPCWSTR str, WCHAR x )
76{
[6712]77 TRACE("%s 0x%04x\n",debugstr_w(str),x);
78 return strchrW(str, x);
[4081]79}
[7820]80
[5618]81/*************************************************************************
[7820]82 * StrCmpIW [SHLWAPI.@]
[5618]83 */
84int WINAPI StrCmpIW ( LPCWSTR wstr1, LPCWSTR wstr2 )
85{
86 TRACE("%s %s\n", debugstr_w(wstr1),debugstr_w(wstr2));
87 return strcmpiW( wstr1, wstr2 );
88}
[4081]89
90/*************************************************************************
[7820]91 * StrCmpNA [SHLWAPI.@]
[4081]92 */
93INT WINAPI StrCmpNA ( LPCSTR str1, LPCSTR str2, INT len)
94{
[6712]95 TRACE("%s %s %i stub\n", str1,str2,len);
96 return strncmp(str1, str2, len);
[4081]97}
98
99/*************************************************************************
[7820]100 * StrCmpNW [SHLWAPI.@]
[4081]101 */
102INT WINAPI StrCmpNW ( LPCWSTR wstr1, LPCWSTR wstr2, INT len)
103{
[6712]104 TRACE("%s %s %i stub\n", debugstr_w(wstr1),debugstr_w(wstr2),len);
105 return strncmpW(wstr1, wstr2, len);
[4081]106}
107
108/*************************************************************************
[7820]109 * StrCmpNIA [SHLWAPI.@]
[4081]110 */
111int WINAPI StrCmpNIA ( LPCSTR str1, LPCSTR str2, int len)
112{
[6712]113 TRACE("%s %s %i stub\n", str1,str2,len);
114 return strncasecmp(str1, str2, len);
[4081]115}
116
117/*************************************************************************
[7820]118 * StrCmpNIW [SHLWAPI.@]
[4081]119 */
120int WINAPI StrCmpNIW ( LPCWSTR wstr1, LPCWSTR wstr2, int len)
121{
[6712]122 TRACE("%s %s %i stub\n", debugstr_w(wstr1),debugstr_w(wstr2),len);
123 return strncmpiW(wstr1, wstr2, len);
[4081]124}
125
126/*************************************************************************
[7820]127 * StrCmpW [SHLWAPI.@]
[5618]128 */
129int WINAPI StrCmpW ( LPCWSTR wstr1, LPCWSTR wstr2 )
130{
131 TRACE("%s %s\n", debugstr_w(wstr1),debugstr_w(wstr2));
132 return strcmpW( wstr1, wstr2 );
133}
134
135/*************************************************************************
[7820]136 * StrCatW [SHLWAPI.@]
[4081]137 */
138LPWSTR WINAPI StrCatW( LPWSTR wstr1, LPCWSTR wstr2 )
139{
140 return strcatW( wstr1, wstr2 );
141}
142
143
144/*************************************************************************
[7820]145 * StrCpyW [SHLWAPI.@]
[4081]146 */
147LPWSTR WINAPI StrCpyW( LPWSTR wstr1, LPCWSTR wstr2 )
148{
149 return strcpyW( wstr1, wstr2 );
150}
151
152
153/*************************************************************************
[7820]154 * StrCpyNW [SHLWAPI.@]
[5618]155 */
156LPWSTR WINAPI StrCpyNW( LPWSTR wstr1, LPCWSTR wstr2, int n )
157{
158 return lstrcpynW( wstr1, wstr2, n );
159}
160
161
162/*************************************************************************
[7820]163 * StrStrA [SHLWAPI.@]
[4081]164 */
165LPSTR WINAPI StrStrA(LPCSTR lpFirst, LPCSTR lpSrch)
166{
167 while (*lpFirst)
168 {
169 LPCSTR p1 = lpFirst, p2 = lpSrch;
170 while (*p1 && *p2 && *p1 == *p2) { p1++; p2++; }
171 if (!*p2) return (LPSTR)lpFirst;
172 lpFirst++;
173 }
174 return NULL;
175}
176
177/*************************************************************************
[7820]178 * StrStrW [SHLWAPI.@]
[4081]179 */
180LPWSTR WINAPI StrStrW(LPCWSTR lpFirst, LPCWSTR lpSrch)
181{
182 while (*lpFirst)
183 {
184 LPCWSTR p1 = lpFirst, p2 = lpSrch;
185 while (*p1 && *p2 && *p1 == *p2) { p1++; p2++; }
186 if (!*p2) return (LPWSTR)lpFirst;
187 lpFirst++;
188 }
189 return NULL;
190}
191
192/*************************************************************************
[7820]193 * StrStrIA [SHLWAPI.@]
[4081]194 */
195LPSTR WINAPI StrStrIA(LPCSTR lpFirst, LPCSTR lpSrch)
196{
197 while (*lpFirst)
198 {
199 LPCSTR p1 = lpFirst, p2 = lpSrch;
200 while (*p1 && *p2 && toupper(*p1) == toupper(*p2)) { p1++; p2++; }
201 if (!*p2) return (LPSTR)lpFirst;
202 lpFirst++;
203 }
204 return NULL;
205}
206
207/*************************************************************************
[7820]208 * StrStrIW [SHLWAPI.@]
[4081]209 */
210LPWSTR WINAPI StrStrIW(LPCWSTR lpFirst, LPCWSTR lpSrch)
211{
212 while (*lpFirst)
213 {
214 LPCWSTR p1 = lpFirst, p2 = lpSrch;
215 while (*p1 && *p2 && toupperW(*p1) == toupperW(*p2)) { p1++; p2++; }
216 if (!*p2) return (LPWSTR)lpFirst;
217 lpFirst++;
218 }
219 return NULL;
220}
221
222/*************************************************************************
[7820]223 * StrToIntA [SHLWAPI.@]
[4081]224 */
225int WINAPI StrToIntA(LPCSTR lpSrc)
226{
[6712]227 TRACE("%s\n", lpSrc);
228 return atol(lpSrc);
[4081]229}
230
231/*************************************************************************
[7820]232 * StrToIntW [SHLWAPI.@]
[4081]233 */
234int WINAPI StrToIntW(LPCWSTR lpSrc)
235{
[5618]236 char buffer[32];
[4081]237
[5618]238 TRACE("%s\n", debugstr_w(lpSrc));
239 WideCharToMultiByte( CP_ACP, 0, lpSrc, -1, buffer, sizeof(buffer), NULL, NULL );
240 buffer[sizeof(buffer)-1] = 0;
241 return atol(buffer);
242}
[4081]243
[5618]244/*************************************************************************
[7820]245 * StrToIntExA [SHLWAPI.@]
[5618]246 */
247BOOL WINAPI StrToIntExA( LPCSTR pszString, DWORD dwFlags, LPINT piRet)
248{
[6712]249 TRACE("%s %ld stub !\n", debugstr_a(pszString), dwFlags);
250 piRet = (LPINT) StrToIntA(pszString);
251 return TRUE;
[4081]252}
253
254/*************************************************************************
[7820]255 * StrToIntExW [SHLWAPI.@]
[5618]256 */
257BOOL WINAPI StrToIntExW( LPCWSTR pszString, DWORD dwFlags, LPINT piRet)
258{
[6712]259 TRACE("%s %ld stub !\n", debugstr_w(pszString), dwFlags);
260 piRet = (LPINT) StrToIntW(pszString);
261 return TRUE;
[5618]262}
263
264/*************************************************************************
[7820]265 * StrDupA [SHLWAPI.@]
[4081]266 */
267LPSTR WINAPI StrDupA (LPCSTR lpSrc)
268{
[6712]269 int len = strlen(lpSrc);
270 LPSTR lpDest = (LPSTR) LocalAlloc(LMEM_FIXED, len+1);
[8584]271
[6712]272 TRACE("%s\n", lpSrc);
[4081]273
[6712]274 if (lpDest) strcpy(lpDest, lpSrc);
275 return lpDest;
[4081]276}
277
278/*************************************************************************
[7820]279 * StrDupW [SHLWAPI.@]
[4081]280 */
281LPWSTR WINAPI StrDupW (LPCWSTR lpSrc)
282{
[6712]283 int len = strlenW(lpSrc);
284 LPWSTR lpDest = (LPWSTR) LocalAlloc(LMEM_FIXED, sizeof(WCHAR) * (len+1));
[8584]285
[6712]286 TRACE("%s\n", debugstr_w(lpSrc));
[4081]287
[6712]288 if (lpDest) strcpyW(lpDest, lpSrc);
289 return lpDest;
[4081]290}
291
292/*************************************************************************
[7820]293 * StrCSpnA [SHLWAPI.@]
[4081]294 */
295int WINAPI StrCSpnA (LPCSTR lpStr, LPCSTR lpSet)
296{
[6712]297 int i,j, pos = strlen(lpStr);
[4081]298
[6712]299 TRACE("(%p %s %p %s)\n",
300 lpStr, debugstr_a(lpStr), lpSet, debugstr_a(lpSet));
[4081]301
[6712]302 for (i=0; i < strlen(lpSet) ; i++ )
303 {
304 for (j = 0; j < pos;j++)
305 {
306 if (lpStr[j] == lpSet[i])
307 {
308 pos = j;
309 }
310 }
[8584]311 }
[6712]312 TRACE("-- %u\n", pos);
[8584]313 return pos;
[4081]314}
315
316/*************************************************************************
[7820]317 * StrCSpnW [SHLWAPI.@]
[4081]318 */
319int WINAPI StrCSpnW (LPCWSTR lpStr, LPCWSTR lpSet)
320{
[6712]321 int i,j, pos = strlenW(lpStr);
[4081]322
[6712]323 TRACE("(%p %s %p %s)\n",
324 lpStr, debugstr_w(lpStr), lpSet, debugstr_w(lpSet));
[4081]325
[6712]326 for (i=0; i < strlenW(lpSet) ; i++ )
327 {
328 for (j = 0; j < pos;j++)
329 {
330 if (lpStr[j] == lpSet[i])
331 {
332 pos = j;
333 }
334 }
[8584]335 }
[6712]336 TRACE("-- %u\n", pos);
[8584]337 return pos;
[4081]338}
339
340/**************************************************************************
341 * StrRChrA [SHLWAPI.@]
342 *
343 */
344LPSTR WINAPI StrRChrA( LPCSTR lpStart, LPCSTR lpEnd, WORD wMatch )
345{
346 LPCSTR lpGotIt = NULL;
347 BOOL dbcs = IsDBCSLeadByte( LOBYTE(wMatch) );
348
349 TRACE("(%p, %p, %x)\n", lpStart, lpEnd, wMatch);
[7820]350 if (!lpStart && !lpEnd) return NULL;
[4081]351 if (!lpEnd) lpEnd = lpStart + strlen(lpStart);
352
353 for(; lpStart < lpEnd; lpStart = CharNextA(lpStart))
354 {
355 if (*lpStart != LOBYTE(wMatch)) continue;
356 if (dbcs && lpStart[1] != HIBYTE(wMatch)) continue;
357 lpGotIt = lpStart;
[8584]358 }
[4081]359 return (LPSTR)lpGotIt;
360}
361
362
363/**************************************************************************
364 * StrRChrW [SHLWAPI.@]
365 *
366 */
367LPWSTR WINAPI StrRChrW( LPCWSTR lpStart, LPCWSTR lpEnd, WORD wMatch)
368{
369 LPCWSTR lpGotIt = NULL;
370
371 TRACE("(%p, %p, %x)\n", lpStart, lpEnd, wMatch);
[7820]372 if (!lpStart && !lpEnd) return NULL;
[4081]373 if (!lpEnd) lpEnd = lpStart + strlenW(lpStart);
374
375 for(; lpStart < lpEnd; lpStart = CharNextW(lpStart))
376 if (*lpStart == wMatch) lpGotIt = lpStart;
377
378 return (LPWSTR)lpGotIt;
379}
380
381
[7820]382/**************************************************************************
383 * StrRChrIA [SHLWAPI.@]
384 *
385 */
386LPSTR WINAPI StrRChrIA( LPCSTR lpStart, LPCSTR lpEnd, WORD wMatch )
387{
388 LPCSTR lpGotIt = NULL;
389 BOOL dbcs = IsDBCSLeadByte( LOBYTE(wMatch) );
390
391 TRACE("(%p, %p, %x)\n", lpStart, lpEnd, wMatch);
392 if (!lpStart && !lpEnd) return NULL;
393 if (!lpEnd) lpEnd = lpStart + strlen(lpStart);
394
395 for(; lpStart < lpEnd; lpStart = CharNextA(lpStart))
396 {
397 if (dbcs) {
398 /*
399 if (_mbctoupper(*lpStart) == _mbctoupper(wMatch))
400 lpGotIt = lpStart;
401 */
402 if (toupper(*lpStart) == toupper(wMatch)) lpGotIt = lpStart;
403 } else {
404 if (toupper(*lpStart) == toupper(wMatch)) lpGotIt = lpStart;
405 }
[8584]406 }
[7820]407 return (LPSTR)lpGotIt;
408}
409
410
411/**************************************************************************
412 * StrRChrIW [SHLWAPI.@]
413 *
414 */
415LPWSTR WINAPI StrRChrIW( LPCWSTR lpStart, LPCWSTR lpEnd, WORD wMatch)
416{
417 LPCWSTR lpGotIt = NULL;
418
419 TRACE("(%p, %p, %x)\n", lpStart, lpEnd, wMatch);
420 if (!lpStart && !lpEnd) return NULL;
421 if (!lpEnd) lpEnd = lpStart + strlenW(lpStart);
422
423 for(; lpStart < lpEnd; lpStart = CharNextW(lpStart))
424 if (toupperW(*lpStart) == toupperW(wMatch)) lpGotIt = lpStart;
425
426 return (LPWSTR)lpGotIt;
427}
428
429
[4081]430/*************************************************************************
[7820]431 * StrCatBuffA [SHLWAPI.@]
[4081]432 *
433 * Appends back onto front, stopping when front is size-1 characters long.
434 * Returns front.
435 *
436 */
437LPSTR WINAPI StrCatBuffA(LPSTR front, LPCSTR back, INT size)
438{
439 LPSTR dst = front + strlen(front);
440 LPCSTR src = back, end = front + size - 1;
441
442 while(dst < end && *src)
443 *dst++ = *src++;
444 *dst = '\0';
445 return front;
446}
447
448/*************************************************************************
[7820]449 * StrCatBuffW [SHLWAPI.@]
[4081]450 *
451 * Appends back onto front, stopping when front is size-1 characters long.
452 * Returns front.
453 *
454 */
455LPWSTR WINAPI StrCatBuffW(LPWSTR front, LPCWSTR back, INT size)
456{
457 LPWSTR dst = front + strlenW(front);
458 LPCWSTR src = back, end = front + size - 1;
459
460 while(dst < end && *src)
461 *dst++ = *src++;
462 *dst = '\0';
463 return front;
464}
465
466/*************************************************************************
[6712]467 * StrRetToBufA [SHLWAPI.@]
[8584]468 *
[4081]469 * converts a STRRET to a normal string
470 *
471 * NOTES
472 * the pidl is for STRRET OFFSET
[7820]473 *
474 * ***** NOTE *****
475 * This routine is identical to StrRetToStrNA in dlls/shell32/shellstring.c.
476 * It was duplicated there because not every version of Shlwapi.dll exports
477 * StrRetToBufA. If you change one routine, change them both. YOU HAVE BEEN
478 * WARNED.
479 * ***** NOTE *****
[4081]480 */
[5618]481HRESULT WINAPI StrRetToBufA (LPSTRRET src, const ITEMIDLIST *pidl, LPSTR dest, DWORD len)
[4081]482{
[7820]483 TRACE("dest=%p len=0x%lx strret=%p pidl=%p stub\n",dest,len,src,pidl);
[4081]484
[6712]485 switch (src->uType)
486 {
487 case STRRET_WSTR:
[21916]488 WideCharToMultiByte(CP_ACP, 0, src->DUMMYUNIONNAME_DOT pOleStr, -1, (LPSTR)dest, len, NULL, NULL);
489/* SHFree(src->DUMMYUNIONNAME_DOT pOleStr); FIXME: is this right? */
[6712]490 break;
[4081]491
[21512]492 case STRRET_CSTR:
[21916]493 lstrcpynA((LPSTR)dest, src->DUMMYUNIONNAME_DOT cStr, len);
[6712]494 break;
[4081]495
[21512]496 case STRRET_OFFSET:
[21916]497 lstrcpynA((LPSTR)dest, ((LPCSTR)&pidl->mkid)+src->DUMMYUNIONNAME_DOT uOffset, len);
[6712]498 break;
[4081]499
[6712]500 default:
501 FIXME("unknown type!\n");
502 if (len)
503 {
504 *(LPSTR)dest = '\0';
505 }
506 return(FALSE);
507 }
508 return S_OK;
[4081]509}
510
511/*************************************************************************
[6712]512 * StrRetToBufW [SHLWAPI.@]
[8584]513 *
[4081]514 * converts a STRRET to a normal string
515 *
516 * NOTES
517 * the pidl is for STRRET OFFSET
[7820]518 *
519 * ***** NOTE *****
520 * This routine is identical to StrRetToStrNW in dlls/shell32/shellstring.c.
521 * It was duplicated there because not every version of Shlwapi.dll exports
522 * StrRetToBufW. If you change one routine, change them both. YOU HAVE BEEN
523 * WARNED.
524 * ***** NOTE *****
[4081]525 */
[5618]526HRESULT WINAPI StrRetToBufW (LPSTRRET src, const ITEMIDLIST *pidl, LPWSTR dest, DWORD len)
[4081]527{
[7820]528 TRACE("dest=%p len=0x%lx strret=%p pidl=%p stub\n",dest,len,src,pidl);
[4081]529
[6712]530 switch (src->uType)
531 {
532 case STRRET_WSTR:
[21916]533 lstrcpynW((LPWSTR)dest, src->DUMMYUNIONNAME_DOT pOleStr, len);
534/* SHFree(src->DUMMYUNIONNAME_DOT pOleStr); FIXME: is this right? */
[6712]535 break;
[4081]536
[21512]537 case STRRET_CSTR:
[21916]538 if (!MultiByteToWideChar( CP_ACP, 0, src->DUMMYUNIONNAME_DOT cStr, -1, dest, len ) && len)
[5618]539 dest[len-1] = 0;
[6712]540 break;
[4081]541
[21512]542 case STRRET_OFFSET:
[6712]543 if (pidl)
544 {
[21916]545 if (!MultiByteToWideChar( CP_ACP, 0, ((LPCSTR)&pidl->mkid)+src->DUMMYUNIONNAME_DOT uOffset, -1,
[5618]546 dest, len ) && len)
547 dest[len-1] = 0;
[6712]548 }
549 break;
[4081]550
[6712]551 default:
552 FIXME("unknown type!\n");
553 if (len)
554 { *(LPSTR)dest = '\0';
555 }
556 return(FALSE);
557 }
558 return S_OK;
[4081]559}
560
561/*************************************************************************
[7820]562 * StrFormatByteSizeA [SHLWAPI.@]
[4081]563 */
564LPSTR WINAPI StrFormatByteSizeA ( DWORD dw, LPSTR pszBuf, UINT cchBuf )
[6712]565{ char buf[64];
566 TRACE("%lx %p %i\n", dw, pszBuf, cchBuf);
567 if ( dw<1024L )
568 { sprintf (buf,"%ld bytes", dw);
569 }
570 else if ( dw<1048576L)
571 { sprintf (buf,"%3.1f KB", (FLOAT)dw/1024);
572 }
573 else if ( dw < 1073741824L)
574 { sprintf (buf,"%3.1f MB", (FLOAT)dw/1048576L);
575 }
576 else
577 { sprintf (buf,"%3.1f GB", (FLOAT)dw/1073741824L);
578 }
579 lstrcpynA (pszBuf, buf, cchBuf);
[8584]580 return pszBuf;
[4081]581}
582
583/*************************************************************************
[7820]584 * StrFormatByteSizeW [SHLWAPI.@]
[4081]585 */
586LPWSTR WINAPI StrFormatByteSizeW ( DWORD dw, LPWSTR pszBuf, UINT cchBuf )
[5618]587{
588 char buf[64];
589 StrFormatByteSizeA( dw, buf, sizeof(buf) );
590 if (!MultiByteToWideChar( CP_ACP, 0, buf, -1, pszBuf, cchBuf ) && cchBuf)
591 pszBuf[cchBuf-1] = 0;
592 return pszBuf;
[4081]593}
594
595/*************************************************************************
[7820]596 * StrNCatA [SHLWAPI.@]
[5618]597 */
598LPSTR WINAPI StrNCatA(LPSTR front, LPCSTR back, INT cchMax)
599{
[6712]600 TRACE("%s %s %i stub\n", debugstr_a(front),debugstr_a(back),cchMax);
601 return (front);
[5618]602}
603
604/*************************************************************************
[7820]605 * StrNCatW [SHLWAPI.@]
[5618]606 */
607LPWSTR WINAPI StrNCatW(LPWSTR front, LPCWSTR back, INT cchMax)
608{
[6712]609 TRACE("%s %s %i stub\n", debugstr_w(front),debugstr_w(back),cchMax);
610 return (front);
[5618]611}
612
613/*************************************************************************
[6712]614 * StrTrimA [SHLWAPI.@]
[6608]615 */
616BOOL WINAPI StrTrimA(LPSTR pszSource, LPCSTR pszTrimChars)
617{
618 BOOL trimmed = FALSE;
619 LPSTR pSrc;
620 LPCSTR pTrim;
621
622 TRACE("('%s', '%s');\n", pszSource, pszTrimChars);
623 for (pTrim = pszTrimChars; *pTrim; pTrim++)
624 {
[6712]625 for (pSrc = pszSource; *pSrc; pSrc++)
626 if (*pSrc == *pTrim)
627 {
628 /* match -> remove this char.
629 * strlen(pSrc) equiv. to the correct strlen(pSrc+1)+1 */
630 memmove(pSrc, pSrc+1, strlen(pSrc));
631 trimmed = TRUE;
632 }
[6608]633 }
634 TRACE("<- '%s'\n", pszSource);
635 return trimmed;
636}
Note: See TracBrowser for help on using the repository browser.