Fix the case of product and company names.
[wine] / memory / string.c
1 /*
2  * String functions
3  *
4  * Copyright 1993 Yngvi Sigurjonsson
5  * Copyright 1996 Alexandre Julliard
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
21
22 #include <ctype.h>
23 #include <stdarg.h>
24 #include <string.h>
25
26 #include "ntstatus.h"
27 #include "windef.h"
28 #include "winbase.h"
29 #include "wine/winbase16.h"
30 #include "wine/exception.h"
31 #include "wine/unicode.h"
32 #include "winerror.h"
33 #include "winnls.h"
34 #include "excpt.h"
35 #include "wine/debug.h"
36
37 WINE_DEFAULT_DEBUG_CHANNEL(string);
38
39 /* filter for page-fault exceptions */
40 static WINE_EXCEPTION_FILTER(page_fault)
41 {
42     if (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION)
43         return EXCEPTION_EXECUTE_HANDLER;
44     return EXCEPTION_CONTINUE_SEARCH;
45 }
46
47
48 /***********************************************************************
49  *           hmemcpy   (KERNEL.348)
50  */
51 void WINAPI hmemcpy16( LPVOID dst, LPCVOID src, LONG count )
52 {
53     memcpy( dst, src, count );
54 }
55
56
57 /***********************************************************************
58  *           lstrcat   (KERNEL.89)
59  */
60 SEGPTR WINAPI lstrcat16( SEGPTR dst, LPCSTR src )
61 {
62     /* Windows does not check for NULL pointers here, so we don't either */
63     strcat( MapSL(dst), src );
64     return dst;
65 }
66
67
68 /***********************************************************************
69  *           lstrcat    (KERNEL32.@)
70  *           lstrcatA   (KERNEL32.@)
71  */
72 LPSTR WINAPI lstrcatA( LPSTR dst, LPCSTR src )
73 {
74     __TRY
75     {
76         strcat( dst, src );
77     }
78     __EXCEPT(page_fault)
79     {
80         SetLastError( ERROR_INVALID_PARAMETER );
81         return NULL;
82     }
83     __ENDTRY
84     return dst;
85 }
86
87
88 /***********************************************************************
89  *           lstrcatW   (KERNEL32.@)
90  */
91 LPWSTR WINAPI lstrcatW( LPWSTR dst, LPCWSTR src )
92 {
93     __TRY
94     {
95         strcatW( dst, src );
96     }
97     __EXCEPT(page_fault)
98     {
99         SetLastError( ERROR_INVALID_PARAMETER );
100         return NULL;
101     }
102     __ENDTRY
103     return dst;
104 }
105
106
107 /***********************************************************************
108  *           lstrcatn   (KERNEL.352)
109  */
110 SEGPTR WINAPI lstrcatn16( SEGPTR dst, LPCSTR src, INT16 n )
111 {
112     LPSTR p = MapSL(dst);
113     LPSTR start = p;
114
115     while (*p) p++;
116     if ((n -= (p - start)) <= 0) return dst;
117     lstrcpynA( p, src, n );
118     return dst;
119 }
120
121
122 /***********************************************************************
123  *           lstrcpy   (KERNEL.88)
124  */
125 SEGPTR WINAPI lstrcpy16( SEGPTR dst, LPCSTR src )
126 {
127     if (!lstrcpyA( MapSL(dst), src )) dst = 0;
128     return dst;
129 }
130
131
132 /***********************************************************************
133  *           lstrcpy    (KERNEL32.@)
134  *           lstrcpyA   (KERNEL32.@)
135  */
136 LPSTR WINAPI lstrcpyA( LPSTR dst, LPCSTR src )
137 {
138     __TRY
139     {
140         /* this is how Windows does it */
141         memmove( dst, src, strlen(src)+1 );
142     }
143     __EXCEPT(page_fault)
144     {
145         ERR("(%p, %p): page fault occurred ! Caused by bug ?\n", dst, src);
146         SetLastError( ERROR_INVALID_PARAMETER );
147         return NULL;
148     }
149     __ENDTRY
150     return dst;
151 }
152
153
154 /***********************************************************************
155  *           lstrcpyW   (KERNEL32.@)
156  */
157 LPWSTR WINAPI lstrcpyW( LPWSTR dst, LPCWSTR src )
158 {
159     __TRY
160     {
161         strcpyW( dst, src );
162     }
163     __EXCEPT(page_fault)
164     {
165         SetLastError( ERROR_INVALID_PARAMETER );
166         return NULL;
167     }
168     __ENDTRY
169     return dst;
170 }
171
172
173 /***********************************************************************
174  *           lstrcpyn   (KERNEL.353)
175  */
176 SEGPTR WINAPI lstrcpyn16( SEGPTR dst, LPCSTR src, INT16 n )
177 {
178     lstrcpynA( MapSL(dst), src, n );
179     return dst;
180 }
181
182
183 /***********************************************************************
184  *           lstrcpyn    (KERNEL32.@)
185  *           lstrcpynA   (KERNEL32.@)
186  *
187  * Note: this function differs from the UNIX strncpy, it _always_ writes
188  * a terminating \0.
189  *
190  * Note: n is an INT but Windows treats it as unsigned, and will happily
191  * copy a gazillion chars if n is negative.
192  */
193 LPSTR WINAPI lstrcpynA( LPSTR dst, LPCSTR src, INT n )
194 {
195     LPSTR p = dst;
196     UINT count = n;
197
198     TRACE("(%p, %s, %i)\n", dst, debugstr_a(src), n);
199
200     /* In real windows the whole function is protected by an exception handler
201      * that returns ERROR_INVALID_PARAMETER on faulty parameters
202      * We currently just check for NULL.
203      */
204     if (!dst || !src) {
205         SetLastError(ERROR_INVALID_PARAMETER);
206         return 0;
207     }
208     while ((count > 1) && *src)
209     {
210         count--;
211         *p++ = *src++;
212     }
213     if (count) *p = 0;
214     return dst;
215 }
216
217
218 /***********************************************************************
219  *           lstrcpynW   (KERNEL32.@)
220  *
221  * Note: this function differs from the UNIX strncpy, it _always_ writes
222  * a terminating \0
223  *
224  * Note: n is an INT but Windows treats it as unsigned, and will happily
225  * copy a gazillion chars if n is negative.
226  */
227 LPWSTR WINAPI lstrcpynW( LPWSTR dst, LPCWSTR src, INT n )
228 {
229     LPWSTR p = dst;
230     UINT count = n;
231
232     TRACE("(%p, %s, %i)\n", dst,  debugstr_w(src), n);
233
234     /* In real windows the whole function is protected by an exception handler
235      * that returns ERROR_INVALID_PARAMETER on faulty parameters
236      * We currently just check for NULL.
237      */
238     if (!dst || !src) {
239         SetLastError(ERROR_INVALID_PARAMETER);
240         return 0;
241     }
242     while ((count > 1) && *src)
243     {
244         count--;
245         *p++ = *src++;
246     }
247     if (count) *p = 0;
248     return dst;
249 }
250
251
252 /***********************************************************************
253  *           lstrlen   (KERNEL.90)
254  */
255 INT16 WINAPI lstrlen16( LPCSTR str )
256 {
257     return (INT16)lstrlenA( str );
258 }
259
260
261 /***********************************************************************
262  *           lstrlen    (KERNEL32.@)
263  *           lstrlenA   (KERNEL32.@)
264  */
265 INT WINAPI lstrlenA( LPCSTR str )
266 {
267     INT ret;
268     __TRY
269     {
270         ret = strlen(str);
271     }
272     __EXCEPT(page_fault)
273     {
274         SetLastError( ERROR_INVALID_PARAMETER );
275         return 0;
276     }
277     __ENDTRY
278     return ret;
279 }
280
281
282 /***********************************************************************
283  *           lstrlenW   (KERNEL32.@)
284  */
285 INT WINAPI lstrlenW( LPCWSTR str )
286 {
287     INT ret;
288     __TRY
289     {
290         ret = strlenW(str);
291     }
292     __EXCEPT(page_fault)
293     {
294         SetLastError( ERROR_INVALID_PARAMETER );
295         return 0;
296     }
297     __ENDTRY
298     return ret;
299 }
300
301
302 /***********************************************************************
303  *           UnicodeToAnsi   (KERNEL.434)
304  */
305 INT16 WINAPI UnicodeToAnsi16( LPCWSTR src, LPSTR dst, INT16 codepage )
306 {
307     if ( codepage == -1 )
308         codepage = CP_ACP;
309
310     return WideCharToMultiByte( codepage, 0, src, -1, dst, 0x7fffffff, NULL, NULL );
311 }