Delete unused third party projects

main
Justine Tunney 2 years ago
parent 113eeabd85
commit 04caf6f9ad
  1. 5
      Makefile
  2. 125
      third_party/bzip2/.clang-format
  3. 33
      third_party/bzip2/bzip2.mk
  4. 569
      third_party/bzip2/µbunzip2.c
  5. 26
      third_party/double-conversion/LICENSE
  6. 1
      third_party/double-conversion/README.cosmo
  7. 621
      third_party/double-conversion/bignum-dtoa.cc
  8. 84
      third_party/double-conversion/bignum-dtoa.h
  9. 775
      third_party/double-conversion/bignum.cc
  10. 153
      third_party/double-conversion/bignum.h
  11. 140
      third_party/double-conversion/diy-fp.h
  12. 54
      third_party/double-conversion/double-conversion.mk
  13. 395
      third_party/double-conversion/ieee.h
  14. 308
      third_party/double-conversion/utils.h
  15. 248
      third_party/editline/ChangeLog.md
  16. 18
      third_party/editline/LICENSE
  17. 362
      third_party/editline/complete.c
  18. 274
      third_party/editline/editline.3
  19. 1557
      third_party/editline/editline.c
  20. 91
      third_party/editline/editline.h
  21. 57
      third_party/editline/editline.mk
  22. 21
      third_party/editline/internal.h
  23. 112
      third_party/editline/sysunix.c
  24. 43
      third_party/lex/COPYING
  25. 8226
      third_party/lex/ChangeLog
  26. 211
      third_party/lex/FlexLexer.h
  27. 532
      third_party/lex/NEWS
  28. 113
      third_party/lex/NOTES
  29. 1233
      third_party/lex/ONEWS
  30. 2759
      third_party/lex/README.txt
  31. 286
      third_party/lex/buf.c
  32. 325
      third_party/lex/ccl.c
  33. 207
      third_party/lex/config.h
  34. 1105
      third_party/lex/dfa.c
  35. 230
      third_party/lex/ecs.c
  36. 452
      third_party/lex/filter.c
  37. 4438
      third_party/lex/flex.1
  38. 3451
      third_party/lex/flex.skl
  39. 1105
      third_party/lex/flexdef.h
  40. 67
      third_party/lex/flexint.h
  41. 2145
      third_party/lex/gen.c
  42. 118
      third_party/lex/lex.mk
  43. 2208
      third_party/lex/lex.ms
  44. 18
      third_party/lex/libmain.c
  45. 31
      third_party/lex/libyywrap.c
  46. 1826
      third_party/lex/main.c
  47. 1017
      third_party/lex/misc.c
  48. 38
      third_party/lex/mkskel.sh
  49. 734
      third_party/lex/nfa.c
  50. 285
      third_party/lex/options.c
  51. 135
      third_party/lex/options.h
  52. 1810
      third_party/lex/parse.c
  53. 45
      third_party/lex/parse.h
  54. 1089
      third_party/lex/parse.y
  55. 181
      third_party/lex/regex.c
  56. 4588
      third_party/lex/scan.c
  57. 1010
      third_party/lex/scan.l
  58. 75
      third_party/lex/scanflags.c
  59. 881
      third_party/lex/scanopt.c
  60. 133
      third_party/lex/scanopt.h
  61. 3740
      third_party/lex/skel.c
  62. 280
      third_party/lex/sym.c
  63. 466
      third_party/lex/tables.c
  64. 86
      third_party/lex/tables.h
  65. 76
      third_party/lex/tables_shared.c
  66. 145
      third_party/lex/tables_shared.h
  67. 885
      third_party/lex/tblcmp.c
  68. 4
      third_party/lex/version.h
  69. 218
      third_party/lex/yylex.c
  70. 25
      third_party/linenoise/LICENSE
  71. 1187
      third_party/linenoise/linenoise.c
  72. 31
      third_party/linenoise/linenoise.h
  73. 57
      third_party/linenoise/linenoise.mk
  74. 8
      third_party/m4/COPYING
  75. 64
      third_party/m4/NOTES
  76. 380
      third_party/m4/README.txt
  77. 38
      third_party/m4/TEST/ack.m4
  78. 43
      third_party/m4/TEST/hanoi.m4
  79. 53
      third_party/m4/TEST/hash.m4
  80. 43
      third_party/m4/TEST/sqroot.m4
  81. 43
      third_party/m4/TEST/string.m4
  82. 241
      third_party/m4/TEST/test.m4
  83. 640
      third_party/m4/TEST/test.m4.golden
  84. 1031
      third_party/m4/eval.c
  85. 37
      third_party/m4/expr.c
  86. 183
      third_party/m4/extern.h
  87. 689
      third_party/m4/gnum4.c
  88. 333
      third_party/m4/look.c
  89. 524
      third_party/m4/m4.1
  90. 69
      third_party/m4/m4.mk
  91. 967
      third_party/m4/m4.ms
  92. 642
      third_party/m4/main.c
  93. 239
      third_party/m4/mdef.h
  94. 466
      third_party/m4/misc.c
  95. 325
      third_party/m4/ohash.c
  96. 75
      third_party/m4/ohash.h
  97. 713
      third_party/m4/parser.c
  98. 13
      third_party/m4/parser.h
  99. 81
      third_party/m4/parser.y
  100. 38
      third_party/m4/pathnames.h
  101. Some files were not shown because too many files have changed in this diff Show More

@ -138,8 +138,6 @@ include libc/dns/dns.mk # │
include libc/crypto/crypto.mk # │
include net/http/http.mk #─┘
include third_party/lemon/lemon.mk
include third_party/linenoise/linenoise.mk
include third_party/editline/editline.mk
include third_party/duktape/duktape.mk
include third_party/regex/regex.mk
include third_party/avir/avir.mk
@ -148,10 +146,7 @@ include third_party/third_party.mk
include libc/testlib/testlib.mk
include tool/viz/lib/vizlib.mk
include examples/examples.mk
include third_party/lex/lex.mk
include third_party/m4/m4.mk
include third_party/lz4cli/lz4cli.mk
include third_party/bzip2/bzip2.mk
include tool/build/lib/buildlib.mk
include third_party/chibicc/chibicc.mk
include third_party/chibicc/test/test.mk

@ -1,125 +0,0 @@
---
Language: Cpp
# BasedOnStyle: WebKit
AccessModifierOffset: -4
AlignAfterOpenBracket: DontAlign
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlines: Right
AlignOperands: false
AlignTrailingComments: false
AllowAllArgumentsOnNextLine: true
AllowAllConstructorInitializersOnNextLine: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: All
AllowShortLambdasOnASingleLine: All
AllowShortIfStatementsOnASingleLine: Never
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: MultiLine
BinPackArguments: true
BinPackParameters: true
BraceWrapping:
AfterCaseLabel: false
AfterClass: false
AfterControlStatement: false
AfterEnum: false
AfterFunction: true
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
AfterExternBlock: false
BeforeCatch: false
BeforeElse: false
IndentBraces: false
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: true
BreakBeforeBinaryOperators: All
BreakBeforeBraces: WebKit
BreakBeforeInheritanceComma: false
BreakInheritanceList: BeforeColon
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: BeforeComma
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true
ColumnLimit: 80
CommentPragmas: '^ IWYU pragma:'
CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: false
DerivePointerAlignment: false
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: false
ForEachMacros:
- foreach
- Q_FOREACH
- BOOST_FOREACH
IncludeBlocks: Preserve
IncludeCategories:
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
Priority: 2
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
Priority: 3
- Regex: '.*'
Priority: 1
IncludeIsMainRegex: '(Test)?$'
IndentCaseLabels: false
IndentPPDirectives: None
IndentWidth: 4
IndentWrappedFunctionNames: false
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: true
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: Inner
ObjCBinPackProtocolList: Auto
ObjCBlockIndentWidth: 4
ObjCSpaceAfterProperty: true
ObjCSpaceBeforeProtocolList: true
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyBreakTemplateDeclaration: 10
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 60
PointerAlignment: Right
ReflowComments: true
SortIncludes: true
SortUsingDeclarations: true
SpaceAfterCStyleCast: false
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: true
SpaceBeforeAssignmentOperators: true
SpaceBeforeCpp11BracedList: true
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Cpp11
StatementMacros:
- Q_UNUSED
- QT_REQUIRE_VERSION
TabWidth: 4
UseTab: Always
...

@ -1,33 +0,0 @@
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
# Description:
# bzip2 is a compression format.
PKGS += THIRD_PARTY_BZIP2
THIRD_PARTY_BZIP2_BINS = \
o/$(MODE)/third_party/bzip2/µbunzip2.com \
o/$(MODE)/third_party/bzip2/µbunzip2.com.dbg
THIRD_PARTY_BZIP2_OBJS = \
o/$(MODE)/third_party/bzip2/µbunzip2.o
THIRD_PARTY_BZIP2_DEPS := $(call uniq, \
$(LIBC_STR) \
$(LIBC_STDIO))
$(THIRD_PARTY_BZIP2_OBJS): \
DEFAULT_CPPFLAGS += \
-DHAVE_CONFIG_H
o/$(MODE)/third_party/bzip2/µbunzip2.com.dbg: \
$(THIRD_PARTY_BZIP2_DEPS) \
$(THIRD_PARTY_BZIP2_OBJS) \
$(CRT) \
$(APE)
@$(APELINK)
$(THIRD_PARTY_BZIP2_OBJS): third_party/bzip2/bzip2.mk
.PHONY: o/$(MODE)/third_party/bzip2
o/$(MODE)/third_party/bzip2: $(THIRD_PARTY_BZIP2_BINS)

@ -1,569 +0,0 @@
/* micro-bunzip, a small, simple bzip2 decompression implementation.
Copyright 2003 by Rob Landley (rob@landley.net).
Based on bzip2 decompression code by Julian R Seward (jseward@acm.org),
which also acknowledges contributions by Mike Burrows, David Wheeler,
Peter Fenwick, Alistair Moffat, Radford Neal, Ian H. Witten,
Robert Sedgewick, and Jon L. Bentley.
I hereby release this code under the GNU Library General Public License
(LGPL) version 2, available at http://www.gnu.org/copyleft/lgpl.html
*/
#include "libc/calls/calls.h"
#include "libc/mem/mem.h"
#include "libc/runtime/runtime.h"
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/fileno.h"
/* Constants for huffman coding */
#define MAX_GROUPS 6
#define GROUP_SIZE 50 /* 64 would have been more efficient */
#define MAX_HUFCODE_BITS 20 /* Longest huffman code allowed */
#define MAX_SYMBOLS 258 /* 256 literals + RUNA + RUNB */
#define SYMBOL_RUNA 0
#define SYMBOL_RUNB 1
/* Status return values */
#define RETVAL_OK 0
#define RETVAL_LAST_BLOCK (-1)
#define RETVAL_NOT_BZIP_DATA (-2)
#define RETVAL_UNEXPECTED_INPUT_EOF (-3)
#define RETVAL_UNEXPECTED_OUTPUT_EOF (-4)
#define RETVAL_DATA_ERROR (-5)
#define RETVAL_OUT_OF_MEMORY (-6)
#define RETVAL_OBSOLETE_INPUT (-7)
/* Other housekeeping constants */
#define IOBUF_SIZE 4096
char *bunzip_errors[] = { NULL, "Bad file checksum", "Not bzip data",
"Unexpected input EOF", "Unexpected output EOF", "Data error",
"Out of memory", "Obsolete (pre 0.9.5) bzip format not supported." };
/* This is what we know about each huffman coding group */
struct group_data {
int limit[MAX_HUFCODE_BITS], base[MAX_HUFCODE_BITS], permute[MAX_SYMBOLS];
char minLen, maxLen;
};
/* Structure holding all the housekeeping data, including IO buffers and
memory that persists between calls to bunzip */
typedef struct {
/* For I/O error handling */
jmp_buf jmpbuf;
/* Input stream, input buffer, input bit buffer */
int64_t in_fd, inbufCount, inbufPos;
unsigned char *inbuf;
unsigned int inbufBitCount, inbufBits;
/* Output buffer */
char outbuf[IOBUF_SIZE];
int outbufPos;
/* The CRC values stored in the block header and calculated from the data */
unsigned int crc32Table[256], headerCRC, dataCRC, totalCRC;
/* Intermediate buffer and its size (in bytes) */
unsigned int *dbuf, dbufSize;
/* State for interrupting output loop */
int writePos, writeRun, writeCount, writeCurrent;
/* These things are a bit too big to go on the stack */
unsigned char selectors[32768]; /* nSelectors=15 bits */
struct group_data groups[MAX_GROUPS]; /* huffman coding tables */
} bunzip_data;
/* Return the next nnn bits of input. All reads from the compressed
input are done through this function. All reads are big endian */
static unsigned int get_bits(bunzip_data *bd, char bits_wanted)
{
unsigned int bits = 0;
/* If we need to get more data from the byte buffer, do so. (Loop
getting one byte at a time to enforce endianness and avoid
unaligned access.) */
while (bd->inbufBitCount < bits_wanted) {
/* If we need to read more data from file into byte buffer, do so */
if (bd->inbufPos == bd->inbufCount) {
if (!(bd->inbufCount = read(bd->in_fd, bd->inbuf, IOBUF_SIZE)))
longjmp(bd->jmpbuf, RETVAL_UNEXPECTED_INPUT_EOF);
bd->inbufPos = 0;
}
/* Avoid 32-bit overflow (dump bit buffer to top of output) */
if (bd->inbufBitCount >= 24) {
bits = bd->inbufBits & ((1u << bd->inbufBitCount) - 1);
bits_wanted -= bd->inbufBitCount;
bits <<= bits_wanted;
bd->inbufBitCount = 0;
}
/* Grab next 8 bits of input from buffer. */
bd->inbufBits = (bd->inbufBits << 8) | bd->inbuf[bd->inbufPos++];
bd->inbufBitCount += 8;
}
/* Calculate result */
bd->inbufBitCount -= bits_wanted;
bits |= (bd->inbufBits >> bd->inbufBitCount) & ((1u << bits_wanted) - 1);
return bits;
}
/* Decompress a block of text to into intermediate buffer */
static int read_bunzip_data(bunzip_data *bd)
{
struct group_data *hufGroup;
int dbufCount, nextSym, dbufSize, origPtr, groupCount, *base, *limit,
selector, i, j, k, t, runPos, symCount, symTotal, nSelectors,
byteCount[256];
unsigned char uc, symToByte[256], mtfSymbol[256], *selectors;
unsigned int *dbuf;
/* Read in header signature (borrowing mtfSymbol for temp space). */
for (i = 0; i < 6; i++)
mtfSymbol[i] = get_bits(bd, 8);
mtfSymbol[6] = 0;
/* Read CRC (which is stored big endian). */
bd->headerCRC = get_bits(bd, 32);
/* Is this the last block (with CRC for file)? */
if (!strcmp((char *)mtfSymbol, "\x17\x72\x45\x38\x50\x90"))
return RETVAL_LAST_BLOCK;
/* If it's not a valid data block, barf. */
if (strcmp((char *)mtfSymbol, "\x31\x41\x59\x26\x53\x59"))
return RETVAL_NOT_BZIP_DATA;
dbuf = bd->dbuf;
dbufSize = bd->dbufSize;
selectors = bd->selectors;
/* We can add support for blockRandomised if anybody complains.
There was some code for this in busybox 1.0.0-pre3, but nobody
ever noticed that it didn't actually work. */
if (get_bits(bd, 1))
return RETVAL_OBSOLETE_INPUT;
if ((origPtr = get_bits(bd, 24)) > dbufSize)
return RETVAL_DATA_ERROR;
/* mapping table: if some byte values are never used (encoding
things like ascii text), the compression code removes the gaps to
have fewer symbols to deal with, and writes a sparse bitfield
indicating which values were present. We make a translation table
to convert the symbols back to the corresponding bytes. */
t = get_bits(bd, 16);
memset(symToByte, 0, 256);
symTotal = 0;
for (i = 0; i < 16; i++) {
if (t & (1u << (15 - i))) {
k = get_bits(bd, 16);
for (j = 0; j < 16; j++)
if (k & (1u << (15 - j)))
symToByte[symTotal++] = (16 * i) + j;
}
}
/* How many different huffman coding groups does this block use? */
groupCount = get_bits(bd, 3);
if (groupCount < 2 || groupCount > MAX_GROUPS)
return RETVAL_DATA_ERROR;
/* nSelectors: Every GROUP_SIZE many symbols we select a new huffman
coding group. Read in the group selector list, which is stored as
MTF encoded bit runs. */
if (!(nSelectors = get_bits(bd, 15)))
return RETVAL_DATA_ERROR;
for (i = 0; i < groupCount; i++)
mtfSymbol[i] = i;
for (i = 0; i < nSelectors; i++) {
/* Get next value */
for (j = 0; get_bits(bd, 1); j++)
if (j >= groupCount)
return RETVAL_DATA_ERROR;
/* Decode MTF to get the next selector */
uc = mtfSymbol[j];
memmove(mtfSymbol + 1, mtfSymbol, j);
mtfSymbol[0] = selectors[i] = uc;
}
/* Read the huffman coding tables for each group, which code for symTotal
literal symbols, plus two run symbols (RUNA, RUNB) */
symCount = symTotal + 2;
for (j = 0; j < groupCount; j++) {
unsigned char length[MAX_SYMBOLS], temp[MAX_HUFCODE_BITS + 1];
int minLen, maxLen, pp;
/* Read lengths */
t = get_bits(bd, 5);
for (i = 0; i < symCount; i++) {
for (;;) {
if (t < 1 || t > MAX_HUFCODE_BITS)
return RETVAL_DATA_ERROR;
if (!get_bits(bd, 1))
break;
if (!get_bits(bd, 1))
t++;
else
t--;
}
length[i] = t;
}
/* Find largest and smallest lengths in this group */
minLen = maxLen = length[0];
for (i = 1; i < symCount; i++) {
if (length[i] > maxLen)
maxLen = length[i];
else if (length[i] < minLen)
minLen = length[i];
}
/* Calculate permute[], base[], and limit[] tables from length[].
*
* permute[] is the lookup table for converting huffman coded symbols
* into decoded symbols. base[] is the amount to subtract from the
* value of a huffman symbol of a given length when using permute[].
*
* limit[] indicates the largest numerical value a symbol with a given
* number of bits can have. It lets us know when to stop reading.
*
* To use these, keep reading bits until value<=limit[bitcount] or
* you've read over 20 bits (error). Then the decoded symbol
* equals permute[hufcode_value-base[hufcode_bitcount]].
*/
hufGroup = bd->groups + j;
hufGroup->minLen = minLen;
hufGroup->maxLen = maxLen;
/* Note that minLen can't be smaller than 1, so we adjust the
base and limit array pointers so we're not always wasting the
first entry. We do this again when using them (during symbol
decoding).*/
base = hufGroup->base - 1;
limit = hufGroup->limit - 1;
/* Calculate permute[] */
pp = 0;
for (i = minLen; i <= maxLen; i++)
for (t = 0; t < symCount; t++)
if (length[t] == i)
hufGroup->permute[pp++] = t;
/* Count cumulative symbols coded for at each bit length */
for (i = minLen; i <= maxLen; i++)
temp[i] = limit[i] = 0;
for (i = 0; i < symCount; i++)
temp[length[i]]++;
/* Calculate limit[] (the largest symbol-coding value at each
bit length, which is (previous limit<<1)+symbols at this
level), and base[] (number of symbols to ignore at each bit
length, which is limit-cumulative count of symbols coded for
already). */
pp = t = 0;
for (i = minLen; i < maxLen; i++) {
pp += temp[i];
limit[i] = pp - 1;
pp <<= 1;
base[i + 1] = pp - (t += temp[i]);
}
limit[maxLen] = pp + temp[maxLen] - 1;
base[minLen] = 0;
}
/* We've finished reading and digesting the block header. Now read this
block's huffman coded symbols from the file and undo the huffman
coding and run length encoding, saving the result into
dbuf[dbufCount++]=uc */
/* Initialize symbol occurrence counters and symbol mtf table */
memset(byteCount, 0, 256 * sizeof(int));
for (i = 0; i < 256; i++)
mtfSymbol[i] = (unsigned char)i;
/* Loop through compressed symbols */
runPos = dbufCount = symCount = selector = 0;
for (;;) {
/* Determine which huffman coding group to use. */
if (!(symCount--)) {
symCount = GROUP_SIZE - 1;
if (selector >= nSelectors)
return RETVAL_DATA_ERROR;
hufGroup = bd->groups + selectors[selector++];
base = hufGroup->base - 1;
limit = hufGroup->limit - 1;
}
/* Read next huffman-coded symbol */
i = hufGroup->minLen;
j = get_bits(bd, i);
for (;;) {
if (i > hufGroup->maxLen)
return RETVAL_DATA_ERROR;
if (j <= limit[i])
break;
i++;
j = (j << 1) | get_bits(bd, 1);
}
/* Huffman decode nextSym (with bounds checking) */
j -= base[i];
if (j < 0 || j >= MAX_SYMBOLS)
return RETVAL_DATA_ERROR;
nextSym = hufGroup->permute[j];
/* If this is a repeated run, loop collecting data */
if (nextSym == SYMBOL_RUNA || nextSym == SYMBOL_RUNB) {
/* If this is the start of a new run, zero out counter */
if (!runPos) {
runPos = 1;
t = 0;
}
/* Neat trick that saves 1 symbol: instead of or-ing 0 or 1
at each bit position, add 1 or 2 instead. For example,
1011 is 1<<0 + 1<<1 + 2<<2. 1010 is 2<<0 + 2<<1 + 1<<2.
You can make any bit pattern that way using 1 less symbol
than the basic or 0/1 method (except all bits 0, which
would use no symbols, but a run of length 0 doesn't mean
anything in this context). Thus space is saved. */
if (nextSym == SYMBOL_RUNA)
t += runPos;
else
t += 2 * runPos;
runPos <<= 1;
continue;
}
/* When we hit the first non-run symbol after a run, we now know
how many times to repeat the last literal, so append that
many copies to our buffer of decoded symbols (dbuf) now. (The
last literal used is the one at the head of the mtfSymbol
array.) */
if (runPos) {
runPos = 0;
if (dbufCount + t >= dbufSize)
return RETVAL_DATA_ERROR;
uc = symToByte[mtfSymbol[0]];
byteCount[uc] += t;
while (t--)
dbuf[dbufCount++] = uc;
}
/* Is this the terminating symbol? */
if (nextSym > symTotal)
break;
/* At this point, the symbol we just decoded indicates a new
literal character. Subtract one to get the position in the
MTF array at which this literal is currently to be found.
(Note that the result can't be -1 or 0, because 0 and 1 are
RUNA and RUNB. Another instance of the first symbol in the
mtf array, position 0, would have been handled as part of a
run.) */
if (dbufCount >= dbufSize)
return RETVAL_DATA_ERROR;
i = nextSym - 1;
uc = mtfSymbol[i];
memmove(mtfSymbol + 1, mtfSymbol, i);
mtfSymbol[0] = uc;
uc = symToByte[uc];
/* We have our literal byte. Save it into dbuf. */
byteCount[uc]++;
dbuf[dbufCount++] = (unsigned int)uc;
}
/* At this point, we've finished reading huffman-coded symbols and
compressed runs from the input stream. There are dbufCount many
of them in dbuf[]. Now undo the Burrows-Wheeler transform on
dbuf. See http://dogma.net/markn/articles/bwt/bwt.htm */
/* Now we know what dbufCount is, do a better sanity check on origPtr. */
if (origPtr < 0 || origPtr >= dbufCount)
return RETVAL_DATA_ERROR;
/* Turn byteCount into cumulative occurrence counts of 0 to n-1. */
j = 0;
for (i = 0; i < 256; i++) {
k = j + byteCount[i];
byteCount[i] = j;
j = k;
}
/* Figure out what order dbuf would be in if we sorted it. */
for (i = 0; i < dbufCount; i++) {
uc = (unsigned char)(dbuf[i] & 0xff);
dbuf[byteCount[uc]] |= (i << 8);
byteCount[uc]++;
}
/* blockRandomised support would go here. */
/* Using i as position, j as previous character, t as current character,
and uc as run count */
bd->dataCRC = 0xffffffffL;
/* Decode first byte by hand to initialize "previous" byte. Note
that it doesn't get output, and if the first three characters are
identical it doesn't qualify as a run (hence uc=255, which will
either wrap to 1 or get reset). */
if (dbufCount) {
bd->writePos = dbuf[origPtr];
bd->writeCurrent = (unsigned char)(bd->writePos & 0xff);
bd->writePos >>= 8;
bd->writeRun = -1;
}
bd->writeCount = dbufCount;
return RETVAL_OK;
}
/* Flush output buffer to disk */
static void flush_bunzip_outbuf(bunzip_data *bd, int64_t out_fd)
{
if (bd->outbufPos) {
if (write(out_fd, bd->outbuf, bd->outbufPos) != bd->outbufPos)
longjmp(bd->jmpbuf, RETVAL_UNEXPECTED_OUTPUT_EOF);
bd->outbufPos = 0;
}
}
/* Undo burrows-wheeler transform on intermediate buffer to produce output.
If !len, write up to len bytes of data to buf. Otherwise write to out_fd.
Returns len ? bytes written : RETVAL_OK. Notice all errors negative #'s. */
static int write_bunzip_data(
bunzip_data *bd, int64_t out_fd, char *outbuf, int len)
{
unsigned int *dbuf = bd->dbuf;
int count, pos, current, run, copies, outbyte, previous, gotcount = 0;
for (;;) {
/* If last read was short due to end of file, return last block now */
if (bd->writeCount < 0)
return bd->writeCount;
/* If we need to refill dbuf, do it. */
if (!bd->writeCount) {
int i = read_bunzip_data(bd);
if (i) {
if (i == RETVAL_LAST_BLOCK) {
bd->writeCount = i;
return gotcount;
} else
return i;
}
}
/* Loop generating output */
count = bd->writeCount;
pos = bd->writePos;
current = bd->writeCurrent;
run = bd->writeRun;
while (count) {
/* If somebody (like busybox tar) wants a certain number of
bytes of data from memory instead of written to a file,
humor them */
if (len && bd->outbufPos >= len)
goto dataus_interruptus;
count--;
/* Follow sequence vector to undo Burrows-Wheeler transform */
previous = current;
pos = dbuf[pos];
current = pos & 0xff;
pos >>= 8;
/* Whenever we see 3 consecutive copies of the same byte,
the 4th is a repeat count */
if (run++ == 3) {
copies = current;
outbyte = previous;
current = -1;
} else {
copies = 1;
outbyte = current;
}
/* Output bytes to buffer, flushing to file if necessary */
while (copies--) {
if (bd->outbufPos == IOBUF_SIZE)
flush_bunzip_outbuf(bd, out_fd);
bd->outbuf[bd->outbufPos++] = outbyte;
bd->dataCRC = (bd->dataCRC << 8)
^ bd->crc32Table[(bd->dataCRC >> 24) ^ outbyte];
}
if (current != previous)
run = 0;
}
/* Decompression of this block completed successfully */
bd->dataCRC = ~(bd->dataCRC);
bd->totalCRC
= ((bd->totalCRC << 1) | (bd->totalCRC >> 31)) ^ bd->dataCRC;
/* If this block had a CRC error, force file level CRC error. */
if (bd->dataCRC != bd->headerCRC) {
bd->totalCRC = bd->headerCRC + 1;
return RETVAL_LAST_BLOCK;
}
dataus_interruptus:
bd->writeCount = count;
if (len) {
gotcount += bd->outbufPos;
memcpy(outbuf, bd->outbuf, len);
/* If we got enough data, checkpoint loop state and return */
if ((len -= bd->outbufPos) < 1) {
bd->outbufPos -= len;
if (bd->outbufPos)
memmove(bd->outbuf, bd->outbuf + len, bd->outbufPos);
bd->writePos = pos;
bd->writeCurrent = current;
bd->writeRun = run;
return gotcount;
}
}
}
}
/* Allocate the structure, read file header. If !len, src_fd contains
filehandle to read from. Else inbuf contains data. */
static int start_bunzip(bunzip_data **bdp, int64_t src_fd, char *inbuf, int len)
{
bunzip_data *bd;
unsigned int i, j, c;
/* Figure out how much data to allocate */
i = sizeof(bunzip_data);
if (!len)
i += IOBUF_SIZE;
/* Allocate bunzip_data. Most fields initialize to zero. */
if (!(bd = *bdp = malloc(i)))
return RETVAL_OUT_OF_MEMORY;
memset(bd, 0, sizeof(bunzip_data));
if (len) {
bd->inbuf = (unsigned char *)inbuf;
bd->inbufCount = len;
bd->in_fd = -1;
} else {
bd->inbuf = (unsigned char *)(bd + 1);
bd->in_fd = src_fd;
}
/* Init the CRC32 table (big endian) */
for (i = 0; i < 256; i++) {
c = i << 24;
for (j = 8; j; j--)
c = c & 0x80000000 ? (c << 1) ^ 0x04c11db7 : (c << 1);
bd->crc32Table[i] = c;
}
/* Setup for I/O error handling via longjmp */
i = setjmp(bd->jmpbuf);
if (i)
return i;
/* Ensure that file starts with "BZh" */
for (i = 0; i < 3; i++)
if (get_bits(bd, 8) != "BZh"[i])
return RETVAL_NOT_BZIP_DATA;
/* Next byte ascii '1'-'9', indicates block size in units of 100k of
uncompressed data. Allocate intermediate buffer for block. */
i = get_bits(bd, 8);
if (i < '1' || i > '9')
return RETVAL_NOT_BZIP_DATA;
bd->dbufSize = 100000 * (i - '0');
if (!(bd->dbuf = malloc(bd->dbufSize * sizeof(int))))
return RETVAL_OUT_OF_MEMORY;
return RETVAL_OK;
}
/* Example usage: decompress src_fd to dst_fd. (Stops at end of bzip data,
not end of file.) */
static char *uncompressStream(int64_t src_fd, int64_t dst_fd)
{
bunzip_data *bd;
int i;
if (!(i = start_bunzip(&bd, src_fd, 0, 0))) {
i = write_bunzip_data(bd, dst_fd, 0, 0);
if (i == RETVAL_LAST_BLOCK && bd->headerCRC == bd->totalCRC)
i = RETVAL_OK;
}
flush_bunzip_outbuf(bd, dst_fd);
if (bd->dbuf)
free(bd->dbuf);
free(bd);
return bunzip_errors[-i];
}
int main(int argc, char *argv[])
{
char *err;
if (!(err = uncompressStream(STDIN_FILENO, STDOUT_FILENO))) {
return 0;
} else {
fprintf(stderr, "\n%s\n", err);
return 1;
}
}

@ -1,26 +0,0 @@
Copyright 2006-2011, the V8 project authors. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

@ -1 +0,0 @@
google/double-conversion@1dce44c4313a6f356fcfa4b3e8887f037ac0bf23

@ -1,621 +0,0 @@
// Copyright 2010 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "libc/macros.h"
#include "libc/math.h"
#include "third_party/double-conversion/bignum-dtoa.h"
#include "third_party/double-conversion/bignum.h"
#include "third_party/double-conversion/ieee.h"
asm(".ident\t\"\\n\\n\
double-conversion (BSD-3)\\n\
Copyright 2010 the V8 project authors\"");
asm(".include \"libc/disclaimer.inc\"");
namespace double_conversion {
static int NormalizedExponent(uint64_t significand, int exponent) {
DOUBLE_CONVERSION_ASSERT(significand != 0);
while ((significand & Double::kHiddenBit) == 0) {
significand = significand << 1;
exponent = exponent - 1;
}
return exponent;
}
// Forward declarations:
// Returns an estimation of k such that 10^(k-1) <= v < 10^k.
static int EstimatePower(int exponent);
// Computes v / 10^estimated_power exactly, as a ratio of two bignums, numerator
// and denominator.
static void InitialScaledStartValues(uint64_t significand, int exponent,
bool lower_boundary_is_closer,
int estimated_power,
bool need_boundary_deltas,
Bignum* numerator, Bignum* denominator,
Bignum* delta_minus, Bignum* delta_plus);
// Multiplies numerator/denominator so that its values lies in the range 1-10.
// Returns decimal_point s.t.
// v = numerator'/denominator' * 10^(decimal_point-1)
// where numerator' and denominator' are the values of numerator and
// denominator after the call to this function.
static void FixupMultiply10(int estimated_power, bool is_even,
int* decimal_point, Bignum* numerator,
Bignum* denominator, Bignum* delta_minus,
Bignum* delta_plus);
// Generates digits from the left to the right and stops when the generated
// digits yield the shortest decimal representation of v.
static void GenerateShortestDigits(Bignum* numerator, Bignum* denominator,
Bignum* delta_minus, Bignum* delta_plus,
bool is_even, Vector<char> buffer,
int* length);
// Generates 'requested_digits' after the decimal point.
static void BignumToFixed(int requested_digits, int* decimal_point,
Bignum* numerator, Bignum* denominator,
Vector<char> buffer, int* length);
// Generates 'count' digits of numerator/denominator.
// Once 'count' digits have been produced rounds the result depending on the
// remainder (remainders of exactly .5 round upwards). Might update the
// decimal_point when rounding up (for example for 0.9999).
static void GenerateCountedDigits(int count, int* decimal_point,
Bignum* numerator, Bignum* denominator,
Vector<char> buffer, int* length);
void BignumDtoa(double v, BignumDtoaMode mode, int requested_digits,
Vector<char> buffer, int* length, int* decimal_point) {
DOUBLE_CONVERSION_ASSERT(v > 0);
DOUBLE_CONVERSION_ASSERT(!Double(v).IsSpecial());
uint64_t significand;
int exponent;
bool lower_boundary_is_closer;
if (mode == BIGNUM_DTOA_SHORTEST_SINGLE) {
float f = static_cast<float>(v);
DOUBLE_CONVERSION_ASSERT(f == v);
significand = Single(f).Significand();
exponent = Single(f).Exponent();
lower_boundary_is_closer = Single(f).LowerBoundaryIsCloser();
} else {
significand = Double(v).Significand();
exponent = Double(v).Exponent();
lower_boundary_is_closer = Double(v).LowerBoundaryIsCloser();
}
bool need_boundary_deltas =
(mode == BIGNUM_DTOA_SHORTEST || mode == BIGNUM_DTOA_SHORTEST_SINGLE);
bool is_even = (significand & 1) == 0;
int normalized_exponent = NormalizedExponent(significand, exponent);
// estimated_power might be too low by 1.
int estimated_power = EstimatePower(normalized_exponent);
// Shortcut for Fixed.
// The requested digits correspond to the digits after the point. If the
// number is much too small, then there is no need in trying to get any
// digits.
if (mode == BIGNUM_DTOA_FIXED && -estimated_power - 1 > requested_digits) {
buffer[0] = '\0';
*length = 0;
// Set decimal-point to -requested_digits. This is what Gay does.
// Note that it should not have any effect anyways since the string is
// empty.
*decimal_point = -requested_digits;
return;
}
Bignum numerator;
Bignum denominator;
Bignum delta_minus;
Bignum delta_plus;
// Make sure the bignum can grow large enough. The smallest double equals
// 4e-324. In this case the denominator needs fewer than 324*4 binary digits.
// The maximum double is 1.7976931348623157e308 which needs fewer than
// 308*4 binary digits.
DOUBLE_CONVERSION_ASSERT(Bignum::kMaxSignificantBits >= 324 * 4);
InitialScaledStartValues(significand, exponent, lower_boundary_is_closer,
estimated_power, need_boundary_deltas, &numerator,
&denominator, &delta_minus, &delta_plus);
// We now have v = (numerator / denominator) * 10^estimated_power.
FixupMultiply10(estimated_power, is_even, decimal_point, &numerator,
&denominator, &delta_minus, &delta_plus);
// We now have v = (numerator / denominator) * 10^(decimal_point-1), and
// 1 <= (numerator + delta_plus) / denominator < 10
switch (mode) {
case BIGNUM_DTOA_SHORTEST:
case BIGNUM_DTOA_SHORTEST_SINGLE:
GenerateShortestDigits(&numerator, &denominator, &delta_minus,
&delta_plus, is_even, buffer, length);
break;
case BIGNUM_DTOA_FIXED:
BignumToFixed(requested_digits, decimal_point, &numerator, &denominator,
buffer, length);
break;
case BIGNUM_DTOA_PRECISION:
GenerateCountedDigits(requested_digits, decimal_point, &numerator,
&denominator, buffer, length);
break;
default:
DOUBLE_CONVERSION_UNREACHABLE();
}
buffer[*length] = '\0';
}
// The procedure starts generating digits from the left to the right and stops
// when the generated digits yield the shortest decimal representation of v. A
// decimal representation of v is a number lying closer to v than to any other
// double, so it converts to v when read.
//
// This is true if d, the decimal representation, is between m- and m+, the
// upper and lower boundaries. d must be strictly between them if !is_even.
// m- := (numerator - delta_minus) / denominator
// m+ := (numerator + delta_plus) / denominator
//
// Precondition: 0 <= (numerator+delta_plus) / denominator < 10.
// If 1 <= (numerator+delta_plus) / denominator < 10 then no leading 0 digit
// will be produced. This should be the standard precondition.
static void GenerateShortestDigits(Bignum* numerator, Bignum* denominator,
Bignum* delta_minus, Bignum* delta_plus,
bool is_even, Vector<char> buffer,
int* length) {
// Small optimization: if delta_minus and delta_plus are the same just reuse
// one of the two bignums.
if (Bignum::Equal(*delta_minus, *delta_plus)) {
delta_plus = delta_minus;
}
*length = 0;
for (;;) {
uint16_t digit;
digit = numerator->DivideModuloIntBignum(*denominator);
DOUBLE_CONVERSION_ASSERT(
digit <= 9); // digit is a uint16_t and therefore always positive.
// digit = numerator / denominator (integer division).
// numerator = numerator % denominator.
buffer[(*length)++] = static_cast<char>(digit + '0');
// Can we stop already?
// If the remainder of the division is less than the distance to the lower
// boundary we can stop. In this case we simply round down (discarding the
// remainder).
// Similarly we test if we can round up (using the upper boundary).
bool in_delta_room_minus;
bool in_delta_room_plus;
if (is_even) {
in_delta_room_minus = Bignum::LessEqual(*numerator, *delta_minus);
} else {
in_delta_room_minus = Bignum::Less(*numerator, *delta_minus);
}
if (is_even) {
in_delta_room_plus =
Bignum::PlusCompare(*numerator, *delta_plus, *denominator) >= 0;
} else {
in_delta_room_plus =
Bignum::PlusCompare(*numerator, *delta_plus, *denominator) > 0;
}
if (!in_delta_room_minus && !in_delta_room_plus) {
// Prepare for next iteration.
numerator->Times10();
delta_minus->Times10();
// We optimized delta_plus to be equal to delta_minus (if they share the
// same value). So don't multiply delta_plus if they point to the same
// object.
if (delta_minus != delta_plus) {
delta_plus->Times10();
}
} else if (in_delta_room_minus && in_delta_room_plus) {
// Let's see if 2*numerator < denominator.
// If yes, then the next digit would be < 5 and we can round down.
int compare = Bignum::PlusCompare(*numerator, *numerator, *denominator);
if (compare < 0) {
// Remaining digits are less than .5. -> Round down (== do nothing).
} else if (compare > 0) {
// Remaining digits are more than .5 of denominator. -> Round up.
// Note that the last digit could not be a '9' as otherwise the whole
// loop would have stopped earlier.
// We still have an assert here in case the preconditions were not
// satisfied.
DOUBLE_CONVERSION_ASSERT(buffer[(*length) - 1] != '9');
buffer[(*length) - 1]++;
} else {
// Halfway case.
// TODO(floitsch): need a way to solve half-way cases.
// For now let's round towards even (since this is what Gay seems to
// do).
if ((buffer[(*length) - 1] - '0') % 2 == 0) {
// Round down => Do nothing.
} else {
DOUBLE_CONVERSION_ASSERT(buffer[(*length) - 1] != '9');
buffer[(*length) - 1]++;
}
}
return;
} else if (in_delta_room_minus) {
// Round down (== do nothing).
return;
} else { // in_delta_room_plus
// Round up.
// Note again that the last digit could not be '9' since this would have
// stopped the loop earlier.
// We still have an DOUBLE_CONVERSION_ASSERT here, in case the
// preconditions were not satisfied.
DOUBLE_CONVERSION_ASSERT(buffer[(*length) - 1] != '9');
buffer[(*length) - 1]++;
return;
}
}
}
// Let v = numerator / denominator < 10.
// Then we generate 'count' digits of d = x.xxxxx... (without the decimal point)
// from left to right. Once 'count' digits have been produced we decide wether
// to round up or down. Remainders of exactly .5 round upwards. Numbers such
// as 9.999999 propagate a carry all the way, and change the
// exponent (decimal_point), when rounding upwards.
static void GenerateCountedDigits(int count, int* decimal_point,
Bignum* numerator, Bignum* denominator,
Vector<char> buffer, int* length) {
DOUBLE_CONVERSION_ASSERT(count >= 0);
for (int i = 0; i < count - 1; ++i) {
uint16_t digit;
digit = numerator->DivideModuloIntBignum(*denominator);
DOUBLE_CONVERSION_ASSERT(
digit <= 9); // digit is a uint16_t and therefore always positive.
// digit = numerator / denominator (integer division).
// numerator = numerator % denominator.
buffer[i] = static_cast<char>(digit + '0');
// Prepare for next iteration.
numerator->Times10();
}
// Generate the last digit.
uint16_t digit;
digit = numerator->DivideModuloIntBignum(*denominator);
if (Bignum::PlusCompare(*numerator, *numerator, *denominator) >= 0) {
digit++;
}
DOUBLE_CONVERSION_ASSERT(digit <= 10);
buffer[count - 1] = static_cast<char>(digit + '0');
// Correct bad digits (in case we had a sequence of '9's). Propagate the
// carry until we hat a non-'9' or til we reach the first digit.
for (int i = count - 1; i > 0; --i) {
if (buffer[i] != '0' + 10) break;
buffer[i] = '0';
buffer[i - 1]++;
}
if (buffer[0] == '0' + 10) {
// Propagate a carry past the top place.
buffer[0] = '1';
(*decimal_point)++;
}
*length = count;
}
// Generates 'requested_digits' after the decimal point. It might omit
// trailing '0's. If the input number is too small then no digits at all are
// generated (ex.: 2 fixed digits for 0.00001).
//
// Input verifies: 1 <= (numerator + delta) / denominator < 10.
static void BignumToFixed(int requested_digits, int* decimal_point,
Bignum* numerator, Bignum* denominator,
Vector<char> buffer, int* length) {
// Note that we have to look at more than just the requested_digits, since
// a number could be rounded up. Example: v=0.5 with requested_digits=0.
// Even though the power of v equals 0 we can't just stop here.
if (-(*decimal_point) > requested_digits) {
// The number is definitively too small.
// Ex: 0.001 with requested_digits == 1.
// Set decimal-point to -requested_digits. This is what Gay does.
// Note that it should not have any effect anyways since the string is
// empty.
*decimal_point = -requested_digits;
*length = 0;
return;
} else if (-(*decimal_point) == requested_digits) {
// We only need to verify if the number rounds down or up.
// Ex: 0.04 and 0.06 with requested_digits == 1.
DOUBLE_CONVERSION_ASSERT(*decimal_point == -requested_digits);
// Initially the fraction lies in range (1, 10]. Multiply the denominator
// by 10 so that we can compare more easily.
denominator->Times10();
if (Bignum::PlusCompare(*numerator, *numerator, *denominator) >= 0) {
// If the fraction is >= 0.5 then we have to include the rounded
// digit.
buffer[0] = '1';
*length = 1;
(*decimal_point)++;
} else {
// Note that we caught most of similar cases earlier.
*length = 0;
}
return;
} else {
// The requested digits correspond to the digits after the point.
// The variable 'needed_digits' includes the digits before the point.
int needed_digits = (*decimal_point) + requested_digits;
GenerateCountedDigits(needed_digits, decimal_point, numerator, denominator,
buffer, length);
}
}
// Returns an estimation of k such that 10^(k-1) <= v < 10^k where
// v = f * 2^exponent and 2^52 <= f < 2^53.
// v is hence a normalized double with the given exponent. The output is an
// approximation for the exponent of the decimal approimation .digits * 10^k.
//
// The result might undershoot by 1 in which case 10^k <= v < 10^k+1.
// Note: this property holds for v's upper boundary m+ too.
// 10^k <= m+ < 10^k+1.
// (see explanation below).
//
// Examples:
// EstimatePower(0) => 16
// EstimatePower(-52) => 0
//
// Note: e >= 0 => EstimatedPower(e) > 0. No similar claim can be made for e<0.
static int EstimatePower(int exponent) {
// This function estimates log10 of v where v = f*2^e (with e == exponent).
// Note that 10^floor(log10(v)) <= v, but v <= 10^ceil(log10(v)).
// Note that f is bounded by its container size. Let p = 53 (the double's
// significand size). Then 2^(p-1) <= f < 2^p.
//
// Given that log10(v) == log2(v)/log2(10) and e+(len(f)-1) is quite close
// to log2(v) the function is simplified to (e+(len(f)-1)/log2(10)).
// The computed number undershoots by less than 0.631 (when we compute log3
// and not log10).
//
// Optimization: since we only need an approximated result this computation
// can be performed on 64 bit integers. On x86/x64 architecture the speedup is
// not really measurable, though.
//
// Since we want to avoid overshooting we decrement by 1e10 so that
// floating-point imprecisions don't affect us.
//
// Explanation for v's boundary m+: the computation takes advantage of
// the fact that 2^(p-1) <= f < 2^p. Boundaries still satisfy this requirement
// (even for denormals where the delta can be much more important).
const double k1Log10 = 0.30102999566398114; // 1/lg(10)
// For doubles len(f) == 53 (don't forget the hidden bit).
const int kSignificandSize = Double::kSignificandSize;
double estimate = ceil((exponent + kSignificandSize - 1) * k1Log10 - 1e-10);
return static_cast<int>(estimate);
}
// See comments for InitialScaledStartValues.
static void InitialScaledStartValuesPositiveExponent(
uint64_t significand, int exponent, int estimated_power,
bool need_boundary_deltas, Bignum* numerator, Bignum* denominator,
Bignum* delta_minus, Bignum* delta_plus) {
// A positive exponent implies a positive power.
DOUBLE_CONVERSION_ASSERT(estimated_power >= 0);
// Since the estimated_power is positive we simply multiply the denominator
// by 10^estimated_power.
// numerator = v.
numerator->AssignUInt64(significand);
numerator->ShiftLeft(exponent);
// denominator = 10^estimated_power.
denominator->AssignPowerUInt16(10, estimated_power);
if (need_boundary_deltas) {
// Introduce a common denominator so that the deltas to the boundaries are
// integers.
denominator->ShiftLeft(1);
numerator->ShiftLeft(1);
// Let v = f * 2^e, then m+ - v = 1/2 * 2^e; With the common
// denominator (of 2) delta_plus equals 2^e.
delta_plus->AssignUInt16(1);
delta_plus->ShiftLeft(exponent);
// Same for delta_minus. The adjustments if f == 2^p-1 are done later.
delta_minus->AssignUInt16(1);
delta_minus->ShiftLeft(exponent);
}
}
// See comments for InitialScaledStartValues
static void InitialScaledStartValuesNegativeExponentPositivePower(
uint64_t significand, int exponent, int estimated_power,
bool need_boundary_deltas, Bignum* numerator, Bignum* denominator,
Bignum* delta_minus, Bignum* delta_plus) {
// v = f * 2^e with e < 0, and with estimated_power >= 0.
// This means that e is close to 0 (have a look at how estimated_power is
// computed).
// numerator = significand
// since v = significand * 2^exponent this is equivalent to
// numerator = v * / 2^-exponent
numerator->AssignUInt64(significand);
// denominator = 10^estimated_power * 2^-exponent (with exponent < 0)
denominator->AssignPowerUInt16(10, estimated_power);
denominator->ShiftLeft(-exponent);
if (need_boundary_deltas) {
// Introduce a common denominator so that the deltas to the boundaries are
// integers.
denominator->ShiftLeft(1);
numerator->ShiftLeft(1);
// Let v = f * 2^e, then m+ - v = 1/2 * 2^e; With the common
// denominator (of 2) delta_plus equals 2^e.
// Given that the denominator already includes v's exponent the distance
// to the boundaries is simply 1.
delta_plus->AssignUInt16(1);
// Same for delta_minus. The adjustments if f == 2^p-1 are done later.
delta_minus->AssignUInt16(1);
}
}
// See comments for InitialScaledStartValues
static void InitialScaledStartValuesNegativeExponentNegativePower(
uint64_t significand, int exponent, int estimated_power,
bool need_boundary_deltas, Bignum* numerator, Bignum* denominator,
Bignum* delta_minus, Bignum* delta_plus) {
// Instead of multiplying the denominator with 10^estimated_power we
// multiply all values (numerator and deltas) by 10^-estimated_power.
// Use numerator as temporary container for power_ten.
Bignum* power_ten = numerator;
power_ten->AssignPowerUInt16(10, -estimated_power);
if (need_boundary_deltas) {
// Since power_ten == numerator we must make a copy of 10^estimated_power
// before we complete the computation of the numerator.
// delta_plus = delta_minus = 10^estimated_power
delta_plus->AssignBignum(*power_ten);
delta_minus->AssignBignum(*power_ten);
}
// numerator = significand * 2 * 10^-estimated_power
// since v = significand * 2^exponent this is equivalent to
// numerator = v * 10^-estimated_power * 2 * 2^-exponent.
// Remember: numerator has been abused as power_ten. So no need to assign it
// to itself.
DOUBLE_CONVERSION_ASSERT(numerator == power_ten);
numerator->MultiplyByUInt64(significand);
// denominator = 2 * 2^-exponent with exponent < 0.
denominator->AssignUInt16(1);
denominator->ShiftLeft(-exponent);
if (need_boundary_deltas) {
// Introduce a common denominator so that the deltas to the boundaries are
// integers.
numerator->ShiftLeft(1);
denominator->ShiftLeft(1);
// With this shift the boundaries have their correct value, since
// delta_plus = 10^-estimated_power, and
// delta_minus = 10^-estimated_power.
// These assignments have been done earlier.
// The adjustments if f == 2^p-1 (lower boundary is closer) are done later.
}
}
// Let v = significand * 2^exponent.
// Computes v / 10^estimated_power exactly, as a ratio of two bignums, numerator
// and denominator. The functions GenerateShortestDigits and
// GenerateCountedDigits will then convert this ratio to its decimal
// representation d, with the required accuracy.
// Then d * 10^estimated_power is the representation of v.
// (Note: the fraction and the estimated_power might get adjusted before
// generating the decimal representation.)
//
// The initial start values consist of:
// - a scaled numerator: s.t. numerator/denominator == v / 10^estimated_power.
// - a scaled (common) denominator.
// optionally (used by GenerateShortes