2 * NTDLL string functions
4 * Copyright 2000 Alexandre Julliard
5 * Copyright 2000 Jon Griffiths
6 * Copyright 2003 Thomas Mertes
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
32 /*********************************************************************
35 INT __cdecl NTDLL__memicmp( LPCSTR s1, LPCSTR s2, DWORD len )
40 if ((ret = tolower(*s1) - tolower(*s2))) break;
48 /*********************************************************************
51 LPSTR __cdecl _strupr( LPSTR str )
54 for ( ; *str; str++) *str = toupper(*str);
59 /*********************************************************************
62 * convert a string in place to lowercase
64 LPSTR __cdecl _strlwr( LPSTR str )
67 for ( ; *str; str++) *str = tolower(*str);
72 /*********************************************************************
75 * Converts an unsigned long integer to a string.
77 * Assigns a '\0' terminated string to str and returns str.
78 * Does not check if radix is in the range of 2 to 36 (as native DLL).
79 * For str == NULL just crashes (as native DLL).
81 char * __cdecl _ultoa( unsigned long value, char *str, int radix )
91 digit = value % radix;
92 value = value / radix;
96 *--pos = 'a' + digit - 10;
98 } while (value != 0L);
100 memcpy(str, pos, &buffer[32] - pos + 1);
105 /*********************************************************************
108 * Converts a long integer to a string.
110 * Assigns a '\0' terminated string to str and returns str. If radix
111 * is 10 and value is negative, the value is converted with sign.
112 * Does not check if radix is in the range of 2 to 36 (as native DLL).
113 * For str == NULL just crashes (as native DLL).
115 char * __cdecl _ltoa( long value, char *str, int radix )
123 if (value < 0 && radix == 10) {
138 *--pos = '0' + digit;
140 *--pos = 'a' + digit - 10;
148 memcpy(str, pos, &buffer[32] - pos + 1);
153 /*********************************************************************
156 * Converts an integer to a string.
158 * Assigns a '\0' terminated wstring to str and returns str. If radix
159 * is 10 and value is negative, the value is converted with sign.
160 * Does not check if radix is in the range of 2 to 36 (as native DLL).
161 * For str == NULL just crashes (as native DLL).
163 char * __cdecl _itoa( int value, char *str, int radix )
165 return _ltoa(value, str, radix);
169 /*********************************************************************
172 * Converts a large unsigned integer to a string.
174 * Assigns a '\0' terminated string to str and returns str.
175 * Does not check if radix is in the range of 2 to 36 (as native DLL).
176 * For str == NULL just crashes (as native DLL).
178 char * __cdecl _ui64toa( ULONGLONG value, char *str, int radix )
188 digit = value % radix;
189 value = value / radix;
191 *--pos = '0' + digit;
193 *--pos = 'a' + digit - 10;
195 } while (value != 0L);
197 memcpy(str, pos, &buffer[64] - pos + 1);
202 /*********************************************************************
205 * Converts a large integer to a string.
207 * Assigns a '\0' terminated string to str and returns str. If radix
208 * is 10 and value is negative, the value is converted with sign.
209 * Does not check if radix is in the range of 2 to 36 (as native DLL).
210 * For str == NULL just crashes (as native DLL).
213 * - The native DLL converts negative values (for base 10) wrong:
214 * -1 is converted to -18446744073709551615
215 * -2 is converted to -18446744073709551614
216 * -9223372036854775807 is converted to -9223372036854775809
217 * -9223372036854775808 is converted to -9223372036854775808
218 * The native msvcrt _i64toa function and our ntdll function do
221 char * __cdecl _i64toa( LONGLONG value, char *str, int radix )
229 if (value < 0 && radix == 10) {
244 *--pos = '0' + digit;
246 *--pos = 'a' + digit - 10;
254 memcpy(str, pos, &buffer[64] - pos + 1);
259 /*********************************************************************
262 * Converts a string to a large integer.
264 * On success it returns the integer value otherwise it returns 0.
265 * Accepts: {whitespace} [+|-] {digits}
266 * No check of overflow: Just assigns lower 64 bits (as native DLL).
267 * Does not check for str != NULL (as native DLL).
269 LONGLONG __cdecl _atoi64( char *str )
271 ULONGLONG RunningTotal = 0;
274 while (*str == ' ' || (*str >= '\011' && *str <= '\015')) {
280 } else if (*str == '-') {
285 while (*str >= '0' && *str <= '9') {
286 RunningTotal = RunningTotal * 10 + *str - '0';
290 return bMinus ? -RunningTotal : RunningTotal;
294 /*********************************************************************
295 * _splitpath (NTDLL.@)
297 void __cdecl _splitpath(const char* inpath, char * drv, char * dir,
298 char* fname, char * ext )
300 /* Modified PD code from 'snippets' collection. */
302 char pathbuff[MAX_PATH], *path=pathbuff;
304 strcpy(pathbuff, inpath);
306 /* convert slashes to backslashes for searching */
307 for (ptr = (char*)path; *ptr; ++ptr)
311 /* look for drive spec */
312 if ('\0' != (ptr = strchr(path, ':')))
317 strncpy(drv, path, ptr - path);
318 drv[ptr - path] = '\0';
325 /* find rightmost backslash or leftmost colon */
326 if (NULL == (ptr = strrchr(path, '\\')))
327 ptr = (strchr(path, ':'));
331 ptr = (char *)path; /* no path */
337 ++ptr; /* skip the delimiter */
347 if (NULL == (p = strrchr(ptr, '.')))
364 /* Fix pathological case - Win returns ':' as part of the
365 * directory when no drive letter is given.
367 if (drv && drv[0] == ':')
374 strcat(pathbuff,dir);
375 strcpy(dir,pathbuff);