OLD | NEW |
| (Empty) |
1 #include <windows.h> | |
2 #include <limits.h> | |
3 #include <stdlib.h> | |
4 | |
5 #include "libctiny.h" | |
6 | |
7 #ifndef _CONST_RETURN | |
8 #define _CONST_RETURN | |
9 #endif | |
10 | |
11 /*** | |
12 *wcsstr.c - search for one wide-character string inside another | |
13 * | |
14 * Copyright (c) Microsoft Corporation. All rights reserved. | |
15 * | |
16 *Purpose: | |
17 * defines wcsstr() - search for one wchar_t string inside another | |
18 * | |
19 *******************************************************************************/ | |
20 | |
21 /*** | |
22 *wchar_t *wcsstr(string1, string2) - search for string2 in string1 | |
23 * (wide strings) | |
24 * | |
25 *Purpose: | |
26 * finds the first occurrence of string2 in string1 (wide strings) | |
27 * | |
28 *Entry: | |
29 * wchar_t *string1 - string to search in | |
30 * wchar_t *string2 - string to search for | |
31 * | |
32 *Exit: | |
33 * returns a pointer to the first occurrence of string2 in | |
34 * string1, or NULL if string2 does not occur in string1 | |
35 * | |
36 *Uses: | |
37 * | |
38 *Exceptions: | |
39 * | |
40 *******************************************************************************/ | |
41 | |
42 _CONST_RETURN wchar_t * __cdecl wcsstr(const wchar_t * wcs1, | |
43 const wchar_t * wcs2) { | |
44 wchar_t *cp = (wchar_t *) wcs1; | |
45 wchar_t *s1, *s2; | |
46 | |
47 if (!*wcs2) | |
48 return (wchar_t *)wcs1; | |
49 | |
50 while (*cp) | |
51 { | |
52 s1 = cp; | |
53 s2 = (wchar_t *) wcs2; | |
54 | |
55 while (*s1 && *s2 && !(*s1-*s2)) | |
56 s1++, s2++; | |
57 | |
58 if (!*s2) | |
59 return(cp); | |
60 | |
61 cp++; | |
62 } | |
63 | |
64 return(NULL); | |
65 } | |
66 | |
67 /*** | |
68 *wcsrchr.c - find last occurrence of wchar_t character in wide string | |
69 * | |
70 * Copyright (c) Microsoft Corporation. All rights reserved. | |
71 * | |
72 *Purpose: | |
73 * defines wcsrchr() - find the last occurrence of a given character | |
74 * in a string (wide-characters). | |
75 * | |
76 *******************************************************************************/ | |
77 | |
78 /*** | |
79 *wchar_t *wcsrchr(string, ch) - find last occurrence of ch in wide string | |
80 * | |
81 *Purpose: | |
82 * Finds the last occurrence of ch in string. The terminating | |
83 * null character is used as part of the search (wide-characters). | |
84 * | |
85 *Entry: | |
86 * wchar_t *string - string to search in | |
87 * wchar_t ch - character to search for | |
88 * | |
89 *Exit: | |
90 * returns a pointer to the last occurrence of ch in the given | |
91 * string | |
92 * returns NULL if ch does not occurr in the string | |
93 * | |
94 *Exceptions: | |
95 * | |
96 *******************************************************************************/ | |
97 | |
98 _CONST_RETURN wchar_t * __cdecl wcsrchr(const wchar_t * string, wchar_t ch) { | |
99 wchar_t *start = (wchar_t *)string; | |
100 | |
101 while (*string++) /* find end of string */ | |
102 ; | |
103 /* search towards front */ | |
104 while (--string != start && *string != (wchar_t)ch) | |
105 ; | |
106 | |
107 if (*string == (wchar_t)ch) /* wchar_t found ? */ | |
108 return( (wchar_t *)string ); | |
109 | |
110 return(NULL); | |
111 } | |
112 | |
113 /*** | |
114 *wcschr.c - search a wchar_t string for a given wchar_t character | |
115 * | |
116 * Copyright (c) Microsoft Corporation. All rights reserved. | |
117 * | |
118 *Purpose: | |
119 * defines wcschr() - search a wchar_t string for a wchar_t character | |
120 * | |
121 *******************************************************************************/ | |
122 | |
123 /*** | |
124 *wchar_t *wcschr(string, c) - search a string for a wchar_t character | |
125 * | |
126 *Purpose: | |
127 * Searches a wchar_t string for a given wchar_t character, | |
128 * which may be the null character L'\0'. | |
129 * | |
130 *Entry: | |
131 * wchar_t *string - wchar_t string to search in | |
132 * wchar_t c - wchar_t character to search for | |
133 * | |
134 *Exit: | |
135 * returns pointer to the first occurence of c in string | |
136 * returns NULL if c does not occur in string | |
137 * | |
138 *Exceptions: | |
139 * | |
140 *******************************************************************************/ | |
141 | |
142 _CONST_RETURN wchar_t * __cdecl wcschr(const wchar_t * string, wchar_t ch) { | |
143 while (*string && *string != (wchar_t)ch) | |
144 string++; | |
145 | |
146 if (*string == (wchar_t)ch) | |
147 return((wchar_t *)string); | |
148 return(NULL); | |
149 } | |
150 | |
151 /*** | |
152 *xtoa.c - convert integers/longs to ASCII string | |
153 * | |
154 * Copyright (c) Microsoft Corporation. All rights reserved. | |
155 * | |
156 *Purpose: | |
157 * The module has code to convert integers/longs to ASCII strings. See | |
158 * | |
159 *******************************************************************************/ | |
160 | |
161 /*** | |
162 *char *_itoa, *_ltoa, *_ultoa(val, buf, radix) - convert binary int to ASCII | |
163 * string | |
164 * | |
165 *Purpose: | |
166 * Converts an int to a character string. | |
167 * | |
168 *Entry: | |
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 | |
172 * | |
173 *Exit: | |
174 * fills in space pointed to by buf with string result | |
175 * returns a pointer to this buffer | |
176 * | |
177 *Exceptions: | |
178 * | |
179 *******************************************************************************/ | |
180 | |
181 /* helper routine that does the main job. */ | |
182 | |
183 static void __cdecl xtoa(unsigned long val, char *buf, unsigned radix, int is_ne
g) { | |
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 */ | |
188 | |
189 p = buf; | |
190 | |
191 if (is_neg) { | |
192 /* negative, so output '-' and negate */ | |
193 *p++ = '-'; | |
194 val = (unsigned long)(-(long)val); | |
195 } | |
196 | |
197 firstdig = p; /* save pointer to first digit */ | |
198 | |
199 do { | |
200 digval = (unsigned) (val % radix); | |
201 val /= radix; /* get next digit */ | |
202 | |
203 /* convert to ascii and store */ | |
204 if (digval > 9) | |
205 *p++ = (char) (digval - 10 + 'a'); /* a letter */ | |
206 else | |
207 *p++ = (char) (digval + '0'); /* a digit */ | |
208 } while (val > 0); | |
209 | |
210 /* We now have the digit of the number in the buffer, but in reverse | |
211 order. Thus we reverse them now. */ | |
212 | |
213 *p-- = '\0'; /* terminate string; p points to last digit */ | |
214 | |
215 do { | |
216 temp = *p; | |
217 *p = *firstdig; | |
218 *firstdig = temp; /* swap *p and *firstdig */ | |
219 --p; | |
220 ++firstdig; /* advance to next two digits */ | |
221 } while (firstdig < p); /* repeat until halfway */ | |
222 } | |
223 | |
224 /* Actual functions just call conversion helper with neg flag set correctly, | |
225 and return pointer to buffer. */ | |
226 | |
227 char * __cdecl _itoa(int val, char *buf, int radix) { | |
228 if (radix == 10 && val < 0) | |
229 xtoa((unsigned long)val, buf, radix, 1); | |
230 else | |
231 xtoa((unsigned long)(unsigned int)val, buf, radix, 0); | |
232 return buf; | |
233 } | |
234 | |
235 /*** | |
236 *strlen.c - contains strlen() routine | |
237 * | |
238 * Copyright (c) Microsoft Corporation. All rights reserved. | |
239 * | |
240 *Purpose: | |
241 * strlen returns the length of a null-terminated string, | |
242 * not including the null byte itself. | |
243 * | |
244 *******************************************************************************/ | |
245 | |
246 #ifdef _MSC_VER | |
247 #pragma function(strlen) | |
248 #endif /* _MSC_VER */ | |
249 | |
250 /*** | |
251 *strlen - return the length of a null-terminated string | |
252 * | |
253 *Purpose: | |
254 * Finds the length in bytes of the given string, not including | |
255 * the final null character. | |
256 * | |
257 *Entry: | |
258 * const char * str - string whose length is to be computed | |
259 * | |
260 *Exit: | |
261 * length of the string "str", exclusive of the final null byte | |
262 * | |
263 *Exceptions: | |
264 * | |
265 *******************************************************************************/ | |
266 | |
267 size_t __cdecl strlen(const char * str) { | |
268 const char *eos = str; | |
269 | |
270 while (*eos++) ; | |
271 | |
272 return( (int)(eos - str - 1) ); | |
273 } | |
274 | |
275 size_t __cdecl strnlen(const char *str, size_t maxsize) { | |
276 return strlen(str); | |
277 } | |
278 | |
279 /*** | |
280 *wcsncpy.c - copy at most n characters of wide-character string | |
281 * | |
282 * Copyright (c) Microsoft Corporation. All rights reserved. | |
283 * | |
284 *Purpose: | |
285 * defines wcsncpy() - copy at most n characters of wchar_t string | |
286 * | |
287 *******************************************************************************/ | |
288 | |
289 /*** | |
290 *wchar_t *wcsncpy(dest, source, count) - copy at most n wide characters | |
291 * | |
292 *Purpose: | |
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). | |
298 * | |
299 * | |
300 *Entry: | |
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 | |
304 * | |
305 *Exit: | |
306 * returns dest | |
307 * | |
308 *Exceptions: | |
309 * | |
310 *******************************************************************************/ | |
311 | |
312 wchar_t * __cdecl wcsncpy(wchar_t * dest, const wchar_t * source, size_t count)
{ | |
313 wchar_t *start = dest; | |
314 | |
315 while (count && (*dest++ = *source++)) /* copy string */ | |
316 count--; | |
317 | |
318 if (count) /* pad out with zeroes */ | |
319 while (--count) | |
320 *dest++ = L'\0'; | |
321 | |
322 return(start); | |
323 } | |
324 | |
325 /*** | |
326 *wcscmp.c - routine to compare two wchar_t strings (for equal, less, or greater) | |
327 * | |
328 * Copyright (c) Microsoft Corporation. All rights reserved. | |
329 * | |
330 *Purpose: | |
331 * Compares two wide-character strings, determining their lexical order. | |
332 * | |
333 *******************************************************************************/ | |
334 | |
335 /*** | |
336 *wcscmp - compare two wchar_t strings, | |
337 * returning less than, equal to, or greater than | |
338 * | |
339 *Purpose: | |
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. | |
343 * | |
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. | |
346 * | |
347 *Entry: | |
348 * const wchar_t * src - string for left-hand side of comparison | |
349 * const wchar_t * dst - string for right-hand side of comparison | |
350 * | |
351 *Exit: | |
352 * returns -1 if src < dst | |
353 * returns 0 if src == dst | |
354 * returns +1 if src > dst | |
355 * | |
356 *Exceptions: | |
357 * | |
358 *******************************************************************************/ | |
359 | |
360 int __cdecl wcscmp(const wchar_t * src, const wchar_t * dst) { | |
361 int ret = 0 ; | |
362 | |
363 while (! (ret = (int)(*src - *dst)) && *dst) | |
364 ++src, ++dst; | |
365 | |
366 if (ret < 0) | |
367 ret = -1 ; | |
368 else if (ret > 0) | |
369 ret = 1 ; | |
370 | |
371 return( ret ); | |
372 } | |
373 | |
374 /*** | |
375 *wcslen.c - contains wcslen() routine | |
376 * | |
377 * Copyright (c) Microsoft Corporation. All rights reserved. | |
378 * | |
379 *Purpose: | |
380 * wcslen returns the length of a null-terminated wide-character string, | |
381 * not including the null wchar_t itself. | |
382 * | |
383 *******************************************************************************/ | |
384 | |
385 /*** | |
386 *wcslen - return the length of a null-terminated wide-character string | |
387 * | |
388 *Purpose: | |
389 * Finds the length in wchar_t's of the given string, not including | |
390 * the final null wchar_t (wide-characters). | |
391 * | |
392 *Entry: | |
393 * const wchar_t * wcs - string whose length is to be computed | |
394 * | |
395 *Exit: | |
396 * length of the string "wcs", exclusive of the final null wchar_t | |
397 * | |
398 *Exceptions: | |
399 * | |
400 *******************************************************************************/ | |
401 | |
402 size_t __cdecl wcslen( | |
403 const wchar_t * wcs | |
404 ) { | |
405 const wchar_t *eos = wcs; | |
406 | |
407 while (*eos++) ; | |
408 | |
409 return( (size_t)(eos - wcs - 1) ); | |
410 } | |
411 | |
412 /*** | |
413 *strstr.c - search for one string inside another | |
414 * | |
415 * Copyright (c) Microsoft Corporation. All rights reserved. | |
416 * | |
417 *Purpose: | |
418 * defines strstr() - search for one string inside another | |
419 * | |
420 *******************************************************************************/ | |
421 | |
422 /*** | |
423 *char *strstr(string1, string2) - search for string2 in string1 | |
424 * | |
425 *Purpose: | |
426 * finds the first occurrence of string2 in string1 | |
427 * | |
428 *Entry: | |
429 * char *string1 - string to search in | |
430 * char *string2 - string to search for | |
431 * | |
432 *Exit: | |
433 * returns a pointer to the first occurrence of string2 in | |
434 * string1, or NULL if string2 does not occur in string1 | |
435 * | |
436 *Uses: | |
437 * | |
438 *Exceptions: | |
439 * | |
440 *******************************************************************************/ | |
441 | |
442 _CONST_RETURN char * __cdecl strstr( | |
443 const char * str1, | |
444 const char * str2 | |
445 ) { | |
446 char *cp = (char *) str1; | |
447 char *s1, *s2; | |
448 | |
449 if (!*str2) | |
450 return((char *)str1); | |
451 | |
452 while (*cp) | |
453 { | |
454 s1 = cp; | |
455 s2 = (char *) str2; | |
456 | |
457 while (*s1 && *s2 && !(*s1-*s2)) | |
458 s1++, s2++; | |
459 | |
460 if (!*s2) | |
461 return(cp); | |
462 | |
463 cp++; | |
464 } | |
465 | |
466 return(NULL); | |
467 | |
468 } | |
469 | |
470 /*** | |
471 *strcmp.c - routine to compare two strings (for equal, less, or greater) | |
472 * | |
473 * Copyright (c) Microsoft Corporation. All rights reserved. | |
474 * | |
475 *Purpose: | |
476 * Compares two string, determining their lexical order. | |
477 * | |
478 *******************************************************************************/ | |
479 | |
480 #ifdef _MSC_VER | |
481 #pragma function(strcmp) | |
482 #endif /* _MSC_VER */ | |
483 | |
484 /*** | |
485 *strcmp - compare two strings, returning less than, equal to, or greater than | |
486 * | |
487 *Purpose: | |
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. | |
491 * | |
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). | |
494 * | |
495 *Entry: | |
496 * const char * src - string for left-hand side of comparison | |
497 * const char * dst - string for right-hand side of comparison | |
498 * | |
499 *Exit: | |
500 * returns -1 if src < dst | |
501 * returns 0 if src == dst | |
502 * returns +1 if src > dst | |
503 * | |
504 *Exceptions: | |
505 * | |
506 *******************************************************************************/ | |
507 | |
508 int __cdecl strcmp( | |
509 const char * src, | |
510 const char * dst | |
511 ) { | |
512 int ret = 0 ; | |
513 | |
514 while (! (ret = *(unsigned char *)src - *(unsigned char *)dst) && *dst) | |
515 ++src, ++dst; | |
516 | |
517 if (ret < 0) | |
518 ret = -1 ; | |
519 else if (ret > 0) | |
520 ret = 1 ; | |
521 | |
522 return( ret ); | |
523 } | |
524 | |
525 #ifndef _MBSCAT | |
526 #ifdef _MSC_VER | |
527 #pragma function(strcpy) | |
528 #endif /* _MSC_VER */ | |
529 #endif /* _MBSCAT */ | |
530 | |
531 /*** | |
532 *char *strcpy(dst, src) - copy one string over another | |
533 * | |
534 *Purpose: | |
535 * Copies the string src into the spot specified by | |
536 * dest; assumes enough room. | |
537 * | |
538 *Entry: | |
539 * char * dst - string over which "src" is to be copied | |
540 * const char * src - string to be copied over "dst" | |
541 * | |
542 *Exit: | |
543 * The address of "dst" | |
544 * | |
545 *Exceptions: | |
546 *******************************************************************************/ | |
547 | |
548 char * __cdecl strcpy(char * dst, const char * src) { | |
549 char * cp = dst; | |
550 | |
551 while (*cp++ = *src++) | |
552 ; /* Copy src over dst */ | |
553 | |
554 return( dst ); | |
555 } | |
556 | |
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 | |
561 | |
562 strcpy(dst, src); | |
563 #pragma warning(pop) | |
564 | |
565 return 0; | |
566 } | |
567 | |
568 /*** | |
569 *strncmp.c - compare first n characters of two strings | |
570 * | |
571 * Copyright (c) Microsoft Corporation. All rights reserved. | |
572 * | |
573 *Purpose: | |
574 * defines strncmp() - compare first n characters of two strings | |
575 * for lexical order. | |
576 * | |
577 *******************************************************************************/ | |
578 | |
579 /*** | |
580 *int strncmp(first, last, count) - compare first count chars of strings | |
581 * | |
582 *Purpose: | |
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 | |
586 * compared. | |
587 * | |
588 *Entry: | |
589 * char *first, *last - strings to compare | |
590 * unsigned count - maximum number of characters to compare | |
591 * | |
592 *Exit: | |
593 * returns <0 if first < last | |
594 * returns 0 if first == last | |
595 * returns >0 if first > last | |
596 * | |
597 *Exceptions: | |
598 * | |
599 *******************************************************************************/ | |
600 | |
601 int __cdecl strncmp( | |
602 const char * first, | |
603 const char * last, | |
604 size_t count | |
605 ) { | |
606 if (!count) | |
607 return(0); | |
608 | |
609 while (--count && *first && *first == *last) | |
610 { | |
611 first++; | |
612 last++; | |
613 } | |
614 | |
615 return( *(unsigned char *)first - *(unsigned char *)last ); | |
616 } | |
617 | |
618 /*** | |
619 *strchr.c - search a string for a given character | |
620 * | |
621 * Copyright (c) Microsoft Corporation. All rights reserved. | |
622 * | |
623 *Purpose: | |
624 * defines strchr() - search a string for a character | |
625 * | |
626 *******************************************************************************/ | |
627 | |
628 /*** | |
629 *char *strchr(string, c) - search a string for a character | |
630 * | |
631 *Purpose: | |
632 * Searches a string for a given character, which may be the | |
633 * null character '\0'. | |
634 * | |
635 *Entry: | |
636 * char *string - string to search in | |
637 * char c - character to search for | |
638 * | |
639 *Exit: | |
640 * returns pointer to the first occurence of c in string | |
641 * returns NULL if c does not occur in string | |
642 * | |
643 *Exceptions: | |
644 * | |
645 *******************************************************************************/ | |
646 | |
647 _CONST_RETURN char * __cdecl strchr( | |
648 const char * string, | |
649 int ch | |
650 ) { | |
651 while (*string && *string != (char)ch) | |
652 string++; | |
653 | |
654 if (*string == (char)ch) | |
655 return((char *)string); | |
656 return(NULL); | |
657 } | |
658 | |
659 /*** | |
660 *wcsncmp.c - compare first n characters of two wide-character strings | |
661 * | |
662 * Copyright (c) Microsoft Corporation. All rights reserved. | |
663 * | |
664 *Purpose: | |
665 * defines wcsncmp() - compare first n characters of two wchar_t strings | |
666 * for lexical order. | |
667 * | |
668 *******************************************************************************/ | |
669 | |
670 /*** | |
671 *int wcsncmp(first, last, count) - compare first count chars of wchar_t strings | |
672 * | |
673 *Purpose: | |
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). | |
678 * | |
679 *Entry: | |
680 * wchar_t *first, *last - strings to compare | |
681 * size_t count - maximum number of characters to compare | |
682 * | |
683 *Exit: | |
684 * returns <0 if first < last | |
685 * returns 0 if first == last | |
686 * returns >0 if first > last | |
687 * | |
688 *Exceptions: | |
689 * | |
690 *******************************************************************************/ | |
691 | |
692 int __cdecl wcsncmp( | |
693 const wchar_t * first, | |
694 const wchar_t * last, | |
695 size_t count | |
696 ) { | |
697 if (!count) | |
698 return(0); | |
699 | |
700 while (--count && *first && *first == *last) | |
701 { | |
702 first++; | |
703 last++; | |
704 } | |
705 | |
706 return((int)(*first - *last)); | |
707 } | |
708 | |
709 /*** | |
710 *wcsspn.c - find length of initial substring of chars from a control string | |
711 * (wide-character strings) | |
712 * | |
713 * Copyright (c) Microsoft Corporation. All rights reserved. | |
714 * | |
715 *Purpose: | |
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). | |
719 * | |
720 *******************************************************************************/ | |
721 | |
722 /*** | |
723 *int wcsspn(string, control) - find init substring of control chars | |
724 * | |
725 *Purpose: | |
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). | |
732 * | |
733 *Entry: | |
734 * wchar_t *string - string to search | |
735 * wchar_t *control - string containing characters not to search for | |
736 * | |
737 *Exit: | |
738 * returns index of first wchar_t in string not in control | |
739 * | |
740 *Exceptions: | |
741 * | |
742 *******************************************************************************/ | |
743 | |
744 size_t __cdecl wcsspn( | |
745 const wchar_t * string, | |
746 const wchar_t * control | |
747 ) { | |
748 wchar_t *str = (wchar_t *) string; | |
749 wchar_t *ctl; | |
750 | |
751 /* 1st char not in control string stops search */ | |
752 while (*str) { | |
753 for (ctl = (wchar_t *)control; *ctl != *str; ctl++) { | |
754 if (*ctl == (wchar_t)0) { | |
755 /* | |
756 * reached end of control string without finding a match | |
757 */ | |
758 return (size_t)(str - string); | |
759 } | |
760 } | |
761 str++; | |
762 } | |
763 /* | |
764 * The whole string consisted of characters from control | |
765 */ | |
766 return (size_t)(str - string); | |
767 } | |
768 | |
769 /*** | |
770 *wcscspn.c - find length of initial substring of wide characters | |
771 * not in a control string | |
772 * | |
773 * Copyright (c) Microsoft Corporation. All rights reserved. | |
774 * | |
775 *Purpose: | |
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). | |
779 * | |
780 *******************************************************************************/ | |
781 | |
782 /*** | |
783 *size_t wcscspn(string, control) - search for init substring w/o control wchars | |
784 * | |
785 *Purpose: | |
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). | |
791 * | |
792 *Entry: | |
793 * wchar_t *string - string to search | |
794 * wchar_t *control - set of characters not allowed in init substring | |
795 * | |
796 *Exit: | |
797 * returns the index of the first wchar_t in string | |
798 * that is in the set of characters specified by control. | |
799 * | |
800 *Exceptions: | |
801 * | |
802 *******************************************************************************/ | |
803 | |
804 size_t __cdecl wcscspn( | |
805 const wchar_t * string, | |
806 const wchar_t * control | |
807 ) { | |
808 wchar_t *str = (wchar_t *) string; | |
809 wchar_t *wcset; | |
810 | |
811 /* 1st char in control string stops search */ | |
812 while (*str) { | |
813 for (wcset = (wchar_t *)control; *wcset; wcset++) { | |
814 if (*wcset == *str) { | |
815 return (size_t)(str - string); | |
816 } | |
817 } | |
818 str++; | |
819 } | |
820 return (size_t)(str - string); | |
821 } | |
822 | |
823 /*** | |
824 *wchar_t *wcscpy(dst, src) - copy one wchar_t string over another | |
825 * | |
826 *Purpose: | |
827 * Copies the wchar_t string src into the spot specified by | |
828 * dest; assumes enough room. | |
829 * | |
830 *Entry: | |
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" | |
833 * | |
834 *Exit: | |
835 * The address of "dst" | |
836 * | |
837 *Exceptions: | |
838 *******************************************************************************/ | |
839 | |
840 wchar_t * __cdecl wcscpy(wchar_t * dst, const wchar_t * src) | |
841 { | |
842 wchar_t * cp = dst; | |
843 | |
844 while( *cp++ = *src++ ) | |
845 ; /* Copy src over dst */ | |
846 | |
847 return( dst ); | |
848 } | |
849 | |
850 /*** | |
851 *strtol, strtoul(nptr,endptr,ibase) - Convert ascii string to long un/signed | |
852 * int. | |
853 * | |
854 *Purpose: | |
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 | |
859 * number: | |
860 * (a) First char = '0', second char = 'x' or 'X', | |
861 * use base 16. | |
862 * (b) First char = '0', use base 8 | |
863 * (c) First char in range '1' - '9', use base 10. | |
864 * | |
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 | |
868 * | |
869 *Entry: | |
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. | |
873 * | |
874 * string format: [whitespace] [sign] [0] [x] [digits/letters] | |
875 * | |
876 *Exit: | |
877 * Good return: | |
878 * result | |
879 * | |
880 * Overflow return: | |
881 * strtol -- LONG_MAX or LONG_MIN | |
882 * strtoul -- ULONG_MAX | |
883 * strtol/strtoul -- errno == ERANGE | |
884 * | |
885 * No digits or bad base return: | |
886 * 0 | |
887 * endptr = nptr* | |
888 * | |
889 *Exceptions: | |
890 * None. | |
891 *******************************************************************************/ | |
892 | |
893 /* flag values */ | |
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 */ | |
898 | |
899 // __ascii_isdigit returns a non-zero value if c is a decimal digit (0 9). | |
900 int __ascii_isdigit(int c) | |
901 { | |
902 return (c >= '0' && c <= '9'); | |
903 } | |
904 | |
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) | |
908 { | |
909 return ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')); | |
910 } | |
911 | |
912 // __ascii_toupper converts lowercase character to uppercase. | |
913 int __ascii_toupper(int c) | |
914 { | |
915 if (c >= 'a' && c <= 'z') return (c - ('a' - 'A')); | |
916 return c; | |
917 } | |
918 | |
919 int isspace(int c) | |
920 { | |
921 static unsigned char spaces[256] = | |
922 { | |
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 | |
949 }; | |
950 | |
951 return spaces[(unsigned char)c] == 1; | |
952 } | |
953 | |
954 static unsigned long __cdecl strtoxl ( | |
955 const char *nptr, | |
956 const char **endptr, | |
957 int ibase, | |
958 int flags | |
959 ) | |
960 { | |
961 const char *p; | |
962 char c; | |
963 unsigned long number; | |
964 unsigned digval; | |
965 unsigned long maxval; | |
966 | |
967 p = nptr; /* p is our scanning pointer */ | |
968 number = 0; /* start with zero */ | |
969 | |
970 c = *p++; /* read char */ | |
971 while ( isspace((int)(unsigned char)c) ) | |
972 c = *p++; /* skip whitespace */ | |
973 | |
974 if (c == '-') { | |
975 flags |= FL_NEG; /* remember minus sign */ | |
976 c = *p++; | |
977 } | |
978 else if (c == '+') | |
979 c = *p++; /* skip sign */ | |
980 | |
981 if (ibase < 0 || ibase == 1 || ibase > 36) { | |
982 /* bad base! */ | |
983 if (endptr) | |
984 /* store beginning of string in endptr */ | |
985 *endptr = nptr; | |
986 return 0L; /* return 0 */ | |
987 } | |
988 else if (ibase == 0) { | |
989 /* determine base free-lance, based on first two chars of | |
990 string */ | |
991 if (c != '0') | |
992 ibase = 10; | |
993 else if (*p == 'x' || *p == 'X') | |
994 ibase = 16; | |
995 else | |
996 ibase = 8; | |
997 } | |
998 | |
999 if (ibase == 16) { | |
1000 /* we might have 0x in front of number; remove if there */ | |
1001 if (c == '0' && (*p == 'x' || *p == 'X')) { | |
1002 ++p; | |
1003 c = *p++; /* advance past prefix */ | |
1004 } | |
1005 } | |
1006 | |
1007 /* if our number exceeds this, we will overflow on multiply */ | |
1008 maxval = ULONG_MAX / ibase; | |
1009 | |
1010 | |
1011 for (;;) { /* exit in middle of loop */ | |
1012 /* convert c to value */ | |
1013 if ( __ascii_isdigit((int)(unsigned char)c) ) | |
1014 digval = c - '0'; | |
1015 else if ( __ascii_isalpha((int)(unsigned char)c) ) | |
1016 digval = __ascii_toupper(c) - 'A' + 10; | |
1017 else | |
1018 break; | |
1019 if (digval >= (unsigned)ibase) | |
1020 break; /* exit loop if bad digit found */ | |
1021 | |
1022 /* record the fact we have read one digit */ | |
1023 flags |= FL_READDIGIT; | |
1024 | |
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. */ | |
1028 | |
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; | |
1033 } | |
1034 else { | |
1035 /* we would have overflowed -- set the overflow flag */ | |
1036 flags |= FL_OVERFLOW; | |
1037 } | |
1038 | |
1039 c = *p++; /* read next digit */ | |
1040 } | |
1041 | |
1042 --p; /* point to place that stopped scan */ | |
1043 | |
1044 if (!(flags & FL_READDIGIT)) { | |
1045 /* no number there; return 0 and point to beginning of | |
1046 string */ | |
1047 if (endptr) | |
1048 /* store beginning of string in endptr later on */ | |
1049 p = nptr; | |
1050 number = 0L; /* return 0 */ | |
1051 } | |
1052 else if ( (flags & FL_OVERFLOW) || | |
1053 ( !(flags & FL_UNSIGNED) && | |
1054 ( ( (flags & FL_NEG) && (number > -LONG_MIN) ) || | |
1055 ( !(flags & FL_NEG) && (number > LONG_MAX) ) ) ) ) | |
1056 { | |
1057 /* overflow or signed overflow occurred */ | |
1058 // errno = ERANGE; | |
1059 if ( flags & FL_UNSIGNED ) | |
1060 number = ULONG_MAX; | |
1061 else if ( flags & FL_NEG ) | |
1062 number = (unsigned long)(-LONG_MIN); | |
1063 else | |
1064 number = LONG_MAX; | |
1065 } | |
1066 | |
1067 if (endptr != NULL) | |
1068 /* store pointer to char that stopped the scan */ | |
1069 *endptr = p; | |
1070 | |
1071 if (flags & FL_NEG) | |
1072 /* negate result if there was a neg sign */ | |
1073 number = (unsigned long)(-(long)number); | |
1074 | |
1075 return number; /* done. */ | |
1076 } | |
1077 | |
1078 long __cdecl strtol ( | |
1079 const char *nptr, | |
1080 char **endptr, | |
1081 int ibase | |
1082 ) | |
1083 { | |
1084 return (long) strtoxl(nptr, (const char**)endptr, ibase, 0); | |
1085 } | |
1086 | |
1087 unsigned long __cdecl strtoul ( | |
1088 const char *nptr, | |
1089 char **endptr, | |
1090 int ibase | |
1091 ) | |
1092 { | |
1093 return strtoxl(nptr, (const char**)endptr, ibase, FL_UNSIGNED); | |
1094 } | |
1095 | |
OLD | NEW |