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