ReactOS 0.4.17-dev-301-g9127a53
string.c
Go to the documentation of this file.
1/*
2 * MSVCRT string functions
3 *
4 * Copyright 1996,1998 Marcus Meissner
5 * Copyright 1996 Jukka Iivonen
6 * Copyright 1997,2000 Uwe Bonnes
7 * Copyright 2000 Jon Griffiths
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 */
23
24#include <assert.h>
25#include <stdlib.h>
26#include <stdio.h>
27#include <math.h>
28#include <limits.h>
29#include <locale.h>
30#include <float.h>
31#include "msvcrt.h"
32#include "bnum.h"
33#include "winnls.h"
34#include "wine/asm.h"
35#include "wine/debug.h"
36
38
39#ifdef _MSC_VER
40#pragma function(_strset,memchr,memcmp,memcpy,memset,strcat,strcmp,strcpy,strlen)
41#ifdef __REACTOS__
42#if defined(_M_ARM) || _MSC_VER >= 1932 // VS2022 version 17.2 and later
43#pragma function(strncmp,strncpy)
44#endif
45#endif
46#endif
47
48/*********************************************************************
49 * _mbsdup (MSVCRT.@)
50 * _strdup (MSVCRT.@)
51 */
52char* CDECL _strdup(const char* str)
53{
54 if(str)
55 {
56 char * ret = malloc(strlen(str)+1);
57 if (ret) strcpy( ret, str );
58 return ret;
59 }
60 else return 0;
61}
62
63/*********************************************************************
64 * _strlwr_s_l (MSVCRT.@)
65 */
67{
69 char *ptr = str;
70
71 if (!str || !len)
72 {
73 *_errno() = EINVAL;
74 return EINVAL;
75 }
76
77 while (len && *ptr)
78 {
79 len--;
80 ptr++;
81 }
82
83 if (!len)
84 {
85 str[0] = '\0';
86 *_errno() = EINVAL;
87 return EINVAL;
88 }
89
90 if(!locale)
92 else
93 locinfo = locale->locinfo;
94
95 if(!locinfo->lc_handle[LC_CTYPE])
96 {
97 while (*str)
98 {
99 if (*str >= 'A' && *str <= 'Z')
100 *str -= 'A' - 'a';
101 str++;
102 }
103 }
104 else
105 {
106 while (*str)
107 {
108 *str = _tolower_l((unsigned char)*str, locale);
109 str++;
110 }
111 }
112
113 return 0;
114}
115
116/*********************************************************************
117 * _strlwr_s (MSVCRT.@)
118 */
119int CDECL _strlwr_s(char *str, size_t len)
120{
121 return _strlwr_s_l(str, len, NULL);
122}
123
124/*********************************************************************
125 * _strlwr_l (MSVCRT.@)
126 */
128{
129 _strlwr_s_l(str, -1, locale);
130 return str;
131}
132
133/*********************************************************************
134 * _strlwr (MSVCRT.@)
135 */
136char* CDECL _strlwr(char *str)
137{
138 _strlwr_s_l(str, -1, NULL);
139 return str;
140}
141
142/*********************************************************************
143 * _strupr_s_l (MSVCRT.@)
144 */
146{
148 char *ptr = str;
149
150 if (!str || !len)
151 {
152 *_errno() = EINVAL;
153 return EINVAL;
154 }
155
156 while (len && *ptr)
157 {
158 len--;
159 ptr++;
160 }
161
162 if (!len)
163 {
164 str[0] = '\0';
165 *_errno() = EINVAL;
166 return EINVAL;
167 }
168
169 if(!locale)
171 else
172 locinfo = locale->locinfo;
173
174 if(!locinfo->lc_handle[LC_CTYPE])
175 {
176 while (*str)
177 {
178 if (*str >= 'a' && *str <= 'z')
179 *str -= 'a' - 'A';
180 str++;
181 }
182 }
183 else
184 {
185 while (*str)
186 {
187 *str = _toupper_l((unsigned char)*str, locale);
188 str++;
189 }
190 }
191
192 return 0;
193}
194
195/*********************************************************************
196 * _strupr_s (MSVCRT.@)
197 */
198int CDECL _strupr_s(char *str, size_t len)
199{
200 return _strupr_s_l(str, len, NULL);
201}
202
203/*********************************************************************
204 * _strupr_l (MSVCRT.@)
205 */
207{
208 _strupr_s_l(str, -1, locale);
209 return str;
210}
211
212/*********************************************************************
213 * _strupr (MSVCRT.@)
214 */
215char* CDECL _strupr(char *str)
216{
217 _strupr_s_l(str, -1, NULL);
218 return str;
219}
220
221/*********************************************************************
222 * _strnset_s (MSVCRT.@)
223 */
224int CDECL _strnset_s(char *str, size_t size, int c, size_t count)
225{
226 size_t i;
227
228 if(!str && !size && !count) return 0;
229 if(!MSVCRT_CHECK_PMT(str != NULL)) return EINVAL;
230 if(!MSVCRT_CHECK_PMT(size > 0)) return EINVAL;
231
232 for(i=0; i<size-1 && i<count; i++) {
233 if(!str[i]) return 0;
234 str[i] = c;
235 }
236 for(; i<size; i++)
237 if(!str[i]) return 0;
238
239 str[0] = 0;
241 *_errno() = EINVAL;
242 return EINVAL;
243}
244
245/*********************************************************************
246 * _strnset (MSVCRT.@)
247 */
248char* CDECL _strnset(char* str, int value, size_t len)
249{
250 if (len > 0 && str)
251 while (*str && len--)
252 *str++ = value;
253 return str;
254}
255
256/*********************************************************************
257 * _strrev (MSVCRT.@)
258 */
259char* CDECL _strrev(char* str)
260{
261 char * p1;
262 char * p2;
263
264 if (str && *str)
265 for (p1 = str, p2 = str + strlen(str) - 1; p2 > p1; ++p1, --p2)
266 {
267 *p1 ^= *p2;
268 *p2 ^= *p1;
269 *p1 ^= *p2;
270 }
271
272 return str;
273}
274
275/*********************************************************************
276 * _strset (MSVCRT.@)
277 */
278char* CDECL _strset(char* str, int value)
279{
280 char *ptr = str;
281 while (*ptr)
282 *ptr++ = value;
283
284 return str;
285}
286
287/*********************************************************************
288 * strtok (MSVCRT.@)
289 */
290char * CDECL strtok( char *str, const char *delim )
291{
293 char *ret;
294
295 if (!str)
296 if (!(str = data->strtok_next)) return NULL;
297
298 while (*str && strchr( delim, *str )) str++;
299 if (!*str)
300 {
301 data->strtok_next = str;
302 return NULL;
303 }
304 ret = str++;
305 while (*str && !strchr( delim, *str )) str++;
306 if (*str) *str++ = 0;
307 data->strtok_next = str;
308 return ret;
309}
310
311/*********************************************************************
312 * strtok_s (MSVCRT.@)
313 */
314char * CDECL strtok_s(char *str, const char *delim, char **ctx)
315{
316 if (!MSVCRT_CHECK_PMT(delim != NULL)) return NULL;
317 if (!MSVCRT_CHECK_PMT(ctx != NULL)) return NULL;
318 if (!MSVCRT_CHECK_PMT(str != NULL || *ctx != NULL)) return NULL;
319
320 if(!str)
321 str = *ctx;
322
323 while(*str && strchr(delim, *str))
324 str++;
325 if(!*str)
326 {
327 *ctx = str;
328 return NULL;
329 }
330
331 *ctx = str+1;
332 while(**ctx && !strchr(delim, **ctx))
333 (*ctx)++;
334 if(**ctx)
335 *(*ctx)++ = 0;
336
337 return str;
338}
339
340/*********************************************************************
341 * _swab (MSVCRT.@)
342 */
343void CDECL _swab(char* src, char* dst, int len)
344{
345 if (len > 1)
346 {
347 len = (unsigned)len >> 1;
348
349 while (len--) {
350 char s0 = src[0];
351 char s1 = src[1];
352 *dst++ = s1;
353 *dst++ = s0;
354 src = src + 2;
355 }
356 }
357}
358
360{
361 struct fpnum ret;
362
363 ret.sign = sign;
364 ret.exp = exp;
365 ret.m = m;
366 ret.mod = mod;
367 return ret;
368}
369
370int fpnum_double(struct fpnum *fp, double *d)
371{
372 ULONGLONG bits = 0;
373
374 if (fp->mod == FP_VAL_INFINITY)
375 {
376 *d = fp->sign * INFINITY;
377 return 0;
378 }
379
380 if (fp->mod == FP_VAL_NAN)
381 {
382 bits = ~0;
383 if (fp->sign == 1)
384 bits &= ~((ULONGLONG)1 << (MANT_BITS + EXP_BITS - 1));
385 *d = *(double*)&bits;
386 return 0;
387 }
388
389 TRACE("%c %#I64x *2^%d (round %d)\n", fp->sign == -1 ? '-' : '+',
390 fp->m, fp->exp, fp->mod);
391 if (!fp->m)
392 {
393 *d = fp->sign * 0.0;
394 return 0;
395 }
396
397 /* make sure that we don't overflow modifying exponent */
398 if (fp->exp > 1<<EXP_BITS)
399 {
400 *d = fp->sign * INFINITY;
401 return ERANGE;
402 }
403 if (fp->exp < -(1<<EXP_BITS))
404 {
405 *d = fp->sign * 0.0;
406 return ERANGE;
407 }
408 fp->exp += MANT_BITS - 1;
409
410 /* normalize mantissa */
411 while(fp->m < (ULONGLONG)1 << (MANT_BITS-1))
412 {
413 fp->m <<= 1;
414 fp->exp--;
415 }
416 while(fp->m >= (ULONGLONG)1 << MANT_BITS)
417 {
418 if (fp->m & 1 || fp->mod != FP_ROUND_ZERO)
419 {
420 if (!(fp->m & 1)) fp->mod = FP_ROUND_DOWN;
421 else if(fp->mod == FP_ROUND_ZERO) fp->mod = FP_ROUND_EVEN;
422 else fp->mod = FP_ROUND_UP;
423 }
424 fp->m >>= 1;
425 fp->exp++;
426 }
427 fp->exp += (1 << (EXP_BITS-1)) - 1;
428
429 /* handle subnormals */
430 if (fp->exp <= 0)
431 {
432 if (fp->m & 1 && fp->mod == FP_ROUND_ZERO) fp->mod = FP_ROUND_EVEN;
433 else if (fp->m & 1) fp->mod = FP_ROUND_UP;
434 else if (fp->mod != FP_ROUND_ZERO) fp->mod = FP_ROUND_DOWN;
435 fp->m >>= 1;
436 }
437 while(fp->m && fp->exp<0)
438 {
439 if (fp->m & 1 && fp->mod == FP_ROUND_ZERO) fp->mod = FP_ROUND_EVEN;
440 else if (fp->m & 1) fp->mod = FP_ROUND_UP;
441 else if (fp->mod != FP_ROUND_ZERO) fp->mod = FP_ROUND_DOWN;
442 fp->m >>= 1;
443 fp->exp++;
444 }
445
446 /* round mantissa */
447 if (fp->mod == FP_ROUND_UP || (fp->mod == FP_ROUND_EVEN && fp->m & 1))
448 {
449 fp->m++;
450
451 /* handle subnormal that falls into regular range due to rounding */
452 if (fp->m == (ULONGLONG)1 << (MANT_BITS - 1))
453 {
454 fp->exp++;
455 }
456 else if (fp->m >= (ULONGLONG)1 << MANT_BITS)
457 {
458 fp->exp++;
459 fp->m >>= 1;
460 }
461 }
462
463 if (fp->exp >= (1<<EXP_BITS)-1)
464 {
465 *d = fp->sign * INFINITY;
466 return ERANGE;
467 }
468 if (!fp->m || fp->exp < 0)
469 {
470 *d = fp->sign * 0.0;
471 return ERANGE;
472 }
473
474 if (fp->sign == -1)
475 bits |= (ULONGLONG)1 << (MANT_BITS + EXP_BITS - 1);
476 bits |= (ULONGLONG)fp->exp << (MANT_BITS - 1);
477 bits |= fp->m & (((ULONGLONG)1 << (MANT_BITS - 1)) - 1);
478
479 TRACE("returning %#I64x\n", bits);
480 *d = *(double*)&bits;
481 return 0;
482}
483
484#define LDBL_EXP_BITS 15
485#define LDBL_MANT_BITS 64
486#ifdef __REACTOS__
487int fpnum_ldouble(struct fpnum *fp, WINE_BROKEN_LDOUBLE *d)
488#else
490#endif
491{
492 if (fp->mod == FP_VAL_INFINITY)
493 {
494 d->x80[0] = 0;
495 d->x80[1] = 0x80000000;
496 d->x80[2] = (1 << LDBL_EXP_BITS) - 1;
497 if (fp->sign == -1)
498 d->x80[2] |= 1 << LDBL_EXP_BITS;
499 return 0;
500 }
501
502 if (fp->mod == FP_VAL_NAN)
503 {
504 d->x80[0] = ~0;
505 d->x80[1] = ~0;
506 d->x80[2] = (1 << LDBL_EXP_BITS) - 1;
507 if (fp->sign == -1)
508 d->x80[2] |= 1 << LDBL_EXP_BITS;
509 return 0;
510 }
511
512 TRACE("%c %#I64x *2^%d (round %d)\n", fp->sign == -1 ? '-' : '+',
513 fp->m, fp->exp, fp->mod);
514 if (!fp->m)
515 {
516 d->x80[0] = 0;
517 d->x80[1] = 0;
518 d->x80[2] = 0;
519 if (fp->sign == -1)
520 d->x80[2] |= 1 << LDBL_EXP_BITS;
521 return 0;
522 }
523
524 /* make sure that we don't overflow modifying exponent */
525 if (fp->exp > 1<<LDBL_EXP_BITS)
526 {
527 d->x80[0] = 0;
528 d->x80[1] = 0x80000000;
529 d->x80[2] = (1 << LDBL_EXP_BITS) - 1;
530 if (fp->sign == -1)
531 d->x80[2] |= 1 << LDBL_EXP_BITS;
532 return ERANGE;
533 }
534 if (fp->exp < -(1<<LDBL_EXP_BITS))
535 {
536 d->x80[0] = 0;
537 d->x80[1] = 0;
538 d->x80[2] = 0;
539 if (fp->sign == -1)
540 d->x80[2] |= 1 << LDBL_EXP_BITS;
541 return ERANGE;
542 }
543 fp->exp += LDBL_MANT_BITS - 1;
544
545 /* normalize mantissa */
546 while(fp->m < (ULONGLONG)1 << (LDBL_MANT_BITS-1))
547 {
548 fp->m <<= 1;
549 fp->exp--;
550 }
551 fp->exp += (1 << (LDBL_EXP_BITS-1)) - 1;
552
553 /* handle subnormals */
554 if (fp->exp <= 0)
555 {
556 if (fp->m & 1 && fp->mod == FP_ROUND_ZERO) fp->mod = FP_ROUND_EVEN;
557 else if (fp->m & 1) fp->mod = FP_ROUND_UP;
558 else if (fp->mod != FP_ROUND_ZERO) fp->mod = FP_ROUND_DOWN;
559 fp->m >>= 1;
560 }
561 while(fp->m && fp->exp<0)
562 {
563 if (fp->m & 1 && fp->mod == FP_ROUND_ZERO) fp->mod = FP_ROUND_EVEN;
564 else if (fp->m & 1) fp->mod = FP_ROUND_UP;
565 else if (fp->mod != FP_ROUND_ZERO) fp->mod = FP_ROUND_DOWN;
566 fp->m >>= 1;
567 fp->exp++;
568 }
569
570 /* round mantissa */
571 if (fp->mod == FP_ROUND_UP || (fp->mod == FP_ROUND_EVEN && fp->m & 1))
572 {
573 if (fp->m == UI64_MAX)
574 {
575 fp->m = (ULONGLONG)1 << (LDBL_MANT_BITS - 1);
576 fp->exp++;
577 }
578 else
579 {
580 fp->m++;
581
582 /* handle subnormal that falls into regular range due to rounding */
583 if ((fp->m ^ (fp->m - 1)) & ((ULONGLONG)1 << (LDBL_MANT_BITS - 1))) fp->exp++;
584 }
585 }
586
587 if (fp->exp >= (1<<LDBL_EXP_BITS)-1)
588 {
589 d->x80[0] = 0;
590 d->x80[1] = 0x80000000;
591 d->x80[2] = (1 << LDBL_EXP_BITS) - 1;
592 if (fp->sign == -1)
593 d->x80[2] |= 1 << LDBL_EXP_BITS;
594 return ERANGE;
595 }
596 if (!fp->m || fp->exp < 0)
597 {
598 d->x80[0] = 0;
599 d->x80[1] = 0;
600 d->x80[2] = 0;
601 if (fp->sign == -1)
602 d->x80[2] |= 1 << LDBL_EXP_BITS;
603 return ERANGE;
604 }
605
606 d->x80[0] = fp->m;
607 d->x80[1] = fp->m >> 32;
608 d->x80[2] = fp->exp;
609 if (fp->sign == -1)
610 d->x80[2] |= 1 << LDBL_EXP_BITS;
611 return 0;
612}
613
614#if _MSVCR_VER >= 140
615
616static inline int hex2int(char c)
617{
618 if (c >= '0' && c <= '9')
619 return c - '0';
620 else if (c >= 'a' && c <= 'f')
621 return c - 'a' + 10;
622 else if (c >= 'A' && c <= 'F')
623 return c - 'A' + 10;
624 return -1;
625}
626
627static struct fpnum fpnum_parse16(wchar_t get(void *ctx), void unget(void *ctx),
628 void *ctx, int sign, pthreadlocinfo locinfo)
629{
630 BOOL found_digit = FALSE, found_dp = FALSE;
632 wchar_t nch;
633 ULONGLONG m = 0;
634 int val, exp = 0;
635
636 nch = get(ctx);
637 while(m < UI64_MAX/16)
638 {
639 val = hex2int(nch);
640 if (val == -1) break;
641 found_digit = TRUE;
642 nch = get(ctx);
643
644 m = m*16 + val;
645 }
646 while(1)
647 {
648 val = hex2int(nch);
649 if (val == -1) break;
650 nch = get(ctx);
651 exp += 4;
652
653 if (val || round != FP_ROUND_ZERO)
654 {
655 if (val < 8) round = FP_ROUND_DOWN;
656 else if (val == 8 && round == FP_ROUND_ZERO) round = FP_ROUND_EVEN;
657 else round = FP_ROUND_UP;
658 }
659 }
660
661 if(nch == *locinfo->lconv->decimal_point)
662 {
663 found_dp = TRUE;
664 nch = get(ctx);
665 }
666 else if (!found_digit)
667 {
668 if(nch!=WEOF) unget(ctx);
669 unget(ctx);
670 return fpnum(0, 0, 0, 0);
671 }
672
673 while(m <= UI64_MAX/16)
674 {
675 val = hex2int(nch);
676 if (val == -1) break;
677 found_digit = TRUE;
678 nch = get(ctx);
679
680 m = m*16 + val;
681 exp -= 4;
682 }
683 while(1)
684 {
685 val = hex2int(nch);
686 if (val == -1) break;
687 nch = get(ctx);
688
689 if (val || round != FP_ROUND_ZERO)
690 {
691 if (val < 8) round = FP_ROUND_DOWN;
692 else if (val == 8 && round == FP_ROUND_ZERO) round = FP_ROUND_EVEN;
693 else round = FP_ROUND_UP;
694 }
695 }
696
697 if (!found_digit)
698 {
699 if (nch != WEOF) unget(ctx);
700 if (found_dp) unget(ctx);
701 unget(ctx);
702 return fpnum(0, 0, 0, 0);
703 }
704
705 if(nch=='p' || nch=='P') {
706 BOOL found_sign = FALSE;
707 int e=0, s=1;
708
709 nch = get(ctx);
710 if(nch == '-') {
711 found_sign = TRUE;
712 s = -1;
713 nch = get(ctx);
714 } else if(nch == '+') {
715 found_sign = TRUE;
716 nch = get(ctx);
717 }
718 if(nch>='0' && nch<='9') {
719 while(nch>='0' && nch<='9') {
720 if(e>INT_MAX/10 || e*10>INT_MAX-nch+'0')
721 e = INT_MAX;
722 else
723 e = e*10+nch-'0';
724 nch = get(ctx);
725 }
726 if((nch!=WEOF) && (nch < '0' || nch > '9')) unget(ctx);
727 e *= s;
728
729 if(e<0 && exp<INT_MIN-e) exp = INT_MIN;
730 else if(e>0 && exp>INT_MAX-e) exp = INT_MAX;
731 else exp += e;
732 } else {
733 if(nch != WEOF) unget(ctx);
734 if(found_sign) unget(ctx);
735 unget(ctx);
736 }
737 }
738
739 return fpnum(sign, exp, m, round);
740}
741#endif
742
743/* Converts first 3 limbs to ULONGLONG */
744/* Return FALSE on overflow */
745static inline BOOL bnum_to_mant(struct bnum *b, ULONGLONG *m)
746{
747 if(UI64_MAX / LIMB_MAX / LIMB_MAX < b->data[bnum_idx(b, b->e-1)]) return FALSE;
748 *m = (ULONGLONG)b->data[bnum_idx(b, b->e-1)] * LIMB_MAX * LIMB_MAX;
749 if(b->b == b->e-1) return TRUE;
750 if(UI64_MAX - *m < (ULONGLONG)b->data[bnum_idx(b, b->e-2)] * LIMB_MAX) return FALSE;
751 *m += (ULONGLONG)b->data[bnum_idx(b, b->e-2)] * LIMB_MAX;
752 if(b->b == b->e-2) return TRUE;
753 if(UI64_MAX - *m < b->data[bnum_idx(b, b->e-3)]) return FALSE;
754 *m += b->data[bnum_idx(b, b->e-3)];
755 return TRUE;
756}
757
758static struct fpnum fpnum_parse_bnum(wchar_t (*get)(void *ctx), void (*unget)(void *ctx),
759 void *ctx, pthreadlocinfo locinfo, BOOL ldouble, struct bnum *b)
760{
761#if _MSVCR_VER >= 140
762 const wchar_t _infinity[] = L"infinity";
763 const wchar_t _nan[] = L"nan";
764 const wchar_t *str_match = NULL;
765 int matched=0;
766#endif
767 BOOL found_digit = FALSE, found_dp = FALSE, found_sign = FALSE;
768 int e2 = 0, dp=0, sign=1, off, limb_digits = 0, i;
770 wchar_t nch;
771 ULONGLONG m;
772
773 nch = get(ctx);
774 if(nch == '-') {
775 found_sign = TRUE;
776 sign = -1;
777 nch = get(ctx);
778 } else if(nch == '+') {
779 found_sign = TRUE;
780 nch = get(ctx);
781 }
782
783#if _MSVCR_VER >= 140
784 if(nch == _infinity[0] || nch == _toupper(_infinity[0]))
785 str_match = _infinity;
786 if(nch == _nan[0] || nch == _toupper(_nan[0]))
787 str_match = _nan;
788 while(str_match && nch != WEOF &&
789 (nch == str_match[matched] || nch == _toupper(str_match[matched]))) {
790 nch = get(ctx);
791 matched++;
792 }
793 if(str_match) {
794 int keep = 0;
795 if(matched >= 8) keep = 8;
796 else if(matched >= 3) keep = 3;
797 if(nch != WEOF) unget(ctx);
798 for (; matched > keep; matched--) {
799 unget(ctx);
800 }
801 if(keep) {
802 if (str_match == _infinity)
803 return fpnum(sign, 0, 0, FP_VAL_INFINITY);
804 if (str_match == _nan)
805 return fpnum(sign, 0, 0, FP_VAL_NAN);
806 } else if(found_sign) {
807 unget(ctx);
808 }
809
810 return fpnum(0, 0, 0, 0);
811 }
812
813 if(nch == '0') {
814 found_digit = TRUE;
815 nch = get(ctx);
816 if(nch == 'x' || nch == 'X')
817 return fpnum_parse16(get, unget, ctx, sign, locinfo);
818 }
819#endif
820
821 while(nch == '0') {
822 found_digit = TRUE;
823 nch = get(ctx);
824 }
825
826 b->b = 0;
827 b->e = 1;
828 b->data[0] = 0;
829 while(nch>='0' && nch<='9') {
830 found_digit = TRUE;
831 if(limb_digits == LIMB_DIGITS) {
832 if(bnum_idx(b, b->b-1) == bnum_idx(b, b->e)) break;
833 else {
834 b->b--;
835 b->data[bnum_idx(b, b->b)] = 0;
836 limb_digits = 0;
837 }
838 }
839
840 b->data[bnum_idx(b, b->b)] = b->data[bnum_idx(b, b->b)] * 10 + nch - '0';
841 limb_digits++;
842 nch = get(ctx);
843 dp++;
844 }
845 while(nch>='0' && nch<='9') {
846 if(nch != '0') b->data[bnum_idx(b, b->b)] |= 1;
847 nch = get(ctx);
848 dp++;
849 }
850
851 if(nch == *locinfo->lconv->decimal_point) {
852 found_dp = TRUE;
853 nch = get(ctx);
854 }
855
856 /* skip leading '0' */
857 if(nch=='0' && !limb_digits && !b->b) {
858 found_digit = TRUE;
859 while(nch == '0') {
860 nch = get(ctx);
861 dp--;
862 }
863 }
864
865 while(nch>='0' && nch<='9') {
866 found_digit = TRUE;
867 if(limb_digits == LIMB_DIGITS) {
868 if(bnum_idx(b, b->b-1) == bnum_idx(b, b->e)) break;
869 else {
870 b->b--;
871 b->data[bnum_idx(b, b->b)] = 0;
872 limb_digits = 0;
873 }
874 }
875
876 b->data[bnum_idx(b, b->b)] = b->data[bnum_idx(b, b->b)] * 10 + nch - '0';
877 limb_digits++;
878 nch = get(ctx);
879 }
880 while(nch>='0' && nch<='9') {
881 if(nch != '0') b->data[bnum_idx(b, b->b)] |= 1;
882 nch = get(ctx);
883 }
884
885 if(!found_digit) {
886 if(nch != WEOF) unget(ctx);
887 if(found_dp) unget(ctx);
888 if(found_sign) unget(ctx);
889 return fpnum(0, 0, 0, 0);
890 }
891
892 if(nch=='e' || nch=='E' || nch=='d' || nch=='D') {
893 int e=0, s=1;
894
895 nch = get(ctx);
896 if(nch == '-') {
897 found_sign = TRUE;
898 s = -1;
899 nch = get(ctx);
900 } else if(nch == '+') {
901 found_sign = TRUE;
902 nch = get(ctx);
903 } else {
904 found_sign = FALSE;
905 }
906
907 if(nch>='0' && nch<='9') {
908 while(nch>='0' && nch<='9') {
909 if(e>INT_MAX/10 || e*10>INT_MAX-nch+'0')
910 e = INT_MAX;
911 else
912 e = e*10+nch-'0';
913 nch = get(ctx);
914 }
915 if(nch != WEOF) unget(ctx);
916 e *= s;
917
918 if(e<0 && dp<INT_MIN-e) dp = INT_MIN;
919 else if(e>0 && dp>INT_MAX-e) dp = INT_MAX;
920 else dp += e;
921 } else {
922 if(nch != WEOF) unget(ctx);
923 if(found_sign) unget(ctx);
924 unget(ctx);
925 }
926 } else if(nch != WEOF) {
927 unget(ctx);
928 }
929
930 if(!b->data[bnum_idx(b, b->e-1)])
931 return fpnum(sign, 0, 0, 0);
932
933 /* Fill last limb with 0 if needed */
934 if(b->b+1 != b->e) {
935 for(; limb_digits != LIMB_DIGITS; limb_digits++)
936 b->data[bnum_idx(b, b->b)] *= 10;
937 }
938 for(; bnum_idx(b, b->b) < bnum_idx(b, b->e); b->b++) {
939 if(b->data[bnum_idx(b, b->b)]) break;
940 }
941
942 /* move decimal point to limb boundary */
943 if(limb_digits==dp && b->b==b->e-1)
944 return fpnum(sign, 0, b->data[bnum_idx(b, b->e-1)], FP_ROUND_ZERO);
945 off = (dp - limb_digits) % LIMB_DIGITS;
946 if(off < 0) off += LIMB_DIGITS;
947 if(off) bnum_mult(b, p10s[off]);
948
949 if(dp-1 > (ldouble ? DBL80_MAX_10_EXP : DBL_MAX_10_EXP))
950 return fpnum(sign, INT_MAX, 1, FP_ROUND_ZERO);
951 /* Count part of exponent stored in denormalized mantissa. */
952 /* Increase exponent range to handle subnormals. */
953 if(dp-1 < (ldouble ? DBL80_MIN_10_EXP : DBL_MIN_10_EXP-DBL_DIG-18))
954 return fpnum(sign, INT_MIN, 1, FP_ROUND_ZERO);
955
956 while(dp > 3*LIMB_DIGITS) {
957 if(bnum_rshift(b, 9)) dp -= LIMB_DIGITS;
958 e2 += 9;
959 }
960 while(dp <= 2*LIMB_DIGITS) {
961 if(bnum_lshift(b, 29)) dp += LIMB_DIGITS;
962 e2 -= 29;
963 }
964 /* Make sure most significant mantissa bit will be set */
965 while(b->data[bnum_idx(b, b->e-1)] <= 9) {
966 bnum_lshift(b, 1);
967 e2--;
968 }
969 while(!bnum_to_mant(b, &m)) {
970 bnum_rshift(b, 1);
971 e2++;
972 }
973
974 if(b->e-4 >= b->b && b->data[bnum_idx(b, b->e-4)]) {
975 if(b->data[bnum_idx(b, b->e-4)] > LIMB_MAX/2) round = FP_ROUND_UP;
976 else if(b->data[bnum_idx(b, b->e-4)] == LIMB_MAX/2) round = FP_ROUND_EVEN;
977 else round = FP_ROUND_DOWN;
978 }
980 for(i=b->e-5; i>=b->b; i--) {
981 if(!b->data[bnum_idx(b, b->b)]) continue;
983 else round = FP_ROUND_DOWN;
984 }
985 }
986
987 return fpnum(sign, e2, m, round);
988}
989
990struct fpnum fpnum_parse(wchar_t (*get)(void *ctx), void (*unget)(void *ctx),
991 void *ctx, pthreadlocinfo locinfo, BOOL ldouble)
992{
993 if(!ldouble) {
994#ifdef _MSC_VER
995 BYTE bnum_data[FIELD_OFFSET(struct bnum, data) + BNUM_PREC64 * sizeof(DWORD)];
996#else
997 BYTE bnum_data[FIELD_OFFSET(struct bnum, data[BNUM_PREC64])];
998#endif
999 struct bnum *b = (struct bnum*)bnum_data;
1000
1001 b->size = BNUM_PREC64;
1002 return fpnum_parse_bnum(get, unget, ctx, locinfo, ldouble, b);
1003 } else {
1004#ifdef _MSC_VER
1005 BYTE bnum_data[FIELD_OFFSET(struct bnum, data) + BNUM_PREC80 * sizeof(DWORD)];
1006#else
1007 BYTE bnum_data[FIELD_OFFSET(struct bnum, data[BNUM_PREC80])];
1008#endif
1009 struct bnum *b = (struct bnum*)bnum_data;
1010
1011 b->size = BNUM_PREC80;
1012 return fpnum_parse_bnum(get, unget, ctx, locinfo, ldouble, b);
1013 }
1014}
1015
1016static wchar_t strtod_str_get(void *ctx)
1017{
1018 const char **p = ctx;
1019 if (!**p) return WEOF;
1020 return *(*p)++;
1021}
1022
1023static void strtod_str_unget(void *ctx)
1024{
1025 const char **p = ctx;
1026 (*p)--;
1027}
1028
1029static inline double strtod_helper(const char *str, char **end, _locale_t locale, int *perr)
1030{
1032 const char *beg, *p;
1033 struct fpnum fp;
1034 double ret;
1035 int err;
1036
1037 if (perr) *perr = 0;
1038#if _MSVCR_VER == 0
1039 else *_errno() = 0;
1040#endif
1041
1042 if (!MSVCRT_CHECK_PMT(str != NULL)) {
1043 if (end) *end = NULL;
1044 return 0;
1045 }
1046
1047 if (!locale)
1048 locinfo = get_locinfo();
1049 else
1050 locinfo = locale->locinfo;
1051
1052 p = str;
1053 while(_isspace_l((unsigned char)*p, locale))
1054 p++;
1055 beg = p;
1056
1058 if (end) *end = (p == beg ? (char*)str : (char*)p);
1059
1060 err = fpnum_double(&fp, &ret);
1061 if (perr) *perr = err;
1062 else if(err) *_errno() = err;
1063 return ret;
1064}
1065
1066/*********************************************************************
1067 * _strtod_l (MSVCRT.@)
1068 */
1069double CDECL _strtod_l(const char *str, char **end, _locale_t locale)
1070{
1071 return strtod_helper(str, end, locale, NULL);
1072}
1073
1074/*********************************************************************
1075 * strtod (MSVCRT.@)
1076 */
1077double CDECL strtod( const char *str, char **end )
1078{
1079 return _strtod_l( str, end, NULL );
1080}
1081
1082#if _MSVCR_VER>=120
1083
1084/*********************************************************************
1085 * strtof_l (MSVCR120.@)
1086 */
1087float CDECL _strtof_l( const char *str, char **end, _locale_t locale )
1088{
1089 double ret = _strtod_l(str, end, locale);
1090 if (ret && isfinite(ret)) {
1091 float f = ret;
1092 if (!f || !isfinite(f))
1093 *_errno() = ERANGE;
1094 }
1095 return ret;
1096}
1097
1098/*********************************************************************
1099 * strtof (MSVCR120.@)
1100 */
1101float CDECL strtof( const char *str, char **end )
1102{
1103 return _strtof_l(str, end, NULL);
1104}
1105
1106#endif /* _MSVCR_VER>=120 */
1107
1108/*********************************************************************
1109 * atof (MSVCRT.@)
1110 */
1111double CDECL atof( const char *str )
1112{
1113 return _strtod_l(str, NULL, NULL);
1114}
1115
1116/*********************************************************************
1117 * _atof_l (MSVCRT.@)
1118 */
1119double CDECL _atof_l( const char *str, _locale_t locale)
1120{
1121 return _strtod_l(str, NULL, locale);
1122}
1123
1124/*********************************************************************
1125 * _atoflt_l (MSVCRT.@)
1126 */
1128{
1129 double d;
1130 int err;
1131
1133 value->f = d;
1134 if(isinf(value->f))
1135 return _OVERFLOW;
1136 if((d!=0 || err) && value->f>-FLT_MIN && value->f<FLT_MIN)
1137 return _UNDERFLOW;
1138 return 0;
1139}
1140
1141/*********************************************************************
1142 * _atoflt (MSVCR100.@)
1143 */
1145{
1146 return _atoflt_l(value, str, NULL);
1147}
1148
1149/*********************************************************************
1150 * _atodbl_l (MSVCRT.@)
1151 */
1153{
1154 int err;
1155
1157 if(isinf(value->x))
1158 return _OVERFLOW;
1159 if((value->x!=0 || err) && value->x>-DBL_MIN && value->x<DBL_MIN)
1160 return _UNDERFLOW;
1161 return 0;
1162}
1163
1164/*********************************************************************
1165 * _atodbl (MSVCRT.@)
1166 */
1168{
1169 return _atodbl_l(value, str, NULL);
1170}
1171
1172/*********************************************************************
1173 * _strcoll_l (MSVCRT.@)
1174 */
1175int CDECL _strcoll_l( const char* str1, const char* str2, _locale_t locale )
1176{
1178
1179 if(!locale)
1180 locinfo = get_locinfo();
1181 else
1182 locinfo = locale->locinfo;
1183
1184 if(!locinfo->lc_handle[LC_COLLATE])
1185 return strcmp(str1, str2);
1187 str1, -1, str2, -1)-CSTR_EQUAL;
1188}
1189
1190/*********************************************************************
1191 * strcoll (MSVCRT.@)
1192 */
1193int CDECL strcoll( const char* str1, const char* str2 )
1194{
1195 return _strcoll_l(str1, str2, NULL);
1196}
1197
1198/*********************************************************************
1199 * _stricoll_l (MSVCRT.@)
1200 */
1201int CDECL _stricoll_l( const char* str1, const char* str2, _locale_t locale )
1202{
1204
1205 if(!locale)
1206 locinfo = get_locinfo();
1207 else
1208 locinfo = locale->locinfo;
1209
1210 if(!locinfo->lc_handle[LC_COLLATE])
1211 return _stricmp(str1, str2);
1213 str1, -1, str2, -1)-CSTR_EQUAL;
1214}
1215
1216/*********************************************************************
1217 * _stricoll (MSVCRT.@)
1218 */
1219int CDECL _stricoll( const char* str1, const char* str2 )
1220{
1221 return _stricoll_l(str1, str2, NULL);
1222}
1223
1224/*********************************************************************
1225 * _strncoll_l (MSVCRT.@)
1226 */
1227int CDECL _strncoll_l( const char* str1, const char* str2, size_t count, _locale_t locale )
1228{
1230
1231 if(!locale)
1232 locinfo = get_locinfo();
1233 else
1234 locinfo = locale->locinfo;
1235
1236 if(!locinfo->lc_handle[LC_COLLATE])
1237 return strncmp(str1, str2, count);
1241}
1242
1243/*********************************************************************
1244 * _strncoll (MSVCRT.@)
1245 */
1246int CDECL _strncoll( const char* str1, const char* str2, size_t count )
1247{
1248 return _strncoll_l(str1, str2, count, NULL);
1249}
1250
1251/*********************************************************************
1252 * _strnicoll_l (MSVCRT.@)
1253 */
1254int CDECL _strnicoll_l( const char* str1, const char* str2, size_t count, _locale_t locale )
1255{
1257
1258 if(!locale)
1259 locinfo = get_locinfo();
1260 else
1261 locinfo = locale->locinfo;
1262
1263 if(!locinfo->lc_handle[LC_COLLATE])
1264 return _strnicmp(str1, str2, count);
1268}
1269
1270/*********************************************************************
1271 * _strnicoll (MSVCRT.@)
1272 */
1273int CDECL _strnicoll( const char* str1, const char* str2, size_t count )
1274{
1275 return _strnicoll_l(str1, str2, count, NULL);
1276}
1277
1278/*********************************************************************
1279 * strncpy (MSVCRT.@)
1280 */
1281char* __cdecl strncpy(char *dst, const char *src, size_t len)
1282{
1283 size_t i;
1284
1285 for(i=0; i<len; i++)
1286 if((dst[i] = src[i]) == '\0') break;
1287
1288 while (i < len) dst[i++] = 0;
1289
1290 return dst;
1291}
1292
1293/******************************************************************
1294 * strncpy_s (MSVCRT.@)
1295 */
1296int __cdecl strncpy_s( char *dst, size_t elem, const char *src, size_t count )
1297{
1298 char *p = dst;
1299 BOOL truncate = (count == _TRUNCATE);
1300
1301 TRACE("(%p %Iu %s %Iu)\n", dst, elem, debugstr_a(src), count);
1302
1303 if (!count)
1304 {
1305 if (dst && elem) *dst = 0;
1306 return 0;
1307 }
1308
1309 if (!MSVCRT_CHECK_PMT(dst != NULL)) return EINVAL;
1310 if (!MSVCRT_CHECK_PMT(elem != 0)) return EINVAL;
1311 if (!MSVCRT_CHECK_PMT(src != NULL))
1312 {
1313 *dst = 0;
1314 return EINVAL;
1315 }
1316
1317 while (elem && count && *src)
1318 {
1319 *p++ = *src++;
1320 elem--;
1321 count--;
1322 }
1323 if (!elem && truncate)
1324 {
1325 *(p-1) = 0;
1326 return STRUNCATE;
1327 }
1328 else if (!elem)
1329 {
1330 *dst = 0;
1331 return ERANGE;
1332 }
1333 *p = 0;
1334 return 0;
1335}
1336
1337/*********************************************************************
1338 * strcpy (MSVCRT.@)
1339 */
1340char* CDECL strcpy(char *dst, const char *src)
1341{
1342 char *ret = dst;
1343 while ((*dst++ = *src++));
1344 return ret;
1345}
1346
1347/*********************************************************************
1348 * strcpy_s (MSVCRT.@)
1349 */
1350int CDECL strcpy_s( char* dst, size_t elem, const char* src )
1351{
1352 size_t i;
1353 if (!MSVCRT_CHECK_PMT(dst != 0)) return EINVAL;
1354 if (!MSVCRT_CHECK_PMT(elem != 0)) return EINVAL;
1355 if (!MSVCRT_CHECK_PMT(src != NULL))
1356 {
1357 dst[0] = '\0';
1358 return EINVAL;
1359 }
1360
1361 for(i = 0; i < elem; i++)
1362 {
1363 if((dst[i] = src[i]) == '\0') return 0;
1364 }
1365 MSVCRT_INVALID_PMT("dst[elem] is too small", ERANGE);
1366 dst[0] = '\0';
1367 return ERANGE;
1368}
1369
1370/*********************************************************************
1371 * strcat_s (MSVCRT.@)
1372 */
1373int CDECL strcat_s( char* dst, size_t elem, const char* src )
1374{
1375 size_t i, j;
1376 if (!MSVCRT_CHECK_PMT(dst != 0)) return EINVAL;
1377 if (!MSVCRT_CHECK_PMT(elem != 0)) return EINVAL;
1378 if (!MSVCRT_CHECK_PMT(src != NULL))
1379 {
1380 dst[0] = '\0';
1381 return EINVAL;
1382 }
1383
1384 for(i = 0; i < elem; i++)
1385 {
1386 if(dst[i] == '\0')
1387 {
1388 for(j = 0; (j + i) < elem; j++)
1389 {
1390 if((dst[j + i] = src[j]) == '\0') return 0;
1391 }
1392 }
1393 }
1394 /* Set the first element to 0, not the first element after the skipped part */
1395 MSVCRT_INVALID_PMT("dst[elem] is too small", ERANGE);
1396 dst[0] = '\0';
1397 return ERANGE;
1398}
1399
1400/*********************************************************************
1401 * strcat (MSVCRT.@)
1402 */
1403char* __cdecl strcat( char *dst, const char *src )
1404{
1405 char *d = dst;
1406 while (*d) d++;
1407 while ((*d++ = *src++));
1408 return dst;
1409}
1410
1411/*********************************************************************
1412 * strncat_s (MSVCRT.@)
1413 */
1414int CDECL strncat_s( char* dst, size_t elem, const char* src, size_t count )
1415{
1416 size_t i, j;
1417
1418 if (!MSVCRT_CHECK_PMT(dst != 0)) return EINVAL;
1419 if (!MSVCRT_CHECK_PMT(elem != 0)) return EINVAL;
1420 if (count == 0) return 0;
1421
1422 if (!MSVCRT_CHECK_PMT(src != NULL))
1423 {
1424 *dst = 0;
1425 return EINVAL;
1426 }
1427
1428 for (i = 0; i < elem; i++) if (!dst[i]) break;
1429
1430 if (i == elem)
1431 {
1432 MSVCRT_INVALID_PMT("dst[elem] is not NULL terminated\n", EINVAL);
1433 *dst = 0;
1434 return EINVAL;
1435 }
1436
1437 for (j = 0; (j + i) < elem; j++)
1438 {
1439 if(count == _TRUNCATE && j + i == elem - 1)
1440 {
1441 dst[j + i] = '\0';
1442 return STRUNCATE;
1443 }
1444 if(j == count || (dst[j + i] = src[j]) == '\0')
1445 {
1446 dst[j + i] = '\0';
1447 return 0;
1448 }
1449 }
1450
1451 MSVCRT_INVALID_PMT("dst[elem] is too small", ERANGE);
1452 dst[0] = '\0';
1453 return ERANGE;
1454}
1455
1456/*********************************************************************
1457 * strncat (MSVCRT.@)
1458 */
1459char* __cdecl strncat(char *dst, const char *src, size_t len)
1460{
1461 char *d = dst;
1462 while (*d) d++;
1463 for ( ; len && *src; d++, src++, len--) *d = *src;
1464 *d = 0;
1465 return dst;
1466}
1467
1468/*********************************************************************
1469 * _strxfrm_l (MSVCRT.@)
1470 */
1471size_t CDECL _strxfrm_l( char *dest, const char *src,
1472 size_t len, _locale_t locale )
1473{
1475 int ret;
1476
1477 if(!MSVCRT_CHECK_PMT(src)) return INT_MAX;
1478 if(!MSVCRT_CHECK_PMT(dest || !len)) return INT_MAX;
1479
1480 if(len > INT_MAX) {
1481 FIXME("len > INT_MAX not supported\n");
1482 len = INT_MAX;
1483 }
1484
1485 if(!locale)
1486 locinfo = get_locinfo();
1487 else
1488 locinfo = locale->locinfo;
1489
1490 if(!locinfo->lc_handle[LC_COLLATE]) {
1491 strncpy(dest, src, len);
1492 return strlen(src);
1493 }
1494
1495 ret = LCMapStringA(locinfo->lc_handle[LC_COLLATE],
1496 LCMAP_SORTKEY, src, -1, NULL, 0);
1497 if(!ret) {
1498 if(len) dest[0] = 0;
1499 *_errno() = EILSEQ;
1500 return INT_MAX;
1501 }
1502 if(!len) return ret-1;
1503
1504 if(ret > len) {
1505 dest[0] = 0;
1506 *_errno() = ERANGE;
1507 return ret-1;
1508 }
1509
1510 return LCMapStringA(locinfo->lc_handle[LC_COLLATE],
1511 LCMAP_SORTKEY, src, -1, dest, len) - 1;
1512}
1513
1514/*********************************************************************
1515 * strxfrm (MSVCRT.@)
1516 */
1517size_t CDECL strxfrm( char *dest, const char *src, size_t len )
1518{
1519 return _strxfrm_l(dest, src, len, NULL);
1520}
1521
1522/********************************************************************
1523 * __STRINGTOLD_L (MSVCR80.@)
1524 */
1525#ifdef __REACTOS__
1526int CDECL __STRINGTOLD_L( MSVCRT__LDOUBLE *value_, char **endptr,
1527#else
1529#endif
1530 const char *str, int flags, _locale_t locale )
1531{
1532#ifdef __REACTOS__
1533 WINE_BROKEN_LDOUBLE value[1];
1534#endif
1536 const char *beg, *p;
1537 int err, ret = 0;
1538 struct fpnum fp;
1539
1540 if (flags) FIXME("flags not supported: %x\n", flags);
1541
1542 if (!locale)
1543 locinfo = get_locinfo();
1544 else
1545 locinfo = locale->locinfo;
1546
1547 p = str;
1548 while (_isspace_l((unsigned char)*p, locale))
1549 p++;
1550 beg = p;
1551
1553 if (endptr) *endptr = (p == beg ? (char*)str : (char*)p);
1554 if (p == beg) ret = 4;
1555
1556 err = fpnum_ldouble(&fp, value);
1557 if (err) ret = (value->x80[2] & 0x7fff ? 2 : 1);
1558#ifdef __REACTOS__
1559 memcpy(value_, value, sizeof(*value_));
1560#endif
1561 return ret;
1562}
1563
1564/********************************************************************
1565 * __STRINGTOLD (MSVCRT.@)
1566 */
1567int CDECL __STRINGTOLD( MSVCRT__LDOUBLE *value, char **endptr, const char *str, int flags )
1568{
1569 return __STRINGTOLD_L( value, endptr, str, flags, NULL );
1570}
1571
1572/********************************************************************
1573 * _atoldbl_l (MSVCRT.@)
1574 */
1576{
1577 char *endptr;
1578 switch(__STRINGTOLD_L( value, &endptr, str, 0, locale ))
1579 {
1580 case 1: return _UNDERFLOW;
1581 case 2: return _OVERFLOW;
1582 default: return 0;
1583 }
1584}
1585
1586/********************************************************************
1587 * _atoldbl (MSVCRT.@)
1588 */
1590{
1591 return _atoldbl_l( (MSVCRT__LDOUBLE*)value, str, NULL );
1592}
1593
1594/*********************************************************************
1595 * strlen (MSVCRT.@)
1596 */
1597size_t __cdecl strlen(const char *str)
1598{
1599 const char *s = str;
1600 while (*s) s++;
1601 return s - str;
1602}
1603
1604/******************************************************************
1605 * strnlen (MSVCRT.@)
1606 */
1607size_t CDECL strnlen(const char *s, size_t maxlen)
1608{
1609 size_t i;
1610
1611 for(i=0; i<maxlen; i++)
1612 if(!s[i]) break;
1613
1614 return i;
1615}
1616
1617/*********************************************************************
1618 * _strtoi64_l (MSVCRT.@)
1619 *
1620 * FIXME: locale parameter is ignored
1621 */
1622__int64 CDECL _strtoi64_l(const char *nptr, char **endptr, int base, _locale_t locale)
1623{
1624 const char *p = nptr;
1625 BOOL negative = FALSE;
1626 BOOL got_digit = FALSE;
1627 __int64 ret = 0;
1628
1629 TRACE("(%s %p %d %p)\n", debugstr_a(nptr), endptr, base, locale);
1630
1631 if (!MSVCRT_CHECK_PMT(nptr != NULL)) return 0;
1632 if (!MSVCRT_CHECK_PMT(base == 0 || base >= 2)) return 0;
1633 if (!MSVCRT_CHECK_PMT(base <= 36)) return 0;
1634
1635 while(_isspace_l((unsigned char)*nptr, locale)) nptr++;
1636
1637 if(*nptr == '-') {
1638 negative = TRUE;
1639 nptr++;
1640 } else if(*nptr == '+')
1641 nptr++;
1642
1643 if((base==0 || base==16) && *nptr=='0' && _tolower_l(*(nptr+1), locale)=='x') {
1644 base = 16;
1645 nptr += 2;
1646 }
1647
1648 if(base == 0) {
1649 if(*nptr=='0')
1650 base = 8;
1651 else
1652 base = 10;
1653 }
1654
1655 while(*nptr) {
1656 char cur = _tolower_l(*nptr, locale);
1657 int v;
1658
1659 if(cur>='0' && cur<='9') {
1660 if(cur >= '0'+base)
1661 break;
1662 v = cur-'0';
1663 } else {
1664 if(cur<'a' || cur>='a'+base-10)
1665 break;
1666 v = cur-'a'+10;
1667 }
1668 got_digit = TRUE;
1669
1670 if(negative)
1671 v = -v;
1672
1673 nptr++;
1674
1675 if(!negative && (ret>I64_MAX/base || ret*base>I64_MAX-v)) {
1676 ret = I64_MAX;
1677 *_errno() = ERANGE;
1678 } else if(negative && (ret<I64_MIN/base || ret*base<I64_MIN-v)) {
1679 ret = I64_MIN;
1680 *_errno() = ERANGE;
1681 } else
1682 ret = ret*base + v;
1683 }
1684
1685 if(endptr)
1686 *endptr = (char*)(got_digit ? nptr : p);
1687
1688 return ret;
1689}
1690
1691/*********************************************************************
1692 * _strtoi64 (MSVCRT.@)
1693 */
1694__int64 CDECL _strtoi64(const char *nptr, char **endptr, int base)
1695{
1696 return _strtoi64_l(nptr, endptr, base, NULL);
1697}
1698
1699/*********************************************************************
1700 * _atoi_l (MSVCRT.@)
1701 */
1703{
1705
1706 if(ret > INT_MAX) {
1707 ret = INT_MAX;
1708 *_errno() = ERANGE;
1709 } else if(ret < INT_MIN) {
1710 ret = INT_MIN;
1711 *_errno() = ERANGE;
1712 }
1713 return ret;
1714}
1715
1716/*********************************************************************
1717 * atoi (MSVCRT.@)
1718 */
1719#if _MSVCR_VER == 0
1720int __cdecl atoi(const char *str)
1721{
1722 BOOL minus = FALSE;
1723 int ret = 0;
1724
1725 if(!str)
1726 return 0;
1727
1728 while(_isspace_l((unsigned char)*str, NULL)) str++;
1729
1730 if(*str == '+') {
1731 str++;
1732 }else if(*str == '-') {
1733 minus = TRUE;
1734 str++;
1735 }
1736
1737 while(*str>='0' && *str<='9') {
1738 ret = ret*10+*str-'0';
1739 str++;
1740 }
1741
1742 return minus ? -ret : ret;
1743}
1744#else
1745int CDECL atoi(const char *str)
1746{
1747 return _atoi_l(str, NULL);
1748}
1749#endif
1750
1751/******************************************************************
1752 * _atoi64_l (MSVCRT.@)
1753 */
1755{
1756 return _strtoi64_l(str, NULL, 10, locale);
1757}
1758
1759/******************************************************************
1760 * _atoi64 (MSVCRT.@)
1761 */
1763{
1764 return _strtoi64_l(str, NULL, 10, NULL);
1765}
1766
1767/******************************************************************
1768 * _atol_l (MSVCRT.@)
1769 */
1771{
1773
1774 if(ret > LONG_MAX) {
1775 ret = LONG_MAX;
1776 *_errno() = ERANGE;
1777 } else if(ret < LONG_MIN) {
1778 ret = LONG_MIN;
1779 *_errno() = ERANGE;
1780 }
1781 return ret;
1782}
1783
1784/******************************************************************
1785 * atol (MSVCRT.@)
1786 */
1788{
1789#if _MSVCR_VER == 0
1790 return atoi(str);
1791#else
1792 return _atol_l(str, NULL);
1793#endif
1794}
1795
1796#if _MSVCR_VER>=120
1797
1798/******************************************************************
1799 * _atoll_l (MSVCR120.@)
1800 */
1802{
1803 return _strtoi64_l(str, NULL, 10, locale);
1804}
1805
1806/******************************************************************
1807 * atoll (MSVCR120.@)
1808 */
1809__int64 CDECL atoll(const char* str)
1810{
1811 return _atoll_l(str, NULL);
1812}
1813
1814#endif /* _MSVCR_VER>=120 */
1815
1816/******************************************************************
1817 * _strtol_l (MSVCRT.@)
1818 */
1820 char** end, int base, _locale_t locale)
1821{
1822 __int64 ret = _strtoi64_l(nptr, end, base, locale);
1823
1824 if(ret > LONG_MAX) {
1825 ret = LONG_MAX;
1826 *_errno() = ERANGE;
1827 } else if(ret < LONG_MIN) {
1828 ret = LONG_MIN;
1829 *_errno() = ERANGE;
1830 }
1831
1832 return ret;
1833}
1834
1835/******************************************************************
1836 * strtol (MSVCRT.@)
1837 */
1838__msvcrt_long CDECL strtol(const char* nptr, char** end, int base)
1839{
1840 return _strtol_l(nptr, end, base, NULL);
1841}
1842
1843/******************************************************************
1844 * _strtoul_l (MSVCRT.@)
1845 */
1846__msvcrt_ulong CDECL _strtoul_l(const char* nptr, char** end, int base, _locale_t locale)
1847{
1848 __int64 ret = _strtoi64_l(nptr, end, base, locale);
1849
1850 if(ret > ULONG_MAX) {
1851 ret = ULONG_MAX;
1852 *_errno() = ERANGE;
1853 }else if(ret < -(__int64)ULONG_MAX) {
1854 ret = 1;
1855 *_errno() = ERANGE;
1856 }
1857
1858 return ret;
1859}
1860
1861/******************************************************************
1862 * strtoul (MSVCRT.@)
1863 */
1864__msvcrt_ulong CDECL strtoul(const char* nptr, char** end, int base)
1865{
1866 return _strtoul_l(nptr, end, base, NULL);
1867}
1868
1869/*********************************************************************
1870 * _strtoui64_l (MSVCRT.@)
1871 *
1872 * FIXME: locale parameter is ignored
1873 */
1874unsigned __int64 CDECL _strtoui64_l(const char *nptr, char **endptr, int base, _locale_t locale)
1875{
1876 const char *p = nptr;
1877 BOOL negative = FALSE;
1878 BOOL got_digit = FALSE;
1879 unsigned __int64 ret = 0;
1880
1881 TRACE("(%s %p %d %p)\n", debugstr_a(nptr), endptr, base, locale);
1882
1883 if (!MSVCRT_CHECK_PMT(nptr != NULL)) return 0;
1884 if (!MSVCRT_CHECK_PMT(base == 0 || base >= 2)) return 0;
1885 if (!MSVCRT_CHECK_PMT(base <= 36)) return 0;
1886
1887 while(_isspace_l((unsigned char)*nptr, locale)) nptr++;
1888
1889 if(*nptr == '-') {
1890 negative = TRUE;
1891 nptr++;
1892 } else if(*nptr == '+')
1893 nptr++;
1894
1895 if((base==0 || base==16) && *nptr=='0' && _tolower_l(*(nptr+1), locale)=='x') {
1896 base = 16;
1897 nptr += 2;
1898 }
1899
1900 if(base == 0) {
1901 if(*nptr=='0')
1902 base = 8;
1903 else
1904 base = 10;
1905 }
1906
1907 while(*nptr) {
1908 char cur = _tolower_l(*nptr, locale);
1909 int v;
1910
1911 if(cur>='0' && cur<='9') {
1912 if(cur >= '0'+base)
1913 break;
1914 v = *nptr-'0';
1915 } else {
1916 if(cur<'a' || cur>='a'+base-10)
1917 break;
1918 v = cur-'a'+10;
1919 }
1920 got_digit = TRUE;
1921
1922 nptr++;
1923
1924 if(ret>UI64_MAX/base || ret*base>UI64_MAX-v) {
1925 ret = UI64_MAX;
1926 *_errno() = ERANGE;
1927 } else
1928 ret = ret*base + v;
1929 }
1930
1931 if(endptr)
1932 *endptr = (char*)(got_digit ? nptr : p);
1933
1934 return negative ? -ret : ret;
1935}
1936
1937/*********************************************************************
1938 * _strtoui64 (MSVCRT.@)
1939 */
1940unsigned __int64 CDECL _strtoui64(const char *nptr, char **endptr, int base)
1941{
1942 return _strtoui64_l(nptr, endptr, base, NULL);
1943}
1944
1945static int ltoa_helper(__msvcrt_long value, char *str, size_t size, int radix)
1946{
1948 unsigned int digit;
1949 BOOL is_negative;
1950 char buffer[33], *pos;
1951 size_t len;
1952
1953 if (value < 0 && radix == 10)
1954 {
1955 is_negative = TRUE;
1956 val = -value;
1957 }
1958 else
1959 {
1960 is_negative = FALSE;
1961 val = value;
1962 }
1963
1964 pos = buffer + 32;
1965 *pos = '\0';
1966
1967 do
1968 {
1969 digit = val % radix;
1970 val /= radix;
1971
1972 if (digit < 10)
1973 *--pos = '0' + digit;
1974 else
1975 *--pos = 'a' + digit - 10;
1976 }
1977 while (val != 0);
1978
1979 if (is_negative)
1980 *--pos = '-';
1981
1982 len = buffer + 33 - pos;
1983 if (len > size)
1984 {
1985 size_t i;
1986 char *p = str;
1987
1988 /* Copy the temporary buffer backwards up to the available number of
1989 * characters. Don't copy the negative sign if present. */
1990
1991 if (is_negative)
1992 {
1993 p++;
1994 size--;
1995 }
1996
1997 for (pos = buffer + 31, i = 0; i < size; i++)
1998 *p++ = *pos--;
1999
2000 str[0] = '\0';
2001 MSVCRT_INVALID_PMT("str[size] is too small", ERANGE);
2002 return ERANGE;
2003 }
2004
2005 memcpy(str, pos, len);
2006 return 0;
2007}
2008
2009static int ltow_helper(__msvcrt_long value, wchar_t *str, size_t size, int radix)
2010{
2012 unsigned int digit;
2013 BOOL is_negative;
2014 wchar_t buffer[33], *pos;
2015 size_t len;
2016
2017 if (value < 0 && radix == 10)
2018 {
2019 is_negative = TRUE;
2020 val = -value;
2021 }
2022 else
2023 {
2024 is_negative = FALSE;
2025 val = value;
2026 }
2027
2028 pos = buffer + 32;
2029 *pos = '\0';
2030
2031 do
2032 {
2033 digit = val % radix;
2034 val /= radix;
2035
2036 if (digit < 10)
2037 *--pos = '0' + digit;
2038 else
2039 *--pos = 'a' + digit - 10;
2040 }
2041 while (val != 0);
2042
2043 if (is_negative)
2044 *--pos = '-';
2045
2046 len = buffer + 33 - pos;
2047 if (len > size)
2048 {
2049 size_t i;
2050 wchar_t *p = str;
2051
2052 /* Copy the temporary buffer backwards up to the available number of
2053 * characters. Don't copy the negative sign if present. */
2054
2055 if (is_negative)
2056 {
2057 p++;
2058 size--;
2059 }
2060
2061 for (pos = buffer + 31, i = 0; i < size; i++)
2062 *p++ = *pos--;
2063
2064 str[0] = '\0';
2065 MSVCRT_INVALID_PMT("str[size] is too small", ERANGE);
2066 return ERANGE;
2067 }
2068
2069 memcpy(str, pos, len * sizeof(wchar_t));
2070 return 0;
2071}
2072
2073/*********************************************************************
2074 * _ltoa_s (MSVCRT.@)
2075 */
2077{
2078 if (!MSVCRT_CHECK_PMT(str != NULL)) return EINVAL;
2079 if (!MSVCRT_CHECK_PMT(size > 0)) return EINVAL;
2080 if (!MSVCRT_CHECK_PMT(radix >= 2 && radix <= 36))
2081 {
2082 str[0] = '\0';
2083 return EINVAL;
2084 }
2085
2086 return ltoa_helper(value, str, size, radix);
2087}
2088
2089/*********************************************************************
2090 * _ltow_s (MSVCRT.@)
2091 */
2092int CDECL _ltow_s(__msvcrt_long value, wchar_t *str, size_t size, int radix)
2093{
2094 if (!MSVCRT_CHECK_PMT(str != NULL)) return EINVAL;
2095 if (!MSVCRT_CHECK_PMT(size > 0)) return EINVAL;
2096 if (!MSVCRT_CHECK_PMT(radix >= 2 && radix <= 36))
2097 {
2098 str[0] = '\0';
2099 return EINVAL;
2100 }
2101
2102 return ltow_helper(value, str, size, radix);
2103}
2104
2105/*********************************************************************
2106 * _itoa_s (MSVCRT.@)
2107 */
2108int CDECL _itoa_s(int value, char *str, size_t size, int radix)
2109{
2110 return _ltoa_s(value, str, size, radix);
2111}
2112
2113/*********************************************************************
2114 * _itoa (MSVCRT.@)
2115 */
2116char* CDECL _itoa(int value, char *str, int radix)
2117{
2118 return ltoa_helper(value, str, SIZE_MAX, radix) ? NULL : str;
2119}
2120
2121/*********************************************************************
2122 * _ltoa (MSVCRT.@)
2123 */
2125{
2126 return ltoa_helper(value, str, SIZE_MAX, radix) ? NULL : str;
2127}
2128
2129/*********************************************************************
2130 * _itow_s (MSVCRT.@)
2131 */
2132int CDECL _itow_s(int value, wchar_t *str, size_t size, int radix)
2133{
2134 return _ltow_s(value, str, size, radix);
2135}
2136
2137/*********************************************************************
2138 * _itow (MSVCRT.@)
2139 */
2140wchar_t* CDECL _itow(int value, wchar_t *str, int radix)
2141{
2142 return ltow_helper(value, str, SIZE_MAX, radix) ? NULL : str;
2143}
2144
2145/*********************************************************************
2146 * _ltow (MSVCRT.@)
2147 */
2148wchar_t* CDECL _ltow(__msvcrt_long value, wchar_t *str, int radix)
2149{
2150 return ltow_helper(value, str, SIZE_MAX, radix) ? NULL : str;
2151}
2152
2153/*********************************************************************
2154 * _ultoa (MSVCRT.@)
2155 */
2157{
2158 char buffer[33], *pos;
2159
2160 pos = &buffer[32];
2161 *pos = '\0';
2162
2163 do {
2164 int digit = value % radix;
2165 value /= radix;
2166
2167 if (digit < 10)
2168 *--pos = '0' + digit;
2169 else
2170 *--pos = 'a' + digit - 10;
2171 } while (value != 0);
2172
2173 memcpy(str, pos, buffer + 33 - pos);
2174 return str;
2175}
2176
2177/*********************************************************************
2178 * _ui64toa (MSVCRT.@)
2179 */
2180char* CDECL _ui64toa(unsigned __int64 value, char *str, int radix)
2181{
2182 char buffer[65], *pos;
2183
2184 pos = &buffer[64];
2185 *pos = '\0';
2186
2187 do {
2188 int digit = value % radix;
2189 value /= radix;
2190
2191 if (digit < 10)
2192 *--pos = '0' + digit;
2193 else
2194 *--pos = 'a' + digit - 10;
2195 } while (value != 0);
2196
2197 memcpy(str, pos, buffer + 65 - pos);
2198 return str;
2199}
2200
2201/*********************************************************************
2202 * _ultow (MSVCRT.@)
2203 */
2204wchar_t* CDECL _ultow(__msvcrt_ulong value, wchar_t *str, int radix)
2205{
2206 wchar_t buffer[33], *pos;
2207
2208 pos = &buffer[32];
2209 *pos = '\0';
2210
2211 do {
2212 int digit = value % radix;
2213 value /= radix;
2214
2215 if (digit < 10)
2216 *--pos = '0' + digit;
2217 else
2218 *--pos = 'a' + digit - 10;
2219 } while (value != 0);
2220
2221 memcpy(str, pos, (buffer + 33 - pos) * sizeof(wchar_t));
2222 return str;
2223}
2224
2225/*********************************************************************
2226 * _ui64tow (MSVCRT.@)
2227 */
2228wchar_t* CDECL _ui64tow(unsigned __int64 value, wchar_t *str, int radix)
2229{
2230 wchar_t buffer[65], *pos;
2231
2232 pos = &buffer[64];
2233 *pos = '\0';
2234
2235 do {
2236 int digit = value % radix;
2237 value /= radix;
2238
2239 if (digit < 10)
2240 *--pos = '0' + digit;
2241 else
2242 *--pos = 'a' + digit - 10;
2243 } while (value != 0);
2244
2245 memcpy(str, pos, (buffer + 65 - pos) * sizeof(wchar_t));
2246 return str;
2247}
2248
2249/*********************************************************************
2250 * _i64toa (MSVCRT.@)
2251 */
2253{
2254 unsigned __int64 val;
2255 BOOL is_negative;
2256 char buffer[65], *pos;
2257
2258 if (value < 0 && radix == 10)
2259 {
2260 is_negative = TRUE;
2261 val = -value;
2262 }
2263 else
2264 {
2265 is_negative = FALSE;
2266 val = value;
2267 }
2268
2269 pos = buffer + 64;
2270 *pos = '\0';
2271
2272 do
2273 {
2274 int digit = val % radix;
2275 val /= radix;
2276
2277 if (digit < 10)
2278 *--pos = '0' + digit;
2279 else
2280 *--pos = 'a' + digit - 10;
2281 }
2282 while (val != 0);
2283
2284 if (is_negative)
2285 *--pos = '-';
2286
2287 memcpy(str, pos, buffer + 65 - pos);
2288 return str;
2289}
2290
2291/*********************************************************************
2292 * _i64tow (MSVCRT.@)
2293 */
2294wchar_t* CDECL _i64tow(__int64 value, wchar_t *str, int radix)
2295{
2296 unsigned __int64 val;
2297 BOOL is_negative;
2298 wchar_t buffer[65], *pos;
2299
2300 if (value < 0 && radix == 10)
2301 {
2302 is_negative = TRUE;
2303 val = -value;
2304 }
2305 else
2306 {
2307 is_negative = FALSE;
2308 val = value;
2309 }
2310
2311 pos = buffer + 64;
2312 *pos = '\0';
2313
2314 do
2315 {
2316 int digit = val % radix;
2317 val /= radix;
2318
2319 if (digit < 10)
2320 *--pos = '0' + digit;
2321 else
2322 *--pos = 'a' + digit - 10;
2323 }
2324 while (val != 0);
2325
2326 if (is_negative)
2327 *--pos = '-';
2328
2329 memcpy(str, pos, (buffer + 65 - pos) * sizeof(wchar_t));
2330 return str;
2331}
2332
2333/*********************************************************************
2334 * _ui64toa_s (MSVCRT.@)
2335 */
2336int CDECL _ui64toa_s(unsigned __int64 value, char *str,
2337 size_t size, int radix)
2338{
2339 char buffer[65], *pos;
2340 int digit;
2341
2342 if (!MSVCRT_CHECK_PMT(str != NULL)) return EINVAL;
2343 if (!MSVCRT_CHECK_PMT(size > 0)) return EINVAL;
2344 if (!MSVCRT_CHECK_PMT(radix >= 2 && radix <= 36))
2345 {
2346 str[0] = '\0';
2347 return EINVAL;
2348 }
2349
2350 pos = buffer+64;
2351 *pos = '\0';
2352
2353 do {
2354 digit = value%radix;
2355 value /= radix;
2356
2357 if(digit < 10)
2358 *--pos = '0'+digit;
2359 else
2360 *--pos = 'a'+digit-10;
2361 }while(value != 0);
2362
2363 if(buffer-pos+65 > size) {
2364 MSVCRT_INVALID_PMT("str[size] is too small", EINVAL);
2365 return EINVAL;
2366 }
2367
2368 memcpy(str, pos, buffer-pos+65);
2369 return 0;
2370}
2371
2372/*********************************************************************
2373 * _ui64tow_s (MSVCRT.@)
2374 */
2375int CDECL _ui64tow_s( unsigned __int64 value, wchar_t *str,
2376 size_t size, int radix )
2377{
2378 wchar_t buffer[65], *pos;
2379 int digit;
2380
2381 if (!MSVCRT_CHECK_PMT(str != NULL)) return EINVAL;
2382 if (!MSVCRT_CHECK_PMT(size > 0)) return EINVAL;
2383 if (!MSVCRT_CHECK_PMT(radix >= 2 && radix <= 36))
2384 {
2385 str[0] = '\0';
2386 return EINVAL;
2387 }
2388
2389 pos = &buffer[64];
2390 *pos = '\0';
2391
2392 do {
2393 digit = value % radix;
2394 value = value / radix;
2395 if (digit < 10)
2396 *--pos = '0' + digit;
2397 else
2398 *--pos = 'a' + digit - 10;
2399 } while (value != 0);
2400
2401 if(buffer-pos+65 > size) {
2402 MSVCRT_INVALID_PMT("str[size] is too small", EINVAL);
2403 return EINVAL;
2404 }
2405
2406 memcpy(str, pos, (buffer-pos+65)*sizeof(wchar_t));
2407 return 0;
2408}
2409
2410/*********************************************************************
2411 * _ultoa_s (MSVCRT.@)
2412 */
2414{
2415 __msvcrt_ulong digit;
2416 char buffer[33], *pos;
2417 size_t len;
2418
2419 if (!str || !size || radix < 2 || radix > 36)
2420 {
2421 if (str && size)
2422 str[0] = '\0';
2423
2424 *_errno() = EINVAL;
2425 return EINVAL;
2426 }
2427
2428 pos = buffer + 32;
2429 *pos = '\0';
2430
2431 do
2432 {
2433 digit = value % radix;
2434 value /= radix;
2435
2436 if (digit < 10)
2437 *--pos = '0' + digit;
2438 else
2439 *--pos = 'a' + digit - 10;
2440 }
2441 while (value != 0);
2442
2443 len = buffer + 33 - pos;
2444 if (len > size)
2445 {
2446 size_t i;
2447 char *p = str;
2448
2449 /* Copy the temporary buffer backwards up to the available number of
2450 * characters. */
2451
2452 for (pos = buffer + 31, i = 0; i < size; i++)
2453 *p++ = *pos--;
2454
2455 str[0] = '\0';
2456 *_errno() = ERANGE;
2457 return ERANGE;
2458 }
2459
2460 memcpy(str, pos, len);
2461 return 0;
2462}
2463
2464/*********************************************************************
2465 * _ultow_s (MSVCRT.@)
2466 */
2467int CDECL _ultow_s(__msvcrt_ulong value, wchar_t *str, size_t size, int radix)
2468{
2469 __msvcrt_ulong digit;
2470 WCHAR buffer[33], *pos;
2471 size_t len;
2472
2473 if (!str || !size || radix < 2 || radix > 36)
2474 {
2475 if (str && size)
2476 str[0] = '\0';
2477
2478 *_errno() = EINVAL;
2479 return EINVAL;
2480 }
2481
2482 pos = buffer + 32;
2483 *pos = '\0';
2484
2485 do
2486 {
2487 digit = value % radix;
2488 value /= radix;
2489
2490 if (digit < 10)
2491 *--pos = '0' + digit;
2492 else
2493 *--pos = 'a' + digit - 10;
2494 }
2495 while (value != 0);
2496
2497 len = buffer + 33 - pos;
2498 if (len > size)
2499 {
2500 size_t i;
2501 WCHAR *p = str;
2502
2503 /* Copy the temporary buffer backwards up to the available number of
2504 * characters. */
2505
2506 for (pos = buffer + 31, i = 0; i < size; i++)
2507 *p++ = *pos--;
2508
2509 str[0] = '\0';
2510 *_errno() = ERANGE;
2511 return ERANGE;
2512 }
2513
2514 memcpy(str, pos, len * sizeof(wchar_t));
2515 return 0;
2516}
2517
2518/*********************************************************************
2519 * _i64toa_s (MSVCRT.@)
2520 */
2521int CDECL _i64toa_s(__int64 value, char *str, size_t size, int radix)
2522{
2523 unsigned __int64 val;
2524 unsigned int digit;
2525 BOOL is_negative;
2526 char buffer[65], *pos;
2527 size_t len;
2528
2529 if (!MSVCRT_CHECK_PMT(str != NULL)) return EINVAL;
2530 if (!MSVCRT_CHECK_PMT(size > 0)) return EINVAL;
2531 if (!MSVCRT_CHECK_PMT(radix >= 2 && radix <= 36))
2532 {
2533 str[0] = '\0';
2534 return EINVAL;
2535 }
2536
2537 if (value < 0 && radix == 10)
2538 {
2539 is_negative = TRUE;
2540 val = -value;
2541 }
2542 else
2543 {
2544 is_negative = FALSE;
2545 val = value;
2546 }
2547
2548 pos = buffer + 64;
2549 *pos = '\0';
2550
2551 do
2552 {
2553 digit = val % radix;
2554 val /= radix;
2555
2556 if (digit < 10)
2557 *--pos = '0' + digit;
2558 else
2559 *--pos = 'a' + digit - 10;
2560 }
2561 while (val != 0);
2562
2563 if (is_negative)
2564 *--pos = '-';
2565
2566 len = buffer + 65 - pos;
2567 if (len > size)
2568 {
2569 size_t i;
2570 char *p = str;
2571
2572 /* Copy the temporary buffer backwards up to the available number of
2573 * characters. Don't copy the negative sign if present. */
2574
2575 if (is_negative)
2576 {
2577 p++;
2578 size--;
2579 }
2580
2581 for (pos = buffer + 63, i = 0; i < size; i++)
2582 *p++ = *pos--;
2583
2584 str[0] = '\0';
2585 MSVCRT_INVALID_PMT("str[size] is too small", ERANGE);
2586 return ERANGE;
2587 }
2588
2589 memcpy(str, pos, len);
2590 return 0;
2591}
2592
2593/*********************************************************************
2594 * _i64tow_s (MSVCRT.@)
2595 */
2596int CDECL _i64tow_s(__int64 value, wchar_t *str, size_t size, int radix)
2597{
2598 unsigned __int64 val;
2599 unsigned int digit;
2600 BOOL is_negative;
2601 wchar_t buffer[65], *pos;
2602 size_t len;
2603
2604 if (!MSVCRT_CHECK_PMT(str != NULL)) return EINVAL;
2605 if (!MSVCRT_CHECK_PMT(size > 0)) return EINVAL;
2606 if (!MSVCRT_CHECK_PMT(radix >= 2 && radix <= 36))
2607 {
2608 str[0] = '\0';
2609 return EINVAL;
2610 }
2611
2612 if (value < 0 && radix == 10)
2613 {
2614 is_negative = TRUE;
2615 val = -value;
2616 }
2617 else
2618 {
2619 is_negative = FALSE;
2620 val = value;
2621 }
2622
2623 pos = buffer + 64;
2624 *pos = '\0';
2625
2626 do
2627 {
2628 digit = val % radix;
2629 val /= radix;
2630
2631 if (digit < 10)
2632 *--pos = '0' + digit;
2633 else
2634 *--pos = 'a' + digit - 10;
2635 }
2636 while (val != 0);
2637
2638 if (is_negative)
2639 *--pos = '-';
2640
2641 len = buffer + 65 - pos;
2642 if (len > size)
2643 {
2644 size_t i;
2645 wchar_t *p = str;
2646
2647 /* Copy the temporary buffer backwards up to the available number of
2648 * characters. Don't copy the negative sign if present. */
2649
2650 if (is_negative)
2651 {
2652 p++;
2653 size--;
2654 }
2655
2656 for (pos = buffer + 63, i = 0; i < size; i++)
2657 *p++ = *pos--;
2658
2659 str[0] = '\0';
2660 MSVCRT_INVALID_PMT("str[size] is too small", ERANGE);
2661 return ERANGE;
2662 }
2663
2664 memcpy(str, pos, len * sizeof(wchar_t));
2665 return 0;
2666}
2667
2668#define I10_OUTPUT_MAX_PREC 21
2669/* Internal structure used by $I10_OUTPUT */
2671 short pos;
2672 char sign;
2674 char str[I10_OUTPUT_MAX_PREC+1]; /* add space for '\0' */
2675};
2676
2677/*********************************************************************
2678 * $I10_OUTPUT (MSVCRT.@)
2679 * ld80 - long double (Intel 80 bit FP in 12 bytes) to be printed to data
2680 * prec - precision of part, we're interested in
2681 * flag - 0 for first prec digits, 1 for fractional part
2682 * data - data to be populated
2683 *
2684 * return value
2685 * 0 if given double is NaN or INF
2686 * 1 otherwise
2687 *
2688 * FIXME
2689 * Native sets last byte of data->str to '0' or '9', I don't know what
2690 * it means. Current implementation sets it always to '0'.
2691 */
2692#ifdef __REACTOS__
2693int CDECL I10_OUTPUT(MSVCRT__LDOUBLE ld80_, int prec, int flag, struct _I10_OUTPUT_DATA *data)
2694#else
2696#endif
2697{
2698#ifdef __REACTOS__
2699 WINE_BROKEN_LDOUBLE ld80 = { 0 };
2700 memcpy(&ld80, &ld80_, sizeof(ld80_));
2701#endif
2702 struct fpnum num;
2703 double d;
2704 char format[8];
2705 char buf[I10_OUTPUT_MAX_PREC+9]; /* 9 = strlen("0.e+0000") + '\0' */
2706 char *p;
2707
2708 if ((ld80.x80[2] & 0x7fff) == 0x7fff)
2709 {
2710 if (ld80.x80[0] == 0 && ld80.x80[1] == 0x80000000)
2711 strcpy( data->str, "1#INF" );
2712 else
2713 strcpy( data->str, (ld80.x80[1] & 0x40000000) ? "1#QNAN" : "1#SNAN" );
2714 data->pos = 1;
2715 data->sign = (ld80.x80[2] & 0x8000) ? '-' : ' ';
2716 data->len = strlen(data->str);
2717 return 0;
2718 }
2719
2720 num.sign = (ld80.x80[2] & 0x8000) ? -1 : 1;
2721 num.exp = (ld80.x80[2] & 0x7fff) - 0x3fff - 63;
2722 num.m = ld80.x80[0] | ((ULONGLONG)ld80.x80[1] << 32);
2723 num.mod = FP_ROUND_EVEN;
2724 fpnum_double( &num, &d );
2725 TRACE("(%lf %d %x %p)\n", d, prec, flag, data);
2726
2727 if(d<0) {
2728 data->sign = '-';
2729 d = -d;
2730 } else
2731 data->sign = ' ';
2732
2733 if(flag&1) {
2734 int exp = 1 + floor(log10(d));
2735
2736 prec += exp;
2737 if(exp < 0)
2738 prec--;
2739 }
2740 prec--;
2741
2742 if(prec+1 > I10_OUTPUT_MAX_PREC)
2743 prec = I10_OUTPUT_MAX_PREC-1;
2744 else if(prec < 0) {
2745 d = 0.0;
2746 prec = 0;
2747 }
2748
2749 sprintf(format, "%%.%dle", prec);
2750 sprintf(buf, format, d);
2751
2752 buf[1] = buf[0];
2753 data->pos = atoi(buf+prec+3);
2754 if(buf[1] != '0')
2755 data->pos++;
2756
2757 for(p = buf+prec+1; p>buf+1 && *p=='0'; p--);
2758 data->len = p-buf;
2759
2760 memcpy(data->str, buf+1, data->len);
2761 data->str[data->len] = '\0';
2762
2763 if(buf[1]!='0' && prec-data->len+1>0)
2764 memcpy(data->str+data->len+1, buf+data->len+1, prec-data->len+1);
2765
2766 return 1;
2767}
2768#undef I10_OUTPUT_MAX_PREC
2769
2770static inline int memcmp_bytes(const void *ptr1, const void *ptr2, size_t n)
2771{
2772 const unsigned char *p1, *p2;
2773
2774 for (p1 = ptr1, p2 = ptr2; n; n--, p1++, p2++)
2775 {
2776 if (*p1 != *p2)
2777 return *p1 > *p2 ? 1 : -1;
2778 }
2779 return 0;
2780}
2781
2782static inline int memcmp_blocks(const void *ptr1, const void *ptr2, size_t size)
2783{
2784 typedef uint64_t DECLSPEC_ALIGN(1) unaligned_ui64;
2785
2786 const uint64_t *p1 = ptr1;
2787 const unaligned_ui64 *p2 = ptr2;
2788 size_t remainder = size & (sizeof(uint64_t) - 1);
2789 size_t block_count = size / sizeof(uint64_t);
2790
2791 while (block_count)
2792 {
2793 if (*p1 != *p2)
2794 return memcmp_bytes(p1, p2, sizeof(uint64_t));
2795
2796 p1++;
2797 p2++;
2798 block_count--;
2799 }
2800
2801 return memcmp_bytes(p1, p2, remainder);
2802}
2803
2804/*********************************************************************
2805 * memcmp (MSVCRT.@)
2806 */
2807int __cdecl memcmp(const void *ptr1, const void *ptr2, size_t n)
2808{
2809 const unsigned char *p1 = ptr1, *p2 = ptr2;
2810 size_t align;
2811 int result;
2812
2813 if (n < sizeof(uint64_t))
2814 return memcmp_bytes(p1, p2, n);
2815
2816 align = -(size_t)p1 & (sizeof(uint64_t) - 1);
2817
2818 if ((result = memcmp_bytes(p1, p2, align)))
2819 return result;
2820
2821 p1 += align;
2822 p2 += align;
2823 n -= align;
2824
2825 return memcmp_blocks(p1, p2, n);
2826}
2827
2828#ifndef __REACTOS__
2829#if defined(__i386__) || (defined(__x86_64__) && !defined(__arm64ec__))
2830
2831#ifdef __i386__
2832
2833#define DEST_REG "%edi"
2834#define SRC_REG "%esi"
2835#define LEN_REG "%ecx"
2836#define TMP_REG "%edx"
2837
2838#define MEMMOVE_INIT \
2839 "pushl " SRC_REG "\n\t" \
2840 __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t") \
2841 "pushl " DEST_REG "\n\t" \
2842 __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t") \
2843 "movl 12(%esp), " DEST_REG "\n\t" \
2844 "movl 16(%esp), " SRC_REG "\n\t" \
2845 "movl 20(%esp), " LEN_REG "\n\t"
2846
2847#define MEMMOVE_CLEANUP \
2848 "movl 12(%esp), %eax\n\t" \
2849 "popl " DEST_REG "\n\t" \
2850 __ASM_CFI(".cfi_adjust_cfa_offset -4\n\t") \
2851 "popl " SRC_REG "\n\t" \
2852 __ASM_CFI(".cfi_adjust_cfa_offset -4\n\t")
2853
2854#else
2855
2856#define DEST_REG "%rdi"
2857#define SRC_REG "%rsi"
2858#define LEN_REG "%r8"
2859#define TMP_REG "%r9"
2860
2861#define MEMMOVE_INIT \
2862 "pushq " SRC_REG "\n\t" \
2863 __ASM_SEH(".seh_pushreg " SRC_REG "\n\t") \
2864 __ASM_CFI(".cfi_adjust_cfa_offset 8\n\t") \
2865 "pushq " DEST_REG "\n\t" \
2866 __ASM_SEH(".seh_pushreg " DEST_REG "\n\t") \
2867 __ASM_SEH(".seh_endprologue\n\t") \
2868 __ASM_CFI(".cfi_adjust_cfa_offset 8\n\t") \
2869 "movq %rcx, " DEST_REG "\n\t" \
2870 "movq %rdx, " SRC_REG "\n\t"
2871
2872#define MEMMOVE_CLEANUP \
2873 "movq %rcx, %rax\n\t" \
2874 "popq " DEST_REG "\n\t" \
2875 __ASM_CFI(".cfi_adjust_cfa_offset -8\n\t") \
2876 "popq " SRC_REG "\n\t" \
2877 __ASM_CFI(".cfi_adjust_cfa_offset -8\n\t")
2878#endif
2879
2880void * __cdecl sse2_memmove(void *dst, const void *src, size_t n);
2881__ASM_GLOBAL_FUNC( sse2_memmove,
2882 MEMMOVE_INIT
2883 "mov " DEST_REG ", " TMP_REG "\n\t" /* check copying direction */
2884 "sub " SRC_REG ", " TMP_REG "\n\t"
2885 "cmp " LEN_REG ", " TMP_REG "\n\t"
2886 "jb copy_bwd\n\t"
2887 /* copy forwards */
2888 "cmp $4, " LEN_REG "\n\t" /* 4-bytes align */
2889 "jb copy_fwd3\n\t"
2890 "mov " DEST_REG ", " TMP_REG "\n\t"
2891 "shr $1, " TMP_REG "\n\t"
2892 "jnc 1f\n\t"
2893 "movsb\n\t"
2894 "dec " LEN_REG "\n\t"
2895 "inc " TMP_REG "\n\t"
2896 "1:\n\t"
2897 "shr $1, " TMP_REG "\n\t"
2898 "jnc 1f\n\t"
2899 "movsw\n\t"
2900 "sub $2, " LEN_REG "\n\t"
2901 "inc " TMP_REG "\n\t"
2902 "1:\n\t" /* 16-bytes align */
2903 "cmp $16, " LEN_REG "\n\t"
2904 "jb copy_fwd15\n\t"
2905 "shr $1, " TMP_REG "\n\t"
2906 "jnc 1f\n\t"
2907 "movsl\n\t"
2908 "sub $4, " LEN_REG "\n\t"
2909 "inc " TMP_REG "\n\t"
2910 "1:\n\t"
2911 "shr $1, " TMP_REG "\n\t"
2912 "jnc 1f\n\t"
2913 "movsl\n\t"
2914 "movsl\n\t"
2915 "sub $8, " LEN_REG "\n\t"
2916 "1:\n\t"
2917 "cmp $64, " LEN_REG "\n\t"
2918 "jb copy_fwd63\n\t"
2919 "1:\n\t" /* copy 64-bytes blocks in loop, dest 16-bytes aligned */
2920 "movdqu 0x00(" SRC_REG "), %xmm0\n\t"
2921 "movdqu 0x10(" SRC_REG "), %xmm1\n\t"
2922 "movdqu 0x20(" SRC_REG "), %xmm2\n\t"
2923 "movdqu 0x30(" SRC_REG "), %xmm3\n\t"
2924 "movdqa %xmm0, 0x00(" DEST_REG ")\n\t"
2925 "movdqa %xmm1, 0x10(" DEST_REG ")\n\t"
2926 "movdqa %xmm2, 0x20(" DEST_REG ")\n\t"
2927 "movdqa %xmm3, 0x30(" DEST_REG ")\n\t"
2928 "add $64, " SRC_REG "\n\t"
2929 "add $64, " DEST_REG "\n\t"
2930 "sub $64, " LEN_REG "\n\t"
2931 "cmp $64, " LEN_REG "\n\t"
2932 "jae 1b\n\t"
2933 "copy_fwd63:\n\t" /* copy last 63 bytes, dest 16-bytes aligned */
2934 "mov " LEN_REG ", " TMP_REG "\n\t"
2935 "and $15, " LEN_REG "\n\t"
2936 "shr $5, " TMP_REG "\n\t"
2937 "jnc 1f\n\t"
2938 "movdqu 0(" SRC_REG "), %xmm0\n\t"
2939 "movdqa %xmm0, 0(" DEST_REG ")\n\t"
2940 "add $16, " SRC_REG "\n\t"
2941 "add $16, " DEST_REG "\n\t"
2942 "1:\n\t"
2943 "shr $1, " TMP_REG "\n\t"
2944 "jnc copy_fwd15\n\t"
2945 "movdqu 0x00(" SRC_REG "), %xmm0\n\t"
2946 "movdqu 0x10(" SRC_REG "), %xmm1\n\t"
2947 "movdqa %xmm0, 0x00(" DEST_REG ")\n\t"
2948 "movdqa %xmm1, 0x10(" DEST_REG ")\n\t"
2949 "add $32, " SRC_REG "\n\t"
2950 "add $32, " DEST_REG "\n\t"
2951 "copy_fwd15:\n\t" /* copy last 15 bytes, dest 4-bytes aligned */
2952 "mov " LEN_REG ", " TMP_REG "\n\t"
2953 "and $3, " LEN_REG "\n\t"
2954 "shr $3, " TMP_REG "\n\t"
2955 "jnc 1f\n\t"
2956 "movsl\n\t"
2957 "1:\n\t"
2958 "shr $1, " TMP_REG "\n\t"
2959 "jnc copy_fwd3\n\t"
2960 "movsl\n\t"
2961 "movsl\n\t"
2962 "copy_fwd3:\n\t" /* copy last 3 bytes */
2963 "shr $1, " LEN_REG "\n\t"
2964 "jnc 1f\n\t"
2965 "movsb\n\t"
2966 "1:\n\t"
2967 "shr $1, " LEN_REG "\n\t"
2968 "jnc 1f\n\t"
2969 "movsw\n\t"
2970 "1:\n\t"
2971 MEMMOVE_CLEANUP
2972 "ret\n\t"
2973 "copy_bwd:\n\t"
2974 "lea (" DEST_REG ", " LEN_REG "), " DEST_REG "\n\t"
2975 "lea (" SRC_REG ", " LEN_REG "), " SRC_REG "\n\t"
2976 "cmp $4, " LEN_REG "\n\t" /* 4-bytes align */
2977 "jb copy_bwd3\n\t"
2978 "mov " DEST_REG ", " TMP_REG "\n\t"
2979 "shr $1, " TMP_REG "\n\t"
2980 "jnc 1f\n\t"
2981 "dec " SRC_REG "\n\t"
2982 "dec " DEST_REG "\n\t"
2983 "movb (" SRC_REG "), %al\n\t"
2984 "movb %al, (" DEST_REG ")\n\t"
2985 "dec " LEN_REG "\n\t"
2986 "1:\n\t"
2987 "shr $1, " TMP_REG "\n\t"
2988 "jnc 1f\n\t"
2989 "sub $2, " SRC_REG "\n\t"
2990 "sub $2, " DEST_REG "\n\t"
2991 "movw (" SRC_REG "), %ax\n\t"
2992 "movw %ax, (" DEST_REG ")\n\t"
2993 "sub $2, " LEN_REG "\n\t"
2994 "1:\n\t" /* 16-bytes align */
2995 "cmp $16, " LEN_REG "\n\t"
2996 "jb copy_bwd15\n\t"
2997 "shr $1, " TMP_REG "\n\t"
2998 "jnc 1f\n\t"
2999 "sub $4, " SRC_REG "\n\t"
3000 "sub $4, " DEST_REG "\n\t"
3001 "movl (" SRC_REG "), %eax\n\t"
3002 "movl %eax, (" DEST_REG ")\n\t"
3003 "sub $4, " LEN_REG "\n\t"
3004 "1:\n\t"
3005 "shr $1, " TMP_REG "\n\t"
3006 "jnc 1f\n\t"
3007 "sub $8, " SRC_REG "\n\t"
3008 "sub $8, " DEST_REG "\n\t"
3009 "movl 4(" SRC_REG "), %eax\n\t"
3010 "movl %eax, 4(" DEST_REG ")\n\t"
3011 "movl (" SRC_REG "), %eax\n\t"
3012 "movl %eax, (" DEST_REG ")\n\t"
3013 "sub $8, " LEN_REG "\n\t"
3014 "1:\n\t"
3015 "cmp $64, " LEN_REG "\n\t"
3016 "jb copy_bwd63\n\t"
3017 "1:\n\t" /* copy 64-bytes blocks in loop, dest 16-bytes aligned */
3018 "sub $64, " SRC_REG "\n\t"
3019 "sub $64, " DEST_REG "\n\t"
3020 "movdqu 0x00(" SRC_REG "), %xmm0\n\t"
3021 "movdqu 0x10(" SRC_REG "), %xmm1\n\t"
3022 "movdqu 0x20(" SRC_REG "), %xmm2\n\t"
3023 "movdqu 0x30(" SRC_REG "), %xmm3\n\t"
3024 "movdqa %xmm0, 0x00(" DEST_REG ")\n\t"
3025 "movdqa %xmm1, 0x10(" DEST_REG ")\n\t"
3026 "movdqa %xmm2, 0x20(" DEST_REG ")\n\t"
3027 "movdqa %xmm3, 0x30(" DEST_REG ")\n\t"
3028 "sub $64, " LEN_REG "\n\t"
3029 "cmp $64, " LEN_REG "\n\t"
3030 "jae 1b\n\t"
3031 "copy_bwd63:\n\t" /* copy last 63 bytes, dest 16-bytes aligned */
3032 "mov " LEN_REG ", " TMP_REG "\n\t"
3033 "and $15, " LEN_REG "\n\t"
3034 "shr $5, " TMP_REG "\n\t"
3035 "jnc 1f\n\t"
3036 "sub $16, " SRC_REG "\n\t"
3037 "sub $16, " DEST_REG "\n\t"
3038 "movdqu (" SRC_REG "), %xmm0\n\t"
3039 "movdqa %xmm0, (" DEST_REG ")\n\t"
3040 "1:\n\t"
3041 "shr $1, " TMP_REG "\n\t"
3042 "jnc copy_bwd15\n\t"
3043 "sub $32, " SRC_REG "\n\t"
3044 "sub $32, " DEST_REG "\n\t"
3045 "movdqu 0x00(" SRC_REG "), %xmm0\n\t"
3046 "movdqu 0x10(" SRC_REG "), %xmm1\n\t"
3047 "movdqa %xmm0, 0x00(" DEST_REG ")\n\t"
3048 "movdqa %xmm1, 0x10(" DEST_REG ")\n\t"
3049 "copy_bwd15:\n\t" /* copy last 15 bytes, dest 4-bytes aligned */
3050 "mov " LEN_REG ", " TMP_REG "\n\t"
3051 "and $3, " LEN_REG "\n\t"
3052 "shr $3, " TMP_REG "\n\t"
3053 "jnc 1f\n\t"
3054 "sub $4, " SRC_REG "\n\t"
3055 "sub $4, " DEST_REG "\n\t"
3056 "movl (" SRC_REG "), %eax\n\t"
3057 "movl %eax, (" DEST_REG ")\n\t"
3058 "1:\n\t"
3059 "shr $1, " TMP_REG "\n\t"
3060 "jnc copy_bwd3\n\t"
3061 "sub $8, " SRC_REG "\n\t"
3062 "sub $8, " DEST_REG "\n\t"
3063 "movl 4(" SRC_REG "), %eax\n\t"
3064 "movl %eax, 4(" DEST_REG ")\n\t"
3065 "movl (" SRC_REG "), %eax\n\t"
3066 "movl %eax, (" DEST_REG ")\n\t"
3067 "copy_bwd3:\n\t" /* copy last 3 bytes */
3068 "shr $1, " LEN_REG "\n\t"
3069 "jnc 1f\n\t"
3070 "dec " SRC_REG "\n\t"
3071 "dec " DEST_REG "\n\t"
3072 "movb (" SRC_REG "), %al\n\t"
3073 "movb %al, (" DEST_REG ")\n\t"
3074 "1:\n\t"
3075 "shr $1, " LEN_REG "\n\t"
3076 "jnc 1f\n\t"
3077 "movw -2(" SRC_REG "), %ax\n\t"
3078 "movw %ax, -2(" DEST_REG ")\n\t"
3079 "1:\n\t"
3080 MEMMOVE_CLEANUP
3081 "ret" )
3082
3083#endif
3084
3085/*********************************************************************
3086 * memmove (MSVCRT.@)
3087 */
3088#ifdef WORDS_BIGENDIAN
3089# define MERGE(w1, sh1, w2, sh2) ((w1 << sh1) | (w2 >> sh2))
3090#else
3091# define MERGE(w1, sh1, w2, sh2) ((w1 >> sh1) | (w2 << sh2))
3092#endif
3093void * __cdecl memmove(void *dst, const void *src, size_t n)
3094{
3095#if defined(__x86_64__) && !defined(__arm64ec__)
3096 return sse2_memmove(dst, src, n);
3097#else
3098 unsigned char *d = dst;
3099 const unsigned char *s = src;
3100 int sh1;
3101
3102#ifdef __i386__
3103 if (sse2_supported)
3104 return sse2_memmove(dst, src, n);
3105#endif
3106
3107 if (!n) return dst;
3108
3109 if ((size_t)dst - (size_t)src >= n)
3110 {
3111 for (; (size_t)d % sizeof(size_t) && n; n--) *d++ = *s++;
3112
3113 sh1 = 8 * ((size_t)s % sizeof(size_t));
3114 if (!sh1)
3115 {
3116 while (n >= sizeof(size_t))
3117 {
3118 *(size_t*)d = *(size_t*)s;
3119 s += sizeof(size_t);
3120 d += sizeof(size_t);
3121 n -= sizeof(size_t);
3122 }
3123 }
3124 else if (n >= 2 * sizeof(size_t))
3125 {
3126 int sh2 = 8 * sizeof(size_t) - sh1;
3127 size_t x, y;
3128
3129 s -= sh1 / 8;
3130 x = *(size_t*)s;
3131 do
3132 {
3133 s += sizeof(size_t);
3134 y = *(size_t*)s;
3135 *(size_t*)d = MERGE(x, sh1, y, sh2);
3136 d += sizeof(size_t);
3137
3138 s += sizeof(size_t);
3139 x = *(size_t*)s;
3140 *(size_t*)d = MERGE(y, sh1, x, sh2);
3141 d += sizeof(size_t);
3142
3143 n -= 2 * sizeof(size_t);
3144 } while (n >= 2 * sizeof(size_t));
3145 s += sh1 / 8;
3146 }
3147 while (n--) *d++ = *s++;
3148 return dst;
3149 }
3150 else
3151 {
3152 d += n;
3153 s += n;
3154
3155 for (; (size_t)d % sizeof(size_t) && n; n--) *--d = *--s;
3156
3157 sh1 = 8 * ((size_t)s % sizeof(size_t));
3158 if (!sh1)
3159 {
3160 while (n >= sizeof(size_t))
3161 {
3162 s -= sizeof(size_t);
3163 d -= sizeof(size_t);
3164 *(size_t*)d = *(size_t*)s;
3165 n -= sizeof(size_t);
3166 }
3167 }
3168 else if (n >= 2 * sizeof(size_t))
3169 {
3170 int sh2 = 8 * sizeof(size_t) - sh1;
3171 size_t x, y;
3172
3173 s -= sh1 / 8;
3174 x = *(size_t*)s;
3175 do
3176 {
3177 s -= sizeof(size_t);
3178 y = *(size_t*)s;
3179 d -= sizeof(size_t);
3180 *(size_t*)d = MERGE(y, sh1, x, sh2);
3181
3182 s -= sizeof(size_t);
3183 x = *(size_t*)s;
3184 d -= sizeof(size_t);
3185 *(size_t*)d = MERGE(x, sh1, y, sh2);
3186
3187 n -= 2 * sizeof(size_t);
3188 } while (n >= 2 * sizeof(size_t));
3189 s += sh1 / 8;
3190 }
3191 while (n--) *--d = *--s;
3192 }
3193 return dst;
3194#endif
3195}
3196#undef MERGE
3197#endif /* !__REACTOS__ */
3198
3199/*********************************************************************
3200 * memcpy (MSVCRT.@)
3201 */
3202void * __cdecl memcpy(void *dst, const void *src, size_t n)
3203{
3204 return memmove(dst, src, n);
3205}
3206
3207/*********************************************************************
3208 * _memccpy (MSVCRT.@)
3209 */
3210void * __cdecl _memccpy(void *dst, const void *src, int c, size_t n)
3211{
3212 unsigned char *d = dst;
3213 const unsigned char *s = src;
3214 while (n--) if ((*d++ = *s++) == (unsigned char)c) return d;
3215 return NULL;
3216}
3217
3218
3219static inline void memset_aligned_32(unsigned char *d, uint64_t v, size_t n)
3220{
3221 unsigned char *end = d + n;
3222 while (d < end)
3223 {
3224 *(uint64_t *)(d + 0) = v;
3225 *(uint64_t *)(d + 8) = v;
3226 *(uint64_t *)(d + 16) = v;
3227 *(uint64_t *)(d + 24) = v;
3228 d += 32;
3229 }
3230}
3231
3232/*********************************************************************
3233 * memset (MSVCRT.@)
3234 */
3235void *__cdecl memset(void *dst, int c, size_t n)
3236{
3237 typedef uint64_t DECLSPEC_ALIGN(1) unaligned_ui64;
3238 typedef uint32_t DECLSPEC_ALIGN(1) unaligned_ui32;
3239 typedef uint16_t DECLSPEC_ALIGN(1) unaligned_ui16;
3240
3241 uint64_t v = 0x101010101010101ull * (unsigned char)c;
3242 unsigned char *d = (unsigned char *)dst;
3243 size_t a = 0x20 - ((uintptr_t)d & 0x1f);
3244
3245 if (n >= 16)
3246 {
3247 *(unaligned_ui64 *)(d + 0) = v;
3248 *(unaligned_ui64 *)(d + 8) = v;
3249 *(unaligned_ui64 *)(d + n - 16) = v;
3250 *(unaligned_ui64 *)(d + n - 8) = v;
3251 if (n <= 32) return dst;
3252 *(unaligned_ui64 *)(d + 16) = v;
3253 *(unaligned_ui64 *)(d + 24) = v;
3254 *(unaligned_ui64 *)(d + n - 32) = v;
3255 *(unaligned_ui64 *)(d + n - 24) = v;
3256 if (n <= 64) return dst;
3257
3258 n = (n - a) & ~0x1f;
3259 memset_aligned_32(d + a, v, n);
3260 return dst;
3261 }
3262 if (n >= 8)
3263 {
3264 *(unaligned_ui64 *)d = v;
3265 *(unaligned_ui64 *)(d + n - 8) = v;
3266 return dst;
3267 }
3268 if (n >= 4)
3269 {
3270 *(unaligned_ui32 *)d = v;
3271 *(unaligned_ui32 *)(d + n - 4) = v;
3272 return dst;
3273 }
3274 if (n >= 2)
3275 {
3276 *(unaligned_ui16 *)d = v;
3277 *(unaligned_ui16 *)(d + n - 2) = v;
3278 return dst;
3279 }
3280 if (n >= 1)
3281 {
3282 *(uint8_t *)d = v;
3283 return dst;
3284 }
3285 return dst;
3286}
3287
3288/*********************************************************************
3289 * strchr (MSVCRT.@)
3290 */
3291char* __cdecl strchr(const char *str, int c)
3292{
3293 do
3294 {
3295 if (*str == (char)c) return (char*)str;
3296 } while (*str++);
3297 return NULL;
3298}
3299
3300/*********************************************************************
3301 * strrchr (MSVCRT.@)
3302 */
3303char* __cdecl strrchr(const char *str, int c)
3304{
3305 char *ret = NULL;
3306 do { if (*str == (char)c) ret = (char*)str; } while (*str++);
3307 return ret;
3308}
3309
3310/*********************************************************************
3311 * memchr (MSVCRT.@)
3312 */
3313void* __cdecl memchr(const void *ptr, int c, size_t n)
3314{
3315 const unsigned char *p = ptr;
3316
3317 for (p = ptr; n; n--, p++) if (*p == (unsigned char)c) return (void *)(ULONG_PTR)p;
3318 return NULL;
3319}
3320
3321/*********************************************************************
3322 * strcmp (MSVCRT.@)
3323 */
3324int __cdecl strcmp(const char *str1, const char *str2)
3325{
3326 while (*str1 && *str1 == *str2) { str1++; str2++; }
3327 if ((unsigned char)*str1 > (unsigned char)*str2) return 1;
3328 if ((unsigned char)*str1 < (unsigned char)*str2) return -1;
3329 return 0;
3330}
3331
3332/*********************************************************************
3333 * strncmp (MSVCRT.@)
3334 */
3335int __cdecl strncmp(const char *str1, const char *str2, size_t len)
3336{
3337 if (!len) return 0;
3338 while (--len && *str1 && *str1 == *str2) { str1++; str2++; }
3339
3340#if defined(_WIN64) || defined(_UCRT) || _MSVCR_VER == 70 || _MSVCR_VER == 71 || _MSVCR_VER >= 110
3341 if ((unsigned char)*str1 > (unsigned char)*str2) return 1;
3342 if ((unsigned char)*str1 < (unsigned char)*str2) return -1;
3343 return 0;
3344#else
3345 return (unsigned char)*str1 - (unsigned char)*str2;
3346#endif
3347}
3348
3349/*********************************************************************
3350 * _strnicmp_l (MSVCRT.@)
3351 */
3352int __cdecl _strnicmp_l(const char *s1, const char *s2,
3353 size_t count, _locale_t locale)
3354{
3356 int c1, c2;
3357
3358 if(!count)
3359 return 0;
3360#if _MSVCR_VER>=80
3361 if(!MSVCRT_CHECK_PMT(s1 && s2 && count <= INT_MAX))
3362#else
3363 /* Old versions of msvcrt.dll didn't have count <= INT_MAX check */
3364 if(!MSVCRT_CHECK_PMT(s1 && s2))
3365#endif /* _MSVCR_VER>=140 */
3366 return _NLSCMPERROR;
3367
3368 if(!locale)
3369 locinfo = get_locinfo();
3370 else
3371 locinfo = locale->locinfo;
3372
3373 if(!locinfo->lc_handle[LC_CTYPE])
3374 {
3375 do {
3376 if ((c1 = *s1++) >= 'A' && c1 <= 'Z')
3377 c1 -= 'A' - 'a';
3378 if ((c2 = *s2++) >= 'A' && c2 <= 'Z')
3379 c2 -= 'A' - 'a';
3380 }while(--count && c1 && c1==c2);
3381
3382 return (unsigned char)c1 - (unsigned char)c2;
3383 }
3384
3385 do {
3386 c1 = _tolower_l((unsigned char)*s1++, locale);
3387 c2 = _tolower_l((unsigned char)*s2++, locale);
3388 }while(--count && c1 && c1==c2);
3389
3390 return c1-c2;
3391}
3392
3393/*********************************************************************
3394 * _stricmp_l (MSVCRT.@)
3395 */
3396int __cdecl _stricmp_l(const char *s1, const char *s2, _locale_t locale)
3397{
3398 return _strnicmp_l(s1, s2, INT_MAX, locale);
3399}
3400
3401/*********************************************************************
3402 * _strnicmp (MSVCRT.@)
3403 */
3404int __cdecl _strnicmp(const char *s1, const char *s2, size_t count)
3405{
3406 return _strnicmp_l(s1, s2, count, NULL);
3407}
3408
3409/*********************************************************************
3410 * _stricmp (MSVCRT.@)
3411 */
3412int __cdecl _stricmp(const char *s1, const char *s2)
3413{
3414 return _strnicmp_l(s1, s2, INT_MAX, NULL);
3415}
3416
3417/*********************************************************************
3418 * strstr (MSVCRT.@)
3419 */
3420char* __cdecl strstr(const char *haystack, const char *needle)
3421{
3422 size_t i, j, len, needle_len, lps_len;
3423 BYTE lps[256];
3424
3425 needle_len = strlen(needle);
3426 if (!needle_len) return (char*)haystack;
3427 lps_len = needle_len > ARRAY_SIZE(lps) ? ARRAY_SIZE(lps) : needle_len;
3428
3429 lps[0] = 0;
3430 len = 0;
3431 i = 1;
3432 while (i < lps_len)
3433 {
3434 if (needle[i] == needle[len]) lps[i++] = ++len;
3435 else if (len) len = lps[len-1];
3436 else lps[i++] = 0;
3437 }
3438
3439 i = j = 0;
3440 while (haystack[i])
3441 {
3442 while (j < lps_len && haystack[i] && haystack[i] == needle[j])
3443 {
3444 i++;
3445 j++;
3446 }
3447
3448 if (j == needle_len) return (char*)haystack + i - j;
3449 else if (j)
3450 {
3451 if (j == ARRAY_SIZE(lps) && !strncmp(haystack + i, needle + j, needle_len - j))
3452 return (char*)haystack + i - j;
3453 j = lps[j-1];
3454 }
3455 else if (haystack[i]) i++;
3456 }
3457 return NULL;
3458}
3459
3460/*********************************************************************
3461 * _memicmp_l (MSVCRT.@)
3462 */
3463int __cdecl _memicmp_l(const void *v1, const void *v2, size_t len, _locale_t locale)
3464{
3465 const char *s1 = v1, *s2 = v2;
3466 int ret = 0;
3467
3468#if _MSVCR_VER == 0 || _MSVCR_VER >= 80
3469 if (!s1 || !s2)
3470 {
3471 if (len)
3473 return len ? _NLSCMPERROR : 0;
3474 }
3475#endif
3476
3477 while (len--)
3478 {
3479 if ((ret = _tolower_l(*s1, locale) - _tolower_l(*s2, locale)))
3480 break;
3481 s1++;
3482 s2++;
3483 }
3484 return ret;
3485}
3486
3487/*********************************************************************
3488 * _memicmp (MSVCRT.@)
3489 */
3490int __cdecl _memicmp(const void *s1, const void *s2, size_t len)
3491{
3492 return _memicmp_l(s1, s2, len, NULL);
3493}
3494
3495/*********************************************************************
3496 * strcspn (MSVCRT.@)
3497 */
3498size_t __cdecl strcspn(const char *str, const char *reject)
3499{
3500 BOOL rejects[256];
3501 const char *p;
3502
3503 memset(rejects, 0, sizeof(rejects));
3504
3505 p = reject;
3506 while(*p)
3507 {
3508 rejects[(unsigned char)*p] = TRUE;
3509 p++;
3510 }
3511
3512 p = str;
3513 while(*p && !rejects[(unsigned char)*p]) p++;
3514 return p - str;
3515}
3516
3517/*********************************************************************
3518 * strspn (MSVCRT.@)
3519 */
3520size_t __cdecl strspn(const char *str, const char *accept)
3521{
3522 const char *ptr;
3523 for (ptr = str; *ptr; ptr++) if (!strchr( accept, *ptr )) break;
3524 return ptr - str;
3525}
3526
3527/*********************************************************************
3528 * strpbrk (MSVCRT.@)
3529 */
3530char* __cdecl strpbrk(const char *str, const char *accept)
3531{
3532 for (; *str; str++) if (strchr( accept, *str )) return (char*)str;
3533 return NULL;
3534}
3535
3536/*********************************************************************
3537 * __strncnt (MSVCRT.@)
3538 */
3539size_t __cdecl __strncnt(const char *str, size_t size)
3540{
3541 size_t ret = 0;
3542
3543#if _MSVCR_VER >= 140
3544 while (*str++ && size--)
3545#else
3546 while (size-- && *str++)
3547#endif
3548 {
3549 ret++;
3550 }
3551
3552 return ret;
3553}
3554
3555
3556#ifdef _CRTDLL
3557/*********************************************************************
3558 * _strdec (CRTDLL.@)
3559 */
3560char * CDECL _strdec(const char *str1, const char *str2)
3561{
3562 return (char *)(str2 - 1);
3563}
3564
3565/*********************************************************************
3566 * _strinc (CRTDLL.@)
3567 */
3568char * CDECL _strinc(const char *str)
3569{
3570 return (char *)(str + 1);
3571}
3572
3573/*********************************************************************
3574 * _strnextc (CRTDLL.@)
3575 */
3576unsigned int CDECL _strnextc(const char *str)
3577{
3578 return (unsigned char)str[0];
3579}
3580
3581/*********************************************************************
3582 * _strninc (CRTDLL.@)
3583 */
3584char * CDECL _strninc(const char *str, size_t len)
3585{
3586 return (char *)(str + len);
3587}
3588
3589/*********************************************************************
3590 * _strspnp (CRTDLL.@)
3591 */
3592char * CDECL _strspnp( const char *str1, const char *str2)
3593{
3594 str1 += strspn( str1, str2 );
3595 return *str1 ? (char*)str1 : NULL;
3596}
3597#endif
std::map< E_MODULE, HMODULE > mod
Definition: LocaleTests.cpp:68
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
void get(int argc, const char *argv[])
Definition: cmds.c:480
#define ARRAY_SIZE(A)
Definition: main.h:20
#define FIXME(fmt,...)
Definition: precomp.h:53
static const int p10s[]
Definition: bnum.h:25
#define EXP_BITS
Definition: bnum.h:22
#define MANT_BITS
Definition: bnum.h:23
static BOOL bnum_lshift(struct bnum *b, int shift)
Definition: bnum.h:47
static void bnum_mult(struct bnum *b, int mult)
Definition: bnum.h:109
#define BNUM_PREC64
Definition: bnum.h:30
#define LIMB_DIGITS
Definition: bnum.h:27
#define LIMB_MAX
Definition: bnum.h:28
static int bnum_idx(struct bnum *b, int idx)
Definition: bnum.h:41
static BOOL bnum_rshift(struct bnum *b, int shift)
Definition: bnum.h:79
#define BNUM_PREC80
Definition: bnum.h:31
#define _stricmp
Definition: cat.c:22
Definition: _locale.h:75
#define _strdup
Definition: debug_ros.c:7
#define malloc
Definition: debug_ros.c:4
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
UINT32 uint32_t
Definition: types.h:75
UINT64 uint64_t
Definition: types.h:77
#define CDECL
Definition: compat.h:29
#define _strnicmp(_String1, _String2, _MaxCount)
Definition: compat.h:23
INT WINAPI LCMapStringA(LCID lcid, DWORD flags, LPCSTR src, INT srclen, LPSTR dst, INT dstlen)
Definition: locale.c:3834
INT WINAPI CompareStringA(LCID lcid, DWORD flags, LPCSTR str1, INT len1, LPCSTR str2, INT len2)
Definition: locale.c:4015
int CDECL _tolower_l(int c, _locale_t locale)
Definition: ctype.c:532
int CDECL _toupper_l(int c, _locale_t locale)
Definition: ctype.c:474
void __cdecl _invalid_parameter(const wchar_t *expr, const wchar_t *func, const wchar_t *file, unsigned int line, uintptr_t arg)
Definition: errno.c:461
int *CDECL _errno(void)
Definition: errno.c:215
#define DECLSPEC_ALIGN(x)
Definition: corecrt.h:141
long __msvcrt_long
Definition: corecrt.h:167
#define __cdecl
Definition: corecrt.h:121
unsigned int uintptr_t
Definition: corecrt.h:185
unsigned int size_t
Definition: corecrt.h:203
unsigned short wchar_t
Definition: corecrt.h:237
#define __int64
Definition: corecrt.h:72
unsigned long __msvcrt_ulong
Definition: corecrt.h:168
#define WEOF
_ACRTIMP int __cdecl memcmp(const void *, const void *, size_t)
Definition: string.c:2807
#define EINVAL
Definition: errno.h:44
#define STRUNCATE
Definition: errno.h:64
#define ERANGE
Definition: errno.h:55
#define EILSEQ
Definition: errno.h:62
#define DBL_MIN_10_EXP
Definition: float.h:25
#define DBL_MAX_10_EXP
Definition: float.h:22
#define FLT_MIN
Definition: float.h:40
#define DBL_DIG
Definition: float.h:18
#define DBL_MIN
Definition: float.h:24
#define I64_MIN
Definition: limits.h:41
#define INT_MIN
Definition: limits.h:25
#define SIZE_MAX
Definition: limits.h:49
#define ULONG_MAX
Definition: limits.h:31
#define LONG_MAX
Definition: limits.h:30
#define I64_MAX
Definition: limits.h:42
#define UI64_MAX
Definition: limits.h:43
#define INT_MAX
Definition: limits.h:26
#define LONG_MIN
Definition: limits.h:29
#define LC_CTYPE
Definition: locale.h:27
#define LC_COLLATE
Definition: locale.h:26
#define _UNDERFLOW
Definition: math.h:23
#define isfinite(x)
Definition: math.h:363
#define isinf(x)
Definition: math.h:359
#define INFINITY
Definition: math.h:272
_ACRTIMP double __cdecl remainder(double, double)
Definition: remainder.c:75
_ACRTIMP double __cdecl floor(double)
Definition: floor.c:18
#define _OVERFLOW
Definition: math.h:22
#define _NLSCMPERROR
Definition: mbstring.h:28
unsigned short uint16_t
Definition: stdint.h:35
unsigned char uint8_t
Definition: stdint.h:33
_ACRTIMP float __cdecl _strtof_l(const char *, char **, _locale_t)
Definition: strtod.cpp:63
_ACRTIMP float __cdecl strtof(const char *, char **)
Definition: strtod.cpp:55
#define _TRUNCATE
Definition: stdlib.h:45
_ACRTIMP int __cdecl atoi(const char *)
Definition: string.c:1720
_ACRTIMP __int64 __cdecl atoll(const char *)
Definition: stdlib.h:1451
_ACRTIMP size_t __cdecl strlen(const char *)
Definition: string.c:1597
BOOL sse2_supported
Definition: math.c:71
thread_data_t *CDECL msvcrt_get_thread_data(void)
Definition: ucrt_tls_sup.c:59
#define MSVCRT_INVALID_PMT(x, err)
Definition: msvcrt.h:376
#define DBL80_MIN_10_EXP
Definition: msvcrt.h:73
#define DBL80_MAX_10_EXP
Definition: msvcrt.h:72
#define MSVCRT_CHECK_PMT(x)
Definition: msvcrt.h:378
fpmod
Definition: msvcrt.h:350
@ FP_VAL_NAN
Definition: msvcrt.h:356
@ FP_ROUND_EVEN
Definition: msvcrt.h:353
@ FP_VAL_INFINITY
Definition: msvcrt.h:355
@ FP_ROUND_UP
Definition: msvcrt.h:354
@ FP_ROUND_ZERO
Definition: msvcrt.h:351
@ FP_ROUND_DOWN
Definition: msvcrt.h:352
int nch
Definition: scanf.h:201
else locinfo
Definition: scanf.h:225
int __cdecl strncmp(const char *str1, const char *str2, size_t len)
Definition: string.c:3335
int CDECL _strlwr_s(char *str, size_t len)
Definition: string.c:119
int __cdecl _memicmp_l(const void *v1, const void *v2, size_t len, _locale_t locale)
Definition: string.c:3463
int CDECL _strnicoll_l(const char *str1, const char *str2, size_t count, _locale_t locale)
Definition: string.c:1254
static int ltoa_helper(__msvcrt_long value, char *str, size_t size, int radix)
Definition: string.c:1945
int CDECL _atodbl(_CRT_DOUBLE *value, char *str)
Definition: string.c:1167
size_t CDECL _strxfrm_l(char *dest, const char *src, size_t len, _locale_t locale)
Definition: string.c:1471
__msvcrt_ulong CDECL _strtoul_l(const char *nptr, char **end, int base, _locale_t locale)
Definition: string.c:1846
void CDECL _swab(char *src, char *dst, int len)
Definition: string.c:343
int __cdecl _memicmp(const void *s1, const void *s2, size_t len)
Definition: string.c:3490
int CDECL _atodbl_l(_CRT_DOUBLE *value, char *str, _locale_t locale)
Definition: string.c:1152
int CDECL _ui64tow_s(unsigned __int64 value, wchar_t *str, size_t size, int radix)
Definition: string.c:2375
__int64 CDECL _strtoi64(const char *nptr, char **endptr, int base)
Definition: string.c:1694
int CDECL _ultow_s(__msvcrt_ulong value, wchar_t *str, size_t size, int radix)
Definition: string.c:2467
int CDECL __STRINGTOLD_L(MSVCRT__LDOUBLE *value, char **endptr, const char *str, int flags, _locale_t locale)
Definition: string.c:1528
int CDECL strcat_s(char *dst, size_t elem, const char *src)
Definition: string.c:1373
unsigned __int64 CDECL _strtoui64(const char *nptr, char **endptr, int base)
Definition: string.c:1940
int CDECL _stricoll_l(const char *str1, const char *str2, _locale_t locale)
Definition: string.c:1201
static struct fpnum fpnum_parse_bnum(wchar_t(*get)(void *ctx), void(*unget)(void *ctx), void *ctx, pthreadlocinfo locinfo, BOOL ldouble, struct bnum *b)
Definition: string.c:758
size_t CDECL strxfrm(char *dest, const char *src, size_t len)
Definition: string.c:1517
double CDECL strtod(const char *str, char **end)
Definition: string.c:1077
__int64 CDECL _atoi64_l(const char *str, _locale_t locale)
Definition: string.c:1754
int CDECL __STRINGTOLD(MSVCRT__LDOUBLE *value, char **endptr, const char *str, int flags)
Definition: string.c:1567
char *CDECL _i64toa(__int64 value, char *str, int radix)
Definition: string.c:2252
char *__cdecl strrchr(const char *str, int c)
Definition: string.c:3303
size_t CDECL strnlen(const char *s, size_t maxlen)
Definition: string.c:1607
int CDECL _strnicoll(const char *str1, const char *str2, size_t count)
Definition: string.c:1273
int CDECL _ltow_s(__msvcrt_long value, wchar_t *str, size_t size, int radix)
Definition: string.c:2092
int CDECL _strncoll(const char *str1, const char *str2, size_t count)
Definition: string.c:1246
size_t __cdecl strcspn(const char *str, const char *reject)
Definition: string.c:3498
void *__cdecl _memccpy(void *dst, const void *src, int c, size_t n)
Definition: string.c:3210
int CDECL _strcoll_l(const char *str1, const char *str2, _locale_t locale)
Definition: string.c:1175
static int memcmp_bytes(const void *ptr1, const void *ptr2, size_t n)
Definition: string.c:2770
__int64 CDECL _atoi64(const char *str)
Definition: string.c:1762
int CDECL _stricoll(const char *str1, const char *str2)
Definition: string.c:1219
wchar_t *CDECL _itow(int value, wchar_t *str, int radix)
Definition: string.c:2140
static BOOL bnum_to_mant(struct bnum *b, ULONGLONG *m)
Definition: string.c:745
#define LDBL_EXP_BITS
Definition: string.c:484
int CDECL _ultoa_s(__msvcrt_ulong value, char *str, size_t size, int radix)
Definition: string.c:2413
size_t __cdecl __strncnt(const char *str, size_t size)
Definition: string.c:3539
char *CDECL strtok(char *str, const char *delim)
Definition: string.c:290
__msvcrt_long CDECL strtol(const char *nptr, char **end, int base)
Definition: string.c:1838
int fpnum_double(struct fpnum *fp, double *d)
Definition: string.c:370
struct fpnum fpnum_parse(wchar_t(*get)(void *ctx), void(*unget)(void *ctx), void *ctx, pthreadlocinfo locinfo, BOOL ldouble)
Definition: string.c:990
int CDECL _ui64toa_s(unsigned __int64 value, char *str, size_t size, int radix)
Definition: string.c:2336
int CDECL _atoldbl_l(MSVCRT__LDOUBLE *value, char *str, _locale_t locale)
Definition: string.c:1575
char *__cdecl strpbrk(const char *str, const char *accept)
Definition: string.c:3530
int CDECL _atoldbl(_LDOUBLE *value, char *str)
Definition: string.c:1589
int __cdecl _strnicmp_l(const char *s1, const char *s2, size_t count, _locale_t locale)
Definition: string.c:3352
int CDECL strcpy_s(char *dst, size_t elem, const char *src)
Definition: string.c:1350
wchar_t *CDECL _ui64tow(unsigned __int64 value, wchar_t *str, int radix)
Definition: string.c:2228
char *__cdecl strchr(const char *str, int c)
Definition: string.c:3291
double CDECL _strtod_l(const char *str, char **end, _locale_t locale)
Definition: string.c:1069
char *CDECL _ui64toa(unsigned __int64 value, char *str, int radix)
Definition: string.c:2180
#define I10_OUTPUT_MAX_PREC
Definition: string.c:2668
char *CDECL _strrev(char *str)
Definition: string.c:259
int __cdecl _atoi_l(const char *str, _locale_t locale)
Definition: string.c:1702
__msvcrt_ulong CDECL strtoul(const char *nptr, char **end, int base)
Definition: string.c:1864
int CDECL _i64tow_s(__int64 value, wchar_t *str, size_t size, int radix)
Definition: string.c:2596
int __cdecl strcmp(const char *str1, const char *str2)
Definition: string.c:3324
#define LDBL_MANT_BITS
Definition: string.c:485
int __cdecl _stricmp_l(const char *s1, const char *s2, _locale_t locale)
Definition: string.c:3396
static int memcmp_blocks(const void *ptr1, const void *ptr2, size_t size)
Definition: string.c:2782
int CDECL _atoflt(_CRT_FLOAT *value, char *str)
Definition: string.c:1144
wchar_t *CDECL _ltow(__msvcrt_long value, wchar_t *str, int radix)
Definition: string.c:2148
int CDECL _itoa_s(int value, char *str, size_t size, int radix)
Definition: string.c:2108
static void strtod_str_unget(void *ctx)
Definition: string.c:1023
wchar_t *CDECL _i64tow(__int64 value, wchar_t *str, int radix)
Definition: string.c:2294
static double strtod_helper(const char *str, char **end, _locale_t locale, int *perr)
Definition: string.c:1029
int CDECL _atoflt_l(_CRT_FLOAT *value, char *str, _locale_t locale)
Definition: string.c:1127
wchar_t *CDECL _ultow(__msvcrt_ulong value, wchar_t *str, int radix)
Definition: string.c:2204
double CDECL _atof_l(const char *str, _locale_t locale)
Definition: string.c:1119
static int ltow_helper(__msvcrt_long value, wchar_t *str, size_t size, int radix)
Definition: string.c:2009
static wchar_t strtod_str_get(void *ctx)
Definition: string.c:1016
static void memset_aligned_32(unsigned char *d, uint64_t v, size_t n)
Definition: string.c:3219
__msvcrt_long CDECL _atol_l(const char *str, _locale_t locale)
Definition: string.c:1770
int CDECL _strncoll_l(const char *str1, const char *str2, size_t count, _locale_t locale)
Definition: string.c:1227
int CDECL I10_OUTPUT(MSVCRT__LDOUBLE ld80, int prec, int flag, struct _I10_OUTPUT_DATA *data)
Definition: string.c:2695
int CDECL _strupr_s(char *str, size_t len)
Definition: string.c:198
__msvcrt_long CDECL atol(const char *str)
Definition: string.c:1787
int CDECL _ltoa_s(__msvcrt_long value, char *str, size_t size, int radix)
Definition: string.c:2076
int CDECL _i64toa_s(__int64 value, char *str, size_t size, int radix)
Definition: string.c:2521
int CDECL _itow_s(int value, wchar_t *str, size_t size, int radix)
Definition: string.c:2132
__int64 CDECL _strtoi64_l(const char *nptr, char **endptr, int base, _locale_t locale)
Definition: string.c:1622
int fpnum_ldouble(struct fpnum *fp, MSVCRT__LDOUBLE *d)
Definition: string.c:489
__msvcrt_long CDECL _strtol_l(const char *nptr, char **end, int base, _locale_t locale)
Definition: string.c:1819
unsigned __int64 CDECL _strtoui64_l(const char *nptr, char **endptr, int base, _locale_t locale)
Definition: string.c:1874
char *__cdecl strstr(const char *haystack, const char *needle)
Definition: string.c:3420
char *CDECL strtok_s(char *str, const char *delim, char **ctx)
Definition: string.c:314
#define MERGE(w1, sh1, w2, sh2)
Definition: string.c:3091
size_t __cdecl strspn(const char *str, const char *accept)
Definition: string.c:3520
unsigned char
Definition: typeof.h:29
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
return ret
Definition: mutex.c:146
#define L(x)
Definition: resources.c:13
#define ULONG_PTR
Definition: config.h:101
int align(int length, int align)
Definition: dsound8.c:36
unsigned int BOOL
Definition: ntddk_ex.h:94
double log10(double x)
Definition: freeldr.c:191
FxCollectionEntry * cur
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
const GLdouble * v
Definition: gl.h:2040
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLdouble s
Definition: gl.h:2039
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLuint GLuint end
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLdouble n
Definition: glext.h:7729
GLenum src
Definition: glext.h:6340
GLuint buffer
Definition: glext.h:5915
GLsizeiptr size
Definition: glext.h:5919
const GLubyte * c
Definition: glext.h:8905
GLfloat f
Definition: glext.h:7540
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLenum GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * bits
Definition: glext.h:10929
GLenum GLenum dst
Definition: glext.h:6340
GLbitfield flags
Definition: glext.h:7161
GLuint GLfloat * val
Definition: glext.h:7180
GLuint64EXT * result
Definition: glext.h:11304
GLfloat GLfloat p
Definition: glext.h:8902
GLuint GLuint num
Definition: glext.h:9618
GLenum GLsizei len
Definition: glext.h:6722
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
GLfloat GLfloat v1
Definition: glext.h:6062
GLfloat GLfloat GLfloat v2
Definition: glext.h:6063
const GLfloat * m
Definition: glext.h:10848
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean flag
Definition: glfuncs.h:52
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
#define _strnextc(_cpc)
Definition: tchar.h:1518
#define _strninc(_pc, _sz)
Definition: tchar.h:1519
#define _strdec(_cpc1, _cpc2)
Definition: tchar.h:1516
#define _strinc(_pc)
Definition: tchar.h:1517
#define _strspnp(_cpc1, _cpc2)
Definition: tchar.h:1522
#define d
Definition: ke_i.h:81
#define e
Definition: ke_i.h:82
#define a
Definition: ke_i.h:78
#define c
Definition: ke_i.h:80
#define debugstr_a
Definition: kernel32.h:31
#define sign(x)
Definition: mapdesc.cc:613
struct S1 s1
#define _nan()
Definition: mingw_math.h:465
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
#define memchr(s, c, n)
Definition: mkisofs.h:875
#define strcoll
Definition: util.h:34
static PVOID ptr
Definition: dispmode.c:27
#define sprintf
Definition: sprintf.c:45
static size_t elem
Definition: string.c:71
static char * dest
Definition: rtl.c:149
static const char haystack[]
Definition: editor.c:190
static unsigned(__cdecl *hash_bstr)(bstr_t s)
DWORD exp
Definition: msg.c:18625
#define __ASM_GLOBAL_FUNC(name, code)
Definition: port.h:201
#define uint64_t
Definition: nsiface.idl:62
#define DWORD
Definition: nt_native.h:44
#define round(x)
Definition: opentype.c:47
short WCHAR
Definition: pedump.c:58
#define err(...)
const WCHAR * str
#define _isspace_l(_Char, _Locale)
Definition: ctype.h:648
#define _toupper(_Char)
Definition: ctype.h:655
_ultoa
Definition: stdlib.h:688
_Check_return_ _ACRTIMP long long __cdecl _atoll_l(_In_z_ char const *_String, _In_opt_ _locale_t _Locale)
_ltoa
Definition: stdlib.h:665
_itoa
Definition: stdlib.h:642
_strlwr_s_l
Definition: string.h:249
strncpy
Definition: string.h:335
_strlwr
Definition: string.h:231
strcat
Definition: string.h:92
_strupr_l
Definition: string.h:471
_strset
Definition: string.h:424
_strupr
Definition: string.h:453
strcpy
Definition: string.h:131
_In_opt_ _Locale strncat
Definition: string.h:263
strncpy_s
Definition: string.h:335
_strnset_s
Definition: string.h:393
_In_opt_ _Locale strncat_s
Definition: string.h:263
_strlwr_l
Definition: string.h:249
_strnset
Definition: string.h:393
_strupr_s_l
Definition: string.h:471
XML_HIDDEN void xmlParserErrors const char const xmlChar const xmlChar * str2
Definition: parser.h:35
XML_HIDDEN void xmlParserErrors const char const xmlChar * str1
Definition: parser.h:35
#define memset(x, y, z)
Definition: compat.h:39
double atof()
PCWSTR s2
Definition: shell32_main.h:38
SOCKET WSAAPI accept(IN SOCKET s, OUT LPSOCKADDR addr, OUT INT FAR *addrlen)
Definition: socklife.c:23
#define TRACE(s)
Definition: solgame.cpp:4
char str[I10_OUTPUT_MAX_PREC+1]
Definition: string.c:2674
Definition: bnum.h:34
int size
Definition: bnum.h:37
Definition: format.c:58
Definition: msvcrt.h:359
enum fpmod mod
Definition: msvcrt.h:363
ULONGLONG m
Definition: msvcrt.h:362
int exp
Definition: msvcrt.h:361
int sign
Definition: msvcrt.h:360
BOOL matched
Definition: taskkill.c:46
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
uint64_t ULONGLONG
Definition: typedefs.h:67
Definition: pdh_main.c:96
#define get_locinfo()
Definition: winesup.h:25
#define NORM_IGNORECASE
Definition: winnls.h:191
#define SORT_STRINGSORT
Definition: winnls.h:199
#define CSTR_EQUAL
Definition: winnls.h:510
#define LCMAP_SORTKEY
Definition: winnls.h:204
size_t const unsigned const radix
Definition: xtoa.cpp:37
unsigned char BYTE
Definition: xxhash.c:193