blob: 6d4bbae1f9004d0ab4024106f63523b89b126ac2 [file] [log] [blame]
Alexandre Julliardd90840e1996-06-11 16:02:08 +00001/*
2 * String functions
3 *
4 * Copyright 1993 Yngvi Sigurjonsson
5 * Copyright 1996 Alexandre Julliard
Alexandre Julliard0799c1a2002-03-09 23:29:33 +00006 *
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
Alexandre Julliardd90840e1996-06-11 16:02:08 +000020 */
21
22#include <ctype.h>
23#include <string.h>
Patrik Stridvallfdcfdb91999-06-12 14:55:11 +000024
Jeremy Whited3e22d92000-02-10 19:03:02 +000025#include "windef.h"
26#include "winbase.h"
Patrik Stridvallfdcfdb91999-06-12 14:55:11 +000027#include "wine/winbase16.h"
Alexandre Julliard7147e4c1999-08-08 18:52:14 +000028#include "wine/exception.h"
Alexandre Julliard261abcd2000-06-12 01:16:11 +000029#include "wine/unicode.h"
Alexandre Julliard77b99181997-09-14 17:17:23 +000030#include "winerror.h"
Alexandre Julliard3850c1a2000-08-06 02:42:46 +000031#include "winnls.h"
Peter Hunnisett73ab6492002-02-25 20:10:35 +000032#include "msvcrt/excpt.h"
Alexandre Julliard0799c1a2002-03-09 23:29:33 +000033#include "wine/debug.h"
Alexandre Julliardd90840e1996-06-11 16:02:08 +000034
Alexandre Julliard0799c1a2002-03-09 23:29:33 +000035WINE_DEFAULT_DEBUG_CHANNEL(string);
Patrik Stridvallb4b9fae1999-04-19 14:56:29 +000036
Alexandre Julliard7147e4c1999-08-08 18:52:14 +000037/* filter for page-fault exceptions */
38static WINE_EXCEPTION_FILTER(page_fault)
39{
40 if (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION)
41 return EXCEPTION_EXECUTE_HANDLER;
42 return EXCEPTION_CONTINUE_SEARCH;
43}
Alexandre Julliard0c0e3be1998-12-10 15:49:22 +000044
Alexandre Julliardd90840e1996-06-11 16:02:08 +000045
46/***********************************************************************
Patrik Stridvall01d5e5b2001-07-02 19:59:40 +000047 * hmemcpy (KERNEL.348)
Alexandre Julliard350c04b2000-08-25 22:00:06 +000048 */
49void WINAPI hmemcpy16( LPVOID dst, LPCVOID src, LONG count )
50{
51 memcpy( dst, src, count );
52}
53
54
55/***********************************************************************
Patrik Stridvall01d5e5b2001-07-02 19:59:40 +000056 * lstrcat (KERNEL.89)
Alexandre Julliardd90840e1996-06-11 16:02:08 +000057 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +000058SEGPTR WINAPI lstrcat16( SEGPTR dst, LPCSTR src )
Alexandre Julliardd90840e1996-06-11 16:02:08 +000059{
Alexandre Julliard7147e4c1999-08-08 18:52:14 +000060 /* Windows does not check for NULL pointers here, so we don't either */
Alexandre Julliard982a2232000-12-13 20:20:09 +000061 strcat( MapSL(dst), src );
Alexandre Julliardd90840e1996-06-11 16:02:08 +000062 return dst;
63}
64
65
66/***********************************************************************
Patrik Stridvall044855c2001-07-11 18:56:41 +000067 * lstrcat (KERNEL32.@)
Patrik Stridvalldae8de62001-06-13 20:13:18 +000068 * lstrcatA (KERNEL32.@)
Alexandre Julliardd90840e1996-06-11 16:02:08 +000069 */
Alexandre Julliarda3960291999-02-26 11:11:13 +000070LPSTR WINAPI lstrcatA( LPSTR dst, LPCSTR src )
Alexandre Julliardd90840e1996-06-11 16:02:08 +000071{
Alexandre Julliard7147e4c1999-08-08 18:52:14 +000072 __TRY
73 {
74 strcat( dst, src );
75 }
76 __EXCEPT(page_fault)
77 {
78 SetLastError( ERROR_INVALID_PARAMETER );
79 return NULL;
80 }
81 __ENDTRY
Alexandre Julliardd90840e1996-06-11 16:02:08 +000082 return dst;
83}
84
85
86/***********************************************************************
Patrik Stridvalldae8de62001-06-13 20:13:18 +000087 * lstrcatW (KERNEL32.@)
Alexandre Julliardd90840e1996-06-11 16:02:08 +000088 */
Alexandre Julliarda3960291999-02-26 11:11:13 +000089LPWSTR WINAPI lstrcatW( LPWSTR dst, LPCWSTR src )
Alexandre Julliardd90840e1996-06-11 16:02:08 +000090{
Alexandre Julliard7147e4c1999-08-08 18:52:14 +000091 __TRY
92 {
Alexandre Julliard261abcd2000-06-12 01:16:11 +000093 strcatW( dst, src );
Alexandre Julliard7147e4c1999-08-08 18:52:14 +000094 }
95 __EXCEPT(page_fault)
96 {
97 SetLastError( ERROR_INVALID_PARAMETER );
98 return NULL;
99 }
100 __ENDTRY
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000101 return dst;
102}
103
104
105/***********************************************************************
Patrik Stridvall01d5e5b2001-07-02 19:59:40 +0000106 * lstrcatn (KERNEL.352)
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000107 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000108SEGPTR WINAPI lstrcatn16( SEGPTR dst, LPCSTR src, INT16 n )
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000109{
Alexandre Julliard982a2232000-12-13 20:20:09 +0000110 LPSTR p = MapSL(dst);
111 LPSTR start = p;
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000112
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000113 while (*p) p++;
Alexandre Julliard982a2232000-12-13 20:20:09 +0000114 if ((n -= (p - start)) <= 0) return dst;
Alexandre Julliarda3960291999-02-26 11:11:13 +0000115 lstrcpynA( p, src, n );
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000116 return dst;
117}
118
119
120/***********************************************************************
Patrik Stridvall044855c2001-07-11 18:56:41 +0000121 * lstrcmp (KERNEL32.@)
122 * lstrcmpA (KERNEL32.@)
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000123 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000124INT WINAPI lstrcmpA( LPCSTR str1, LPCSTR str2 )
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000125{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000126 return CompareStringA(LOCALE_SYSTEM_DEFAULT,0,str1,-1,str2,-1) - 2 ;
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000127}
128
129
130/***********************************************************************
Patrik Stridvall044855c2001-07-11 18:56:41 +0000131 * lstrcmpW (KERNEL32.@)
Patrik Stridvall2d6457c2000-03-28 20:22:59 +0000132 * FIXME : should call CompareStringW, when it is implemented.
Alexandre Julliardf90efa91998-06-14 15:24:15 +0000133 * This implementation is not "word sort", as it should.
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000134 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000135INT WINAPI lstrcmpW( LPCWSTR str1, LPCWSTR str2 )
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000136{
Francois Gougete73b8b81999-12-26 00:40:37 +0000137 TRACE("%s and %s\n",
Alexandre Julliarda0b2b1d1997-11-16 17:38:29 +0000138 debugstr_w (str1), debugstr_w (str2));
Alexandre Julliard77b99181997-09-14 17:17:23 +0000139 if (!str1 || !str2) {
140 SetLastError(ERROR_INVALID_PARAMETER);
141 return 0;
142 }
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000143 while (*str1 && (*str1 == *str2)) { str1++; str2++; }
Alexandre Julliarda3960291999-02-26 11:11:13 +0000144 return (INT)(*str1 - *str2);
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000145}
146
147
148/***********************************************************************
Patrik Stridvalle9782fa2001-07-12 22:33:51 +0000149 * lstrcmpi (KERNEL32.@)
Patrik Stridvalldae8de62001-06-13 20:13:18 +0000150 * lstrcmpiA (KERNEL32.@)
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000151 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000152INT WINAPI lstrcmpiA( LPCSTR str1, LPCSTR str2 )
Alexandre Julliard15657091999-05-23 10:25:25 +0000153{ TRACE("strcmpi %s and %s\n",
Alexandre Julliarda0b2b1d1997-11-16 17:38:29 +0000154 debugstr_a (str1), debugstr_a (str2));
Alexandre Julliarda3960291999-02-26 11:11:13 +0000155 return CompareStringA(LOCALE_SYSTEM_DEFAULT,NORM_IGNORECASE,str1,-1,str2,-1)-2;
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000156}
157
158
159/***********************************************************************
Patrik Stridvalldae8de62001-06-13 20:13:18 +0000160 * lstrcmpiW (KERNEL32.@)
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000161 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000162INT WINAPI lstrcmpiW( LPCWSTR str1, LPCWSTR str2 )
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000163{
Alexandre Julliard77b99181997-09-14 17:17:23 +0000164 if (!str1 || !str2) {
165 SetLastError(ERROR_INVALID_PARAMETER);
166 return 0;
167 }
Alexandre Julliard261abcd2000-06-12 01:16:11 +0000168 return strcmpiW( str1, str2 );
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000169}
170
171
172/***********************************************************************
Patrik Stridvall01d5e5b2001-07-02 19:59:40 +0000173 * lstrcpy (KERNEL.88)
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000174 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000175SEGPTR WINAPI lstrcpy16( SEGPTR dst, LPCSTR src )
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000176{
Alexandre Julliard982a2232000-12-13 20:20:09 +0000177 if (!lstrcpyA( MapSL(dst), src )) dst = 0;
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000178 return dst;
179}
180
181
182/***********************************************************************
Patrik Stridvall044855c2001-07-11 18:56:41 +0000183 * lstrcpy (KERNEL32.@)
Patrik Stridvalldae8de62001-06-13 20:13:18 +0000184 * lstrcpyA (KERNEL32.@)
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000185 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000186LPSTR WINAPI lstrcpyA( LPSTR dst, LPCSTR src )
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000187{
Alexandre Julliard7147e4c1999-08-08 18:52:14 +0000188 __TRY
189 {
190 /* this is how Windows does it */
191 memmove( dst, src, strlen(src)+1 );
Marcus Meissnera6af1f71999-01-30 15:48:18 +0000192 }
Alexandre Julliard7147e4c1999-08-08 18:52:14 +0000193 __EXCEPT(page_fault)
194 {
Andreas Mohr3c506fa2000-03-19 14:20:28 +0000195 ERR("(%p, %p): page fault occurred ! Caused by bug ?\n", dst, src);
Alexandre Julliard7147e4c1999-08-08 18:52:14 +0000196 SetLastError( ERROR_INVALID_PARAMETER );
197 return NULL;
198 }
199 __ENDTRY
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000200 return dst;
201}
202
203
204/***********************************************************************
Patrik Stridvalldae8de62001-06-13 20:13:18 +0000205 * lstrcpyW (KERNEL32.@)
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000206 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000207LPWSTR WINAPI lstrcpyW( LPWSTR dst, LPCWSTR src )
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000208{
Alexandre Julliard7147e4c1999-08-08 18:52:14 +0000209 __TRY
210 {
Alexandre Julliard261abcd2000-06-12 01:16:11 +0000211 strcpyW( dst, src );
Marcus Meissnera6af1f71999-01-30 15:48:18 +0000212 }
Alexandre Julliard7147e4c1999-08-08 18:52:14 +0000213 __EXCEPT(page_fault)
214 {
215 SetLastError( ERROR_INVALID_PARAMETER );
216 return NULL;
217 }
218 __ENDTRY
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000219 return dst;
220}
221
222
223/***********************************************************************
Patrik Stridvall01d5e5b2001-07-02 19:59:40 +0000224 * lstrcpyn (KERNEL.353)
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000225 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000226SEGPTR WINAPI lstrcpyn16( SEGPTR dst, LPCSTR src, INT16 n )
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000227{
Alexandre Julliard982a2232000-12-13 20:20:09 +0000228 lstrcpynA( MapSL(dst), src, n );
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000229 return dst;
230}
231
232
233/***********************************************************************
Patrik Stridvalle9782fa2001-07-12 22:33:51 +0000234 * lstrcpyn (KERNEL32.@)
Patrik Stridvalldae8de62001-06-13 20:13:18 +0000235 * lstrcpynA (KERNEL32.@)
Patrik Stridvalle9782fa2001-07-12 22:33:51 +0000236 *
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000237 * Note: this function differs from the UNIX strncpy, it _always_ writes
238 * a terminating \0
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000239 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000240LPSTR WINAPI lstrcpynA( LPSTR dst, LPCSTR src, INT n )
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000241{
242 LPSTR p = dst;
Francois Gougete73b8b81999-12-26 00:40:37 +0000243 TRACE("(%p, %s, %i)\n", dst, debugstr_an(src,n), n);
Marcus Meissnera6af1f71999-01-30 15:48:18 +0000244 /* In real windows the whole function is protected by an exception handler
245 * that returns ERROR_INVALID_PARAMETER on faulty parameters
246 * We currently just check for NULL.
247 */
248 if (!dst || !src) {
249 SetLastError(ERROR_INVALID_PARAMETER);
250 return 0;
251 }
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000252 while ((n-- > 1) && *src) *p++ = *src++;
Alexandre Julliard3db94ef1997-09-28 17:43:24 +0000253 if (n >= 0) *p = 0;
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000254 return dst;
255}
256
257
258/***********************************************************************
Patrik Stridvalldae8de62001-06-13 20:13:18 +0000259 * lstrcpynW (KERNEL32.@)
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000260 * Note: this function differs from the UNIX strncpy, it _always_ writes
261 * a terminating \0
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000262 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000263LPWSTR WINAPI lstrcpynW( LPWSTR dst, LPCWSTR src, INT n )
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000264{
265 LPWSTR p = dst;
Francois Gougete73b8b81999-12-26 00:40:37 +0000266 TRACE("(%p, %s, %i)\n", dst, debugstr_wn(src,n), n);
Marcus Meissnera6af1f71999-01-30 15:48:18 +0000267 /* In real windows the whole function is protected by an exception handler
268 * that returns ERROR_INVALID_PARAMETER on faulty parameters
269 * We currently just check for NULL.
270 */
271 if (!dst || !src) {
272 SetLastError(ERROR_INVALID_PARAMETER);
273 return 0;
274 }
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000275 while ((n-- > 1) && *src) *p++ = *src++;
Alexandre Julliard3db94ef1997-09-28 17:43:24 +0000276 if (n >= 0) *p = 0;
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000277 return dst;
278}
279
280
281/***********************************************************************
Patrik Stridvall01d5e5b2001-07-02 19:59:40 +0000282 * lstrlen (KERNEL.90)
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000283 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000284INT16 WINAPI lstrlen16( LPCSTR str )
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000285{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000286 return (INT16)lstrlenA( str );
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000287}
288
289
290/***********************************************************************
Patrik Stridvall044855c2001-07-11 18:56:41 +0000291 * lstrlen (KERNEL32.@)
Patrik Stridvalldae8de62001-06-13 20:13:18 +0000292 * lstrlenA (KERNEL32.@)
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000293 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000294INT WINAPI lstrlenA( LPCSTR str )
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000295{
Alexandre Julliard7147e4c1999-08-08 18:52:14 +0000296 INT ret;
297 __TRY
298 {
299 ret = strlen(str);
300 }
301 __EXCEPT(page_fault)
302 {
303 SetLastError( ERROR_INVALID_PARAMETER );
304 return 0;
305 }
306 __ENDTRY
307 return ret;
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000308}
309
310
311/***********************************************************************
Patrik Stridvalldae8de62001-06-13 20:13:18 +0000312 * lstrlenW (KERNEL32.@)
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000313 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000314INT WINAPI lstrlenW( LPCWSTR str )
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000315{
Alexandre Julliard7147e4c1999-08-08 18:52:14 +0000316 INT ret;
317 __TRY
318 {
Alexandre Julliard261abcd2000-06-12 01:16:11 +0000319 ret = strlenW(str);
Alexandre Julliard7147e4c1999-08-08 18:52:14 +0000320 }
321 __EXCEPT(page_fault)
322 {
323 SetLastError( ERROR_INVALID_PARAMETER );
324 return 0;
325 }
326 __ENDTRY
327 return ret;
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000328}
329
330
331/***********************************************************************
Ulrich Weigand16bdc251999-02-02 10:27:31 +0000332 * UnicodeToAnsi (KERNEL.434)
333 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000334INT16 WINAPI UnicodeToAnsi16( LPCWSTR src, LPSTR dst, INT16 codepage )
Ulrich Weigand16bdc251999-02-02 10:27:31 +0000335{
Dmitry Timoshkov73c32e72000-06-18 17:18:18 +0000336 if ( codepage == -1 )
337 codepage = CP_ACP;
Ulrich Weigand16bdc251999-02-02 10:27:31 +0000338
Dmitry Timoshkov73c32e72000-06-18 17:18:18 +0000339 return WideCharToMultiByte( codepage, 0, src, -1, dst, 0x7fffffff, NULL, NULL );
Ulrich Weigand16bdc251999-02-02 10:27:31 +0000340}