Removed a few dependencies on kernel32 functions.
[wine] / dlls / shlwapi / string.c
1 #include <ctype.h>
2 #include <stdlib.h> 
3 #include <stdio.h>
4 #include <string.h>
5
6 #include "winerror.h"
7 #include "windef.h"
8 #include "winbase.h"
9 #include "wingdi.h"
10 #include "winuser.h"
11 #include "shlwapi.h"
12 #include "shlobj.h"
13 #include "wine/unicode.h"
14 #include "wine/winestring.h"
15 #include "heap.h"
16 #include "debugtools.h"
17
18 DEFAULT_DEBUG_CHANNEL(shell);
19
20 /*************************************************************************
21  * StrChrA                                      [SHLWAPI]
22  */
23 LPSTR WINAPI StrChrA (LPCSTR str, WORD c)
24 {
25         TRACE("%s %i\n", str,c);
26         return strchr(str, c);
27 }
28
29 /*************************************************************************
30  * StrChrW                                      [SHLWAPI]
31  *
32  */
33 LPWSTR WINAPI StrChrW (LPCWSTR str, WCHAR x )
34 {
35         TRACE("%s 0x%04x\n",debugstr_w(str),x);
36         return strchrW(str, x);
37 }
38
39 /*************************************************************************
40  * StrCmpNA                                     [SHLWAPI]
41  */
42 INT WINAPI StrCmpNA ( LPCSTR str1, LPCSTR str2, INT len)
43 {
44         TRACE("%s %s %i stub\n", str1,str2,len);
45         return strncmp(str1, str2, len);
46 }
47
48 /*************************************************************************
49  * StrCmpNW                                     [SHLWAPI]
50  */
51 INT WINAPI StrCmpNW ( LPCWSTR wstr1, LPCWSTR wstr2, INT len)
52 {
53         TRACE("%s %s %i stub\n", debugstr_w(wstr1),debugstr_w(wstr2),len);
54         return strncmpW(wstr1, wstr2, len);
55 }
56
57 /*************************************************************************
58  * StrCmpNIA                                    [SHLWAPI]
59  */
60 int WINAPI StrCmpNIA ( LPCSTR str1, LPCSTR str2, int len)
61 {
62         TRACE("%s %s %i stub\n", str1,str2,len);
63         return strncasecmp(str1, str2, len);
64 }
65
66 /*************************************************************************
67  * StrCmpNIW                                    [SHLWAPI]
68  */
69 int WINAPI StrCmpNIW ( LPCWSTR wstr1, LPCWSTR wstr2, int len)
70 {
71         TRACE("%s %s %i stub\n", debugstr_w(wstr1),debugstr_w(wstr2),len);
72         return strncmpiW(wstr1, wstr2, len);
73 }
74
75 /*************************************************************************
76  * StrCatW                                      [SHLWAPI]
77  */
78 LPWSTR WINAPI StrCatW( LPWSTR wstr1, LPCWSTR wstr2 )
79 {
80     return strcatW( wstr1, wstr2 );
81 }
82
83
84 /*************************************************************************
85  * StrCpyW                                      [SHLWAPI]
86  */
87 LPWSTR WINAPI StrCpyW( LPWSTR wstr1, LPCWSTR wstr2 )
88 {
89     return strcpyW( wstr1, wstr2 );
90 }
91
92
93 /*************************************************************************
94  * StrStrA                                      [SHLWAPI]
95  */
96 LPSTR WINAPI StrStrA(LPCSTR lpFirst, LPCSTR lpSrch)
97 {
98     while (*lpFirst)
99     {
100         LPCSTR p1 = lpFirst, p2 = lpSrch;
101         while (*p1 && *p2 && *p1 == *p2) { p1++; p2++; }
102         if (!*p2) return (LPSTR)lpFirst;
103         lpFirst++;
104     }
105     return NULL;
106 }
107
108 /*************************************************************************
109  * StrStrW                                      [SHLWAPI]
110  */
111 LPWSTR WINAPI StrStrW(LPCWSTR lpFirst, LPCWSTR lpSrch)
112 {
113     while (*lpFirst)
114     {
115         LPCWSTR p1 = lpFirst, p2 = lpSrch;
116         while (*p1 && *p2 && *p1 == *p2) { p1++; p2++; }
117         if (!*p2) return (LPWSTR)lpFirst;
118         lpFirst++;
119     }
120     return NULL;
121 }
122
123 /*************************************************************************
124  * StrStrIA                                     [SHLWAPI]
125  */
126 LPSTR WINAPI StrStrIA(LPCSTR lpFirst, LPCSTR lpSrch)
127 {
128     while (*lpFirst)
129     {
130         LPCSTR p1 = lpFirst, p2 = lpSrch;
131         while (*p1 && *p2 && toupper(*p1) == toupper(*p2)) { p1++; p2++; }
132         if (!*p2) return (LPSTR)lpFirst;
133         lpFirst++;
134     }
135     return NULL;
136 }
137
138 /*************************************************************************
139  * StrStrIW                                     [SHLWAPI]
140  */
141 LPWSTR WINAPI StrStrIW(LPCWSTR lpFirst, LPCWSTR lpSrch)
142 {
143     while (*lpFirst)
144     {
145         LPCWSTR p1 = lpFirst, p2 = lpSrch;
146         while (*p1 && *p2 && toupperW(*p1) == toupperW(*p2)) { p1++; p2++; }
147         if (!*p2) return (LPWSTR)lpFirst;
148         lpFirst++;
149     }
150     return NULL;
151 }
152
153 /*************************************************************************
154  *      StrToIntA                       [SHLWAPI]
155  */
156 int WINAPI StrToIntA(LPCSTR lpSrc)
157 {
158         TRACE("%s\n", lpSrc);
159         return atol(lpSrc);
160 }
161
162 /*************************************************************************
163  *      StrToIntW                       [SHLWAPI]
164  */
165 int WINAPI StrToIntW(LPCWSTR lpSrc)
166 {
167         int ret;
168         LPSTR lpStr =  HEAP_strdupWtoA(GetProcessHeap(),0,lpSrc);
169
170         TRACE("%s\n", debugstr_w(lpSrc));
171
172         ret = atol(lpStr);
173         HeapFree(GetProcessHeap(),0,lpStr);
174         return ret;
175 }
176
177 /*************************************************************************
178  *      StrDupA                 [SHLWAPI]
179  */
180 LPSTR WINAPI StrDupA (LPCSTR lpSrc)
181 {
182         int len = strlen(lpSrc);
183         LPSTR lpDest = (LPSTR) LocalAlloc(LMEM_FIXED, len+1);
184         
185         TRACE("%s\n", lpSrc);
186
187         if (lpDest) strcpy(lpDest, lpSrc);
188         return lpDest;
189 }
190
191 /*************************************************************************
192  *      StrDupW                 [SHLWAPI]
193  */
194 LPWSTR WINAPI StrDupW (LPCWSTR lpSrc)
195 {
196         int len = strlenW(lpSrc);
197         LPWSTR lpDest = (LPWSTR) LocalAlloc(LMEM_FIXED, sizeof(WCHAR) * (len+1));
198         
199         TRACE("%s\n", debugstr_w(lpSrc));
200
201         if (lpDest) strcpyW(lpDest, lpSrc);
202         return lpDest;
203 }
204
205 /*************************************************************************
206  *      StrCSpnA                [SHLWAPI]
207  */
208 int WINAPI StrCSpnA (LPCSTR lpStr, LPCSTR lpSet)
209 {
210         int i,j, pos = strlen(lpStr);
211
212         TRACE("(%p %s  %p %s)\n",
213            lpStr, debugstr_a(lpStr), lpSet, debugstr_a(lpSet));
214
215         for (i=0; i < strlen(lpSet) ; i++ )
216         {
217           for (j = 0; j < pos;j++)
218           {
219             if (lpStr[j] == lpSet[i])
220             {
221               pos = j;
222             }
223           }
224         }      
225         TRACE("-- %u\n", pos);
226         return pos;     
227 }
228
229 /*************************************************************************
230  *      StrCSpnW                [SHLWAPI]
231  */
232 int WINAPI StrCSpnW (LPCWSTR lpStr, LPCWSTR lpSet)
233 {
234         int i,j, pos = strlenW(lpStr);
235
236         TRACE("(%p %s %p %s)\n",
237            lpStr, debugstr_w(lpStr), lpSet, debugstr_w(lpSet));
238
239         for (i=0; i < strlenW(lpSet) ; i++ )
240         {
241           for (j = 0; j < pos;j++)
242           {
243             if (lpStr[j] == lpSet[i])
244             {
245               pos = j;
246             }
247           }
248         }      
249         TRACE("-- %u\n", pos);
250         return pos;     
251 }
252
253 /**************************************************************************
254  * StrRChrA [SHLWAPI.@]
255  *
256  */
257 LPSTR WINAPI StrRChrA( LPCSTR lpStart, LPCSTR lpEnd, WORD wMatch )
258 {
259     LPCSTR lpGotIt = NULL;
260     BOOL dbcs = IsDBCSLeadByte( LOBYTE(wMatch) );
261
262     TRACE("(%p, %p, %x)\n", lpStart, lpEnd, wMatch);
263
264     if (!lpEnd) lpEnd = lpStart + strlen(lpStart);
265
266     for(; lpStart < lpEnd; lpStart = CharNextA(lpStart))
267     {
268         if (*lpStart != LOBYTE(wMatch)) continue;
269         if (dbcs && lpStart[1] != HIBYTE(wMatch)) continue;
270         lpGotIt = lpStart;
271     }    
272     return (LPSTR)lpGotIt;
273 }
274
275
276 /**************************************************************************
277  * StrRChrW [SHLWAPI.@]
278  *
279  */
280 LPWSTR WINAPI StrRChrW( LPCWSTR lpStart, LPCWSTR lpEnd, WORD wMatch)
281 {
282     LPCWSTR lpGotIt = NULL;
283
284     TRACE("(%p, %p, %x)\n", lpStart, lpEnd, wMatch);
285     if (!lpEnd) lpEnd = lpStart + strlenW(lpStart);
286
287     for(; lpStart < lpEnd; lpStart = CharNextW(lpStart))
288         if (*lpStart == wMatch) lpGotIt = lpStart;
289
290     return (LPWSTR)lpGotIt;
291 }
292
293
294 /*************************************************************************
295  *      StrCatBuffA             [SHLWAPI]
296  *
297  * Appends back onto front, stopping when front is size-1 characters long.
298  * Returns front.
299  *
300  */
301 LPSTR WINAPI StrCatBuffA(LPSTR front, LPCSTR back, INT size)
302 {
303     LPSTR dst = front + strlen(front);
304     LPCSTR src = back, end = front + size - 1;
305
306     while(dst < end && *src)
307         *dst++ = *src++;
308     *dst = '\0';
309     return front;
310 }
311
312 /*************************************************************************
313  *      StrCatBuffW             [SHLWAPI]
314  *
315  * Appends back onto front, stopping when front is size-1 characters long.
316  * Returns front.
317  *
318  */
319 LPWSTR WINAPI StrCatBuffW(LPWSTR front, LPCWSTR back, INT size)
320 {
321     LPWSTR dst = front + strlenW(front);
322     LPCWSTR src = back, end = front + size - 1;
323
324     while(dst < end && *src)
325         *dst++ = *src++;
326     *dst = '\0';
327     return front;
328 }
329
330 /*************************************************************************
331  * StrRetToBufA                                 [SHLWAPI.@]
332  * 
333  * converts a STRRET to a normal string
334  *
335  * NOTES
336  *  the pidl is for STRRET OFFSET
337  */
338 HRESULT WINAPI StrRetToBufA (LPSTRRET src, const ITEMIDLIST *pidl, LPSTR dest, DWORD len)
339 {
340         TRACE("dest=0x%p len=0x%lx strret=0x%p pidl=%p stub\n",dest,len,src,pidl);
341
342         switch (src->uType)
343         {
344           case STRRET_WSTR:
345             WideCharToMultiByte(CP_ACP, 0, src->u.pOleStr, -1, (LPSTR)dest, len, NULL, NULL);
346 /*          SHFree(src->u.pOleStr);  FIXME: is this right? */
347             break;
348
349           case STRRET_CSTRA:
350             lstrcpynA((LPSTR)dest, src->u.cStr, len);
351             break;
352
353           case STRRET_OFFSETA:
354             lstrcpynA((LPSTR)dest, ((LPCSTR)&pidl->mkid)+src->u.uOffset, len);
355             break;
356
357           default:
358             FIXME("unknown type!\n");
359             if (len)
360             {
361               *(LPSTR)dest = '\0';
362             }
363             return(FALSE);
364         }
365         return S_OK;
366 }
367
368 /*************************************************************************
369  * StrRetToBufW                                 [SHLWAPI.@]
370  * 
371  * converts a STRRET to a normal string
372  *
373  * NOTES
374  *  the pidl is for STRRET OFFSET
375  */
376 HRESULT WINAPI StrRetToBufW (LPSTRRET src, const ITEMIDLIST *pidl, LPWSTR dest, DWORD len)
377 {
378         TRACE("dest=0x%p len=0x%lx strret=0x%p pidl=%p stub\n",dest,len,src,pidl);
379
380         switch (src->uType)
381         {
382           case STRRET_WSTR:
383             lstrcpynW((LPWSTR)dest, src->u.pOleStr, len);
384 /*          SHFree(src->u.pOleStr);  FIXME: is this right? */
385             break;
386
387           case STRRET_CSTRA:
388             lstrcpynAtoW((LPWSTR)dest, src->u.cStr, len);
389             break;
390
391           case STRRET_OFFSETA:
392             if (pidl)
393             {
394               lstrcpynAtoW((LPWSTR)dest, ((LPCSTR)&pidl->mkid)+src->u.uOffset, len);
395             }
396             break;
397
398           default:
399             FIXME("unknown type!\n");
400             if (len)
401             { *(LPSTR)dest = '\0';
402             }
403             return(FALSE);
404         }
405         return S_OK;
406 }
407
408 /*************************************************************************
409  * StrFormatByteSizeA                           [SHLWAPI]
410  */
411 LPSTR WINAPI StrFormatByteSizeA ( DWORD dw, LPSTR pszBuf, UINT cchBuf )
412 {       char buf[64];
413         TRACE("%lx %p %i\n", dw, pszBuf, cchBuf);
414         if ( dw<1024L )
415         { sprintf (buf,"%3.1f bytes", (FLOAT)dw);
416         }
417         else if ( dw<1048576L)
418         { sprintf (buf,"%3.1f KB", (FLOAT)dw/1024);
419         }
420         else if ( dw < 1073741824L)
421         { sprintf (buf,"%3.1f MB", (FLOAT)dw/1048576L);
422         }
423         else
424         { sprintf (buf,"%3.1f GB", (FLOAT)dw/1073741824L);
425         }
426         lstrcpynA (pszBuf, buf, cchBuf);
427         return pszBuf;  
428 }
429
430 /*************************************************************************
431  * StrFormatByteSizeW                           [SHLWAPI]
432  */
433 LPWSTR WINAPI StrFormatByteSizeW ( DWORD dw, LPWSTR pszBuf, UINT cchBuf )
434 {       char buf[64];
435         TRACE("%lx %p %i\n", dw, pszBuf, cchBuf);
436         if ( dw<1024L )
437         { sprintf (buf,"%3.1f bytes", (FLOAT)dw);
438         }
439         else if ( dw<1048576L)
440         { sprintf (buf,"%3.1f KB", (FLOAT)dw/1024);
441         }
442         else if ( dw < 1073741824L)
443         { sprintf (buf,"%3.1f MB", (FLOAT)dw/1048576L);
444         }
445         else
446         { sprintf (buf,"%3.1f GB", (FLOAT)dw/1073741824L);
447         }
448         lstrcpynAtoW (pszBuf, buf, cchBuf);
449         return pszBuf;  
450 }
451
452 /*************************************************************************
453  *      wnsprintfA      [SHLWAPI]
454  */
455 int WINAPIV wnsprintfA(LPSTR lpOut, int cchLimitIn, LPCSTR lpFmt, ...)
456 {
457     va_list valist;
458     INT res;
459
460     va_start( valist, lpFmt );
461     res = wvsnprintfA( lpOut, cchLimitIn, lpFmt, valist );
462     va_end( valist );
463     return res;
464 }
465
466 /*************************************************************************
467  *      wnsprintfW      [SHLWAPI]
468  */
469 int WINAPIV wnsprintfW(LPWSTR lpOut, int cchLimitIn, LPCWSTR lpFmt, ...)
470 {
471     va_list valist;
472     INT res;
473
474     va_start( valist, lpFmt );
475     res = wvsnprintfW( lpOut, cchLimitIn, lpFmt, valist );
476     va_end( valist );
477     return res;
478 }