Added a few DirectInput 7 definitions and C++ fixes.
[wine.git] / memory / string.c
blob49dac0100ab4e46832d3f6169bb69b13d09b4ee4
1 /*
2 * String functions
4 * Copyright 1993 Yngvi Sigurjonsson
5 * Copyright 1996 Alexandre Julliard
6 */
8 #include <ctype.h>
9 #include <string.h>
11 #include "windef.h"
12 #include "winbase.h"
13 #include "wine/winbase16.h"
14 #include "wine/exception.h"
15 #include "wine/unicode.h"
16 #include "winerror.h"
17 #include "winnls.h"
18 #include "ldt.h"
19 #include "debugtools.h"
21 DEFAULT_DEBUG_CHANNEL(string);
23 /* filter for page-fault exceptions */
24 static WINE_EXCEPTION_FILTER(page_fault)
26 if (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION)
27 return EXCEPTION_EXECUTE_HANDLER;
28 return EXCEPTION_CONTINUE_SEARCH;
32 /***********************************************************************
33 * lstrcat16 (KERNEL.89)
35 SEGPTR WINAPI lstrcat16( SEGPTR dst, LPCSTR src )
37 /* Windows does not check for NULL pointers here, so we don't either */
38 strcat( (LPSTR)PTR_SEG_TO_LIN(dst), src );
39 return dst;
43 /***********************************************************************
44 * lstrcatA (KERNEL32.599)
46 LPSTR WINAPI lstrcatA( LPSTR dst, LPCSTR src )
48 __TRY
50 strcat( dst, src );
52 __EXCEPT(page_fault)
54 SetLastError( ERROR_INVALID_PARAMETER );
55 return NULL;
57 __ENDTRY
58 return dst;
62 /***********************************************************************
63 * lstrcatW (KERNEL32.600)
65 LPWSTR WINAPI lstrcatW( LPWSTR dst, LPCWSTR src )
67 __TRY
69 strcatW( dst, src );
71 __EXCEPT(page_fault)
73 SetLastError( ERROR_INVALID_PARAMETER );
74 return NULL;
76 __ENDTRY
77 return dst;
81 /***********************************************************************
82 * lstrcatn16 (KERNEL.352)
84 SEGPTR WINAPI lstrcatn16( SEGPTR dst, LPCSTR src, INT16 n )
86 LPSTR p = (LPSTR)PTR_SEG_TO_LIN(dst);
88 while (*p) p++;
89 if ((n -= (p - (LPSTR)PTR_SEG_TO_LIN(dst))) <= 0) return dst;
90 lstrcpynA( p, src, n );
91 return dst;
95 /***********************************************************************
96 * lstrcmpA (KERNEL.602)
98 INT WINAPI lstrcmpA( LPCSTR str1, LPCSTR str2 )
100 return CompareStringA(LOCALE_SYSTEM_DEFAULT,0,str1,-1,str2,-1) - 2 ;
104 /***********************************************************************
105 * lstrcmpW (KERNEL.603)
106 * FIXME : should call CompareStringW, when it is implemented.
107 * This implementation is not "word sort", as it should.
109 INT WINAPI lstrcmpW( LPCWSTR str1, LPCWSTR str2 )
111 TRACE("%s and %s\n",
112 debugstr_w (str1), debugstr_w (str2));
113 if (!str1 || !str2) {
114 SetLastError(ERROR_INVALID_PARAMETER);
115 return 0;
117 while (*str1 && (*str1 == *str2)) { str1++; str2++; }
118 return (INT)(*str1 - *str2);
122 /***********************************************************************
123 * lstrcmpiA (KERNEL32.605)
125 INT WINAPI lstrcmpiA( LPCSTR str1, LPCSTR str2 )
126 { TRACE("strcmpi %s and %s\n",
127 debugstr_a (str1), debugstr_a (str2));
128 return CompareStringA(LOCALE_SYSTEM_DEFAULT,NORM_IGNORECASE,str1,-1,str2,-1)-2;
132 /***********************************************************************
133 * lstrcmpiW (KERNEL32.606)
135 INT WINAPI lstrcmpiW( LPCWSTR str1, LPCWSTR str2 )
137 if (!str1 || !str2) {
138 SetLastError(ERROR_INVALID_PARAMETER);
139 return 0;
141 return strcmpiW( str1, str2 );
145 /***********************************************************************
146 * lstrcpy16 (KERNEL.88)
148 SEGPTR WINAPI lstrcpy16( SEGPTR dst, LPCSTR src )
150 if (!lstrcpyA( PTR_SEG_TO_LIN(dst), src )) dst = 0;
151 return dst;
155 /***********************************************************************
156 * lstrcpyA (KERNEL32.608)
158 LPSTR WINAPI lstrcpyA( LPSTR dst, LPCSTR src )
160 __TRY
162 /* this is how Windows does it */
163 memmove( dst, src, strlen(src)+1 );
165 __EXCEPT(page_fault)
167 ERR("(%p, %p): page fault occurred ! Caused by bug ?\n", dst, src);
168 SetLastError( ERROR_INVALID_PARAMETER );
169 return NULL;
171 __ENDTRY
172 return dst;
176 /***********************************************************************
177 * lstrcpyW (KERNEL32.609)
179 LPWSTR WINAPI lstrcpyW( LPWSTR dst, LPCWSTR src )
181 __TRY
183 strcpyW( dst, src );
185 __EXCEPT(page_fault)
187 SetLastError( ERROR_INVALID_PARAMETER );
188 return NULL;
190 __ENDTRY
191 return dst;
195 /***********************************************************************
196 * lstrcpyn16 (KERNEL.353)
198 SEGPTR WINAPI lstrcpyn16( SEGPTR dst, LPCSTR src, INT16 n )
200 lstrcpynA( (LPSTR)PTR_SEG_TO_LIN(dst), src, n );
201 return dst;
205 /***********************************************************************
206 * lstrcpynA (KERNEL32.611)
207 * Note: this function differs from the UNIX strncpy, it _always_ writes
208 * a terminating \0
210 LPSTR WINAPI lstrcpynA( LPSTR dst, LPCSTR src, INT n )
212 LPSTR p = dst;
213 TRACE("(%p, %s, %i)\n", dst, debugstr_an(src,n), n);
214 /* In real windows the whole function is protected by an exception handler
215 * that returns ERROR_INVALID_PARAMETER on faulty parameters
216 * We currently just check for NULL.
218 if (!dst || !src) {
219 SetLastError(ERROR_INVALID_PARAMETER);
220 return 0;
222 while ((n-- > 1) && *src) *p++ = *src++;
223 if (n >= 0) *p = 0;
224 return dst;
228 /***********************************************************************
229 * lstrcpynW (KERNEL32.612)
230 * Note: this function differs from the UNIX strncpy, it _always_ writes
231 * a terminating \0
233 LPWSTR WINAPI lstrcpynW( LPWSTR dst, LPCWSTR src, INT n )
235 LPWSTR p = dst;
236 TRACE("(%p, %s, %i)\n", dst, debugstr_wn(src,n), n);
237 /* In real windows the whole function is protected by an exception handler
238 * that returns ERROR_INVALID_PARAMETER on faulty parameters
239 * We currently just check for NULL.
241 if (!dst || !src) {
242 SetLastError(ERROR_INVALID_PARAMETER);
243 return 0;
245 while ((n-- > 1) && *src) *p++ = *src++;
246 if (n >= 0) *p = 0;
247 return dst;
251 /***********************************************************************
252 * lstrlen16 (KERNEL.90)
254 INT16 WINAPI lstrlen16( LPCSTR str )
256 return (INT16)lstrlenA( str );
260 /***********************************************************************
261 * lstrlenA (KERNEL32.614)
263 INT WINAPI lstrlenA( LPCSTR str )
265 INT ret;
266 __TRY
268 ret = strlen(str);
270 __EXCEPT(page_fault)
272 SetLastError( ERROR_INVALID_PARAMETER );
273 return 0;
275 __ENDTRY
276 return ret;
280 /***********************************************************************
281 * lstrlenW (KERNEL32.615)
283 INT WINAPI lstrlenW( LPCWSTR str )
285 INT ret;
286 __TRY
288 ret = strlenW(str);
290 __EXCEPT(page_fault)
292 SetLastError( ERROR_INVALID_PARAMETER );
293 return 0;
295 __ENDTRY
296 return ret;
300 /***********************************************************************
301 * lstrcpynAtoW (Not a Windows API)
302 * Note: this function differs from the UNIX strncpy, it _always_ writes
303 * a terminating \0
305 LPWSTR WINAPI lstrcpynAtoW( LPWSTR dst, LPCSTR src, INT n )
307 if (n > 0 && !MultiByteToWideChar( CP_ACP, 0, src, -1, dst, n )) dst[n-1] = 0;
308 return dst;
312 /***********************************************************************
313 * lstrcpynWtoA (Not a Windows API)
314 * Note: this function differs from the UNIX strncpy, it _always_ writes
315 * a terminating \0
317 * The terminating zero should be written at the end of the string, not
318 * the end of the buffer, as some programs specify the wrong size for
319 * the buffer (eg. winnt's sol.exe)
321 LPSTR WINAPI lstrcpynWtoA( LPSTR dst, LPCWSTR src, INT n )
323 if (n > 0 && !WideCharToMultiByte( CP_ACP, 0, src, -1, dst, n, NULL, NULL )) dst[n-1] = 0;
324 return dst;
327 /***********************************************************************
328 * UnicodeToAnsi (KERNEL.434)
330 INT16 WINAPI UnicodeToAnsi16( LPCWSTR src, LPSTR dst, INT16 codepage )
332 if ( codepage == -1 )
333 codepage = CP_ACP;
335 return WideCharToMultiByte( codepage, 0, src, -1, dst, 0x7fffffff, NULL, NULL );