diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-07-24 09:54:23 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-07-24 09:54:44 +0000 |
commit | 836b47cb7e99a977c5a23b059ca1d0b5065d310e (patch) | |
tree | 1604da8f482d02effa033c94a84be42bc0c848c3 /web/server/h2o/libh2o/deps/mruby/src/fmt_fp.c | |
parent | Releasing debian version 1.44.3-2. (diff) | |
download | netdata-836b47cb7e99a977c5a23b059ca1d0b5065d310e.tar.xz netdata-836b47cb7e99a977c5a23b059ca1d0b5065d310e.zip |
Merging upstream version 1.46.3.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'web/server/h2o/libh2o/deps/mruby/src/fmt_fp.c')
-rw-r--r-- | web/server/h2o/libh2o/deps/mruby/src/fmt_fp.c | 372 |
1 files changed, 0 insertions, 372 deletions
diff --git a/web/server/h2o/libh2o/deps/mruby/src/fmt_fp.c b/web/server/h2o/libh2o/deps/mruby/src/fmt_fp.c deleted file mode 100644 index 0a8b22b41..000000000 --- a/web/server/h2o/libh2o/deps/mruby/src/fmt_fp.c +++ /dev/null @@ -1,372 +0,0 @@ -/* - -Most code in this file originates from musl (src/stdio/vfprintf.c) -which, just like mruby itself, is licensed under the MIT license. - -Copyright (c) 2005-2014 Rich Felker, et al. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ - -#include <limits.h> -#include <string.h> -#include <stdint.h> -#include <math.h> -#include <float.h> -#include <ctype.h> - -#include <mruby.h> -#include <mruby/string.h> - -struct fmt_args { - mrb_state *mrb; - mrb_value str; -}; - -#define MAX(a,b) ((a)>(b) ? (a) : (b)) -#define MIN(a,b) ((a)<(b) ? (a) : (b)) - -/* Convenient bit representation for modifier flags, which all fall - * within 31 codepoints of the space character. */ - -#define ALT_FORM (1U<<('#'-' ')) -#define ZERO_PAD (1U<<('0'-' ')) -#define LEFT_ADJ (1U<<('-'-' ')) -#define PAD_POS (1U<<(' '-' ')) -#define MARK_POS (1U<<('+'-' ')) - -static void -out(struct fmt_args *f, const char *s, size_t l) -{ - mrb_str_cat(f->mrb, f->str, s, l); -} - -#define PAD_SIZE 256 -static void -pad(struct fmt_args *f, char c, ptrdiff_t w, ptrdiff_t l, uint8_t fl) -{ - char pad[PAD_SIZE]; - if (fl & (LEFT_ADJ | ZERO_PAD) || l >= w) return; - l = w - l; - memset(pad, c, l>PAD_SIZE ? PAD_SIZE : l); - for (; l >= PAD_SIZE; l -= PAD_SIZE) - out(f, pad, PAD_SIZE); - out(f, pad, l); -} - -static const char xdigits[16] = { - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' -}; - -static char* -fmt_u(uint32_t x, char *s) -{ - for (; x; x /= 10) *--s = '0' + x % 10; - return s; -} - -/* Do not override this check. The floating point printing code below - * depends on the float.h constants being right. If they are wrong, it - * may overflow the stack. */ -#if LDBL_MANT_DIG == 53 -typedef char compiler_defines_long_double_incorrectly[9-(int)sizeof(long double)]; -#endif - -static int -fmt_fp(struct fmt_args *f, long double y, ptrdiff_t p, uint8_t fl, int t) -{ - uint32_t big[(LDBL_MANT_DIG+28)/29 + 1 // mantissa expansion - + (LDBL_MAX_EXP+LDBL_MANT_DIG+28+8)/9]; // exponent expansion - uint32_t *a, *d, *r, *z; - uint32_t i; - int e2=0, e, j; - ptrdiff_t l; - char buf[9+LDBL_MANT_DIG/4], *s; - const char *prefix="-0X+0X 0X-0x+0x 0x"; - ptrdiff_t pl; - char ebuf0[3*sizeof(int)], *ebuf=&ebuf0[3*sizeof(int)], *estr; - - pl=1; - if (signbit(y)) { - y=-y; - } else if (fl & MARK_POS) { - prefix+=3; - } else if (fl & PAD_POS) { - prefix+=6; - } else prefix++, pl=0; - - if (!isfinite(y)) { - const char *ss = (t&32)?"inf":"INF"; - if (y!=y) ss=(t&32)?"nan":"NAN"; - pad(f, ' ', 0, 3+pl, fl&~ZERO_PAD); - out(f, prefix, pl); - out(f, ss, 3); - pad(f, ' ', 0, 3+pl, fl^LEFT_ADJ); - return 3+(int)pl; - } - - y = frexp((double)y, &e2) * 2; - if (y) e2--; - - if ((t|32)=='a') { - long double round = 8.0; - ptrdiff_t re; - - if (t&32) prefix += 9; - pl += 2; - - if (p<0 || p>=LDBL_MANT_DIG/4-1) re=0; - else re=LDBL_MANT_DIG/4-1-p; - - if (re) { - while (re--) round*=16; - if (*prefix=='-') { - y=-y; - y-=round; - y+=round; - y=-y; - } - else { - y+=round; - y-=round; - } - } - - estr=fmt_u(e2<0 ? -e2 : e2, ebuf); - if (estr==ebuf) *--estr='0'; - *--estr = (e2<0 ? '-' : '+'); - *--estr = t+('p'-'a'); - - s=buf; - do { - int x=(int)y; - *s++=xdigits[x]|(t&32); - y=16*(y-x); - if (s-buf==1 && (y||p>0||(fl&ALT_FORM))) *s++='.'; - } while (y); - - if (p && s-buf-2 < p) - l = (p+2) + (ebuf-estr); - else - l = (s-buf) + (ebuf-estr); - - pad(f, ' ', 0, pl+l, fl); - out(f, prefix, pl); - pad(f, '0', 0, pl+l, fl^ZERO_PAD); - out(f, buf, s-buf); - pad(f, '0', l-(ebuf-estr)-(s-buf), 0, 0); - out(f, estr, ebuf-estr); - pad(f, ' ', 0, pl+l, fl^LEFT_ADJ); - return (int)pl+(int)l; - } - if (p<0) p=6; - - if (y) y *= 268435456.0, e2-=28; - - if (e2<0) a=r=z=big; - else a=r=z=big+sizeof(big)/sizeof(*big) - LDBL_MANT_DIG - 1; - - do { - *z = (uint32_t)y; - y = 1000000000*(y-*z++); - } while (y); - - while (e2>0) { - uint32_t carry=0; - int sh=MIN(29,e2); - for (d=z-1; d>=a; d--) { - uint64_t x = ((uint64_t)*d<<sh)+carry; - *d = x % 1000000000; - carry = (uint32_t)(x / 1000000000); - } - if (carry) *--a = carry; - while (z>a && !z[-1]) z--; - e2-=sh; - } - while (e2<0) { - uint32_t carry=0, *b; - int sh=MIN(9,-e2), need=1+((int)p+LDBL_MANT_DIG/3+8)/9; - for (d=a; d<z; d++) { - uint32_t rm = *d & ((1<<sh)-1); - *d = (*d>>sh) + carry; - carry = (1000000000>>sh) * rm; - } - if (!*a) a++; - if (carry) *z++ = carry; - /* Avoid (slow!) computation past requested precision */ - b = (t|32)=='f' ? r : a; - if (z-b > need) z = b+need; - e2+=sh; - } - - if (a<z) for (i=10, e=9*(int)(r-a); *a>=i; i*=10, e++); - else e=0; - - /* Perform rounding: j is precision after the radix (possibly neg) */ - j = (int)p - ((t|32)!='f')*e - ((t|32)=='g' && p); - if (j < 9*(z-r-1)) { - uint32_t x; - /* We avoid C's broken division of negative numbers */ - d = r + 1 + ((j+9*LDBL_MAX_EXP)/9 - LDBL_MAX_EXP); - j += 9*LDBL_MAX_EXP; - j %= 9; - for (i=10, j++; j<9; i*=10, j++); - x = *d % i; - /* Are there any significant digits past j? */ - if (x || d+1!=z) { - long double round = 2/LDBL_EPSILON; - long double small; - if (*d/i & 1) round += 2; - if (x<i/2) small=0.5; - else if (x==i/2 && d+1==z) small=1.0; - else small=1.5; - if (pl && *prefix=='-') round*=-1, small*=-1; - *d -= x; - /* Decide whether to round by probing round+small */ - if (round+small != round) { - *d = *d + i; - while (*d > 999999999) { - *d--=0; - if (d<a) *--a=0; - (*d)++; - } - for (i=10, e=9*(int)(r-a); *a>=i; i*=10, e++); - } - } - if (z>d+1) z=d+1; - } - for (; z>a && !z[-1]; z--); - - if ((t|32)=='g') { - if (!p) p++; - if (p>e && e>=-4) { - t--; - p-=e+1; - } - else { - t-=2; - p--; - } - if (!(fl&ALT_FORM)) { - /* Count trailing zeros in last place */ - if (z>a && z[-1]) for (i=10, j=0; z[-1]%i==0; i*=10, j++); - else j=9; - if ((t|32)=='f') - p = MIN(p,MAX(0,9*(z-r-1)-j)); - else - p = MIN(p,MAX(0,9*(z-r-1)+e-j)); - } - } - l = 1 + p + (p || (fl&ALT_FORM)); - if ((t|32)=='f') { - if (e>0) l+=e; - } - else { - estr=fmt_u(e<0 ? -e : e, ebuf); - while(ebuf-estr<2) *--estr='0'; - *--estr = (e<0 ? '-' : '+'); - *--estr = t; - l += ebuf-estr; - } - - pad(f, ' ', 0, pl+l, fl); - out(f, prefix, pl); - pad(f, '0', 0, pl+l, fl^ZERO_PAD); - - if ((t|32)=='f') { - if (a>r) a=r; - for (d=a; d<=r; d++) { - char *ss = fmt_u(*d, buf+9); - if (d!=a) while (ss>buf) *--ss='0'; - else if (ss==buf+9) *--ss='0'; - out(f, ss, buf+9-ss); - } - if (p || (fl&ALT_FORM)) out(f, ".", 1); - for (; d<z && p>0; d++, p-=9) { - char *ss = fmt_u(*d, buf+9); - while (ss>buf) *--ss='0'; - out(f, ss, MIN(9,p)); - } - pad(f, '0', p+9, 9, 0); - } - else { - if (z<=a) z=a+1; - for (d=a; d<z && p>=0; d++) { - char *ss = fmt_u(*d, buf+9); - if (ss==buf+9) *--ss='0'; - if (d!=a) while (ss>buf) *--ss='0'; - else { - out(f, ss++, 1); - if (p>0||(fl&ALT_FORM)) out(f, ".", 1); - } - out(f, ss, MIN(buf+9-ss, p)); - p -= (int)(buf+9-ss); - } - pad(f, '0', p+18, 18, 0); - out(f, estr, ebuf-estr); - } - - pad(f, ' ', 0, pl+l, fl^LEFT_ADJ); - - return (int)pl+(int)l; -} - -static int -fmt_core(struct fmt_args *f, const char *fmt, mrb_float flo) -{ - ptrdiff_t p; - - if (*fmt != '%') { - return -1; - } - ++fmt; - - if (*fmt == '.') { - ++fmt; - for (p = 0; ISDIGIT(*fmt); ++fmt) { - p = 10 * p + (*fmt - '0'); - } - } - else { - p = -1; - } - - switch (*fmt) { - case 'e': case 'f': case 'g': case 'a': - case 'E': case 'F': case 'G': case 'A': - return fmt_fp(f, flo, p, 0, *fmt); - default: - return -1; - } -} - -mrb_value -mrb_float_to_str(mrb_state *mrb, mrb_value flo, const char *fmt) -{ - struct fmt_args f; - - f.mrb = mrb; - f.str = mrb_str_new_capa(mrb, 24); - if (fmt_core(&f, fmt, mrb_float(flo)) < 0) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid format string"); - } - return f.str; -} |