From 991b616a108e1a4b648a9d761195494f77dead23 Mon Sep 17 00:00:00 2001 From: Lephe Date: Mon, 7 Jun 2021 18:53:05 +0200 Subject: [PATCH] std: remove the printf implementation --- CMakeLists.txt | 8 - README.md | 4 - include/gint/kprint.h | 155 ----- include/gint/std/stdio.h | 51 +- src/3rdparty/grisu2b_59_56/LICENSE | 22 - src/3rdparty/grisu2b_59_56/README | 14 - src/3rdparty/grisu2b_59_56/diy_fp.h | 58 -- src/3rdparty/grisu2b_59_56/double.h | 110 ---- src/3rdparty/grisu2b_59_56/grisu2.h | 27 - src/3rdparty/grisu2b_59_56/grisu2b_59_56.c | 95 --- src/3rdparty/grisu2b_59_56/k_comp.h | 32 -- src/3rdparty/grisu2b_59_56/powers.h | 27 - .../grisu2b_59_56/powers_ten_round64.h | 36 -- src/kprint/kformat_fp.c | 282 --------- src/kprint/kprint.c | 539 ------------------ src/std/aprint.c | 30 +- src/std/print.c | 43 -- 17 files changed, 17 insertions(+), 1516 deletions(-) delete mode 100644 include/gint/kprint.h delete mode 100644 src/3rdparty/grisu2b_59_56/LICENSE delete mode 100644 src/3rdparty/grisu2b_59_56/README delete mode 100644 src/3rdparty/grisu2b_59_56/diy_fp.h delete mode 100644 src/3rdparty/grisu2b_59_56/double.h delete mode 100644 src/3rdparty/grisu2b_59_56/grisu2.h delete mode 100644 src/3rdparty/grisu2b_59_56/grisu2b_59_56.c delete mode 100644 src/3rdparty/grisu2b_59_56/k_comp.h delete mode 100644 src/3rdparty/grisu2b_59_56/powers.h delete mode 100644 src/3rdparty/grisu2b_59_56/powers_ten_round64.h delete mode 100644 src/kprint/kformat_fp.c delete mode 100644 src/kprint/kprint.c delete mode 100644 src/std/print.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 75759a8..b6f1750 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -51,8 +51,6 @@ set(SOURCES_COMMON src/kmalloc/arena_gint.c src/kmalloc/arena_osheap.c src/kmalloc/kmalloc.c - src/kprint/kprint.c - src/kprint/kformat_fp.c src/mmu/mmu.c src/render/dhline.c src/render/dimage.c @@ -67,7 +65,6 @@ set(SOURCES_COMMON src/spu/spu.c src/std/aprint.c src/std/malloc.c - src/std/print.c src/tmu/inth-etmu.s src/tmu/inth-tmu.s src/tmu/sleep.c @@ -80,7 +77,6 @@ set(SOURCES_COMMON src/usb/usb.c src/3rdparty/tinymt32/rand.c src/3rdparty/tinymt32/tinymt32.c - src/3rdparty/grisu2b_59_56/grisu2b_59_56.c ) set(SOURCES_FX src/gray/engine.c @@ -132,10 +128,6 @@ include_directories( "${FXSDK_COMPILER_INSTALL}/include/openlibm") add_compile_options(-Wall -Wextra -std=c11 -Os -fstrict-volatile-bitfields -mtas) -# Silence extended warnings on Grisu2b code -set_source_files_properties(src/3rdparty/grisu2b_59_56/grisu2b_59_56.c PROPERTIES - COMPILE_OPTIONS "-Wno-all;-Wno-extra") - if("${FXSDK_PLATFORM_LONG}" STREQUAL fx9860G) add_compile_definitions(FX9860G) add_library(gint-fx STATIC ${SOURCES_COMMON} ${SOURCES_FX} ${ASSETS_FX}) diff --git a/README.md b/README.md index 79112a8..1434937 100644 --- a/README.md +++ b/README.md @@ -18,10 +18,6 @@ Currently, this includes: * A stripped-down version of the [TinyMT random number generator](http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/TINYMT/index.html) ([GitHub repository](https://github.com/MersenneTwister-Lab/TinyMT)) by Mutsuo Saito and Makoto Matsumoto. See `src/3rdparty/tinymt32/LICENSE.txt`. -* A stripped-down version of the [Grisu2b floating-point representation - algorithm](https://www.cs.tufts.edu/~nr/cs257/archive/florian-loitsch/printf.pdf) - with α=-59 and γ=-56, by Florian Loitsch. See `src/3rdparty/grisu2b_59_56/README` - for details, and [the original code here](https://drive.google.com/open?id=0BwvYOx00EwKmejFIMjRORTFLcTA). ## Programming interface diff --git a/include/gint/kprint.h b/include/gint/kprint.h deleted file mode 100644 index c52cdc4..0000000 --- a/include/gint/kprint.h +++ /dev/null @@ -1,155 +0,0 @@ -//--- -// gint:kprint - gint's printf(3)-like formatted printer -//--- - -#ifndef GINT_KPRINT -#define GINT_KPRINT - -#include -#include -#include - -//--- -// Formatted printing -//--- - -/* kvsprint(): Formatted print to string - This function is similar to vsnprintf(3), except that variadic arguments are - passed as a pointer to va_list. For standard functions like vsnprintf(3), - see . */ -size_t kvsprint(char *output, size_t len, char const *format, va_list *args); - -/* kprint_enable_fp(): Enable and load floating-point formats - Loads floating-point formats %e, %E, %f, %F, %g and %G. By default these - formats are not enabled because the formatting code takes a large amount of - space. Calling this function pulls the floating-point formatter from the - gint library at link time. */ -void kprint_enable_fp(void); - -//--- -// Printer extensions -//--- - -/* Arguments passed to formatters */ -#define KFORMAT_ARGS \ - GUNUSED int spec, /* Specifier letter */ \ - GUNUSED kprint_options_t *opt, /* Other options in format */ \ - va_list *args /* Vararg list to read from */ - -/* kprint_options_t: Standard format options */ -typedef struct { - /* Minimal length of formatted string (padding can be added) */ - uint16_t length; - /* How much significant characters of data, meaning varies */ - int16_t precision; - - /* Size specifier for integers (%o, %x, %i, %d, %u), may be one of: - (0) char (8-bit) - (1) short (16-bit) - (2) int (32-bit) - (3) long (32-bit) - (4) long long (64-bit) */ - uint8_t size; - - /* (#) Alternative form: base prefixes, decimal point */ - uint alternative :1; - /* ( ) Add a blank sign before nonnegative numbers */ - uint blank_sign :1; - /* (+) Always add a sign before a number (overrides ' ') */ - uint force_sign :1; - - /* Alignment options: each option overrides all others before itself - NUL By default, align right - (0) Left-pad numerical values with zeros - (-) Align left by adding space on the right, dropping zeros */ - uint8_t alignment; - -} GPACKED(2) kprint_options_t; - -/* kprint_formatter_t: Type of format function */ -typedef void (*kprint_formatter_t)(KFORMAT_ARGS); - -/* kprint_register(): Register a formatter - - The formatter designated by the specified lowercase letter (eg 'q') is - registered. It will handle formats for both the lowercase and uppercase - formats (eg "%q" and "%Q"). - - Default formatters can be overridden (although not advised), but formatters - for "h" and "l" and "z" cannot be set because these letters are used as size - specifiers (eg in "%hd" or "%zu"). - - A formatter can be removed or disabled by registering NULL. - - @spec Specifier to use, should be a lowercase letter - @kformat Format function */ -void kprint_register(int spec, kprint_formatter_t kformat); - -/* kprint_out(): Output a single character to the kprint buffer */ -void kprint_out(int byte); - -/* kprint_outn(): Output the same character times */ -void kprint_outn(int byte, int n); - -/* kprint_outstr(): Output a string to the kprint buffer */ -void kprint_outstr(char const *str, int n); - -//--- -// Helper functions for formatters -//--- - -/* kprint_geometry_t: General geometry for a format - This helper defines the structure of a format as follows: - - sign v |< zeros >| |< content >| - _ _ _ _ _ _ _ _ _ + 0 x 0 0 0 0 0 0 8 a c 7 . 3 c _ _ _ _ _ _ _ _ _ _ - |< left_spaces >| ^^^ prefix |< right_spaces >| - - The sign character is absent if sign=0, the prefix is specified by length - and is also absent if prefix=0. */ -typedef struct -{ - uint16_t left_spaces; /* Spaces before content */ - uint8_t sign; /* Sign character (NUL, ' ', '+' or '-') */ - uint8_t prefix; /* Base prefix ('0', '0x', etc) length */ - uint16_t zeros; /* For integer displays, number of zeros */ - uint16_t content; /* Content length in bytes */ - uint16_t right_spaces; /* Spaces after content */ - - /* Style of display: - KPRINT_GENERIC Sign ignored, 0-padding ignored - KPRINT_INTEGER .precision causes 0-padding - KPRINT_NUMERIC No effect */ - enum { KPRINT_GENERIC = 0, KPRINT_INTEGER, KPRINT_NUMERIC } style; - -} GPACKED(2) kprint_geometry_t; - -/* kformat_geometry(): Calculate the geometry of a format - - The caller provides as input: - * opt, as passed by the main kprint() routine - * g->prefix, the length of the desired prefix (if unused, 0) - * g->content, the natural content length for the provided data - * g->sign, the sign of the input ("+" or "-"); for KPRINT_GENERIC, 0 - * g->style, which affects the meaning of options - - This function outputs: - * g->sign, which will be changed to " " or NUL (0) depending on options - * All fields of g that are not part of the input - - The algorithm for laying out the format is as follows. - 1. For numerical and integer formats, turn a "+" sign into " " if - opt->blank_sign is set, "+" if opt->force_sign is set, NUL otherwise. - 2. Compute the total amount of padding needed to reach opt->length. - 3. In integer style, if a precision is specified and more than content - length plus sign and prefix, turn some padding into zeros. - 4. If numerical and integer styles, if opt->alignment == '0' turn all the - padding into zeros. - 5. Turn remaining padding into spaces at the left (if opt->alignment == NUL) - or right (if opt->alignment == '-'). - - @opt Options provided by the main kprint() routine - @g Format geometry (input/output) */ -void kformat_geometry(kprint_options_t *opt, kprint_geometry_t *g); - -#endif /* GINT_KPRINT */ diff --git a/include/gint/std/stdio.h b/include/gint/std/stdio.h index 4fe37cb..33f7a57 100644 --- a/include/gint/std/stdio.h +++ b/include/gint/std/stdio.h @@ -1,49 +1,2 @@ -//--- -// gint:std:stdio - a few functions provided by gint -//--- - -#ifndef GINT_STD_STDIO -#define GINT_STD_STDIO - -#include -#include - -/* Formatted printing functions - - These functions implement most of printf(3)'s features, including: - * Signed and unsigned integer formats (%d, %i, %o, %u, %x, %X) - * Character, string and pointer formats (%c, %s, %p) - * Format options (0, #, -, (space), length, precision) - * Parameter length (hh, h, l, ll, z) - * Limiting the size of the output and still returning the whole length - * If kprint_enable_fp() from is called: floating-point - formats (%e, %E, %f, %F, %g, %G) (disabled by default to save space) - - They do not support: - * Hexadecimal floating-point (%a, %A) - * The strerror() shorthand, since there is no errno (%m) - * Some size modifiers: long double (L), intmax_t (j), ptrdiff_t (t), and the - nonstandard synonyms q (ll) and Z (z) - * Dynamic length field (*) - * Thousands separators (') and locale-aware digits (I) - * Nonstandard synonyms %C (%lc) and %S (%ls) - - A new fixed-point format %j has been added; it behaves like %d but includes - a decimal point. The number of decimal places is specified by the precision - field. For instance %.3j with 12345 prints "123.45". This can be used for - decimal fixed-point values. */ - -/* Print to string from var args */ -int sprintf(char *str, char const *format, ...); -/* Print to string from va_list */ -int vsprintf(char *str, char const *format, va_list args); -/* Print to string with limited size from var args */ -int snprintf(char *str, size_t n, char const *format, ...); -/* Print to string with limited size from va_list */ -int vsnprintf(char *str, size_t n, char const *format, va_list args); -/* Print to auto-allocated string */ -int asprintf(char **strp, char const *format, ...); -/* Print to auto-allocated string from va_list */ -int vasprintf(char **strp, char const *format, va_list args); - -#endif /* GINT_STD_STDIO */ +/* Now provided by fxlibc. */ +#include diff --git a/src/3rdparty/grisu2b_59_56/LICENSE b/src/3rdparty/grisu2b_59_56/LICENSE deleted file mode 100644 index 46df159..0000000 --- a/src/3rdparty/grisu2b_59_56/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -Copyright (c) 2009 Florian Loitsch - - 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. diff --git a/src/3rdparty/grisu2b_59_56/README b/src/3rdparty/grisu2b_59_56/README deleted file mode 100644 index 3e14477..0000000 --- a/src/3rdparty/grisu2b_59_56/README +++ /dev/null @@ -1,14 +0,0 @@ -Grisu is an algorithm by Florian Loitsch to print the decimal representation of -floating-point numbers. - -The original code from which this folder is extracted can be found at -. - -Only a minimal variation, the Grisu2 rounding algorithm with α=-59 and γ=-56, -is present here. The code has been adapted to fit the limited runtime as well -as the use of OpenLibm. - -See the original paper at -and Florian Loitsch's home page at . - -The files are licensed under the permissive conditions of the attached LICENSE. diff --git a/src/3rdparty/grisu2b_59_56/diy_fp.h b/src/3rdparty/grisu2b_59_56/diy_fp.h deleted file mode 100644 index 021b89a..0000000 --- a/src/3rdparty/grisu2b_59_56/diy_fp.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - Copyright (c) 2009 Florian Loitsch - - 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. - */ -#pragma once -#include - -typedef struct diy_fp_t { - uint64_t f; - int e; -} diy_fp_t; - -static diy_fp_t minus(diy_fp_t x, diy_fp_t y) { - diy_fp_t r = {.f = x.f - y.f, .e = x.e}; - return r; -} - -/* -static diy_fp_t minus(diy_fp_t x, diy_fp_t y) { - assert(x.e == y.e); - assert(x.f >= y.f); - diy_fp_t r = {.f = x.f - y.f, .e = x.e}; - return r; -} -*/ - -static diy_fp_t multiply(diy_fp_t x, diy_fp_t y) { - uint64_t a,b,c,d,ac,bc,ad,bd,tmp,h; - diy_fp_t r; uint64_t M32 = 0xFFFFFFFF; - a = x.f >> 32; b = x.f & M32; - c = y.f >> 32; d = y.f & M32; - ac = a*c; bc = b*c; ad = a*d; bd = b*d; - tmp = (bd>>32) + (ad&M32) + (bc&M32); - tmp += 1U << 31; /// mult_round - r.f = ac+(ad>>32)+(bc>>32)+(tmp >>32); - r.e = x.e + y.e + 64; - return r; -} diff --git a/src/3rdparty/grisu2b_59_56/double.h b/src/3rdparty/grisu2b_59_56/double.h deleted file mode 100644 index f8f6c02..0000000 --- a/src/3rdparty/grisu2b_59_56/double.h +++ /dev/null @@ -1,110 +0,0 @@ -/* - Copyright (c) 2009 Florian Loitsch - - 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. - */ -#pragma once - -#include "diy_fp.h" -#include "powers.h" -#include - -typedef union { - double d; - uint64_t n; -} converter_t; - -static uint64_t double_to_uint64(double d) { converter_t tmp; tmp.d = d; return tmp.n; } -static double uint64_to_double(uint64_t d64) { converter_t tmp; tmp.n = d64; return tmp.d; } - -#define DP_SIGNIFICAND_SIZE 52 -#define DP_EXPONENT_BIAS (0x3FF + DP_SIGNIFICAND_SIZE) -#define DP_MIN_EXPONENT (-DP_EXPONENT_BIAS) -#define DP_EXPONENT_MASK 0x7FF0000000000000 -#define DP_SIGNIFICAND_MASK 0x000FFFFFFFFFFFFF -#define DP_HIDDEN_BIT 0x0010000000000000 - -static diy_fp_t normalize_diy_fp(diy_fp_t in) { - diy_fp_t res = in; - /* Normalize now */ - /* the original number could have been a denormal. */ - while (! (res.f & DP_HIDDEN_BIT)) - { - res.f <<= 1; - res.e--; - } - /* do the final shifts in one go. Don't forget the hidden bit (the '-1') */ - res.f <<= (DIY_SIGNIFICAND_SIZE - DP_SIGNIFICAND_SIZE - 1); - res.e = res.e - (DIY_SIGNIFICAND_SIZE - DP_SIGNIFICAND_SIZE - 1); - return res; -} - -static diy_fp_t double2diy_fp(double d) { - uint64_t d64 = double_to_uint64(d); - int biased_e = (d64 & DP_EXPONENT_MASK) >> DP_SIGNIFICAND_SIZE; - uint64_t significand = (d64 & DP_SIGNIFICAND_MASK); - diy_fp_t res; - if (biased_e != 0) - { - res.f = significand + DP_HIDDEN_BIT; - res.e = biased_e - DP_EXPONENT_BIAS; - } else { - res.f = significand; - res.e = DP_MIN_EXPONENT + 1; - } - return res; -} - -static diy_fp_t normalize_boundary(diy_fp_t in) { - diy_fp_t res = in; - /* Normalize now */ - /* the original number could have been a denormal. */ - while (! (res.f & (DP_HIDDEN_BIT << 1))) - { - res.f <<= 1; - res.e--; - } - /* do the final shifts in one go. Don't forget the hidden bit (the '-1') */ - res.f <<= (DIY_SIGNIFICAND_SIZE - DP_SIGNIFICAND_SIZE - 2); - res.e = res.e - (DIY_SIGNIFICAND_SIZE - DP_SIGNIFICAND_SIZE - 2); - return res; -} - -static void normalized_boundaries(double d, diy_fp_t* out_m_minus, diy_fp_t* out_m_plus) { - diy_fp_t v = double2diy_fp(d); - diy_fp_t pl, mi; - bool significand_is_zero = v.f == DP_HIDDEN_BIT; - pl.f = (v.f << 1) + 1; pl.e = v.e - 1; - pl = normalize_boundary(pl); - if (significand_is_zero) - { - mi.f = (v.f << 2) - 1; - mi.e = v.e - 2; - } else { - mi.f = (v.f << 1) - 1; - mi.e = v.e - 1; - } - mi.f <<= mi.e - pl.e; - mi.e = pl.e; - *out_m_plus = pl; - *out_m_minus = mi; -} diff --git a/src/3rdparty/grisu2b_59_56/grisu2.h b/src/3rdparty/grisu2b_59_56/grisu2.h deleted file mode 100644 index c9b0cad..0000000 --- a/src/3rdparty/grisu2b_59_56/grisu2.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - Copyright (c) 2009 Florian Loitsch - - 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. - */ -#pragma once - -void grisu2(double v, char* buffer, int* length, int* K); diff --git a/src/3rdparty/grisu2b_59_56/grisu2b_59_56.c b/src/3rdparty/grisu2b_59_56/grisu2b_59_56.c deleted file mode 100644 index af0b652..0000000 --- a/src/3rdparty/grisu2b_59_56/grisu2b_59_56.c +++ /dev/null @@ -1,95 +0,0 @@ -/* - Copyright (c) 2009 Florian Loitsch - - 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 "diy_fp.h" -#include "k_comp.h" -#include "double.h" -#include "powers.h" -#include -#include "grisu2.h" -#include - -#define TEN9 1000000000 - -void grisu_round(char* buffer, int len, - uint64_t delta, uint64_t rest, - uint64_t ten_kappa, uint64_t wp_w) { - while (rest < wp_w && - delta - rest >= ten_kappa && - (rest + ten_kappa < wp_w || /// closer - wp_w - rest > rest+ten_kappa - wp_w)) - { - buffer[len-1]--; rest += ten_kappa; - } -} - -void digit_gen(diy_fp_t W, diy_fp_t Mp, diy_fp_t delta, - char* buffer, int* len, int* K) { - uint32_t div; int d,kappa; diy_fp_t one, wp_w; - wp_w = minus(Mp, W); - one.f = ((uint64_t) 1) << -Mp.e; one.e = Mp.e; - uint32_t p1 = Mp.f >> -one.e; /// Mp_cut - uint64_t p2 = Mp.f & (one.f - 1); - *len = 0; kappa = 10; div = TEN9; - while (kappa > 0) { - d = p1 / div; - if (d || *len) buffer[(*len)++] = '0' + d; /// Mp_inv1 - p1 %= div; kappa--; - uint64_t tmp = (((uint64_t)p1)<<-one.e)+p2; - if (tmp <= delta.f) { /// Mp_delta - *K += kappa; - grisu_round(buffer, *len, delta.f, tmp, ((uint64_t)div) << -one.e, wp_w.f); - return; - } - div /= 10; - } - uint64_t unit = 1; - while (1) { - p2 *= 10; delta.f *= 10; unit *= 10; - d = p2 >> -one.e; - if (d || *len) buffer[(*len)++] = '0' + d; - p2 &= one.f - 1; kappa--; - if (p2 < delta.f) { - *K += kappa; - grisu_round(buffer, *len, delta.f, p2, one.f, wp_w.f*unit); - return; - } - } -} - -void grisu2(double v, char* buffer, int* length, int* K) { - diy_fp_t w_m, w_p; - int q = 64, alpha = -59, gamma = -56; int pos; - normalized_boundaries(v, &w_m, &w_p); - diy_fp_t w = normalize_diy_fp(double2diy_fp(v)); - int mk = k_comp(w_p.e + q, alpha, gamma); - diy_fp_t c_mk = cached_power(mk); - diy_fp_t W = multiply(w, c_mk); - diy_fp_t Wp = multiply(w_p, c_mk); - diy_fp_t Wm = multiply(w_m, c_mk); - Wm.f++; Wp.f--; - diy_fp_t delta = minus(Wp, Wm); - *K = -mk; - digit_gen(W, Wp, delta, buffer, length, K); -} diff --git a/src/3rdparty/grisu2b_59_56/k_comp.h b/src/3rdparty/grisu2b_59_56/k_comp.h deleted file mode 100644 index 226a3f6..0000000 --- a/src/3rdparty/grisu2b_59_56/k_comp.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - Copyright (c) 2009 Florian Loitsch - - 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. - */ -#pragma once -#include - -#define D_1_LOG2_10 0.30102999566398114 // 1 / lg(10) - -static int k_comp(int e, int alpha, int gamma) { - return ceil((alpha-e+63) * D_1_LOG2_10); -} diff --git a/src/3rdparty/grisu2b_59_56/powers.h b/src/3rdparty/grisu2b_59_56/powers.h deleted file mode 100644 index 16a4301..0000000 --- a/src/3rdparty/grisu2b_59_56/powers.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - Copyright (c) 2009 Florian Loitsch - - 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. - */ -#pragma once -#include "diy_fp.h" -#include "powers_ten_round64.h" diff --git a/src/3rdparty/grisu2b_59_56/powers_ten_round64.h b/src/3rdparty/grisu2b_59_56/powers_ten_round64.h deleted file mode 100644 index 6d72879..0000000 --- a/src/3rdparty/grisu2b_59_56/powers_ten_round64.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - Copyright (c) 2009 Florian Loitsch - - 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 - -#define DIY_SIGNIFICAND_SIZE 64 -static const uint64_t powers_ten[] = {0xbf29dcaba82fdeae , 0xeef453d6923bd65a , 0x9558b4661b6565f8 , 0xbaaee17fa23ebf76 , 0xe95a99df8ace6f54 , 0x91d8a02bb6c10594 , 0xb64ec836a47146fa , 0xe3e27a444d8d98b8 , 0x8e6d8c6ab0787f73 , 0xb208ef855c969f50 , 0xde8b2b66b3bc4724 , 0x8b16fb203055ac76 , 0xaddcb9e83c6b1794 , 0xd953e8624b85dd79 , 0x87d4713d6f33aa6c , 0xa9c98d8ccb009506 , 0xd43bf0effdc0ba48 , 0x84a57695fe98746d , 0xa5ced43b7e3e9188 , 0xcf42894a5dce35ea , 0x818995ce7aa0e1b2 , 0xa1ebfb4219491a1f , 0xca66fa129f9b60a7 , 0xfd00b897478238d1 , 0x9e20735e8cb16382 , 0xc5a890362fddbc63 , 0xf712b443bbd52b7c , 0x9a6bb0aa55653b2d , 0xc1069cd4eabe89f9 , 0xf148440a256e2c77 , 0x96cd2a865764dbca , 0xbc807527ed3e12bd , 0xeba09271e88d976c , 0x93445b8731587ea3 , 0xb8157268fdae9e4c , 0xe61acf033d1a45df , 0x8fd0c16206306bac , 0xb3c4f1ba87bc8697 , 0xe0b62e2929aba83c , 0x8c71dcd9ba0b4926 , 0xaf8e5410288e1b6f , 0xdb71e91432b1a24b , 0x892731ac9faf056f , 0xab70fe17c79ac6ca , 0xd64d3d9db981787d , 0x85f0468293f0eb4e , 0xa76c582338ed2622 , 0xd1476e2c07286faa , 0x82cca4db847945ca , 0xa37fce126597973d , 0xcc5fc196fefd7d0c , 0xff77b1fcbebcdc4f , 0x9faacf3df73609b1 , 0xc795830d75038c1e , 0xf97ae3d0d2446f25 , 0x9becce62836ac577 , 0xc2e801fb244576d5 , 0xf3a20279ed56d48a , 0x9845418c345644d7 , 0xbe5691ef416bd60c , 0xedec366b11c6cb8f , 0x94b3a202eb1c3f39 , 0xb9e08a83a5e34f08 , 0xe858ad248f5c22ca , 0x91376c36d99995be , 0xb58547448ffffb2e , 0xe2e69915b3fff9f9 , 0x8dd01fad907ffc3c , 0xb1442798f49ffb4b , 0xdd95317f31c7fa1d , 0x8a7d3eef7f1cfc52 , 0xad1c8eab5ee43b67 , 0xd863b256369d4a41 , 0x873e4f75e2224e68 , 0xa90de3535aaae202 , 0xd3515c2831559a83 , 0x8412d9991ed58092 , 0xa5178fff668ae0b6 , 0xce5d73ff402d98e4 , 0x80fa687f881c7f8e , 0xa139029f6a239f72 , 0xc987434744ac874f , 0xfbe9141915d7a922 , 0x9d71ac8fada6c9b5 , 0xc4ce17b399107c23 , 0xf6019da07f549b2b , 0x99c102844f94e0fb , 0xc0314325637a193a , 0xf03d93eebc589f88 , 0x96267c7535b763b5 , 0xbbb01b9283253ca3 , 0xea9c227723ee8bcb , 0x92a1958a7675175f , 0xb749faed14125d37 , 0xe51c79a85916f485 , 0x8f31cc0937ae58d3 , 0xb2fe3f0b8599ef08 , 0xdfbdcece67006ac9 , 0x8bd6a141006042be , 0xaecc49914078536d , 0xda7f5bf590966849 , 0x888f99797a5e012d , 0xaab37fd7d8f58179 , 0xd5605fcdcf32e1d7 , 0x855c3be0a17fcd26 , 0xa6b34ad8c9dfc070 , 0xd0601d8efc57b08c , 0x823c12795db6ce57 , 0xa2cb1717b52481ed , 0xcb7ddcdda26da269 , 0xfe5d54150b090b03 , 0x9efa548d26e5a6e2 , 0xc6b8e9b0709f109a , 0xf867241c8cc6d4c1 , 0x9b407691d7fc44f8 , 0xc21094364dfb5637 , 0xf294b943e17a2bc4 , 0x979cf3ca6cec5b5b , 0xbd8430bd08277231 , 0xece53cec4a314ebe , 0x940f4613ae5ed137 , 0xb913179899f68584 , 0xe757dd7ec07426e5 , 0x9096ea6f3848984f , 0xb4bca50b065abe63 , 0xe1ebce4dc7f16dfc , 0x8d3360f09cf6e4bd , 0xb080392cc4349ded , 0xdca04777f541c568 , 0x89e42caaf9491b61 , 0xac5d37d5b79b6239 , 0xd77485cb25823ac7 , 0x86a8d39ef77164bd , 0xa8530886b54dbdec , 0xd267caa862a12d67 , 0x8380dea93da4bc60 , 0xa46116538d0deb78 , 0xcd795be870516656 , 0x806bd9714632dff6 , 0xa086cfcd97bf97f4 , 0xc8a883c0fdaf7df0 , 0xfad2a4b13d1b5d6c , 0x9cc3a6eec6311a64 , 0xc3f490aa77bd60fd , 0xf4f1b4d515acb93c , 0x991711052d8bf3c5 , 0xbf5cd54678eef0b7 , 0xef340a98172aace5 , 0x9580869f0e7aac0f , 0xbae0a846d2195713 , 0xe998d258869facd7 , 0x91ff83775423cc06 , 0xb67f6455292cbf08 , 0xe41f3d6a7377eeca , 0x8e938662882af53e , 0xb23867fb2a35b28e , 0xdec681f9f4c31f31 , 0x8b3c113c38f9f37f , 0xae0b158b4738705f , 0xd98ddaee19068c76 , 0x87f8a8d4cfa417ca , 0xa9f6d30a038d1dbc , 0xd47487cc8470652b , 0x84c8d4dfd2c63f3b , 0xa5fb0a17c777cf0a , 0xcf79cc9db955c2cc , 0x81ac1fe293d599c0 , 0xa21727db38cb0030 , 0xca9cf1d206fdc03c , 0xfd442e4688bd304b , 0x9e4a9cec15763e2f , 0xc5dd44271ad3cdba , 0xf7549530e188c129 , 0x9a94dd3e8cf578ba , 0xc13a148e3032d6e8 , 0xf18899b1bc3f8ca2 , 0x96f5600f15a7b7e5 , 0xbcb2b812db11a5de , 0xebdf661791d60f56 , 0x936b9fcebb25c996 , 0xb84687c269ef3bfb , 0xe65829b3046b0afa , 0x8ff71a0fe2c2e6dc , 0xb3f4e093db73a093 , 0xe0f218b8d25088b8 , 0x8c974f7383725573 , 0xafbd2350644eead0 , 0xdbac6c247d62a584 , 0x894bc396ce5da772 , 0xab9eb47c81f5114f , 0xd686619ba27255a3 , 0x8613fd0145877586 , 0xa798fc4196e952e7 , 0xd17f3b51fca3a7a1 , 0x82ef85133de648c5 , 0xa3ab66580d5fdaf6 , 0xcc963fee10b7d1b3 , 0xffbbcfe994e5c620 , 0x9fd561f1fd0f9bd4 , 0xc7caba6e7c5382c9 , 0xf9bd690a1b68637b , 0x9c1661a651213e2d , 0xc31bfa0fe5698db8 , 0xf3e2f893dec3f126 , 0x986ddb5c6b3a76b8 , 0xbe89523386091466 , 0xee2ba6c0678b597f , 0x94db483840b717f0 , 0xba121a4650e4ddec , 0xe896a0d7e51e1566 , 0x915e2486ef32cd60 , 0xb5b5ada8aaff80b8 , 0xe3231912d5bf60e6 , 0x8df5efabc5979c90 , 0xb1736b96b6fd83b4 , 0xddd0467c64bce4a1 , 0x8aa22c0dbef60ee4 , 0xad4ab7112eb3929e , 0xd89d64d57a607745 , 0x87625f056c7c4a8b , 0xa93af6c6c79b5d2e , 0xd389b47879823479 , 0x843610cb4bf160cc , 0xa54394fe1eedb8ff , 0xce947a3da6a9273e , 0x811ccc668829b887 , 0xa163ff802a3426a9 , 0xc9bcff6034c13053 , 0xfc2c3f3841f17c68 , 0x9d9ba7832936edc1 , 0xc5029163f384a931 , 0xf64335bcf065d37d , 0x99ea0196163fa42e , 0xc06481fb9bcf8d3a , 0xf07da27a82c37088 , 0x964e858c91ba2655 , 0xbbe226efb628afeb , 0xeadab0aba3b2dbe5 , 0x92c8ae6b464fc96f , 0xb77ada0617e3bbcb , 0xe55990879ddcaabe , 0x8f57fa54c2a9eab7 , 0xb32df8e9f3546564 , 0xdff9772470297ebd , 0x8bfbea76c619ef36 , 0xaefae51477a06b04 , 0xdab99e59958885c5 , 0x88b402f7fd75539b , 0xaae103b5fcd2a882 , 0xd59944a37c0752a2 , 0x857fcae62d8493a5 , 0xa6dfbd9fb8e5b88f , 0xd097ad07a71f26b2 , 0x825ecc24c8737830 , 0xa2f67f2dfa90563b , 0xcbb41ef979346bca , 0xfea126b7d78186bd , 0x9f24b832e6b0f436 , 0xc6ede63fa05d3144 , 0xf8a95fcf88747d94 , 0x9b69dbe1b548ce7d , 0xc24452da229b021c , 0xf2d56790ab41c2a3 , 0x97c560ba6b0919a6 , 0xbdb6b8e905cb600f , 0xed246723473e3813 , 0x9436c0760c86e30c , 0xb94470938fa89bcf , 0xe7958cb87392c2c3 , 0x90bd77f3483bb9ba , 0xb4ecd5f01a4aa828 , 0xe2280b6c20dd5232 , 0x8d590723948a535f , 0xb0af48ec79ace837 , 0xdcdb1b2798182245 , 0x8a08f0f8bf0f156b , 0xac8b2d36eed2dac6 , 0xd7adf884aa879177 , 0x86ccbb52ea94baeb , 0xa87fea27a539e9a5 , 0xd29fe4b18e88640f , 0x83a3eeeef9153e89 , 0xa48ceaaab75a8e2b , 0xcdb02555653131b6 , 0x808e17555f3ebf12 , 0xa0b19d2ab70e6ed6 , 0xc8de047564d20a8c , 0xfb158592be068d2f , 0x9ced737bb6c4183d , 0xc428d05aa4751e4d , 0xf53304714d9265e0 , 0x993fe2c6d07b7fac , 0xbf8fdb78849a5f97 , 0xef73d256a5c0f77d , 0x95a8637627989aae , 0xbb127c53b17ec159 , 0xe9d71b689dde71b0 , 0x9226712162ab070e , 0xb6b00d69bb55c8d1 , 0xe45c10c42a2b3b06 , 0x8eb98a7a9a5b04e3 , 0xb267ed1940f1c61c , 0xdf01e85f912e37a3 , 0x8b61313bbabce2c6 , 0xae397d8aa96c1b78 , 0xd9c7dced53c72256 , 0x881cea14545c7575 , 0xaa242499697392d3 , 0xd4ad2dbfc3d07788 , 0x84ec3c97da624ab5 , 0xa6274bbdd0fadd62 , 0xcfb11ead453994ba , 0x81ceb32c4b43fcf5 , 0xa2425ff75e14fc32 , 0xcad2f7f5359a3b3e , 0xfd87b5f28300ca0e , 0x9e74d1b791e07e48 , 0xc612062576589ddb , 0xf79687aed3eec551 , 0x9abe14cd44753b53 , 0xc16d9a0095928a27 , 0xf1c90080baf72cb1 , 0x971da05074da7bef , 0xbce5086492111aeb , 0xec1e4a7db69561a5 , 0x9392ee8e921d5d07 , 0xb877aa3236a4b449 , 0xe69594bec44de15b , 0x901d7cf73ab0acd9 , 0xb424dc35095cd80f , 0xe12e13424bb40e13 , 0x8cbccc096f5088cc , 0xafebff0bcb24aaff , 0xdbe6fecebdedd5bf , 0x89705f4136b4a597 , 0xabcc77118461cefd , 0xd6bf94d5e57a42bc , 0x8637bd05af6c69b6 , 0xa7c5ac471b478423 , 0xd1b71758e219652c , 0x83126e978d4fdf3b , 0xa3d70a3d70a3d70a , 0xcccccccccccccccd , 0x8000000000000000 , 0xa000000000000000 , 0xc800000000000000 , 0xfa00000000000000 , 0x9c40000000000000 , 0xc350000000000000 , 0xf424000000000000 , 0x9896800000000000 , 0xbebc200000000000 , 0xee6b280000000000 , 0x9502f90000000000 , 0xba43b74000000000 , 0xe8d4a51000000000 , 0x9184e72a00000000 , 0xb5e620f480000000 , 0xe35fa931a0000000 , 0x8e1bc9bf04000000 , 0xb1a2bc2ec5000000 , 0xde0b6b3a76400000 , 0x8ac7230489e80000 , 0xad78ebc5ac620000 , 0xd8d726b7177a8000 , 0x878678326eac9000 , 0xa968163f0a57b400 , 0xd3c21bcecceda100 , 0x84595161401484a0 , 0xa56fa5b99019a5c8 , 0xcecb8f27f4200f3a , 0x813f3978f8940984 , 0xa18f07d736b90be5 , 0xc9f2c9cd04674edf , 0xfc6f7c4045812296 , 0x9dc5ada82b70b59e , 0xc5371912364ce305 , 0xf684df56c3e01bc7 , 0x9a130b963a6c115c , 0xc097ce7bc90715b3 , 0xf0bdc21abb48db20 , 0x96769950b50d88f4 , 0xbc143fa4e250eb31 , 0xeb194f8e1ae525fd , 0x92efd1b8d0cf37be , 0xb7abc627050305ae , 0xe596b7b0c643c719 , 0x8f7e32ce7bea5c70 , 0xb35dbf821ae4f38c , 0xe0352f62a19e306f , 0x8c213d9da502de45 , 0xaf298d050e4395d7 , 0xdaf3f04651d47b4c , 0x88d8762bf324cd10 , 0xab0e93b6efee0054 , 0xd5d238a4abe98068 , 0x85a36366eb71f041 , 0xa70c3c40a64e6c52 , 0xd0cf4b50cfe20766 , 0x82818f1281ed44a0 , 0xa321f2d7226895c8 , 0xcbea6f8ceb02bb3a , 0xfee50b7025c36a08 , 0x9f4f2726179a2245 , 0xc722f0ef9d80aad6 , 0xf8ebad2b84e0d58c , 0x9b934c3b330c8577 , 0xc2781f49ffcfa6d5 , 0xf316271c7fc3908b , 0x97edd871cfda3a57 , 0xbde94e8e43d0c8ec , 0xed63a231d4c4fb27 , 0x945e455f24fb1cf9 , 0xb975d6b6ee39e437 , 0xe7d34c64a9c85d44 , 0x90e40fbeea1d3a4b , 0xb51d13aea4a488dd , 0xe264589a4dcdab15 , 0x8d7eb76070a08aed , 0xb0de65388cc8ada8 , 0xdd15fe86affad912 , 0x8a2dbf142dfcc7ab , 0xacb92ed9397bf996 , 0xd7e77a8f87daf7fc , 0x86f0ac99b4e8dafd , 0xa8acd7c0222311bd , 0xd2d80db02aabd62c , 0x83c7088e1aab65db , 0xa4b8cab1a1563f52 , 0xcde6fd5e09abcf27 , 0x80b05e5ac60b6178 , 0xa0dc75f1778e39d6 , 0xc913936dd571c84c , 0xfb5878494ace3a5f , 0x9d174b2dcec0e47b , 0xc45d1df942711d9a , 0xf5746577930d6501 , 0x9968bf6abbe85f20 , 0xbfc2ef456ae276e9 , 0xefb3ab16c59b14a3 , 0x95d04aee3b80ece6 , 0xbb445da9ca61281f , 0xea1575143cf97227 , 0x924d692ca61be758 , 0xb6e0c377cfa2e12e , 0xe498f455c38b997a , 0x8edf98b59a373fec , 0xb2977ee300c50fe7 , 0xdf3d5e9bc0f653e1 , 0x8b865b215899f46d , 0xae67f1e9aec07188 , 0xda01ee641a708dea , 0x884134fe908658b2 , 0xaa51823e34a7eedf , 0xd4e5e2cdc1d1ea96 , 0x850fadc09923329e , 0xa6539930bf6bff46 , 0xcfe87f7cef46ff17 , 0x81f14fae158c5f6e , 0xa26da3999aef774a , 0xcb090c8001ab551c , 0xfdcb4fa002162a63 , 0x9e9f11c4014dda7e , 0xc646d63501a1511e , 0xf7d88bc24209a565 , 0x9ae757596946075f , 0xc1a12d2fc3978937 , 0xf209787bb47d6b85 , 0x9745eb4d50ce6333 , 0xbd176620a501fc00 , 0xec5d3fa8ce427b00 , 0x93ba47c980e98ce0 , 0xb8a8d9bbe123f018 , 0xe6d3102ad96cec1e , 0x9043ea1ac7e41393 , 0xb454e4a179dd1877 , 0xe16a1dc9d8545e95 , 0x8ce2529e2734bb1d , 0xb01ae745b101e9e4 , 0xdc21a1171d42645d , 0x899504ae72497eba , 0xabfa45da0edbde69 , 0xd6f8d7509292d603 , 0x865b86925b9bc5c2 , 0xa7f26836f282b733 , 0xd1ef0244af2364ff , 0x8335616aed761f1f , 0xa402b9c5a8d3a6e7 , 0xcd036837130890a1 , 0x802221226be55a65 , 0xa02aa96b06deb0fe , 0xc83553c5c8965d3d , 0xfa42a8b73abbf48d , 0x9c69a97284b578d8 , 0xc38413cf25e2d70e , 0xf46518c2ef5b8cd1 , 0x98bf2f79d5993803 , 0xbeeefb584aff8604 , 0xeeaaba2e5dbf6785 , 0x952ab45cfa97a0b3 , 0xba756174393d88e0 , 0xe912b9d1478ceb17 , 0x91abb422ccb812ef , 0xb616a12b7fe617aa , 0xe39c49765fdf9d95 , 0x8e41ade9fbebc27d , 0xb1d219647ae6b31c , 0xde469fbd99a05fe3 , 0x8aec23d680043bee , 0xada72ccc20054aea , 0xd910f7ff28069da4 , 0x87aa9aff79042287 , 0xa99541bf57452b28 , 0xd3fa922f2d1675f2 , 0x847c9b5d7c2e09b7 , 0xa59bc234db398c25 , 0xcf02b2c21207ef2f , 0x8161afb94b44f57d , 0xa1ba1ba79e1632dc , 0xca28a291859bbf93 , 0xfcb2cb35e702af78 , 0x9defbf01b061adab , 0xc56baec21c7a1916 , 0xf6c69a72a3989f5c , 0x9a3c2087a63f6399 , 0xc0cb28a98fcf3c80 , 0xf0fdf2d3f3c30b9f , 0x969eb7c47859e744 , 0xbc4665b596706115 , 0xeb57ff22fc0c795a , 0x9316ff75dd87cbd8 , 0xb7dcbf5354e9bece , 0xe5d3ef282a242e82 , 0x8fa475791a569d11 , 0xb38d92d760ec4455 , 0xe070f78d3927556b , 0x8c469ab843b89563 , 0xaf58416654a6babb , 0xdb2e51bfe9d0696a , 0x88fcf317f22241e2 , 0xab3c2fddeeaad25b , 0xd60b3bd56a5586f2 , 0x85c7056562757457 , 0xa738c6bebb12d16d , 0xd106f86e69d785c8 , 0x82a45b450226b39d , 0xa34d721642b06084 , 0xcc20ce9bd35c78a5 , 0xff290242c83396ce , 0x9f79a169bd203e41 , 0xc75809c42c684dd1 , 0xf92e0c3537826146 , 0x9bbcc7a142b17ccc , 0xc2abf989935ddbfe , 0xf356f7ebf83552fe , 0x98165af37b2153df , 0xbe1bf1b059e9a8d6 , 0xeda2ee1c7064130c , 0x9485d4d1c63e8be8 , 0xb9a74a0637ce2ee1 , 0xe8111c87c5c1ba9a , 0x910ab1d4db9914a0 , 0xb54d5e4a127f59c8 , 0xe2a0b5dc971f303a , 0x8da471a9de737e24 , 0xb10d8e1456105dad , 0xdd50f1996b947519 , 0x8a5296ffe33cc930 , 0xace73cbfdc0bfb7b , 0xd8210befd30efa5a , 0x8714a775e3e95c78 , 0xa8d9d1535ce3b396 , 0xd31045a8341ca07c , 0x83ea2b892091e44e , 0xa4e4b66b68b65d61 , 0xce1de40642e3f4b9 , 0x80d2ae83e9ce78f4 , 0xa1075a24e4421731 , 0xc94930ae1d529cfd , 0xfb9b7cd9a4a7443c , 0x9d412e0806e88aa6 , 0xc491798a08a2ad4f , 0xf5b5d7ec8acb58a3 , 0x9991a6f3d6bf1766 , 0xbff610b0cc6edd3f , 0xeff394dcff8a948f , 0x95f83d0a1fb69cd9 , 0xbb764c4ca7a44410 , 0xea53df5fd18d5514 , 0x92746b9be2f8552c , 0xb7118682dbb66a77 , 0xe4d5e82392a40515 , 0x8f05b1163ba6832d , 0xb2c71d5bca9023f8 , 0xdf78e4b2bd342cf7 , 0x8bab8eefb6409c1a , 0xae9672aba3d0c321 , 0xda3c0f568cc4f3e9 , 0x8865899617fb1871 , 0xaa7eebfb9df9de8e , 0xd51ea6fa85785631 , 0x8533285c936b35df , 0xa67ff273b8460357 , 0xd01fef10a657842c , 0x8213f56a67f6b29c , 0xa298f2c501f45f43 , 0xcb3f2f7642717713 , 0xfe0efb53d30dd4d8 , 0x9ec95d1463e8a507 , 0xc67bb4597ce2ce49 , 0xf81aa16fdc1b81db , 0x9b10a4e5e9913129 , 0xc1d4ce1f63f57d73 , 0xf24a01a73cf2dcd0 , 0x976e41088617ca02 , 0xbd49d14aa79dbc82 , 0xec9c459d51852ba3 , 0x93e1ab8252f33b46 , 0xb8da1662e7b00a17 , 0xe7109bfba19c0c9d , 0x906a617d450187e2 , 0xb484f9dc9641e9db , 0xe1a63853bbd26451 , 0x8d07e33455637eb3 , 0xb049dc016abc5e60 , 0xdc5c5301c56b75f7 , 0x89b9b3e11b6329bb , 0xac2820d9623bf429 , 0xd732290fbacaf134 , 0x867f59a9d4bed6c0 , 0xa81f301449ee8c70 , 0xd226fc195c6a2f8c , 0x83585d8fd9c25db8 , 0xa42e74f3d032f526 , 0xcd3a1230c43fb26f , 0x80444b5e7aa7cf85 , 0xa0555e361951c367 , 0xc86ab5c39fa63441 , 0xfa856334878fc151 , 0x9c935e00d4b9d8d2 , 0xc3b8358109e84f07 , 0xf4a642e14c6262c9 , 0x98e7e9cccfbd7dbe , 0xbf21e44003acdd2d , 0xeeea5d5004981478 , 0x95527a5202df0ccb , 0xbaa718e68396cffe , 0xe950df20247c83fd , 0x91d28b7416cdd27e , 0xb6472e511c81471e , 0xe3d8f9e563a198e5 , 0x8e679c2f5e44ff8f , 0xb201833b35d63f73 , 0xde81e40a034bcf50 , 0x8b112e86420f6192 , 0xadd57a27d29339f6 , 0xd94ad8b1c7380874 , 0x87cec76f1c830549 , 0xa9c2794ae3a3c69b , 0xd433179d9c8cb841 , 0x849feec281d7f329 , 0xa5c7ea73224deff3 , 0xcf39e50feae16bf0 , 0x81842f29f2cce376 , 0xa1e53af46f801c53 , 0xca5e89b18b602368 , 0xfcf62c1dee382c42 , 0x9e19db92b4e31ba9 , 0xc5a05277621be294 , 0xf70867153aa2db39 , 0x9a65406d44a5c903 , 0xc0fe908895cf3b44 , 0xf13e34aabb430a15 , 0x96c6e0eab509e64d , 0xbc789925624c5fe1 , 0xeb96bf6ebadf77d9 , 0x933e37a534cbaae8 , 0xb80dc58e81fe95a1 , 0xe61136f2227e3b0a , 0x8fcac257558ee4e6 , 0xb3bd72ed2af29e20 , 0xe0accfa875af45a8 , 0x8c6c01c9498d8b89 , 0xaf87023b9bf0ee6b , 0xdb68c2ca82ed2a06 , 0x892179be91d43a44 , 0xab69d82e364948d4 }; -static const int powers_ten_e[] = {-1203 , -1200 , -1196 , -1193 , -1190 , -1186 , -1183 , -1180 , -1176 , -1173 , -1170 , -1166 , -1163 , -1160 , -1156 , -1153 , -1150 , -1146 , -1143 , -1140 , -1136 , -1133 , -1130 , -1127 , -1123 , -1120 , -1117 , -1113 , -1110 , -1107 , -1103 , -1100 , -1097 , -1093 , -1090 , -1087 , -1083 , -1080 , -1077 , -1073 , -1070 , -1067 , -1063 , -1060 , -1057 , -1053 , -1050 , -1047 , -1043 , -1040 , -1037 , -1034 , -1030 , -1027 , -1024 , -1020 , -1017 , -1014 , -1010 , -1007 , -1004 , -1000 , -997 , -994 , -990 , -987 , -984 , -980 , -977 , -974 , -970 , -967 , -964 , -960 , -957 , -954 , -950 , -947 , -944 , -940 , -937 , -934 , -931 , -927 , -924 , -921 , -917 , -914 , -911 , -907 , -904 , -901 , -897 , -894 , -891 , -887 , -884 , -881 , -877 , -874 , -871 , -867 , -864 , -861 , -857 , -854 , -851 , -847 , -844 , -841 , -838 , -834 , -831 , -828 , -824 , -821 , -818 , -814 , -811 , -808 , -804 , -801 , -798 , -794 , -791 , -788 , -784 , -781 , -778 , -774 , -771 , -768 , -764 , -761 , -758 , -754 , -751 , -748 , -744 , -741 , -738 , -735 , -731 , -728 , -725 , -721 , -718 , -715 , -711 , -708 , -705 , -701 , -698 , -695 , -691 , -688 , -685 , -681 , -678 , -675 , -671 , -668 , -665 , -661 , -658 , -655 , -651 , -648 , -645 , -642 , -638 , -635 , -632 , -628 , -625 , -622 , -618 , -615 , -612 , -608 , -605 , -602 , -598 , -595 , -592 , -588 , -585 , -582 , -578 , -575 , -572 , -568 , -565 , -562 , -558 , -555 , -552 , -549 , -545 , -542 , -539 , -535 , -532 , -529 , -525 , -522 , -519 , -515 , -512 , -509 , -505 , -502 , -499 , -495 , -492 , -489 , -485 , -482 , -479 , -475 , -472 , -469 , -465 , -462 , -459 , -455 , -452 , -449 , -446 , -442 , -439 , -436 , -432 , -429 , -426 , -422 , -419 , -416 , -412 , -409 , -406 , -402 , -399 , -396 , -392 , -389 , -386 , -382 , -379 , -376 , -372 , -369 , -366 , -362 , -359 , -356 , -353 , -349 , -346 , -343 , -339 , -336 , -333 , -329 , -326 , -323 , -319 , -316 , -313 , -309 , -306 , -303 , -299 , -296 , -293 , -289 , -286 , -283 , -279 , -276 , -273 , -269 , -266 , -263 , -259 , -256 , -253 , -250 , -246 , -243 , -240 , -236 , -233 , -230 , -226 , -223 , -220 , -216 , -213 , -210 , -206 , -203 , -200 , -196 , -193 , -190 , -186 , -183 , -180 , -176 , -173 , -170 , -166 , -163 , -160 , -157 , -153 , -150 , -147 , -143 , -140 , -137 , -133 , -130 , -127 , -123 , -120 , -117 , -113 , -110 , -107 , -103 , -100 , -97 , -93 , -90 , -87 , -83 , -80 , -77 , -73 , -70 , -67 , -63 , -60 , -57 , -54 , -50 , -47 , -44 , -40 , -37 , -34 , -30 , -27 , -24 , -20 , -17 , -14 , -10 , -7 , -4 , 0 , 3 , 6 , 10 , 13 , 16 , 20 , 23 , 26 , 30 , 33 , 36 , 39 , 43 , 46 , 49 , 53 , 56 , 59 , 63 , 66 , 69 , 73 , 76 , 79 , 83 , 86 , 89 , 93 , 96 , 99 , 103 , 106 , 109 , 113 , 116 , 119 , 123 , 126 , 129 , 132 , 136 , 139 , 142 , 146 , 149 , 152 , 156 , 159 , 162 , 166 , 169 , 172 , 176 , 179 , 182 , 186 , 189 , 192 , 196 , 199 , 202 , 206 , 209 , 212 , 216 , 219 , 222 , 226 , 229 , 232 , 235 , 239 , 242 , 245 , 249 , 252 , 255 , 259 , 262 , 265 , 269 , 272 , 275 , 279 , 282 , 285 , 289 , 292 , 295 , 299 , 302 , 305 , 309 , 312 , 315 , 319 , 322 , 325 , 328 , 332 , 335 , 338 , 342 , 345 , 348 , 352 , 355 , 358 , 362 , 365 , 368 , 372 , 375 , 378 , 382 , 385 , 388 , 392 , 395 , 398 , 402 , 405 , 408 , 412 , 415 , 418 , 422 , 425 , 428 , 431 , 435 , 438 , 441 , 445 , 448 , 451 , 455 , 458 , 461 , 465 , 468 , 471 , 475 , 478 , 481 , 485 , 488 , 491 , 495 , 498 , 501 , 505 , 508 , 511 , 515 , 518 , 521 , 524 , 528 , 531 , 534 , 538 , 541 , 544 , 548 , 551 , 554 , 558 , 561 , 564 , 568 , 571 , 574 , 578 , 581 , 584 , 588 , 591 , 594 , 598 , 601 , 604 , 608 , 611 , 614 , 617 , 621 , 624 , 627 , 631 , 634 , 637 , 641 , 644 , 647 , 651 , 654 , 657 , 661 , 664 , 667 , 671 , 674 , 677 , 681 , 684 , 687 , 691 , 694 , 697 , 701 , 704 , 707 , 711 , 714 , 717 , 720 , 724 , 727 , 730 , 734 , 737 , 740 , 744 , 747 , 750 , 754 , 757 , 760 , 764 , 767 , 770 , 774 , 777 , 780 , 784 , 787 , 790 , 794 , 797 , 800 , 804 , 807 , 810 , 813 , 817 , 820 , 823 , 827 , 830 , 833 , 837 , 840 , 843 , 847 , 850 , 853 , 857 , 860 , 863 , 867 , 870 , 873 , 877 , 880 , 883 , 887 , 890 , 893 , 897 , 900 , 903 , 907 , 910 , 913 , 916 , 920 , 923 , 926 , 930 , 933 , 936 , 940 , 943 , 946 , 950 , 953 , 956 , 960 , 963 , 966 , 970 , 973 , 976 , 980 , 983 , 986 , 990 , 993 , 996 , 1000 , 1003 , 1006 , 1009 , 1013 , 1016 , 1019 , 1023 , 1026 , 1029 , 1033 , 1036 , 1039 , 1043 , 1046 , 1049 , 1053 , 1056 , 1059 , 1063 , 1066 , 1069 , 1073 , 1076 }; -static diy_fp_t cached_power(int k) { - diy_fp_t res; - int index = 343 + k; - res.f = powers_ten[index]; - res.e = powers_ten_e[index]; - return res; -} diff --git a/src/kprint/kformat_fp.c b/src/kprint/kformat_fp.c deleted file mode 100644 index 581a652..0000000 --- a/src/kprint/kformat_fp.c +++ /dev/null @@ -1,282 +0,0 @@ -//--- -// gint:kprint:kformat-fp: Floating-point formatted printing -// -// This object file provides floating-point formatters. It can be linked in by -// calling kprint_enable_fp() and will automatically register floating-point -// formatters that use the Grisu2b algorithm. -//--- - -#include -#include -#include - -#include "../3rdparty/grisu2b_59_56/grisu2.h" - -//--- -// String generation for doubles -//--- - -/* The grisu2() function does not have a size limit so we generate into a - buffer large enough to hold the result. */ -static char digit_buffer[50]; - -/* Round a number at the specified place (which can be out of bounds). An extra - byte before the buffer should be secured to leave room for a new digit in - case a carry reaches there. Returns the new start-of-buffer. - - @buffer Buffer with generated digits, updated if needed - @length Number of digits generated in the buffer, updated if needed - @e Location of decimal dot relative to integer in buffer - @place Decimal to place to round to */ -static void round_str(char **buffer_ptr, int *length, int e, int place) -{ - char *buffer = *buffer_ptr; - - /* Interpret place as relative to buffer indices */ - place += *length + e - 1; - - /* Specified place is out-of-bounds */ - if(place < 0 || place >= *length - 1) return; - /* Next digit is 0..4 so rounding has no effect */ - if(buffer[place + 1] < '5') return; - - /* Propagate carries if needed */ - while(place >= -1) - { - buffer[place]++; - if(buffer[place] <= '9') break; - - buffer[place] = '0'; - place--; - } - - /* Add one digit if needed */ - if(place >= 0) return; - (*buffer_ptr)--; - (*length)++; -} - -/* Remove zeros at the end of the digits, reducing [length] accordingly. */ -static int remove_zeros(char *buffer, int length, int unremovable) -{ - int removed = 0; - - while(length > unremovable && buffer[length - 1] == '0') - { - buffer[length - 1] = 0; - length--; - removed++; - } - - return removed; -} - -/* Handles infinities and NaNs. */ -static int special_notation(double v, int upper) -{ - if(__builtin_isinf(v) && v < 0) - { - kprint_outstr(upper ? "-INF" : "-inf", 4); - return 1; - } - if(__builtin_isinf(v)) - { - kprint_outstr(upper ? "INF" : "inf", 3); - return 1; - } - if(__builtin_isnan(v)) - { - kprint_outstr(upper ? "NAN" : "nan", 3); - return 1; - } - return 0; -} - -/* Prints decimal explicitly for %f and %g. */ -static void direct_notation(kprint_options_t *opt, kprint_geometry_t g, - char *digits, int length, int e) -{ - /* Number of characters for decimal part, including dot */ - int dec_chars = opt->precision + (opt->precision > 0); - - /* See case discussion below */ - g.content = (length + e >= 0) ? length + e + dec_chars : 1 + dec_chars; - kformat_geometry(opt, &g); - - kprint_outn(' ', g.left_spaces); - if(g.sign) kprint_out(g.sign); - kprint_outn('0', g.zeros); - - int pre = opt->precision; - - if(e >= 0) /* xxxxxx00[.00] */ - { - /* Decimal dot is after digits; rounding never occurs */ - kprint_outstr(digits, length); - kprint_outn('0', e); - - if(pre > 0) - { - kprint_out('.'); - kprint_outn('0', pre); - } - } - else if(length + e > 0) /* xxxy(.xx), xx.xy(xx), xx.xxxx[00] */ - { - /* Decimal dot is within the digits; we might have rounded */ - kprint_outstr(digits, length + e); - - if(pre > 0) - { - kprint_out('.'); - kprint_outstr(digits + length + e, min(-e, pre)); - kprint_outn('0', pre + e); - } - } - else if(length + e <= 0) /* 0.00(00xxxx), 0.00xy(xx), 0.00xxxx00 */ - { - /* Decimal dot is before the digits; we might have rounded */ - kprint_out('0'); - if(pre > 0) - { - kprint_out('.'); - kprint_outn('0', min(-e - length, pre)); - kprint_outstr(digits, min(length, pre + length + e)); - kprint_outn('0', pre + e); - } - } - - kprint_outn(' ', g.right_spaces); -} - -/* Prints exponent notation for %e and %g. */ -static void exponent_notation(kprint_options_t *opt, kprint_geometry_t g, - char *digits, int length, int e, int uppercase) -{ - int true_e = e + length - 1; - - /* Number of characters for decimal part and for exponent */ - int dec_chars = opt->precision + (opt->precision > 0); - int exp_chars = 4 + (true_e >= 100 || true_e <= -100); - - g.content = 1 + dec_chars + exp_chars; - kformat_geometry(opt, &g); - - kprint_outn(' ', g.left_spaces); - if(g.sign) kprint_out(g.sign); - kprint_outn('0', g.zeros); - - /* Digits */ - kprint_out(digits[0]); - if(opt->precision > 0) - { - kprint_out('.'); - kprint_outstr(digits + 1, min(length - 1, opt->precision)); - kprint_outn('0', opt->precision - (length - 1)); - } - - /* Exponent */ - kprint_out(uppercase ? 'E' : 'e'); - kprint_out(true_e >= 0 ? '+' : '-'); - - if(true_e < 0) true_e = -true_e; - if(true_e >= 100) - { - kprint_out(true_e / 100 + '0'); - true_e %= 100; - } - kprint_out(true_e / 10 + '0'); - kprint_out(true_e % 10 + '0'); - - kprint_outn(' ', g.right_spaces); -} - -//--- -// Formatters for kprint -//--- - -static void kformat_fp(KFORMAT_ARGS) -{ - double v = va_arg(*args, double); - digit_buffer[0] = '0'; - char *digits = digit_buffer + 1; - int length = 0, e = 0; - - int is_e = (spec | 0x20) == 'e'; - int is_f = (spec | 0x20) == 'f'; - int is_g = (spec | 0x20) == 'g'; - - /* In %e and %f, default to 6 decimals. In %g, default to 6 significant - digits, and force to at least 1 */ - if(opt->precision < 0) opt->precision = 6; - if(opt->precision == 0 && is_g) opt->precision = 1; - - if(special_notation(v, (spec & 0x20) == 0)) return; - - /* fabs(v) = int(digits) * 10^e */ - if(v == 0.0) digits[length++] = '0'; - else grisu2(v, digits, &length, &e); - digits[length] = 0; - - /* In %f and %e, .precision is the number of decimal places; in %g, it - is the number of significant digits. Determine the number of decimal - places for the rounding (which is one more than the final number if - a carry creates a new significant digit on the left) */ - int round_place = opt->precision; - if(is_e) round_place -= (length + e - 1); - if(is_g) round_place -= (length + e); - - /* Round off to the specified number of decimal places. digits and - length may extend one place left because of carries */ - round_str(&digits, &length, e, round_place); - - kprint_geometry_t g = { - .sign = (v < 0) ? '-' : '+', - .prefix = 0, - .style = KPRINT_NUMERIC, - }; - - if(is_f) return direct_notation(opt, g, digits, length, e); - if(is_e) return exponent_notation(opt, g, digits, length, e,spec=='E'); - - int true_e = length + e - 1; - int extreme = (true_e < -4) || (true_e >= opt->precision); - - /* %g is left. Remove decimal zeros at the end of the digit string, - starting from the last-shown digit. Keep all figits before the - point, the amount of which depends on the mode */ - int removed = remove_zeros(digits, min(length, opt->precision), - extreme ? 1 : true_e + 1); - opt->precision -= removed; - - if(extreme) - { - /* Don't print more significant digits than we have digits - (elimination of trailing zeros) */ - opt->precision = min(opt->precision, length); - /* There is one leading digit and this many decimal places */ - opt->precision--; - - return exponent_notation(opt, g, digits, length, e, spec=='G'); - } - else - { - /* Number of digits before the point */ - int leading_digits = true_e + 1; - - /* Eliminate trailing zeros after the point */ - opt->precision = min(opt->precision, length); - /* Remove leading digits from decimal place count */ - opt->precision -= leading_digits; - - return direct_notation(opt, g, digits, length, e); - } -} - -/* kprint_enable_fp(): Enable and load floating-point formats */ -void kprint_enable_fp(void) -{ - kprint_register('e', kformat_fp); - kprint_register('f', kformat_fp); - kprint_register('g', kformat_fp); -} diff --git a/src/kprint/kprint.c b/src/kprint/kprint.c deleted file mode 100644 index 13cabd7..0000000 --- a/src/kprint/kprint.c +++ /dev/null @@ -1,539 +0,0 @@ -//--- -// gint:kprint - gint's printf(3)-like formatted printer -// -// Things to change when creating new formats: -// -> List of prototypes at the end of the definition section -// -> Formatted table just below the list of prototypes -// -> List of non-numerical specifiers in kformat_geometry() -//--- - -#include -#include -#include - -#include -#include -#include - -#include - -//--- -// kprint() definitions -//--- - -#define KPRINT_BUFSIZE 64 - -/* Current position in the output buffer */ -static char *kprint_ptr = NULL; -/* Limit of the output buffer */ -static char *kprint_limit = NULL; - -/* Total number of characters written for this call to kprint() */ -static size_t kprint_count = 0; -/* Address of the current output buffer */ -static char *kprint_buffer = NULL; -/* Internal buffer, used in many cases */ -static char kprint_internal[KPRINT_BUFSIZE]; - -/* Output kind for this execution of kprint() */ -static enum { - /* Output is user-provided string, then internal buffer for the rest */ - KPrintOutputString = 0, - /* Output is a device, file descriptor, whatever */ -// KprintOutputDevice = 1, -} kprint_type; - -/* Default formatters */ -static void kformat_char (KFORMAT_ARGS); -static void kformat_int (KFORMAT_ARGS); -static void kformat_uint (KFORMAT_ARGS); -static void kformat_ptr (KFORMAT_ARGS); -static void kformat_str (KFORMAT_ARGS); -static void kformat_fixed(KFORMAT_ARGS); - -/* Formatter functions for a..z */ -kprint_formatter_t kprint_formatters[26] = { - /* Standard formats plus the 'j' for fixed-point integers in base 10 */ - NULL, NULL, kformat_char, kformat_int, - NULL, NULL, NULL, NULL, - kformat_int, kformat_fixed, NULL, NULL, - NULL, NULL, kformat_uint, kformat_ptr, - NULL, NULL, kformat_str, NULL, - kformat_uint, NULL, NULL, kformat_uint, - NULL, NULL, -}; - -/* kprint_register(): Register a formatter */ -void kprint_register(int spec, kprint_formatter_t kformat) -{ - /* Non-letters */ - if(spec < 'a' || spec > 'z') return; - /* Size-specifying letters */ - if(spec == 'h' || spec == 'l' || spec == 'L' || spec == 'z') return; - - kprint_formatters[spec - 'a'] = kformat; -} - -//--- -// Output functions -//--- - -/* kprint_flush(): Flush the buffer when it's full */ -static void kprint_flush(void) -{ - /* Update the number of flushed characters */ - kprint_count += kprint_ptr - kprint_buffer; - - if(kprint_type != KPrintOutputString) return; - - /* Make sure to write a NUL at the end of the string, even if - it means overriding one of the generated characters */ - if(kprint_buffer != kprint_internal) - { - char *nul = min(kprint_ptr, kprint_limit - 1); - *nul = 0x00; - } - - /* Switch to the internal buffer now that the output string has - been filled */ - kprint_buffer = kprint_internal; - kprint_limit = kprint_internal + KPRINT_BUFSIZE; - kprint_ptr = kprint_buffer; -} - -/* kprint_out(): Output a single character to the kprint buffer */ -GINLINE void kprint_out(int byte) -{ - if(kprint_ptr >= kprint_limit) kprint_flush(); - *kprint_ptr++ = byte; -} - -/* kprint_outn(): Output the same character times */ -GINLINE void kprint_outn(int byte, int n) -{ - while(n-- > 0) kprint_out(byte); -} - -/* kprint_outstr(): Output a string to the kprint buffer */ -GINLINE void kprint_outstr(char const *str, int n) -{ - for(int i = 0; i < n; i++) kprint_out(str[i]); -} - -//--- -// Parsing helpers -//--- - -/* kprint_opt(): Parse option strings */ -kprint_options_t kprint_opt(char const **options_ptr) -{ - /* No options enabled by default, set the size to int */ - kprint_options_t opt = { .size = 2, .precision = -1 }; - - /* This function acts as a deterministic finite automaton */ - enum { - basic, /* Reading option characters */ - length, /* Reading length digits */ - precision, /* Reading precision digits */ - } state = basic; - - char const *options = *options_ptr; - - for(int c; (c = *options); options++) - { - int c_low = c | 0x20; - if(c_low >= 'a' && c_low <= 'z' && c != 'h' && c != 'l' && - c != 'L') break; - - if(c == '.') - { - state = precision; - opt.precision = 0; - continue; - } - else if(state == length && c >= '0' && c <= '9') - { - opt.length = opt.length * 10 + (c - '0'); - continue; - } - else if(state == precision && c >= '0' && c <= '9') - { - opt.precision = opt.precision * 10 + (c - '0'); - continue; - } - - /* Remain in basic state mode */ - state = basic; - - if(c == '#') opt.alternative = 1; - if(c == ' ') opt.blank_sign = 1; - if(c == '+') opt.force_sign = 1; - - /* Alignment options, including priority */ - if((c == '-' || c == '0') && opt.alignment != '0') - { - opt.alignment = c; - } - - /* Data size */ - if(c == 'h') opt.size--; - if(c == 'l') opt.size++; - if(c == 'z') opt.size = 3; - if(c == 'L') {} - - if(c >= '1' && c <= '9') state = length, options--; - } - - *options_ptr = options; - return opt; -} - -//--- -// Base formatted printer -//--- - -/* kprint(): The kernel's formatted printer */ -void kprint(char const *format, va_list *args) -{ - int c, spec; - kprint_options_t opt; - - while((c = *format++)) - { - if(c != '%') - { - kprint_out(c); - continue; - } - - if(!(c = *format)) break; - - /* '%' character */ - if(c == '%') - { - kprint_out('%'); - format++; - continue; - } - - opt = kprint_opt(&format); - spec = *format++; - - int id = (spec | 0x20) - 'a'; - if(id >= 0 && id < 26 && kprint_formatters[id]) - kprint_formatters[id](spec, &opt, args); - } - - kprint_flush(); -} - -/* kvsprint(): Formatted print to string */ -size_t kvsprint(char *output, size_t length, char const *format, va_list *args) -{ - kprint_buffer = output; - kprint_limit = output + length; - - kprint_count = 0; - kprint_ptr = kprint_buffer; - kprint_type = KPrintOutputString; - - kprint(format, args); - return kprint_count; -} - -//--- -// Formatter helpers -//--- - -/* kformat_geometry(): Calculate the geometry of a format */ -void kformat_geometry(kprint_options_t *opt, kprint_geometry_t *g) -{ - int integral = (g->style == KPRINT_INTEGER); - int numerical = (g->style == KPRINT_NUMERIC) || integral; - ssize_t padding; - - /* Sign character (no discussion required for negative values) */ - if(numerical && g->sign == '+') - { - g->sign = 0; - if(opt->blank_sign) g->sign = ' '; - if(opt->force_sign) g->sign = '+'; - } - - g->zeros = 0; - - padding = opt->length - (g->sign != 0) - g->prefix - - max(g->content, opt->precision); - if(padding < 0) padding = 0; - - /* In integral modes, precision forces zeros */ - if(integral && opt->precision >= 0) - { - if(opt->alignment == '0') opt->alignment = 0; - - ssize_t zeros = opt->precision - g->content; - if(zeros > 0) g->zeros = zeros; - } - - if(opt->alignment == '0') - { - /* Zeros are only allowed in numerical modes */ - if(numerical) g->zeros = padding; - else g->left_spaces = padding; - } - else if(opt->alignment == '-') - { - g->right_spaces = padding; - } - else - { - g->left_spaces = padding; - } -} - -/* digits_10(): Generate digits in base 10 - Fills up the provided digit string from least significant to most - significant digit, not adding zeros except if argument is zero. Returns the - number of digits. No NUL terminator is added. */ -static int digits_10(char *str, uint64_t n) -{ - int digits = 0; - while(n || !digits) - { - /* TODO: Use qdiv() in kprint's digits_10() */ - str[digits++] = (n % 10) + '0'; - n /= 10; - } - return digits; -} - -/* digits_16(): Generate digits in base 16 */ -static int digits_16(char *str, int uppercase, uint64_t n) -{ - char *hex = uppercase ? "0123456789ABCDEF" : "0123456789abcdef"; - int digits = 0; - - while(n || !digits) - { - str[digits++] = hex[n & 0xf]; - n >>= 4; - } - return digits; -} - -/* digits_8(): Generate digits in base 8 */ -static int digits_8(char *str, uint64_t n) -{ - int digits = 0; - - while(n || !digits) - { - str[digits++] = (n & 0x7) + '0'; - n >>= 3; - } - return digits; -} - -//--- -// Loading helpers -//--- - -static int64_t load_i(int size, va_list *args) -{ - /* All smaller types are promoted to int with sign extension, so we - don't need to care about them. */ - if(size == 3) return va_arg(*args, long); - if(size == 4) return va_arg(*args, long long); - return va_arg(*args, int); -} - -static uint64_t load_u(int size, va_list *args) -{ - /* Again, no need to care about small types */ - if(size == 3) return va_arg(*args, unsigned long); - if(size == 4) return va_arg(*args, unsigned long long); - return va_arg(*args, unsigned int); -} - -//--- -// Individual formatters -//--- - -/* kformat_char(): Character formatter (%c) - (-) Move spaces to the right - {len} Specifies numbers of (whitespace-padded) characters to print */ -static void kformat_char(KFORMAT_ARGS) -{ - int c = va_arg(*args, int); - - kprint_geometry_t g = { - .prefix = 0, .sign = 0, .content = 1, - }; - kformat_geometry(opt, &g); - - kprint_outn(' ', g.left_spaces); - kprint_out(c); - kprint_outn(' ', g.right_spaces); -} - -/* kformat_str(): String formatter (%s) - (-) Move spaces to the right - {len} Minimal numbers of characters to output - {pre} Maximal numbers of bytes to read from argument */ -static void kformat_str(KFORMAT_ARGS) -{ - char const *s = va_arg(*args, char const *); - - /* Compute content length, which is the smallest of two sizes: the - length set as precision and the actual length of the string */ - size_t len = 0; - uint32_t precision = opt->precision ? opt->precision : (-1); - while(s[len] && len < precision) len++; - - kprint_geometry_t g = { - .prefix = 0, .sign = 0, .content = len, - }; - kformat_geometry(opt, &g); - - kprint_outn(' ', g.left_spaces); - for(size_t i = 0; i < len; i++) kprint_out(s[i]); - kprint_outn(' ', g.right_spaces); -} - -/* kformat_int(): Integer formatter (%d, %i) - (0) Pad with zeros, rather than spaces, on the left - (-) Move spaces to the right (overrides '0', extends {pre}) - ( ) Force a blank sign before nonnegative numbers - (+) Force a sign before every number (overrides ' ') - {len} Minimal number of characters to print - {pre} Forces a minimal number of digits, creating 0s (overrides '0') */ -static void kformat_int(KFORMAT_ARGS) -{ - int64_t n = load_i(opt->size, args); - - /* Compute the sign and the absolute value */ - kprint_geometry_t g = { - .sign = (n < 0) ? '-' : '+', - .prefix = 0, - .style = KPRINT_INTEGER, - }; - if(n < 0) n = -n; - - /* Get the digit string */ - char digits[32]; - int pure, total; - - pure = digits_10(digits, n); - if(opt->precision == 0 && !n) pure = 0; - total = max(pure, opt->precision); - g.content = total; - - kformat_geometry(opt, &g); - - /* Print the result */ - kprint_outn(' ', g.left_spaces); - if(g.sign) kprint_out(g.sign); - kprint_outn('0', g.zeros); - - kprint_outn('0', total - pure); - for(int i = pure - 1; i >= 0; i--) kprint_out(digits[i]); - - kprint_outn(' ', g.right_spaces); -} - -/* kformat_uint(): Unsigned integer formatter in various bases (%u, %o, %x) - (#) Enable base prefixes ("0" in octal, "0x" in hexadecimal) - (0) Pad with zeros, rather than spaces, on the left - (-) Move spaces to the right (overrides '0', extends {pre}) - {len} Minimal number of characters to print - {pre} Forces a minimal number of digits, creating 0s (overrides '0') */ -static void kformat_uint(KFORMAT_ARGS) -{ - uint64_t n = load_u(opt->size, args); - - char digits[48]; - int pure = 0, total; - int specl = spec | 0x20; - - if(specl == 'u') pure = digits_10(digits, n); - if(specl == 'o') pure = digits_8(digits, n); - if(specl == 'x') pure = digits_16(digits, spec == 'X', n); - - if(opt->precision == 0 && !n) pure = 0; - total = max(pure, opt->precision); - - /* Prefix length */ - size_t prefix = 0; - if(opt->alternative) prefix = (specl != 'u') + (specl == 'x'); - - kprint_geometry_t g = { - .sign = 0, .prefix = prefix, .content = total, - .style = KPRINT_INTEGER, - }; - kformat_geometry(opt, &g); - - /* Output */ - kprint_outn(' ', g.left_spaces); - if(opt->alternative) - { - if(specl != 'u') kprint_out('0'); - if(specl == 'x') kprint_out(spec); - } - kprint_outn('0', g.zeros); - - kprint_outn('0', total - pure); - for(int i = pure - 1; i >= 0; i--) kprint_out(digits[i]); - kprint_outn(' ', g.right_spaces); -} - -/* kformat_ptr(): Pointer formatter */ -static void kformat_ptr(KFORMAT_ARGS) -{ - void *p = va_arg(*args, void *); - - char digits[] = "00000000"; - digits_16(digits, 0, (uint32_t)p); - - kprint_out('0'); - kprint_out('x'); - for(int i = 7; i >= 0; i--) kprint_out(digits[i]); -} - -/* kformat_fixed(): Fixed-point decimal formatter - (0) Pad with zeros, rather than spaces, on the left - (-) Move spaces to the right (overrides '0') - ( ) Force a blank sign before nonnegative numbers - (+) Force a sign before every number (overrides ' ') - {len} Minimal number of characters to print - {pre} Number of digits after the decimal dot */ -static void kformat_fixed(KFORMAT_ARGS) -{ - int64_t n = load_i(opt->size, args); - - /* Compute the sign and the absolute value */ - kprint_geometry_t g = { - .sign = (n < 0) ? '-' : '+', - .prefix = 0, - .style = KPRINT_NUMERIC, - }; - if(n < 0) n = -n; - - /* Get the digit string */ - char digits[32]; - - g.content = digits_10(digits, n) + 1; - kformat_geometry(opt, &g); - - /* Print the result */ - kprint_outn(' ', g.left_spaces); - if(g.sign) kprint_out(g.sign); - kprint_outn('0', g.zeros); - - for(int i = g.content - 2; i >= 0; i--) - { - if(i == opt->precision - 1) kprint_out('.'); - kprint_out(digits[i]); - } - - kprint_outn(' ', g.right_spaces); -} diff --git a/src/std/aprint.c b/src/std/aprint.c index 9808122..100cf3b 100644 --- a/src/std/aprint.c +++ b/src/std/aprint.c @@ -2,22 +2,9 @@ // gint:src:aprint - Allocating extensions to formatted printing //--- -#include +#include #include -#include -#include - -/* asprintf() */ -GWEAK int asprintf(char **strp, char const *format, ...) -{ - va_list args; - va_start(args, format); - - int count = vasprintf(strp, format, args); - - va_end(args); - return count; -} +#include /* vasprintf() */ GWEAK int vasprintf(char **strp, char const *format, va_list args1) @@ -36,3 +23,16 @@ GWEAK int vasprintf(char **strp, char const *format, va_list args1) *strp = str; return count; } + +/* asprintf() */ +GWEAK int asprintf(char **strp, char const *format, ...) +{ + va_list args; + va_start(args, format); + + int count = vasprintf(strp, format, args); + + va_end(args); + return count; +} + diff --git a/src/std/print.c b/src/std/print.c deleted file mode 100644 index ff5ec75..0000000 --- a/src/std/print.c +++ /dev/null @@ -1,43 +0,0 @@ -//--- -// gint:src:print - Standard formatted printing functions -//--- - -#include -#include -#include - -/* sprintf() */ -GWEAK int sprintf(char *str, char const *format, ...) -{ - va_list args; - va_start(args, format); - - int count = kvsprint(str, 65536, format, &args); - - va_end(args); - return count; -} - -/* vsprintf() */ -GWEAK int vsprintf(char *str, char const *format, va_list args) -{ - return kvsprint(str, 65536, format, &args); -} - -/* snprintf() */ -GWEAK int snprintf(char *str, size_t n, char const *format, ...) -{ - va_list args; - va_start(args, format); - - int count = kvsprint(str, n, format, &args); - - va_end(args); - return count; -} - -/* vsprintf() */ -GWEAK int vsnprintf(char *str, size_t n, char const *format, va_list args) -{ - return kvsprint(str, n, format, &args); -}