Release 1.5.29.
[wine] / dlls / ntdll / string.c
1 /*
2  * NTDLL string functions
3  *
4  * Copyright 2000 Alexandre Julliard
5  * Copyright 2000 Jon Griffiths
6  * Copyright 2003 Thomas Mertes
7  *
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.
12  *
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.
17  *
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21  */
22
23 #include "config.h"
24 #include "wine/port.h"
25
26 #include <ctype.h>
27 #include <stdarg.h>
28 #include <stdlib.h>
29 #include <stdio.h>
30 #include <string.h>
31
32 #include "windef.h"
33 #include "winternl.h"
34
35
36 /*********************************************************************
37  *                  memchr   (NTDLL.@)
38  */
39 void * __cdecl NTDLL_memchr( const void *ptr, int c, size_t n )
40 {
41     return memchr( ptr, c, n );
42 }
43
44
45 /*********************************************************************
46  *                  memcmp   (NTDLL.@)
47  */
48 int __cdecl NTDLL_memcmp( const void *ptr1, const void *ptr2, size_t n )
49 {
50     return memcmp( ptr1, ptr2, n );
51 }
52
53
54 /*********************************************************************
55  *                  memcpy   (NTDLL.@)
56  *
57  * NOTES
58  *  Behaves like memmove.
59  */
60 void * __cdecl NTDLL_memcpy( void *dst, const void *src, size_t n )
61 {
62     return memmove( dst, src, n );
63 }
64
65
66 /*********************************************************************
67  *                  memmove   (NTDLL.@)
68  */
69 void * __cdecl NTDLL_memmove( void *dst, const void *src, size_t n )
70 {
71     return memmove( dst, src, n );
72 }
73
74
75 /*********************************************************************
76  *                  memset   (NTDLL.@)
77  */
78 void * __cdecl NTDLL_memset( void *dst, int c, size_t n )
79 {
80     return memset( dst, c, n );
81 }
82
83
84 /*********************************************************************
85  *                  strcat   (NTDLL.@)
86  */
87 char * __cdecl NTDLL_strcat( char *dst, const char *src )
88 {
89     return strcat( dst, src );
90 }
91
92
93 /*********************************************************************
94  *                  strchr   (NTDLL.@)
95  */
96 char * __cdecl NTDLL_strchr( const char *str, int c )
97 {
98     return strchr( str, c );
99 }
100
101
102 /*********************************************************************
103  *                  strcmp   (NTDLL.@)
104  */
105 int __cdecl NTDLL_strcmp( const char *str1, const char *str2 )
106 {
107     return strcmp( str1, str2 );
108 }
109
110
111 /*********************************************************************
112  *                  strcpy   (NTDLL.@)
113  */
114 char * __cdecl NTDLL_strcpy( char *dst, const char *src )
115 {
116     return strcpy( dst, src );
117 }
118
119
120 /*********************************************************************
121  *                  strcspn   (NTDLL.@)
122  */
123 size_t __cdecl NTDLL_strcspn( const char *str, const char *reject )
124 {
125     return strcspn( str, reject );
126 }
127
128
129 /*********************************************************************
130  *                  strlen   (NTDLL.@)
131  */
132 size_t __cdecl NTDLL_strlen( const char *str )
133 {
134     return strlen( str );
135 }
136
137
138 /*********************************************************************
139  *                  strncat   (NTDLL.@)
140  */
141 char * __cdecl NTDLL_strncat( char *dst, const char *src, size_t len )
142 {
143     return strncat( dst, src, len );
144 }
145
146
147 /*********************************************************************
148  *                  strncmp   (NTDLL.@)
149  */
150 int __cdecl NTDLL_strncmp( const char *str1, const char *str2, size_t len )
151 {
152     return strncmp( str1, str2, len );
153 }
154
155
156 /*********************************************************************
157  *                  strncpy   (NTDLL.@)
158  */
159 char * __cdecl NTDLL_strncpy( char *dst, const char *src, size_t len )
160 {
161     return strncpy( dst, src, len );
162 }
163
164
165 /*********************************************************************
166  *                  strpbrk   (NTDLL.@)
167  */
168 char * __cdecl NTDLL_strpbrk( const char *str, const char *accept )
169 {
170     return strpbrk( str, accept );
171 }
172
173
174 /*********************************************************************
175  *                  strrchr   (NTDLL.@)
176  */
177 char * __cdecl NTDLL_strrchr( const char *str, int c )
178 {
179     return strrchr( str, c );
180 }
181
182
183 /*********************************************************************
184  *                  strspn   (NTDLL.@)
185  */
186 size_t __cdecl NTDLL_strspn( const char *str, const char *accept )
187 {
188     return strspn( str, accept );
189 }
190
191
192 /*********************************************************************
193  *                  strstr   (NTDLL.@)
194  */
195 char * __cdecl NTDLL_strstr( const char *haystack, const char *needle )
196 {
197     return strstr( haystack, needle );
198 }
199
200
201 /*********************************************************************
202  *                  _memccpy   (NTDLL.@)
203  */
204 void * __cdecl _memccpy( void *dst, const void *src, int c, size_t n )
205 {
206     return memccpy( dst, src, c, n );
207 }
208
209
210 /*********************************************************************
211  *                  _memicmp   (NTDLL.@)
212  *
213  * Compare two blocks of memory as strings, ignoring case.
214  *
215  * PARAMS
216  *  s1  [I] First string to compare to s2
217  *  s2  [I] Second string to compare to s1
218  *  len [I] Number of bytes to compare
219  *
220  * RETURNS
221  *  An integer less than, equal to, or greater than zero indicating that
222  *  s1 is less than, equal to or greater than s2 respectively.
223  *
224  * NOTES
225  *  Any Nul characters in s1 or s2 are ignored. This function always
226  *  compares up to len bytes or the first place where s1 and s2 differ.
227  */
228 INT __cdecl _memicmp( LPCSTR s1, LPCSTR s2, DWORD len )
229 {
230     int ret = 0;
231     while (len--)
232     {
233         if ((ret = tolower(*s1) - tolower(*s2))) break;
234         s1++;
235         s2++;
236     }
237     return ret;
238 }
239
240
241 /*********************************************************************
242  *                  _stricmp   (NTDLL.@)
243  *                  _strcmpi   (NTDLL.@)
244  */
245 int __cdecl _stricmp( LPCSTR str1, LPCSTR str2 )
246 {
247     return strcasecmp( str1, str2 );
248 }
249
250
251 /*********************************************************************
252  *                  _strnicmp   (NTDLL.@)
253  */
254 int __cdecl _strnicmp( LPCSTR str1, LPCSTR str2, size_t n )
255 {
256     return strncasecmp( str1, str2, n );
257 }
258
259
260 /*********************************************************************
261  *                  _strupr   (NTDLL.@)
262  *
263  * Convert a string to upper case.
264  *
265  * PARAMS
266  *  str [I/O] String to convert
267  *
268  * RETURNS
269  *  str. There is no error return, if str is NULL or invalid, this
270  *  function will crash.
271  */
272 LPSTR __cdecl _strupr( LPSTR str )
273 {
274     LPSTR ret = str;
275     for ( ; *str; str++) *str = toupper(*str);
276     return ret;
277 }
278
279
280 /*********************************************************************
281  *                  _strlwr   (NTDLL.@)
282  *
283  * Convert a string to lowercase
284  *
285  * PARAMS
286  *  str [I/O] String to convert
287  *
288  * RETURNS
289  *  str. There is no error return, if str is NULL or invalid, this
290  *  function will crash.
291  */
292 LPSTR __cdecl _strlwr( LPSTR str )
293 {
294     LPSTR ret = str;
295     for ( ; *str; str++) *str = tolower(*str);
296     return ret;
297 }
298
299
300 /*********************************************************************
301  *                  tolower   (NTDLL.@)
302  */
303 int __cdecl NTDLL_tolower( int c )
304 {
305     return tolower( c );
306 }
307
308
309 /*********************************************************************
310  *                  toupper   (NTDLL.@)
311  */
312 int __cdecl NTDLL_toupper( int c )
313 {
314     return toupper( c );
315 }
316
317
318 /*********************************************************************
319  *                  isalnum   (NTDLL.@)
320  */
321 int __cdecl NTDLL_isalnum( int c )
322 {
323     return isalnum( c );
324 }
325
326
327 /*********************************************************************
328  *                  isalpha   (NTDLL.@)
329  */
330 int __cdecl NTDLL_isalpha( int c )
331 {
332     return isalpha( c );
333 }
334
335
336 /*********************************************************************
337  *                  iscntrl   (NTDLL.@)
338  */
339 int __cdecl NTDLL_iscntrl( int c )
340 {
341     return iscntrl( c );
342 }
343
344
345 /*********************************************************************
346  *                  isdigit   (NTDLL.@)
347  */
348 int __cdecl NTDLL_isdigit( int c )
349 {
350     return isdigit( c );
351 }
352
353
354 /*********************************************************************
355  *                  isgraph   (NTDLL.@)
356  */
357 int __cdecl NTDLL_isgraph( int c )
358 {
359     return isgraph( c );
360 }
361
362
363 /*********************************************************************
364  *                  islower   (NTDLL.@)
365  */
366 int __cdecl NTDLL_islower( int c )
367 {
368     return islower( c );
369 }
370
371
372 /*********************************************************************
373  *                  isprint   (NTDLL.@)
374  */
375 int __cdecl NTDLL_isprint( int c )
376 {
377     return isprint( c );
378 }
379
380
381 /*********************************************************************
382  *                  ispunct   (NTDLL.@)
383  */
384 int __cdecl NTDLL_ispunct( int c )
385 {
386     return ispunct( c );
387 }
388
389
390 /*********************************************************************
391  *                  isspace   (NTDLL.@)
392  */
393 int __cdecl NTDLL_isspace( int c )
394 {
395     return isspace( c );
396 }
397
398
399 /*********************************************************************
400  *                  isupper   (NTDLL.@)
401  */
402 int __cdecl NTDLL_isupper( int c )
403 {
404     return isupper( c );
405 }
406
407
408 /*********************************************************************
409  *                  isxdigit   (NTDLL.@)
410  */
411 int __cdecl NTDLL_isxdigit( int c )
412 {
413     return isxdigit( c );
414 }
415
416
417 /*********************************************************************
418  *              __isascii (NTDLL.@)
419  */
420 int CDECL NTDLL___isascii(int c)
421 {
422     return (unsigned)c < 0x80;
423 }
424
425
426 /*********************************************************************
427  *              __toascii (NTDLL.@)
428  */
429 int CDECL NTDLL___toascii(int c)
430 {
431     return (unsigned)c & 0x7f;
432 }
433
434
435 /*********************************************************************
436  *              __iscsym (NTDLL.@)
437  */
438 int CDECL NTDLL___iscsym(int c)
439 {
440     return (c < 127 && (isalnum(c) || c == '_'));
441 }
442
443
444 /*********************************************************************
445  *              __iscsymf (NTDLL.@)
446  */
447 int CDECL NTDLL___iscsymf(int c)
448 {
449     return (c < 127 && (isalpha(c) || c == '_'));
450 }
451
452
453 /*********************************************************************
454  *              _toupper (NTDLL.@)
455  */
456 int CDECL NTDLL__toupper(int c)
457 {
458     return c - 0x20;  /* sic */
459 }
460
461
462 /*********************************************************************
463  *              _tolower (NTDLL.@)
464  */
465 int CDECL NTDLL__tolower(int c)
466 {
467     return c + 0x20;  /* sic */
468 }
469
470
471 /*********************************************************************
472  *                  strtol   (NTDLL.@)
473  */
474 LONG __cdecl NTDLL_strtol( const char *nptr, char **endptr, int base )
475 {
476     return strtol( nptr, endptr, base );
477 }
478
479
480 /*********************************************************************
481  *                  strtoul   (NTDLL.@)
482  */
483 ULONG __cdecl NTDLL_strtoul( const char *nptr, char **endptr, int base )
484 {
485     return strtoul( nptr, endptr, base );
486 }
487
488
489 /*********************************************************************
490  *      _ultoa   (NTDLL.@)
491  *
492  * Convert an unsigned long integer to a string.
493  *
494  * RETURNS
495  *  str.
496  *
497  * NOTES
498  *  - Converts value to a Nul terminated string which is copied to str.
499  *  - The maximum length of the copied str is 33 bytes.
500  *  - Does not check if radix is in the range of 2 to 36.
501  *  - If str is NULL it crashes, as the native function does.
502  */
503 char * __cdecl _ultoa(
504     ULONG value,         /* [I] Value to be converted */
505     char *str,           /* [O] Destination for the converted value */
506     int radix)           /* [I] Number base for conversion */
507 {
508     char buffer[33];
509     char *pos;
510     int digit;
511
512     pos = &buffer[32];
513     *pos = '\0';
514
515     do {
516         digit = value % radix;
517         value = value / radix;
518         if (digit < 10) {
519             *--pos = '0' + digit;
520         } else {
521             *--pos = 'a' + digit - 10;
522         } /* if */
523     } while (value != 0L);
524
525     memcpy(str, pos, &buffer[32] - pos + 1);
526     return str;
527 }
528
529
530 /*********************************************************************
531  *      _ltoa   (NTDLL.@)
532  *
533  * Convert a long integer to a string.
534  *
535  * RETURNS
536  *  str.
537  *
538  * NOTES
539  *  - Converts value to a Nul terminated string which is copied to str.
540  *  - The maximum length of the copied str is 33 bytes. If radix
541  *  is 10 and value is negative, the value is converted with sign.
542  *  - Does not check if radix is in the range of 2 to 36.
543  *  - If str is NULL it crashes, as the native function does.
544  */
545 char * __cdecl _ltoa(
546     LONG value, /* [I] Value to be converted */
547     char *str,  /* [O] Destination for the converted value */
548     int radix)  /* [I] Number base for conversion */
549 {
550     ULONG val;
551     int negative;
552     char buffer[33];
553     char *pos;
554     int digit;
555
556     if (value < 0 && radix == 10) {
557         negative = 1;
558         val = -value;
559     } else {
560         negative = 0;
561         val = value;
562     } /* if */
563
564     pos = &buffer[32];
565     *pos = '\0';
566
567     do {
568         digit = val % radix;
569         val = val / radix;
570         if (digit < 10) {
571             *--pos = '0' + digit;
572         } else {
573             *--pos = 'a' + digit - 10;
574         } /* if */
575     } while (val != 0L);
576
577     if (negative) {
578         *--pos = '-';
579     } /* if */
580
581     memcpy(str, pos, &buffer[32] - pos + 1);
582     return str;
583 }
584
585
586 /*********************************************************************
587  *      _itoa    (NTDLL.@)
588  *
589  * Converts an integer to a string.
590  *
591  * RETURNS
592  *  str.
593  *
594  * NOTES
595  *  - Converts value to a '\0' terminated string which is copied to str.
596  *  - The maximum length of the copied str is 33 bytes. If radix
597  *  is 10 and value is negative, the value is converted with sign.
598  *  - Does not check if radix is in the range of 2 to 36.
599  *  - If str is NULL it crashes, as the native function does.
600  */
601 char * __cdecl _itoa(
602     int value, /* [I] Value to be converted */
603     char *str, /* [O] Destination for the converted value */
604     int radix) /* [I] Number base for conversion */
605 {
606     return _ltoa(value, str, radix);
607 }
608
609
610 /*********************************************************************
611  *      _ui64toa   (NTDLL.@)
612  *
613  * Converts a large unsigned integer to a string.
614  *
615  * RETURNS
616  *  str.
617  *
618  * NOTES
619  *  - Converts value to a '\0' terminated string which is copied to str.
620  *  - The maximum length of the copied str is 65 bytes.
621  *  - Does not check if radix is in the range of 2 to 36.
622  *  - If str is NULL it crashes, as the native function does.
623  */
624 char * __cdecl _ui64toa(
625     ULONGLONG value, /* [I] Value to be converted */
626     char *str,       /* [O] Destination for the converted value */
627     int radix)       /* [I] Number base for conversion */
628 {
629     char buffer[65];
630     char *pos;
631     int digit;
632
633     pos = &buffer[64];
634     *pos = '\0';
635
636     do {
637         digit = value % radix;
638         value = value / radix;
639         if (digit < 10) {
640             *--pos = '0' + digit;
641         } else {
642             *--pos = 'a' + digit - 10;
643         } /* if */
644     } while (value != 0L);
645
646     memcpy(str, pos, &buffer[64] - pos + 1);
647     return str;
648 }
649
650
651 /*********************************************************************
652  *      _i64toa   (NTDLL.@)
653  *
654  * Converts a large integer to a string.
655  *
656  * RETURNS
657  *  str.
658  *
659  * NOTES
660  *  - Converts value to a Nul terminated string which is copied to str.
661  *  - The maximum length of the copied str is 65 bytes. If radix
662  *  is 10 and value is negative, the value is converted with sign.
663  *  - Does not check if radix is in the range of 2 to 36.
664  *  - If str is NULL it crashes, as the native function does.
665  *
666  * DIFFERENCES
667  * - The native DLL converts negative values (for base 10) wrong:
668  *|                     -1 is converted to -18446744073709551615
669  *|                     -2 is converted to -18446744073709551614
670  *|   -9223372036854775807 is converted to  -9223372036854775809
671  *|   -9223372036854775808 is converted to  -9223372036854775808
672  *   The native msvcrt _i64toa function and our ntdll _i64toa function
673  *   do not have this bug.
674  */
675 char * __cdecl _i64toa(
676     LONGLONG value, /* [I] Value to be converted */
677     char *str,      /* [O] Destination for the converted value */
678     int radix)      /* [I] Number base for conversion */
679 {
680     ULONGLONG val;
681     int negative;
682     char buffer[65];
683     char *pos;
684     int digit;
685
686     if (value < 0 && radix == 10) {
687         negative = 1;
688         val = -value;
689     } else {
690         negative = 0;
691         val = value;
692     } /* if */
693
694     pos = &buffer[64];
695     *pos = '\0';
696
697     do {
698         digit = val % radix;
699         val = val / radix;
700         if (digit < 10) {
701             *--pos = '0' + digit;
702         } else {
703             *--pos = 'a' + digit - 10;
704         } /* if */
705     } while (val != 0L);
706
707     if (negative) {
708         *--pos = '-';
709     } /* if */
710
711     memcpy(str, pos, &buffer[64] - pos + 1);
712     return str;
713 }
714
715
716 /*********************************************************************
717  *      _atoi64   (NTDLL.@)
718  *
719  * Convert a string to a large integer.
720  *
721  * PARAMS
722  *  str [I] String to be converted
723  *
724  * RETURNS
725  *  Success: The integer value represented by str.
726  *  Failure: 0. Note that this cannot be distinguished from a successful
727  *           return, if the string contains "0".
728  *
729  * NOTES
730  *  - Accepts: {whitespace} [+|-] {digits}
731  *  - No check is made for value overflow, only the lower 64 bits are assigned.
732  *  - If str is NULL it crashes, as the native function does.
733  */
734 LONGLONG __cdecl _atoi64( const char *str )
735 {
736     ULONGLONG RunningTotal = 0;
737     char bMinus = 0;
738
739     while (*str == ' ' || (*str >= '\011' && *str <= '\015')) {
740         str++;
741     } /* while */
742
743     if (*str == '+') {
744         str++;
745     } else if (*str == '-') {
746         bMinus = 1;
747         str++;
748     } /* if */
749
750     while (*str >= '0' && *str <= '9') {
751         RunningTotal = RunningTotal * 10 + *str - '0';
752         str++;
753     } /* while */
754
755     return bMinus ? -RunningTotal : RunningTotal;
756 }
757
758
759 /*********************************************************************
760  *                  atoi   (NTDLL.@)
761  */
762 int __cdecl NTDLL_atoi( const char *nptr )
763 {
764     return _atoi64( nptr );
765 }
766
767
768 /*********************************************************************
769  *                  atol   (NTDLL.@)
770  */
771 LONG __cdecl NTDLL_atol( const char *nptr )
772 {
773     return _atoi64( nptr );
774 }
775
776
777 /*********************************************************************
778  *                  sscanf   (NTDLL.@)
779  */
780 int __cdecl NTDLL_sscanf( const char *str, const char *format, ... )
781 {
782     int ret;
783     va_list valist;
784     va_start( valist, format );
785     ret = vsscanf( str, format, valist );
786     va_end( valist );
787     return ret;
788 }
789
790
791 /*********************************************************************
792  *              _splitpath (NTDLL.@)
793  *
794  * Split a path into its component pieces.
795  *
796  * PARAMS
797  *  inpath [I] Path to split
798  *  drv    [O] Destination for drive component (e.g. "A:"). Must be at least 3 characters.
799  *  dir    [O] Destination for directory component. Should be at least MAX_PATH characters.
800  *  fname  [O] Destination for File name component. Should be at least MAX_PATH characters.
801  *  ext    [O] Destination for file extension component. Should be at least MAX_PATH characters.
802  *
803  * RETURNS
804  *  Nothing.
805  */
806 void __cdecl _splitpath(const char* inpath, char * drv, char * dir,
807                         char* fname, char * ext )
808 {
809     const char *p, *end;
810
811     if (inpath[0] && inpath[1] == ':')
812     {
813         if (drv)
814         {
815             drv[0] = inpath[0];
816             drv[1] = inpath[1];
817             drv[2] = 0;
818         }
819         inpath += 2;
820     }
821     else if (drv) drv[0] = 0;
822
823     /* look for end of directory part */
824     end = NULL;
825     for (p = inpath; *p; p++) if (*p == '/' || *p == '\\') end = p + 1;
826
827     if (end)  /* got a directory */
828     {
829         if (dir)
830         {
831             memcpy( dir, inpath, end - inpath );
832             dir[end - inpath] = 0;
833         }
834         inpath = end;
835     }
836     else if (dir) dir[0] = 0;
837
838     /* look for extension: what's after the last dot */
839     end = NULL;
840     for (p = inpath; *p; p++) if (*p == '.') end = p;
841
842     if (!end) end = p; /* there's no extension */
843
844     if (fname)
845     {
846         memcpy( fname, inpath, end - inpath );
847         fname[end - inpath] = 0;
848     }
849     if (ext) strcpy( ext, end );
850 }