1 /*
2 * Copyright (c) 2005-2014 Rich Felker, et al.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sublicense, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 */
23
24 #include <errno.h>
26 #include <math.h>
27 #include <stdarg.h>
28 #include <stddef.h>
29 #include <stdint.h>
30 #include <stdio.h>
31 #include <string.h>
33
36
44 size_t (*
read)(
struct FFFILE *,
unsigned char *, size_t);
46
53
54 #define shcnt(f) ((f)->shcnt + ((f)->rpos - (f)->buf))
55
57 {
58 f->rpos =
f->rend =
f->buf +
f->buf_size;
59 return 0;
60 }
61
63 {
64 char *
src =
f->cookie;
66 char *end = memchr(
src, 0, k);
67
72 f->rend = (
void *)(
src+k);
74
76 }
77
79 {
82 return EOF;
83 }
84
86 {
88 f->shcnt =
f->buf -
f->rpos;
89 /* If lim is nonzero, rend must be a valid pointer. */
90 if (lim &&
f->rend -
f->rpos > lim)
91 f->shend =
f->rpos + lim;
92 else
94 }
95
97 {
100 if (
f->shlim && cnt >=
f->shlim || (
c=
ffuflow(
f)) < 0) {
101 f->shcnt =
f->buf -
f->rpos + cnt;
103 return EOF;
104 }
105 cnt++;
106 if (
f->shlim &&
f->rend -
f->rpos >
f->shlim - cnt)
107 f->shend =
f->rpos + (
f->shlim - cnt);
108 else
110 f->shcnt =
f->buf -
f->rpos + cnt;
111 if (
f->rpos[-1] !=
c)
f->rpos[-1] =
c;
113 }
114
115 #define shlim(f, lim) ffshlim((f), (lim))
116 #define shgetc(f) (((f)->rpos < (f)->shend) ? *(f)->rpos++ : ffshgetc(f))
117 #define shunget(f) ((f)->shend ? (void)(f)->rpos-- : (void)0)
118
119 static const unsigned char table[] = { -1,
120 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
121 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
122 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
123 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1,
124 -1,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,
125 25,26,27,28,29,30,31,32,33,34,35,-1,-1,-1,-1,-1,
126 -1,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,
127 25,26,27,28,29,30,31,32,33,34,35,-1,-1,-1,-1,-1,
128 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
129 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
130 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
131 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
132 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
133 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
134 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
135 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
136 };
137
139 {
142 unsigned x;
143 unsigned long long y;
145 errno = EINVAL;
146 return 0;
147 }
149 if (
c==
'+' ||
c==
'-') {
152 }
153 if ((
base == 0 ||
base == 16) &&
c==
'0') {
161 return 0;
162 }
164 }
else if (
base == 0) {
166 }
167 } else {
172 errno = EINVAL;
173 return 0;
174 }
175 }
177 for (x=0;
c-
'0'<10
U && x<=UINT_MAX/10-1;
c=
shgetc(
f))
179 for (y=x;
c-
'0'<10
U && y<=ULLONG_MAX/10 && 10*y<=ULLONG_MAX-(
c-
'0');
c=
shgetc(
f))
181 if (
c-
'0'>=10
U)
goto done;
183 int bs =
"0円1円2円4円7円3円6円5円"[(0x17*
base)>>5&7];
188 } else {
193 }
196 errno = ERANGE;
197 y = lim;
198 if (lim&1) neg = 0;
199 }
200 done:
202 if (y>=lim) {
203 if (!(lim&1) && !neg) {
204 errno = ERANGE;
205 return lim-1;
206 } else if (y>lim) {
207 errno = ERANGE;
208 return lim;
209 }
210 }
211 return (y^neg)-neg;
212 }
213
215 {
217 int x;
218 long long y;
219 int neg = 0;
220
222 if (
c==
'+' ||
c==
'-') {
226 }
229 return LLONG_MIN;
230 }
231 for (x=0;
c-
'0'<10
U && x<INT_MAX/10;
c =
shgetc(
f))
233 for (y=x;
c-
'0'<10
U && y<LLONG_MAX/100;
c =
shgetc(
f))
237 return neg ? -y : y;
238 }
239
241 #define LD_B1B_MAX 9007199, 254740991
243 #define MASK (KMAX-1)
244
246 {
250 long long lrp=0,
dc=0;
251 long long e10=0;
252 int lnz = 0;
253 int gotdig = 0, gotrad = 0;
254 int rp;
255 int e2;
256 int emax = -emin-
bits+3;
257 int denormal = 0;
258 double y;
259 double frac=0;
261 static const int p10s[] = { 10, 100, 1000, 10000,
262 100000, 1000000, 10000000, 100000000 };
263
264 j=0;
265 k=0;
266
267 /* Don't let leading zeros consume buffer space */
270 gotrad = 1;
272 }
273
274 x[0] = 0;
277 if (gotrad) break;
278 gotrad = 1;
280 }
else if (k <
KMAX-3) {
282 if (
c!=
'0') lnz =
dc;
283 if (j) x[k] = x[k]*10 +
c-
'0';
285 if (++j==9) {
286 k++;
287 j=0;
288 }
289 gotdig=1;
290 } else {
295 }
296 }
297 }
299
300 if (gotdig && (
c|32)==
'e') {
302 if (e10 == LLONG_MIN) {
303 if (pok) {
305 } else {
307 return 0;
308 }
309 e10 = 0;
310 }
311 lrp += e10;
314 }
315 if (!gotdig) {
316 errno = EINVAL;
318 return 0;
319 }
320
321 /* Handle zero specially to avoid nasty special cases later */
322 if (!x[0]) return sign * 0.0;
323
324 /* Optimize small integers (w/no exponent) and over/under-flow */
326 return sign * (
double)x[0];
327 if (lrp > -emin/2) {
328 errno = ERANGE;
329 return sign * DBL_MAX * DBL_MAX;
330 }
331 if (lrp < emin-2*DBL_MANT_DIG) {
332 errno = ERANGE;
333 return sign * DBL_MIN * DBL_MIN;
334 }
335
336 /* Align incomplete final B1B digit */
337 if (j) {
338 for (; j<9; j++) x[k]*=10;
339 k++;
340 j=0;
341 }
342
344 z = k;
345 e2 = 0;
346 rp = lrp;
347
348 /* Optimize small to mid-size integers (even in exp. notation) */
349 if (lnz<9 && lnz<=rp && rp < 18) {
350 int bitlim;
351 if (rp == 9)
return sign * (
double)x[0];
352 if (rp < 9)
return sign * (
double)x[0] / p10s[8-rp];
354 if (bitlim>30 || x[0]>>bitlim==0)
355 return sign * (
double)x[0] * p10s[rp-10];
356 }
357
358 /* Drop trailing zeros */
359 for (; !x[z-1]; z--);
360
361 /* Align radix point to B1B digit boundary */
362 if (rp % 9) {
363 int rpm9 = rp>=0 ? rp%9 : rp%9+9;
364 int p10 = p10s[8-rpm9];
365 uint32_t carry = 0;
366 for (k=
a; k!=z; k++) {
367 uint32_t
tmp = x[k] % p10;
368 x[k] = x[k]/p10 + carry;
369 carry = 1000000000/p10 *
tmp;
372 rp -= 9;
373 }
374 }
375 if (carry) x[z++] = carry;
376 rp += 9-rpm9;
377 }
378
379 /* Upscale until desired number of bits are left of radix point */
381 uint32_t carry = 0;
382 e2 -= 29;
383 for (k=(z-1 &
MASK); ; k=(k-1 &
MASK)) {
384 uint64_t
tmp = ((uint64_t)x[k] << 29) + carry;
385 if (
tmp > 1000000000) {
386 carry =
tmp / 1000000000;
387 x[k] =
tmp % 1000000000;
388 } else {
389 carry = 0;
391 }
392 if (k==(z-1 &
MASK) && k!=
a && !x[k]) z = k;
394 }
395 if (carry) {
396 rp += 9;
400 x[z-1 &
MASK] |= x[z];
401 }
403 }
404 }
405
406 /* Downscale until exactly number of bits are left of radix point */
407 for (;;) {
408 uint32_t carry = 0;
409 int sh = 1;
412 if (k == z || x[k] <
th[
i]) {
414 break;
415 }
417 }
419 /* FIXME: find a way to compute optimal sh */
421 e2 += sh;
422 for (k=
a; k!=z; k=(k+1 &
MASK)) {
423 uint32_t
tmp = x[k] & (1<<sh)-1;
424 x[k] = (x[k]>>sh) + carry;
425 carry = (1000000000>>sh) *
tmp;
429 rp -= 9;
430 }
431 }
432 if (carry) {
433 if ((z+1 &
MASK) !=
a) {
434 x[z] = carry;
436 }
else x[z-1 &
MASK] |= 1;
437 }
438 }
439
440 /* Assemble desired bits into floating point variable */
442 if ((
a+
i &
MASK)==z) x[(z=(z+1 &
MASK))-1] = 0;
443 y = 1000000000.0L * y + x[
a+
i &
MASK];
444 }
445
446 y *= sign;
447
448 /* Limit precision for denormal results */
449 if (
bits > DBL_MANT_DIG+e2-emin) {
450 bits = DBL_MANT_DIG+e2-emin;
452 denormal = 1;
453 }
454
455 /* Calculate bias term to force rounding, move out lower bits */
456 if (
bits < DBL_MANT_DIG) {
458 frac = fmod(y, scalbn(1, DBL_MANT_DIG-
bits));
459 y -= frac;
461 }
462
463 /* Process tail of decimal input so it can affect rounding */
465 uint32_t t = x[
a+
i &
MASK];
466 if (t < 500000000 && (t || (
a+
i+1 &
MASK) != z))
467 frac += 0.25*sign;
468 else if (t > 500000000)
469 frac += 0.75*sign;
470 else if (t == 500000000) {
472 frac += 0.5*sign;
473 else
474 frac += 0.75*sign;
475 }
476 if (DBL_MANT_DIG-
bits >= 2 && !fmod(frac, 1))
477 frac++;
478 }
479
480 y += frac;
482
483 if ((e2+DBL_MANT_DIG & INT_MAX) > emax-5) {
484 if (
fabs(y) >= pow(2, DBL_MANT_DIG)) {
485 if (denormal &&
bits==DBL_MANT_DIG+e2-emin)
486 denormal = 0;
487 y *= 0.5;
488 e2++;
489 }
490 if (e2+DBL_MANT_DIG>emax || (denormal && frac))
491 errno = ERANGE;
492 }
493
494 return scalbn(y, e2);
495 }
496
498 {
499 uint32_t x = 0;
500 double y = 0;
503 int gottail = 0, gotrad = 0, gotdig = 0;
504 long long rp = 0;
506 long long e2 = 0;
509
511
512 /* Skip leading zeros */
514 gotdig = 1;
515
517 gotrad = 1;
519 /* Count zeros after the radix point before significand */
520 for (rp=0;
c==
'0';
c =
shgetc(
f), rp--) gotdig = 1;
521 }
522
523 for (;
c-
'0'<10
U || (
c|32)-
'a'<6
U ||
c==
'.';
c =
shgetc(
f)) {
525 if (gotrad) break;
527 gotrad = 1;
528 } else {
529 gotdig = 1;
530 if (
c >
'9')
d = (
c|32)+10-
'a';
534 }
else if (
dc < DBL_MANT_DIG/4+1) {
536 }
else if (
d && !gottail) {
538 gottail = 1;
539 }
541 }
542 }
543 if (!gotdig) {
545 if (pok) {
548 } else {
550 }
551 return sign * 0.0;
552 }
553 if (!gotrad) rp =
dc;
554 while (
dc<8) x *= 16,
dc++;
557 if (e2 == LLONG_MIN) {
558 if (pok) {
560 } else {
562 return 0;
563 }
564 e2 = 0;
565 }
566 } else {
568 }
569 e2 += 4*rp - 32;
570
571 if (!x) return sign * 0.0;
572 if (e2 > -emin) {
573 errno = ERANGE;
574 return sign * DBL_MAX * DBL_MAX;
575 }
576 if (e2 < emin-2*DBL_MANT_DIG) {
577 errno = ERANGE;
578 return sign * DBL_MIN * DBL_MIN;
579 }
580
581 while (x < 0x80000000) {
582 if (y>=0.5) {
583 x += x + 1;
584 y += y - 1;
585 } else {
586 x += x;
587 y += y;
588 }
589 e2--;
590 }
591
592 if (
bits > 32+e2-emin) {
595 }
596
597 if (
bits < DBL_MANT_DIG)
599
600 if (
bits<32 && y && !(x&1)) x++, y=0;
601
604
605 if (!y) errno = ERANGE;
606
607 return scalbn(y, e2);
608 }
609
611 {
612 int sign = 1;
615 int emin;
617
618 switch (prec) {
619 case 0:
621 emin = FLT_MIN_EXP-
bits;
622 break;
623 case 1:
625 emin = DBL_MIN_EXP-
bits;
626 break;
627 case 2:
629 emin = DBL_MIN_EXP-
bits;
630 break;
631 default:
632 return 0;
633 }
634
636
637 if (
c==
'+' ||
c==
'-') {
640 }
641
642 for (
i=0;
i<8 && (
c|32)==
"infinity"[
i];
i++)
644 if (
i==3 ||
i==8 || (
i>3 && pok)) {
648 }
650 }
651 if (!
i)
for (
i=0;
i<3 && (
c|32)==
"nan"[
i];
i++)
657 }
660 if (
c-
'0'<10
U ||
c-
'A'<26
U ||
c-
'a'<26
U ||
c==
'_')
661 continue;
662 if (
c==
')')
return NAN;
664 if (!pok) {
665 errno = EINVAL;
667 return 0;
668 }
671 }
673 }
674
677 errno = EINVAL;
679 return 0;
680 }
681
688 }
689
691 }
692
693 static void *
arg_n(va_list ap,
unsigned int n)
694 {
695 void *p;
697 va_list ap2;
699 for (
i=n;
i>1;
i--) va_arg(ap2,
void *);
700 p = va_arg(ap2, void *);
701 va_end(ap2);
702 return p;
703 }
704
706 {
707 if (!dest) return;
711 break;
714 break;
717 break;
720 break;
722 *(
long long *)dest =
i;
723 break;
724 }
725 }
726
728 {
732 const unsigned char *p;
737 int matches=0;
738 unsigned long long x;
739 double y;
741 unsigned char scanset[257];
743
744 for (p=(const unsigned char *)fmt; *p; p++) {
745
752 continue;
753 }
754 if (*p != '%' || p[1] == '%') {
756 if (*p == '%') {
757 p++;
759 } else {
761 }
764 if (
c<0)
goto input_fail;
765 goto match_fail;
766 }
768 continue;
769 }
770
771 p++;
772 if (*p=='*') {
773 dest = 0; p++;
775 dest =
arg_n(ap, *p-
'0'); p+=2;
776 } else {
777 dest = va_arg(ap, void *);
778 }
779
782 }
783
784 if (*p=='m') {
786 p++;
787 }
788
790 switch (*p++) {
791 case 'h':
794 break;
795 case 'l':
798 break;
799 case 'j':
801 break;
802 case 'z':
803 case 't':
805 break;
806 case 'L':
808 break;
809 case 'd': case 'i': case 'o': case 'u': case 'x':
810 case 'a': case 'e': case 'f': case 'g':
811 case 'A': case 'E': case 'F': case 'G': case 'X':
812 case 's': case 'c': case '[':
813 case 'S': case 'C':
814 case 'p': case 'n':
815 p--;
816 break;
817 default:
818 goto fmt_fail;
819 }
820
821 t = *p;
822
823 /* C or S */
824 if ((t&0x2f) == 3) {
825 t |= 32;
827 }
828
829 switch (t) {
830 case 'c':
832 case '[':
833 break;
834 case 'n':
836 /* do not increment match count, etc! */
837 continue;
838 default:
843 }
844
846 if (
shgetc(
f) < 0)
goto input_fail;
848
849 switch (t) {
850 case 's':
851 case 'c':
852 case '[':
853 if (t == 'c' || t == 's') {
854 memset(scanset, -1, sizeof scanset);
855 scanset[0] = 0;
856 if (t == 's') {
857 scanset[1 + '\t'] = 0;
858 scanset[1 + '\n'] = 0;
859 scanset[1 + '\v'] = 0;
860 scanset[1 + '\f'] = 0;
861 scanset[1 + '\r'] = 0;
862 scanset[1 + ' ' ] = 0;
863 }
864 } else {
865 if (*++p ==
'^') p++,
invert = 1;
867 memset(scanset,
invert,
sizeof scanset);
868 scanset[0] = 0;
869 if (*p ==
'-') p++, scanset[1+
'-'] = 1-
invert;
870 else if (*p ==
']') p++, scanset[1+
']'] = 1-
invert;
871 for (; *p != ']'; p++) {
872 if (!*p) goto fmt_fail;
873 if (*p=='-' && p[1] && p[1] != ']')
874 for (
c=p++[-1];
c<*p;
c++)
877 }
878 }
884 } else {
886 }
888 if (!
shcnt(
f))
goto match_fail;
889 if (t ==
'c' &&
shcnt(
f) !=
width)
goto match_fail;
890 if (t != 'c') {
892 }
893 break;
894 case 'p':
895 case 'X':
896 case 'x':
898 goto int_common;
899 case 'o':
901 goto int_common;
902 case 'd':
903 case 'u':
905 goto int_common;
906 case 'i':
908 int_common:
911 goto match_fail;
912 if (t=='p' && dest)
913 *(void **)dest = (void *)(uintptr_t)x;
914 else
916 break;
917 case 'a': case 'A':
918 case 'e': case 'E':
919 case 'f': case 'F':
920 case 'g': case 'G':
923 goto match_fail;
924 if (dest) {
927 *(float *)dest = y;
928 break;
930 *(double *)dest = y;
931 break;
933 *(double *)dest = y;
934 break;
935 }
936 }
937 break;
938 }
939
941 if (dest) matches++;
942 }
943 if (0) {
944 fmt_fail:
945 input_fail:
946 if (!matches) matches--;
947 }
948 match_fail:
949 return matches;
950 }
951
953 {
955 .buf = (
void *)
s, .
cookie = (
void *)
s,
957 };
958
960 }
961
963 {
965 va_list ap;
968 va_end(ap);
970 }