12 *wcsstr.c - search for one wide-character string inside another
14 * Copyright (c) Microsoft Corporation. All rights reserved.
17 * defines wcsstr() - search for one wchar_t string inside another
19 *******************************************************************************/
22 *wchar_t *wcsstr(string1, string2) - search for string2 in string1
26 * finds the first occurrence of string2 in string1 (wide strings)
29 * wchar_t *string1 - string to search in
30 * wchar_t *string2 - string to search for
33 * returns a pointer to the first occurrence of string2 in
34 * string1, or NULL if string2 does not occur in string1
40 *******************************************************************************/
42 _CONST_RETURN
wchar_t * __cdecl
wcsstr(const wchar_t * wcs1
,
43 const wchar_t * wcs2
) {
44 wchar_t *cp
= (wchar_t *) wcs1
;
48 return (wchar_t *)wcs1
;
53 s2
= (wchar_t *) wcs2
;
55 while (*s1
&& *s2
&& !(*s1
-*s2
))
68 *wcsrchr.c - find last occurrence of wchar_t character in wide string
70 * Copyright (c) Microsoft Corporation. All rights reserved.
73 * defines wcsrchr() - find the last occurrence of a given character
74 * in a string (wide-characters).
76 *******************************************************************************/
79 *wchar_t *wcsrchr(string, ch) - find last occurrence of ch in wide string
82 * Finds the last occurrence of ch in string. The terminating
83 * null character is used as part of the search (wide-characters).
86 * wchar_t *string - string to search in
87 * wchar_t ch - character to search for
90 * returns a pointer to the last occurrence of ch in the given
92 * returns NULL if ch does not occurr in the string
96 *******************************************************************************/
98 _CONST_RETURN
wchar_t * __cdecl
wcsrchr(const wchar_t * string
, wchar_t ch
) {
99 wchar_t *start
= (wchar_t *)string
;
101 while (*string
++) /* find end of string */
103 /* search towards front */
104 while (--string
!= start
&& *string
!= (wchar_t)ch
)
107 if (*string
== (wchar_t)ch
) /* wchar_t found ? */
108 return( (wchar_t *)string
);
114 *wcschr.c - search a wchar_t string for a given wchar_t character
116 * Copyright (c) Microsoft Corporation. All rights reserved.
119 * defines wcschr() - search a wchar_t string for a wchar_t character
121 *******************************************************************************/
124 *wchar_t *wcschr(string, c) - search a string for a wchar_t character
127 * Searches a wchar_t string for a given wchar_t character,
128 * which may be the null character L'\0'.
131 * wchar_t *string - wchar_t string to search in
132 * wchar_t c - wchar_t character to search for
135 * returns pointer to the first occurence of c in string
136 * returns NULL if c does not occur in string
140 *******************************************************************************/
142 _CONST_RETURN
wchar_t * __cdecl
wcschr(const wchar_t * string
, wchar_t ch
) {
143 while (*string
&& *string
!= (wchar_t)ch
)
146 if (*string
== (wchar_t)ch
)
147 return((wchar_t *)string
);
152 *xtoa.c - convert integers/longs to ASCII string
154 * Copyright (c) Microsoft Corporation. All rights reserved.
157 * The module has code to convert integers/longs to ASCII strings. See
159 *******************************************************************************/
162 *char *_itoa, *_ltoa, *_ultoa(val, buf, radix) - convert binary int to ASCII
166 * Converts an int to a character string.
169 * val - number to be converted (int, long or unsigned long)
170 * int radix - base to convert into
171 * char *buf - ptr to buffer to place result
174 * fills in space pointed to by buf with string result
175 * returns a pointer to this buffer
179 *******************************************************************************/
181 /* helper routine that does the main job. */
183 static void __cdecl
xtoa(unsigned long val
, char *buf
, unsigned radix
, int is_neg
) {
184 char *p
; /* pointer to traverse string */
185 char *firstdig
; /* pointer to first digit */
186 char temp
; /* temp char */
187 unsigned digval
; /* value of digit */
192 /* negative, so output '-' and negate */
194 val
= (unsigned long)(-(long)val
);
197 firstdig
= p
; /* save pointer to first digit */
200 digval
= (unsigned) (val
% radix
);
201 val
/= radix
; /* get next digit */
203 /* convert to ascii and store */
205 *p
++ = (char) (digval
- 10 + 'a'); /* a letter */
207 *p
++ = (char) (digval
+ '0'); /* a digit */
210 /* We now have the digit of the number in the buffer, but in reverse
211 order. Thus we reverse them now. */
213 *p
-- = '\0'; /* terminate string; p points to last digit */
218 *firstdig
= temp
; /* swap *p and *firstdig */
220 ++firstdig
; /* advance to next two digits */
221 } while (firstdig
< p
); /* repeat until halfway */
224 /* Actual functions just call conversion helper with neg flag set correctly,
225 and return pointer to buffer. */
227 char * __cdecl
_itoa(int val
, char *buf
, int radix
) {
228 if (radix
== 10 && val
< 0)
229 xtoa((unsigned long)val
, buf
, radix
, 1);
231 xtoa((unsigned long)(unsigned int)val
, buf
, radix
, 0);
236 *strlen.c - contains strlen() routine
238 * Copyright (c) Microsoft Corporation. All rights reserved.
241 * strlen returns the length of a null-terminated string,
242 * not including the null byte itself.
244 *******************************************************************************/
247 #pragma function(strlen)
248 #endif /* _MSC_VER */
251 *strlen - return the length of a null-terminated string
254 * Finds the length in bytes of the given string, not including
255 * the final null character.
258 * const char * str - string whose length is to be computed
261 * length of the string "str", exclusive of the final null byte
265 *******************************************************************************/
267 size_t __cdecl
strlen(const char * str
) {
268 const char *eos
= str
;
272 return( (int)(eos
- str
- 1) );
275 size_t __cdecl
strnlen(const char *str
, size_t maxsize
) {
280 *wcsncpy.c - copy at most n characters of wide-character string
282 * Copyright (c) Microsoft Corporation. All rights reserved.
285 * defines wcsncpy() - copy at most n characters of wchar_t string
287 *******************************************************************************/
290 *wchar_t *wcsncpy(dest, source, count) - copy at most n wide characters
293 * Copies count characters from the source string to the
294 * destination. If count is less than the length of source,
295 * NO NULL CHARACTER is put onto the end of the copied string.
296 * If count is greater than the length of sources, dest is padded
297 * with null characters to length count (wide-characters).
301 * wchar_t *dest - pointer to destination
302 * wchar_t *source - source string for copy
303 * size_t count - max number of characters to copy
310 *******************************************************************************/
312 wchar_t * __cdecl
wcsncpy(wchar_t * dest
, const wchar_t * source
, size_t count
) {
313 wchar_t *start
= dest
;
315 while (count
&& (*dest
++ = *source
++)) /* copy string */
318 if (count
) /* pad out with zeroes */
326 *wcscmp.c - routine to compare two wchar_t strings (for equal, less, or greater)
328 * Copyright (c) Microsoft Corporation. All rights reserved.
331 * Compares two wide-character strings, determining their lexical order.
333 *******************************************************************************/
336 *wcscmp - compare two wchar_t strings,
337 * returning less than, equal to, or greater than
340 * wcscmp compares two wide-character strings and returns an integer
341 * to indicate whether the first is less than the second, the two are
342 * equal, or whether the first is greater than the second.
344 * Comparison is done wchar_t by wchar_t on an UNSIGNED basis, which is to
345 * say that Null wchar_t(0) is less than any other character.
348 * const wchar_t * src - string for left-hand side of comparison
349 * const wchar_t * dst - string for right-hand side of comparison
352 * returns -1 if src < dst
353 * returns 0 if src == dst
354 * returns +1 if src > dst
358 *******************************************************************************/
359 #pragma function(wcscmp)
360 int __cdecl
wcscmp(const wchar_t * src
, const wchar_t * dst
) {
363 while (! (ret
= (int)(*src
- *dst
)) && *dst
)
375 *wcslen.c - contains wcslen() routine
377 * Copyright (c) Microsoft Corporation. All rights reserved.
380 * wcslen returns the length of a null-terminated wide-character string,
381 * not including the null wchar_t itself.
383 *******************************************************************************/
386 *wcslen - return the length of a null-terminated wide-character string
389 * Finds the length in wchar_t's of the given string, not including
390 * the final null wchar_t (wide-characters).
393 * const wchar_t * wcs - string whose length is to be computed
396 * length of the string "wcs", exclusive of the final null wchar_t
400 *******************************************************************************/
401 #pragma function(wcslen)
402 size_t __cdecl
wcslen(
405 const wchar_t *eos
= wcs
;
409 return( (size_t)(eos
- wcs
- 1) );
413 *strstr.c - search for one string inside another
415 * Copyright (c) Microsoft Corporation. All rights reserved.
418 * defines strstr() - search for one string inside another
420 *******************************************************************************/
423 *char *strstr(string1, string2) - search for string2 in string1
426 * finds the first occurrence of string2 in string1
429 * char *string1 - string to search in
430 * char *string2 - string to search for
433 * returns a pointer to the first occurrence of string2 in
434 * string1, or NULL if string2 does not occur in string1
440 *******************************************************************************/
442 _CONST_RETURN
char * __cdecl
strstr(
446 char *cp
= (char *) str1
;
450 return((char *)str1
);
457 while (*s1
&& *s2
&& !(*s1
-*s2
))
471 *strcmp.c - routine to compare two strings (for equal, less, or greater)
473 * Copyright (c) Microsoft Corporation. All rights reserved.
476 * Compares two string, determining their lexical order.
478 *******************************************************************************/
481 #pragma function(strcmp)
482 #endif /* _MSC_VER */
485 *strcmp - compare two strings, returning less than, equal to, or greater than
488 * STRCMP compares two strings and returns an integer
489 * to indicate whether the first is less than the second, the two are
490 * equal, or whether the first is greater than the second.
492 * Comparison is done byte by byte on an UNSIGNED basis, which is to
493 * say that Null (0) is less than any other character (1-255).
496 * const char * src - string for left-hand side of comparison
497 * const char * dst - string for right-hand side of comparison
500 * returns -1 if src < dst
501 * returns 0 if src == dst
502 * returns +1 if src > dst
506 *******************************************************************************/
514 while (! (ret
= *(unsigned char *)src
- *(unsigned char *)dst
) && *dst
)
527 #pragma function(strcpy)
528 #endif /* _MSC_VER */
532 *char *strcpy(dst, src) - copy one string over another
535 * Copies the string src into the spot specified by
536 * dest; assumes enough room.
539 * char * dst - string over which "src" is to be copied
540 * const char * src - string to be copied over "dst"
543 * The address of "dst"
546 *******************************************************************************/
548 char * __cdecl
strcpy(char * dst
, const char * src
) {
551 while (*cp
++ = *src
++)
552 ; /* Copy src over dst */
557 errno_t __cdecl
strcpy_s(char * dst
, size_t num_bytes
, const char * src
) {
558 #pragma warning(push)
559 #pragma warning(disable : 4996)
560 // 4996: 'function' was declared deprecated
569 *strncmp.c - compare first n characters of two strings
571 * Copyright (c) Microsoft Corporation. All rights reserved.
574 * defines strncmp() - compare first n characters of two strings
577 *******************************************************************************/
580 *int strncmp(first, last, count) - compare first count chars of strings
583 * Compares two strings for lexical order. The comparison stops
584 * after: (1) a difference between the strings is found, (2) the end
585 * of the strings is reached, or (3) count characters have been
589 * char *first, *last - strings to compare
590 * unsigned count - maximum number of characters to compare
593 * returns <0 if first < last
594 * returns 0 if first == last
595 * returns >0 if first > last
599 *******************************************************************************/
609 while (--count
&& *first
&& *first
== *last
)
615 return( *(unsigned char *)first
- *(unsigned char *)last
);
619 *strchr.c - search a string for a given character
621 * Copyright (c) Microsoft Corporation. All rights reserved.
624 * defines strchr() - search a string for a character
626 *******************************************************************************/
629 *char *strchr(string, c) - search a string for a character
632 * Searches a string for a given character, which may be the
633 * null character '\0'.
636 * char *string - string to search in
637 * char c - character to search for
640 * returns pointer to the first occurence of c in string
641 * returns NULL if c does not occur in string
645 *******************************************************************************/
647 _CONST_RETURN
char * __cdecl
strchr(
651 while (*string
&& *string
!= (char)ch
)
654 if (*string
== (char)ch
)
655 return((char *)string
);
660 *wcsncmp.c - compare first n characters of two wide-character strings
662 * Copyright (c) Microsoft Corporation. All rights reserved.
665 * defines wcsncmp() - compare first n characters of two wchar_t strings
668 *******************************************************************************/
671 *int wcsncmp(first, last, count) - compare first count chars of wchar_t strings
674 * Compares two strings for lexical order. The comparison stops
675 * after: (1) a difference between the strings is found, (2) the end
676 * of the strings is reached, or (3) count characters have been
677 * compared (wide-character strings).
680 * wchar_t *first, *last - strings to compare
681 * size_t count - maximum number of characters to compare
684 * returns <0 if first < last
685 * returns 0 if first == last
686 * returns >0 if first > last
690 *******************************************************************************/
693 const wchar_t * first
,
694 const wchar_t * last
,
700 while (--count
&& *first
&& *first
== *last
)
706 return((int)(*first
- *last
));
710 *wcsspn.c - find length of initial substring of chars from a control string
711 * (wide-character strings)
713 * Copyright (c) Microsoft Corporation. All rights reserved.
716 * defines wcsspn() - finds the length of the initial substring of
717 * a string consisting entirely of characters from a control string
718 * (wide-character strings).
720 *******************************************************************************/
723 *int wcsspn(string, control) - find init substring of control chars
726 * Finds the index of the first character in string that does belong
727 * to the set of characters specified by control. This is
728 * equivalent to the length of the initial substring of string that
729 * consists entirely of characters from control. The L'\0' character
730 * that terminates control is not considered in the matching process
731 * (wide-character strings).
734 * wchar_t *string - string to search
735 * wchar_t *control - string containing characters not to search for
738 * returns index of first wchar_t in string not in control
742 *******************************************************************************/
744 size_t __cdecl
wcsspn(
745 const wchar_t * string
,
746 const wchar_t * control
748 wchar_t *str
= (wchar_t *) string
;
751 /* 1st char not in control string stops search */
753 for (ctl
= (wchar_t *)control
; *ctl
!= *str
; ctl
++) {
754 if (*ctl
== (wchar_t)0) {
756 * reached end of control string without finding a match
758 return (size_t)(str
- string
);
764 * The whole string consisted of characters from control
766 return (size_t)(str
- string
);
770 *wcscspn.c - find length of initial substring of wide characters
771 * not in a control string
773 * Copyright (c) Microsoft Corporation. All rights reserved.
776 * defines wcscspn()- finds the length of the initial substring of
777 * a string consisting entirely of characters not in a control string
778 * (wide-character strings).
780 *******************************************************************************/
783 *size_t wcscspn(string, control) - search for init substring w/o control wchars
786 * returns the index of the first character in string that belongs
787 * to the set of characters specified by control. This is equivalent
788 * to the length of the length of the initial substring of string
789 * composed entirely of characters not in control. Null chars not
790 * considered (wide-character strings).
793 * wchar_t *string - string to search
794 * wchar_t *control - set of characters not allowed in init substring
797 * returns the index of the first wchar_t in string
798 * that is in the set of characters specified by control.
802 *******************************************************************************/
804 size_t __cdecl
wcscspn(
805 const wchar_t * string
,
806 const wchar_t * control
808 wchar_t *str
= (wchar_t *) string
;
811 /* 1st char in control string stops search */
813 for (wcset
= (wchar_t *)control
; *wcset
; wcset
++) {
814 if (*wcset
== *str
) {
815 return (size_t)(str
- string
);
820 return (size_t)(str
- string
);
824 *wchar_t *wcscpy(dst, src) - copy one wchar_t string over another
827 * Copies the wchar_t string src into the spot specified by
828 * dest; assumes enough room.
831 * wchar_t * dst - wchar_t string over which "src" is to be copied
832 * const wchar_t * src - wchar_t string to be copied over "dst"
835 * The address of "dst"
838 *******************************************************************************/
839 #pragma function(wcscpy)
840 wchar_t * __cdecl
wcscpy(wchar_t * dst
, const wchar_t * src
)
844 while( *cp
++ = *src
++ )
845 ; /* Copy src over dst */
851 *strtol, strtoul(nptr,endptr,ibase) - Convert ascii string to long un/signed
855 * Convert an ascii string to a long 32-bit value. The base
856 * used for the caculations is supplied by the caller. The base
857 * must be in the range 0, 2-36. If a base of 0 is supplied, the
858 * ascii string must be examined to determine the base of the
860 * (a) First char = '0', second char = 'x' or 'X',
862 * (b) First char = '0', use base 8
863 * (c) First char in range '1' - '9', use base 10.
865 * If the 'endptr' value is non-NULL, then strtol/strtoul places
866 * a pointer to the terminating character in this value.
867 * See ANSI standard for details
870 * nptr == NEAR/FAR pointer to the start of string.
871 * endptr == NEAR/FAR pointer to the end of the string.
872 * ibase == integer base to use for the calculations.
874 * string format: [whitespace] [sign] [0] [x] [digits/letters]
881 * strtol -- LONG_MAX or LONG_MIN
882 * strtoul -- ULONG_MAX
883 * strtol/strtoul -- errno == ERANGE
885 * No digits or bad base return:
891 *******************************************************************************/
894 #define FL_UNSIGNED 1 /* strtoul called */
895 #define FL_NEG 2 /* negative sign found */
896 #define FL_OVERFLOW 4 /* overflow occured */
897 #define FL_READDIGIT 8 /* we've read at least one correct digit */
899 // __ascii_isdigit returns a non-zero value if c is a decimal digit (0 – 9).
900 int __ascii_isdigit(int c
)
902 return (c
>= '0' && c
<= '9');
905 // __ascii_isalpha returns a nonzero value if c is within
906 // the ranges A – Z or a – z.
907 int __ascii_isalpha(int c
)
909 return ((c
>= 'A' && c
<= 'Z') || (c
>= 'a' && c
<= 'z'));
912 // __ascii_toupper converts lowercase character to uppercase.
913 int __ascii_toupper(int c
)
915 if (c
>= 'a' && c
<= 'z') return (c
- ('a' - 'A'));
921 static unsigned char spaces
[256] =
923 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, // 0-9
924 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, // 10-19
925 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20-29
926 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, // 30-39
927 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 40-49
928 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 50-59
929 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 60-69
930 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 70-79
931 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 80-89
932 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 90-99
933 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 100-109
934 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 110-119
935 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 120-129
936 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 130-139
937 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 140-149
938 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 150-159
939 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 160-169
940 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 170-179
941 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 180-189
942 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 190-199
943 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 200-209
944 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 210-219
945 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 220-229
946 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 230-239
947 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 240-249
948 0, 0, 0, 0, 0, 1, // 250-255
951 return spaces
[(unsigned char)c
] == 1;
954 static unsigned long __cdecl
strtoxl (
963 unsigned long number
;
965 unsigned long maxval
;
967 p
= nptr
; /* p is our scanning pointer */
968 number
= 0; /* start with zero */
970 c
= *p
++; /* read char */
971 while ( isspace((int)(unsigned char)c
) )
972 c
= *p
++; /* skip whitespace */
975 flags
|= FL_NEG
; /* remember minus sign */
979 c
= *p
++; /* skip sign */
981 if (ibase
< 0 || ibase
== 1 || ibase
> 36) {
984 /* store beginning of string in endptr */
986 return 0L; /* return 0 */
988 else if (ibase
== 0) {
989 /* determine base free-lance, based on first two chars of
993 else if (*p
== 'x' || *p
== 'X')
1000 /* we might have 0x in front of number; remove if there */
1001 if (c
== '0' && (*p
== 'x' || *p
== 'X')) {
1003 c
= *p
++; /* advance past prefix */
1007 /* if our number exceeds this, we will overflow on multiply */
1008 maxval
= ULONG_MAX
/ ibase
;
1011 for (;;) { /* exit in middle of loop */
1012 /* convert c to value */
1013 if ( __ascii_isdigit((int)(unsigned char)c
) )
1015 else if ( __ascii_isalpha((int)(unsigned char)c
) )
1016 digval
= __ascii_toupper(c
) - 'A' + 10;
1019 if (digval
>= (unsigned)ibase
)
1020 break; /* exit loop if bad digit found */
1022 /* record the fact we have read one digit */
1023 flags
|= FL_READDIGIT
;
1025 /* we now need to compute number = number * base + digval,
1026 but we need to know if overflow occured. This requires
1027 a tricky pre-check. */
1029 if (number
< maxval
|| (number
== maxval
&&
1030 (unsigned long)digval
<= ULONG_MAX
% ibase
)) {
1031 /* we won't overflow, go ahead and multiply */
1032 number
= number
* ibase
+ digval
;
1035 /* we would have overflowed -- set the overflow flag */
1036 flags
|= FL_OVERFLOW
;
1039 c
= *p
++; /* read next digit */
1042 --p
; /* point to place that stopped scan */
1044 if (!(flags
& FL_READDIGIT
)) {
1045 /* no number there; return 0 and point to beginning of
1048 /* store beginning of string in endptr later on */
1050 number
= 0L; /* return 0 */
1052 else if ( (flags
& FL_OVERFLOW
) ||
1053 ( !(flags
& FL_UNSIGNED
) &&
1054 ( ( (flags
& FL_NEG
) && (number
> -LONG_MIN
) ) ||
1055 ( !(flags
& FL_NEG
) && (number
> LONG_MAX
) ) ) ) )
1057 /* overflow or signed overflow occurred */
1059 if ( flags
& FL_UNSIGNED
)
1061 else if ( flags
& FL_NEG
)
1062 number
= (unsigned long)(-LONG_MIN
);
1068 /* store pointer to char that stopped the scan */
1072 /* negate result if there was a neg sign */
1073 number
= (unsigned long)(-(long)number
);
1075 return number
; /* done. */
1078 long __cdecl
strtol (
1084 return (long) strtoxl(nptr
, (const char**)endptr
, ibase
, 0);
1087 unsigned long __cdecl
strtoul (
1093 return strtoxl(nptr
, (const char**)endptr
, ibase
, FL_UNSIGNED
);