浏览代码

更新配置

杜鑫 5 年之前
父节点
当前提交
a5990b9f68
共有 100 个文件被更改,包括 375653 次插入0 次删除
  1. 7 0
      js/navigator/AppNavigators.js
  2. 61 0
      js/page/register3.js
  3. 二进制
      static/uploadIcon.png
  4. 3 0
      third-party/double-conversion-1.1.6/.gitignore
  5. 0 0
      third-party/double-conversion-1.1.6/.installed
  6. 13 0
      third-party/double-conversion-1.1.6/AUTHORS
  7. 93 0
      third-party/double-conversion-1.1.6/CMakeLists.txt
  8. 26 0
      third-party/double-conversion-1.1.6/COPYING
  9. 38 0
      third-party/double-conversion-1.1.6/Changelog
  10. 26 0
      third-party/double-conversion-1.1.6/LICENSE
  11. 7 0
      third-party/double-conversion-1.1.6/Makefile
  12. 54 0
      third-party/double-conversion-1.1.6/README
  13. 46 0
      third-party/double-conversion-1.1.6/SConstruct
  14. 2 0
      third-party/double-conversion-1.1.6/double-conversionBuildTreeSettings.cmake.in
  15. 17 0
      third-party/double-conversion-1.1.6/double-conversionConfig.cmake.in
  16. 11 0
      third-party/double-conversion-1.1.6/double-conversionConfigVersion.cmake.in
  17. 48 0
      third-party/double-conversion-1.1.6/src/CMakeLists.txt
  18. 12 0
      third-party/double-conversion-1.1.6/src/SConscript
  19. 641 0
      third-party/double-conversion-1.1.6/src/bignum-dtoa.cc
  20. 84 0
      third-party/double-conversion-1.1.6/src/bignum-dtoa.h
  21. 766 0
      third-party/double-conversion-1.1.6/src/bignum.cc
  22. 145 0
      third-party/double-conversion-1.1.6/src/bignum.h
  23. 176 0
      third-party/double-conversion-1.1.6/src/cached-powers.cc
  24. 64 0
      third-party/double-conversion-1.1.6/src/cached-powers.h
  25. 57 0
      third-party/double-conversion-1.1.6/src/diy-fp.cc
  26. 118 0
      third-party/double-conversion-1.1.6/src/diy-fp.h
  27. 910 0
      third-party/double-conversion-1.1.6/src/double-conversion.cc
  28. 536 0
      third-party/double-conversion-1.1.6/src/double-conversion.h
  29. 665 0
      third-party/double-conversion-1.1.6/src/fast-dtoa.cc
  30. 88 0
      third-party/double-conversion-1.1.6/src/fast-dtoa.h
  31. 404 0
      third-party/double-conversion-1.1.6/src/fixed-dtoa.cc
  32. 56 0
      third-party/double-conversion-1.1.6/src/fixed-dtoa.h
  33. 402 0
      third-party/double-conversion-1.1.6/src/ieee.h
  34. 555 0
      third-party/double-conversion-1.1.6/src/strtod.cc
  35. 45 0
      third-party/double-conversion-1.1.6/src/strtod.h
  36. 324 0
      third-party/double-conversion-1.1.6/src/utils.h
  37. 1 0
      third-party/double-conversion-1.1.6/test/CMakeLists.txt
  38. 50 0
      third-party/double-conversion-1.1.6/test/cctest/CMakeLists.txt
  39. 17 0
      third-party/double-conversion-1.1.6/test/cctest/SConscript
  40. 122 0
      third-party/double-conversion-1.1.6/test/cctest/cctest.cc
  41. 141 0
      third-party/double-conversion-1.1.6/test/cctest/cctest.h
  42. 314 0
      third-party/double-conversion-1.1.6/test/cctest/checks.h
  43. 100048 0
      third-party/double-conversion-1.1.6/test/cctest/gay-fixed.cc
  44. 46 0
      third-party/double-conversion-1.1.6/test/cctest/gay-fixed.h
  45. 100049 0
      third-party/double-conversion-1.1.6/test/cctest/gay-precision.cc
  46. 46 0
      third-party/double-conversion-1.1.6/test/cctest/gay-precision.h
  47. 10049 0
      third-party/double-conversion-1.1.6/test/cctest/gay-shortest-single.cc
  48. 44 0
      third-party/double-conversion-1.1.6/test/cctest/gay-shortest-single.h
  49. 100049 0
      third-party/double-conversion-1.1.6/test/cctest/gay-shortest.cc
  50. 43 0
      third-party/double-conversion-1.1.6/test/cctest/gay-shortest.h
  51. 395 0
      third-party/double-conversion-1.1.6/test/cctest/test-bignum-dtoa.cc
  52. 1502 0
      third-party/double-conversion-1.1.6/test/cctest/test-bignum.cc
  53. 4571 0
      third-party/double-conversion-1.1.6/test/cctest/test-conversions.cc
  54. 65 0
      third-party/double-conversion-1.1.6/test/cctest/test-diy-fp.cc
  55. 507 0
      third-party/double-conversion-1.1.6/test/cctest/test-dtoa.cc
  56. 372 0
      third-party/double-conversion-1.1.6/test/cctest/test-fast-dtoa.cc
  57. 511 0
      third-party/double-conversion-1.1.6/test/cctest/test-fixed-dtoa.cc
  58. 422 0
      third-party/double-conversion-1.1.6/test/cctest/test-ieee.cc
  59. 751 0
      third-party/double-conversion-1.1.6/test/cctest/test-strtod.cc
  60. 4 0
      third-party/glog-0.3.5/.gitignore
  61. 22 0
      third-party/glog-0.3.5/AUTHORS
  62. 583 0
      third-party/glog-0.3.5/CMakeLists.txt
  63. 58 0
      third-party/glog-0.3.5/CONTRIBUTING.md
  64. 40 0
      third-party/glog-0.3.5/CONTRIBUTORS
  65. 65 0
      third-party/glog-0.3.5/COPYING
  66. 84 0
      third-party/glog-0.3.5/ChangeLog
  67. 297 0
      third-party/glog-0.3.5/INSTALL
  68. 249 0
      third-party/glog-0.3.5/Makefile.am
  69. 2071 0
      third-party/glog-0.3.5/Makefile.in
  70. 0 0
      third-party/glog-0.3.5/NEWS
  71. 5 0
      third-party/glog-0.3.5/README
  72. 26 0
      third-party/glog-0.3.5/README.windows
  73. 1193 0
      third-party/glog-0.3.5/aclocal.m4
  74. 69 0
      third-party/glog-0.3.5/cmake/DetermineGflagsNamespace.cmake
  75. 30 0
      third-party/glog-0.3.5/cmake/INSTALL.md
  76. 99 0
      third-party/glog-0.3.5/compile
  77. 1519 0
      third-party/glog-0.3.5/config.guess
  78. 1626 0
      third-party/glog-0.3.5/config.sub
  79. 20101 0
      third-party/glog-0.3.5/configure
  80. 236 0
      third-party/glog-0.3.5/configure.ac
  81. 589 0
      third-party/glog-0.3.5/depcomp
  82. 115 0
      third-party/glog-0.3.5/doc/designstyle.css
  83. 613 0
      third-party/glog-0.3.5/doc/glog.html
  84. 7 0
      third-party/glog-0.3.5/glog-config.cmake.in
  85. 44 0
      third-party/glog-0.3.5/google-glog.sln
  86. 519 0
      third-party/glog-0.3.5/install-sh
  87. 10 0
      third-party/glog-0.3.5/libglog.pc.in
  88. 9661 0
      third-party/glog-0.3.5/ltmain.sh
  89. 16 0
      third-party/glog-0.3.5/m4/ac_have_attribute.m4
  90. 14 0
      third-party/glog-0.3.5/m4/ac_have_builtin_expect.m4
  91. 14 0
      third-party/glog-0.3.5/m4/ac_have_sync_val_compare_and_swap.m4
  92. 31 0
      third-party/glog-0.3.5/m4/ac_rwlock.m4
  93. 363 0
      third-party/glog-0.3.5/m4/acx_pthread.m4
  94. 36 0
      third-party/glog-0.3.5/m4/google_namespace.m4
  95. 8001 0
      third-party/glog-0.3.5/m4/libtool.m4
  96. 384 0
      third-party/glog-0.3.5/m4/ltoptions.m4
  97. 123 0
      third-party/glog-0.3.5/m4/ltsugar.m4
  98. 23 0
      third-party/glog-0.3.5/m4/ltversion.m4
  99. 98 0
      third-party/glog-0.3.5/m4/lt~obsolete.m4
  100. 0 0
      third-party/glog-0.3.5/m4/namespaces.m4

+ 7 - 0
js/navigator/AppNavigators.js

@@ -5,10 +5,17 @@ import LoginPage from"../page/LoginPage"
 import register from "../page/register"
 import register1 from "../page/register1"
 import register2 from "../page/register2"
+import register3 from "../page/register3"
 import forgetPassWord from "../page/forgetPassWord"
 import HomePage from "../page/HomePage"
 
 const InitNavigator = createStackNavigator({
+    register3:{
+        screen:register3,
+        navigationOptions:{
+            headerTitle:"完善资料"
+        }
+    },
     register2:{
         screen:register2,
         navigationOptions:{

+ 61 - 0
js/page/register3.js

@@ -0,0 +1,61 @@
+import React, { Component } from "react"
+import { StyleSheet, Text, View, TextInput, Image } from "react-native"
+import AntDesign from "react-native-vector-icons/AntDesign"
+import RNPickerSelect from 'react-native-picker-select';
+import { unitWidth, unitHeight, getStatusBarHeight } from "../utils/AdapterUtil";
+import MyButtom from '../component/MyButton'
+
+export default class Loginpage extends Component {
+    render() {
+        return (
+            <View style={styles.container}>
+                <View style={{ width: unitWidth * 310, height: unitHeight * 295 }}>
+                    <Image
+                        source={require("../../static/uploadIcon.png")}
+                        style={{ width: "100%", height: "100%", resizeMode: "stretch" }}
+                    />
+                </View>
+                <Text style={styles.title}>请上传您的形象照</Text>
+                <Text style={styles.subTitle}>优质的照片,异性缘提升8.7倍</Text>
+                <View style={styles.bottomBtn}>
+                    <MyButtom
+                        text={"下一步"}
+                        width={unitWidth * 502}
+                        height={unitHeight * 84}
+                        borderRadius={unitHeight * 84}
+                        bgColor="#FA788A"
+                        shadowBgc="rgba(250,120,138,1)"
+                        style={{ fontSize: unitWidth * 32 }}
+                    />
+                </View>
+            </View>
+        )
+    }
+}
+const styles = StyleSheet.create({
+    container: {
+        flex: 1,
+        paddingTop: getStatusBarHeight() + unitHeight * 154,
+        paddingLeft: unitWidth * 60,
+        paddingRight: unitWidth * 60,
+        alignItems: "center"
+    },
+    title:{
+        color:"#FA788A",
+        fontSize:unitWidth * 28,
+        marginTop: unitHeight * 50,
+        marginBottom:unitHeight * 30,
+    },
+    subTitle:{
+        color:"#999999",
+        fontSize:unitWidth * 28
+    },
+    bottomBtn: {
+        width: "100%",
+        marginTop: unitHeight * 405,
+        height: unitHeight * 84,
+        justifyContent: 'center',
+        alignItems: 'center'
+    }
+
+})

二进制
static/uploadIcon.png


+ 3 - 0
third-party/double-conversion-1.1.6/.gitignore

@@ -0,0 +1,3 @@
+.sconsign.dblite
+run_tests
+*.o

+ 0 - 0
third-party/double-conversion-1.1.6/.installed


+ 13 - 0
third-party/double-conversion-1.1.6/AUTHORS

@@ -0,0 +1,13 @@
+# Below is a list of people and organizations that have contributed
+# to the double-conversion project.  Names should be added to the
+# list like so:
+#
+#   Name/Organization <email address>
+
+Google Inc.
+Mozilla Foundation
+
+Jeff Muizelaar <jmuizelaar@mozilla.com>
+Mike Hommey <mhommey@mozilla.com>
+Martin Olsson <mnemo@minimum.se>
+Kent Williams <chaircrusher@gmail.com>

+ 93 - 0
third-party/double-conversion-1.1.6/CMakeLists.txt

@@ -0,0 +1,93 @@
+cmake_minimum_required(VERSION 2.8)
+project(double-conversion)
+
+# pick a version #
+set(double-conversion_VERSION 1.1.5)
+set(double-conversion_SOVERSION_MAJOR 0)
+set(double-conversion_SOVERSION_MINOR 0)
+set(double-conversion_SOVERSION_PATCH 0)
+set(double-conversion_SOVERSION
+  ${double-conversion_SOVERSION_MAJOR}.${double-conversion_SOVERSION_MINOR}.${double-conversion_SOVERSION_PATCH})
+
+# set paths for install -- empty initially
+# Offer the user the choice of overriding the installation directories
+set(INSTALL_BIN_DIR CACHE PATH "Installation directory for libraries")
+set(INSTALL_LIB_DIR CACHE PATH "Installation directory for libraries")
+set(INSTALL_INCLUDE_DIR CACHE PATH "Installation directory for include")
+# set suffix for CMake files used for packaging
+if(WIN32 AND NOT CYGWIN)
+  set(INSTALL_CMAKE_DIR CMake)
+else()
+  set(INSTALL_CMAKE_DIR lib/CMake/double-conversion)
+endif()
+
+# Make relative paths absolute (needed later)
+foreach(p LIB BIN INCLUDE CMAKE)
+  set(var INSTALL_${p}_DIR)
+  if(NOT IS_ABSOLUTE "${${var}}")
+    set(${var} "${CMAKE_INSTALL_PREFIX}/${${var}}")
+  endif()
+endforeach()
+
+#
+# set up include dirs
+include_directories("${PROJECT_SOURCE_DIR}/src"
+  "${PROJECT_BINARY_DIR}"
+  )
+
+# Add src subdirectory
+add_subdirectory(src)
+
+#
+# set up testing if requested
+option(BUILD_TESTING "Build test programs" OFF)
+if(BUILD_TESTING)
+  enable_testing()
+  include(CTest)
+  add_subdirectory(test)
+endif()
+
+#
+# mention the library target as export library
+export(TARGETS double-conversion
+  FILE "${PROJECT_BINARY_DIR}/double-conversionLibraryDepends.cmake")
+
+#
+# set this build as an importable package
+export(PACKAGE double-conversion)
+
+#
+# make a cmake file -- in this case, all that needs defining
+# is double-conversion_INCLUDE_DIRS
+configure_file(double-conversionBuildTreeSettings.cmake.in
+  "${PROJECT_BINARY_DIR}/double-conversionBuildTreeSettings.cmake"
+  @ONLY)
+
+#
+# determine where include is relative to the CMake dir in
+# in installed tree
+file(RELATIVE_PATH CONF_REL_INCLUDE_DIR "${INSTALL_CMAKE_DIR}"
+  "${INSTALL_INCLUDE_DIR}")
+
+#
+# sets up config to be used by CMake find_package
+configure_file(double-conversionConfig.cmake.in
+  "${PROJECT_BINARY_DIR}/double-conversionConfig.cmake"
+  @ONLY)
+#
+# Export version # checked by find_package
+configure_file(double-conversionConfigVersion.cmake.in
+  "${PROJECT_BINARY_DIR}/double-conversionConfigVersion.cmake"
+  @ONLY)
+#
+# install config files for find_package
+install(FILES
+  "${PROJECT_BINARY_DIR}/double-conversionConfig.cmake"
+  "${PROJECT_BINARY_DIR}/double-conversionConfigVersion.cmake"
+  DESTINATION "${INSTALL_CMAKE_DIR}" COMPONENT dev)
+
+
+#
+# generates install cmake files to find libraries in installation.
+install(EXPORT double-conversionLibraryDepends DESTINATION
+  "${INSTALL_CMAKE_DIR}" COMPONENT dev)

+ 26 - 0
third-party/double-conversion-1.1.6/COPYING

@@ -0,0 +1,26 @@
+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.

+ 38 - 0
third-party/double-conversion-1.1.6/Changelog

@@ -0,0 +1,38 @@
+2014-03-08:
+  Update version number for cmake.
+  Support shared libraries with cmake.
+  Add build instructions to the README.
+
+2014-01-12:
+  Tagged v1.1.5.
+  Enabled shared libraries in v1.1 branch.
+
+2014-01-12:
+  Tagged v1.1.4.
+  Backported SConstruct improvements.
+
+2014-01-12:
+  Tagged v1.1.3.
+  Backported warning fixes from 2.0 branch.
+
+2013-12-23:
+  Fix compilation for ARMv8 64bit (used wrong define).
+
+2013-11-09:
+  Tagged v1.1.2.
+  Add support for ARM 64 and OsX ppc.
+  Rewrite tests so they pass under Visual Studio.
+  Add CMake build system support.
+  Fix warnings.
+
+2012-06-10:
+  Tagged v1.1.1.
+  Null terminate exponent buffer (only an issue when asserts are enabled).
+  Support more architectures.
+
+2012-02-05:
+  Merged in Single-branch with single-precision support.
+  Tagged v1.1 (based on b28450f33e1db493948a535d8f84e88fa211bd10).
+
+2012-02-05:
+  Tagged v1.0 (based on eda0196e9ac8fcdf59e92cb62885ee0af5391969).

+ 26 - 0
third-party/double-conversion-1.1.6/LICENSE

@@ -0,0 +1,26 @@
+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.

+ 7 - 0
third-party/double-conversion-1.1.6/Makefile

@@ -0,0 +1,7 @@
+all:
+	scons debug=1
+
+test:
+	./run_tests --list | tr -d '<' | xargs ./run_tests
+
+.PHONY: test all

+ 54 - 0
third-party/double-conversion-1.1.6/README

@@ -0,0 +1,54 @@
+http://code.google.com/p/double-conversion
+
+This project (double-conversion) provides binary-decimal and decimal-binary
+routines for IEEE doubles.
+
+The library consists of efficient conversion routines that have been extracted
+from the V8 JavaScript engine. The code has been refactored and improved so that
+it can be used more easily in other projects.
+
+There is extensive documentation in src/double-conversion.h. Other examples can
+be found in test/cctest/test-conversions.cc.
+
+
+Building
+========
+
+This library can be built with scons [0] or cmake [1].
+The checked-in Makefile simply forwards to scons, and provides a
+shortcut to run all tests:
+
+    make
+    make test
+
+Scons
+-----
+
+The easiest way to install this library is to use `scons`. It builds
+the static and shared library, and is set up to install those at the
+correct locations:
+
+    scons install
+
+Use the `DESTDIR` option to change the target directory:
+
+    scons DESTDIR=alternative_directory install
+
+Cmake
+-----
+
+To use cmake run `cmake .` in the root directory. This overwrites the
+existing Makefile.
+
+Use `-DBUILD_SHARED_LIBS=ON` to enable the compilation of shared libraries.
+Note that this disables static libraries. There is currently no way to
+build both libraries at the same time with cmake.
+
+Use `-DBUILD_TESTING=ON` to build the test executable.
+
+    cmake . -DBUILD_TESTING=ON
+    make
+    test/cctest/cctest --list | tr -d '<' | xargs test/cctest/cctest
+
+[0]: http://www.scons.org
+[1]: http://www.cmake.org

+ 46 - 0
third-party/double-conversion-1.1.6/SConstruct

@@ -0,0 +1,46 @@
+# vim:ft=python
+import os
+
+double_conversion_sources = ['src/' + x for x in SConscript('src/SConscript')]
+double_conversion_test_sources = ['test/cctest/' + x for x in SConscript('test/cctest/SConscript')]
+
+DESTDIR = ARGUMENTS.get('DESTDIR', '')
+prefix = ARGUMENTS.get('prefix', '/usr/local')
+lib = ARGUMENTS.get('libsuffix', 'lib')
+libdir = os.path.join(DESTDIR + prefix, lib)
+
+env = Environment(CPPPATH='#/src', LIBS=['m', 'stdc++'],
+    CXXFLAGS=ARGUMENTS.get('CXXFLAGS', ''))
+debug = ARGUMENTS.get('debug', 0)
+optimize = ARGUMENTS.get('optimize', 0)
+env.Replace(CXX = ARGUMENTS.get('CXX', 'g++'))
+
+# for shared lib, requires scons 2.3.0
+env['SHLIBVERSION'] = '0.0.0'
+
+CCFLAGS = []
+if int(debug):
+  CCFLAGS.append(ARGUMENTS.get('CXXFLAGS', '-g -Wall -Werror'))
+if int(optimize):
+  CCFLAGS.append(ARGUMENTS.get('CXXFLAGS', '-O3'))
+
+env.Append(CCFLAGS = " ".join(CCFLAGS))
+
+double_conversion_shared_objects = [
+    env.SharedObject(src) for src in double_conversion_sources]
+double_conversion_static_objects = [
+    env.StaticObject(src) for src in double_conversion_sources]
+
+library_name = 'double-conversion'
+
+static_lib = env.StaticLibrary(library_name, double_conversion_static_objects)
+static_lib_pic = env.StaticLibrary(library_name + '_pic', double_conversion_shared_objects)
+shared_lib = env.SharedLibrary(library_name, double_conversion_shared_objects)
+
+env.Program('run_tests', double_conversion_test_sources, LIBS=[static_lib])
+
+env.InstallVersionedLib(libdir, shared_lib)
+env.Install(libdir, static_lib)
+env.Install(libdir, static_lib_pic)
+
+env.Alias('install', libdir)

+ 2 - 0
third-party/double-conversion-1.1.6/double-conversionBuildTreeSettings.cmake.in

@@ -0,0 +1,2 @@
+set(double-conversion_INCLUDE_DIRS
+  "@PROJECT_SOURCE_DIR@/src")

+ 17 - 0
third-party/double-conversion-1.1.6/double-conversionConfig.cmake.in

@@ -0,0 +1,17 @@
+# - Config file for the double-conversion package
+# It defines the following variables
+# double-conversion_INCLUDE_DIRS
+# double-conversion_LIBRARIES
+
+get_filename_component(double-conversion_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
+
+if(EXISTS "${double-conversion_CMAKE_DIR}/CMakeCache.txt")
+  include("${double-conversion_CMAKE_DIR}/double-conversionBuildTreeSettings.cmake")
+else()
+  set(double-conversion_INCLUDE_DIRS
+    "${double-conversion_CMAKE_DIR}/@CONF_REL_INCLUDE_DIR@/include/double-conversion")
+endif()
+
+include("${double-conversion_CMAKE_DIR}/double-conversionLibraryDepends.cmake")
+
+set(double-conversion_LIBRARIES double-conversion)

+ 11 - 0
third-party/double-conversion-1.1.6/double-conversionConfigVersion.cmake.in

@@ -0,0 +1,11 @@
+set(PACKAGE_VERSION "@double-conversion_VERSION@")
+ 
+# Check whether the requested PACKAGE_FIND_VERSION is compatible
+if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}")
+  set(PACKAGE_VERSION_COMPATIBLE FALSE)
+else()
+  set(PACKAGE_VERSION_COMPATIBLE TRUE)
+  if ("${PACKAGE_VERSION}" VERSION_EQUAL "${PACKAGE_FIND_VERSION}")
+    set(PACKAGE_VERSION_EXACT TRUE)
+  endif()
+endif()

+ 48 - 0
third-party/double-conversion-1.1.6/src/CMakeLists.txt

@@ -0,0 +1,48 @@
+
+set(headers
+  bignum.h
+  cached-powers.h
+  diy-fp.h
+  double-conversion.h
+  fast-dtoa.h
+  fixed-dtoa.h
+  ieee.h
+  strtod.h
+  utils.h
+  )
+
+add_library(double-conversion
+bignum.cc
+bignum-dtoa.cc
+cached-powers.cc
+diy-fp.cc
+double-conversion.cc
+fast-dtoa.cc
+fixed-dtoa.cc
+strtod.cc
+${headers}
+)
+
+#
+# associates the list of headers with the library
+# for the purposes of installation/import into other projects
+set_target_properties(double-conversion
+    PROPERTIES PUBLIC_HEADER "${headers}")
+
+if (BUILD_SHARED_LIBS)
+  set_target_properties(double-conversion
+    PROPERTIES VERSION ${double-conversion_SOVERSION}
+               SOVERSION ${double-conversion_SOVERSION_MAJOR})
+endif()
+
+#
+# install command to set up library install
+# given the above PUBLIC_HEADER property set, this
+# pulls along all the header files with the library.
+install(TARGETS double-conversion
+  EXPORT double-conversionLibraryDepends
+  RUNTIME DESTINATION "${INSTALL_BIN_DIR}" COMPONENT bin
+  LIBRARY DESTINATION "${INSTALL_LIB_DIR}/lib" COMPONENT shlib
+  ARCHIVE DESTINATION "${INSTALL_LIB_DIR}/lib" COMPONENT lib
+  PUBLIC_HEADER DESTINATION "${INSTALL_INCLUDE_DIR}/include/double-conversion"
+  COMPONENT dev)

+ 12 - 0
third-party/double-conversion-1.1.6/src/SConscript

@@ -0,0 +1,12 @@
+# -*- coding: utf-8 -*-
+double_conversion_sources = [
+    'bignum.cc',
+    'bignum-dtoa.cc',
+    'cached-powers.cc',
+    'diy-fp.cc',
+    'double-conversion.cc',
+    'fast-dtoa.cc',
+    'fixed-dtoa.cc',
+    'strtod.cc'
+  ]
+Return('double_conversion_sources')

+ 641 - 0
third-party/double-conversion-1.1.6/src/bignum-dtoa.cc

@@ -0,0 +1,641 @@
+// 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 <math.h>
+
+#include "bignum-dtoa.h"
+
+#include "bignum.h"
+#include "ieee.h"
+
+namespace double_conversion {
+
+static int NormalizedExponent(uint64_t significand, int exponent) {
+  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) {
+  ASSERT(v > 0);
+  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);
+    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.
+  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:
+      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);
+    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.
+        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 {
+          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 ASSERT here, in case the preconditions were not
+      // satisfied.
+      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) {
+  ASSERT(count >= 0);
+  for (int i = 0; i < count - 1; ++i) {
+    uint16_t digit;
+    digit = numerator->DivideModuloIntBignum(*denominator);
+    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++;
+  }
+  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.
+    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.
+  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.
+  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 GenerateShortestDigits to decide if it has the shortest
+//  decimal converting back to v):
+//  - v - m-: the distance to the lower boundary.
+//  - m+ - v: the distance to the upper boundary.
+//
+// v, m+, m-, and therefore v - m- and m+ - v all share the same denominator.
+//
+// Let ep == estimated_power, then the returned values will satisfy:
+//  v / 10^ep = numerator / denominator.
+//  v's boundarys m- and m+:
+//    m- / 10^ep == v / 10^ep - delta_minus / denominator
+//    m+ / 10^ep == v / 10^ep + delta_plus / denominator
+//  Or in other words:
+//    m- == v - delta_minus * 10^ep / denominator;
+//    m+ == v + delta_plus * 10^ep / denominator;
+//
+// Since 10^(k-1) <= v < 10^k    (with k == estimated_power)
+//  or       10^k <= v < 10^(k+1)
+//  we then have 0.1 <= numerator/denominator < 1
+//           or    1 <= numerator/denominator < 10
+//
+// It is then easy to kickstart the digit-generation routine.
+//
+// The boundary-deltas are only filled if the mode equals BIGNUM_DTOA_SHORTEST
+// or BIGNUM_DTOA_SHORTEST_SINGLE.
+
+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) {
+  if (exponent >= 0) {
+    InitialScaledStartValuesPositiveExponent(
+        significand, exponent, estimated_power, need_boundary_deltas,
+        numerator, denominator, delta_minus, delta_plus);
+  } else if (estimated_power >= 0) {
+    InitialScaledStartValuesNegativeExponentPositivePower(
+        significand, exponent, estimated_power, need_boundary_deltas,
+        numerator, denominator, delta_minus, delta_plus);
+  } else {
+    InitialScaledStartValuesNegativeExponentNegativePower(
+        significand, exponent, estimated_power, need_boundary_deltas,
+        numerator, denominator, delta_minus, delta_plus);
+  }
+
+  if (need_boundary_deltas && lower_boundary_is_closer) {
+    // The lower boundary is closer at half the distance of "normal" numbers.
+    // Increase the common denominator and adapt all but the delta_minus.
+    denominator->ShiftLeft(1);  // *2
+    numerator->ShiftLeft(1);    // *2
+    delta_plus->ShiftLeft(1);   // *2
+  }
+}
+
+
+// This routine multiplies numerator/denominator so that its values lies in the
+// range 1-10. That is after a call to this function we have:
+//    1 <= (numerator + delta_plus) /denominator < 10.
+// Let numerator the input before modification and numerator' the argument
+// after modification, then the output-parameter decimal_point is such that
+//  numerator / denominator * 10^estimated_power ==
+//    numerator' / denominator' * 10^(decimal_point - 1)
+// In some cases estimated_power was too low, and this is already the case. We
+// then simply adjust the power so that 10^(k-1) <= v < 10^k (with k ==
+// estimated_power) but do not touch the numerator or denominator.
+// Otherwise the routine multiplies the numerator and the deltas by 10.
+static void FixupMultiply10(int estimated_power, bool is_even,
+                            int* decimal_point,
+                            Bignum* numerator, Bignum* denominator,
+                            Bignum* delta_minus, Bignum* delta_plus) {
+  bool in_range;
+  if (is_even) {
+    // For IEEE doubles half-way cases (in decimal system numbers ending with 5)
+    // are rounded to the closest floating-point number with even significand.
+    in_range = Bignum::PlusCompare(*numerator, *delta_plus, *denominator) >= 0;
+  } else {
+    in_range = Bignum::PlusCompare(*numerator, *delta_plus, *denominator) > 0;
+  }
+  if (in_range) {
+    // Since numerator + delta_plus >= denominator we already have
+    // 1 <= numerator/denominator < 10. Simply update the estimated_power.
+    *decimal_point = estimated_power + 1;
+  } else {
+    *decimal_point = estimated_power;
+    numerator->Times10();
+    if (Bignum::Equal(*delta_minus, *delta_plus)) {
+      delta_minus->Times10();
+      delta_plus->AssignBignum(*delta_minus);
+    } else {
+      delta_minus->Times10();
+      delta_plus->Times10();
+    }
+  }
+}
+
+}  // namespace double_conversion

+ 84 - 0
third-party/double-conversion-1.1.6/src/bignum-dtoa.h

@@ -0,0 +1,84 @@
+// 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.
+
+#ifndef DOUBLE_CONVERSION_BIGNUM_DTOA_H_
+#define DOUBLE_CONVERSION_BIGNUM_DTOA_H_
+
+#include "utils.h"
+
+namespace double_conversion {
+
+enum BignumDtoaMode {
+  // Return the shortest correct representation.
+  // For example the output of 0.299999999999999988897 is (the less accurate but
+  // correct) 0.3.
+  BIGNUM_DTOA_SHORTEST,
+  // Same as BIGNUM_DTOA_SHORTEST but for single-precision floats.
+  BIGNUM_DTOA_SHORTEST_SINGLE,
+  // Return a fixed number of digits after the decimal point.
+  // For instance fixed(0.1, 4) becomes 0.1000
+  // If the input number is big, the output will be big.
+  BIGNUM_DTOA_FIXED,
+  // Return a fixed number of digits, no matter what the exponent is.
+  BIGNUM_DTOA_PRECISION
+};
+
+// Converts the given double 'v' to ascii.
+// The result should be interpreted as buffer * 10^(point-length).
+// The buffer will be null-terminated.
+//
+// The input v must be > 0 and different from NaN, and Infinity.
+//
+// The output depends on the given mode:
+//  - SHORTEST: produce the least amount of digits for which the internal
+//   identity requirement is still satisfied. If the digits are printed
+//   (together with the correct exponent) then reading this number will give
+//   'v' again. The buffer will choose the representation that is closest to
+//   'v'. If there are two at the same distance, than the number is round up.
+//   In this mode the 'requested_digits' parameter is ignored.
+//  - FIXED: produces digits necessary to print a given number with
+//   'requested_digits' digits after the decimal point. The produced digits
+//   might be too short in which case the caller has to fill the gaps with '0's.
+//   Example: toFixed(0.001, 5) is allowed to return buffer="1", point=-2.
+//   Halfway cases are rounded up. The call toFixed(0.15, 2) thus returns
+//     buffer="2", point=0.
+//   Note: the length of the returned buffer has no meaning wrt the significance
+//   of its digits. That is, just because it contains '0's does not mean that
+//   any other digit would not satisfy the internal identity requirement.
+//  - PRECISION: produces 'requested_digits' where the first digit is not '0'.
+//   Even though the length of produced digits usually equals
+//   'requested_digits', the function is allowed to return fewer digits, in
+//   which case the caller has to fill the missing digits with '0's.
+//   Halfway cases are again rounded up.
+// 'BignumDtoa' expects the given buffer to be big enough to hold all digits
+// and a terminating null-character.
+void BignumDtoa(double v, BignumDtoaMode mode, int requested_digits,
+                Vector<char> buffer, int* length, int* point);
+
+}  // namespace double_conversion
+
+#endif  // DOUBLE_CONVERSION_BIGNUM_DTOA_H_

+ 766 - 0
third-party/double-conversion-1.1.6/src/bignum.cc

@@ -0,0 +1,766 @@
+// 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 "bignum.h"
+#include "utils.h"
+
+namespace double_conversion {
+
+Bignum::Bignum()
+    : bigits_(bigits_buffer_, kBigitCapacity), used_digits_(0), exponent_(0) {
+  for (int i = 0; i < kBigitCapacity; ++i) {
+    bigits_[i] = 0;
+  }
+}
+
+
+template<typename S>
+static int BitSize(S value) {
+  (void) value;  // Mark variable as used.
+  return 8 * sizeof(value);
+}
+
+// Guaranteed to lie in one Bigit.
+void Bignum::AssignUInt16(uint16_t value) {
+  ASSERT(kBigitSize >= BitSize(value));
+  Zero();
+  if (value == 0) return;
+
+  EnsureCapacity(1);
+  bigits_[0] = value;
+  used_digits_ = 1;
+}
+
+
+void Bignum::AssignUInt64(uint64_t value) {
+  const int kUInt64Size = 64;
+
+  Zero();
+  if (value == 0) return;
+
+  int needed_bigits = kUInt64Size / kBigitSize + 1;
+  EnsureCapacity(needed_bigits);
+  for (int i = 0; i < needed_bigits; ++i) {
+    bigits_[i] = value & kBigitMask;
+    value = value >> kBigitSize;
+  }
+  used_digits_ = needed_bigits;
+  Clamp();
+}
+
+
+void Bignum::AssignBignum(const Bignum& other) {
+  exponent_ = other.exponent_;
+  for (int i = 0; i < other.used_digits_; ++i) {
+    bigits_[i] = other.bigits_[i];
+  }
+  // Clear the excess digits (if there were any).
+  for (int i = other.used_digits_; i < used_digits_; ++i) {
+    bigits_[i] = 0;
+  }
+  used_digits_ = other.used_digits_;
+}
+
+
+static uint64_t ReadUInt64(Vector<const char> buffer,
+                           int from,
+                           int digits_to_read) {
+  uint64_t result = 0;
+  for (int i = from; i < from + digits_to_read; ++i) {
+    int digit = buffer[i] - '0';
+    ASSERT(0 <= digit && digit <= 9);
+    result = result * 10 + digit;
+  }
+  return result;
+}
+
+
+void Bignum::AssignDecimalString(Vector<const char> value) {
+  // 2^64 = 18446744073709551616 > 10^19
+  const int kMaxUint64DecimalDigits = 19;
+  Zero();
+  int length = value.length();
+  int pos = 0;
+  // Let's just say that each digit needs 4 bits.
+  while (length >= kMaxUint64DecimalDigits) {
+    uint64_t digits = ReadUInt64(value, pos, kMaxUint64DecimalDigits);
+    pos += kMaxUint64DecimalDigits;
+    length -= kMaxUint64DecimalDigits;
+    MultiplyByPowerOfTen(kMaxUint64DecimalDigits);
+    AddUInt64(digits);
+  }
+  uint64_t digits = ReadUInt64(value, pos, length);
+  MultiplyByPowerOfTen(length);
+  AddUInt64(digits);
+  Clamp();
+}
+
+
+static int HexCharValue(char c) {
+  if ('0' <= c && c <= '9') return c - '0';
+  if ('a' <= c && c <= 'f') return 10 + c - 'a';
+  ASSERT('A' <= c && c <= 'F');
+  return 10 + c - 'A';
+}
+
+
+void Bignum::AssignHexString(Vector<const char> value) {
+  Zero();
+  int length = value.length();
+
+  int needed_bigits = length * 4 / kBigitSize + 1;
+  EnsureCapacity(needed_bigits);
+  int string_index = length - 1;
+  for (int i = 0; i < needed_bigits - 1; ++i) {
+    // These bigits are guaranteed to be "full".
+    Chunk current_bigit = 0;
+    for (int j = 0; j < kBigitSize / 4; j++) {
+      current_bigit += HexCharValue(value[string_index--]) << (j * 4);
+    }
+    bigits_[i] = current_bigit;
+  }
+  used_digits_ = needed_bigits - 1;
+
+  Chunk most_significant_bigit = 0;  // Could be = 0;
+  for (int j = 0; j <= string_index; ++j) {
+    most_significant_bigit <<= 4;
+    most_significant_bigit += HexCharValue(value[j]);
+  }
+  if (most_significant_bigit != 0) {
+    bigits_[used_digits_] = most_significant_bigit;
+    used_digits_++;
+  }
+  Clamp();
+}
+
+
+void Bignum::AddUInt64(uint64_t operand) {
+  if (operand == 0) return;
+  Bignum other;
+  other.AssignUInt64(operand);
+  AddBignum(other);
+}
+
+
+void Bignum::AddBignum(const Bignum& other) {
+  ASSERT(IsClamped());
+  ASSERT(other.IsClamped());
+
+  // If this has a greater exponent than other append zero-bigits to this.
+  // After this call exponent_ <= other.exponent_.
+  Align(other);
+
+  // There are two possibilities:
+  //   aaaaaaaaaaa 0000  (where the 0s represent a's exponent)
+  //     bbbbb 00000000
+  //   ----------------
+  //   ccccccccccc 0000
+  // or
+  //    aaaaaaaaaa 0000
+  //  bbbbbbbbb 0000000
+  //  -----------------
+  //  cccccccccccc 0000
+  // In both cases we might need a carry bigit.
+
+  EnsureCapacity(1 + Max(BigitLength(), other.BigitLength()) - exponent_);
+  Chunk carry = 0;
+  int bigit_pos = other.exponent_ - exponent_;
+  ASSERT(bigit_pos >= 0);
+  for (int i = 0; i < other.used_digits_; ++i) {
+    Chunk sum = bigits_[bigit_pos] + other.bigits_[i] + carry;
+    bigits_[bigit_pos] = sum & kBigitMask;
+    carry = sum >> kBigitSize;
+    bigit_pos++;
+  }
+
+  while (carry != 0) {
+    Chunk sum = bigits_[bigit_pos] + carry;
+    bigits_[bigit_pos] = sum & kBigitMask;
+    carry = sum >> kBigitSize;
+    bigit_pos++;
+  }
+  used_digits_ = Max(bigit_pos, used_digits_);
+  ASSERT(IsClamped());
+}
+
+
+void Bignum::SubtractBignum(const Bignum& other) {
+  ASSERT(IsClamped());
+  ASSERT(other.IsClamped());
+  // We require this to be bigger than other.
+  ASSERT(LessEqual(other, *this));
+
+  Align(other);
+
+  int offset = other.exponent_ - exponent_;
+  Chunk borrow = 0;
+  int i;
+  for (i = 0; i < other.used_digits_; ++i) {
+    ASSERT((borrow == 0) || (borrow == 1));
+    Chunk difference = bigits_[i + offset] - other.bigits_[i] - borrow;
+    bigits_[i + offset] = difference & kBigitMask;
+    borrow = difference >> (kChunkSize - 1);
+  }
+  while (borrow != 0) {
+    Chunk difference = bigits_[i + offset] - borrow;
+    bigits_[i + offset] = difference & kBigitMask;
+    borrow = difference >> (kChunkSize - 1);
+    ++i;
+  }
+  Clamp();
+}
+
+
+void Bignum::ShiftLeft(int shift_amount) {
+  if (used_digits_ == 0) return;
+  exponent_ += shift_amount / kBigitSize;
+  int local_shift = shift_amount % kBigitSize;
+  EnsureCapacity(used_digits_ + 1);
+  BigitsShiftLeft(local_shift);
+}
+
+
+void Bignum::MultiplyByUInt32(uint32_t factor) {
+  if (factor == 1) return;
+  if (factor == 0) {
+    Zero();
+    return;
+  }
+  if (used_digits_ == 0) return;
+
+  // The product of a bigit with the factor is of size kBigitSize + 32.
+  // Assert that this number + 1 (for the carry) fits into double chunk.
+  ASSERT(kDoubleChunkSize >= kBigitSize + 32 + 1);
+  DoubleChunk carry = 0;
+  for (int i = 0; i < used_digits_; ++i) {
+    DoubleChunk product = static_cast<DoubleChunk>(factor) * bigits_[i] + carry;
+    bigits_[i] = static_cast<Chunk>(product & kBigitMask);
+    carry = (product >> kBigitSize);
+  }
+  while (carry != 0) {
+    EnsureCapacity(used_digits_ + 1);
+    bigits_[used_digits_] = carry & kBigitMask;
+    used_digits_++;
+    carry >>= kBigitSize;
+  }
+}
+
+
+void Bignum::MultiplyByUInt64(uint64_t factor) {
+  if (factor == 1) return;
+  if (factor == 0) {
+    Zero();
+    return;
+  }
+  ASSERT(kBigitSize < 32);
+  uint64_t carry = 0;
+  uint64_t low = factor & 0xFFFFFFFF;
+  uint64_t high = factor >> 32;
+  for (int i = 0; i < used_digits_; ++i) {
+    uint64_t product_low = low * bigits_[i];
+    uint64_t product_high = high * bigits_[i];
+    uint64_t tmp = (carry & kBigitMask) + product_low;
+    bigits_[i] = tmp & kBigitMask;
+    carry = (carry >> kBigitSize) + (tmp >> kBigitSize) +
+        (product_high << (32 - kBigitSize));
+  }
+  while (carry != 0) {
+    EnsureCapacity(used_digits_ + 1);
+    bigits_[used_digits_] = carry & kBigitMask;
+    used_digits_++;
+    carry >>= kBigitSize;
+  }
+}
+
+
+void Bignum::MultiplyByPowerOfTen(int exponent) {
+  const uint64_t kFive27 = UINT64_2PART_C(0x6765c793, fa10079d);
+  const uint16_t kFive1 = 5;
+  const uint16_t kFive2 = kFive1 * 5;
+  const uint16_t kFive3 = kFive2 * 5;
+  const uint16_t kFive4 = kFive3 * 5;
+  const uint16_t kFive5 = kFive4 * 5;
+  const uint16_t kFive6 = kFive5 * 5;
+  const uint32_t kFive7 = kFive6 * 5;
+  const uint32_t kFive8 = kFive7 * 5;
+  const uint32_t kFive9 = kFive8 * 5;
+  const uint32_t kFive10 = kFive9 * 5;
+  const uint32_t kFive11 = kFive10 * 5;
+  const uint32_t kFive12 = kFive11 * 5;
+  const uint32_t kFive13 = kFive12 * 5;
+  const uint32_t kFive1_to_12[] =
+      { kFive1, kFive2, kFive3, kFive4, kFive5, kFive6,
+        kFive7, kFive8, kFive9, kFive10, kFive11, kFive12 };
+
+  ASSERT(exponent >= 0);
+  if (exponent == 0) return;
+  if (used_digits_ == 0) return;
+
+  // We shift by exponent at the end just before returning.
+  int remaining_exponent = exponent;
+  while (remaining_exponent >= 27) {
+    MultiplyByUInt64(kFive27);
+    remaining_exponent -= 27;
+  }
+  while (remaining_exponent >= 13) {
+    MultiplyByUInt32(kFive13);
+    remaining_exponent -= 13;
+  }
+  if (remaining_exponent > 0) {
+    MultiplyByUInt32(kFive1_to_12[remaining_exponent - 1]);
+  }
+  ShiftLeft(exponent);
+}
+
+
+void Bignum::Square() {
+  ASSERT(IsClamped());
+  int product_length = 2 * used_digits_;
+  EnsureCapacity(product_length);
+
+  // Comba multiplication: compute each column separately.
+  // Example: r = a2a1a0 * b2b1b0.
+  //    r =  1    * a0b0 +
+  //        10    * (a1b0 + a0b1) +
+  //        100   * (a2b0 + a1b1 + a0b2) +
+  //        1000  * (a2b1 + a1b2) +
+  //        10000 * a2b2
+  //
+  // In the worst case we have to accumulate nb-digits products of digit*digit.
+  //
+  // Assert that the additional number of bits in a DoubleChunk are enough to
+  // sum up used_digits of Bigit*Bigit.
+  if ((1 << (2 * (kChunkSize - kBigitSize))) <= used_digits_) {
+    UNIMPLEMENTED();
+  }
+  DoubleChunk accumulator = 0;
+  // First shift the digits so we don't overwrite them.
+  int copy_offset = used_digits_;
+  for (int i = 0; i < used_digits_; ++i) {
+    bigits_[copy_offset + i] = bigits_[i];
+  }
+  // We have two loops to avoid some 'if's in the loop.
+  for (int i = 0; i < used_digits_; ++i) {
+    // Process temporary digit i with power i.
+    // The sum of the two indices must be equal to i.
+    int bigit_index1 = i;
+    int bigit_index2 = 0;
+    // Sum all of the sub-products.
+    while (bigit_index1 >= 0) {
+      Chunk chunk1 = bigits_[copy_offset + bigit_index1];
+      Chunk chunk2 = bigits_[copy_offset + bigit_index2];
+      accumulator += static_cast<DoubleChunk>(chunk1) * chunk2;
+      bigit_index1--;
+      bigit_index2++;
+    }
+    bigits_[i] = static_cast<Chunk>(accumulator) & kBigitMask;
+    accumulator >>= kBigitSize;
+  }
+  for (int i = used_digits_; i < product_length; ++i) {
+    int bigit_index1 = used_digits_ - 1;
+    int bigit_index2 = i - bigit_index1;
+    // Invariant: sum of both indices is again equal to i.
+    // Inner loop runs 0 times on last iteration, emptying accumulator.
+    while (bigit_index2 < used_digits_) {
+      Chunk chunk1 = bigits_[copy_offset + bigit_index1];
+      Chunk chunk2 = bigits_[copy_offset + bigit_index2];
+      accumulator += static_cast<DoubleChunk>(chunk1) * chunk2;
+      bigit_index1--;
+      bigit_index2++;
+    }
+    // The overwritten bigits_[i] will never be read in further loop iterations,
+    // because bigit_index1 and bigit_index2 are always greater
+    // than i - used_digits_.
+    bigits_[i] = static_cast<Chunk>(accumulator) & kBigitMask;
+    accumulator >>= kBigitSize;
+  }
+  // Since the result was guaranteed to lie inside the number the
+  // accumulator must be 0 now.
+  ASSERT(accumulator == 0);
+
+  // Don't forget to update the used_digits and the exponent.
+  used_digits_ = product_length;
+  exponent_ *= 2;
+  Clamp();
+}
+
+
+void Bignum::AssignPowerUInt16(uint16_t base, int power_exponent) {
+  ASSERT(base != 0);
+  ASSERT(power_exponent >= 0);
+  if (power_exponent == 0) {
+    AssignUInt16(1);
+    return;
+  }
+  Zero();
+  int shifts = 0;
+  // We expect base to be in range 2-32, and most often to be 10.
+  // It does not make much sense to implement different algorithms for counting
+  // the bits.
+  while ((base & 1) == 0) {
+    base >>= 1;
+    shifts++;
+  }
+  int bit_size = 0;
+  int tmp_base = base;
+  while (tmp_base != 0) {
+    tmp_base >>= 1;
+    bit_size++;
+  }
+  int final_size = bit_size * power_exponent;
+  // 1 extra bigit for the shifting, and one for rounded final_size.
+  EnsureCapacity(final_size / kBigitSize + 2);
+
+  // Left to Right exponentiation.
+  int mask = 1;
+  while (power_exponent >= mask) mask <<= 1;
+
+  // The mask is now pointing to the bit above the most significant 1-bit of
+  // power_exponent.
+  // Get rid of first 1-bit;
+  mask >>= 2;
+  uint64_t this_value = base;
+
+  bool delayed_multipliciation = false;
+  const uint64_t max_32bits = 0xFFFFFFFF;
+  while (mask != 0 && this_value <= max_32bits) {
+    this_value = this_value * this_value;
+    // Verify that there is enough space in this_value to perform the
+    // multiplication.  The first bit_size bits must be 0.
+    if ((power_exponent & mask) != 0) {
+      uint64_t base_bits_mask =
+          ~((static_cast<uint64_t>(1) << (64 - bit_size)) - 1);
+      bool high_bits_zero = (this_value & base_bits_mask) == 0;
+      if (high_bits_zero) {
+        this_value *= base;
+      } else {
+        delayed_multipliciation = true;
+      }
+    }
+    mask >>= 1;
+  }
+  AssignUInt64(this_value);
+  if (delayed_multipliciation) {
+    MultiplyByUInt32(base);
+  }
+
+  // Now do the same thing as a bignum.
+  while (mask != 0) {
+    Square();
+    if ((power_exponent & mask) != 0) {
+      MultiplyByUInt32(base);
+    }
+    mask >>= 1;
+  }
+
+  // And finally add the saved shifts.
+  ShiftLeft(shifts * power_exponent);
+}
+
+
+// Precondition: this/other < 16bit.
+uint16_t Bignum::DivideModuloIntBignum(const Bignum& other) {
+  ASSERT(IsClamped());
+  ASSERT(other.IsClamped());
+  ASSERT(other.used_digits_ > 0);
+
+  // Easy case: if we have less digits than the divisor than the result is 0.
+  // Note: this handles the case where this == 0, too.
+  if (BigitLength() < other.BigitLength()) {
+    return 0;
+  }
+
+  Align(other);
+
+  uint16_t result = 0;
+
+  // Start by removing multiples of 'other' until both numbers have the same
+  // number of digits.
+  while (BigitLength() > other.BigitLength()) {
+    // This naive approach is extremely inefficient if `this` divided by other
+    // is big. This function is implemented for doubleToString where
+    // the result should be small (less than 10).
+    ASSERT(other.bigits_[other.used_digits_ - 1] >= ((1 << kBigitSize) / 16));
+    ASSERT(bigits_[used_digits_ - 1] < 0x10000);
+    // Remove the multiples of the first digit.
+    // Example this = 23 and other equals 9. -> Remove 2 multiples.
+    result += static_cast<uint16_t>(bigits_[used_digits_ - 1]);
+    SubtractTimes(other, bigits_[used_digits_ - 1]);
+  }
+
+  ASSERT(BigitLength() == other.BigitLength());
+
+  // Both bignums are at the same length now.
+  // Since other has more than 0 digits we know that the access to
+  // bigits_[used_digits_ - 1] is safe.
+  Chunk this_bigit = bigits_[used_digits_ - 1];
+  Chunk other_bigit = other.bigits_[other.used_digits_ - 1];
+
+  if (other.used_digits_ == 1) {
+    // Shortcut for easy (and common) case.
+    int quotient = this_bigit / other_bigit;
+    bigits_[used_digits_ - 1] = this_bigit - other_bigit * quotient;
+    ASSERT(quotient < 0x10000);
+    result += static_cast<uint16_t>(quotient);
+    Clamp();
+    return result;
+  }
+
+  int division_estimate = this_bigit / (other_bigit + 1);
+  ASSERT(division_estimate < 0x10000);
+  result += static_cast<uint16_t>(division_estimate);
+  SubtractTimes(other, division_estimate);
+
+  if (other_bigit * (division_estimate + 1) > this_bigit) {
+    // No need to even try to subtract. Even if other's remaining digits were 0
+    // another subtraction would be too much.
+    return result;
+  }
+
+  while (LessEqual(other, *this)) {
+    SubtractBignum(other);
+    result++;
+  }
+  return result;
+}
+
+
+template<typename S>
+static int SizeInHexChars(S number) {
+  ASSERT(number > 0);
+  int result = 0;
+  while (number != 0) {
+    number >>= 4;
+    result++;
+  }
+  return result;
+}
+
+
+static char HexCharOfValue(int value) {
+  ASSERT(0 <= value && value <= 16);
+  if (value < 10) return static_cast<char>(value + '0');
+  return static_cast<char>(value - 10 + 'A');
+}
+
+
+bool Bignum::ToHexString(char* buffer, int buffer_size) const {
+  ASSERT(IsClamped());
+  // Each bigit must be printable as separate hex-character.
+  ASSERT(kBigitSize % 4 == 0);
+  const int kHexCharsPerBigit = kBigitSize / 4;
+
+  if (used_digits_ == 0) {
+    if (buffer_size < 2) return false;
+    buffer[0] = '0';
+    buffer[1] = '\0';
+    return true;
+  }
+  // We add 1 for the terminating '\0' character.
+  int needed_chars = (BigitLength() - 1) * kHexCharsPerBigit +
+      SizeInHexChars(bigits_[used_digits_ - 1]) + 1;
+  if (needed_chars > buffer_size) return false;
+  int string_index = needed_chars - 1;
+  buffer[string_index--] = '\0';
+  for (int i = 0; i < exponent_; ++i) {
+    for (int j = 0; j < kHexCharsPerBigit; ++j) {
+      buffer[string_index--] = '0';
+    }
+  }
+  for (int i = 0; i < used_digits_ - 1; ++i) {
+    Chunk current_bigit = bigits_[i];
+    for (int j = 0; j < kHexCharsPerBigit; ++j) {
+      buffer[string_index--] = HexCharOfValue(current_bigit & 0xF);
+      current_bigit >>= 4;
+    }
+  }
+  // And finally the last bigit.
+  Chunk most_significant_bigit = bigits_[used_digits_ - 1];
+  while (most_significant_bigit != 0) {
+    buffer[string_index--] = HexCharOfValue(most_significant_bigit & 0xF);
+    most_significant_bigit >>= 4;
+  }
+  return true;
+}
+
+
+Bignum::Chunk Bignum::BigitAt(int index) const {
+  if (index >= BigitLength()) return 0;
+  if (index < exponent_) return 0;
+  return bigits_[index - exponent_];
+}
+
+
+int Bignum::Compare(const Bignum& a, const Bignum& b) {
+  ASSERT(a.IsClamped());
+  ASSERT(b.IsClamped());
+  int bigit_length_a = a.BigitLength();
+  int bigit_length_b = b.BigitLength();
+  if (bigit_length_a < bigit_length_b) return -1;
+  if (bigit_length_a > bigit_length_b) return +1;
+  for (int i = bigit_length_a - 1; i >= Min(a.exponent_, b.exponent_); --i) {
+    Chunk bigit_a = a.BigitAt(i);
+    Chunk bigit_b = b.BigitAt(i);
+    if (bigit_a < bigit_b) return -1;
+    if (bigit_a > bigit_b) return +1;
+    // Otherwise they are equal up to this digit. Try the next digit.
+  }
+  return 0;
+}
+
+
+int Bignum::PlusCompare(const Bignum& a, const Bignum& b, const Bignum& c) {
+  ASSERT(a.IsClamped());
+  ASSERT(b.IsClamped());
+  ASSERT(c.IsClamped());
+  if (a.BigitLength() < b.BigitLength()) {
+    return PlusCompare(b, a, c);
+  }
+  if (a.BigitLength() + 1 < c.BigitLength()) return -1;
+  if (a.BigitLength() > c.BigitLength()) return +1;
+  // The exponent encodes 0-bigits. So if there are more 0-digits in 'a' than
+  // 'b' has digits, then the bigit-length of 'a'+'b' must be equal to the one
+  // of 'a'.
+  if (a.exponent_ >= b.BigitLength() && a.BigitLength() < c.BigitLength()) {
+    return -1;
+  }
+
+  Chunk borrow = 0;
+  // Starting at min_exponent all digits are == 0. So no need to compare them.
+  int min_exponent = Min(Min(a.exponent_, b.exponent_), c.exponent_);
+  for (int i = c.BigitLength() - 1; i >= min_exponent; --i) {
+    Chunk chunk_a = a.BigitAt(i);
+    Chunk chunk_b = b.BigitAt(i);
+    Chunk chunk_c = c.BigitAt(i);
+    Chunk sum = chunk_a + chunk_b;
+    if (sum > chunk_c + borrow) {
+      return +1;
+    } else {
+      borrow = chunk_c + borrow - sum;
+      if (borrow > 1) return -1;
+      borrow <<= kBigitSize;
+    }
+  }
+  if (borrow == 0) return 0;
+  return -1;
+}
+
+
+void Bignum::Clamp() {
+  while (used_digits_ > 0 && bigits_[used_digits_ - 1] == 0) {
+    used_digits_--;
+  }
+  if (used_digits_ == 0) {
+    // Zero.
+    exponent_ = 0;
+  }
+}
+
+
+bool Bignum::IsClamped() const {
+  return used_digits_ == 0 || bigits_[used_digits_ - 1] != 0;
+}
+
+
+void Bignum::Zero() {
+  for (int i = 0; i < used_digits_; ++i) {
+    bigits_[i] = 0;
+  }
+  used_digits_ = 0;
+  exponent_ = 0;
+}
+
+
+void Bignum::Align(const Bignum& other) {
+  if (exponent_ > other.exponent_) {
+    // If "X" represents a "hidden" digit (by the exponent) then we are in the
+    // following case (a == this, b == other):
+    // a:  aaaaaaXXXX   or a:   aaaaaXXX
+    // b:     bbbbbbX      b: bbbbbbbbXX
+    // We replace some of the hidden digits (X) of a with 0 digits.
+    // a:  aaaaaa000X   or a:   aaaaa0XX
+    int zero_digits = exponent_ - other.exponent_;
+    EnsureCapacity(used_digits_ + zero_digits);
+    for (int i = used_digits_ - 1; i >= 0; --i) {
+      bigits_[i + zero_digits] = bigits_[i];
+    }
+    for (int i = 0; i < zero_digits; ++i) {
+      bigits_[i] = 0;
+    }
+    used_digits_ += zero_digits;
+    exponent_ -= zero_digits;
+    ASSERT(used_digits_ >= 0);
+    ASSERT(exponent_ >= 0);
+  }
+}
+
+
+void Bignum::BigitsShiftLeft(int shift_amount) {
+  ASSERT(shift_amount < kBigitSize);
+  ASSERT(shift_amount >= 0);
+  Chunk carry = 0;
+  for (int i = 0; i < used_digits_; ++i) {
+    Chunk new_carry = bigits_[i] >> (kBigitSize - shift_amount);
+    bigits_[i] = ((bigits_[i] << shift_amount) + carry) & kBigitMask;
+    carry = new_carry;
+  }
+  if (carry != 0) {
+    bigits_[used_digits_] = carry;
+    used_digits_++;
+  }
+}
+
+
+void Bignum::SubtractTimes(const Bignum& other, int factor) {
+  ASSERT(exponent_ <= other.exponent_);
+  if (factor < 3) {
+    for (int i = 0; i < factor; ++i) {
+      SubtractBignum(other);
+    }
+    return;
+  }
+  Chunk borrow = 0;
+  int exponent_diff = other.exponent_ - exponent_;
+  for (int i = 0; i < other.used_digits_; ++i) {
+    DoubleChunk product = static_cast<DoubleChunk>(factor) * other.bigits_[i];
+    DoubleChunk remove = borrow + product;
+    Chunk difference = bigits_[i + exponent_diff] - (remove & kBigitMask);
+    bigits_[i + exponent_diff] = difference & kBigitMask;
+    borrow = static_cast<Chunk>((difference >> (kChunkSize - 1)) +
+                                (remove >> kBigitSize));
+  }
+  for (int i = other.used_digits_ + exponent_diff; i < used_digits_; ++i) {
+    if (borrow == 0) return;
+    Chunk difference = bigits_[i] - borrow;
+    bigits_[i] = difference & kBigitMask;
+    borrow = difference >> (kChunkSize - 1);
+  }
+  Clamp();
+}
+
+
+}  // namespace double_conversion

+ 145 - 0
third-party/double-conversion-1.1.6/src/bignum.h

@@ -0,0 +1,145 @@
+// 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.
+
+#ifndef DOUBLE_CONVERSION_BIGNUM_H_
+#define DOUBLE_CONVERSION_BIGNUM_H_
+
+#include "utils.h"
+
+namespace double_conversion {
+
+class Bignum {
+ public:
+  // 3584 = 128 * 28. We can represent 2^3584 > 10^1000 accurately.
+  // This bignum can encode much bigger numbers, since it contains an
+  // exponent.
+  static const int kMaxSignificantBits = 3584;
+
+  Bignum();
+  void AssignUInt16(uint16_t value);
+  void AssignUInt64(uint64_t value);
+  void AssignBignum(const Bignum& other);
+
+  void AssignDecimalString(Vector<const char> value);
+  void AssignHexString(Vector<const char> value);
+
+  void AssignPowerUInt16(uint16_t base, int exponent);
+
+  void AddUInt16(uint16_t operand);
+  void AddUInt64(uint64_t operand);
+  void AddBignum(const Bignum& other);
+  // Precondition: this >= other.
+  void SubtractBignum(const Bignum& other);
+
+  void Square();
+  void ShiftLeft(int shift_amount);
+  void MultiplyByUInt32(uint32_t factor);
+  void MultiplyByUInt64(uint64_t factor);
+  void MultiplyByPowerOfTen(int exponent);
+  void Times10() { return MultiplyByUInt32(10); }
+  // Pseudocode:
+  //  int result = this / other;
+  //  this = this % other;
+  // In the worst case this function is in O(this/other).
+  uint16_t DivideModuloIntBignum(const Bignum& other);
+
+  bool ToHexString(char* buffer, int buffer_size) const;
+
+  // Returns
+  //  -1 if a < b,
+  //   0 if a == b, and
+  //  +1 if a > b.
+  static int Compare(const Bignum& a, const Bignum& b);
+  static bool Equal(const Bignum& a, const Bignum& b) {
+    return Compare(a, b) == 0;
+  }
+  static bool LessEqual(const Bignum& a, const Bignum& b) {
+    return Compare(a, b) <= 0;
+  }
+  static bool Less(const Bignum& a, const Bignum& b) {
+    return Compare(a, b) < 0;
+  }
+  // Returns Compare(a + b, c);
+  static int PlusCompare(const Bignum& a, const Bignum& b, const Bignum& c);
+  // Returns a + b == c
+  static bool PlusEqual(const Bignum& a, const Bignum& b, const Bignum& c) {
+    return PlusCompare(a, b, c) == 0;
+  }
+  // Returns a + b <= c
+  static bool PlusLessEqual(const Bignum& a, const Bignum& b, const Bignum& c) {
+    return PlusCompare(a, b, c) <= 0;
+  }
+  // Returns a + b < c
+  static bool PlusLess(const Bignum& a, const Bignum& b, const Bignum& c) {
+    return PlusCompare(a, b, c) < 0;
+  }
+ private:
+  typedef uint32_t Chunk;
+  typedef uint64_t DoubleChunk;
+
+  static const int kChunkSize = sizeof(Chunk) * 8;
+  static const int kDoubleChunkSize = sizeof(DoubleChunk) * 8;
+  // With bigit size of 28 we loose some bits, but a double still fits easily
+  // into two chunks, and more importantly we can use the Comba multiplication.
+  static const int kBigitSize = 28;
+  static const Chunk kBigitMask = (1 << kBigitSize) - 1;
+  // Every instance allocates kBigitLength chunks on the stack. Bignums cannot
+  // grow. There are no checks if the stack-allocated space is sufficient.
+  static const int kBigitCapacity = kMaxSignificantBits / kBigitSize;
+
+  void EnsureCapacity(int size) {
+    if (size > kBigitCapacity) {
+      UNREACHABLE();
+    }
+  }
+  void Align(const Bignum& other);
+  void Clamp();
+  bool IsClamped() const;
+  void Zero();
+  // Requires this to have enough capacity (no tests done).
+  // Updates used_digits_ if necessary.
+  // shift_amount must be < kBigitSize.
+  void BigitsShiftLeft(int shift_amount);
+  // BigitLength includes the "hidden" digits encoded in the exponent.
+  int BigitLength() const { return used_digits_ + exponent_; }
+  Chunk BigitAt(int index) const;
+  void SubtractTimes(const Bignum& other, int factor);
+
+  Chunk bigits_buffer_[kBigitCapacity];
+  // A vector backed by bigits_buffer_. This way accesses to the array are
+  // checked for out-of-bounds errors.
+  Vector<Chunk> bigits_;
+  int used_digits_;
+  // The Bignum's value equals value(bigits_) * 2^(exponent_ * kBigitSize).
+  int exponent_;
+
+  DISALLOW_COPY_AND_ASSIGN(Bignum);
+};
+
+}  // namespace double_conversion
+
+#endif  // DOUBLE_CONVERSION_BIGNUM_H_

+ 176 - 0
third-party/double-conversion-1.1.6/src/cached-powers.cc

@@ -0,0 +1,176 @@
+// Copyright 2006-2008 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 <stdarg.h>
+#include <limits.h>
+#include <math.h>
+
+#include "utils.h"
+
+#include "cached-powers.h"
+
+namespace double_conversion {
+
+struct CachedPower {
+  uint64_t significand;
+  int16_t binary_exponent;
+  int16_t decimal_exponent;
+};
+
+static const CachedPower kCachedPowers[] = {
+  {UINT64_2PART_C(0xfa8fd5a0, 081c0288), -1220, -348},
+  {UINT64_2PART_C(0xbaaee17f, a23ebf76), -1193, -340},
+  {UINT64_2PART_C(0x8b16fb20, 3055ac76), -1166, -332},
+  {UINT64_2PART_C(0xcf42894a, 5dce35ea), -1140, -324},
+  {UINT64_2PART_C(0x9a6bb0aa, 55653b2d), -1113, -316},
+  {UINT64_2PART_C(0xe61acf03, 3d1a45df), -1087, -308},
+  {UINT64_2PART_C(0xab70fe17, c79ac6ca), -1060, -300},
+  {UINT64_2PART_C(0xff77b1fc, bebcdc4f), -1034, -292},
+  {UINT64_2PART_C(0xbe5691ef, 416bd60c), -1007, -284},
+  {UINT64_2PART_C(0x8dd01fad, 907ffc3c), -980, -276},
+  {UINT64_2PART_C(0xd3515c28, 31559a83), -954, -268},
+  {UINT64_2PART_C(0x9d71ac8f, ada6c9b5), -927, -260},
+  {UINT64_2PART_C(0xea9c2277, 23ee8bcb), -901, -252},
+  {UINT64_2PART_C(0xaecc4991, 4078536d), -874, -244},
+  {UINT64_2PART_C(0x823c1279, 5db6ce57), -847, -236},
+  {UINT64_2PART_C(0xc2109436, 4dfb5637), -821, -228},
+  {UINT64_2PART_C(0x9096ea6f, 3848984f), -794, -220},
+  {UINT64_2PART_C(0xd77485cb, 25823ac7), -768, -212},
+  {UINT64_2PART_C(0xa086cfcd, 97bf97f4), -741, -204},
+  {UINT64_2PART_C(0xef340a98, 172aace5), -715, -196},
+  {UINT64_2PART_C(0xb23867fb, 2a35b28e), -688, -188},
+  {UINT64_2PART_C(0x84c8d4df, d2c63f3b), -661, -180},
+  {UINT64_2PART_C(0xc5dd4427, 1ad3cdba), -635, -172},
+  {UINT64_2PART_C(0x936b9fce, bb25c996), -608, -164},
+  {UINT64_2PART_C(0xdbac6c24, 7d62a584), -582, -156},
+  {UINT64_2PART_C(0xa3ab6658, 0d5fdaf6), -555, -148},
+  {UINT64_2PART_C(0xf3e2f893, dec3f126), -529, -140},
+  {UINT64_2PART_C(0xb5b5ada8, aaff80b8), -502, -132},
+  {UINT64_2PART_C(0x87625f05, 6c7c4a8b), -475, -124},
+  {UINT64_2PART_C(0xc9bcff60, 34c13053), -449, -116},
+  {UINT64_2PART_C(0x964e858c, 91ba2655), -422, -108},
+  {UINT64_2PART_C(0xdff97724, 70297ebd), -396, -100},
+  {UINT64_2PART_C(0xa6dfbd9f, b8e5b88f), -369, -92},
+  {UINT64_2PART_C(0xf8a95fcf, 88747d94), -343, -84},
+  {UINT64_2PART_C(0xb9447093, 8fa89bcf), -316, -76},
+  {UINT64_2PART_C(0x8a08f0f8, bf0f156b), -289, -68},
+  {UINT64_2PART_C(0xcdb02555, 653131b6), -263, -60},
+  {UINT64_2PART_C(0x993fe2c6, d07b7fac), -236, -52},
+  {UINT64_2PART_C(0xe45c10c4, 2a2b3b06), -210, -44},
+  {UINT64_2PART_C(0xaa242499, 697392d3), -183, -36},
+  {UINT64_2PART_C(0xfd87b5f2, 8300ca0e), -157, -28},
+  {UINT64_2PART_C(0xbce50864, 92111aeb), -130, -20},
+  {UINT64_2PART_C(0x8cbccc09, 6f5088cc), -103, -12},
+  {UINT64_2PART_C(0xd1b71758, e219652c), -77, -4},
+  {UINT64_2PART_C(0x9c400000, 00000000), -50, 4},
+  {UINT64_2PART_C(0xe8d4a510, 00000000), -24, 12},
+  {UINT64_2PART_C(0xad78ebc5, ac620000), 3, 20},
+  {UINT64_2PART_C(0x813f3978, f8940984), 30, 28},
+  {UINT64_2PART_C(0xc097ce7b, c90715b3), 56, 36},
+  {UINT64_2PART_C(0x8f7e32ce, 7bea5c70), 83, 44},
+  {UINT64_2PART_C(0xd5d238a4, abe98068), 109, 52},
+  {UINT64_2PART_C(0x9f4f2726, 179a2245), 136, 60},
+  {UINT64_2PART_C(0xed63a231, d4c4fb27), 162, 68},
+  {UINT64_2PART_C(0xb0de6538, 8cc8ada8), 189, 76},
+  {UINT64_2PART_C(0x83c7088e, 1aab65db), 216, 84},
+  {UINT64_2PART_C(0xc45d1df9, 42711d9a), 242, 92},
+  {UINT64_2PART_C(0x924d692c, a61be758), 269, 100},
+  {UINT64_2PART_C(0xda01ee64, 1a708dea), 295, 108},
+  {UINT64_2PART_C(0xa26da399, 9aef774a), 322, 116},
+  {UINT64_2PART_C(0xf209787b, b47d6b85), 348, 124},
+  {UINT64_2PART_C(0xb454e4a1, 79dd1877), 375, 132},
+  {UINT64_2PART_C(0x865b8692, 5b9bc5c2), 402, 140},
+  {UINT64_2PART_C(0xc83553c5, c8965d3d), 428, 148},
+  {UINT64_2PART_C(0x952ab45c, fa97a0b3), 455, 156},
+  {UINT64_2PART_C(0xde469fbd, 99a05fe3), 481, 164},
+  {UINT64_2PART_C(0xa59bc234, db398c25), 508, 172},
+  {UINT64_2PART_C(0xf6c69a72, a3989f5c), 534, 180},
+  {UINT64_2PART_C(0xb7dcbf53, 54e9bece), 561, 188},
+  {UINT64_2PART_C(0x88fcf317, f22241e2), 588, 196},
+  {UINT64_2PART_C(0xcc20ce9b, d35c78a5), 614, 204},
+  {UINT64_2PART_C(0x98165af3, 7b2153df), 641, 212},
+  {UINT64_2PART_C(0xe2a0b5dc, 971f303a), 667, 220},
+  {UINT64_2PART_C(0xa8d9d153, 5ce3b396), 694, 228},
+  {UINT64_2PART_C(0xfb9b7cd9, a4a7443c), 720, 236},
+  {UINT64_2PART_C(0xbb764c4c, a7a44410), 747, 244},
+  {UINT64_2PART_C(0x8bab8eef, b6409c1a), 774, 252},
+  {UINT64_2PART_C(0xd01fef10, a657842c), 800, 260},
+  {UINT64_2PART_C(0x9b10a4e5, e9913129), 827, 268},
+  {UINT64_2PART_C(0xe7109bfb, a19c0c9d), 853, 276},
+  {UINT64_2PART_C(0xac2820d9, 623bf429), 880, 284},
+  {UINT64_2PART_C(0x80444b5e, 7aa7cf85), 907, 292},
+  {UINT64_2PART_C(0xbf21e440, 03acdd2d), 933, 300},
+  {UINT64_2PART_C(0x8e679c2f, 5e44ff8f), 960, 308},
+  {UINT64_2PART_C(0xd433179d, 9c8cb841), 986, 316},
+  {UINT64_2PART_C(0x9e19db92, b4e31ba9), 1013, 324},
+  {UINT64_2PART_C(0xeb96bf6e, badf77d9), 1039, 332},
+  {UINT64_2PART_C(0xaf87023b, 9bf0ee6b), 1066, 340},
+};
+
+static const int kCachedPowersLength = ARRAY_SIZE(kCachedPowers);
+static const int kCachedPowersOffset = 348;  // -1 * the first decimal_exponent.
+static const double kD_1_LOG2_10 = 0.30102999566398114;  //  1 / lg(10)
+// Difference between the decimal exponents in the table above.
+const int PowersOfTenCache::kDecimalExponentDistance = 8;
+const int PowersOfTenCache::kMinDecimalExponent = -348;
+const int PowersOfTenCache::kMaxDecimalExponent = 340;
+
+void PowersOfTenCache::GetCachedPowerForBinaryExponentRange(
+    int min_exponent,
+    int max_exponent,
+    DiyFp* power,
+    int* decimal_exponent) {
+  int kQ = DiyFp::kSignificandSize;
+  double k = ceil((min_exponent + kQ - 1) * kD_1_LOG2_10);
+  int foo = kCachedPowersOffset;
+  int index =
+      (foo + static_cast<int>(k) - 1) / kDecimalExponentDistance + 1;
+  ASSERT(0 <= index && index < kCachedPowersLength);
+  CachedPower cached_power = kCachedPowers[index];
+  ASSERT(min_exponent <= cached_power.binary_exponent);
+  (void) max_exponent;  // Mark variable as used.
+  ASSERT(cached_power.binary_exponent <= max_exponent);
+  *decimal_exponent = cached_power.decimal_exponent;
+  *power = DiyFp(cached_power.significand, cached_power.binary_exponent);
+}
+
+
+void PowersOfTenCache::GetCachedPowerForDecimalExponent(int requested_exponent,
+                                                        DiyFp* power,
+                                                        int* found_exponent) {
+  ASSERT(kMinDecimalExponent <= requested_exponent);
+  ASSERT(requested_exponent < kMaxDecimalExponent + kDecimalExponentDistance);
+  int index =
+      (requested_exponent + kCachedPowersOffset) / kDecimalExponentDistance;
+  CachedPower cached_power = kCachedPowers[index];
+  *power = DiyFp(cached_power.significand, cached_power.binary_exponent);
+  *found_exponent = cached_power.decimal_exponent;
+  ASSERT(*found_exponent <= requested_exponent);
+  ASSERT(requested_exponent < *found_exponent + kDecimalExponentDistance);
+}
+
+}  // namespace double_conversion

+ 64 - 0
third-party/double-conversion-1.1.6/src/cached-powers.h

@@ -0,0 +1,64 @@
+// 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.
+
+#ifndef DOUBLE_CONVERSION_CACHED_POWERS_H_
+#define DOUBLE_CONVERSION_CACHED_POWERS_H_
+
+#include "diy-fp.h"
+
+namespace double_conversion {
+
+class PowersOfTenCache {
+ public:
+
+  // Not all powers of ten are cached. The decimal exponent of two neighboring
+  // cached numbers will differ by kDecimalExponentDistance.
+  static const int kDecimalExponentDistance;
+
+  static const int kMinDecimalExponent;
+  static const int kMaxDecimalExponent;
+
+  // Returns a cached power-of-ten with a binary exponent in the range
+  // [min_exponent; max_exponent] (boundaries included).
+  static void GetCachedPowerForBinaryExponentRange(int min_exponent,
+                                                   int max_exponent,
+                                                   DiyFp* power,
+                                                   int* decimal_exponent);
+
+  // Returns a cached power of ten x ~= 10^k such that
+  //   k <= decimal_exponent < k + kCachedPowersDecimalDistance.
+  // The given decimal_exponent must satisfy
+  //   kMinDecimalExponent <= requested_exponent, and
+  //   requested_exponent < kMaxDecimalExponent + kDecimalExponentDistance.
+  static void GetCachedPowerForDecimalExponent(int requested_exponent,
+                                               DiyFp* power,
+                                               int* found_exponent);
+};
+
+}  // namespace double_conversion
+
+#endif  // DOUBLE_CONVERSION_CACHED_POWERS_H_

+ 57 - 0
third-party/double-conversion-1.1.6/src/diy-fp.cc

@@ -0,0 +1,57 @@
+// 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 "diy-fp.h"
+#include "utils.h"
+
+namespace double_conversion {
+
+void DiyFp::Multiply(const DiyFp& other) {
+  // Simply "emulates" a 128 bit multiplication.
+  // However: the resulting number only contains 64 bits. The least
+  // significant 64 bits are only used for rounding the most significant 64
+  // bits.
+  const uint64_t kM32 = 0xFFFFFFFFU;
+  uint64_t a = f_ >> 32;
+  uint64_t b = f_ & kM32;
+  uint64_t c = other.f_ >> 32;
+  uint64_t d = other.f_ & kM32;
+  uint64_t ac = a * c;
+  uint64_t bc = b * c;
+  uint64_t ad = a * d;
+  uint64_t bd = b * d;
+  uint64_t tmp = (bd >> 32) + (ad & kM32) + (bc & kM32);
+  // By adding 1U << 31 to tmp we round the final result.
+  // Halfway cases will be round up.
+  tmp += 1U << 31;
+  uint64_t result_f = ac + (ad >> 32) + (bc >> 32) + (tmp >> 32);
+  e_ += other.e_ + 64;
+  f_ = result_f;
+}
+
+}  // namespace double_conversion

+ 118 - 0
third-party/double-conversion-1.1.6/src/diy-fp.h

@@ -0,0 +1,118 @@
+// 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.
+
+#ifndef DOUBLE_CONVERSION_DIY_FP_H_
+#define DOUBLE_CONVERSION_DIY_FP_H_
+
+#include "utils.h"
+
+namespace double_conversion {
+
+// This "Do It Yourself Floating Point" class implements a floating-point number
+// with a uint64 significand and an int exponent. Normalized DiyFp numbers will
+// have the most significant bit of the significand set.
+// Multiplication and Subtraction do not normalize their results.
+// DiyFp are not designed to contain special doubles (NaN and Infinity).
+class DiyFp {
+ public:
+  static const int kSignificandSize = 64;
+
+  DiyFp() : f_(0), e_(0) {}
+  DiyFp(uint64_t f, int e) : f_(f), e_(e) {}
+
+  // this = this - other.
+  // The exponents of both numbers must be the same and the significand of this
+  // must be bigger than the significand of other.
+  // The result will not be normalized.
+  void Subtract(const DiyFp& other) {
+    ASSERT(e_ == other.e_);
+    ASSERT(f_ >= other.f_);
+    f_ -= other.f_;
+  }
+
+  // Returns a - b.
+  // The exponents of both numbers must be the same and this must be bigger
+  // than other. The result will not be normalized.
+  static DiyFp Minus(const DiyFp& a, const DiyFp& b) {
+    DiyFp result = a;
+    result.Subtract(b);
+    return result;
+  }
+
+
+  // this = this * other.
+  void Multiply(const DiyFp& other);
+
+  // returns a * b;
+  static DiyFp Times(const DiyFp& a, const DiyFp& b) {
+    DiyFp result = a;
+    result.Multiply(b);
+    return result;
+  }
+
+  void Normalize() {
+    ASSERT(f_ != 0);
+    uint64_t f = f_;
+    int e = e_;
+
+    // This method is mainly called for normalizing boundaries. In general
+    // boundaries need to be shifted by 10 bits. We thus optimize for this case.
+    const uint64_t k10MSBits = UINT64_2PART_C(0xFFC00000, 00000000);
+    while ((f & k10MSBits) == 0) {
+      f <<= 10;
+      e -= 10;
+    }
+    while ((f & kUint64MSB) == 0) {
+      f <<= 1;
+      e--;
+    }
+    f_ = f;
+    e_ = e;
+  }
+
+  static DiyFp Normalize(const DiyFp& a) {
+    DiyFp result = a;
+    result.Normalize();
+    return result;
+  }
+
+  uint64_t f() const { return f_; }
+  int e() const { return e_; }
+
+  void set_f(uint64_t new_value) { f_ = new_value; }
+  void set_e(int new_value) { e_ = new_value; }
+
+ private:
+  static const uint64_t kUint64MSB = UINT64_2PART_C(0x80000000, 00000000);
+
+  uint64_t f_;
+  int e_;
+};
+
+}  // namespace double_conversion
+
+#endif  // DOUBLE_CONVERSION_DIY_FP_H_

+ 910 - 0
third-party/double-conversion-1.1.6/src/double-conversion.cc

@@ -0,0 +1,910 @@
+// 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 <limits.h>
+#include <math.h>
+
+#include "double-conversion.h"
+
+#include "bignum-dtoa.h"
+#include "fast-dtoa.h"
+#include "fixed-dtoa.h"
+#include "ieee.h"
+#include "strtod.h"
+#include "utils.h"
+
+namespace double_conversion {
+
+const DoubleToStringConverter& DoubleToStringConverter::EcmaScriptConverter() {
+  int flags = UNIQUE_ZERO | EMIT_POSITIVE_EXPONENT_SIGN;
+  static DoubleToStringConverter converter(flags,
+                                           "Infinity",
+                                           "NaN",
+                                           'e',
+                                           -6, 21,
+                                           6, 0);
+  return converter;
+}
+
+
+bool DoubleToStringConverter::HandleSpecialValues(
+    double value,
+    StringBuilder* result_builder) const {
+  Double double_inspect(value);
+  if (double_inspect.IsInfinite()) {
+    if (infinity_symbol_ == NULL) return false;
+    if (value < 0) {
+      result_builder->AddCharacter('-');
+    }
+    result_builder->AddString(infinity_symbol_);
+    return true;
+  }
+  if (double_inspect.IsNan()) {
+    if (nan_symbol_ == NULL) return false;
+    result_builder->AddString(nan_symbol_);
+    return true;
+  }
+  return false;
+}
+
+
+void DoubleToStringConverter::CreateExponentialRepresentation(
+    const char* decimal_digits,
+    int length,
+    int exponent,
+    StringBuilder* result_builder) const {
+  ASSERT(length != 0);
+  result_builder->AddCharacter(decimal_digits[0]);
+  if (length != 1) {
+    result_builder->AddCharacter('.');
+    result_builder->AddSubstring(&decimal_digits[1], length-1);
+  }
+  result_builder->AddCharacter(exponent_character_);
+  if (exponent < 0) {
+    result_builder->AddCharacter('-');
+    exponent = -exponent;
+  } else {
+    if ((flags_ & EMIT_POSITIVE_EXPONENT_SIGN) != 0) {
+      result_builder->AddCharacter('+');
+    }
+  }
+  if (exponent == 0) {
+    result_builder->AddCharacter('0');
+    return;
+  }
+  ASSERT(exponent < 1e4);
+  const int kMaxExponentLength = 5;
+  char buffer[kMaxExponentLength + 1];
+  buffer[kMaxExponentLength] = '\0';
+  int first_char_pos = kMaxExponentLength;
+  while (exponent > 0) {
+    buffer[--first_char_pos] = '0' + (exponent % 10);
+    exponent /= 10;
+  }
+  result_builder->AddSubstring(&buffer[first_char_pos],
+                               kMaxExponentLength - first_char_pos);
+}
+
+
+void DoubleToStringConverter::CreateDecimalRepresentation(
+    const char* decimal_digits,
+    int length,
+    int decimal_point,
+    int digits_after_point,
+    StringBuilder* result_builder) const {
+  // Create a representation that is padded with zeros if needed.
+  if (decimal_point <= 0) {
+      // "0.00000decimal_rep".
+    result_builder->AddCharacter('0');
+    if (digits_after_point > 0) {
+      result_builder->AddCharacter('.');
+      result_builder->AddPadding('0', -decimal_point);
+      ASSERT(length <= digits_after_point - (-decimal_point));
+      result_builder->AddSubstring(decimal_digits, length);
+      int remaining_digits = digits_after_point - (-decimal_point) - length;
+      result_builder->AddPadding('0', remaining_digits);
+    }
+  } else if (decimal_point >= length) {
+    // "decimal_rep0000.00000" or "decimal_rep.0000"
+    result_builder->AddSubstring(decimal_digits, length);
+    result_builder->AddPadding('0', decimal_point - length);
+    if (digits_after_point > 0) {
+      result_builder->AddCharacter('.');
+      result_builder->AddPadding('0', digits_after_point);
+    }
+  } else {
+    // "decima.l_rep000"
+    ASSERT(digits_after_point > 0);
+    result_builder->AddSubstring(decimal_digits, decimal_point);
+    result_builder->AddCharacter('.');
+    ASSERT(length - decimal_point <= digits_after_point);
+    result_builder->AddSubstring(&decimal_digits[decimal_point],
+                                 length - decimal_point);
+    int remaining_digits = digits_after_point - (length - decimal_point);
+    result_builder->AddPadding('0', remaining_digits);
+  }
+  if (digits_after_point == 0) {
+    if ((flags_ & EMIT_TRAILING_DECIMAL_POINT) != 0) {
+      result_builder->AddCharacter('.');
+    }
+    if ((flags_ & EMIT_TRAILING_ZERO_AFTER_POINT) != 0) {
+      result_builder->AddCharacter('0');
+    }
+  }
+}
+
+
+bool DoubleToStringConverter::ToShortestIeeeNumber(
+    double value,
+    StringBuilder* result_builder,
+    DoubleToStringConverter::DtoaMode mode) const {
+  ASSERT(mode == SHORTEST || mode == SHORTEST_SINGLE);
+  if (Double(value).IsSpecial()) {
+    return HandleSpecialValues(value, result_builder);
+  }
+
+  int decimal_point;
+  bool sign;
+  const int kDecimalRepCapacity = kBase10MaximalLength + 1;
+  char decimal_rep[kDecimalRepCapacity];
+  int decimal_rep_length;
+
+  DoubleToAscii(value, mode, 0, decimal_rep, kDecimalRepCapacity,
+                &sign, &decimal_rep_length, &decimal_point);
+
+  bool unique_zero = (flags_ & UNIQUE_ZERO) != 0;
+  if (sign && (value != 0.0 || !unique_zero)) {
+    result_builder->AddCharacter('-');
+  }
+
+  int exponent = decimal_point - 1;
+  if ((decimal_in_shortest_low_ <= exponent) &&
+      (exponent < decimal_in_shortest_high_)) {
+    CreateDecimalRepresentation(decimal_rep, decimal_rep_length,
+                                decimal_point,
+                                Max(0, decimal_rep_length - decimal_point),
+                                result_builder);
+  } else {
+    CreateExponentialRepresentation(decimal_rep, decimal_rep_length, exponent,
+                                    result_builder);
+  }
+  return true;
+}
+
+
+bool DoubleToStringConverter::ToFixed(double value,
+                                      int requested_digits,
+                                      StringBuilder* result_builder) const {
+  ASSERT(kMaxFixedDigitsBeforePoint == 60);
+  const double kFirstNonFixed = 1e60;
+
+  if (Double(value).IsSpecial()) {
+    return HandleSpecialValues(value, result_builder);
+  }
+
+  if (requested_digits > kMaxFixedDigitsAfterPoint) return false;
+  if (value >= kFirstNonFixed || value <= -kFirstNonFixed) return false;
+
+  // Find a sufficiently precise decimal representation of n.
+  int decimal_point;
+  bool sign;
+  // Add space for the '\0' byte.
+  const int kDecimalRepCapacity =
+      kMaxFixedDigitsBeforePoint + kMaxFixedDigitsAfterPoint + 1;
+  char decimal_rep[kDecimalRepCapacity];
+  int decimal_rep_length;
+  DoubleToAscii(value, FIXED, requested_digits,
+                decimal_rep, kDecimalRepCapacity,
+                &sign, &decimal_rep_length, &decimal_point);
+
+  bool unique_zero = ((flags_ & UNIQUE_ZERO) != 0);
+  if (sign && (value != 0.0 || !unique_zero)) {
+    result_builder->AddCharacter('-');
+  }
+
+  CreateDecimalRepresentation(decimal_rep, decimal_rep_length, decimal_point,
+                              requested_digits, result_builder);
+  return true;
+}
+
+
+bool DoubleToStringConverter::ToExponential(
+    double value,
+    int requested_digits,
+    StringBuilder* result_builder) const {
+  if (Double(value).IsSpecial()) {
+    return HandleSpecialValues(value, result_builder);
+  }
+
+  if (requested_digits < -1) return false;
+  if (requested_digits > kMaxExponentialDigits) return false;
+
+  int decimal_point;
+  bool sign;
+  // Add space for digit before the decimal point and the '\0' character.
+  const int kDecimalRepCapacity = kMaxExponentialDigits + 2;
+  ASSERT(kDecimalRepCapacity > kBase10MaximalLength);
+  char decimal_rep[kDecimalRepCapacity];
+  int decimal_rep_length;
+
+  if (requested_digits == -1) {
+    DoubleToAscii(value, SHORTEST, 0,
+                  decimal_rep, kDecimalRepCapacity,
+                  &sign, &decimal_rep_length, &decimal_point);
+  } else {
+    DoubleToAscii(value, PRECISION, requested_digits + 1,
+                  decimal_rep, kDecimalRepCapacity,
+                  &sign, &decimal_rep_length, &decimal_point);
+    ASSERT(decimal_rep_length <= requested_digits + 1);
+
+    for (int i = decimal_rep_length; i < requested_digits + 1; ++i) {
+      decimal_rep[i] = '0';
+    }
+    decimal_rep_length = requested_digits + 1;
+  }
+
+  bool unique_zero = ((flags_ & UNIQUE_ZERO) != 0);
+  if (sign && (value != 0.0 || !unique_zero)) {
+    result_builder->AddCharacter('-');
+  }
+
+  int exponent = decimal_point - 1;
+  CreateExponentialRepresentation(decimal_rep,
+                                  decimal_rep_length,
+                                  exponent,
+                                  result_builder);
+  return true;
+}
+
+
+bool DoubleToStringConverter::ToPrecision(double value,
+                                          int precision,
+                                          StringBuilder* result_builder) const {
+  if (Double(value).IsSpecial()) {
+    return HandleSpecialValues(value, result_builder);
+  }
+
+  if (precision < kMinPrecisionDigits || precision > kMaxPrecisionDigits) {
+    return false;
+  }
+
+  // Find a sufficiently precise decimal representation of n.
+  int decimal_point;
+  bool sign;
+  // Add one for the terminating null character.
+  const int kDecimalRepCapacity = kMaxPrecisionDigits + 1;
+  char decimal_rep[kDecimalRepCapacity];
+  int decimal_rep_length;
+
+  DoubleToAscii(value, PRECISION, precision,
+                decimal_rep, kDecimalRepCapacity,
+                &sign, &decimal_rep_length, &decimal_point);
+  ASSERT(decimal_rep_length <= precision);
+
+  bool unique_zero = ((flags_ & UNIQUE_ZERO) != 0);
+  if (sign && (value != 0.0 || !unique_zero)) {
+    result_builder->AddCharacter('-');
+  }
+
+  // The exponent if we print the number as x.xxeyyy. That is with the
+  // decimal point after the first digit.
+  int exponent = decimal_point - 1;
+
+  int extra_zero = ((flags_ & EMIT_TRAILING_ZERO_AFTER_POINT) != 0) ? 1 : 0;
+  if ((-decimal_point + 1 > max_leading_padding_zeroes_in_precision_mode_) ||
+      (decimal_point - precision + extra_zero >
+       max_trailing_padding_zeroes_in_precision_mode_)) {
+    // Fill buffer to contain 'precision' digits.
+    // Usually the buffer is already at the correct length, but 'DoubleToAscii'
+    // is allowed to return less characters.
+    for (int i = decimal_rep_length; i < precision; ++i) {
+      decimal_rep[i] = '0';
+    }
+
+    CreateExponentialRepresentation(decimal_rep,
+                                    precision,
+                                    exponent,
+                                    result_builder);
+  } else {
+    CreateDecimalRepresentation(decimal_rep, decimal_rep_length, decimal_point,
+                                Max(0, precision - decimal_point),
+                                result_builder);
+  }
+  return true;
+}
+
+
+static BignumDtoaMode DtoaToBignumDtoaMode(
+    DoubleToStringConverter::DtoaMode dtoa_mode) {
+  switch (dtoa_mode) {
+    case DoubleToStringConverter::SHORTEST:  return BIGNUM_DTOA_SHORTEST;
+    case DoubleToStringConverter::SHORTEST_SINGLE:
+        return BIGNUM_DTOA_SHORTEST_SINGLE;
+    case DoubleToStringConverter::FIXED:     return BIGNUM_DTOA_FIXED;
+    case DoubleToStringConverter::PRECISION: return BIGNUM_DTOA_PRECISION;
+    default:
+      UNREACHABLE();
+  }
+}
+
+
+void DoubleToStringConverter::DoubleToAscii(double v,
+                                            DtoaMode mode,
+                                            int requested_digits,
+                                            char* buffer,
+                                            int buffer_length,
+                                            bool* sign,
+                                            int* length,
+                                            int* point) {
+  Vector<char> vector(buffer, buffer_length);
+  ASSERT(!Double(v).IsSpecial());
+  ASSERT(mode == SHORTEST || mode == SHORTEST_SINGLE || requested_digits >= 0);
+
+  if (Double(v).Sign() < 0) {
+    *sign = true;
+    v = -v;
+  } else {
+    *sign = false;
+  }
+
+  if (mode == PRECISION && requested_digits == 0) {
+    vector[0] = '\0';
+    *length = 0;
+    return;
+  }
+
+  if (v == 0) {
+    vector[0] = '0';
+    vector[1] = '\0';
+    *length = 1;
+    *point = 1;
+    return;
+  }
+
+  bool fast_worked;
+  switch (mode) {
+    case SHORTEST:
+      fast_worked = FastDtoa(v, FAST_DTOA_SHORTEST, 0, vector, length, point);
+      break;
+    case SHORTEST_SINGLE:
+      fast_worked = FastDtoa(v, FAST_DTOA_SHORTEST_SINGLE, 0,
+                             vector, length, point);
+      break;
+    case FIXED:
+      fast_worked = FastFixedDtoa(v, requested_digits, vector, length, point);
+      break;
+    case PRECISION:
+      fast_worked = FastDtoa(v, FAST_DTOA_PRECISION, requested_digits,
+                             vector, length, point);
+      break;
+    default:
+      fast_worked = false;
+      UNREACHABLE();
+  }
+  if (fast_worked) return;
+
+  // If the fast dtoa didn't succeed use the slower bignum version.
+  BignumDtoaMode bignum_mode = DtoaToBignumDtoaMode(mode);
+  BignumDtoa(v, bignum_mode, requested_digits, vector, length, point);
+  vector[*length] = '\0';
+}
+
+
+// Consumes the given substring from the iterator.
+// Returns false, if the substring does not match.
+static bool ConsumeSubString(const char** current,
+                             const char* end,
+                             const char* substring) {
+  ASSERT(**current == *substring);
+  for (substring++; *substring != '\0'; substring++) {
+    ++*current;
+    if (*current == end || **current != *substring) return false;
+  }
+  ++*current;
+  return true;
+}
+
+
+// Maximum number of significant digits in decimal representation.
+// The longest possible double in decimal representation is
+// (2^53 - 1) * 2 ^ -1074 that is (2 ^ 53 - 1) * 5 ^ 1074 / 10 ^ 1074
+// (768 digits). If we parse a number whose first digits are equal to a
+// mean of 2 adjacent doubles (that could have up to 769 digits) the result
+// must be rounded to the bigger one unless the tail consists of zeros, so
+// we don't need to preserve all the digits.
+const int kMaxSignificantDigits = 772;
+
+
+// Returns true if a nonspace found and false if the end has reached.
+static inline bool AdvanceToNonspace(const char** current, const char* end) {
+  while (*current != end) {
+    if (**current != ' ') return true;
+    ++*current;
+  }
+  return false;
+}
+
+
+static bool isDigit(int x, int radix) {
+  return (x >= '0' && x <= '9' && x < '0' + radix)
+      || (radix > 10 && x >= 'a' && x < 'a' + radix - 10)
+      || (radix > 10 && x >= 'A' && x < 'A' + radix - 10);
+}
+
+
+static double SignedZero(bool sign) {
+  return sign ? -0.0 : 0.0;
+}
+
+
+// Returns true if 'c' is a decimal digit that is valid for the given radix.
+//
+// The function is small and could be inlined, but VS2012 emitted a warning
+// because it constant-propagated the radix and concluded that the last
+// condition was always true. By moving it into a separate function the
+// compiler wouldn't warn anymore.
+static bool IsDecimalDigitForRadix(int c, int radix) {
+  return '0' <= c && c <= '9' && (c - '0') < radix;
+}
+
+// Returns true if 'c' is a character digit that is valid for the given radix.
+// The 'a_character' should be 'a' or 'A'.
+//
+// The function is small and could be inlined, but VS2012 emitted a warning
+// because it constant-propagated the radix and concluded that the first
+// condition was always false. By moving it into a separate function the
+// compiler wouldn't warn anymore.
+static bool IsCharacterDigitForRadix(int c, int radix, char a_character) {
+  return radix > 10 && c >= a_character && c < a_character + radix - 10;
+}
+
+
+// Parsing integers with radix 2, 4, 8, 16, 32. Assumes current != end.
+template <int radix_log_2>
+static double RadixStringToIeee(const char* current,
+                                const char* end,
+                                bool sign,
+                                bool allow_trailing_junk,
+                                double junk_string_value,
+                                bool read_as_double,
+                                const char** trailing_pointer) {
+  ASSERT(current != end);
+
+  const int kDoubleSize = Double::kSignificandSize;
+  const int kSingleSize = Single::kSignificandSize;
+  const int kSignificandSize = read_as_double? kDoubleSize: kSingleSize;
+
+  // Skip leading 0s.
+  while (*current == '0') {
+    ++current;
+    if (current == end) {
+      *trailing_pointer = end;
+      return SignedZero(sign);
+    }
+  }
+
+  int64_t number = 0;
+  int exponent = 0;
+  const int radix = (1 << radix_log_2);
+
+  do {
+    int digit;
+    if (IsDecimalDigitForRadix(*current, radix)) {
+      digit = static_cast<char>(*current) - '0';
+    } else if (IsCharacterDigitForRadix(*current, radix, 'a')) {
+      digit = static_cast<char>(*current) - 'a' + 10;
+    } else if (IsCharacterDigitForRadix(*current, radix, 'A')) {
+      digit = static_cast<char>(*current) - 'A' + 10;
+    } else {
+      if (allow_trailing_junk || !AdvanceToNonspace(&current, end)) {
+        break;
+      } else {
+        return junk_string_value;
+      }
+    }
+
+    number = number * radix + digit;
+    int overflow = static_cast<int>(number >> kSignificandSize);
+    if (overflow != 0) {
+      // Overflow occurred. Need to determine which direction to round the
+      // result.
+      int overflow_bits_count = 1;
+      while (overflow > 1) {
+        overflow_bits_count++;
+        overflow >>= 1;
+      }
+
+      int dropped_bits_mask = ((1 << overflow_bits_count) - 1);
+      int dropped_bits = static_cast<int>(number) & dropped_bits_mask;
+      number >>= overflow_bits_count;
+      exponent = overflow_bits_count;
+
+      bool zero_tail = true;
+      for (;;) {
+        ++current;
+        if (current == end || !isDigit(*current, radix)) break;
+        zero_tail = zero_tail && *current == '0';
+        exponent += radix_log_2;
+      }
+
+      if (!allow_trailing_junk && AdvanceToNonspace(&current, end)) {
+        return junk_string_value;
+      }
+
+      int middle_value = (1 << (overflow_bits_count - 1));
+      if (dropped_bits > middle_value) {
+        number++;  // Rounding up.
+      } else if (dropped_bits == middle_value) {
+        // Rounding to even to consistency with decimals: half-way case rounds
+        // up if significant part is odd and down otherwise.
+        if ((number & 1) != 0 || !zero_tail) {
+          number++;  // Rounding up.
+        }
+      }
+
+      // Rounding up may cause overflow.
+      if ((number & ((int64_t)1 << kSignificandSize)) != 0) {
+        exponent++;
+        number >>= 1;
+      }
+      break;
+    }
+    ++current;
+  } while (current != end);
+
+  ASSERT(number < ((int64_t)1 << kSignificandSize));
+  ASSERT(static_cast<int64_t>(static_cast<double>(number)) == number);
+
+  *trailing_pointer = current;
+
+  if (exponent == 0) {
+    if (sign) {
+      if (number == 0) return -0.0;
+      number = -number;
+    }
+    return static_cast<double>(number);
+  }
+
+  ASSERT(number != 0);
+  return Double(DiyFp(number, exponent)).value();
+}
+
+
+double StringToDoubleConverter::StringToIeee(
+    const char* input,
+    int length,
+    int* processed_characters_count,
+    bool read_as_double) const {
+  const char* current = input;
+  const char* end = input + length;
+
+  *processed_characters_count = 0;
+
+  const bool allow_trailing_junk = (flags_ & ALLOW_TRAILING_JUNK) != 0;
+  const bool allow_leading_spaces = (flags_ & ALLOW_LEADING_SPACES) != 0;
+  const bool allow_trailing_spaces = (flags_ & ALLOW_TRAILING_SPACES) != 0;
+  const bool allow_spaces_after_sign = (flags_ & ALLOW_SPACES_AFTER_SIGN) != 0;
+
+  // To make sure that iterator dereferencing is valid the following
+  // convention is used:
+  // 1. Each '++current' statement is followed by check for equality to 'end'.
+  // 2. If AdvanceToNonspace returned false then current == end.
+  // 3. If 'current' becomes equal to 'end' the function returns or goes to
+  // 'parsing_done'.
+  // 4. 'current' is not dereferenced after the 'parsing_done' label.
+  // 5. Code before 'parsing_done' may rely on 'current != end'.
+  if (current == end) return empty_string_value_;
+
+  if (allow_leading_spaces || allow_trailing_spaces) {
+    if (!AdvanceToNonspace(&current, end)) {
+      *processed_characters_count = static_cast<int>(current - input);
+      return empty_string_value_;
+    }
+    if (!allow_leading_spaces && (input != current)) {
+      // No leading spaces allowed, but AdvanceToNonspace moved forward.
+      return junk_string_value_;
+    }
+  }
+
+  // The longest form of simplified number is: "-<significant digits>.1eXXX\0".
+  const int kBufferSize = kMaxSignificantDigits + 10;
+  char buffer[kBufferSize];  // NOLINT: size is known at compile time.
+  int buffer_pos = 0;
+
+  // Exponent will be adjusted if insignificant digits of the integer part
+  // or insignificant leading zeros of the fractional part are dropped.
+  int exponent = 0;
+  int significant_digits = 0;
+  int insignificant_digits = 0;
+  bool nonzero_digit_dropped = false;
+
+  bool sign = false;
+
+  if (*current == '+' || *current == '-') {
+    sign = (*current == '-');
+    ++current;
+    const char* next_non_space = current;
+    // Skip following spaces (if allowed).
+    if (!AdvanceToNonspace(&next_non_space, end)) return junk_string_value_;
+    if (!allow_spaces_after_sign && (current != next_non_space)) {
+      return junk_string_value_;
+    }
+    current = next_non_space;
+  }
+
+  if (infinity_symbol_ != NULL) {
+    if (*current == infinity_symbol_[0]) {
+      if (!ConsumeSubString(&current, end, infinity_symbol_)) {
+        return junk_string_value_;
+      }
+
+      if (!(allow_trailing_spaces || allow_trailing_junk) && (current != end)) {
+        return junk_string_value_;
+      }
+      if (!allow_trailing_junk && AdvanceToNonspace(&current, end)) {
+        return junk_string_value_;
+      }
+
+      ASSERT(buffer_pos == 0);
+      *processed_characters_count = static_cast<int>(current - input);
+      return sign ? -Double::Infinity() : Double::Infinity();
+    }
+  }
+
+  if (nan_symbol_ != NULL) {
+    if (*current == nan_symbol_[0]) {
+      if (!ConsumeSubString(&current, end, nan_symbol_)) {
+        return junk_string_value_;
+      }
+
+      if (!(allow_trailing_spaces || allow_trailing_junk) && (current != end)) {
+        return junk_string_value_;
+      }
+      if (!allow_trailing_junk && AdvanceToNonspace(&current, end)) {
+        return junk_string_value_;
+      }
+
+      ASSERT(buffer_pos == 0);
+      *processed_characters_count = static_cast<int>(current - input);
+      return sign ? -Double::NaN() : Double::NaN();
+    }
+  }
+
+  bool leading_zero = false;
+  if (*current == '0') {
+    ++current;
+    if (current == end) {
+      *processed_characters_count = static_cast<int>(current - input);
+      return SignedZero(sign);
+    }
+
+    leading_zero = true;
+
+    // It could be hexadecimal value.
+    if ((flags_ & ALLOW_HEX) && (*current == 'x' || *current == 'X')) {
+      ++current;
+      if (current == end || !isDigit(*current, 16)) {
+        return junk_string_value_;  // "0x".
+      }
+
+      const char* tail_pointer = NULL;
+      double result = RadixStringToIeee<4>(current,
+                                           end,
+                                           sign,
+                                           allow_trailing_junk,
+                                           junk_string_value_,
+                                           read_as_double,
+                                           &tail_pointer);
+      if (tail_pointer != NULL) {
+        if (allow_trailing_spaces) AdvanceToNonspace(&tail_pointer, end);
+        *processed_characters_count = static_cast<int>(tail_pointer - input);
+      }
+      return result;
+    }
+
+    // Ignore leading zeros in the integer part.
+    while (*current == '0') {
+      ++current;
+      if (current == end) {
+        *processed_characters_count = static_cast<int>(current - input);
+        return SignedZero(sign);
+      }
+    }
+  }
+
+  bool octal = leading_zero && (flags_ & ALLOW_OCTALS) != 0;
+
+  // Copy significant digits of the integer part (if any) to the buffer.
+  while (*current >= '0' && *current <= '9') {
+    if (significant_digits < kMaxSignificantDigits) {
+      ASSERT(buffer_pos < kBufferSize);
+      buffer[buffer_pos++] = static_cast<char>(*current);
+      significant_digits++;
+      // Will later check if it's an octal in the buffer.
+    } else {
+      insignificant_digits++;  // Move the digit into the exponential part.
+      nonzero_digit_dropped = nonzero_digit_dropped || *current != '0';
+    }
+    octal = octal && *current < '8';
+    ++current;
+    if (current == end) goto parsing_done;
+  }
+
+  if (significant_digits == 0) {
+    octal = false;
+  }
+
+  if (*current == '.') {
+    if (octal && !allow_trailing_junk) return junk_string_value_;
+    if (octal) goto parsing_done;
+
+    ++current;
+    if (current == end) {
+      if (significant_digits == 0 && !leading_zero) {
+        return junk_string_value_;
+      } else {
+        goto parsing_done;
+      }
+    }
+
+    if (significant_digits == 0) {
+      // octal = false;
+      // Integer part consists of 0 or is absent. Significant digits start after
+      // leading zeros (if any).
+      while (*current == '0') {
+        ++current;
+        if (current == end) {
+          *processed_characters_count = static_cast<int>(current - input);
+          return SignedZero(sign);
+        }
+        exponent--;  // Move this 0 into the exponent.
+      }
+    }
+
+    // There is a fractional part.
+    // We don't emit a '.', but adjust the exponent instead.
+    while (*current >= '0' && *current <= '9') {
+      if (significant_digits < kMaxSignificantDigits) {
+        ASSERT(buffer_pos < kBufferSize);
+        buffer[buffer_pos++] = static_cast<char>(*current);
+        significant_digits++;
+        exponent--;
+      } else {
+        // Ignore insignificant digits in the fractional part.
+        nonzero_digit_dropped = nonzero_digit_dropped || *current != '0';
+      }
+      ++current;
+      if (current == end) goto parsing_done;
+    }
+  }
+
+  if (!leading_zero && exponent == 0 && significant_digits == 0) {
+    // If leading_zeros is true then the string contains zeros.
+    // If exponent < 0 then string was [+-]\.0*...
+    // If significant_digits != 0 the string is not equal to 0.
+    // Otherwise there are no digits in the string.
+    return junk_string_value_;
+  }
+
+  // Parse exponential part.
+  if (*current == 'e' || *current == 'E') {
+    if (octal && !allow_trailing_junk) return junk_string_value_;
+    if (octal) goto parsing_done;
+    ++current;
+    if (current == end) {
+      if (allow_trailing_junk) {
+        goto parsing_done;
+      } else {
+        return junk_string_value_;
+      }
+    }
+    char sign = '+';
+    if (*current == '+' || *current == '-') {
+      sign = static_cast<char>(*current);
+      ++current;
+      if (current == end) {
+        if (allow_trailing_junk) {
+          goto parsing_done;
+        } else {
+          return junk_string_value_;
+        }
+      }
+    }
+
+    if (current == end || *current < '0' || *current > '9') {
+      if (allow_trailing_junk) {
+        goto parsing_done;
+      } else {
+        return junk_string_value_;
+      }
+    }
+
+    const int max_exponent = INT_MAX / 2;
+    ASSERT(-max_exponent / 2 <= exponent && exponent <= max_exponent / 2);
+    int num = 0;
+    do {
+      // Check overflow.
+      int digit = *current - '0';
+      if (num >= max_exponent / 10
+          && !(num == max_exponent / 10 && digit <= max_exponent % 10)) {
+        num = max_exponent;
+      } else {
+        num = num * 10 + digit;
+      }
+      ++current;
+    } while (current != end && *current >= '0' && *current <= '9');
+
+    exponent += (sign == '-' ? -num : num);
+  }
+
+  if (!(allow_trailing_spaces || allow_trailing_junk) && (current != end)) {
+    return junk_string_value_;
+  }
+  if (!allow_trailing_junk && AdvanceToNonspace(&current, end)) {
+    return junk_string_value_;
+  }
+  if (allow_trailing_spaces) {
+    AdvanceToNonspace(&current, end);
+  }
+
+  parsing_done:
+  exponent += insignificant_digits;
+
+  if (octal) {
+    double result;
+    const char* tail_pointer = NULL;
+    result = RadixStringToIeee<3>(buffer,
+                                  buffer + buffer_pos,
+                                  sign,
+                                  allow_trailing_junk,
+                                  junk_string_value_,
+                                  read_as_double,
+                                  &tail_pointer);
+    ASSERT(tail_pointer != NULL);
+    *processed_characters_count = static_cast<int>(current - input);
+    return result;
+  }
+
+  if (nonzero_digit_dropped) {
+    buffer[buffer_pos++] = '1';
+    exponent--;
+  }
+
+  ASSERT(buffer_pos < kBufferSize);
+  buffer[buffer_pos] = '\0';
+
+  double converted;
+  if (read_as_double) {
+    converted = Strtod(Vector<const char>(buffer, buffer_pos), exponent);
+  } else {
+    converted = Strtof(Vector<const char>(buffer, buffer_pos), exponent);
+  }
+  *processed_characters_count = static_cast<int>(current - input);
+  return sign? -converted: converted;
+}
+
+}  // namespace double_conversion

+ 536 - 0
third-party/double-conversion-1.1.6/src/double-conversion.h

@@ -0,0 +1,536 @@
+// Copyright 2012 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.
+
+#ifndef DOUBLE_CONVERSION_DOUBLE_CONVERSION_H_
+#define DOUBLE_CONVERSION_DOUBLE_CONVERSION_H_
+
+#include "utils.h"
+
+namespace double_conversion {
+
+class DoubleToStringConverter {
+ public:
+  // When calling ToFixed with a double > 10^kMaxFixedDigitsBeforePoint
+  // or a requested_digits parameter > kMaxFixedDigitsAfterPoint then the
+  // function returns false.
+  static const int kMaxFixedDigitsBeforePoint = 60;
+  static const int kMaxFixedDigitsAfterPoint = 60;
+
+  // When calling ToExponential with a requested_digits
+  // parameter > kMaxExponentialDigits then the function returns false.
+  static const int kMaxExponentialDigits = 120;
+
+  // When calling ToPrecision with a requested_digits
+  // parameter < kMinPrecisionDigits or requested_digits > kMaxPrecisionDigits
+  // then the function returns false.
+  static const int kMinPrecisionDigits = 1;
+  static const int kMaxPrecisionDigits = 120;
+
+  enum Flags {
+    NO_FLAGS = 0,
+    EMIT_POSITIVE_EXPONENT_SIGN = 1,
+    EMIT_TRAILING_DECIMAL_POINT = 2,
+    EMIT_TRAILING_ZERO_AFTER_POINT = 4,
+    UNIQUE_ZERO = 8
+  };
+
+  // Flags should be a bit-or combination of the possible Flags-enum.
+  //  - NO_FLAGS: no special flags.
+  //  - EMIT_POSITIVE_EXPONENT_SIGN: when the number is converted into exponent
+  //    form, emits a '+' for positive exponents. Example: 1.2e+2.
+  //  - EMIT_TRAILING_DECIMAL_POINT: when the input number is an integer and is
+  //    converted into decimal format then a trailing decimal point is appended.
+  //    Example: 2345.0 is converted to "2345.".
+  //  - EMIT_TRAILING_ZERO_AFTER_POINT: in addition to a trailing decimal point
+  //    emits a trailing '0'-character. This flag requires the
+  //    EXMIT_TRAILING_DECIMAL_POINT flag.
+  //    Example: 2345.0 is converted to "2345.0".
+  //  - UNIQUE_ZERO: "-0.0" is converted to "0.0".
+  //
+  // Infinity symbol and nan_symbol provide the string representation for these
+  // special values. If the string is NULL and the special value is encountered
+  // then the conversion functions return false.
+  //
+  // The exponent_character is used in exponential representations. It is
+  // usually 'e' or 'E'.
+  //
+  // When converting to the shortest representation the converter will
+  // represent input numbers in decimal format if they are in the interval
+  // [10^decimal_in_shortest_low; 10^decimal_in_shortest_high[
+  //    (lower boundary included, greater boundary excluded).
+  // Example: with decimal_in_shortest_low = -6 and
+  //               decimal_in_shortest_high = 21:
+  //   ToShortest(0.000001)  -> "0.000001"
+  //   ToShortest(0.0000001) -> "1e-7"
+  //   ToShortest(111111111111111111111.0)  -> "111111111111111110000"
+  //   ToShortest(100000000000000000000.0)  -> "100000000000000000000"
+  //   ToShortest(1111111111111111111111.0) -> "1.1111111111111111e+21"
+  //
+  // When converting to precision mode the converter may add
+  // max_leading_padding_zeroes before returning the number in exponential
+  // format.
+  // Example with max_leading_padding_zeroes_in_precision_mode = 6.
+  //   ToPrecision(0.0000012345, 2) -> "0.0000012"
+  //   ToPrecision(0.00000012345, 2) -> "1.2e-7"
+  // Similarily the converter may add up to
+  // max_trailing_padding_zeroes_in_precision_mode in precision mode to avoid
+  // returning an exponential representation. A zero added by the
+  // EMIT_TRAILING_ZERO_AFTER_POINT flag is counted for this limit.
+  // Examples for max_trailing_padding_zeroes_in_precision_mode = 1:
+  //   ToPrecision(230.0, 2) -> "230"
+  //   ToPrecision(230.0, 2) -> "230."  with EMIT_TRAILING_DECIMAL_POINT.
+  //   ToPrecision(230.0, 2) -> "2.3e2" with EMIT_TRAILING_ZERO_AFTER_POINT.
+  DoubleToStringConverter(int flags,
+                          const char* infinity_symbol,
+                          const char* nan_symbol,
+                          char exponent_character,
+                          int decimal_in_shortest_low,
+                          int decimal_in_shortest_high,
+                          int max_leading_padding_zeroes_in_precision_mode,
+                          int max_trailing_padding_zeroes_in_precision_mode)
+      : flags_(flags),
+        infinity_symbol_(infinity_symbol),
+        nan_symbol_(nan_symbol),
+        exponent_character_(exponent_character),
+        decimal_in_shortest_low_(decimal_in_shortest_low),
+        decimal_in_shortest_high_(decimal_in_shortest_high),
+        max_leading_padding_zeroes_in_precision_mode_(
+            max_leading_padding_zeroes_in_precision_mode),
+        max_trailing_padding_zeroes_in_precision_mode_(
+            max_trailing_padding_zeroes_in_precision_mode) {
+    // When 'trailing zero after the point' is set, then 'trailing point'
+    // must be set too.
+    ASSERT(((flags & EMIT_TRAILING_DECIMAL_POINT) != 0) ||
+        !((flags & EMIT_TRAILING_ZERO_AFTER_POINT) != 0));
+  }
+
+  // Returns a converter following the EcmaScript specification.
+  static const DoubleToStringConverter& EcmaScriptConverter();
+
+  // Computes the shortest string of digits that correctly represent the input
+  // number. Depending on decimal_in_shortest_low and decimal_in_shortest_high
+  // (see constructor) it then either returns a decimal representation, or an
+  // exponential representation.
+  // Example with decimal_in_shortest_low = -6,
+  //              decimal_in_shortest_high = 21,
+  //              EMIT_POSITIVE_EXPONENT_SIGN activated, and
+  //              EMIT_TRAILING_DECIMAL_POINT deactived:
+  //   ToShortest(0.000001)  -> "0.000001"
+  //   ToShortest(0.0000001) -> "1e-7"
+  //   ToShortest(111111111111111111111.0)  -> "111111111111111110000"
+  //   ToShortest(100000000000000000000.0)  -> "100000000000000000000"
+  //   ToShortest(1111111111111111111111.0) -> "1.1111111111111111e+21"
+  //
+  // Note: the conversion may round the output if the returned string
+  // is accurate enough to uniquely identify the input-number.
+  // For example the most precise representation of the double 9e59 equals
+  // "899999999999999918767229449717619953810131273674690656206848", but
+  // the converter will return the shorter (but still correct) "9e59".
+  //
+  // Returns true if the conversion succeeds. The conversion always succeeds
+  // except when the input value is special and no infinity_symbol or
+  // nan_symbol has been given to the constructor.
+  bool ToShortest(double value, StringBuilder* result_builder) const {
+    return ToShortestIeeeNumber(value, result_builder, SHORTEST);
+  }
+
+  // Same as ToShortest, but for single-precision floats.
+  bool ToShortestSingle(float value, StringBuilder* result_builder) const {
+    return ToShortestIeeeNumber(value, result_builder, SHORTEST_SINGLE);
+  }
+
+
+  // Computes a decimal representation with a fixed number of digits after the
+  // decimal point. The last emitted digit is rounded.
+  //
+  // Examples:
+  //   ToFixed(3.12, 1) -> "3.1"
+  //   ToFixed(3.1415, 3) -> "3.142"
+  //   ToFixed(1234.56789, 4) -> "1234.5679"
+  //   ToFixed(1.23, 5) -> "1.23000"
+  //   ToFixed(0.1, 4) -> "0.1000"
+  //   ToFixed(1e30, 2) -> "1000000000000000019884624838656.00"
+  //   ToFixed(0.1, 30) -> "0.100000000000000005551115123126"
+  //   ToFixed(0.1, 17) -> "0.10000000000000001"
+  //
+  // If requested_digits equals 0, then the tail of the result depends on
+  // the EMIT_TRAILING_DECIMAL_POINT and EMIT_TRAILING_ZERO_AFTER_POINT.
+  // Examples, for requested_digits == 0,
+  //   let EMIT_TRAILING_DECIMAL_POINT and EMIT_TRAILING_ZERO_AFTER_POINT be
+  //    - false and false: then 123.45 -> 123
+  //                             0.678 -> 1
+  //    - true and false: then 123.45 -> 123.
+  //                            0.678 -> 1.
+  //    - true and true: then 123.45 -> 123.0
+  //                           0.678 -> 1.0
+  //
+  // Returns true if the conversion succeeds. The conversion always succeeds
+  // except for the following cases:
+  //   - the input value is special and no infinity_symbol or nan_symbol has
+  //     been provided to the constructor,
+  //   - 'value' > 10^kMaxFixedDigitsBeforePoint, or
+  //   - 'requested_digits' > kMaxFixedDigitsAfterPoint.
+  // The last two conditions imply that the result will never contain more than
+  // 1 + kMaxFixedDigitsBeforePoint + 1 + kMaxFixedDigitsAfterPoint characters
+  // (one additional character for the sign, and one for the decimal point).
+  bool ToFixed(double value,
+               int requested_digits,
+               StringBuilder* result_builder) const;
+
+  // Computes a representation in exponential format with requested_digits
+  // after the decimal point. The last emitted digit is rounded.
+  // If requested_digits equals -1, then the shortest exponential representation
+  // is computed.
+  //
+  // Examples with EMIT_POSITIVE_EXPONENT_SIGN deactivated, and
+  //               exponent_character set to 'e'.
+  //   ToExponential(3.12, 1) -> "3.1e0"
+  //   ToExponential(5.0, 3) -> "5.000e0"
+  //   ToExponential(0.001, 2) -> "1.00e-3"
+  //   ToExponential(3.1415, -1) -> "3.1415e0"
+  //   ToExponential(3.1415, 4) -> "3.1415e0"
+  //   ToExponential(3.1415, 3) -> "3.142e0"
+  //   ToExponential(123456789000000, 3) -> "1.235e14"
+  //   ToExponential(1000000000000000019884624838656.0, -1) -> "1e30"
+  //   ToExponential(1000000000000000019884624838656.0, 32) ->
+  //                     "1.00000000000000001988462483865600e30"
+  //   ToExponential(1234, 0) -> "1e3"
+  //
+  // Returns true if the conversion succeeds. The conversion always succeeds
+  // except for the following cases:
+  //   - the input value is special and no infinity_symbol or nan_symbol has
+  //     been provided to the constructor,
+  //   - 'requested_digits' > kMaxExponentialDigits.
+  // The last condition implies that the result will never contain more than
+  // kMaxExponentialDigits + 8 characters (the sign, the digit before the
+  // decimal point, the decimal point, the exponent character, the
+  // exponent's sign, and at most 3 exponent digits).
+  bool ToExponential(double value,
+                     int requested_digits,
+                     StringBuilder* result_builder) const;
+
+  // Computes 'precision' leading digits of the given 'value' and returns them
+  // either in exponential or decimal format, depending on
+  // max_{leading|trailing}_padding_zeroes_in_precision_mode (given to the
+  // constructor).
+  // The last computed digit is rounded.
+  //
+  // Example with max_leading_padding_zeroes_in_precision_mode = 6.
+  //   ToPrecision(0.0000012345, 2) -> "0.0000012"
+  //   ToPrecision(0.00000012345, 2) -> "1.2e-7"
+  // Similarily the converter may add up to
+  // max_trailing_padding_zeroes_in_precision_mode in precision mode to avoid
+  // returning an exponential representation. A zero added by the
+  // EMIT_TRAILING_ZERO_AFTER_POINT flag is counted for this limit.
+  // Examples for max_trailing_padding_zeroes_in_precision_mode = 1:
+  //   ToPrecision(230.0, 2) -> "230"
+  //   ToPrecision(230.0, 2) -> "230."  with EMIT_TRAILING_DECIMAL_POINT.
+  //   ToPrecision(230.0, 2) -> "2.3e2" with EMIT_TRAILING_ZERO_AFTER_POINT.
+  // Examples for max_trailing_padding_zeroes_in_precision_mode = 3, and no
+  //    EMIT_TRAILING_ZERO_AFTER_POINT:
+  //   ToPrecision(123450.0, 6) -> "123450"
+  //   ToPrecision(123450.0, 5) -> "123450"
+  //   ToPrecision(123450.0, 4) -> "123500"
+  //   ToPrecision(123450.0, 3) -> "123000"
+  //   ToPrecision(123450.0, 2) -> "1.2e5"
+  //
+  // Returns true if the conversion succeeds. The conversion always succeeds
+  // except for the following cases:
+  //   - the input value is special and no infinity_symbol or nan_symbol has
+  //     been provided to the constructor,
+  //   - precision < kMinPericisionDigits
+  //   - precision > kMaxPrecisionDigits
+  // The last condition implies that the result will never contain more than
+  // kMaxPrecisionDigits + 7 characters (the sign, the decimal point, the
+  // exponent character, the exponent's sign, and at most 3 exponent digits).
+  bool ToPrecision(double value,
+                   int precision,
+                   StringBuilder* result_builder) const;
+
+  enum DtoaMode {
+    // Produce the shortest correct representation.
+    // For example the output of 0.299999999999999988897 is (the less accurate
+    // but correct) 0.3.
+    SHORTEST,
+    // Same as SHORTEST, but for single-precision floats.
+    SHORTEST_SINGLE,
+    // Produce a fixed number of digits after the decimal point.
+    // For instance fixed(0.1, 4) becomes 0.1000
+    // If the input number is big, the output will be big.
+    FIXED,
+    // Fixed number of digits (independent of the decimal point).
+    PRECISION
+  };
+
+  // The maximal number of digits that are needed to emit a double in base 10.
+  // A higher precision can be achieved by using more digits, but the shortest
+  // accurate representation of any double will never use more digits than
+  // kBase10MaximalLength.
+  // Note that DoubleToAscii null-terminates its input. So the given buffer
+  // should be at least kBase10MaximalLength + 1 characters long.
+  static const int kBase10MaximalLength = 17;
+
+  // Converts the given double 'v' to ascii. 'v' must not be NaN, +Infinity, or
+  // -Infinity. In SHORTEST_SINGLE-mode this restriction also applies to 'v'
+  // after it has been casted to a single-precision float. That is, in this
+  // mode static_cast<float>(v) must not be NaN, +Infinity or -Infinity.
+  //
+  // The result should be interpreted as buffer * 10^(point-length).
+  //
+  // The output depends on the given mode:
+  //  - SHORTEST: produce the least amount of digits for which the internal
+  //   identity requirement is still satisfied. If the digits are printed
+  //   (together with the correct exponent) then reading this number will give
+  //   'v' again. The buffer will choose the representation that is closest to
+  //   'v'. If there are two at the same distance, than the one farther away
+  //   from 0 is chosen (halfway cases - ending with 5 - are rounded up).
+  //   In this mode the 'requested_digits' parameter is ignored.
+  //  - SHORTEST_SINGLE: same as SHORTEST but with single-precision.
+  //  - FIXED: produces digits necessary to print a given number with
+  //   'requested_digits' digits after the decimal point. The produced digits
+  //   might be too short in which case the caller has to fill the remainder
+  //   with '0's.
+  //   Example: toFixed(0.001, 5) is allowed to return buffer="1", point=-2.
+  //   Halfway cases are rounded towards +/-Infinity (away from 0). The call
+  //   toFixed(0.15, 2) thus returns buffer="2", point=0.
+  //   The returned buffer may contain digits that would be truncated from the
+  //   shortest representation of the input.
+  //  - PRECISION: produces 'requested_digits' where the first digit is not '0'.
+  //   Even though the length of produced digits usually equals
+  //   'requested_digits', the function is allowed to return fewer digits, in
+  //   which case the caller has to fill the missing digits with '0's.
+  //   Halfway cases are again rounded away from 0.
+  // DoubleToAscii expects the given buffer to be big enough to hold all
+  // digits and a terminating null-character. In SHORTEST-mode it expects a
+  // buffer of at least kBase10MaximalLength + 1. In all other modes the
+  // requested_digits parameter and the padding-zeroes limit the size of the
+  // output. Don't forget the decimal point, the exponent character and the
+  // terminating null-character when computing the maximal output size.
+  // The given length is only used in debug mode to ensure the buffer is big
+  // enough.
+  static void DoubleToAscii(double v,
+                            DtoaMode mode,
+                            int requested_digits,
+                            char* buffer,
+                            int buffer_length,
+                            bool* sign,
+                            int* length,
+                            int* point);
+
+ private:
+  // Implementation for ToShortest and ToShortestSingle.
+  bool ToShortestIeeeNumber(double value,
+                            StringBuilder* result_builder,
+                            DtoaMode mode) const;
+
+  // If the value is a special value (NaN or Infinity) constructs the
+  // corresponding string using the configured infinity/nan-symbol.
+  // If either of them is NULL or the value is not special then the
+  // function returns false.
+  bool HandleSpecialValues(double value, StringBuilder* result_builder) const;
+  // Constructs an exponential representation (i.e. 1.234e56).
+  // The given exponent assumes a decimal point after the first decimal digit.
+  void CreateExponentialRepresentation(const char* decimal_digits,
+                                       int length,
+                                       int exponent,
+                                       StringBuilder* result_builder) const;
+  // Creates a decimal representation (i.e 1234.5678).
+  void CreateDecimalRepresentation(const char* decimal_digits,
+                                   int length,
+                                   int decimal_point,
+                                   int digits_after_point,
+                                   StringBuilder* result_builder) const;
+
+  const int flags_;
+  const char* const infinity_symbol_;
+  const char* const nan_symbol_;
+  const char exponent_character_;
+  const int decimal_in_shortest_low_;
+  const int decimal_in_shortest_high_;
+  const int max_leading_padding_zeroes_in_precision_mode_;
+  const int max_trailing_padding_zeroes_in_precision_mode_;
+
+  DISALLOW_IMPLICIT_CONSTRUCTORS(DoubleToStringConverter);
+};
+
+
+class StringToDoubleConverter {
+ public:
+  // Enumeration for allowing octals and ignoring junk when converting
+  // strings to numbers.
+  enum Flags {
+    NO_FLAGS = 0,
+    ALLOW_HEX = 1,
+    ALLOW_OCTALS = 2,
+    ALLOW_TRAILING_JUNK = 4,
+    ALLOW_LEADING_SPACES = 8,
+    ALLOW_TRAILING_SPACES = 16,
+    ALLOW_SPACES_AFTER_SIGN = 32
+  };
+
+  // Flags should be a bit-or combination of the possible Flags-enum.
+  //  - NO_FLAGS: no special flags.
+  //  - ALLOW_HEX: recognizes the prefix "0x". Hex numbers may only be integers.
+  //      Ex: StringToDouble("0x1234") -> 4660.0
+  //          In StringToDouble("0x1234.56") the characters ".56" are trailing
+  //          junk. The result of the call is hence dependent on
+  //          the ALLOW_TRAILING_JUNK flag and/or the junk value.
+  //      With this flag "0x" is a junk-string. Even with ALLOW_TRAILING_JUNK,
+  //      the string will not be parsed as "0" followed by junk.
+  //
+  //  - ALLOW_OCTALS: recognizes the prefix "0" for octals:
+  //      If a sequence of octal digits starts with '0', then the number is
+  //      read as octal integer. Octal numbers may only be integers.
+  //      Ex: StringToDouble("01234") -> 668.0
+  //          StringToDouble("012349") -> 12349.0  // Not a sequence of octal
+  //                                               // digits.
+  //          In StringToDouble("01234.56") the characters ".56" are trailing
+  //          junk. The result of the call is hence dependent on
+  //          the ALLOW_TRAILING_JUNK flag and/or the junk value.
+  //          In StringToDouble("01234e56") the characters "e56" are trailing
+  //          junk, too.
+  //  - ALLOW_TRAILING_JUNK: ignore trailing characters that are not part of
+  //      a double literal.
+  //  - ALLOW_LEADING_SPACES: skip over leading spaces.
+  //  - ALLOW_TRAILING_SPACES: ignore trailing spaces.
+  //  - ALLOW_SPACES_AFTER_SIGN: ignore spaces after the sign.
+  //       Ex: StringToDouble("-   123.2") -> -123.2.
+  //           StringToDouble("+   123.2") -> 123.2
+  //
+  // empty_string_value is returned when an empty string is given as input.
+  // If ALLOW_LEADING_SPACES or ALLOW_TRAILING_SPACES are set, then a string
+  // containing only spaces is converted to the 'empty_string_value', too.
+  //
+  // junk_string_value is returned when
+  //  a) ALLOW_TRAILING_JUNK is not set, and a junk character (a character not
+  //     part of a double-literal) is found.
+  //  b) ALLOW_TRAILING_JUNK is set, but the string does not start with a
+  //     double literal.
+  //
+  // infinity_symbol and nan_symbol are strings that are used to detect
+  // inputs that represent infinity and NaN. They can be null, in which case
+  // they are ignored.
+  // The conversion routine first reads any possible signs. Then it compares the
+  // following character of the input-string with the first character of
+  // the infinity, and nan-symbol. If either matches, the function assumes, that
+  // a match has been found, and expects the following input characters to match
+  // the remaining characters of the special-value symbol.
+  // This means that the following restrictions apply to special-value symbols:
+  //  - they must not start with signs ('+', or '-'),
+  //  - they must not have the same first character.
+  //  - they must not start with digits.
+  //
+  // Examples:
+  //  flags = ALLOW_HEX | ALLOW_TRAILING_JUNK,
+  //  empty_string_value = 0.0,
+  //  junk_string_value = NaN,
+  //  infinity_symbol = "infinity",
+  //  nan_symbol = "nan":
+  //    StringToDouble("0x1234") -> 4660.0.
+  //    StringToDouble("0x1234K") -> 4660.0.
+  //    StringToDouble("") -> 0.0  // empty_string_value.
+  //    StringToDouble(" ") -> NaN  // junk_string_value.
+  //    StringToDouble(" 1") -> NaN  // junk_string_value.
+  //    StringToDouble("0x") -> NaN  // junk_string_value.
+  //    StringToDouble("-123.45") -> -123.45.
+  //    StringToDouble("--123.45") -> NaN  // junk_string_value.
+  //    StringToDouble("123e45") -> 123e45.
+  //    StringToDouble("123E45") -> 123e45.
+  //    StringToDouble("123e+45") -> 123e45.
+  //    StringToDouble("123E-45") -> 123e-45.
+  //    StringToDouble("123e") -> 123.0  // trailing junk ignored.
+  //    StringToDouble("123e-") -> 123.0  // trailing junk ignored.
+  //    StringToDouble("+NaN") -> NaN  // NaN string literal.
+  //    StringToDouble("-infinity") -> -inf.  // infinity literal.
+  //    StringToDouble("Infinity") -> NaN  // junk_string_value.
+  //
+  //  flags = ALLOW_OCTAL | ALLOW_LEADING_SPACES,
+  //  empty_string_value = 0.0,
+  //  junk_string_value = NaN,
+  //  infinity_symbol = NULL,
+  //  nan_symbol = NULL:
+  //    StringToDouble("0x1234") -> NaN  // junk_string_value.
+  //    StringToDouble("01234") -> 668.0.
+  //    StringToDouble("") -> 0.0  // empty_string_value.
+  //    StringToDouble(" ") -> 0.0  // empty_string_value.
+  //    StringToDouble(" 1") -> 1.0
+  //    StringToDouble("0x") -> NaN  // junk_string_value.
+  //    StringToDouble("0123e45") -> NaN  // junk_string_value.
+  //    StringToDouble("01239E45") -> 1239e45.
+  //    StringToDouble("-infinity") -> NaN  // junk_string_value.
+  //    StringToDouble("NaN") -> NaN  // junk_string_value.
+  StringToDoubleConverter(int flags,
+                          double empty_string_value,
+                          double junk_string_value,
+                          const char* infinity_symbol,
+                          const char* nan_symbol)
+      : flags_(flags),
+        empty_string_value_(empty_string_value),
+        junk_string_value_(junk_string_value),
+        infinity_symbol_(infinity_symbol),
+        nan_symbol_(nan_symbol) {
+  }
+
+  // Performs the conversion.
+  // The output parameter 'processed_characters_count' is set to the number
+  // of characters that have been processed to read the number.
+  // Spaces than are processed with ALLOW_{LEADING|TRAILING}_SPACES are included
+  // in the 'processed_characters_count'. Trailing junk is never included.
+  double StringToDouble(const char* buffer,
+                        int length,
+                        int* processed_characters_count) const {
+    return StringToIeee(buffer, length, processed_characters_count, true);
+  }
+
+  // Same as StringToDouble but reads a float.
+  // Note that this is not equivalent to static_cast<float>(StringToDouble(...))
+  // due to potential double-rounding.
+  float StringToFloat(const char* buffer,
+                      int length,
+                      int* processed_characters_count) const {
+    return static_cast<float>(StringToIeee(buffer, length,
+                                           processed_characters_count, false));
+  }
+
+ private:
+  const int flags_;
+  const double empty_string_value_;
+  const double junk_string_value_;
+  const char* const infinity_symbol_;
+  const char* const nan_symbol_;
+
+  double StringToIeee(const char* buffer,
+                      int length,
+                      int* processed_characters_count,
+                      bool read_as_double) const;
+
+  DISALLOW_IMPLICIT_CONSTRUCTORS(StringToDoubleConverter);
+};
+
+}  // namespace double_conversion
+
+#endif  // DOUBLE_CONVERSION_DOUBLE_CONVERSION_H_

+ 665 - 0
third-party/double-conversion-1.1.6/src/fast-dtoa.cc

@@ -0,0 +1,665 @@
+// Copyright 2012 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 "fast-dtoa.h"
+
+#include "cached-powers.h"
+#include "diy-fp.h"
+#include "ieee.h"
+
+namespace double_conversion {
+
+// The minimal and maximal target exponent define the range of w's binary
+// exponent, where 'w' is the result of multiplying the input by a cached power
+// of ten.
+//
+// A different range might be chosen on a different platform, to optimize digit
+// generation, but a smaller range requires more powers of ten to be cached.
+static const int kMinimalTargetExponent = -60;
+static const int kMaximalTargetExponent = -32;
+
+
+// Adjusts the last digit of the generated number, and screens out generated
+// solutions that may be inaccurate. A solution may be inaccurate if it is
+// outside the safe interval, or if we cannot prove that it is closer to the
+// input than a neighboring representation of the same length.
+//
+// Input: * buffer containing the digits of too_high / 10^kappa
+//        * the buffer's length
+//        * distance_too_high_w == (too_high - w).f() * unit
+//        * unsafe_interval == (too_high - too_low).f() * unit
+//        * rest = (too_high - buffer * 10^kappa).f() * unit
+//        * ten_kappa = 10^kappa * unit
+//        * unit = the common multiplier
+// Output: returns true if the buffer is guaranteed to contain the closest
+//    representable number to the input.
+//  Modifies the generated digits in the buffer to approach (round towards) w.
+static bool RoundWeed(Vector<char> buffer,
+                      int length,
+                      uint64_t distance_too_high_w,
+                      uint64_t unsafe_interval,
+                      uint64_t rest,
+                      uint64_t ten_kappa,
+                      uint64_t unit) {
+  uint64_t small_distance = distance_too_high_w - unit;
+  uint64_t big_distance = distance_too_high_w + unit;
+  // Let w_low  = too_high - big_distance, and
+  //     w_high = too_high - small_distance.
+  // Note: w_low < w < w_high
+  //
+  // The real w (* unit) must lie somewhere inside the interval
+  // ]w_low; w_high[ (often written as "(w_low; w_high)")
+
+  // Basically the buffer currently contains a number in the unsafe interval
+  // ]too_low; too_high[ with too_low < w < too_high
+  //
+  //  too_high - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+  //                     ^v 1 unit            ^      ^                 ^      ^
+  //  boundary_high ---------------------     .      .                 .      .
+  //                     ^v 1 unit            .      .                 .      .
+  //   - - - - - - - - - - - - - - - - - - -  +  - - + - - - - - -     .      .
+  //                                          .      .         ^       .      .
+  //                                          .  big_distance  .       .      .
+  //                                          .      .         .       .    rest
+  //                              small_distance     .         .       .      .
+  //                                          v      .         .       .      .
+  //  w_high - - - - - - - - - - - - - - - - - -     .         .       .      .
+  //                     ^v 1 unit                   .         .       .      .
+  //  w ----------------------------------------     .         .       .      .
+  //                     ^v 1 unit                   v         .       .      .
+  //  w_low  - - - - - - - - - - - - - - - - - - - - -         .       .      .
+  //                                                           .       .      v
+  //  buffer --------------------------------------------------+-------+--------
+  //                                                           .       .
+  //                                                  safe_interval    .
+  //                                                           v       .
+  //   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -     .
+  //                     ^v 1 unit                                     .
+  //  boundary_low -------------------------                     unsafe_interval
+  //                     ^v 1 unit                                     v
+  //  too_low  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+  //
+  //
+  // Note that the value of buffer could lie anywhere inside the range too_low
+  // to too_high.
+  //
+  // boundary_low, boundary_high and w are approximations of the real boundaries
+  // and v (the input number). They are guaranteed to be precise up to one unit.
+  // In fact the error is guaranteed to be strictly less than one unit.
+  //
+  // Anything that lies outside the unsafe interval is guaranteed not to round
+  // to v when read again.
+  // Anything that lies inside the safe interval is guaranteed to round to v
+  // when read again.
+  // If the number inside the buffer lies inside the unsafe interval but not
+  // inside the safe interval then we simply do not know and bail out (returning
+  // false).
+  //
+  // Similarly we have to take into account the imprecision of 'w' when finding
+  // the closest representation of 'w'. If we have two potential
+  // representations, and one is closer to both w_low and w_high, then we know
+  // it is closer to the actual value v.
+  //
+  // By generating the digits of too_high we got the largest (closest to
+  // too_high) buffer that is still in the unsafe interval. In the case where
+  // w_high < buffer < too_high we try to decrement the buffer.
+  // This way the buffer approaches (rounds towards) w.
+  // There are 3 conditions that stop the decrementation process:
+  //   1) the buffer is already below w_high
+  //   2) decrementing the buffer would make it leave the unsafe interval
+  //   3) decrementing the buffer would yield a number below w_high and farther
+  //      away than the current number. In other words:
+  //              (buffer{-1} < w_high) && w_high - buffer{-1} > buffer - w_high
+  // Instead of using the buffer directly we use its distance to too_high.
+  // Conceptually rest ~= too_high - buffer
+  // We need to do the following tests in this order to avoid over- and
+  // underflows.
+  ASSERT(rest <= unsafe_interval);
+  while (rest < small_distance &&  // Negated condition 1
+         unsafe_interval - rest >= ten_kappa &&  // Negated condition 2
+         (rest + ten_kappa < small_distance ||  // buffer{-1} > w_high
+          small_distance - rest >= rest + ten_kappa - small_distance)) {
+    buffer[length - 1]--;
+    rest += ten_kappa;
+  }
+
+  // We have approached w+ as much as possible. We now test if approaching w-
+  // would require changing the buffer. If yes, then we have two possible
+  // representations close to w, but we cannot decide which one is closer.
+  if (rest < big_distance &&
+      unsafe_interval - rest >= ten_kappa &&
+      (rest + ten_kappa < big_distance ||
+       big_distance - rest > rest + ten_kappa - big_distance)) {
+    return false;
+  }
+
+  // Weeding test.
+  //   The safe interval is [too_low + 2 ulp; too_high - 2 ulp]
+  //   Since too_low = too_high - unsafe_interval this is equivalent to
+  //      [too_high - unsafe_interval + 4 ulp; too_high - 2 ulp]
+  //   Conceptually we have: rest ~= too_high - buffer
+  return (2 * unit <= rest) && (rest <= unsafe_interval - 4 * unit);
+}
+
+
+// Rounds the buffer upwards if the result is closer to v by possibly adding
+// 1 to the buffer. If the precision of the calculation is not sufficient to
+// round correctly, return false.
+// The rounding might shift the whole buffer in which case the kappa is
+// adjusted. For example "99", kappa = 3 might become "10", kappa = 4.
+//
+// If 2*rest > ten_kappa then the buffer needs to be round up.
+// rest can have an error of +/- 1 unit. This function accounts for the
+// imprecision and returns false, if the rounding direction cannot be
+// unambiguously determined.
+//
+// Precondition: rest < ten_kappa.
+static bool RoundWeedCounted(Vector<char> buffer,
+                             int length,
+                             uint64_t rest,
+                             uint64_t ten_kappa,
+                             uint64_t unit,
+                             int* kappa) {
+  ASSERT(rest < ten_kappa);
+  // The following tests are done in a specific order to avoid overflows. They
+  // will work correctly with any uint64 values of rest < ten_kappa and unit.
+  //
+  // If the unit is too big, then we don't know which way to round. For example
+  // a unit of 50 means that the real number lies within rest +/- 50. If
+  // 10^kappa == 40 then there is no way to tell which way to round.
+  if (unit >= ten_kappa) return false;
+  // Even if unit is just half the size of 10^kappa we are already completely
+  // lost. (And after the previous test we know that the expression will not
+  // over/underflow.)
+  if (ten_kappa - unit <= unit) return false;
+  // If 2 * (rest + unit) <= 10^kappa we can safely round down.
+  if ((ten_kappa - rest > rest) && (ten_kappa - 2 * rest >= 2 * unit)) {
+    return true;
+  }
+  // If 2 * (rest - unit) >= 10^kappa, then we can safely round up.
+  if ((rest > unit) && (ten_kappa - (rest - unit) <= (rest - unit))) {
+    // Increment the last digit recursively until we find a non '9' digit.
+    buffer[length - 1]++;
+    for (int i = length - 1; i > 0; --i) {
+      if (buffer[i] != '0' + 10) break;
+      buffer[i] = '0';
+      buffer[i - 1]++;
+    }
+    // If the first digit is now '0'+ 10 we had a buffer with all '9's. With the
+    // exception of the first digit all digits are now '0'. Simply switch the
+    // first digit to '1' and adjust the kappa. Example: "99" becomes "10" and
+    // the power (the kappa) is increased.
+    if (buffer[0] == '0' + 10) {
+      buffer[0] = '1';
+      (*kappa) += 1;
+    }
+    return true;
+  }
+  return false;
+}
+
+// Returns the biggest power of ten that is less than or equal to the given
+// number. We furthermore receive the maximum number of bits 'number' has.
+//
+// Returns power == 10^(exponent_plus_one-1) such that
+//    power <= number < power * 10.
+// If number_bits == 0 then 0^(0-1) is returned.
+// The number of bits must be <= 32.
+// Precondition: number < (1 << (number_bits + 1)).
+
+// Inspired by the method for finding an integer log base 10 from here:
+// http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10
+static unsigned int const kSmallPowersOfTen[] =
+    {0, 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000,
+     1000000000};
+
+static void BiggestPowerTen(uint32_t number,
+                            int number_bits,
+                            uint32_t* power,
+                            int* exponent_plus_one) {
+  ASSERT(number < (1u << (number_bits + 1)));
+  // 1233/4096 is approximately 1/lg(10).
+  int exponent_plus_one_guess = ((number_bits + 1) * 1233 >> 12);
+  // We increment to skip over the first entry in the kPowersOf10 table.
+  // Note: kPowersOf10[i] == 10^(i-1).
+  exponent_plus_one_guess++;
+  // We don't have any guarantees that 2^number_bits <= number.
+  if (number < kSmallPowersOfTen[exponent_plus_one_guess]) {
+    exponent_plus_one_guess--;
+  }
+  *power = kSmallPowersOfTen[exponent_plus_one_guess];
+  *exponent_plus_one = exponent_plus_one_guess;
+}
+
+// Generates the digits of input number w.
+// w is a floating-point number (DiyFp), consisting of a significand and an
+// exponent. Its exponent is bounded by kMinimalTargetExponent and
+// kMaximalTargetExponent.
+//       Hence -60 <= w.e() <= -32.
+//
+// Returns false if it fails, in which case the generated digits in the buffer
+// should not be used.
+// Preconditions:
+//  * low, w and high are correct up to 1 ulp (unit in the last place). That
+//    is, their error must be less than a unit of their last digits.
+//  * low.e() == w.e() == high.e()
+//  * low < w < high, and taking into account their error: low~ <= high~
+//  * kMinimalTargetExponent <= w.e() <= kMaximalTargetExponent
+// Postconditions: returns false if procedure fails.
+//   otherwise:
+//     * buffer is not null-terminated, but len contains the number of digits.
+//     * buffer contains the shortest possible decimal digit-sequence
+//       such that LOW < buffer * 10^kappa < HIGH, where LOW and HIGH are the
+//       correct values of low and high (without their error).
+//     * if more than one decimal representation gives the minimal number of
+//       decimal digits then the one closest to W (where W is the correct value
+//       of w) is chosen.
+// Remark: this procedure takes into account the imprecision of its input
+//   numbers. If the precision is not enough to guarantee all the postconditions
+//   then false is returned. This usually happens rarely (~0.5%).
+//
+// Say, for the sake of example, that
+//   w.e() == -48, and w.f() == 0x1234567890abcdef
+// w's value can be computed by w.f() * 2^w.e()
+// We can obtain w's integral digits by simply shifting w.f() by -w.e().
+//  -> w's integral part is 0x1234
+//  w's fractional part is therefore 0x567890abcdef.
+// Printing w's integral part is easy (simply print 0x1234 in decimal).
+// In order to print its fraction we repeatedly multiply the fraction by 10 and
+// get each digit. Example the first digit after the point would be computed by
+//   (0x567890abcdef * 10) >> 48. -> 3
+// The whole thing becomes slightly more complicated because we want to stop
+// once we have enough digits. That is, once the digits inside the buffer
+// represent 'w' we can stop. Everything inside the interval low - high
+// represents w. However we have to pay attention to low, high and w's
+// imprecision.
+static bool DigitGen(DiyFp low,
+                     DiyFp w,
+                     DiyFp high,
+                     Vector<char> buffer,
+                     int* length,
+                     int* kappa) {
+  ASSERT(low.e() == w.e() && w.e() == high.e());
+  ASSERT(low.f() + 1 <= high.f() - 1);
+  ASSERT(kMinimalTargetExponent <= w.e() && w.e() <= kMaximalTargetExponent);
+  // low, w and high are imprecise, but by less than one ulp (unit in the last
+  // place).
+  // If we remove (resp. add) 1 ulp from low (resp. high) we are certain that
+  // the new numbers are outside of the interval we want the final
+  // representation to lie in.
+  // Inversely adding (resp. removing) 1 ulp from low (resp. high) would yield
+  // numbers that are certain to lie in the interval. We will use this fact
+  // later on.
+  // We will now start by generating the digits within the uncertain
+  // interval. Later we will weed out representations that lie outside the safe
+  // interval and thus _might_ lie outside the correct interval.
+  uint64_t unit = 1;
+  DiyFp too_low = DiyFp(low.f() - unit, low.e());
+  DiyFp too_high = DiyFp(high.f() + unit, high.e());
+  // too_low and too_high are guaranteed to lie outside the interval we want the
+  // generated number in.
+  DiyFp unsafe_interval = DiyFp::Minus(too_high, too_low);
+  // We now cut the input number into two parts: the integral digits and the
+  // fractionals. We will not write any decimal separator though, but adapt
+  // kappa instead.
+  // Reminder: we are currently computing the digits (stored inside the buffer)
+  // such that:   too_low < buffer * 10^kappa < too_high
+  // We use too_high for the digit_generation and stop as soon as possible.
+  // If we stop early we effectively round down.
+  DiyFp one = DiyFp(static_cast<uint64_t>(1) << -w.e(), w.e());
+  // Division by one is a shift.
+  uint32_t integrals = static_cast<uint32_t>(too_high.f() >> -one.e());
+  // Modulo by one is an and.
+  uint64_t fractionals = too_high.f() & (one.f() - 1);
+  uint32_t divisor;
+  int divisor_exponent_plus_one;
+  BiggestPowerTen(integrals, DiyFp::kSignificandSize - (-one.e()),
+                  &divisor, &divisor_exponent_plus_one);
+  *kappa = divisor_exponent_plus_one;
+  *length = 0;
+  // Loop invariant: buffer = too_high / 10^kappa  (integer division)
+  // The invariant holds for the first iteration: kappa has been initialized
+  // with the divisor exponent + 1. And the divisor is the biggest power of ten
+  // that is smaller than integrals.
+  while (*kappa > 0) {
+    int digit = integrals / divisor;
+    ASSERT(digit <= 9);
+    buffer[*length] = static_cast<char>('0' + digit);
+    (*length)++;
+    integrals %= divisor;
+    (*kappa)--;
+    // Note that kappa now equals the exponent of the divisor and that the
+    // invariant thus holds again.
+    uint64_t rest =
+        (static_cast<uint64_t>(integrals) << -one.e()) + fractionals;
+    // Invariant: too_high = buffer * 10^kappa + DiyFp(rest, one.e())
+    // Reminder: unsafe_interval.e() == one.e()
+    if (rest < unsafe_interval.f()) {
+      // Rounding down (by not emitting the remaining digits) yields a number
+      // that lies within the unsafe interval.
+      return RoundWeed(buffer, *length, DiyFp::Minus(too_high, w).f(),
+                       unsafe_interval.f(), rest,
+                       static_cast<uint64_t>(divisor) << -one.e(), unit);
+    }
+    divisor /= 10;
+  }
+
+  // The integrals have been generated. We are at the point of the decimal
+  // separator. In the following loop we simply multiply the remaining digits by
+  // 10 and divide by one. We just need to pay attention to multiply associated
+  // data (like the interval or 'unit'), too.
+  // Note that the multiplication by 10 does not overflow, because w.e >= -60
+  // and thus one.e >= -60.
+  ASSERT(one.e() >= -60);
+  ASSERT(fractionals < one.f());
+  ASSERT(UINT64_2PART_C(0xFFFFFFFF, FFFFFFFF) / 10 >= one.f());
+  for (;;) {
+    fractionals *= 10;
+    unit *= 10;
+    unsafe_interval.set_f(unsafe_interval.f() * 10);
+    // Integer division by one.
+    int digit = static_cast<int>(fractionals >> -one.e());
+    ASSERT(digit <= 9);
+    buffer[*length] = static_cast<char>('0' + digit);
+    (*length)++;
+    fractionals &= one.f() - 1;  // Modulo by one.
+    (*kappa)--;
+    if (fractionals < unsafe_interval.f()) {
+      return RoundWeed(buffer, *length, DiyFp::Minus(too_high, w).f() * unit,
+                       unsafe_interval.f(), fractionals, one.f(), unit);
+    }
+  }
+}
+
+
+
+// Generates (at most) requested_digits digits of input number w.
+// w is a floating-point number (DiyFp), consisting of a significand and an
+// exponent. Its exponent is bounded by kMinimalTargetExponent and
+// kMaximalTargetExponent.
+//       Hence -60 <= w.e() <= -32.
+//
+// Returns false if it fails, in which case the generated digits in the buffer
+// should not be used.
+// Preconditions:
+//  * w is correct up to 1 ulp (unit in the last place). That
+//    is, its error must be strictly less than a unit of its last digit.
+//  * kMinimalTargetExponent <= w.e() <= kMaximalTargetExponent
+//
+// Postconditions: returns false if procedure fails.
+//   otherwise:
+//     * buffer is not null-terminated, but length contains the number of
+//       digits.
+//     * the representation in buffer is the most precise representation of
+//       requested_digits digits.
+//     * buffer contains at most requested_digits digits of w. If there are less
+//       than requested_digits digits then some trailing '0's have been removed.
+//     * kappa is such that
+//            w = buffer * 10^kappa + eps with |eps| < 10^kappa / 2.
+//
+// Remark: This procedure takes into account the imprecision of its input
+//   numbers. If the precision is not enough to guarantee all the postconditions
+//   then false is returned. This usually happens rarely, but the failure-rate
+//   increases with higher requested_digits.
+static bool DigitGenCounted(DiyFp w,
+                            int requested_digits,
+                            Vector<char> buffer,
+                            int* length,
+                            int* kappa) {
+  ASSERT(kMinimalTargetExponent <= w.e() && w.e() <= kMaximalTargetExponent);
+  ASSERT(kMinimalTargetExponent >= -60);
+  ASSERT(kMaximalTargetExponent <= -32);
+  // w is assumed to have an error less than 1 unit. Whenever w is scaled we
+  // also scale its error.
+  uint64_t w_error = 1;
+  // We cut the input number into two parts: the integral digits and the
+  // fractional digits. We don't emit any decimal separator, but adapt kappa
+  // instead. Example: instead of writing "1.2" we put "12" into the buffer and
+  // increase kappa by 1.
+  DiyFp one = DiyFp(static_cast<uint64_t>(1) << -w.e(), w.e());
+  // Division by one is a shift.
+  uint32_t integrals = static_cast<uint32_t>(w.f() >> -one.e());
+  // Modulo by one is an and.
+  uint64_t fractionals = w.f() & (one.f() - 1);
+  uint32_t divisor;
+  int divisor_exponent_plus_one;
+  BiggestPowerTen(integrals, DiyFp::kSignificandSize - (-one.e()),
+                  &divisor, &divisor_exponent_plus_one);
+  *kappa = divisor_exponent_plus_one;
+  *length = 0;
+
+  // Loop invariant: buffer = w / 10^kappa  (integer division)
+  // The invariant holds for the first iteration: kappa has been initialized
+  // with the divisor exponent + 1. And the divisor is the biggest power of ten
+  // that is smaller than 'integrals'.
+  while (*kappa > 0) {
+    int digit = integrals / divisor;
+    ASSERT(digit <= 9);
+    buffer[*length] = static_cast<char>('0' + digit);
+    (*length)++;
+    requested_digits--;
+    integrals %= divisor;
+    (*kappa)--;
+    // Note that kappa now equals the exponent of the divisor and that the
+    // invariant thus holds again.
+    if (requested_digits == 0) break;
+    divisor /= 10;
+  }
+
+  if (requested_digits == 0) {
+    uint64_t rest =
+        (static_cast<uint64_t>(integrals) << -one.e()) + fractionals;
+    return RoundWeedCounted(buffer, *length, rest,
+                            static_cast<uint64_t>(divisor) << -one.e(), w_error,
+                            kappa);
+  }
+
+  // The integrals have been generated. We are at the point of the decimal
+  // separator. In the following loop we simply multiply the remaining digits by
+  // 10 and divide by one. We just need to pay attention to multiply associated
+  // data (the 'unit'), too.
+  // Note that the multiplication by 10 does not overflow, because w.e >= -60
+  // and thus one.e >= -60.
+  ASSERT(one.e() >= -60);
+  ASSERT(fractionals < one.f());
+  ASSERT(UINT64_2PART_C(0xFFFFFFFF, FFFFFFFF) / 10 >= one.f());
+  while (requested_digits > 0 && fractionals > w_error) {
+    fractionals *= 10;
+    w_error *= 10;
+    // Integer division by one.
+    int digit = static_cast<int>(fractionals >> -one.e());
+    ASSERT(digit <= 9);
+    buffer[*length] = static_cast<char>('0' + digit);
+    (*length)++;
+    requested_digits--;
+    fractionals &= one.f() - 1;  // Modulo by one.
+    (*kappa)--;
+  }
+  if (requested_digits != 0) return false;
+  return RoundWeedCounted(buffer, *length, fractionals, one.f(), w_error,
+                          kappa);
+}
+
+
+// Provides a decimal representation of v.
+// Returns true if it succeeds, otherwise the result cannot be trusted.
+// There will be *length digits inside the buffer (not null-terminated).
+// If the function returns true then
+//        v == (double) (buffer * 10^decimal_exponent).
+// The digits in the buffer are the shortest representation possible: no
+// 0.09999999999999999 instead of 0.1. The shorter representation will even be
+// chosen even if the longer one would be closer to v.
+// The last digit will be closest to the actual v. That is, even if several
+// digits might correctly yield 'v' when read again, the closest will be
+// computed.
+static bool Grisu3(double v,
+                   FastDtoaMode mode,
+                   Vector<char> buffer,
+                   int* length,
+                   int* decimal_exponent) {
+  DiyFp w = Double(v).AsNormalizedDiyFp();
+  // boundary_minus and boundary_plus are the boundaries between v and its
+  // closest floating-point neighbors. Any number strictly between
+  // boundary_minus and boundary_plus will round to v when convert to a double.
+  // Grisu3 will never output representations that lie exactly on a boundary.
+  DiyFp boundary_minus, boundary_plus;
+  if (mode == FAST_DTOA_SHORTEST) {
+    Double(v).NormalizedBoundaries(&boundary_minus, &boundary_plus);
+  } else {
+    ASSERT(mode == FAST_DTOA_SHORTEST_SINGLE);
+    float single_v = static_cast<float>(v);
+    Single(single_v).NormalizedBoundaries(&boundary_minus, &boundary_plus);
+  }
+  ASSERT(boundary_plus.e() == w.e());
+  DiyFp ten_mk;  // Cached power of ten: 10^-k
+  int mk;        // -k
+  int ten_mk_minimal_binary_exponent =
+     kMinimalTargetExponent - (w.e() + DiyFp::kSignificandSize);
+  int ten_mk_maximal_binary_exponent =
+     kMaximalTargetExponent - (w.e() + DiyFp::kSignificandSize);
+  PowersOfTenCache::GetCachedPowerForBinaryExponentRange(
+      ten_mk_minimal_binary_exponent,
+      ten_mk_maximal_binary_exponent,
+      &ten_mk, &mk);
+  ASSERT((kMinimalTargetExponent <= w.e() + ten_mk.e() +
+          DiyFp::kSignificandSize) &&
+         (kMaximalTargetExponent >= w.e() + ten_mk.e() +
+          DiyFp::kSignificandSize));
+  // Note that ten_mk is only an approximation of 10^-k. A DiyFp only contains a
+  // 64 bit significand and ten_mk is thus only precise up to 64 bits.
+
+  // The DiyFp::Times procedure rounds its result, and ten_mk is approximated
+  // too. The variable scaled_w (as well as scaled_boundary_minus/plus) are now
+  // off by a small amount.
+  // In fact: scaled_w - w*10^k < 1ulp (unit in the last place) of scaled_w.
+  // In other words: let f = scaled_w.f() and e = scaled_w.e(), then
+  //           (f-1) * 2^e < w*10^k < (f+1) * 2^e
+  DiyFp scaled_w = DiyFp::Times(w, ten_mk);
+  ASSERT(scaled_w.e() ==
+         boundary_plus.e() + ten_mk.e() + DiyFp::kSignificandSize);
+  // In theory it would be possible to avoid some recomputations by computing
+  // the difference between w and boundary_minus/plus (a power of 2) and to
+  // compute scaled_boundary_minus/plus by subtracting/adding from
+  // scaled_w. However the code becomes much less readable and the speed
+  // enhancements are not terriffic.
+  DiyFp scaled_boundary_minus = DiyFp::Times(boundary_minus, ten_mk);
+  DiyFp scaled_boundary_plus  = DiyFp::Times(boundary_plus,  ten_mk);
+
+  // DigitGen will generate the digits of scaled_w. Therefore we have
+  // v == (double) (scaled_w * 10^-mk).
+  // Set decimal_exponent == -mk and pass it to DigitGen. If scaled_w is not an
+  // integer than it will be updated. For instance if scaled_w == 1.23 then
+  // the buffer will be filled with "123" und the decimal_exponent will be
+  // decreased by 2.
+  int kappa;
+  bool result = DigitGen(scaled_boundary_minus, scaled_w, scaled_boundary_plus,
+                         buffer, length, &kappa);
+  *decimal_exponent = -mk + kappa;
+  return result;
+}
+
+
+// The "counted" version of grisu3 (see above) only generates requested_digits
+// number of digits. This version does not generate the shortest representation,
+// and with enough requested digits 0.1 will at some point print as 0.9999999...
+// Grisu3 is too imprecise for real halfway cases (1.5 will not work) and
+// therefore the rounding strategy for halfway cases is irrelevant.
+static bool Grisu3Counted(double v,
+                          int requested_digits,
+                          Vector<char> buffer,
+                          int* length,
+                          int* decimal_exponent) {
+  DiyFp w = Double(v).AsNormalizedDiyFp();
+  DiyFp ten_mk;  // Cached power of ten: 10^-k
+  int mk;        // -k
+  int ten_mk_minimal_binary_exponent =
+     kMinimalTargetExponent - (w.e() + DiyFp::kSignificandSize);
+  int ten_mk_maximal_binary_exponent =
+     kMaximalTargetExponent - (w.e() + DiyFp::kSignificandSize);
+  PowersOfTenCache::GetCachedPowerForBinaryExponentRange(
+      ten_mk_minimal_binary_exponent,
+      ten_mk_maximal_binary_exponent,
+      &ten_mk, &mk);
+  ASSERT((kMinimalTargetExponent <= w.e() + ten_mk.e() +
+          DiyFp::kSignificandSize) &&
+         (kMaximalTargetExponent >= w.e() + ten_mk.e() +
+          DiyFp::kSignificandSize));
+  // Note that ten_mk is only an approximation of 10^-k. A DiyFp only contains a
+  // 64 bit significand and ten_mk is thus only precise up to 64 bits.
+
+  // The DiyFp::Times procedure rounds its result, and ten_mk is approximated
+  // too. The variable scaled_w (as well as scaled_boundary_minus/plus) are now
+  // off by a small amount.
+  // In fact: scaled_w - w*10^k < 1ulp (unit in the last place) of scaled_w.
+  // In other words: let f = scaled_w.f() and e = scaled_w.e(), then
+  //           (f-1) * 2^e < w*10^k < (f+1) * 2^e
+  DiyFp scaled_w = DiyFp::Times(w, ten_mk);
+
+  // We now have (double) (scaled_w * 10^-mk).
+  // DigitGen will generate the first requested_digits digits of scaled_w and
+  // return together with a kappa such that scaled_w ~= buffer * 10^kappa. (It
+  // will not always be exactly the same since DigitGenCounted only produces a
+  // limited number of digits.)
+  int kappa;
+  bool result = DigitGenCounted(scaled_w, requested_digits,
+                                buffer, length, &kappa);
+  *decimal_exponent = -mk + kappa;
+  return result;
+}
+
+
+bool FastDtoa(double v,
+              FastDtoaMode mode,
+              int requested_digits,
+              Vector<char> buffer,
+              int* length,
+              int* decimal_point) {
+  ASSERT(v > 0);
+  ASSERT(!Double(v).IsSpecial());
+
+  bool result = false;
+  int decimal_exponent = 0;
+  switch (mode) {
+    case FAST_DTOA_SHORTEST:
+    case FAST_DTOA_SHORTEST_SINGLE:
+      result = Grisu3(v, mode, buffer, length, &decimal_exponent);
+      break;
+    case FAST_DTOA_PRECISION:
+      result = Grisu3Counted(v, requested_digits,
+                             buffer, length, &decimal_exponent);
+      break;
+    default:
+      UNREACHABLE();
+  }
+  if (result) {
+    *decimal_point = *length + decimal_exponent;
+    buffer[*length] = '\0';
+  }
+  return result;
+}
+
+}  // namespace double_conversion

+ 88 - 0
third-party/double-conversion-1.1.6/src/fast-dtoa.h

@@ -0,0 +1,88 @@
+// 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.
+
+#ifndef DOUBLE_CONVERSION_FAST_DTOA_H_
+#define DOUBLE_CONVERSION_FAST_DTOA_H_
+
+#include "utils.h"
+
+namespace double_conversion {
+
+enum FastDtoaMode {
+  // Computes the shortest representation of the given input. The returned
+  // result will be the most accurate number of this length. Longer
+  // representations might be more accurate.
+  FAST_DTOA_SHORTEST,
+  // Same as FAST_DTOA_SHORTEST but for single-precision floats.
+  FAST_DTOA_SHORTEST_SINGLE,
+  // Computes a representation where the precision (number of digits) is
+  // given as input. The precision is independent of the decimal point.
+  FAST_DTOA_PRECISION
+};
+
+// FastDtoa will produce at most kFastDtoaMaximalLength digits. This does not
+// include the terminating '\0' character.
+static const int kFastDtoaMaximalLength = 17;
+// Same for single-precision numbers.
+static const int kFastDtoaMaximalSingleLength = 9;
+
+// Provides a decimal representation of v.
+// The result should be interpreted as buffer * 10^(point - length).
+//
+// Precondition:
+//   * v must be a strictly positive finite double.
+//
+// Returns true if it succeeds, otherwise the result can not be trusted.
+// There will be *length digits inside the buffer followed by a null terminator.
+// If the function returns true and mode equals
+//   - FAST_DTOA_SHORTEST, then
+//     the parameter requested_digits is ignored.
+//     The result satisfies
+//         v == (double) (buffer * 10^(point - length)).
+//     The digits in the buffer are the shortest representation possible. E.g.
+//     if 0.099999999999 and 0.1 represent the same double then "1" is returned
+//     with point = 0.
+//     The last digit will be closest to the actual v. That is, even if several
+//     digits might correctly yield 'v' when read again, the buffer will contain
+//     the one closest to v.
+//   - FAST_DTOA_PRECISION, then
+//     the buffer contains requested_digits digits.
+//     the difference v - (buffer * 10^(point-length)) is closest to zero for
+//     all possible representations of requested_digits digits.
+//     If there are two values that are equally close, then FastDtoa returns
+//     false.
+// For both modes the buffer must be large enough to hold the result.
+bool FastDtoa(double d,
+              FastDtoaMode mode,
+              int requested_digits,
+              Vector<char> buffer,
+              int* length,
+              int* decimal_point);
+
+}  // namespace double_conversion
+
+#endif  // DOUBLE_CONVERSION_FAST_DTOA_H_

+ 404 - 0
third-party/double-conversion-1.1.6/src/fixed-dtoa.cc

@@ -0,0 +1,404 @@
+// 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 <math.h>
+
+#include "fixed-dtoa.h"
+#include "ieee.h"
+
+namespace double_conversion {
+
+// Represents a 128bit type. This class should be replaced by a native type on
+// platforms that support 128bit integers.
+class UInt128 {
+ public:
+  UInt128() : high_bits_(0), low_bits_(0) { }
+  UInt128(uint64_t high, uint64_t low) : high_bits_(high), low_bits_(low) { }
+
+  void Multiply(uint32_t multiplicand) {
+    uint64_t accumulator;
+
+    accumulator = (low_bits_ & kMask32) * multiplicand;
+    uint32_t part = static_cast<uint32_t>(accumulator & kMask32);
+    accumulator >>= 32;
+    accumulator = accumulator + (low_bits_ >> 32) * multiplicand;
+    low_bits_ = (accumulator << 32) + part;
+    accumulator >>= 32;
+    accumulator = accumulator + (high_bits_ & kMask32) * multiplicand;
+    part = static_cast<uint32_t>(accumulator & kMask32);
+    accumulator >>= 32;
+    accumulator = accumulator + (high_bits_ >> 32) * multiplicand;
+    high_bits_ = (accumulator << 32) + part;
+    ASSERT((accumulator >> 32) == 0);
+  }
+
+  void Shift(int shift_amount) {
+    ASSERT(-64 <= shift_amount && shift_amount <= 64);
+    if (shift_amount == 0) {
+      return;
+    } else if (shift_amount == -64) {
+      high_bits_ = low_bits_;
+      low_bits_ = 0;
+    } else if (shift_amount == 64) {
+      low_bits_ = high_bits_;
+      high_bits_ = 0;
+    } else if (shift_amount <= 0) {
+      high_bits_ <<= -shift_amount;
+      high_bits_ += low_bits_ >> (64 + shift_amount);
+      low_bits_ <<= -shift_amount;
+    } else {
+      low_bits_ >>= shift_amount;
+      low_bits_ += high_bits_ << (64 - shift_amount);
+      high_bits_ >>= shift_amount;
+    }
+  }
+
+  // Modifies *this to *this MOD (2^power).
+  // Returns *this DIV (2^power).
+  int DivModPowerOf2(int power) {
+    if (power >= 64) {
+      int result = static_cast<int>(high_bits_ >> (power - 64));
+      high_bits_ -= static_cast<uint64_t>(result) << (power - 64);
+      return result;
+    } else {
+      uint64_t part_low = low_bits_ >> power;
+      uint64_t part_high = high_bits_ << (64 - power);
+      int result = static_cast<int>(part_low + part_high);
+      high_bits_ = 0;
+      low_bits_ -= part_low << power;
+      return result;
+    }
+  }
+
+  bool IsZero() const {
+    return high_bits_ == 0 && low_bits_ == 0;
+  }
+
+  int BitAt(int position) {
+    if (position >= 64) {
+      return static_cast<int>(high_bits_ >> (position - 64)) & 1;
+    } else {
+      return static_cast<int>(low_bits_ >> position) & 1;
+    }
+  }
+
+ private:
+  static const uint64_t kMask32 = 0xFFFFFFFF;
+  // Value == (high_bits_ << 64) + low_bits_
+  uint64_t high_bits_;
+  uint64_t low_bits_;
+};
+
+
+static const int kDoubleSignificandSize = 53;  // Includes the hidden bit.
+
+
+static void FillDigits32FixedLength(uint32_t number, int requested_length,
+                                    Vector<char> buffer, int* length) {
+  for (int i = requested_length - 1; i >= 0; --i) {
+    buffer[(*length) + i] = '0' + number % 10;
+    number /= 10;
+  }
+  *length += requested_length;
+}
+
+
+static void FillDigits32(uint32_t number, Vector<char> buffer, int* length) {
+  int number_length = 0;
+  // We fill the digits in reverse order and exchange them afterwards.
+  while (number != 0) {
+    int digit = number % 10;
+    number /= 10;
+    buffer[(*length) + number_length] = static_cast<char>('0' + digit);
+    number_length++;
+  }
+  // Exchange the digits.
+  int i = *length;
+  int j = *length + number_length - 1;
+  while (i < j) {
+    char tmp = buffer[i];
+    buffer[i] = buffer[j];
+    buffer[j] = tmp;
+    i++;
+    j--;
+  }
+  *length += number_length;
+}
+
+
+static void FillDigits64FixedLength(uint64_t number,
+                                    Vector<char> buffer, int* length) {
+  const uint32_t kTen7 = 10000000;
+  // For efficiency cut the number into 3 uint32_t parts, and print those.
+  uint32_t part2 = static_cast<uint32_t>(number % kTen7);
+  number /= kTen7;
+  uint32_t part1 = static_cast<uint32_t>(number % kTen7);
+  uint32_t part0 = static_cast<uint32_t>(number / kTen7);
+
+  FillDigits32FixedLength(part0, 3, buffer, length);
+  FillDigits32FixedLength(part1, 7, buffer, length);
+  FillDigits32FixedLength(part2, 7, buffer, length);
+}
+
+
+static void FillDigits64(uint64_t number, Vector<char> buffer, int* length) {
+  const uint32_t kTen7 = 10000000;
+  // For efficiency cut the number into 3 uint32_t parts, and print those.
+  uint32_t part2 = static_cast<uint32_t>(number % kTen7);
+  number /= kTen7;
+  uint32_t part1 = static_cast<uint32_t>(number % kTen7);
+  uint32_t part0 = static_cast<uint32_t>(number / kTen7);
+
+  if (part0 != 0) {
+    FillDigits32(part0, buffer, length);
+    FillDigits32FixedLength(part1, 7, buffer, length);
+    FillDigits32FixedLength(part2, 7, buffer, length);
+  } else if (part1 != 0) {
+    FillDigits32(part1, buffer, length);
+    FillDigits32FixedLength(part2, 7, buffer, length);
+  } else {
+    FillDigits32(part2, buffer, length);
+  }
+}
+
+
+static void RoundUp(Vector<char> buffer, int* length, int* decimal_point) {
+  // An empty buffer represents 0.
+  if (*length == 0) {
+    buffer[0] = '1';
+    *decimal_point = 1;
+    *length = 1;
+    return;
+  }
+  // Round the last digit until we either have a digit that was not '9' or until
+  // we reached the first digit.
+  buffer[(*length) - 1]++;
+  for (int i = (*length) - 1; i > 0; --i) {
+    if (buffer[i] != '0' + 10) {
+      return;
+    }
+    buffer[i] = '0';
+    buffer[i - 1]++;
+  }
+  // If the first digit is now '0' + 10, we would need to set it to '0' and add
+  // a '1' in front. However we reach the first digit only if all following
+  // digits had been '9' before rounding up. Now all trailing digits are '0' and
+  // we simply switch the first digit to '1' and update the decimal-point
+  // (indicating that the point is now one digit to the right).
+  if (buffer[0] == '0' + 10) {
+    buffer[0] = '1';
+    (*decimal_point)++;
+  }
+}
+
+
+// The given fractionals number represents a fixed-point number with binary
+// point at bit (-exponent).
+// Preconditions:
+//   -128 <= exponent <= 0.
+//   0 <= fractionals * 2^exponent < 1
+//   The buffer holds the result.
+// The function will round its result. During the rounding-process digits not
+// generated by this function might be updated, and the decimal-point variable
+// might be updated. If this function generates the digits 99 and the buffer
+// already contained "199" (thus yielding a buffer of "19999") then a
+// rounding-up will change the contents of the buffer to "20000".
+static void FillFractionals(uint64_t fractionals, int exponent,
+                            int fractional_count, Vector<char> buffer,
+                            int* length, int* decimal_point) {
+  ASSERT(-128 <= exponent && exponent <= 0);
+  // 'fractionals' is a fixed-point number, with binary point at bit
+  // (-exponent). Inside the function the non-converted remainder of fractionals
+  // is a fixed-point number, with binary point at bit 'point'.
+  if (-exponent <= 64) {
+    // One 64 bit number is sufficient.
+    ASSERT(fractionals >> 56 == 0);
+    int point = -exponent;
+    for (int i = 0; i < fractional_count; ++i) {
+      if (fractionals == 0) break;
+      // Instead of multiplying by 10 we multiply by 5 and adjust the point
+      // location. This way the fractionals variable will not overflow.
+      // Invariant at the beginning of the loop: fractionals < 2^point.
+      // Initially we have: point <= 64 and fractionals < 2^56
+      // After each iteration the point is decremented by one.
+      // Note that 5^3 = 125 < 128 = 2^7.
+      // Therefore three iterations of this loop will not overflow fractionals
+      // (even without the subtraction at the end of the loop body). At this
+      // time point will satisfy point <= 61 and therefore fractionals < 2^point
+      // and any further multiplication of fractionals by 5 will not overflow.
+      fractionals *= 5;
+      point--;
+      int digit = static_cast<int>(fractionals >> point);
+      ASSERT(digit <= 9);
+      buffer[*length] = static_cast<char>('0' + digit);
+      (*length)++;
+      fractionals -= static_cast<uint64_t>(digit) << point;
+    }
+    // If the first bit after the point is set we have to round up.
+    if (((fractionals >> (point - 1)) & 1) == 1) {
+      RoundUp(buffer, length, decimal_point);
+    }
+  } else {  // We need 128 bits.
+    ASSERT(64 < -exponent && -exponent <= 128);
+    UInt128 fractionals128 = UInt128(fractionals, 0);
+    fractionals128.Shift(-exponent - 64);
+    int point = 128;
+    for (int i = 0; i < fractional_count; ++i) {
+      if (fractionals128.IsZero()) break;
+      // As before: instead of multiplying by 10 we multiply by 5 and adjust the
+      // point location.
+      // This multiplication will not overflow for the same reasons as before.
+      fractionals128.Multiply(5);
+      point--;
+      int digit = fractionals128.DivModPowerOf2(point);
+      ASSERT(digit <= 9);
+      buffer[*length] = static_cast<char>('0' + digit);
+      (*length)++;
+    }
+    if (fractionals128.BitAt(point - 1) == 1) {
+      RoundUp(buffer, length, decimal_point);
+    }
+  }
+}
+
+
+// Removes leading and trailing zeros.
+// If leading zeros are removed then the decimal point position is adjusted.
+static void TrimZeros(Vector<char> buffer, int* length, int* decimal_point) {
+  while (*length > 0 && buffer[(*length) - 1] == '0') {
+    (*length)--;
+  }
+  int first_non_zero = 0;
+  while (first_non_zero < *length && buffer[first_non_zero] == '0') {
+    first_non_zero++;
+  }
+  if (first_non_zero != 0) {
+    for (int i = first_non_zero; i < *length; ++i) {
+      buffer[i - first_non_zero] = buffer[i];
+    }
+    *length -= first_non_zero;
+    *decimal_point -= first_non_zero;
+  }
+}
+
+
+bool FastFixedDtoa(double v,
+                   int fractional_count,
+                   Vector<char> buffer,
+                   int* length,
+                   int* decimal_point) {
+  const uint32_t kMaxUInt32 = 0xFFFFFFFF;
+  uint64_t significand = Double(v).Significand();
+  int exponent = Double(v).Exponent();
+  // v = significand * 2^exponent (with significand a 53bit integer).
+  // If the exponent is larger than 20 (i.e. we may have a 73bit number) then we
+  // don't know how to compute the representation. 2^73 ~= 9.5*10^21.
+  // If necessary this limit could probably be increased, but we don't need
+  // more.
+  if (exponent > 20) return false;
+  if (fractional_count > 20) return false;
+  *length = 0;
+  // At most kDoubleSignificandSize bits of the significand are non-zero.
+  // Given a 64 bit integer we have 11 0s followed by 53 potentially non-zero
+  // bits:  0..11*..0xxx..53*..xx
+  if (exponent + kDoubleSignificandSize > 64) {
+    // The exponent must be > 11.
+    //
+    // We know that v = significand * 2^exponent.
+    // And the exponent > 11.
+    // We simplify the task by dividing v by 10^17.
+    // The quotient delivers the first digits, and the remainder fits into a 64
+    // bit number.
+    // Dividing by 10^17 is equivalent to dividing by 5^17*2^17.
+    const uint64_t kFive17 = UINT64_2PART_C(0xB1, A2BC2EC5);  // 5^17
+    uint64_t divisor = kFive17;
+    int divisor_power = 17;
+    uint64_t dividend = significand;
+    uint32_t quotient;
+    uint64_t remainder;
+    // Let v = f * 2^e with f == significand and e == exponent.
+    // Then need q (quotient) and r (remainder) as follows:
+    //   v            = q * 10^17       + r
+    //   f * 2^e      = q * 10^17       + r
+    //   f * 2^e      = q * 5^17 * 2^17 + r
+    // If e > 17 then
+    //   f * 2^(e-17) = q * 5^17        + r/2^17
+    // else
+    //   f  = q * 5^17 * 2^(17-e) + r/2^e
+    if (exponent > divisor_power) {
+      // We only allow exponents of up to 20 and therefore (17 - e) <= 3
+      dividend <<= exponent - divisor_power;
+      quotient = static_cast<uint32_t>(dividend / divisor);
+      remainder = (dividend % divisor) << divisor_power;
+    } else {
+      divisor <<= divisor_power - exponent;
+      quotient = static_cast<uint32_t>(dividend / divisor);
+      remainder = (dividend % divisor) << exponent;
+    }
+    FillDigits32(quotient, buffer, length);
+    FillDigits64FixedLength(remainder, buffer, length);
+    *decimal_point = *length;
+  } else if (exponent >= 0) {
+    // 0 <= exponent <= 11
+    significand <<= exponent;
+    FillDigits64(significand, buffer, length);
+    *decimal_point = *length;
+  } else if (exponent > -kDoubleSignificandSize) {
+    // We have to cut the number.
+    uint64_t integrals = significand >> -exponent;
+    uint64_t fractionals = significand - (integrals << -exponent);
+    if (integrals > kMaxUInt32) {
+      FillDigits64(integrals, buffer, length);
+    } else {
+      FillDigits32(static_cast<uint32_t>(integrals), buffer, length);
+    }
+    *decimal_point = *length;
+    FillFractionals(fractionals, exponent, fractional_count,
+                    buffer, length, decimal_point);
+  } else if (exponent < -128) {
+    // This configuration (with at most 20 digits) means that all digits must be
+    // 0.
+    ASSERT(fractional_count <= 20);
+    buffer[0] = '\0';
+    *length = 0;
+    *decimal_point = -fractional_count;
+  } else {
+    *decimal_point = 0;
+    FillFractionals(significand, exponent, fractional_count,
+                    buffer, length, decimal_point);
+  }
+  TrimZeros(buffer, length, decimal_point);
+  buffer[*length] = '\0';
+  if ((*length) == 0) {
+    // The string is empty and the decimal_point thus has no importance. Mimick
+    // Gay's dtoa and and set it to -fractional_count.
+    *decimal_point = -fractional_count;
+  }
+  return true;
+}
+
+}  // namespace double_conversion

+ 56 - 0
third-party/double-conversion-1.1.6/src/fixed-dtoa.h

@@ -0,0 +1,56 @@
+// 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.
+
+#ifndef DOUBLE_CONVERSION_FIXED_DTOA_H_
+#define DOUBLE_CONVERSION_FIXED_DTOA_H_
+
+#include "utils.h"
+
+namespace double_conversion {
+
+// Produces digits necessary to print a given number with
+// 'fractional_count' digits after the decimal point.
+// The buffer must be big enough to hold the result plus one terminating null
+// character.
+//
+// The produced digits might be too short in which case the caller has to fill
+// the gaps with '0's.
+// Example: FastFixedDtoa(0.001, 5, ...) is allowed to return buffer = "1", and
+// decimal_point = -2.
+// Halfway cases are rounded towards +/-Infinity (away from 0). The call
+// FastFixedDtoa(0.15, 2, ...) thus returns buffer = "2", decimal_point = 0.
+// The returned buffer may contain digits that would be truncated from the
+// shortest representation of the input.
+//
+// This method only works for some parameters. If it can't handle the input it
+// returns false. The output is null-terminated when the function succeeds.
+bool FastFixedDtoa(double v, int fractional_count,
+                   Vector<char> buffer, int* length, int* decimal_point);
+
+}  // namespace double_conversion
+
+#endif  // DOUBLE_CONVERSION_FIXED_DTOA_H_

+ 402 - 0
third-party/double-conversion-1.1.6/src/ieee.h

@@ -0,0 +1,402 @@
+// Copyright 2012 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.
+
+#ifndef DOUBLE_CONVERSION_DOUBLE_H_
+#define DOUBLE_CONVERSION_DOUBLE_H_
+
+#include "diy-fp.h"
+
+namespace double_conversion {
+
+// We assume that doubles and uint64_t have the same endianness.
+static uint64_t double_to_uint64(double d) { return BitCast<uint64_t>(d); }
+static double uint64_to_double(uint64_t d64) { return BitCast<double>(d64); }
+static uint32_t float_to_uint32(float f) { return BitCast<uint32_t>(f); }
+static float uint32_to_float(uint32_t d32) { return BitCast<float>(d32); }
+
+// Helper functions for doubles.
+class Double {
+ public:
+  static const uint64_t kSignMask = UINT64_2PART_C(0x80000000, 00000000);
+  static const uint64_t kExponentMask = UINT64_2PART_C(0x7FF00000, 00000000);
+  static const uint64_t kSignificandMask = UINT64_2PART_C(0x000FFFFF, FFFFFFFF);
+  static const uint64_t kHiddenBit = UINT64_2PART_C(0x00100000, 00000000);
+  static const int kPhysicalSignificandSize = 52;  // Excludes the hidden bit.
+  static const int kSignificandSize = 53;
+
+  Double() : d64_(0) {}
+  explicit Double(double d) : d64_(double_to_uint64(d)) {}
+  explicit Double(uint64_t d64) : d64_(d64) {}
+  explicit Double(DiyFp diy_fp)
+    : d64_(DiyFpToUint64(diy_fp)) {}
+
+  // The value encoded by this Double must be greater or equal to +0.0.
+  // It must not be special (infinity, or NaN).
+  DiyFp AsDiyFp() const {
+    ASSERT(Sign() > 0);
+    ASSERT(!IsSpecial());
+    return DiyFp(Significand(), Exponent());
+  }
+
+  // The value encoded by this Double must be strictly greater than 0.
+  DiyFp AsNormalizedDiyFp() const {
+    ASSERT(value() > 0.0);
+    uint64_t f = Significand();
+    int e = Exponent();
+
+    // The current double could be a denormal.
+    while ((f & kHiddenBit) == 0) {
+      f <<= 1;
+      e--;
+    }
+    // Do the final shifts in one go.
+    f <<= DiyFp::kSignificandSize - kSignificandSize;
+    e -= DiyFp::kSignificandSize - kSignificandSize;
+    return DiyFp(f, e);
+  }
+
+  // Returns the double's bit as uint64.
+  uint64_t AsUint64() const {
+    return d64_;
+  }
+
+  // Returns the next greater double. Returns +infinity on input +infinity.
+  double NextDouble() const {
+    if (d64_ == kInfinity) return Double(kInfinity).value();
+    if (Sign() < 0 && Significand() == 0) {
+      // -0.0
+      return 0.0;
+    }
+    if (Sign() < 0) {
+      return Double(d64_ - 1).value();
+    } else {
+      return Double(d64_ + 1).value();
+    }
+  }
+
+  double PreviousDouble() const {
+    if (d64_ == (kInfinity | kSignMask)) return -Double::Infinity();
+    if (Sign() < 0) {
+      return Double(d64_ + 1).value();
+    } else {
+      if (Significand() == 0) return -0.0;
+      return Double(d64_ - 1).value();
+    }
+  }
+
+  int Exponent() const {
+    if (IsDenormal()) return kDenormalExponent;
+
+    uint64_t d64 = AsUint64();
+    int biased_e =
+        static_cast<int>((d64 & kExponentMask) >> kPhysicalSignificandSize);
+    return biased_e - kExponentBias;
+  }
+
+  uint64_t Significand() const {
+    uint64_t d64 = AsUint64();
+    uint64_t significand = d64 & kSignificandMask;
+    if (!IsDenormal()) {
+      return significand + kHiddenBit;
+    } else {
+      return significand;
+    }
+  }
+
+  // Returns true if the double is a denormal.
+  bool IsDenormal() const {
+    uint64_t d64 = AsUint64();
+    return (d64 & kExponentMask) == 0;
+  }
+
+  // We consider denormals not to be special.
+  // Hence only Infinity and NaN are special.
+  bool IsSpecial() const {
+    uint64_t d64 = AsUint64();
+    return (d64 & kExponentMask) == kExponentMask;
+  }
+
+  bool IsNan() const {
+    uint64_t d64 = AsUint64();
+    return ((d64 & kExponentMask) == kExponentMask) &&
+        ((d64 & kSignificandMask) != 0);
+  }
+
+  bool IsInfinite() const {
+    uint64_t d64 = AsUint64();
+    return ((d64 & kExponentMask) == kExponentMask) &&
+        ((d64 & kSignificandMask) == 0);
+  }
+
+  int Sign() const {
+    uint64_t d64 = AsUint64();
+    return (d64 & kSignMask) == 0? 1: -1;
+  }
+
+  // Precondition: the value encoded by this Double must be greater or equal
+  // than +0.0.
+  DiyFp UpperBoundary() const {
+    ASSERT(Sign() > 0);
+    return DiyFp(Significand() * 2 + 1, Exponent() - 1);
+  }
+
+  // Computes the two boundaries of this.
+  // The bigger boundary (m_plus) is normalized. The lower boundary has the same
+  // exponent as m_plus.
+  // Precondition: the value encoded by this Double must be greater than 0.
+  void NormalizedBoundaries(DiyFp* out_m_minus, DiyFp* out_m_plus) const {
+    ASSERT(value() > 0.0);
+    DiyFp v = this->AsDiyFp();
+    DiyFp m_plus = DiyFp::Normalize(DiyFp((v.f() << 1) + 1, v.e() - 1));
+    DiyFp m_minus;
+    if (LowerBoundaryIsCloser()) {
+      m_minus = DiyFp((v.f() << 2) - 1, v.e() - 2);
+    } else {
+      m_minus = DiyFp((v.f() << 1) - 1, v.e() - 1);
+    }
+    m_minus.set_f(m_minus.f() << (m_minus.e() - m_plus.e()));
+    m_minus.set_e(m_plus.e());
+    *out_m_plus = m_plus;
+    *out_m_minus = m_minus;
+  }
+
+  bool LowerBoundaryIsCloser() const {
+    // The boundary is closer if the significand is of the form f == 2^p-1 then
+    // the lower boundary is closer.
+    // Think of v = 1000e10 and v- = 9999e9.
+    // Then the boundary (== (v - v-)/2) is not just at a distance of 1e9 but
+    // at a distance of 1e8.
+    // The only exception is for the smallest normal: the largest denormal is
+    // at the same distance as its successor.
+    // Note: denormals have the same exponent as the smallest normals.
+    bool physical_significand_is_zero = ((AsUint64() & kSignificandMask) == 0);
+    return physical_significand_is_zero && (Exponent() != kDenormalExponent);
+  }
+
+  double value() const { return uint64_to_double(d64_); }
+
+  // Returns the significand size for a given order of magnitude.
+  // If v = f*2^e with 2^p-1 <= f <= 2^p then p+e is v's order of magnitude.
+  // This function returns the number of significant binary digits v will have
+  // once it's encoded into a double. In almost all cases this is equal to
+  // kSignificandSize. The only exceptions are denormals. They start with
+  // leading zeroes and their effective significand-size is hence smaller.
+  static int SignificandSizeForOrderOfMagnitude(int order) {
+    if (order >= (kDenormalExponent + kSignificandSize)) {
+      return kSignificandSize;
+    }
+    if (order <= kDenormalExponent) return 0;
+    return order - kDenormalExponent;
+  }
+
+  static double Infinity() {
+    return Double(kInfinity).value();
+  }
+
+  static double NaN() {
+    return Double(kNaN).value();
+  }
+
+ private:
+  static const int kExponentBias = 0x3FF + kPhysicalSignificandSize;
+  static const int kDenormalExponent = -kExponentBias + 1;
+  static const int kMaxExponent = 0x7FF - kExponentBias;
+  static const uint64_t kInfinity = UINT64_2PART_C(0x7FF00000, 00000000);
+  static const uint64_t kNaN = UINT64_2PART_C(0x7FF80000, 00000000);
+
+  const uint64_t d64_;
+
+  static uint64_t DiyFpToUint64(DiyFp diy_fp) {
+    uint64_t significand = diy_fp.f();
+    int exponent = diy_fp.e();
+    while (significand > kHiddenBit + kSignificandMask) {
+      significand >>= 1;
+      exponent++;
+    }
+    if (exponent >= kMaxExponent) {
+      return kInfinity;
+    }
+    if (exponent < kDenormalExponent) {
+      return 0;
+    }
+    while (exponent > kDenormalExponent && (significand & kHiddenBit) == 0) {
+      significand <<= 1;
+      exponent--;
+    }
+    uint64_t biased_exponent;
+    if (exponent == kDenormalExponent && (significand & kHiddenBit) == 0) {
+      biased_exponent = 0;
+    } else {
+      biased_exponent = static_cast<uint64_t>(exponent + kExponentBias);
+    }
+    return (significand & kSignificandMask) |
+        (biased_exponent << kPhysicalSignificandSize);
+  }
+
+  DISALLOW_COPY_AND_ASSIGN(Double);
+};
+
+class Single {
+ public:
+  static const uint32_t kSignMask = 0x80000000;
+  static const uint32_t kExponentMask = 0x7F800000;
+  static const uint32_t kSignificandMask = 0x007FFFFF;
+  static const uint32_t kHiddenBit = 0x00800000;
+  static const int kPhysicalSignificandSize = 23;  // Excludes the hidden bit.
+  static const int kSignificandSize = 24;
+
+  Single() : d32_(0) {}
+  explicit Single(float f) : d32_(float_to_uint32(f)) {}
+  explicit Single(uint32_t d32) : d32_(d32) {}
+
+  // The value encoded by this Single must be greater or equal to +0.0.
+  // It must not be special (infinity, or NaN).
+  DiyFp AsDiyFp() const {
+    ASSERT(Sign() > 0);
+    ASSERT(!IsSpecial());
+    return DiyFp(Significand(), Exponent());
+  }
+
+  // Returns the single's bit as uint64.
+  uint32_t AsUint32() const {
+    return d32_;
+  }
+
+  int Exponent() const {
+    if (IsDenormal()) return kDenormalExponent;
+
+    uint32_t d32 = AsUint32();
+    int biased_e =
+        static_cast<int>((d32 & kExponentMask) >> kPhysicalSignificandSize);
+    return biased_e - kExponentBias;
+  }
+
+  uint32_t Significand() const {
+    uint32_t d32 = AsUint32();
+    uint32_t significand = d32 & kSignificandMask;
+    if (!IsDenormal()) {
+      return significand + kHiddenBit;
+    } else {
+      return significand;
+    }
+  }
+
+  // Returns true if the single is a denormal.
+  bool IsDenormal() const {
+    uint32_t d32 = AsUint32();
+    return (d32 & kExponentMask) == 0;
+  }
+
+  // We consider denormals not to be special.
+  // Hence only Infinity and NaN are special.
+  bool IsSpecial() const {
+    uint32_t d32 = AsUint32();
+    return (d32 & kExponentMask) == kExponentMask;
+  }
+
+  bool IsNan() const {
+    uint32_t d32 = AsUint32();
+    return ((d32 & kExponentMask) == kExponentMask) &&
+        ((d32 & kSignificandMask) != 0);
+  }
+
+  bool IsInfinite() const {
+    uint32_t d32 = AsUint32();
+    return ((d32 & kExponentMask) == kExponentMask) &&
+        ((d32 & kSignificandMask) == 0);
+  }
+
+  int Sign() const {
+    uint32_t d32 = AsUint32();
+    return (d32 & kSignMask) == 0? 1: -1;
+  }
+
+  // Computes the two boundaries of this.
+  // The bigger boundary (m_plus) is normalized. The lower boundary has the same
+  // exponent as m_plus.
+  // Precondition: the value encoded by this Single must be greater than 0.
+  void NormalizedBoundaries(DiyFp* out_m_minus, DiyFp* out_m_plus) const {
+    ASSERT(value() > 0.0);
+    DiyFp v = this->AsDiyFp();
+    DiyFp m_plus = DiyFp::Normalize(DiyFp((v.f() << 1) + 1, v.e() - 1));
+    DiyFp m_minus;
+    if (LowerBoundaryIsCloser()) {
+      m_minus = DiyFp((v.f() << 2) - 1, v.e() - 2);
+    } else {
+      m_minus = DiyFp((v.f() << 1) - 1, v.e() - 1);
+    }
+    m_minus.set_f(m_minus.f() << (m_minus.e() - m_plus.e()));
+    m_minus.set_e(m_plus.e());
+    *out_m_plus = m_plus;
+    *out_m_minus = m_minus;
+  }
+
+  // Precondition: the value encoded by this Single must be greater or equal
+  // than +0.0.
+  DiyFp UpperBoundary() const {
+    ASSERT(Sign() > 0);
+    return DiyFp(Significand() * 2 + 1, Exponent() - 1);
+  }
+
+  bool LowerBoundaryIsCloser() const {
+    // The boundary is closer if the significand is of the form f == 2^p-1 then
+    // the lower boundary is closer.
+    // Think of v = 1000e10 and v- = 9999e9.
+    // Then the boundary (== (v - v-)/2) is not just at a distance of 1e9 but
+    // at a distance of 1e8.
+    // The only exception is for the smallest normal: the largest denormal is
+    // at the same distance as its successor.
+    // Note: denormals have the same exponent as the smallest normals.
+    bool physical_significand_is_zero = ((AsUint32() & kSignificandMask) == 0);
+    return physical_significand_is_zero && (Exponent() != kDenormalExponent);
+  }
+
+  float value() const { return uint32_to_float(d32_); }
+
+  static float Infinity() {
+    return Single(kInfinity).value();
+  }
+
+  static float NaN() {
+    return Single(kNaN).value();
+  }
+
+ private:
+  static const int kExponentBias = 0x7F + kPhysicalSignificandSize;
+  static const int kDenormalExponent = -kExponentBias + 1;
+  static const int kMaxExponent = 0xFF - kExponentBias;
+  static const uint32_t kInfinity = 0x7F800000;
+  static const uint32_t kNaN = 0x7FC00000;
+
+  const uint32_t d32_;
+
+  DISALLOW_COPY_AND_ASSIGN(Single);
+};
+
+}  // namespace double_conversion
+
+#endif  // DOUBLE_CONVERSION_DOUBLE_H_

+ 555 - 0
third-party/double-conversion-1.1.6/src/strtod.cc

@@ -0,0 +1,555 @@
+// 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 <stdarg.h>
+#include <limits.h>
+
+#include "strtod.h"
+#include "bignum.h"
+#include "cached-powers.h"
+#include "ieee.h"
+
+namespace double_conversion {
+
+// 2^53 = 9007199254740992.
+// Any integer with at most 15 decimal digits will hence fit into a double
+// (which has a 53bit significand) without loss of precision.
+static const int kMaxExactDoubleIntegerDecimalDigits = 15;
+// 2^64 = 18446744073709551616 > 10^19
+static const int kMaxUint64DecimalDigits = 19;
+
+// Max double: 1.7976931348623157 x 10^308
+// Min non-zero double: 4.9406564584124654 x 10^-324
+// Any x >= 10^309 is interpreted as +infinity.
+// Any x <= 10^-324 is interpreted as 0.
+// Note that 2.5e-324 (despite being smaller than the min double) will be read
+// as non-zero (equal to the min non-zero double).
+static const int kMaxDecimalPower = 309;
+static const int kMinDecimalPower = -324;
+
+// 2^64 = 18446744073709551616
+static const uint64_t kMaxUint64 = UINT64_2PART_C(0xFFFFFFFF, FFFFFFFF);
+
+
+static const double exact_powers_of_ten[] = {
+  1.0,  // 10^0
+  10.0,
+  100.0,
+  1000.0,
+  10000.0,
+  100000.0,
+  1000000.0,
+  10000000.0,
+  100000000.0,
+  1000000000.0,
+  10000000000.0,  // 10^10
+  100000000000.0,
+  1000000000000.0,
+  10000000000000.0,
+  100000000000000.0,
+  1000000000000000.0,
+  10000000000000000.0,
+  100000000000000000.0,
+  1000000000000000000.0,
+  10000000000000000000.0,
+  100000000000000000000.0,  // 10^20
+  1000000000000000000000.0,
+  // 10^22 = 0x21e19e0c9bab2400000 = 0x878678326eac9 * 2^22
+  10000000000000000000000.0
+};
+static const int kExactPowersOfTenSize = ARRAY_SIZE(exact_powers_of_ten);
+
+// Maximum number of significant digits in the decimal representation.
+// In fact the value is 772 (see conversions.cc), but to give us some margin
+// we round up to 780.
+static const int kMaxSignificantDecimalDigits = 780;
+
+static Vector<const char> TrimLeadingZeros(Vector<const char> buffer) {
+  for (int i = 0; i < buffer.length(); i++) {
+    if (buffer[i] != '0') {
+      return buffer.SubVector(i, buffer.length());
+    }
+  }
+  return Vector<const char>(buffer.start(), 0);
+}
+
+
+static Vector<const char> TrimTrailingZeros(Vector<const char> buffer) {
+  for (int i = buffer.length() - 1; i >= 0; --i) {
+    if (buffer[i] != '0') {
+      return buffer.SubVector(0, i + 1);
+    }
+  }
+  return Vector<const char>(buffer.start(), 0);
+}
+
+
+static void CutToMaxSignificantDigits(Vector<const char> buffer,
+                                       int exponent,
+                                       char* significant_buffer,
+                                       int* significant_exponent) {
+  for (int i = 0; i < kMaxSignificantDecimalDigits - 1; ++i) {
+    significant_buffer[i] = buffer[i];
+  }
+  // The input buffer has been trimmed. Therefore the last digit must be
+  // different from '0'.
+  ASSERT(buffer[buffer.length() - 1] != '0');
+  // Set the last digit to be non-zero. This is sufficient to guarantee
+  // correct rounding.
+  significant_buffer[kMaxSignificantDecimalDigits - 1] = '1';
+  *significant_exponent =
+      exponent + (buffer.length() - kMaxSignificantDecimalDigits);
+}
+
+
+// Trims the buffer and cuts it to at most kMaxSignificantDecimalDigits.
+// If possible the input-buffer is reused, but if the buffer needs to be
+// modified (due to cutting), then the input needs to be copied into the
+// buffer_copy_space.
+static void TrimAndCut(Vector<const char> buffer, int exponent,
+                       char* buffer_copy_space, int space_size,
+                       Vector<const char>* trimmed, int* updated_exponent) {
+  Vector<const char> left_trimmed = TrimLeadingZeros(buffer);
+  Vector<const char> right_trimmed = TrimTrailingZeros(left_trimmed);
+  exponent += left_trimmed.length() - right_trimmed.length();
+  if (right_trimmed.length() > kMaxSignificantDecimalDigits) {
+    (void) space_size;  // Mark variable as used.
+    ASSERT(space_size >= kMaxSignificantDecimalDigits);
+    CutToMaxSignificantDigits(right_trimmed, exponent,
+                              buffer_copy_space, updated_exponent);
+    *trimmed = Vector<const char>(buffer_copy_space,
+                                 kMaxSignificantDecimalDigits);
+  } else {
+    *trimmed = right_trimmed;
+    *updated_exponent = exponent;
+  }
+}
+
+
+// Reads digits from the buffer and converts them to a uint64.
+// Reads in as many digits as fit into a uint64.
+// When the string starts with "1844674407370955161" no further digit is read.
+// Since 2^64 = 18446744073709551616 it would still be possible read another
+// digit if it was less or equal than 6, but this would complicate the code.
+static uint64_t ReadUint64(Vector<const char> buffer,
+                           int* number_of_read_digits) {
+  uint64_t result = 0;
+  int i = 0;
+  while (i < buffer.length() && result <= (kMaxUint64 / 10 - 1)) {
+    int digit = buffer[i++] - '0';
+    ASSERT(0 <= digit && digit <= 9);
+    result = 10 * result + digit;
+  }
+  *number_of_read_digits = i;
+  return result;
+}
+
+
+// Reads a DiyFp from the buffer.
+// The returned DiyFp is not necessarily normalized.
+// If remaining_decimals is zero then the returned DiyFp is accurate.
+// Otherwise it has been rounded and has error of at most 1/2 ulp.
+static void ReadDiyFp(Vector<const char> buffer,
+                      DiyFp* result,
+                      int* remaining_decimals) {
+  int read_digits;
+  uint64_t significand = ReadUint64(buffer, &read_digits);
+  if (buffer.length() == read_digits) {
+    *result = DiyFp(significand, 0);
+    *remaining_decimals = 0;
+  } else {
+    // Round the significand.
+    if (buffer[read_digits] >= '5') {
+      significand++;
+    }
+    // Compute the binary exponent.
+    int exponent = 0;
+    *result = DiyFp(significand, exponent);
+    *remaining_decimals = buffer.length() - read_digits;
+  }
+}
+
+
+static bool DoubleStrtod(Vector<const char> trimmed,
+                         int exponent,
+                         double* result) {
+#if !defined(DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS)
+  // On x86 the floating-point stack can be 64 or 80 bits wide. If it is
+  // 80 bits wide (as is the case on Linux) then double-rounding occurs and the
+  // result is not accurate.
+  // We know that Windows32 uses 64 bits and is therefore accurate.
+  // Note that the ARM simulator is compiled for 32bits. It therefore exhibits
+  // the same problem.
+  return false;
+#endif
+  if (trimmed.length() <= kMaxExactDoubleIntegerDecimalDigits) {
+    int read_digits;
+    // The trimmed input fits into a double.
+    // If the 10^exponent (resp. 10^-exponent) fits into a double too then we
+    // can compute the result-double simply by multiplying (resp. dividing) the
+    // two numbers.
+    // This is possible because IEEE guarantees that floating-point operations
+    // return the best possible approximation.
+    if (exponent < 0 && -exponent < kExactPowersOfTenSize) {
+      // 10^-exponent fits into a double.
+      *result = static_cast<double>(ReadUint64(trimmed, &read_digits));
+      ASSERT(read_digits == trimmed.length());
+      *result /= exact_powers_of_ten[-exponent];
+      return true;
+    }
+    if (0 <= exponent && exponent < kExactPowersOfTenSize) {
+      // 10^exponent fits into a double.
+      *result = static_cast<double>(ReadUint64(trimmed, &read_digits));
+      ASSERT(read_digits == trimmed.length());
+      *result *= exact_powers_of_ten[exponent];
+      return true;
+    }
+    int remaining_digits =
+        kMaxExactDoubleIntegerDecimalDigits - trimmed.length();
+    if ((0 <= exponent) &&
+        (exponent - remaining_digits < kExactPowersOfTenSize)) {
+      // The trimmed string was short and we can multiply it with
+      // 10^remaining_digits. As a result the remaining exponent now fits
+      // into a double too.
+      *result = static_cast<double>(ReadUint64(trimmed, &read_digits));
+      ASSERT(read_digits == trimmed.length());
+      *result *= exact_powers_of_ten[remaining_digits];
+      *result *= exact_powers_of_ten[exponent - remaining_digits];
+      return true;
+    }
+  }
+  return false;
+}
+
+
+// Returns 10^exponent as an exact DiyFp.
+// The given exponent must be in the range [1; kDecimalExponentDistance[.
+static DiyFp AdjustmentPowerOfTen(int exponent) {
+  ASSERT(0 < exponent);
+  ASSERT(exponent < PowersOfTenCache::kDecimalExponentDistance);
+  // Simply hardcode the remaining powers for the given decimal exponent
+  // distance.
+  ASSERT(PowersOfTenCache::kDecimalExponentDistance == 8);
+  switch (exponent) {
+    case 1: return DiyFp(UINT64_2PART_C(0xa0000000, 00000000), -60);
+    case 2: return DiyFp(UINT64_2PART_C(0xc8000000, 00000000), -57);
+    case 3: return DiyFp(UINT64_2PART_C(0xfa000000, 00000000), -54);
+    case 4: return DiyFp(UINT64_2PART_C(0x9c400000, 00000000), -50);
+    case 5: return DiyFp(UINT64_2PART_C(0xc3500000, 00000000), -47);
+    case 6: return DiyFp(UINT64_2PART_C(0xf4240000, 00000000), -44);
+    case 7: return DiyFp(UINT64_2PART_C(0x98968000, 00000000), -40);
+    default:
+      UNREACHABLE();
+  }
+}
+
+
+// If the function returns true then the result is the correct double.
+// Otherwise it is either the correct double or the double that is just below
+// the correct double.
+static bool DiyFpStrtod(Vector<const char> buffer,
+                        int exponent,
+                        double* result) {
+  DiyFp input;
+  int remaining_decimals;
+  ReadDiyFp(buffer, &input, &remaining_decimals);
+  // Since we may have dropped some digits the input is not accurate.
+  // If remaining_decimals is different than 0 than the error is at most
+  // .5 ulp (unit in the last place).
+  // We don't want to deal with fractions and therefore keep a common
+  // denominator.
+  const int kDenominatorLog = 3;
+  const int kDenominator = 1 << kDenominatorLog;
+  // Move the remaining decimals into the exponent.
+  exponent += remaining_decimals;
+  uint64_t error = (remaining_decimals == 0 ? 0 : kDenominator / 2);
+
+  int old_e = input.e();
+  input.Normalize();
+  error <<= old_e - input.e();
+
+  ASSERT(exponent <= PowersOfTenCache::kMaxDecimalExponent);
+  if (exponent < PowersOfTenCache::kMinDecimalExponent) {
+    *result = 0.0;
+    return true;
+  }
+  DiyFp cached_power;
+  int cached_decimal_exponent;
+  PowersOfTenCache::GetCachedPowerForDecimalExponent(exponent,
+                                                     &cached_power,
+                                                     &cached_decimal_exponent);
+
+  if (cached_decimal_exponent != exponent) {
+    int adjustment_exponent = exponent - cached_decimal_exponent;
+    DiyFp adjustment_power = AdjustmentPowerOfTen(adjustment_exponent);
+    input.Multiply(adjustment_power);
+    if (kMaxUint64DecimalDigits - buffer.length() >= adjustment_exponent) {
+      // The product of input with the adjustment power fits into a 64 bit
+      // integer.
+      ASSERT(DiyFp::kSignificandSize == 64);
+    } else {
+      // The adjustment power is exact. There is hence only an error of 0.5.
+      error += kDenominator / 2;
+    }
+  }
+
+  input.Multiply(cached_power);
+  // The error introduced by a multiplication of a*b equals
+  //   error_a + error_b + error_a*error_b/2^64 + 0.5
+  // Substituting a with 'input' and b with 'cached_power' we have
+  //   error_b = 0.5  (all cached powers have an error of less than 0.5 ulp),
+  //   error_ab = 0 or 1 / kDenominator > error_a*error_b/ 2^64
+  int error_b = kDenominator / 2;
+  int error_ab = (error == 0 ? 0 : 1);  // We round up to 1.
+  int fixed_error = kDenominator / 2;
+  error += error_b + error_ab + fixed_error;
+
+  old_e = input.e();
+  input.Normalize();
+  error <<= old_e - input.e();
+
+  // See if the double's significand changes if we add/subtract the error.
+  int order_of_magnitude = DiyFp::kSignificandSize + input.e();
+  int effective_significand_size =
+      Double::SignificandSizeForOrderOfMagnitude(order_of_magnitude);
+  int precision_digits_count =
+      DiyFp::kSignificandSize - effective_significand_size;
+  if (precision_digits_count + kDenominatorLog >= DiyFp::kSignificandSize) {
+    // This can only happen for very small denormals. In this case the
+    // half-way multiplied by the denominator exceeds the range of an uint64.
+    // Simply shift everything to the right.
+    int shift_amount = (precision_digits_count + kDenominatorLog) -
+        DiyFp::kSignificandSize + 1;
+    input.set_f(input.f() >> shift_amount);
+    input.set_e(input.e() + shift_amount);
+    // We add 1 for the lost precision of error, and kDenominator for
+    // the lost precision of input.f().
+    error = (error >> shift_amount) + 1 + kDenominator;
+    precision_digits_count -= shift_amount;
+  }
+  // We use uint64_ts now. This only works if the DiyFp uses uint64_ts too.
+  ASSERT(DiyFp::kSignificandSize == 64);
+  ASSERT(precision_digits_count < 64);
+  uint64_t one64 = 1;
+  uint64_t precision_bits_mask = (one64 << precision_digits_count) - 1;
+  uint64_t precision_bits = input.f() & precision_bits_mask;
+  uint64_t half_way = one64 << (precision_digits_count - 1);
+  precision_bits *= kDenominator;
+  half_way *= kDenominator;
+  DiyFp rounded_input(input.f() >> precision_digits_count,
+                      input.e() + precision_digits_count);
+  if (precision_bits >= half_way + error) {
+    rounded_input.set_f(rounded_input.f() + 1);
+  }
+  // If the last_bits are too close to the half-way case than we are too
+  // inaccurate and round down. In this case we return false so that we can
+  // fall back to a more precise algorithm.
+
+  *result = Double(rounded_input).value();
+  if (half_way - error < precision_bits && precision_bits < half_way + error) {
+    // Too imprecise. The caller will have to fall back to a slower version.
+    // However the returned number is guaranteed to be either the correct
+    // double, or the next-lower double.
+    return false;
+  } else {
+    return true;
+  }
+}
+
+
+// Returns
+//   - -1 if buffer*10^exponent < diy_fp.
+//   -  0 if buffer*10^exponent == diy_fp.
+//   - +1 if buffer*10^exponent > diy_fp.
+// Preconditions:
+//   buffer.length() + exponent <= kMaxDecimalPower + 1
+//   buffer.length() + exponent > kMinDecimalPower
+//   buffer.length() <= kMaxDecimalSignificantDigits
+static int CompareBufferWithDiyFp(Vector<const char> buffer,
+                                  int exponent,
+                                  DiyFp diy_fp) {
+  ASSERT(buffer.length() + exponent <= kMaxDecimalPower + 1);
+  ASSERT(buffer.length() + exponent > kMinDecimalPower);
+  ASSERT(buffer.length() <= kMaxSignificantDecimalDigits);
+  // Make sure that the Bignum will be able to hold all our numbers.
+  // Our Bignum implementation has a separate field for exponents. Shifts will
+  // consume at most one bigit (< 64 bits).
+  // ln(10) == 3.3219...
+  ASSERT(((kMaxDecimalPower + 1) * 333 / 100) < Bignum::kMaxSignificantBits);
+  Bignum buffer_bignum;
+  Bignum diy_fp_bignum;
+  buffer_bignum.AssignDecimalString(buffer);
+  diy_fp_bignum.AssignUInt64(diy_fp.f());
+  if (exponent >= 0) {
+    buffer_bignum.MultiplyByPowerOfTen(exponent);
+  } else {
+    diy_fp_bignum.MultiplyByPowerOfTen(-exponent);
+  }
+  if (diy_fp.e() > 0) {
+    diy_fp_bignum.ShiftLeft(diy_fp.e());
+  } else {
+    buffer_bignum.ShiftLeft(-diy_fp.e());
+  }
+  return Bignum::Compare(buffer_bignum, diy_fp_bignum);
+}
+
+
+// Returns true if the guess is the correct double.
+// Returns false, when guess is either correct or the next-lower double.
+static bool ComputeGuess(Vector<const char> trimmed, int exponent,
+                         double* guess) {
+  if (trimmed.length() == 0) {
+    *guess = 0.0;
+    return true;
+  }
+  if (exponent + trimmed.length() - 1 >= kMaxDecimalPower) {
+    *guess = Double::Infinity();
+    return true;
+  }
+  if (exponent + trimmed.length() <= kMinDecimalPower) {
+    *guess = 0.0;
+    return true;
+  }
+
+  if (DoubleStrtod(trimmed, exponent, guess) ||
+      DiyFpStrtod(trimmed, exponent, guess)) {
+    return true;
+  }
+  if (*guess == Double::Infinity()) {
+    return true;
+  }
+  return false;
+}
+
+double Strtod(Vector<const char> buffer, int exponent) {
+  char copy_buffer[kMaxSignificantDecimalDigits];
+  Vector<const char> trimmed;
+  int updated_exponent;
+  TrimAndCut(buffer, exponent, copy_buffer, kMaxSignificantDecimalDigits,
+             &trimmed, &updated_exponent);
+  exponent = updated_exponent;
+
+  double guess;
+  bool is_correct = ComputeGuess(trimmed, exponent, &guess);
+  if (is_correct) return guess;
+
+  DiyFp upper_boundary = Double(guess).UpperBoundary();
+  int comparison = CompareBufferWithDiyFp(trimmed, exponent, upper_boundary);
+  if (comparison < 0) {
+    return guess;
+  } else if (comparison > 0) {
+    return Double(guess).NextDouble();
+  } else if ((Double(guess).Significand() & 1) == 0) {
+    // Round towards even.
+    return guess;
+  } else {
+    return Double(guess).NextDouble();
+  }
+}
+
+float Strtof(Vector<const char> buffer, int exponent) {
+  char copy_buffer[kMaxSignificantDecimalDigits];
+  Vector<const char> trimmed;
+  int updated_exponent;
+  TrimAndCut(buffer, exponent, copy_buffer, kMaxSignificantDecimalDigits,
+             &trimmed, &updated_exponent);
+  exponent = updated_exponent;
+
+  double double_guess;
+  bool is_correct = ComputeGuess(trimmed, exponent, &double_guess);
+
+  float float_guess = static_cast<float>(double_guess);
+  if (float_guess == double_guess) {
+    // This shortcut triggers for integer values.
+    return float_guess;
+  }
+
+  // We must catch double-rounding. Say the double has been rounded up, and is
+  // now a boundary of a float, and rounds up again. This is why we have to
+  // look at previous too.
+  // Example (in decimal numbers):
+  //    input: 12349
+  //    high-precision (4 digits): 1235
+  //    low-precision (3 digits):
+  //       when read from input: 123
+  //       when rounded from high precision: 124.
+  // To do this we simply look at the neigbors of the correct result and see
+  // if they would round to the same float. If the guess is not correct we have
+  // to look at four values (since two different doubles could be the correct
+  // double).
+
+  double double_next = Double(double_guess).NextDouble();
+  double double_previous = Double(double_guess).PreviousDouble();
+
+  float f1 = static_cast<float>(double_previous);
+  float f2 = float_guess;
+  float f3 = static_cast<float>(double_next);
+  float f4;
+  if (is_correct) {
+    f4 = f3;
+  } else {
+    double double_next2 = Double(double_next).NextDouble();
+    f4 = static_cast<float>(double_next2);
+  }
+  (void) f2;  // Mark variable as used.
+  ASSERT(f1 <= f2 && f2 <= f3 && f3 <= f4);
+
+  // If the guess doesn't lie near a single-precision boundary we can simply
+  // return its float-value.
+  if (f1 == f4) {
+    return float_guess;
+  }
+
+  ASSERT((f1 != f2 && f2 == f3 && f3 == f4) ||
+         (f1 == f2 && f2 != f3 && f3 == f4) ||
+         (f1 == f2 && f2 == f3 && f3 != f4));
+
+  // guess and next are the two possible canditates (in the same way that
+  // double_guess was the lower candidate for a double-precision guess).
+  float guess = f1;
+  float next = f4;
+  DiyFp upper_boundary;
+  if (guess == 0.0f) {
+    float min_float = 1e-45f;
+    upper_boundary = Double(static_cast<double>(min_float) / 2).AsDiyFp();
+  } else {
+    upper_boundary = Single(guess).UpperBoundary();
+  }
+  int comparison = CompareBufferWithDiyFp(trimmed, exponent, upper_boundary);
+  if (comparison < 0) {
+    return guess;
+  } else if (comparison > 0) {
+    return next;
+  } else if ((Single(guess).Significand() & 1) == 0) {
+    // Round towards even.
+    return guess;
+  } else {
+    return next;
+  }
+}
+
+}  // namespace double_conversion

+ 45 - 0
third-party/double-conversion-1.1.6/src/strtod.h

@@ -0,0 +1,45 @@
+// 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.
+
+#ifndef DOUBLE_CONVERSION_STRTOD_H_
+#define DOUBLE_CONVERSION_STRTOD_H_
+
+#include "utils.h"
+
+namespace double_conversion {
+
+// The buffer must only contain digits in the range [0-9]. It must not
+// contain a dot or a sign. It must not start with '0', and must not be empty.
+double Strtod(Vector<const char> buffer, int exponent);
+
+// The buffer must only contain digits in the range [0-9]. It must not
+// contain a dot or a sign. It must not start with '0', and must not be empty.
+float Strtof(Vector<const char> buffer, int exponent);
+
+}  // namespace double_conversion
+
+#endif  // DOUBLE_CONVERSION_STRTOD_H_

+ 324 - 0
third-party/double-conversion-1.1.6/src/utils.h

@@ -0,0 +1,324 @@
+// 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.
+
+#ifndef DOUBLE_CONVERSION_UTILS_H_
+#define DOUBLE_CONVERSION_UTILS_H_
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <assert.h>
+#ifndef ASSERT
+#define ASSERT(condition)         \
+    assert(condition);
+#endif
+#ifndef UNIMPLEMENTED
+#define UNIMPLEMENTED() (abort())
+#endif
+#ifndef UNREACHABLE
+#define UNREACHABLE()   (abort())
+#endif
+
+// Double operations detection based on target architecture.
+// Linux uses a 80bit wide floating point stack on x86. This induces double
+// rounding, which in turn leads to wrong results.
+// An easy way to test if the floating-point operations are correct is to
+// evaluate: 89255.0/1e22. If the floating-point stack is 64 bits wide then
+// the result is equal to 89255e-22.
+// The best way to test this, is to create a division-function and to compare
+// the output of the division with the expected result. (Inlining must be
+// disabled.)
+// On Linux,x86 89255e-22 != Div_double(89255.0/1e22)
+#if defined(_M_X64) || defined(__x86_64__) || \
+    defined(__ARMEL__) || defined(__avr32__) || \
+    defined(__hppa__) || defined(__ia64__) || \
+    defined(__mips__) || \
+    defined(__powerpc__) || defined(__ppc__) || defined(__ppc64__) || \
+    defined(__sparc__) || defined(__sparc) || defined(__s390__) || \
+    defined(__SH4__) || defined(__alpha__) || \
+    defined(_MIPS_ARCH_MIPS32R2) || \
+    defined(__AARCH64EL__)
+#define DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS 1
+#elif defined(__mc68000__)
+#undef DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS
+#elif defined(_M_IX86) || defined(__i386__) || defined(__i386)
+#if defined(_WIN32)
+// Windows uses a 64bit wide floating point stack.
+#define DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS 1
+#else
+#undef DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS
+#endif  // _WIN32
+#else
+#error Target architecture was not detected as supported by Double-Conversion.
+#endif
+
+#if defined(__GNUC__)
+#define DOUBLE_CONVERSION_UNUSED __attribute__((unused))
+#else
+#define DOUBLE_CONVERSION_UNUSED
+#endif
+
+#if defined(_WIN32) && !defined(__MINGW32__)
+
+typedef signed char int8_t;
+typedef unsigned char uint8_t;
+typedef short int16_t;  // NOLINT
+typedef unsigned short uint16_t;  // NOLINT
+typedef int int32_t;
+typedef unsigned int uint32_t;
+typedef __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+// intptr_t and friends are defined in crtdefs.h through stdio.h.
+
+#else
+
+#include <stdint.h>
+
+#endif
+
+// The following macro works on both 32 and 64-bit platforms.
+// Usage: instead of writing 0x1234567890123456
+//      write UINT64_2PART_C(0x12345678,90123456);
+#define UINT64_2PART_C(a, b) (((static_cast<uint64_t>(a) << 32) + 0x##b##u))
+
+
+// The expression ARRAY_SIZE(a) is a compile-time constant of type
+// size_t which represents the number of elements of the given
+// array. You should only use ARRAY_SIZE on statically allocated
+// arrays.
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(a)                                   \
+  ((sizeof(a) / sizeof(*(a))) /                         \
+  static_cast<size_t>(!(sizeof(a) % sizeof(*(a)))))
+#endif
+
+// A macro to disallow the evil copy constructor and operator= functions
+// This should be used in the private: declarations for a class
+#ifndef DISALLOW_COPY_AND_ASSIGN
+#define DISALLOW_COPY_AND_ASSIGN(TypeName)      \
+  TypeName(const TypeName&);                    \
+  void operator=(const TypeName&)
+#endif
+
+// A macro to disallow all the implicit constructors, namely the
+// default constructor, copy constructor and operator= functions.
+//
+// This should be used in the private: declarations for a class
+// that wants to prevent anyone from instantiating it. This is
+// especially useful for classes containing only static methods.
+#ifndef DISALLOW_IMPLICIT_CONSTRUCTORS
+#define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \
+  TypeName();                                    \
+  DISALLOW_COPY_AND_ASSIGN(TypeName)
+#endif
+
+namespace double_conversion {
+
+static const int kCharSize = sizeof(char);
+
+// Returns the maximum of the two parameters.
+template <typename T>
+static T Max(T a, T b) {
+  return a < b ? b : a;
+}
+
+
+// Returns the minimum of the two parameters.
+template <typename T>
+static T Min(T a, T b) {
+  return a < b ? a : b;
+}
+
+
+inline int StrLength(const char* string) {
+  size_t length = strlen(string);
+  ASSERT(length == static_cast<size_t>(static_cast<int>(length)));
+  return static_cast<int>(length);
+}
+
+// This is a simplified version of V8's Vector class.
+template <typename T>
+class Vector {
+ public:
+  Vector() : start_(NULL), length_(0) {}
+  Vector(T* data, int length) : start_(data), length_(length) {
+    ASSERT(length == 0 || (length > 0 && data != NULL));
+  }
+
+  // Returns a vector using the same backing storage as this one,
+  // spanning from and including 'from', to but not including 'to'.
+  Vector<T> SubVector(int from, int to) {
+    ASSERT(to <= length_);
+    ASSERT(from < to);
+    ASSERT(0 <= from);
+    return Vector<T>(start() + from, to - from);
+  }
+
+  // Returns the length of the vector.
+  int length() const { return length_; }
+
+  // Returns whether or not the vector is empty.
+  bool is_empty() const { return length_ == 0; }
+
+  // Returns the pointer to the start of the data in the vector.
+  T* start() const { return start_; }
+
+  // Access individual vector elements - checks bounds in debug mode.
+  T& operator[](int index) const {
+    ASSERT(0 <= index && index < length_);
+    return start_[index];
+  }
+
+  T& first() { return start_[0]; }
+
+  T& last() { return start_[length_ - 1]; }
+
+ private:
+  T* start_;
+  int length_;
+};
+
+
+// Helper class for building result strings in a character buffer. The
+// purpose of the class is to use safe operations that checks the
+// buffer bounds on all operations in debug mode.
+class StringBuilder {
+ public:
+  StringBuilder(char* buffer, int size)
+      : buffer_(buffer, size), position_(0) { }
+
+  ~StringBuilder() { if (!is_finalized()) Finalize(); }
+
+  int size() const { return buffer_.length(); }
+
+  // Get the current position in the builder.
+  int position() const {
+    ASSERT(!is_finalized());
+    return position_;
+  }
+
+  // Reset the position.
+  void Reset() { position_ = 0; }
+
+  // Add a single character to the builder. It is not allowed to add
+  // 0-characters; use the Finalize() method to terminate the string
+  // instead.
+  void AddCharacter(char c) {
+    ASSERT(c != '\0');
+    ASSERT(!is_finalized() && position_ < buffer_.length());
+    buffer_[position_++] = c;
+  }
+
+  // Add an entire string to the builder. Uses strlen() internally to
+  // compute the length of the input string.
+  void AddString(const char* s) {
+    AddSubstring(s, StrLength(s));
+  }
+
+  // Add the first 'n' characters of the given string 's' to the
+  // builder. The input string must have enough characters.
+  void AddSubstring(const char* s, int n) {
+    ASSERT(!is_finalized() && position_ + n < buffer_.length());
+    ASSERT(static_cast<size_t>(n) <= strlen(s));
+    memmove(&buffer_[position_], s, n * kCharSize);
+    position_ += n;
+  }
+
+
+  // Add character padding to the builder. If count is non-positive,
+  // nothing is added to the builder.
+  void AddPadding(char c, int count) {
+    for (int i = 0; i < count; i++) {
+      AddCharacter(c);
+    }
+  }
+
+  // Finalize the string by 0-terminating it and returning the buffer.
+  char* Finalize() {
+    ASSERT(!is_finalized() && position_ < buffer_.length());
+    buffer_[position_] = '\0';
+    // Make sure nobody managed to add a 0-character to the
+    // buffer while building the string.
+    ASSERT(strlen(buffer_.start()) == static_cast<size_t>(position_));
+    position_ = -1;
+    ASSERT(is_finalized());
+    return buffer_.start();
+  }
+
+ private:
+  Vector<char> buffer_;
+  int position_;
+
+  bool is_finalized() const { return position_ < 0; }
+
+  DISALLOW_IMPLICIT_CONSTRUCTORS(StringBuilder);
+};
+
+// The type-based aliasing rule allows the compiler to assume that pointers of
+// different types (for some definition of different) never alias each other.
+// Thus the following code does not work:
+//
+// float f = foo();
+// int fbits = *(int*)(&f);
+//
+// The compiler 'knows' that the int pointer can't refer to f since the types
+// don't match, so the compiler may cache f in a register, leaving random data
+// in fbits.  Using C++ style casts makes no difference, however a pointer to
+// char data is assumed to alias any other pointer.  This is the 'memcpy
+// exception'.
+//
+// Bit_cast uses the memcpy exception to move the bits from a variable of one
+// type of a variable of another type.  Of course the end result is likely to
+// be implementation dependent.  Most compilers (gcc-4.2 and MSVC 2005)
+// will completely optimize BitCast away.
+//
+// There is an additional use for BitCast.
+// Recent gccs will warn when they see casts that may result in breakage due to
+// the type-based aliasing rule.  If you have checked that there is no breakage
+// you can use BitCast to cast one pointer type to another.  This confuses gcc
+// enough that it can no longer see that you have cast one pointer type to
+// another thus avoiding the warning.
+template <class Dest, class Source>
+inline Dest BitCast(const Source& source) {
+  // Compile time assertion: sizeof(Dest) == sizeof(Source)
+  // A compile error here means your Dest and Source have different sizes.
+  DOUBLE_CONVERSION_UNUSED
+      typedef char VerifySizesAreEqual[sizeof(Dest) == sizeof(Source) ? 1 : -1];
+
+  Dest dest;
+  memmove(&dest, &source, sizeof(dest));
+  return dest;
+}
+
+template <class Dest, class Source>
+inline Dest BitCast(Source* source) {
+  return BitCast<Dest>(reinterpret_cast<uintptr_t>(source));
+}
+
+}  // namespace double_conversion
+
+#endif  // DOUBLE_CONVERSION_UTILS_H_

+ 1 - 0
third-party/double-conversion-1.1.6/test/CMakeLists.txt

@@ -0,0 +1 @@
+add_subdirectory(cctest)

+ 50 - 0
third-party/double-conversion-1.1.6/test/cctest/CMakeLists.txt

@@ -0,0 +1,50 @@
+
+set(CCTEST_SRC
+  cctest.cc
+  gay-fixed.cc
+  gay-precision.cc
+  gay-shortest.cc
+  gay-shortest-single.cc
+  test-bignum.cc
+  test-bignum-dtoa.cc
+  test-conversions.cc
+  test-diy-fp.cc
+  test-dtoa.cc
+  test-fast-dtoa.cc
+  test-fixed-dtoa.cc
+  test-ieee.cc
+  test-strtod.cc
+)
+
+add_executable(cctest ${CCTEST_SRC})
+target_link_libraries(cctest double-conversion)
+
+add_test(NAME test_bignum
+  WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+  COMMAND $<TARGET_FILE:cctest> test-bignum)
+
+add_test(NAME test_bignum_dtoa
+  WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+  COMMAND $<TARGET_FILE:cctest> test-bignum-dtoa)
+
+add_test(NAME test_conversions
+  WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+  COMMAND $<TARGET_FILE:cctest> test-conversions)
+add_test(NAME test_diy_fp
+  WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+  COMMAND $<TARGET_FILE:cctest> test-diy-fp)
+add_test(NAME test_dtoa
+  WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+  COMMAND $<TARGET_FILE:cctest> test-dtoa)
+add_test(NAME test_fast_dtoa
+  WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+  COMMAND $<TARGET_FILE:cctest> test-fast-dtoa)
+add_test(NAME test_fixed_dtoa
+  WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+  COMMAND $<TARGET_FILE:cctest> test-fixed-dtoa)
+add_test(NAME test_ieee
+  WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+  COMMAND $<TARGET_FILE:cctest> test-ieee)
+add_test(NAME test_strtod
+  WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+  COMMAND $<TARGET_FILE:cctest> test-strtod)

+ 17 - 0
third-party/double-conversion-1.1.6/test/cctest/SConscript

@@ -0,0 +1,17 @@
+double_conversion_test_sources = [
+    'cctest.cc',
+    'gay-fixed.cc',
+    'gay-precision.cc',
+    'gay-shortest.cc',
+    'gay-shortest-single.cc',
+    'test-bignum.cc',
+    'test-bignum-dtoa.cc',
+    'test-conversions.cc',
+    'test-diy-fp.cc',
+    'test-dtoa.cc',
+    'test-fast-dtoa.cc',
+    'test-fixed-dtoa.cc',
+    'test-ieee.cc',
+    'test-strtod.cc',
+  ]
+Return('double_conversion_test_sources')

+ 122 - 0
third-party/double-conversion-1.1.6/test/cctest/cctest.cc

@@ -0,0 +1,122 @@
+// Copyright 2008 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 "cctest.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+CcTest* CcTest::last_ = NULL;
+
+
+CcTest::CcTest(TestFunction* callback, const char* file, const char* name,
+               const char* dependency, bool enabled)
+    : callback_(callback), name_(name), dependency_(dependency), prev_(last_) {
+  // Find the base name of this test (const_cast required on Windows).
+  char *basename = strrchr(const_cast<char *>(file), '/');
+  if (!basename) {
+    basename = strrchr(const_cast<char *>(file), '\\');
+  }
+  if (!basename) {
+    basename = strdup(file);
+  } else {
+    basename = strdup(basename + 1);
+  }
+  // Drop the extension, if there is one.
+  char *extension = strrchr(basename, '.');
+  if (extension) *extension = 0;
+  // Install this test in the list of tests
+  file_ = basename;
+  enabled_ = enabled;
+  prev_ = last_;
+  last_ = this;
+}
+
+
+static void PrintTestList(CcTest* current) {
+  if (current == NULL) return;
+  PrintTestList(current->prev());
+  if (current->dependency() != NULL) {
+    printf("%s/%s<%s\n",
+           current->file(), current->name(), current->dependency());
+  } else {
+    printf("%s/%s<\n", current->file(), current->name());
+  }
+}
+
+
+int main(int argc, char* argv[]) {
+  int tests_run = 0;
+  bool print_run_count = true;
+  for (int i = 1; i < argc; i++) {
+    char* arg = argv[i];
+    if (strcmp(arg, "--list") == 0) {
+      PrintTestList(CcTest::last());
+      print_run_count = false;
+
+    } else {
+      char* arg_copy = strdup(arg);
+      char* testname = strchr(arg_copy, '/');
+      if (testname) {
+        // Split the string in two by nulling the slash and then run
+        // exact matches.
+        *testname = 0;
+        char* file = arg_copy;
+        char* name = testname + 1;
+        CcTest* test = CcTest::last();
+        while (test != NULL) {
+          if (test->enabled()
+              && strcmp(test->file(), file) == 0
+              && strcmp(test->name(), name) == 0) {
+            test->Run();
+            tests_run++;
+          }
+          test = test->prev();
+        }
+
+      } else {
+        // Run all tests with the specified file or test name.
+        char* file_or_name = arg_copy;
+        CcTest* test = CcTest::last();
+        while (test != NULL) {
+          if (test->enabled()
+              && (strcmp(test->file(), file_or_name) == 0
+                  || strcmp(test->name(), file_or_name) == 0)) {
+            test->Run();
+            tests_run++;
+          }
+          test = test->prev();
+        }
+      }
+      delete[] arg_copy;
+    }
+  }
+  if (print_run_count && tests_run != 1)
+    printf("Ran %i tests.\n", tests_run);
+  return 0;
+}

+ 141 - 0
third-party/double-conversion-1.1.6/test/cctest/cctest.h

@@ -0,0 +1,141 @@
+// Copyright 2008 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.
+
+#ifndef CCTEST_H_
+#define CCTEST_H_
+
+#include <stdio.h>
+#include <string.h>
+
+#include "utils.h"
+
+#ifndef TEST
+#define TEST(Name)                                                       \
+  static void Test##Name();                                              \
+  CcTest register_test_##Name(Test##Name, __FILE__, #Name, NULL, true);  \
+  static void Test##Name()
+#endif
+
+#ifndef DEPENDENT_TEST
+#define DEPENDENT_TEST(Name, Dep)                                        \
+  static void Test##Name();                                              \
+  CcTest register_test_##Name(Test##Name, __FILE__, #Name, #Dep, true);  \
+  static void Test##Name()
+#endif
+
+#ifndef DISABLED_TEST
+#define DISABLED_TEST(Name)                                              \
+  static void Test##Name();                                              \
+  CcTest register_test_##Name(Test##Name, __FILE__, #Name, NULL, false); \
+  static void Test##Name()
+#endif
+
+#define CHECK(condition) CheckHelper(__FILE__, __LINE__, #condition, condition)
+#define CHECK_GE(a, b) CHECK((a) >= (b))
+
+static inline void CheckHelper(const char* file,
+                               int line,
+                               const char* source,
+                               bool condition) {
+  if (!condition) {
+    printf("%s:%d:\n CHECK(%s) failed\n", file, line, source);
+    abort();
+  }
+}
+
+#define CHECK_EQ(a, b) CheckEqualsHelper(__FILE__, __LINE__, #a, a, #b, b)
+
+static inline void CheckEqualsHelper(const char* file, int line,
+                                     const char* expected_source,
+                                     const char* expected,
+                                     const char* value_source,
+                                     const char* value) {
+  if ((expected == NULL && value != NULL) ||
+      (expected != NULL && value == NULL) ||
+      (expected != NULL && value != NULL && strcmp(expected, value) != 0)) {
+    printf("%s:%d:\n CHECK_EQ(%s, %s) failed\n"
+           "#  Expected: %s\n"
+           "#  Found:    %s\n",
+           file, line, expected_source, value_source, expected, value);
+    abort();
+  }
+}
+
+static inline void CheckEqualsHelper(const char* file, int line,
+                                     const char* expected_source,
+                                     int expected,
+                                     const char* value_source,
+                                     int value) {
+  if (expected != value) {
+    printf("%s:%d:\n CHECK_EQ(%s, %s) failed\n"
+           "#  Expected: %d\n"
+           "#  Found:    %d\n",
+           file, line, expected_source, value_source, expected, value);
+    abort();
+  }
+}
+
+static inline void CheckEqualsHelper(const char* file, int line,
+                                     const char* expected_source,
+                                     double expected,
+                                     const char* value_source,
+                                     double value) {
+  // If expected and value are NaNs then expected != value.
+  if (expected != value && (expected == expected || value == value)) {
+    printf("%s:%d:\n CHECK_EQ(%s, %s) failed\n"
+           "#  Expected: %.30e\n"
+           "#  Found:    %.30e\n",
+           file, line, expected_source, value_source, expected, value);
+    abort();
+  }
+}
+
+
+class CcTest {
+ public:
+  typedef void (TestFunction)();
+  CcTest(TestFunction* callback, const char* file, const char* name,
+         const char* dependency, bool enabled);
+  void Run() { callback_(); }
+  static int test_count();
+  static CcTest* last() { return last_; }
+  CcTest* prev() { return prev_; }
+  const char* file() { return file_; }
+  const char* name() { return name_; }
+  const char* dependency() { return dependency_; }
+  bool enabled() { return enabled_; }
+ private:
+  TestFunction* callback_;
+  const char* file_;
+  const char* name_;
+  const char* dependency_;
+  bool enabled_;
+  static CcTest* last_;
+  CcTest* prev_;
+};
+
+#endif  // ifndef CCTEST_H_

+ 314 - 0
third-party/double-conversion-1.1.6/test/cctest/checks.h

@@ -0,0 +1,314 @@
+// Copyright 2006-2008 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.
+
+#ifndef V8_CHECKS_H_
+#define V8_CHECKS_H_
+
+#include <string.h>
+
+#include "flags.h"
+
+extern "C" void V8_Fatal(const char* file, int line, const char* format, ...);
+void API_Fatal(const char* location, const char* format, ...);
+
+// The FATAL, UNREACHABLE and UNIMPLEMENTED macros are useful during
+// development, but they should not be relied on in the final product.
+#ifdef DEBUG
+#define FATAL(msg)                              \
+  V8_Fatal(__FILE__, __LINE__, "%s", (msg))
+#define UNIMPLEMENTED()                         \
+  V8_Fatal(__FILE__, __LINE__, "unimplemented code")
+#define UNREACHABLE()                           \
+  V8_Fatal(__FILE__, __LINE__, "unreachable code")
+#else
+#define FATAL(msg)                              \
+  V8_Fatal("", 0, "%s", (msg))
+#define UNIMPLEMENTED()                         \
+  V8_Fatal("", 0, "unimplemented code")
+#define UNREACHABLE() ((void) 0)
+#endif
+
+
+// Used by the CHECK macro -- should not be called directly.
+static inline void CheckHelper(const char* file,
+                               int line,
+                               const char* source,
+                               bool condition) {
+  if (!condition)
+    V8_Fatal(file, line, "CHECK(%s) failed", source);
+}
+
+
+// The CHECK macro checks that the given condition is true; if not, it
+// prints a message to stderr and aborts.
+#define CHECK(condition) CheckHelper(__FILE__, __LINE__, #condition, condition)
+
+
+// Helper function used by the CHECK_EQ function when given int
+// arguments.  Should not be called directly.
+static inline void CheckEqualsHelper(const char* file, int line,
+                                     const char* expected_source, int expected,
+                                     const char* value_source, int value) {
+  if (expected != value) {
+    V8_Fatal(file, line,
+             "CHECK_EQ(%s, %s) failed\n#   Expected: %i\n#   Found: %i",
+             expected_source, value_source, expected, value);
+  }
+}
+
+
+// Helper function used by the CHECK_EQ function when given int64_t
+// arguments.  Should not be called directly.
+static inline void CheckEqualsHelper(const char* file, int line,
+                                     const char* expected_source,
+                                     int64_t expected,
+                                     const char* value_source,
+                                     int64_t value) {
+  if (expected != value) {
+    // Print int64_t values in hex, as two int32s,
+    // to avoid platform-dependencies.
+    V8_Fatal(file, line,
+             "CHECK_EQ(%s, %s) failed\n#"
+             "   Expected: 0x%08x%08x\n#   Found: 0x%08x%08x",
+             expected_source, value_source,
+             static_cast<uint32_t>(expected >> 32),
+             static_cast<uint32_t>(expected),
+             static_cast<uint32_t>(value >> 32),
+             static_cast<uint32_t>(value));
+  }
+}
+
+
+// Helper function used by the CHECK_NE function when given int
+// arguments.  Should not be called directly.
+static inline void CheckNonEqualsHelper(const char* file,
+                                        int line,
+                                        const char* unexpected_source,
+                                        int unexpected,
+                                        const char* value_source,
+                                        int value) {
+  if (unexpected == value) {
+    V8_Fatal(file, line, "CHECK_NE(%s, %s) failed\n#   Value: %i",
+             unexpected_source, value_source, value);
+  }
+}
+
+
+// Helper function used by the CHECK function when given string
+// arguments.  Should not be called directly.
+static inline void CheckEqualsHelper(const char* file,
+                                     int line,
+                                     const char* expected_source,
+                                     const char* expected,
+                                     const char* value_source,
+                                     const char* value) {
+  if ((expected == NULL && value != NULL) ||
+      (expected != NULL && value == NULL) ||
+      (expected != NULL && value != NULL && strcmp(expected, value) != 0)) {
+    V8_Fatal(file, line,
+             "CHECK_EQ(%s, %s) failed\n#   Expected: %s\n#   Found: %s",
+             expected_source, value_source, expected, value);
+  }
+}
+
+
+static inline void CheckNonEqualsHelper(const char* file,
+                                        int line,
+                                        const char* expected_source,
+                                        const char* expected,
+                                        const char* value_source,
+                                        const char* value) {
+  if (expected == value ||
+      (expected != NULL && value != NULL && strcmp(expected, value) == 0)) {
+    V8_Fatal(file, line, "CHECK_NE(%s, %s) failed\n#   Value: %s",
+             expected_source, value_source, value);
+  }
+}
+
+
+// Helper function used by the CHECK function when given pointer
+// arguments.  Should not be called directly.
+static inline void CheckEqualsHelper(const char* file,
+                                     int line,
+                                     const char* expected_source,
+                                     const void* expected,
+                                     const char* value_source,
+                                     const void* value) {
+  if (expected != value) {
+    V8_Fatal(file, line,
+             "CHECK_EQ(%s, %s) failed\n#   Expected: %p\n#   Found: %p",
+             expected_source, value_source,
+             expected, value);
+  }
+}
+
+
+static inline void CheckNonEqualsHelper(const char* file,
+                                        int line,
+                                        const char* expected_source,
+                                        const void* expected,
+                                        const char* value_source,
+                                        const void* value) {
+  if (expected == value) {
+    V8_Fatal(file, line, "CHECK_NE(%s, %s) failed\n#   Value: %p",
+             expected_source, value_source, value);
+  }
+}
+
+
+// Helper function used by the CHECK function when given floating
+// point arguments.  Should not be called directly.
+static inline void CheckEqualsHelper(const char* file,
+                                     int line,
+                                     const char* expected_source,
+                                     double expected,
+                                     const char* value_source,
+                                     double value) {
+  // Force values to 64 bit memory to truncate 80 bit precision on IA32.
+  volatile double* exp = new double[1];
+  *exp = expected;
+  volatile double* val = new double[1];
+  *val = value;
+  if (*exp != *val) {
+    V8_Fatal(file, line,
+             "CHECK_EQ(%s, %s) failed\n#   Expected: %f\n#   Found: %f",
+             expected_source, value_source, *exp, *val);
+  }
+  delete[] exp;
+  delete[] val;
+}
+
+
+static inline void CheckNonEqualsHelper(const char* file,
+                                     int line,
+                                     const char* expected_source,
+                                     double expected,
+                                     const char* value_source,
+                                     double value) {
+  // Force values to 64 bit memory to truncate 80 bit precision on IA32.
+  volatile double* exp = new double[1];
+  *exp = expected;
+  volatile double* val = new double[1];
+  *val = value;
+  if (*exp == *val) {
+    V8_Fatal(file, line,
+             "CHECK_NE(%s, %s) failed\n#   Value: %f",
+             expected_source, value_source, *val);
+  }
+  delete[] exp;
+  delete[] val;
+}
+
+
+namespace v8 {
+  class Value;
+  template <class T> class Handle;
+}
+
+
+void CheckNonEqualsHelper(const char* file,
+                          int line,
+                          const char* unexpected_source,
+                          v8::Handle<v8::Value> unexpected,
+                          const char* value_source,
+                          v8::Handle<v8::Value> value);
+
+
+void CheckEqualsHelper(const char* file,
+                       int line,
+                       const char* expected_source,
+                       v8::Handle<v8::Value> expected,
+                       const char* value_source,
+                       v8::Handle<v8::Value> value);
+
+
+#define CHECK_EQ(expected, value) CheckEqualsHelper(__FILE__, __LINE__, \
+  #expected, expected, #value, value)
+
+
+#define CHECK_NE(unexpected, value) CheckNonEqualsHelper(__FILE__, __LINE__, \
+  #unexpected, unexpected, #value, value)
+
+
+#define CHECK_GT(a, b) CHECK((a) > (b))
+#define CHECK_GE(a, b) CHECK((a) >= (b))
+
+
+// This is inspired by the static assertion facility in boost.  This
+// is pretty magical.  If it causes you trouble on a platform you may
+// find a fix in the boost code.
+template <bool> class StaticAssertion;
+template <> class StaticAssertion<true> { };
+// This macro joins two tokens.  If one of the tokens is a macro the
+// helper call causes it to be resolved before joining.
+#define SEMI_STATIC_JOIN(a, b) SEMI_STATIC_JOIN_HELPER(a, b)
+#define SEMI_STATIC_JOIN_HELPER(a, b) a##b
+// Causes an error during compilation of the condition is not
+// statically known to be true.  It is formulated as a typedef so that
+// it can be used wherever a typedef can be used.  Beware that this
+// actually causes each use to introduce a new defined type with a
+// name depending on the source line.
+template <int> class StaticAssertionHelper { };
+#define STATIC_CHECK(test)                                                  \
+  typedef                                                                   \
+    StaticAssertionHelper<sizeof(StaticAssertion<static_cast<bool>(test)>)> \
+    SEMI_STATIC_JOIN(__StaticAssertTypedef__, __LINE__)
+
+
+// The ASSERT macro is equivalent to CHECK except that it only
+// generates code in debug builds.
+#ifdef DEBUG
+#define ASSERT_RESULT(expr)  CHECK(expr)
+#define ASSERT(condition)    CHECK(condition)
+#define ASSERT_EQ(v1, v2)    CHECK_EQ(v1, v2)
+#define ASSERT_NE(v1, v2)    CHECK_NE(v1, v2)
+#define ASSERT_GE(v1, v2)    CHECK_GE(v1, v2)
+#define SLOW_ASSERT(condition) if (FLAG_enable_slow_asserts) CHECK(condition)
+#else
+#define ASSERT_RESULT(expr)     (expr)
+#define ASSERT(condition)      ((void) 0)
+#define ASSERT_EQ(v1, v2)      ((void) 0)
+#define ASSERT_NE(v1, v2)      ((void) 0)
+#define ASSERT_GE(v1, v2)      ((void) 0)
+#define SLOW_ASSERT(condition) ((void) 0)
+#endif
+// Static asserts has no impact on runtime performance, so they can be
+// safely enabled in release mode. Moreover, the ((void) 0) expression
+// obeys different syntax rules than typedef's, e.g. it can't appear
+// inside class declaration, this leads to inconsistency between debug
+// and release compilation modes behaviour.
+#define STATIC_ASSERT(test)  STATIC_CHECK(test)
+
+
+#define ASSERT_TAG_ALIGNED(address) \
+  ASSERT((reinterpret_cast<intptr_t>(address) & kHeapObjectTagMask) == 0)
+
+#define ASSERT_SIZE_TAG_ALIGNED(size) ASSERT((size & kHeapObjectTagMask) == 0)
+
+#define ASSERT_NOT_NULL(p)  ASSERT_NE(NULL, p)
+
+#endif  // V8_CHECKS_H_

文件差异内容过多而无法显示
+ 100048 - 0
third-party/double-conversion-1.1.6/test/cctest/gay-fixed.cc


+ 46 - 0
third-party/double-conversion-1.1.6/test/cctest/gay-fixed.h

@@ -0,0 +1,46 @@
+// Copyright 2006-2008 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.
+
+#ifndef GAY_FIXED_H_
+#define GAY_FIXED_H_
+
+namespace double_conversion {
+
+struct PrecomputedFixed {
+  double v;
+  int number_digits;
+  const char* representation;
+  int decimal_point;
+};
+
+// Returns precomputed values of dtoa. The strings have been generated using
+// Gay's dtoa in mode "fixed".
+Vector<const PrecomputedFixed> PrecomputedFixedRepresentations();
+
+}  // namespace double_conversion
+
+#endif  // GAY_FIXED_H_

文件差异内容过多而无法显示
+ 100049 - 0
third-party/double-conversion-1.1.6/test/cctest/gay-precision.cc


+ 46 - 0
third-party/double-conversion-1.1.6/test/cctest/gay-precision.h

@@ -0,0 +1,46 @@
+// Copyright 2006-2008 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.
+
+#ifndef GAY_PRECISION_H_
+#define GAY_PRECISION_H_
+
+namespace double_conversion {
+
+struct PrecomputedPrecision {
+  double v;
+  int number_digits;
+  const char* representation;
+  int decimal_point;
+};
+
+// Returns precomputed values of dtoa. The strings have been generated using
+// Gay's dtoa in mode "precision".
+Vector<const PrecomputedPrecision> PrecomputedPrecisionRepresentations();
+
+}  // namespace double_conversion
+
+#endif  // GAY_PRECISION_H_

文件差异内容过多而无法显示
+ 10049 - 0
third-party/double-conversion-1.1.6/test/cctest/gay-shortest-single.cc


+ 44 - 0
third-party/double-conversion-1.1.6/test/cctest/gay-shortest-single.h

@@ -0,0 +1,44 @@
+// Copyright 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.
+
+#ifndef GAY_SHORTEST_SINGLE_H_
+#define GAY_SHORTEST_SINGLE_H_
+
+namespace double_conversion {
+
+struct PrecomputedShortestSingle {
+  float v;
+  const char* representation;
+  int decimal_point;
+};
+
+Vector<const PrecomputedShortestSingle>
+    PrecomputedShortestSingleRepresentations();
+
+}  // namespace double_conversion
+
+#endif  // GAY_SHORTEST_SINGLE_H_

文件差异内容过多而无法显示
+ 100049 - 0
third-party/double-conversion-1.1.6/test/cctest/gay-shortest.cc


+ 43 - 0
third-party/double-conversion-1.1.6/test/cctest/gay-shortest.h

@@ -0,0 +1,43 @@
+// Copyright 2006-2008 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.
+
+#ifndef GAY_SHORTEST_H_
+#define GAY_SHORTEST_H_
+
+namespace double_conversion {
+
+struct PrecomputedShortest {
+  double v;
+  const char* representation;
+  int decimal_point;
+};
+
+Vector<const PrecomputedShortest> PrecomputedShortestRepresentations();
+
+}  // namespace double_conversion
+
+#endif  // GAY_SHORTEST_H_

+ 395 - 0
third-party/double-conversion-1.1.6/test/cctest/test-bignum-dtoa.cc

@@ -0,0 +1,395 @@
+// Copyright 2012 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 <stdlib.h>
+
+#include "bignum-dtoa.h"
+
+#include "cctest.h"
+#include "gay-fixed.h"
+#include "gay-precision.h"
+#include "gay-shortest.h"
+#include "gay-shortest-single.h"
+#include "ieee.h"
+#include "utils.h"
+
+using namespace double_conversion;
+
+
+// Removes trailing '0' digits.
+// Can return the empty string if all digits are 0.
+static void TrimRepresentation(Vector<char> representation) {
+  int len = strlen(representation.start());
+  int i;
+  for (i = len - 1; i >= 0; --i) {
+    if (representation[i] != '0') break;
+  }
+  representation[i + 1] = '\0';
+}
+
+
+static const int kBufferSize = 100;
+
+
+TEST(BignumDtoaVariousDoubles) {
+  char buffer_container[kBufferSize];
+  Vector<char> buffer(buffer_container, kBufferSize);
+  int length;
+  int point;
+
+  BignumDtoa(1.0, BIGNUM_DTOA_SHORTEST, 0, buffer, &length, &point);
+  CHECK_EQ("1", buffer.start());
+  CHECK_EQ(1, point);
+
+  BignumDtoa(1.0, BIGNUM_DTOA_FIXED, 3, buffer, &length, &point);
+  CHECK_GE(3, length - point);
+  TrimRepresentation(buffer);
+  CHECK_EQ("1", buffer.start());
+  CHECK_EQ(1, point);
+
+  BignumDtoa(1.0, BIGNUM_DTOA_PRECISION, 3, buffer, &length, &point);
+  CHECK_GE(3, length);
+  TrimRepresentation(buffer);
+  CHECK_EQ("1", buffer.start());
+  CHECK_EQ(1, point);
+
+  BignumDtoa(1.5, BIGNUM_DTOA_SHORTEST, 0, buffer, &length, &point);
+  CHECK_EQ("15", buffer.start());
+  CHECK_EQ(1, point);
+
+  BignumDtoa(1.5, BIGNUM_DTOA_FIXED, 10, buffer, &length, &point);
+  CHECK_GE(10, length - point);
+  TrimRepresentation(buffer);
+  CHECK_EQ("15", buffer.start());
+  CHECK_EQ(1, point);
+
+  BignumDtoa(1.5, BIGNUM_DTOA_PRECISION, 10, buffer, &length, &point);
+  CHECK_GE(10, length);
+  TrimRepresentation(buffer);
+  CHECK_EQ("15", buffer.start());
+  CHECK_EQ(1, point);
+
+  double min_double = 5e-324;
+  BignumDtoa(min_double, BIGNUM_DTOA_SHORTEST, 0, buffer, &length, &point);
+  CHECK_EQ("5", buffer.start());
+  CHECK_EQ(-323, point);
+
+  BignumDtoa(min_double, BIGNUM_DTOA_FIXED, 5, buffer, &length, &point);
+  CHECK_GE(5, length - point);
+  TrimRepresentation(buffer);
+  CHECK_EQ("", buffer.start());
+
+  BignumDtoa(min_double, BIGNUM_DTOA_PRECISION, 5, buffer, &length, &point);
+  CHECK_GE(5, length);
+  TrimRepresentation(buffer);
+  CHECK_EQ("49407", buffer.start());
+  CHECK_EQ(-323, point);
+
+  double max_double = 1.7976931348623157e308;
+  BignumDtoa(max_double, BIGNUM_DTOA_SHORTEST, 0, buffer, &length, &point);
+  CHECK_EQ("17976931348623157", buffer.start());
+  CHECK_EQ(309, point);
+
+  BignumDtoa(max_double, BIGNUM_DTOA_PRECISION, 7, buffer, &length, &point);
+  CHECK_GE(7, length);
+  TrimRepresentation(buffer);
+  CHECK_EQ("1797693", buffer.start());
+  CHECK_EQ(309, point);
+
+  BignumDtoa(4294967272.0, BIGNUM_DTOA_SHORTEST, 0, buffer, &length, &point);
+  CHECK_EQ("4294967272", buffer.start());
+  CHECK_EQ(10, point);
+
+  BignumDtoa(4294967272.0, BIGNUM_DTOA_FIXED, 5, buffer, &length, &point);
+  CHECK_EQ("429496727200000", buffer.start());
+  CHECK_EQ(10, point);
+
+
+  BignumDtoa(4294967272.0, BIGNUM_DTOA_PRECISION, 14, buffer, &length, &point);
+  CHECK_GE(14, length);
+  TrimRepresentation(buffer);
+  CHECK_EQ("4294967272", buffer.start());
+  CHECK_EQ(10, point);
+
+  BignumDtoa(4.1855804968213567e298, BIGNUM_DTOA_SHORTEST, 0,
+             buffer, &length, &point);
+  CHECK_EQ("4185580496821357", buffer.start());
+  CHECK_EQ(299, point);
+
+  BignumDtoa(4.1855804968213567e298, BIGNUM_DTOA_PRECISION, 20,
+             buffer, &length, &point);
+  CHECK_GE(20, length);
+  TrimRepresentation(buffer);
+  CHECK_EQ("41855804968213567225", buffer.start());
+  CHECK_EQ(299, point);
+
+  BignumDtoa(5.5626846462680035e-309, BIGNUM_DTOA_SHORTEST, 0,
+             buffer, &length, &point);
+  CHECK_EQ("5562684646268003", buffer.start());
+  CHECK_EQ(-308, point);
+
+  BignumDtoa(5.5626846462680035e-309, BIGNUM_DTOA_PRECISION, 1,
+             buffer, &length, &point);
+  CHECK_GE(1, length);
+  TrimRepresentation(buffer);
+  CHECK_EQ("6", buffer.start());
+  CHECK_EQ(-308, point);
+
+  BignumDtoa(2147483648.0, BIGNUM_DTOA_SHORTEST, 0,
+             buffer, &length, &point);
+  CHECK_EQ("2147483648", buffer.start());
+  CHECK_EQ(10, point);
+
+
+  BignumDtoa(2147483648.0, BIGNUM_DTOA_FIXED, 2,
+             buffer, &length, &point);
+  CHECK_GE(2, length - point);
+  TrimRepresentation(buffer);
+  CHECK_EQ("2147483648", buffer.start());
+  CHECK_EQ(10, point);
+
+  BignumDtoa(2147483648.0, BIGNUM_DTOA_PRECISION, 5,
+             buffer, &length, &point);
+  CHECK_GE(5, length);
+  TrimRepresentation(buffer);
+  CHECK_EQ("21475", buffer.start());
+  CHECK_EQ(10, point);
+
+  BignumDtoa(3.5844466002796428e+298, BIGNUM_DTOA_SHORTEST, 0,
+             buffer, &length, &point);
+  CHECK_EQ("35844466002796428", buffer.start());
+  CHECK_EQ(299, point);
+
+  BignumDtoa(3.5844466002796428e+298, BIGNUM_DTOA_PRECISION, 10,
+             buffer, &length, &point);
+  CHECK_GE(10, length);
+  TrimRepresentation(buffer);
+  CHECK_EQ("35844466", buffer.start());
+  CHECK_EQ(299, point);
+
+  uint64_t smallest_normal64 = UINT64_2PART_C(0x00100000, 00000000);
+  double v = Double(smallest_normal64).value();
+  BignumDtoa(v, BIGNUM_DTOA_SHORTEST, 0, buffer, &length, &point);
+  CHECK_EQ("22250738585072014", buffer.start());
+  CHECK_EQ(-307, point);
+
+  BignumDtoa(v, BIGNUM_DTOA_PRECISION, 20, buffer, &length, &point);
+  CHECK_GE(20, length);
+  TrimRepresentation(buffer);
+  CHECK_EQ("22250738585072013831", buffer.start());
+  CHECK_EQ(-307, point);
+
+  uint64_t largest_denormal64 = UINT64_2PART_C(0x000FFFFF, FFFFFFFF);
+  v = Double(largest_denormal64).value();
+  BignumDtoa(v, BIGNUM_DTOA_SHORTEST, 0, buffer, &length, &point);
+  CHECK_EQ("2225073858507201", buffer.start());
+  CHECK_EQ(-307, point);
+
+  BignumDtoa(v, BIGNUM_DTOA_PRECISION, 20, buffer, &length, &point);
+  CHECK_GE(20, length);
+  TrimRepresentation(buffer);
+  CHECK_EQ("2225073858507200889", buffer.start());
+  CHECK_EQ(-307, point);
+
+  BignumDtoa(4128420500802942e-24, BIGNUM_DTOA_SHORTEST, 0,
+             buffer, &length, &point);
+  CHECK_EQ("4128420500802942", buffer.start());
+  CHECK_EQ(-8, point);
+
+  v = 3.9292015898194142585311918e-10;
+  BignumDtoa(v, BIGNUM_DTOA_SHORTEST, 0, buffer, &length, &point);
+  CHECK_EQ("39292015898194143", buffer.start());
+
+  v = 4194304.0;
+  BignumDtoa(v, BIGNUM_DTOA_FIXED, 5, buffer, &length, &point);
+  CHECK_GE(5, length - point);
+  TrimRepresentation(buffer);
+  CHECK_EQ("4194304", buffer.start());
+
+  v = 3.3161339052167390562200598e-237;
+  BignumDtoa(v, BIGNUM_DTOA_PRECISION, 19, buffer, &length, &point);
+  CHECK_GE(19, length);
+  TrimRepresentation(buffer);
+  CHECK_EQ("3316133905216739056", buffer.start());
+  CHECK_EQ(-236, point);
+
+  v = 7.9885183916008099497815232e+191;
+  BignumDtoa(v, BIGNUM_DTOA_PRECISION, 4, buffer, &length, &point);
+  CHECK_GE(4, length);
+  TrimRepresentation(buffer);
+  CHECK_EQ("7989", buffer.start());
+  CHECK_EQ(192, point);
+
+  v = 1.0000000000000012800000000e+17;
+  BignumDtoa(v, BIGNUM_DTOA_FIXED, 1, buffer, &length, &point);
+  CHECK_GE(1, length - point);
+  TrimRepresentation(buffer);
+  CHECK_EQ("100000000000000128", buffer.start());
+  CHECK_EQ(18, point);
+}
+
+
+TEST(BignumDtoaShortestVariousFloats) {
+  char buffer_container[kBufferSize];
+  Vector<char> buffer(buffer_container, kBufferSize);
+  int length;
+  int point;
+
+  float min_float = 1e-45f;
+  BignumDtoa(min_float, BIGNUM_DTOA_SHORTEST_SINGLE, 0,
+             buffer, &length, &point);
+  CHECK_EQ("1", buffer.start());
+  CHECK_EQ(-44, point);
+
+
+  float max_float = 3.4028234e38f;
+  BignumDtoa(max_float, BIGNUM_DTOA_SHORTEST_SINGLE, 0,
+             buffer, &length, &point);
+  CHECK_EQ("34028235", buffer.start());
+  CHECK_EQ(39, point);
+
+  BignumDtoa(4294967272.0f, BIGNUM_DTOA_SHORTEST_SINGLE, 0,
+             buffer, &length, &point);
+  CHECK_EQ("42949673", buffer.start());
+  CHECK_EQ(10, point);
+
+  BignumDtoa(3.32306998946228968226e+35f, BIGNUM_DTOA_SHORTEST_SINGLE, 0,
+             buffer, &length, &point);
+  CHECK_EQ("332307", buffer.start());
+  CHECK_EQ(36, point);
+
+  BignumDtoa(1.2341e-41f, BIGNUM_DTOA_SHORTEST_SINGLE, 0,
+             buffer, &length, &point);
+  CHECK_EQ("12341", buffer.start());
+  CHECK_EQ(-40, point);
+
+  BignumDtoa(3.3554432e7, BIGNUM_DTOA_SHORTEST_SINGLE, 0,
+             buffer, &length, &point);
+  CHECK_EQ("33554432", buffer.start());
+  CHECK_EQ(8, point);
+
+  BignumDtoa(3.26494756798464e14f, BIGNUM_DTOA_SHORTEST_SINGLE, 0,
+             buffer, &length, &point);
+  CHECK_EQ("32649476", buffer.start());
+  CHECK_EQ(15, point);
+
+  BignumDtoa(3.91132223637771935344e37f, BIGNUM_DTOA_SHORTEST_SINGLE, 0,
+             buffer, &length, &point);
+  CHECK_EQ("39113222", buffer.start());
+  CHECK_EQ(38, point);
+
+  uint32_t smallest_normal32 = 0x00800000;
+  double v = Single(smallest_normal32).value();
+  BignumDtoa(v, BIGNUM_DTOA_SHORTEST_SINGLE, 0, buffer, &length, &point);
+  CHECK_EQ("11754944", buffer.start());
+  CHECK_EQ(-37, point);
+
+  uint32_t largest_denormal32 = 0x007FFFFF;
+  v = Single(largest_denormal32).value();
+  BignumDtoa(v, BIGNUM_DTOA_SHORTEST_SINGLE, 0, buffer, &length, &point);
+  CHECK_EQ("11754942", buffer.start());
+  CHECK_EQ(-37, point);
+}
+
+
+TEST(BignumDtoaGayShortest) {
+  char buffer_container[kBufferSize];
+  Vector<char> buffer(buffer_container, kBufferSize);
+  int length;
+  int point;
+
+  Vector<const PrecomputedShortest> precomputed =
+      PrecomputedShortestRepresentations();
+  for (int i = 0; i < precomputed.length(); ++i) {
+    const PrecomputedShortest current_test = precomputed[i];
+    double v = current_test.v;
+    BignumDtoa(v, BIGNUM_DTOA_SHORTEST, 0, buffer, &length, &point);
+    CHECK_EQ(current_test.decimal_point, point);
+    CHECK_EQ(current_test.representation, buffer.start());
+  }
+}
+
+
+TEST(BignumDtoaGayShortestSingle) {
+  char buffer_container[kBufferSize];
+  Vector<char> buffer(buffer_container, kBufferSize);
+  int length;
+  int point;
+
+  Vector<const PrecomputedShortestSingle> precomputed =
+      PrecomputedShortestSingleRepresentations();
+  for (int i = 0; i < precomputed.length(); ++i) {
+    const PrecomputedShortestSingle current_test = precomputed[i];
+    float v = current_test.v;
+    BignumDtoa(v, BIGNUM_DTOA_SHORTEST_SINGLE, 0, buffer, &length, &point);
+    CHECK_EQ(current_test.decimal_point, point);
+    CHECK_EQ(current_test.representation, buffer.start());
+  }
+}
+
+
+TEST(BignumDtoaGayFixed) {
+  char buffer_container[kBufferSize];
+  Vector<char> buffer(buffer_container, kBufferSize);
+  int length;
+  int point;
+
+  Vector<const PrecomputedFixed> precomputed =
+      PrecomputedFixedRepresentations();
+  for (int i = 0; i < precomputed.length(); ++i) {
+    const PrecomputedFixed current_test = precomputed[i];
+    double v = current_test.v;
+    int number_digits = current_test.number_digits;
+    BignumDtoa(v, BIGNUM_DTOA_FIXED, number_digits, buffer, &length, &point);
+    CHECK_EQ(current_test.decimal_point, point);
+    CHECK_GE(number_digits, length - point);
+    TrimRepresentation(buffer);
+    CHECK_EQ(current_test.representation, buffer.start());
+  }
+}
+
+
+TEST(BignumDtoaGayPrecision) {
+  char buffer_container[kBufferSize];
+  Vector<char> buffer(buffer_container, kBufferSize);
+  int length;
+  int point;
+
+  Vector<const PrecomputedPrecision> precomputed =
+      PrecomputedPrecisionRepresentations();
+  for (int i = 0; i < precomputed.length(); ++i) {
+    const PrecomputedPrecision current_test = precomputed[i];
+    double v = current_test.v;
+    int number_digits = current_test.number_digits;
+    BignumDtoa(v, BIGNUM_DTOA_PRECISION, number_digits,
+               buffer, &length, &point);
+    CHECK_EQ(current_test.decimal_point, point);
+    CHECK_GE(number_digits, length);
+    TrimRepresentation(buffer);
+    CHECK_EQ(current_test.representation, buffer.start());
+  }
+}

文件差异内容过多而无法显示
+ 1502 - 0
third-party/double-conversion-1.1.6/test/cctest/test-bignum.cc


文件差异内容过多而无法显示
+ 4571 - 0
third-party/double-conversion-1.1.6/test/cctest/test-conversions.cc


+ 65 - 0
third-party/double-conversion-1.1.6/test/cctest/test-diy-fp.cc

@@ -0,0 +1,65 @@
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
+
+#include <stdlib.h>
+
+#include "cctest.h"
+#include "diy-fp.h"
+#include "utils.h"
+
+
+using namespace double_conversion;
+
+
+TEST(Subtract) {
+  DiyFp diy_fp1 = DiyFp(3, 0);
+  DiyFp diy_fp2 = DiyFp(1, 0);
+  DiyFp diff = DiyFp::Minus(diy_fp1, diy_fp2);
+
+  CHECK(2 == diff.f());  // NOLINT
+  CHECK_EQ(0, diff.e());
+  diy_fp1.Subtract(diy_fp2);
+  CHECK(2 == diy_fp1.f());  // NOLINT
+  CHECK_EQ(0, diy_fp1.e());
+}
+
+
+TEST(Multiply) {
+  DiyFp diy_fp1 = DiyFp(3, 0);
+  DiyFp diy_fp2 = DiyFp(2, 0);
+  DiyFp product = DiyFp::Times(diy_fp1, diy_fp2);
+
+  CHECK(0 == product.f());  // NOLINT
+  CHECK_EQ(64, product.e());
+  diy_fp1.Multiply(diy_fp2);
+  CHECK(0 == diy_fp1.f());  // NOLINT
+  CHECK_EQ(64, diy_fp1.e());
+
+  diy_fp1 = DiyFp(UINT64_2PART_C(0x80000000, 00000000), 11);
+  diy_fp2 = DiyFp(2, 13);
+  product = DiyFp::Times(diy_fp1, diy_fp2);
+  CHECK(1 == product.f());  // NOLINT
+  CHECK_EQ(11 + 13 + 64, product.e());
+
+  // Test rounding.
+  diy_fp1 = DiyFp(UINT64_2PART_C(0x80000000, 00000001), 11);
+  diy_fp2 = DiyFp(1, 13);
+  product = DiyFp::Times(diy_fp1, diy_fp2);
+  CHECK(1 == product.f());  // NOLINT
+  CHECK_EQ(11 + 13 + 64, product.e());
+
+  diy_fp1 = DiyFp(UINT64_2PART_C(0x7fffffff, ffffffff), 11);
+  diy_fp2 = DiyFp(1, 13);
+  product = DiyFp::Times(diy_fp1, diy_fp2);
+  CHECK(0 == product.f());  // NOLINT
+  CHECK_EQ(11 + 13 + 64, product.e());
+
+  // Halfway cases are allowed to round either way. So don't check for it.
+
+  // Big numbers.
+  diy_fp1 = DiyFp(UINT64_2PART_C(0xFFFFFFFF, FFFFFFFF), 11);
+  diy_fp2 = DiyFp(UINT64_2PART_C(0xFFFFFFFF, FFFFFFFF), 13);
+  // 128bit result: 0xfffffffffffffffe0000000000000001
+  product = DiyFp::Times(diy_fp1, diy_fp2);
+  CHECK(UINT64_2PART_C(0xFFFFFFFF, FFFFFFFe) == product.f());
+  CHECK_EQ(11 + 13 + 64, product.e());
+}

+ 507 - 0
third-party/double-conversion-1.1.6/test/cctest/test-dtoa.cc

@@ -0,0 +1,507 @@
+// 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 <stdlib.h>
+
+#include "double-conversion.h"
+
+#include "cctest.h"
+#include "gay-fixed.h"
+#include "gay-precision.h"
+#include "gay-shortest.h"
+#include "gay-shortest-single.h"
+#include "ieee.h"
+
+
+using namespace double_conversion;
+
+
+enum DtoaMode {
+  SHORTEST,
+  SHORTEST_SINGLE,
+  FIXED,
+  PRECISION
+};
+
+static void DoubleToAscii(double v, DtoaMode test_mode, int requested_digits,
+                          Vector<char> buffer, bool* sign, int* length,
+                          int* point) {
+  DoubleToStringConverter::DtoaMode mode = DoubleToStringConverter::SHORTEST;
+  switch (test_mode) {
+    case SHORTEST: mode = DoubleToStringConverter::SHORTEST; break;
+    case SHORTEST_SINGLE:
+        mode = DoubleToStringConverter::SHORTEST_SINGLE;
+        break;
+    case FIXED: mode = DoubleToStringConverter::FIXED; break;
+    case PRECISION: mode = DoubleToStringConverter::PRECISION; break;
+  }
+  DoubleToStringConverter::DoubleToAscii(v, mode, requested_digits,
+                                 buffer.start(), buffer.length(),
+                                 sign, length, point);
+}
+
+// Removes trailing '0' digits.
+static void TrimRepresentation(Vector<char> representation) {
+  int len = strlen(representation.start());
+  int i;
+  for (i = len - 1; i >= 0; --i) {
+    if (representation[i] != '0') break;
+  }
+  representation[i + 1] = '\0';
+}
+
+
+static const int kBufferSize = 100;
+
+
+TEST(DtoaVariousDoubles) {
+  char buffer_container[kBufferSize];
+  Vector<char> buffer(buffer_container, kBufferSize);
+  int length;
+  int point;
+  bool sign;
+
+  DoubleToAscii(0.0, SHORTEST, 0, buffer, &sign, &length, &point);
+  CHECK_EQ("0", buffer.start());
+  CHECK_EQ(1, point);
+
+  DoubleToAscii(0.0f, SHORTEST_SINGLE, 0, buffer, &sign, &length, &point);
+  CHECK_EQ("0", buffer.start());
+  CHECK_EQ(1, point);
+
+  DoubleToAscii(0.0, FIXED, 2, buffer, &sign, &length, &point);
+  CHECK_EQ(1, length);
+  CHECK_EQ("0", buffer.start());
+  CHECK_EQ(1, point);
+
+  DoubleToAscii(0.0, PRECISION, 3, buffer, &sign, &length, &point);
+  CHECK_EQ(1, length);
+  CHECK_EQ("0", buffer.start());
+  CHECK_EQ(1, point);
+
+  DoubleToAscii(1.0, SHORTEST, 0, buffer, &sign, &length, &point);
+  CHECK_EQ("1", buffer.start());
+  CHECK_EQ(1, point);
+
+  DoubleToAscii(1.0f, SHORTEST_SINGLE, 0, buffer, &sign, &length, &point);
+  CHECK_EQ("1", buffer.start());
+  CHECK_EQ(1, point);
+
+  DoubleToAscii(1.0, FIXED, 3, buffer, &sign, &length, &point);
+  CHECK_GE(3, length - point);
+  TrimRepresentation(buffer);
+  CHECK_EQ("1", buffer.start());
+  CHECK_EQ(1, point);
+
+  DoubleToAscii(1.0, PRECISION, 3, buffer, &sign, &length, &point);
+  CHECK_GE(3, length);
+  TrimRepresentation(buffer);
+  CHECK_EQ("1", buffer.start());
+  CHECK_EQ(1, point);
+
+  DoubleToAscii(1.5, SHORTEST, 0, buffer, &sign, &length, &point);
+  CHECK_EQ("15", buffer.start());
+  CHECK_EQ(1, point);
+
+  DoubleToAscii(1.5f, SHORTEST_SINGLE, 0, buffer, &sign, &length, &point);
+  CHECK_EQ("15", buffer.start());
+  CHECK_EQ(1, point);
+
+  DoubleToAscii(1.5, FIXED, 10, buffer, &sign, &length, &point);
+  CHECK_GE(10, length - point);
+  TrimRepresentation(buffer);
+  CHECK_EQ("15", buffer.start());
+  CHECK_EQ(1, point);
+
+  DoubleToAscii(1.5, PRECISION, 10, buffer, &sign, &length, &point);
+  CHECK_GE(10, length);
+  TrimRepresentation(buffer);
+  CHECK_EQ("15", buffer.start());
+  CHECK_EQ(1, point);
+
+  double min_double = 5e-324;
+  DoubleToAscii(min_double, SHORTEST, 0, buffer, &sign, &length, &point);
+  CHECK_EQ("5", buffer.start());
+  CHECK_EQ(-323, point);
+
+  float min_float = 1e-45f;
+  DoubleToAscii(min_float, SHORTEST_SINGLE, 0, buffer, &sign, &length, &point);
+  CHECK_EQ("1", buffer.start());
+  CHECK_EQ(-44, point);
+
+  DoubleToAscii(min_double, FIXED, 5, buffer, &sign, &length, &point);
+  CHECK_GE(5, length - point);
+  TrimRepresentation(buffer);
+  CHECK_EQ("", buffer.start());
+  CHECK_GE(-5, point);
+
+  DoubleToAscii(min_double, PRECISION, 5, buffer, &sign, &length, &point);
+  CHECK_GE(5, length);
+  TrimRepresentation(buffer);
+  CHECK_EQ("49407", buffer.start());
+  CHECK_EQ(-323, point);
+
+  double max_double = 1.7976931348623157e308;
+  DoubleToAscii(max_double, SHORTEST, 0, buffer, &sign, &length, &point);
+  CHECK_EQ("17976931348623157", buffer.start());
+  CHECK_EQ(309, point);
+
+  float max_float = 3.4028234e38f;
+  DoubleToAscii(max_float, SHORTEST_SINGLE, 0,
+                buffer, &sign, &length, &point);
+  CHECK_EQ("34028235", buffer.start());
+  CHECK_EQ(39, point);
+
+  DoubleToAscii(max_double, PRECISION, 7, buffer, &sign, &length, &point);
+  CHECK_GE(7, length);
+  TrimRepresentation(buffer);
+  CHECK_EQ("1797693", buffer.start());
+  CHECK_EQ(309, point);
+
+  DoubleToAscii(4294967272.0, SHORTEST, 0, buffer, &sign, &length, &point);
+  CHECK_EQ("4294967272", buffer.start());
+  CHECK_EQ(10, point);
+
+  DoubleToAscii(4294967272.0f, SHORTEST_SINGLE, 0, buffer, &sign, &length, &point);
+  CHECK_EQ("42949673", buffer.start());
+  CHECK_EQ(10, point);
+
+  DoubleToAscii(4294967272.0, FIXED, 5, buffer, &sign, &length, &point);
+  CHECK_GE(5, length - point);
+  TrimRepresentation(buffer);
+  CHECK_EQ("4294967272", buffer.start());
+  CHECK_EQ(10, point);
+
+  DoubleToAscii(4294967272.0, PRECISION, 14,
+                buffer, &sign, &length, &point);
+  CHECK_GE(14, length);
+  TrimRepresentation(buffer);
+  CHECK_EQ("4294967272", buffer.start());
+  CHECK_EQ(10, point);
+
+  DoubleToAscii(4.1855804968213567e298, SHORTEST, 0,
+                buffer, &sign, &length, &point);
+  CHECK_EQ("4185580496821357", buffer.start());
+  CHECK_EQ(299, point);
+
+  DoubleToAscii(4.1855804968213567e298, PRECISION, 20,
+                buffer, &sign, &length, &point);
+  CHECK_GE(20, length);
+  TrimRepresentation(buffer);
+  CHECK_EQ("41855804968213567225", buffer.start());
+  CHECK_EQ(299, point);
+
+  DoubleToAscii(5.5626846462680035e-309, SHORTEST, 0,
+                buffer, &sign, &length, &point);
+  CHECK_EQ("5562684646268003", buffer.start());
+  CHECK_EQ(-308, point);
+
+  DoubleToAscii(5.5626846462680035e-309, PRECISION, 1,
+                buffer, &sign, &length, &point);
+  CHECK_GE(1, length);
+  TrimRepresentation(buffer);
+  CHECK_EQ("6", buffer.start());
+  CHECK_EQ(-308, point);
+
+  DoubleToAscii(-2147483648.0, SHORTEST, 0,
+                buffer, &sign, &length, &point);
+  CHECK_EQ(1, sign);
+  CHECK_EQ("2147483648", buffer.start());
+  CHECK_EQ(10, point);
+
+  DoubleToAscii(-2147483648.0, SHORTEST_SINGLE, 0,
+                buffer, &sign, &length, &point);
+  CHECK_EQ(1, sign);
+  CHECK_EQ("21474836", buffer.start());
+  CHECK_EQ(10, point);
+
+
+  DoubleToAscii(-2147483648.0, FIXED, 2, buffer, &sign, &length, &point);
+  CHECK_GE(2, length - point);
+  TrimRepresentation(buffer);
+  CHECK_EQ(1, sign);
+  CHECK_EQ("2147483648", buffer.start());
+  CHECK_EQ(10, point);
+
+  DoubleToAscii(-2147483648.0, PRECISION, 5,
+                buffer, &sign, &length, &point);
+  CHECK_GE(5, length);
+  TrimRepresentation(buffer);
+  CHECK_EQ(1, sign);
+  CHECK_EQ("21475", buffer.start());
+  CHECK_EQ(10, point);
+
+  DoubleToAscii(-3.5844466002796428e+298, SHORTEST, 0,
+                buffer, &sign, &length, &point);
+  CHECK_EQ(1, sign);
+  CHECK_EQ("35844466002796428", buffer.start());
+  CHECK_EQ(299, point);
+
+  DoubleToAscii(-3.5844466002796428e+298, PRECISION, 10,
+                buffer, &sign, &length, &point);
+  CHECK_EQ(1, sign);
+  CHECK_GE(10, length);
+  TrimRepresentation(buffer);
+  CHECK_EQ("35844466", buffer.start());
+  CHECK_EQ(299, point);
+
+  uint64_t smallest_normal64 = UINT64_2PART_C(0x00100000, 00000000);
+  double v = Double(smallest_normal64).value();
+  DoubleToAscii(v, SHORTEST, 0, buffer, &sign, &length, &point);
+  CHECK_EQ("22250738585072014", buffer.start());
+  CHECK_EQ(-307, point);
+
+  uint32_t smallest_normal32 = 0x00800000;
+  float f = Single(smallest_normal32).value();
+  DoubleToAscii(f, SHORTEST_SINGLE, 0, buffer, &sign, &length, &point);
+  CHECK_EQ("11754944", buffer.start());
+  CHECK_EQ(-37, point);
+
+  DoubleToAscii(v, PRECISION, 20, buffer, &sign, &length, &point);
+  CHECK_GE(20, length);
+  TrimRepresentation(buffer);
+  CHECK_EQ("22250738585072013831", buffer.start());
+  CHECK_EQ(-307, point);
+
+  uint64_t largest_denormal64 = UINT64_2PART_C(0x000FFFFF, FFFFFFFF);
+  v = Double(largest_denormal64).value();
+  DoubleToAscii(v, SHORTEST, 0, buffer, &sign, &length, &point);
+  CHECK_EQ("2225073858507201", buffer.start());
+  CHECK_EQ(-307, point);
+
+  uint32_t largest_denormal32 = 0x007FFFFF;
+  f = Single(largest_denormal32).value();
+  DoubleToAscii(f, SHORTEST_SINGLE, 0, buffer, &sign, &length, &point);
+  CHECK_EQ("11754942", buffer.start());
+  CHECK_EQ(-37, point);
+
+  DoubleToAscii(v, PRECISION, 20, buffer, &sign, &length, &point);
+  CHECK_GE(20, length);
+  TrimRepresentation(buffer);
+  CHECK_EQ("2225073858507200889", buffer.start());
+  CHECK_EQ(-307, point);
+
+  DoubleToAscii(4128420500802942e-24, SHORTEST, 0,
+                buffer, &sign, &length, &point);
+  CHECK_EQ(0, sign);
+  CHECK_EQ("4128420500802942", buffer.start());
+  CHECK_EQ(-8, point);
+
+  v = -3.9292015898194142585311918e-10;
+  DoubleToAscii(v, SHORTEST, 0, buffer, &sign, &length, &point);
+  CHECK_EQ("39292015898194143", buffer.start());
+
+  f = -3.9292015898194142585311918e-10f;
+  DoubleToAscii(f, SHORTEST_SINGLE, 0, buffer, &sign, &length, &point);
+  CHECK_EQ("39292017", buffer.start());
+
+  v = 4194304.0;
+  DoubleToAscii(v, FIXED, 5, buffer, &sign, &length, &point);
+  CHECK_GE(5, length - point);
+  TrimRepresentation(buffer);
+  CHECK_EQ("4194304", buffer.start());
+
+  v = 3.3161339052167390562200598e-237;
+  DoubleToAscii(v, PRECISION, 19, buffer, &sign, &length, &point);
+  CHECK_GE(19, length);
+  TrimRepresentation(buffer);
+  CHECK_EQ("3316133905216739056", buffer.start());
+  CHECK_EQ(-236, point);
+}
+
+
+TEST(DtoaSign) {
+  char buffer_container[kBufferSize];
+  Vector<char> buffer(buffer_container, kBufferSize);
+  bool sign;
+  int length;
+  int point;
+
+  DoubleToAscii(0.0, SHORTEST, 0, buffer, &sign, &length, &point);
+  CHECK(!sign);
+
+  DoubleToAscii(-0.0, SHORTEST, 0, buffer, &sign, &length, &point);
+  CHECK(sign);
+
+  DoubleToAscii(1.0, SHORTEST, 0, buffer, &sign, &length, &point);
+  CHECK(!sign);
+
+  DoubleToAscii(-1.0, SHORTEST, 0, buffer, &sign, &length, &point);
+  CHECK(sign);
+
+  DoubleToAscii(0.0f, SHORTEST_SINGLE, 0, buffer, &sign, &length, &point);
+  CHECK(!sign);
+
+  DoubleToAscii(-0.0f, SHORTEST_SINGLE, 0, buffer, &sign, &length, &point);
+  CHECK(sign);
+
+  DoubleToAscii(1.0f, SHORTEST_SINGLE, 0, buffer, &sign, &length, &point);
+  CHECK(!sign);
+
+  DoubleToAscii(-1.0f, SHORTEST_SINGLE, 0, buffer, &sign, &length, &point);
+  CHECK(sign);
+
+  DoubleToAscii(0.0, PRECISION, 1, buffer, &sign, &length, &point);
+  CHECK(!sign);
+
+  DoubleToAscii(-0.0, PRECISION, 1, buffer, &sign, &length, &point);
+  CHECK(sign);
+
+  DoubleToAscii(1.0, PRECISION, 1, buffer, &sign, &length, &point);
+  CHECK(!sign);
+
+  DoubleToAscii(-1.0, PRECISION, 1, buffer, &sign, &length, &point);
+  CHECK(sign);
+
+  DoubleToAscii(0.0, FIXED, 1, buffer, &sign, &length, &point);
+  CHECK(!sign);
+
+  DoubleToAscii(-0.0, FIXED, 1, buffer, &sign, &length, &point);
+  CHECK(sign);
+
+  DoubleToAscii(1.0, FIXED, 1, buffer, &sign, &length, &point);
+  CHECK(!sign);
+
+  DoubleToAscii(-1.0, FIXED, 1, buffer, &sign, &length, &point);
+  CHECK(sign);
+}
+
+
+TEST(DtoaCorners) {
+  char buffer_container[kBufferSize];
+  Vector<char> buffer(buffer_container, kBufferSize);
+  bool sign;
+  int length;
+  int point;
+
+  DoubleToAscii(0.0, PRECISION, 0, buffer, &sign, &length, &point);
+  CHECK_EQ(0, length);
+  CHECK_EQ("", buffer.start());
+  CHECK(!sign);
+
+  DoubleToAscii(1.0, PRECISION, 0, buffer, &sign, &length, &point);
+  CHECK_EQ(0, length);
+  CHECK_EQ("", buffer.start());
+  CHECK(!sign);
+
+  DoubleToAscii(0.0, FIXED, 0, buffer, &sign, &length, &point);
+  CHECK_EQ(1, length);
+  CHECK_EQ("0", buffer.start());
+  CHECK(!sign);
+
+  DoubleToAscii(1.0, FIXED, 0, buffer, &sign, &length, &point);
+  CHECK_EQ(1, length);
+  CHECK_EQ("1", buffer.start());
+  CHECK(!sign);
+}
+
+
+TEST(DtoaGayShortest) {
+  char buffer_container[kBufferSize];
+  Vector<char> buffer(buffer_container, kBufferSize);
+  bool sign;
+  int length;
+  int point;
+
+  Vector<const PrecomputedShortest> precomputed =
+      PrecomputedShortestRepresentations();
+  for (int i = 0; i < precomputed.length(); ++i) {
+    const PrecomputedShortest current_test = precomputed[i];
+    double v = current_test.v;
+    DoubleToAscii(v, SHORTEST, 0, buffer, &sign, &length, &point);
+    CHECK(!sign);  // All precomputed numbers are positive.
+    CHECK_EQ(current_test.decimal_point, point);
+    CHECK_EQ(current_test.representation, buffer.start());
+  }
+}
+
+
+TEST(DtoaGayShortestSingle) {
+  char buffer_container[kBufferSize];
+  Vector<char> buffer(buffer_container, kBufferSize);
+  bool sign;
+  int length;
+  int point;
+
+  Vector<const PrecomputedShortestSingle> precomputed =
+      PrecomputedShortestSingleRepresentations();
+  for (int i = 0; i < precomputed.length(); ++i) {
+    const PrecomputedShortestSingle current_test = precomputed[i];
+    float v = current_test.v;
+    DoubleToAscii(v, SHORTEST_SINGLE, 0, buffer, &sign, &length, &point);
+    CHECK(!sign);  // All precomputed numbers are positive.
+    CHECK_EQ(current_test.decimal_point, point);
+    CHECK_EQ(current_test.representation, buffer.start());
+  }
+}
+
+
+TEST(DtoaGayFixed) {
+  char buffer_container[kBufferSize];
+  Vector<char> buffer(buffer_container, kBufferSize);
+  bool sign;
+  int length;
+  int point;
+
+  Vector<const PrecomputedFixed> precomputed =
+      PrecomputedFixedRepresentations();
+  for (int i = 0; i < precomputed.length(); ++i) {
+    const PrecomputedFixed current_test = precomputed[i];
+    double v = current_test.v;
+    int number_digits = current_test.number_digits;
+    DoubleToAscii(v, FIXED, number_digits, buffer, &sign, &length, &point);
+    CHECK(!sign);  // All precomputed numbers are positive.
+    CHECK_EQ(current_test.decimal_point, point);
+    CHECK_GE(number_digits, length - point);
+    TrimRepresentation(buffer);
+    CHECK_EQ(current_test.representation, buffer.start());
+  }
+}
+
+
+TEST(DtoaGayPrecision) {
+  char buffer_container[kBufferSize];
+  Vector<char> buffer(buffer_container, kBufferSize);
+  bool sign;
+  int length;
+  int point;
+
+  Vector<const PrecomputedPrecision> precomputed =
+      PrecomputedPrecisionRepresentations();
+  for (int i = 0; i < precomputed.length(); ++i) {
+    const PrecomputedPrecision current_test = precomputed[i];
+    double v = current_test.v;
+    int number_digits = current_test.number_digits;
+    DoubleToAscii(v, PRECISION, number_digits,
+                  buffer, &sign, &length, &point);
+    CHECK(!sign);  // All precomputed numbers are positive.
+    CHECK_EQ(current_test.decimal_point, point);
+    CHECK_GE(number_digits, length);
+    TrimRepresentation(buffer);
+    CHECK_EQ(current_test.representation, buffer.start());
+  }
+}

+ 372 - 0
third-party/double-conversion-1.1.6/test/cctest/test-fast-dtoa.cc

@@ -0,0 +1,372 @@
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
+
+#include <stdlib.h>
+
+#include "cctest.h"
+#include "diy-fp.h"
+#include "fast-dtoa.h"
+#include "gay-precision.h"
+#include "gay-shortest.h"
+#include "gay-shortest-single.h"
+#include "ieee.h"
+#include "utils.h"
+
+using namespace double_conversion;
+
+static const int kBufferSize = 100;
+
+
+// Removes trailing '0' digits.
+static void TrimRepresentation(Vector<char> representation) {
+  int len = strlen(representation.start());
+  int i;
+  for (i = len - 1; i >= 0; --i) {
+    if (representation[i] != '0') break;
+  }
+  representation[i + 1] = '\0';
+}
+
+
+TEST(FastDtoaShortestVariousDoubles) {
+  char buffer_container[kBufferSize];
+  Vector<char> buffer(buffer_container, kBufferSize);
+  int length;
+  int point;
+  bool status;
+
+  double min_double = 5e-324;
+  status = FastDtoa(min_double, FAST_DTOA_SHORTEST, 0,
+                    buffer, &length, &point);
+  CHECK(status);
+  CHECK_EQ("5", buffer.start());
+  CHECK_EQ(-323, point);
+
+  double max_double = 1.7976931348623157e308;
+  status = FastDtoa(max_double, FAST_DTOA_SHORTEST, 0,
+                    buffer, &length, &point);
+  CHECK(status);
+  CHECK_EQ("17976931348623157", buffer.start());
+  CHECK_EQ(309, point);
+
+  status = FastDtoa(4294967272.0, FAST_DTOA_SHORTEST, 0,
+                    buffer, &length, &point);
+  CHECK(status);
+  CHECK_EQ("4294967272", buffer.start());
+  CHECK_EQ(10, point);
+
+  status = FastDtoa(4.1855804968213567e298, FAST_DTOA_SHORTEST, 0,
+                    buffer, &length, &point);
+  CHECK(status);
+  CHECK_EQ("4185580496821357", buffer.start());
+  CHECK_EQ(299, point);
+
+  status = FastDtoa(5.5626846462680035e-309, FAST_DTOA_SHORTEST, 0,
+                    buffer, &length, &point);
+  CHECK(status);
+  CHECK_EQ("5562684646268003", buffer.start());
+  CHECK_EQ(-308, point);
+
+  status = FastDtoa(2147483648.0, FAST_DTOA_SHORTEST, 0,
+                    buffer, &length, &point);
+  CHECK(status);
+  CHECK_EQ("2147483648", buffer.start());
+  CHECK_EQ(10, point);
+
+  status = FastDtoa(3.5844466002796428e+298, FAST_DTOA_SHORTEST, 0,
+                    buffer, &length, &point);
+  if (status) {  // Not all FastDtoa variants manage to compute this number.
+    CHECK_EQ("35844466002796428", buffer.start());
+    CHECK_EQ(299, point);
+  }
+
+  uint64_t smallest_normal64 = UINT64_2PART_C(0x00100000, 00000000);
+  double v = Double(smallest_normal64).value();
+  status = FastDtoa(v, FAST_DTOA_SHORTEST, 0, buffer, &length, &point);
+  if (status) {
+    CHECK_EQ("22250738585072014", buffer.start());
+    CHECK_EQ(-307, point);
+  }
+
+  uint64_t largest_denormal64 = UINT64_2PART_C(0x000FFFFF, FFFFFFFF);
+  v = Double(largest_denormal64).value();
+  status = FastDtoa(v, FAST_DTOA_SHORTEST, 0, buffer, &length, &point);
+  if (status) {
+    CHECK_EQ("2225073858507201", buffer.start());
+    CHECK_EQ(-307, point);
+  }
+}
+
+
+TEST(FastDtoaShortestVariousFloats) {
+  char buffer_container[kBufferSize];
+  Vector<char> buffer(buffer_container, kBufferSize);
+  int length;
+  int point;
+  bool status;
+
+  float min_float = 1e-45f;
+  status = FastDtoa(min_float, FAST_DTOA_SHORTEST_SINGLE, 0,
+                    buffer, &length, &point);
+  CHECK(status);
+  CHECK_EQ("1", buffer.start());
+  CHECK_EQ(-44, point);
+
+
+  float max_float = 3.4028234e38f;
+  status = FastDtoa(max_float, FAST_DTOA_SHORTEST_SINGLE, 0,
+                    buffer, &length, &point);
+  CHECK(status);
+  CHECK_EQ("34028235", buffer.start());
+  CHECK_EQ(39, point);
+
+  status = FastDtoa(4294967272.0f, FAST_DTOA_SHORTEST_SINGLE, 0,
+                    buffer, &length, &point);
+  CHECK(status);
+  CHECK_EQ("42949673", buffer.start());
+  CHECK_EQ(10, point);
+
+  status = FastDtoa(3.32306998946228968226e+35f, FAST_DTOA_SHORTEST_SINGLE, 0,
+                    buffer, &length, &point);
+  CHECK(status);
+  CHECK_EQ("332307", buffer.start());
+  CHECK_EQ(36, point);
+
+  status = FastDtoa(1.2341e-41f, FAST_DTOA_SHORTEST_SINGLE, 0,
+                    buffer, &length, &point);
+  CHECK(status);
+  CHECK_EQ("12341", buffer.start());
+  CHECK_EQ(-40, point);
+
+  status = FastDtoa(3.3554432e7, FAST_DTOA_SHORTEST_SINGLE, 0,
+                    buffer, &length, &point);
+  CHECK(status);
+  CHECK_EQ("33554432", buffer.start());
+  CHECK_EQ(8, point);
+
+  status = FastDtoa(3.26494756798464e14f, FAST_DTOA_SHORTEST_SINGLE, 0,
+                    buffer, &length, &point);
+  CHECK(status);
+  CHECK_EQ("32649476", buffer.start());
+  CHECK_EQ(15, point);
+
+  status = FastDtoa(3.91132223637771935344e37f, FAST_DTOA_SHORTEST_SINGLE, 0,
+                    buffer, &length, &point);
+  if (status) {  // Not all FastDtoa variants manage to compute this number.
+    CHECK_EQ("39113222", buffer.start());
+    CHECK_EQ(38, point);
+  }
+
+  uint32_t smallest_normal32 = 0x00800000;
+  float v = Single(smallest_normal32).value();
+  status = FastDtoa(v, FAST_DTOA_SHORTEST_SINGLE, 0, buffer, &length, &point);
+  if (status) {
+    CHECK_EQ("11754944", buffer.start());
+    CHECK_EQ(-37, point);
+  }
+
+  uint32_t largest_denormal32 = 0x007FFFFF;
+  v = Single(largest_denormal32).value();
+  status = FastDtoa(v, FAST_DTOA_SHORTEST_SINGLE, 0, buffer, &length, &point);
+  CHECK(status);
+  CHECK_EQ("11754942", buffer.start());
+  CHECK_EQ(-37, point);
+}
+
+
+TEST(FastDtoaPrecisionVariousDoubles) {
+  char buffer_container[kBufferSize];
+  Vector<char> buffer(buffer_container, kBufferSize);
+  int length;
+  int point;
+  bool status;
+
+  status = FastDtoa(1.0, FAST_DTOA_PRECISION, 3, buffer, &length, &point);
+  CHECK(status);
+  CHECK(3 >= length);
+  TrimRepresentation(buffer);
+  CHECK_EQ("1", buffer.start());
+  CHECK_EQ(1, point);
+
+  status = FastDtoa(1.5, FAST_DTOA_PRECISION, 10, buffer, &length, &point);
+  if (status) {
+    CHECK(10 >= length);
+    TrimRepresentation(buffer);
+    CHECK_EQ("15", buffer.start());
+    CHECK_EQ(1, point);
+  }
+
+  double min_double = 5e-324;
+  status = FastDtoa(min_double, FAST_DTOA_PRECISION, 5,
+                    buffer, &length, &point);
+  CHECK(status);
+  CHECK_EQ("49407", buffer.start());
+  CHECK_EQ(-323, point);
+
+  double max_double = 1.7976931348623157e308;
+  status = FastDtoa(max_double, FAST_DTOA_PRECISION, 7,
+                    buffer, &length, &point);
+  CHECK(status);
+  CHECK_EQ("1797693", buffer.start());
+  CHECK_EQ(309, point);
+
+  status = FastDtoa(4294967272.0, FAST_DTOA_PRECISION, 14,
+                    buffer, &length, &point);
+  if (status) {
+    CHECK(14 >= length);
+    TrimRepresentation(buffer);
+    CHECK_EQ("4294967272", buffer.start());
+    CHECK_EQ(10, point);
+  }
+
+  status = FastDtoa(4.1855804968213567e298, FAST_DTOA_PRECISION, 17,
+                    buffer, &length, &point);
+  CHECK(status);
+  CHECK_EQ("41855804968213567", buffer.start());
+  CHECK_EQ(299, point);
+
+  status = FastDtoa(5.5626846462680035e-309, FAST_DTOA_PRECISION, 1,
+                    buffer, &length, &point);
+  CHECK(status);
+  CHECK_EQ("6", buffer.start());
+  CHECK_EQ(-308, point);
+
+  status = FastDtoa(2147483648.0, FAST_DTOA_PRECISION, 5,
+                    buffer, &length, &point);
+  CHECK(status);
+  CHECK_EQ("21475", buffer.start());
+  CHECK_EQ(10, point);
+
+  status = FastDtoa(3.5844466002796428e+298, FAST_DTOA_PRECISION, 10,
+                    buffer, &length, &point);
+  CHECK(status);
+  CHECK(10 >= length);
+  TrimRepresentation(buffer);
+  CHECK_EQ("35844466", buffer.start());
+  CHECK_EQ(299, point);
+
+  uint64_t smallest_normal64 = UINT64_2PART_C(0x00100000, 00000000);
+  double v = Double(smallest_normal64).value();
+  status = FastDtoa(v, FAST_DTOA_PRECISION, 17, buffer, &length, &point);
+  CHECK(status);
+  CHECK_EQ("22250738585072014", buffer.start());
+  CHECK_EQ(-307, point);
+
+  uint64_t largest_denormal64 = UINT64_2PART_C(0x000FFFFF, FFFFFFFF);
+  v = Double(largest_denormal64).value();
+  status = FastDtoa(v, FAST_DTOA_PRECISION, 17, buffer, &length, &point);
+  CHECK(status);
+  CHECK(20 >= length);
+  TrimRepresentation(buffer);
+  CHECK_EQ("22250738585072009", buffer.start());
+  CHECK_EQ(-307, point);
+
+  v = 3.3161339052167390562200598e-237;
+  status = FastDtoa(v, FAST_DTOA_PRECISION, 18, buffer, &length, &point);
+  CHECK(status);
+  CHECK_EQ("331613390521673906", buffer.start());
+  CHECK_EQ(-236, point);
+
+  v = 7.9885183916008099497815232e+191;
+  status = FastDtoa(v, FAST_DTOA_PRECISION, 4, buffer, &length, &point);
+  CHECK(status);
+  CHECK_EQ("7989", buffer.start());
+  CHECK_EQ(192, point);
+}
+
+
+TEST(FastDtoaGayShortest) {
+  char buffer_container[kBufferSize];
+  Vector<char> buffer(buffer_container, kBufferSize);
+  bool status;
+  int length;
+  int point;
+  int succeeded = 0;
+  int total = 0;
+  bool needed_max_length = false;
+
+  Vector<const PrecomputedShortest> precomputed =
+      PrecomputedShortestRepresentations();
+  for (int i = 0; i < precomputed.length(); ++i) {
+    const PrecomputedShortest current_test = precomputed[i];
+    total++;
+    double v = current_test.v;
+    status = FastDtoa(v, FAST_DTOA_SHORTEST, 0, buffer, &length, &point);
+    CHECK(kFastDtoaMaximalLength >= length);
+    if (!status) continue;
+    if (length == kFastDtoaMaximalLength) needed_max_length = true;
+    succeeded++;
+    CHECK_EQ(current_test.decimal_point, point);
+    CHECK_EQ(current_test.representation, buffer.start());
+  }
+  CHECK(succeeded*1.0/total > 0.99);
+  CHECK(needed_max_length);
+}
+
+
+TEST(FastDtoaGayShortestSingle) {
+  char buffer_container[kBufferSize];
+  Vector<char> buffer(buffer_container, kBufferSize);
+  bool status;
+  int length;
+  int point;
+  int succeeded = 0;
+  int total = 0;
+  bool needed_max_length = false;
+
+  Vector<const PrecomputedShortestSingle> precomputed =
+      PrecomputedShortestSingleRepresentations();
+  for (int i = 0; i < precomputed.length(); ++i) {
+    const PrecomputedShortestSingle current_test = precomputed[i];
+    total++;
+    float v = current_test.v;
+    status = FastDtoa(v, FAST_DTOA_SHORTEST_SINGLE, 0, buffer, &length, &point);
+    CHECK(kFastDtoaMaximalSingleLength >= length);
+    if (!status) continue;
+    if (length == kFastDtoaMaximalSingleLength) needed_max_length = true;
+    succeeded++;
+    CHECK_EQ(current_test.decimal_point, point);
+    CHECK_EQ(current_test.representation, buffer.start());
+  }
+  CHECK(succeeded*1.0/total > 0.98);
+  CHECK(needed_max_length);
+}
+
+
+TEST(FastDtoaGayPrecision) {
+  char buffer_container[kBufferSize];
+  Vector<char> buffer(buffer_container, kBufferSize);
+  bool status;
+  int length;
+  int point;
+  int succeeded = 0;
+  int total = 0;
+  // Count separately for entries with less than 15 requested digits.
+  int succeeded_15 = 0;
+  int total_15 = 0;
+
+  Vector<const PrecomputedPrecision> precomputed =
+      PrecomputedPrecisionRepresentations();
+  for (int i = 0; i < precomputed.length(); ++i) {
+    const PrecomputedPrecision current_test = precomputed[i];
+    double v = current_test.v;
+    int number_digits = current_test.number_digits;
+    total++;
+    if (number_digits <= 15) total_15++;
+    status = FastDtoa(v, FAST_DTOA_PRECISION, number_digits,
+                      buffer, &length, &point);
+    CHECK(number_digits >= length);
+    if (!status) continue;
+    succeeded++;
+    if (number_digits <= 15) succeeded_15++;
+    TrimRepresentation(buffer);
+    CHECK_EQ(current_test.decimal_point, point);
+    CHECK_EQ(current_test.representation, buffer.start());
+  }
+  // The precomputed numbers contain many entries with many requested
+  // digits. These have a high failure rate and we therefore expect a lower
+  // success rate than for the shortest representation.
+  CHECK(succeeded*1.0/total > 0.85);
+  // However with less than 15 digits almost the algorithm should almost always
+  // succeed.
+  CHECK(succeeded_15*1.0/total_15 > 0.9999);
+}

+ 511 - 0
third-party/double-conversion-1.1.6/test/cctest/test-fixed-dtoa.cc

@@ -0,0 +1,511 @@
+// 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 <stdlib.h>
+
+
+#include "cctest.h"
+#include "fixed-dtoa.h"
+#include "gay-fixed.h"
+#include "ieee.h"
+#include "utils.h"
+
+using namespace double_conversion;
+
+static const int kBufferSize = 500;
+
+TEST(FastFixedVariousDoubles) {
+  char buffer_container[kBufferSize];
+  Vector<char> buffer(buffer_container, kBufferSize);
+  int length;
+  int point;
+
+  CHECK(FastFixedDtoa(1.0, 1, buffer, &length, &point));
+  CHECK_EQ("1", buffer.start());
+  CHECK_EQ(1, point);
+
+  CHECK(FastFixedDtoa(1.0, 15, buffer, &length, &point));
+  CHECK_EQ("1", buffer.start());
+  CHECK_EQ(1, point);
+
+  CHECK(FastFixedDtoa(1.0, 0, buffer, &length, &point));
+  CHECK_EQ("1", buffer.start());
+  CHECK_EQ(1, point);
+
+  CHECK(FastFixedDtoa(0xFFFFFFFF, 5, buffer, &length, &point));
+  CHECK_EQ("4294967295", buffer.start());
+  CHECK_EQ(10, point);
+
+  CHECK(FastFixedDtoa(4294967296.0, 5, buffer, &length, &point));
+  CHECK_EQ("4294967296", buffer.start());
+  CHECK_EQ(10, point);
+
+  CHECK(FastFixedDtoa(1e21, 5, buffer, &length, &point));
+  CHECK_EQ("1", buffer.start());
+  // CHECK_EQ(22, point);
+  CHECK_EQ(22, point);
+
+  CHECK(FastFixedDtoa(999999999999999868928.00, 2, buffer, &length, &point));
+  CHECK_EQ("999999999999999868928", buffer.start());
+  CHECK_EQ(21, point);
+
+  CHECK(FastFixedDtoa(6.9999999999999989514240000e+21, 5, buffer,
+                      &length, &point));
+  CHECK_EQ("6999999999999998951424", buffer.start());
+  CHECK_EQ(22, point);
+
+  CHECK(FastFixedDtoa(1.5, 5, buffer, &length, &point));
+  CHECK_EQ("15", buffer.start());
+  CHECK_EQ(1, point);
+
+  CHECK(FastFixedDtoa(1.55, 5, buffer, &length, &point));
+  CHECK_EQ("155", buffer.start());
+  CHECK_EQ(1, point);
+
+  CHECK(FastFixedDtoa(1.55, 1, buffer, &length, &point));
+  CHECK_EQ("16", buffer.start());
+  CHECK_EQ(1, point);
+
+  CHECK(FastFixedDtoa(1.00000001, 15, buffer, &length, &point));
+  CHECK_EQ("100000001", buffer.start());
+  CHECK_EQ(1, point);
+
+  CHECK(FastFixedDtoa(0.1, 10, buffer, &length, &point));
+  CHECK_EQ("1", buffer.start());
+  CHECK_EQ(0, point);
+
+  CHECK(FastFixedDtoa(0.01, 10, buffer, &length, &point));
+  CHECK_EQ("1", buffer.start());
+  CHECK_EQ(-1, point);
+
+  CHECK(FastFixedDtoa(0.001, 10, buffer, &length, &point));
+  CHECK_EQ("1", buffer.start());
+  CHECK_EQ(-2, point);
+
+  CHECK(FastFixedDtoa(0.0001, 10, buffer, &length, &point));
+  CHECK_EQ("1", buffer.start());
+  CHECK_EQ(-3, point);
+
+  CHECK(FastFixedDtoa(0.00001, 10, buffer, &length, &point));
+  CHECK_EQ("1", buffer.start());
+  CHECK_EQ(-4, point);
+
+  CHECK(FastFixedDtoa(0.000001, 10, buffer, &length, &point));
+  CHECK_EQ("1", buffer.start());
+  CHECK_EQ(-5, point);
+
+  CHECK(FastFixedDtoa(0.0000001, 10, buffer, &length, &point));
+  CHECK_EQ("1", buffer.start());
+  CHECK_EQ(-6, point);
+
+  CHECK(FastFixedDtoa(0.00000001, 10, buffer, &length, &point));
+  CHECK_EQ("1", buffer.start());
+  CHECK_EQ(-7, point);
+
+  CHECK(FastFixedDtoa(0.000000001, 10, buffer, &length, &point));
+  CHECK_EQ("1", buffer.start());
+  CHECK_EQ(-8, point);
+
+  CHECK(FastFixedDtoa(0.0000000001, 15, buffer, &length, &point));
+  CHECK_EQ("1", buffer.start());
+  CHECK_EQ(-9, point);
+
+  CHECK(FastFixedDtoa(0.00000000001, 15, buffer, &length, &point));
+  CHECK_EQ("1", buffer.start());
+  CHECK_EQ(-10, point);
+
+  CHECK(FastFixedDtoa(0.000000000001, 15, buffer, &length, &point));
+  CHECK_EQ("1", buffer.start());
+  CHECK_EQ(-11, point);
+
+  CHECK(FastFixedDtoa(0.0000000000001, 15, buffer, &length, &point));
+  CHECK_EQ("1", buffer.start());
+  CHECK_EQ(-12, point);
+
+  CHECK(FastFixedDtoa(0.00000000000001, 15, buffer, &length, &point));
+  CHECK_EQ("1", buffer.start());
+  CHECK_EQ(-13, point);
+
+  CHECK(FastFixedDtoa(0.000000000000001, 20, buffer, &length, &point));
+  CHECK_EQ("1", buffer.start());
+  CHECK_EQ(-14, point);
+
+  CHECK(FastFixedDtoa(0.0000000000000001, 20, buffer, &length, &point));
+  CHECK_EQ("1", buffer.start());
+  CHECK_EQ(-15, point);
+
+  CHECK(FastFixedDtoa(0.00000000000000001, 20, buffer, &length, &point));
+  CHECK_EQ("1", buffer.start());
+  CHECK_EQ(-16, point);
+
+  CHECK(FastFixedDtoa(0.000000000000000001, 20, buffer, &length, &point));
+  CHECK_EQ("1", buffer.start());
+  CHECK_EQ(-17, point);
+
+  CHECK(FastFixedDtoa(0.0000000000000000001, 20, buffer, &length, &point));
+  CHECK_EQ("1", buffer.start());
+  CHECK_EQ(-18, point);
+
+  CHECK(FastFixedDtoa(0.00000000000000000001, 20, buffer, &length, &point));
+  CHECK_EQ("1", buffer.start());
+  CHECK_EQ(-19, point);
+
+  CHECK(FastFixedDtoa(0.10000000004, 10, buffer, &length, &point));
+  CHECK_EQ("1", buffer.start());
+  CHECK_EQ(0, point);
+
+  CHECK(FastFixedDtoa(0.01000000004, 10, buffer, &length, &point));
+  CHECK_EQ("1", buffer.start());
+  CHECK_EQ(-1, point);
+
+  CHECK(FastFixedDtoa(0.00100000004, 10, buffer, &length, &point));
+  CHECK_EQ("1", buffer.start());
+  CHECK_EQ(-2, point);
+
+  CHECK(FastFixedDtoa(0.00010000004, 10, buffer, &length, &point));
+  CHECK_EQ("1", buffer.start());
+  CHECK_EQ(-3, point);
+
+  CHECK(FastFixedDtoa(0.00001000004, 10, buffer, &length, &point));
+  CHECK_EQ("1", buffer.start());
+  CHECK_EQ(-4, point);
+
+  CHECK(FastFixedDtoa(0.00000100004, 10, buffer, &length, &point));
+  CHECK_EQ("1", buffer.start());
+  CHECK_EQ(-5, point);
+
+  CHECK(FastFixedDtoa(0.00000010004, 10, buffer, &length, &point));
+  CHECK_EQ("1", buffer.start());
+  CHECK_EQ(-6, point);
+
+  CHECK(FastFixedDtoa(0.00000001004, 10, buffer, &length, &point));
+  CHECK_EQ("1", buffer.start());
+  CHECK_EQ(-7, point);
+
+  CHECK(FastFixedDtoa(0.00000000104, 10, buffer, &length, &point));
+  CHECK_EQ("1", buffer.start());
+  CHECK_EQ(-8, point);
+
+  CHECK(FastFixedDtoa(0.0000000001000004, 15, buffer, &length, &point));
+  CHECK_EQ("1", buffer.start());
+  CHECK_EQ(-9, point);
+
+  CHECK(FastFixedDtoa(0.0000000000100004, 15, buffer, &length, &point));
+  CHECK_EQ("1", buffer.start());
+  CHECK_EQ(-10, point);
+
+  CHECK(FastFixedDtoa(0.0000000000010004, 15, buffer, &length, &point));
+  CHECK_EQ("1", buffer.start());
+  CHECK_EQ(-11, point);
+
+  CHECK(FastFixedDtoa(0.0000000000001004, 15, buffer, &length, &point));
+  CHECK_EQ("1", buffer.start());
+  CHECK_EQ(-12, point);
+
+  CHECK(FastFixedDtoa(0.0000000000000104, 15, buffer, &length, &point));
+  CHECK_EQ("1", buffer.start());
+  CHECK_EQ(-13, point);
+
+  CHECK(FastFixedDtoa(0.000000000000001000004, 20, buffer, &length, &point));
+  CHECK_EQ("1", buffer.start());
+  CHECK_EQ(-14, point);
+
+  CHECK(FastFixedDtoa(0.000000000000000100004, 20, buffer, &length, &point));
+  CHECK_EQ("1", buffer.start());
+  CHECK_EQ(-15, point);
+
+  CHECK(FastFixedDtoa(0.000000000000000010004, 20, buffer, &length, &point));
+  CHECK_EQ("1", buffer.start());
+  CHECK_EQ(-16, point);
+
+  CHECK(FastFixedDtoa(0.000000000000000001004, 20, buffer, &length, &point));
+  CHECK_EQ("1", buffer.start());
+  CHECK_EQ(-17, point);
+
+  CHECK(FastFixedDtoa(0.000000000000000000104, 20, buffer, &length, &point));
+  CHECK_EQ("1", buffer.start());
+  CHECK_EQ(-18, point);
+
+  CHECK(FastFixedDtoa(0.000000000000000000014, 20, buffer, &length, &point));
+  CHECK_EQ("1", buffer.start());
+  CHECK_EQ(-19, point);
+
+  CHECK(FastFixedDtoa(0.10000000006, 10, buffer, &length, &point));
+  CHECK_EQ("1000000001", buffer.start());
+  CHECK_EQ(0, point);
+
+  CHECK(FastFixedDtoa(0.01000000006, 10, buffer, &length, &point));
+  CHECK_EQ("100000001", buffer.start());
+  CHECK_EQ(-1, point);
+
+  CHECK(FastFixedDtoa(0.00100000006, 10, buffer, &length, &point));
+  CHECK_EQ("10000001", buffer.start());
+  CHECK_EQ(-2, point);
+
+  CHECK(FastFixedDtoa(0.00010000006, 10, buffer, &length, &point));
+  CHECK_EQ("1000001", buffer.start());
+  CHECK_EQ(-3, point);
+
+  CHECK(FastFixedDtoa(0.00001000006, 10, buffer, &length, &point));
+  CHECK_EQ("100001", buffer.start());
+  CHECK_EQ(-4, point);
+
+  CHECK(FastFixedDtoa(0.00000100006, 10, buffer, &length, &point));
+  CHECK_EQ("10001", buffer.start());
+  CHECK_EQ(-5, point);
+
+  CHECK(FastFixedDtoa(0.00000010006, 10, buffer, &length, &point));
+  CHECK_EQ("1001", buffer.start());
+  CHECK_EQ(-6, point);
+
+  CHECK(FastFixedDtoa(0.00000001006, 10, buffer, &length, &point));
+  CHECK_EQ("101", buffer.start());
+  CHECK_EQ(-7, point);
+
+  CHECK(FastFixedDtoa(0.00000000106, 10, buffer, &length, &point));
+  CHECK_EQ("11", buffer.start());
+  CHECK_EQ(-8, point);
+
+  CHECK(FastFixedDtoa(0.0000000001000006, 15, buffer, &length, &point));
+  CHECK_EQ("100001", buffer.start());
+  CHECK_EQ(-9, point);
+
+  CHECK(FastFixedDtoa(0.0000000000100006, 15, buffer, &length, &point));
+  CHECK_EQ("10001", buffer.start());
+  CHECK_EQ(-10, point);
+
+  CHECK(FastFixedDtoa(0.0000000000010006, 15, buffer, &length, &point));
+  CHECK_EQ("1001", buffer.start());
+  CHECK_EQ(-11, point);
+
+  CHECK(FastFixedDtoa(0.0000000000001006, 15, buffer, &length, &point));
+  CHECK_EQ("101", buffer.start());
+  CHECK_EQ(-12, point);
+
+  CHECK(FastFixedDtoa(0.0000000000000106, 15, buffer, &length, &point));
+  CHECK_EQ("11", buffer.start());
+  CHECK_EQ(-13, point);
+
+  CHECK(FastFixedDtoa(0.000000000000001000006, 20, buffer, &length, &point));
+  CHECK_EQ("100001", buffer.start());
+  CHECK_EQ(-14, point);
+
+  CHECK(FastFixedDtoa(0.000000000000000100006, 20, buffer, &length, &point));
+  CHECK_EQ("10001", buffer.start());
+  CHECK_EQ(-15, point);
+
+  CHECK(FastFixedDtoa(0.000000000000000010006, 20, buffer, &length, &point));
+  CHECK_EQ("1001", buffer.start());
+  CHECK_EQ(-16, point);
+
+  CHECK(FastFixedDtoa(0.000000000000000001006, 20, buffer, &length, &point));
+  CHECK_EQ("101", buffer.start());
+  CHECK_EQ(-17, point);
+
+  CHECK(FastFixedDtoa(0.000000000000000000106, 20, buffer, &length, &point));
+  CHECK_EQ("11", buffer.start());
+  CHECK_EQ(-18, point);
+
+  CHECK(FastFixedDtoa(0.000000000000000000016, 20, buffer, &length, &point));
+  CHECK_EQ("2", buffer.start());
+  CHECK_EQ(-19, point);
+
+  CHECK(FastFixedDtoa(0.6, 0, buffer, &length, &point));
+  CHECK_EQ("1", buffer.start());
+  CHECK_EQ(1, point);
+
+  CHECK(FastFixedDtoa(0.96, 1, buffer, &length, &point));
+  CHECK_EQ("1", buffer.start());
+  CHECK_EQ(1, point);
+
+  CHECK(FastFixedDtoa(0.996, 2, buffer, &length, &point));
+  CHECK_EQ("1", buffer.start());
+  CHECK_EQ(1, point);
+
+  CHECK(FastFixedDtoa(0.9996, 3, buffer, &length, &point));
+  CHECK_EQ("1", buffer.start());
+  CHECK_EQ(1, point);
+
+  CHECK(FastFixedDtoa(0.99996, 4, buffer, &length, &point));
+  CHECK_EQ("1", buffer.start());
+  CHECK_EQ(1, point);
+
+  CHECK(FastFixedDtoa(0.999996, 5, buffer, &length, &point));
+  CHECK_EQ("1", buffer.start());
+  CHECK_EQ(1, point);
+
+  CHECK(FastFixedDtoa(0.9999996, 6, buffer, &length, &point));
+  CHECK_EQ("1", buffer.start());
+  CHECK_EQ(1, point);
+
+  CHECK(FastFixedDtoa(0.99999996, 7, buffer, &length, &point));
+  CHECK_EQ("1", buffer.start());
+  CHECK_EQ(1, point);
+
+  CHECK(FastFixedDtoa(0.999999996, 8, buffer, &length, &point));
+  CHECK_EQ("1", buffer.start());
+  CHECK_EQ(1, point);
+
+  CHECK(FastFixedDtoa(0.9999999996, 9, buffer, &length, &point));
+  CHECK_EQ("1", buffer.start());
+  CHECK_EQ(1, point);
+
+  CHECK(FastFixedDtoa(0.99999999996, 10, buffer, &length, &point));
+  CHECK_EQ("1", buffer.start());
+  CHECK_EQ(1, point);
+
+  CHECK(FastFixedDtoa(0.999999999996, 11, buffer, &length, &point));
+  CHECK_EQ("1", buffer.start());
+  CHECK_EQ(1, point);
+
+  CHECK(FastFixedDtoa(0.9999999999996, 12, buffer, &length, &point));
+  CHECK_EQ("1", buffer.start());
+  CHECK_EQ(1, point);
+
+  CHECK(FastFixedDtoa(0.99999999999996, 13, buffer, &length, &point));
+  CHECK_EQ("1", buffer.start());
+  CHECK_EQ(1, point);
+
+  CHECK(FastFixedDtoa(0.999999999999996, 14, buffer, &length, &point));
+  CHECK_EQ("1", buffer.start());
+  CHECK_EQ(1, point);
+
+  CHECK(FastFixedDtoa(0.9999999999999996, 15, buffer, &length, &point));
+  CHECK_EQ("1", buffer.start());
+  CHECK_EQ(1, point);
+
+  CHECK(FastFixedDtoa(0.00999999999999996, 16, buffer, &length, &point));
+  CHECK_EQ("1", buffer.start());
+  CHECK_EQ(-1, point);
+
+  CHECK(FastFixedDtoa(0.000999999999999996, 17, buffer, &length, &point));
+  CHECK_EQ("1", buffer.start());
+  CHECK_EQ(-2, point);
+
+  CHECK(FastFixedDtoa(0.0000999999999999996, 18, buffer, &length, &point));
+  CHECK_EQ("1", buffer.start());
+  CHECK_EQ(-3, point);
+
+  CHECK(FastFixedDtoa(0.00000999999999999996, 19, buffer, &length, &point));
+  CHECK_EQ("1", buffer.start());
+  CHECK_EQ(-4, point);
+
+  CHECK(FastFixedDtoa(0.000000999999999999996, 20, buffer, &length, &point));
+  CHECK_EQ("1", buffer.start());
+  CHECK_EQ(-5, point);
+
+  CHECK(FastFixedDtoa(323423.234234, 10, buffer, &length, &point));
+  CHECK_EQ("323423234234", buffer.start());
+  CHECK_EQ(6, point);
+
+  CHECK(FastFixedDtoa(12345678.901234, 4, buffer, &length, &point));
+  CHECK_EQ("123456789012", buffer.start());
+  CHECK_EQ(8, point);
+
+  CHECK(FastFixedDtoa(98765.432109, 5, buffer, &length, &point));
+  CHECK_EQ("9876543211", buffer.start());
+  CHECK_EQ(5, point);
+
+  CHECK(FastFixedDtoa(42, 20, buffer, &length, &point));
+  CHECK_EQ("42", buffer.start());
+  CHECK_EQ(2, point);
+
+  CHECK(FastFixedDtoa(0.5, 0, buffer, &length, &point));
+  CHECK_EQ("1", buffer.start());
+  CHECK_EQ(1, point);
+
+  CHECK(FastFixedDtoa(1e-23, 10, buffer, &length, &point));
+  CHECK_EQ("", buffer.start());
+  CHECK_EQ(-10, point);
+
+  CHECK(FastFixedDtoa(1e-123, 2, buffer, &length, &point));
+  CHECK_EQ("", buffer.start());
+  CHECK_EQ(-2, point);
+
+  CHECK(FastFixedDtoa(1e-123, 0, buffer, &length, &point));
+  CHECK_EQ("", buffer.start());
+  CHECK_EQ(0, point);
+
+  CHECK(FastFixedDtoa(1e-23, 20, buffer, &length, &point));
+  CHECK_EQ("", buffer.start());
+  CHECK_EQ(-20, point);
+
+  CHECK(FastFixedDtoa(1e-21, 20, buffer, &length, &point));
+  CHECK_EQ("", buffer.start());
+  CHECK_EQ(-20, point);
+
+  CHECK(FastFixedDtoa(1e-22, 20, buffer, &length, &point));
+  CHECK_EQ("", buffer.start());
+  CHECK_EQ(-20, point);
+
+  CHECK(FastFixedDtoa(6e-21, 20, buffer, &length, &point));
+  CHECK_EQ("1", buffer.start());
+  CHECK_EQ(-19, point);
+
+  CHECK(FastFixedDtoa(9.1193616301674545152000000e+19, 0,
+                      buffer, &length, &point));
+  CHECK_EQ("91193616301674545152", buffer.start());
+  CHECK_EQ(20, point);
+
+  CHECK(FastFixedDtoa(4.8184662102767651659096515e-04, 19,
+                      buffer, &length, &point));
+  CHECK_EQ("4818466210276765", buffer.start());
+  CHECK_EQ(-3, point);
+
+  CHECK(FastFixedDtoa(1.9023164229540652612705182e-23, 8,
+                      buffer, &length, &point));
+  CHECK_EQ("", buffer.start());
+  CHECK_EQ(-8, point);
+
+  CHECK(FastFixedDtoa(1000000000000000128.0, 0,
+                      buffer, &length, &point));
+  CHECK_EQ("1000000000000000128", buffer.start());
+  CHECK_EQ(19, point);
+}
+
+
+TEST(FastFixedDtoaGayFixed) {
+  char buffer_container[kBufferSize];
+  Vector<char> buffer(buffer_container, kBufferSize);
+  bool status;
+  int length;
+  int point;
+
+  Vector<const PrecomputedFixed> precomputed =
+      PrecomputedFixedRepresentations();
+  for (int i = 0; i < precomputed.length(); ++i) {
+    const PrecomputedFixed current_test = precomputed[i];
+    double v = current_test.v;
+    int number_digits = current_test.number_digits;
+    status = FastFixedDtoa(v, number_digits,
+                           buffer, &length, &point);
+    CHECK(status);
+    CHECK_EQ(current_test.decimal_point, point);
+    CHECK(number_digits >= length - point);
+    CHECK_EQ(current_test.representation, buffer.start());
+  }
+}

+ 422 - 0
third-party/double-conversion-1.1.6/test/cctest/test-ieee.cc

@@ -0,0 +1,422 @@
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
+
+#include <stdlib.h>
+
+#include "cctest.h"
+#include "diy-fp.h"
+#include "ieee.h"
+#include "utils.h"
+#include "../../src/ieee.h"
+
+
+using namespace double_conversion;
+
+
+TEST(Uint64Conversions) {
+  // Start by checking the byte-order.
+  uint64_t ordered = UINT64_2PART_C(0x01234567, 89ABCDEF);
+  CHECK_EQ(3512700564088504e-318, Double(ordered).value());
+
+  uint64_t min_double64 = UINT64_2PART_C(0x00000000, 00000001);
+  CHECK_EQ(5e-324, Double(min_double64).value());
+
+  uint64_t max_double64 = UINT64_2PART_C(0x7fefffff, ffffffff);
+  CHECK_EQ(1.7976931348623157e308, Double(max_double64).value());
+}
+
+
+TEST(Uint32Conversions) {
+  // Start by checking the byte-order.
+  uint32_t ordered = 0x01234567;
+  CHECK_EQ(2.9988165487136453e-38f, Single(ordered).value());
+
+  uint32_t min_float32 = 0x00000001;
+  CHECK_EQ(1.4e-45f, Single(min_float32).value());
+
+  uint32_t max_float32 = 0x7f7fffff;
+  CHECK_EQ(3.4028234e38f, Single(max_float32).value());
+}
+
+
+TEST(Double_AsDiyFp) {
+  uint64_t ordered = UINT64_2PART_C(0x01234567, 89ABCDEF);
+  DiyFp diy_fp = Double(ordered).AsDiyFp();
+  CHECK_EQ(0x12 - 0x3FF - 52, diy_fp.e());
+  // The 52 mantissa bits, plus the implicit 1 in bit 52 as a UINT64.
+  CHECK(UINT64_2PART_C(0x00134567, 89ABCDEF) == diy_fp.f());  // NOLINT
+
+  uint64_t min_double64 = UINT64_2PART_C(0x00000000, 00000001);
+  diy_fp = Double(min_double64).AsDiyFp();
+  CHECK_EQ(-0x3FF - 52 + 1, diy_fp.e());
+  // This is a denormal; so no hidden bit.
+  CHECK(1 == diy_fp.f());  // NOLINT
+
+  uint64_t max_double64 = UINT64_2PART_C(0x7fefffff, ffffffff);
+  diy_fp = Double(max_double64).AsDiyFp();
+  CHECK_EQ(0x7FE - 0x3FF - 52, diy_fp.e());
+  CHECK(UINT64_2PART_C(0x001fffff, ffffffff) == diy_fp.f());  // NOLINT
+}
+
+
+TEST(Single_AsDiyFp) {
+  uint32_t ordered = 0x01234567;
+  DiyFp diy_fp = Single(ordered).AsDiyFp();
+  CHECK_EQ(0x2 - 0x7F - 23, diy_fp.e());
+  // The 23 mantissa bits, plus the implicit 1 in bit 24 as a uint32_t.
+  CHECK_EQ(0xA34567, diy_fp.f());
+
+  uint32_t min_float32 = 0x00000001;
+  diy_fp = Single(min_float32).AsDiyFp();
+  CHECK_EQ(-0x7F - 23 + 1, diy_fp.e());
+  // This is a denormal; so no hidden bit.
+  CHECK_EQ(1, diy_fp.f());
+
+  uint32_t max_float32 = 0x7f7fffff;
+  diy_fp = Single(max_float32).AsDiyFp();
+  CHECK_EQ(0xFE - 0x7F - 23, diy_fp.e());
+  CHECK_EQ(0x00ffffff, diy_fp.f());
+}
+
+
+TEST(AsNormalizedDiyFp) {
+  uint64_t ordered = UINT64_2PART_C(0x01234567, 89ABCDEF);
+  DiyFp diy_fp = Double(ordered).AsNormalizedDiyFp();
+  CHECK_EQ(0x12 - 0x3FF - 52 - 11, diy_fp.e());
+  CHECK((UINT64_2PART_C(0x00134567, 89ABCDEF) << 11) ==
+        diy_fp.f());  // NOLINT
+
+  uint64_t min_double64 = UINT64_2PART_C(0x00000000, 00000001);
+  diy_fp = Double(min_double64).AsNormalizedDiyFp();
+  CHECK_EQ(-0x3FF - 52 + 1 - 63, diy_fp.e());
+  // This is a denormal; so no hidden bit.
+  CHECK(UINT64_2PART_C(0x80000000, 00000000) == diy_fp.f());  // NOLINT
+
+  uint64_t max_double64 = UINT64_2PART_C(0x7fefffff, ffffffff);
+  diy_fp = Double(max_double64).AsNormalizedDiyFp();
+  CHECK_EQ(0x7FE - 0x3FF - 52 - 11, diy_fp.e());
+  CHECK((UINT64_2PART_C(0x001fffff, ffffffff) << 11) ==
+        diy_fp.f());  // NOLINT
+}
+
+
+TEST(Double_IsDenormal) {
+  uint64_t min_double64 = UINT64_2PART_C(0x00000000, 00000001);
+  CHECK(Double(min_double64).IsDenormal());
+  uint64_t bits = UINT64_2PART_C(0x000FFFFF, FFFFFFFF);
+  CHECK(Double(bits).IsDenormal());
+  bits = UINT64_2PART_C(0x00100000, 00000000);
+  CHECK(!Double(bits).IsDenormal());
+}
+
+
+TEST(Single_IsDenormal) {
+  uint32_t min_float32 = 0x00000001;
+  CHECK(Single(min_float32).IsDenormal());
+  uint32_t bits = 0x007FFFFF;
+  CHECK(Single(bits).IsDenormal());
+  bits = 0x00800000;
+  CHECK(!Single(bits).IsDenormal());
+}
+
+
+TEST(Double_IsSpecial) {
+  CHECK(Double(Double::Infinity()).IsSpecial());
+  CHECK(Double(-Double::Infinity()).IsSpecial());
+  CHECK(Double(Double::NaN()).IsSpecial());
+  uint64_t bits = UINT64_2PART_C(0xFFF12345, 00000000);
+  CHECK(Double(bits).IsSpecial());
+  // Denormals are not special:
+  CHECK(!Double(5e-324).IsSpecial());
+  CHECK(!Double(-5e-324).IsSpecial());
+  // And some random numbers:
+  CHECK(!Double(0.0).IsSpecial());
+  CHECK(!Double(-0.0).IsSpecial());
+  CHECK(!Double(1.0).IsSpecial());
+  CHECK(!Double(-1.0).IsSpecial());
+  CHECK(!Double(1000000.0).IsSpecial());
+  CHECK(!Double(-1000000.0).IsSpecial());
+  CHECK(!Double(1e23).IsSpecial());
+  CHECK(!Double(-1e23).IsSpecial());
+  CHECK(!Double(1.7976931348623157e308).IsSpecial());
+  CHECK(!Double(-1.7976931348623157e308).IsSpecial());
+}
+
+
+TEST(Single_IsSpecial) {
+  CHECK(Single(Single::Infinity()).IsSpecial());
+  CHECK(Single(-Single::Infinity()).IsSpecial());
+  CHECK(Single(Single::NaN()).IsSpecial());
+  uint32_t bits = 0xFFF12345;
+  CHECK(Single(bits).IsSpecial());
+  // Denormals are not special:
+  CHECK(!Single(1.4e-45f).IsSpecial());
+  CHECK(!Single(-1.4e-45f).IsSpecial());
+  // And some random numbers:
+  CHECK(!Single(0.0f).IsSpecial());
+  CHECK(!Single(-0.0f).IsSpecial());
+  CHECK(!Single(1.0f).IsSpecial());
+  CHECK(!Single(-1.0f).IsSpecial());
+  CHECK(!Single(1000000.0f).IsSpecial());
+  CHECK(!Single(-1000000.0f).IsSpecial());
+  CHECK(!Single(1e23f).IsSpecial());
+  CHECK(!Single(-1e23f).IsSpecial());
+  CHECK(!Single(1.18e-38f).IsSpecial());
+  CHECK(!Single(-1.18e-38f).IsSpecial());
+}
+
+
+TEST(Double_IsInfinite) {
+  CHECK(Double(Double::Infinity()).IsInfinite());
+  CHECK(Double(-Double::Infinity()).IsInfinite());
+  CHECK(!Double(Double::NaN()).IsInfinite());
+  CHECK(!Double(0.0).IsInfinite());
+  CHECK(!Double(-0.0).IsInfinite());
+  CHECK(!Double(1.0).IsInfinite());
+  CHECK(!Double(-1.0).IsInfinite());
+  uint64_t min_double64 = UINT64_2PART_C(0x00000000, 00000001);
+  CHECK(!Double(min_double64).IsInfinite());
+}
+
+
+TEST(Single_IsInfinite) {
+  CHECK(Single(Single::Infinity()).IsInfinite());
+  CHECK(Single(-Single::Infinity()).IsInfinite());
+  CHECK(!Single(Single::NaN()).IsInfinite());
+  CHECK(!Single(0.0f).IsInfinite());
+  CHECK(!Single(-0.0f).IsInfinite());
+  CHECK(!Single(1.0f).IsInfinite());
+  CHECK(!Single(-1.0f).IsInfinite());
+  uint32_t min_float32 = 0x00000001;
+  CHECK(!Single(min_float32).IsInfinite());
+}
+
+
+TEST(Double_IsNan) {
+  CHECK(Double(Double::NaN()).IsNan());
+  uint64_t other_nan = UINT64_2PART_C(0xFFFFFFFF, 00000001);
+  CHECK(Double(other_nan).IsNan());
+  CHECK(!Double(Double::Infinity()).IsNan());
+  CHECK(!Double(-Double::Infinity()).IsNan());
+  CHECK(!Double(0.0).IsNan());
+  CHECK(!Double(-0.0).IsNan());
+  CHECK(!Double(1.0).IsNan());
+  CHECK(!Double(-1.0).IsNan());
+  uint64_t min_double64 = UINT64_2PART_C(0x00000000, 00000001);
+  CHECK(!Double(min_double64).IsNan());
+}
+
+
+TEST(Single_IsNan) {
+  CHECK(Single(Single::NaN()).IsNan());
+  uint32_t other_nan = 0xFFFFF001;
+  CHECK(Single(other_nan).IsNan());
+  CHECK(!Single(Single::Infinity()).IsNan());
+  CHECK(!Single(-Single::Infinity()).IsNan());
+  CHECK(!Single(0.0f).IsNan());
+  CHECK(!Single(-0.0f).IsNan());
+  CHECK(!Single(1.0f).IsNan());
+  CHECK(!Single(-1.0f).IsNan());
+  uint32_t min_float32 = 0x00000001;
+  CHECK(!Single(min_float32).IsNan());
+}
+
+
+TEST(Double_Sign) {
+  CHECK_EQ(1, Double(1.0).Sign());
+  CHECK_EQ(1, Double(Double::Infinity()).Sign());
+  CHECK_EQ(-1, Double(-Double::Infinity()).Sign());
+  CHECK_EQ(1, Double(0.0).Sign());
+  CHECK_EQ(-1, Double(-0.0).Sign());
+  uint64_t min_double64 = UINT64_2PART_C(0x00000000, 00000001);
+  CHECK_EQ(1, Double(min_double64).Sign());
+}
+
+
+TEST(Single_Sign) {
+  CHECK_EQ(1, Single(1.0f).Sign());
+  CHECK_EQ(1, Single(Single::Infinity()).Sign());
+  CHECK_EQ(-1, Single(-Single::Infinity()).Sign());
+  CHECK_EQ(1, Single(0.0f).Sign());
+  CHECK_EQ(-1, Single(-0.0f).Sign());
+  uint32_t min_float32 = 0x00000001;
+  CHECK_EQ(1, Single(min_float32).Sign());
+}
+
+
+TEST(Double_NormalizedBoundaries) {
+  DiyFp boundary_plus;
+  DiyFp boundary_minus;
+  DiyFp diy_fp = Double(1.5).AsNormalizedDiyFp();
+  Double(1.5).NormalizedBoundaries(&boundary_minus, &boundary_plus);
+  CHECK_EQ(diy_fp.e(), boundary_minus.e());
+  CHECK_EQ(diy_fp.e(), boundary_plus.e());
+  // 1.5 does not have a significand of the form 2^p (for some p).
+  // Therefore its boundaries are at the same distance.
+  CHECK(diy_fp.f() - boundary_minus.f() == boundary_plus.f() - diy_fp.f());
+  CHECK((1 << 10) == diy_fp.f() - boundary_minus.f());  // NOLINT
+
+  diy_fp = Double(1.0).AsNormalizedDiyFp();
+  Double(1.0).NormalizedBoundaries(&boundary_minus, &boundary_plus);
+  CHECK_EQ(diy_fp.e(), boundary_minus.e());
+  CHECK_EQ(diy_fp.e(), boundary_plus.e());
+  // 1.0 does have a significand of the form 2^p (for some p).
+  // Therefore its lower boundary is twice as close as the upper boundary.
+  CHECK(boundary_plus.f() - diy_fp.f() > diy_fp.f() - boundary_minus.f());
+  CHECK((1 << 9) == diy_fp.f() - boundary_minus.f());  // NOLINT
+  CHECK((1 << 10) == boundary_plus.f() - diy_fp.f());  // NOLINT
+
+  uint64_t min_double64 = UINT64_2PART_C(0x00000000, 00000001);
+  diy_fp = Double(min_double64).AsNormalizedDiyFp();
+  Double(min_double64).NormalizedBoundaries(&boundary_minus, &boundary_plus);
+  CHECK_EQ(diy_fp.e(), boundary_minus.e());
+  CHECK_EQ(diy_fp.e(), boundary_plus.e());
+  // min-value does not have a significand of the form 2^p (for some p).
+  // Therefore its boundaries are at the same distance.
+  CHECK(diy_fp.f() - boundary_minus.f() == boundary_plus.f() - diy_fp.f());
+  // Denormals have their boundaries much closer.
+  CHECK((static_cast<uint64_t>(1) << 62) ==
+        diy_fp.f() - boundary_minus.f());  // NOLINT
+
+  uint64_t smallest_normal64 = UINT64_2PART_C(0x00100000, 00000000);
+  diy_fp = Double(smallest_normal64).AsNormalizedDiyFp();
+  Double(smallest_normal64).NormalizedBoundaries(&boundary_minus,
+                                                 &boundary_plus);
+  CHECK_EQ(diy_fp.e(), boundary_minus.e());
+  CHECK_EQ(diy_fp.e(), boundary_plus.e());
+  // Even though the significand is of the form 2^p (for some p), its boundaries
+  // are at the same distance. (This is the only exception).
+  CHECK(diy_fp.f() - boundary_minus.f() == boundary_plus.f() - diy_fp.f());
+  CHECK((1 << 10) == diy_fp.f() - boundary_minus.f());  // NOLINT
+
+  uint64_t largest_denormal64 = UINT64_2PART_C(0x000FFFFF, FFFFFFFF);
+  diy_fp = Double(largest_denormal64).AsNormalizedDiyFp();
+  Double(largest_denormal64).NormalizedBoundaries(&boundary_minus,
+                                                  &boundary_plus);
+  CHECK_EQ(diy_fp.e(), boundary_minus.e());
+  CHECK_EQ(diy_fp.e(), boundary_plus.e());
+  CHECK(diy_fp.f() - boundary_minus.f() == boundary_plus.f() - diy_fp.f());
+  CHECK((1 << 11) == diy_fp.f() - boundary_minus.f());  // NOLINT
+
+  uint64_t max_double64 = UINT64_2PART_C(0x7fefffff, ffffffff);
+  diy_fp = Double(max_double64).AsNormalizedDiyFp();
+  Double(max_double64).NormalizedBoundaries(&boundary_minus, &boundary_plus);
+  CHECK_EQ(diy_fp.e(), boundary_minus.e());
+  CHECK_EQ(diy_fp.e(), boundary_plus.e());
+  // max-value does not have a significand of the form 2^p (for some p).
+  // Therefore its boundaries are at the same distance.
+  CHECK(diy_fp.f() - boundary_minus.f() == boundary_plus.f() - diy_fp.f());
+  CHECK((1 << 10) == diy_fp.f() - boundary_minus.f());  // NOLINT
+}
+
+
+TEST(Single_NormalizedBoundaries) {
+  uint64_t kOne64 = 1;
+  DiyFp boundary_plus;
+  DiyFp boundary_minus;
+  DiyFp diy_fp = Single(1.5f).AsDiyFp();
+  diy_fp.Normalize();
+  Single(1.5f).NormalizedBoundaries(&boundary_minus, &boundary_plus);
+  CHECK_EQ(diy_fp.e(), boundary_minus.e());
+  CHECK_EQ(diy_fp.e(), boundary_plus.e());
+  // 1.5 does not have a significand of the form 2^p (for some p).
+  // Therefore its boundaries are at the same distance.
+  CHECK(diy_fp.f() - boundary_minus.f() == boundary_plus.f() - diy_fp.f());
+  // Normalization shifts the significand by 8 bits. Add 32 bits for the bigger
+  // data-type, and remove 1 because boundaries are at half a ULP.
+  CHECK((kOne64 << 39) == diy_fp.f() - boundary_minus.f());
+
+  diy_fp = Single(1.0f).AsDiyFp();
+  diy_fp.Normalize();
+  Single(1.0f).NormalizedBoundaries(&boundary_minus, &boundary_plus);
+  CHECK_EQ(diy_fp.e(), boundary_minus.e());
+  CHECK_EQ(diy_fp.e(), boundary_plus.e());
+  // 1.0 does have a significand of the form 2^p (for some p).
+  // Therefore its lower boundary is twice as close as the upper boundary.
+  CHECK(boundary_plus.f() - diy_fp.f() > diy_fp.f() - boundary_minus.f());
+  CHECK((kOne64 << 38) == diy_fp.f() - boundary_minus.f());  // NOLINT
+  CHECK((kOne64 << 39) == boundary_plus.f() - diy_fp.f());  // NOLINT
+
+  uint32_t min_float32 = 0x00000001;
+  diy_fp = Single(min_float32).AsDiyFp();
+  diy_fp.Normalize();
+  Single(min_float32).NormalizedBoundaries(&boundary_minus, &boundary_plus);
+  CHECK_EQ(diy_fp.e(), boundary_minus.e());
+  CHECK_EQ(diy_fp.e(), boundary_plus.e());
+  // min-value does not have a significand of the form 2^p (for some p).
+  // Therefore its boundaries are at the same distance.
+  CHECK(diy_fp.f() - boundary_minus.f() == boundary_plus.f() - diy_fp.f());
+  // Denormals have their boundaries much closer.
+  CHECK((kOne64 << 62) == diy_fp.f() - boundary_minus.f());  // NOLINT
+
+  uint32_t smallest_normal32 = 0x00800000;
+  diy_fp = Single(smallest_normal32).AsDiyFp();
+  diy_fp.Normalize();
+  Single(smallest_normal32).NormalizedBoundaries(&boundary_minus,
+                                                 &boundary_plus);
+  CHECK_EQ(diy_fp.e(), boundary_minus.e());
+  CHECK_EQ(diy_fp.e(), boundary_plus.e());
+  // Even though the significand is of the form 2^p (for some p), its boundaries
+  // are at the same distance. (This is the only exception).
+  CHECK(diy_fp.f() - boundary_minus.f() == boundary_plus.f() - diy_fp.f());
+  CHECK((kOne64 << 39) == diy_fp.f() - boundary_minus.f());  // NOLINT
+
+  uint32_t largest_denormal32 = 0x007FFFFF;
+  diy_fp = Single(largest_denormal32).AsDiyFp();
+  diy_fp.Normalize();
+  Single(largest_denormal32).NormalizedBoundaries(&boundary_minus,
+                                                  &boundary_plus);
+  CHECK_EQ(diy_fp.e(), boundary_minus.e());
+  CHECK_EQ(diy_fp.e(), boundary_plus.e());
+  CHECK(diy_fp.f() - boundary_minus.f() == boundary_plus.f() - diy_fp.f());
+  CHECK((kOne64 << 40) == diy_fp.f() - boundary_minus.f());  // NOLINT
+
+  uint32_t max_float32 = 0x7f7fffff;
+  diy_fp = Single(max_float32).AsDiyFp();
+  diy_fp.Normalize();
+  Single(max_float32).NormalizedBoundaries(&boundary_minus, &boundary_plus);
+  CHECK_EQ(diy_fp.e(), boundary_minus.e());
+  CHECK_EQ(diy_fp.e(), boundary_plus.e());
+  // max-value does not have a significand of the form 2^p (for some p).
+  // Therefore its boundaries are at the same distance.
+  CHECK(diy_fp.f() - boundary_minus.f() == boundary_plus.f() - diy_fp.f());
+  CHECK((kOne64 << 39) == diy_fp.f() - boundary_minus.f());  // NOLINT
+}
+
+
+TEST(NextDouble) {
+  CHECK_EQ(4e-324, Double(0.0).NextDouble());
+  CHECK_EQ(0.0, Double(-0.0).NextDouble());
+  CHECK_EQ(-0.0, Double(-4e-324).NextDouble());
+  CHECK(Double(Double(-0.0).NextDouble()).Sign() > 0);
+  CHECK(Double(Double(-4e-324).NextDouble()).Sign() < 0);
+  Double d0(-4e-324);
+  Double d1(d0.NextDouble());
+  Double d2(d1.NextDouble());
+  CHECK_EQ(-0.0, d1.value());
+  CHECK(d1.Sign() < 0);
+  CHECK_EQ(0.0, d2.value());
+  CHECK(d2.Sign() > 0);
+  CHECK_EQ(4e-324, d2.NextDouble());
+  CHECK_EQ(-1.7976931348623157e308, Double(-Double::Infinity()).NextDouble());
+  CHECK_EQ(Double::Infinity(),
+           Double(UINT64_2PART_C(0x7fefffff, ffffffff)).NextDouble());
+}
+
+
+TEST(PreviousDouble) {
+  CHECK_EQ(0.0, Double(4e-324).PreviousDouble());
+  CHECK_EQ(-0.0, Double(0.0).PreviousDouble());
+  CHECK(Double(Double(0.0).PreviousDouble()).Sign() < 0);
+  CHECK_EQ(-4e-324, Double(-0.0).PreviousDouble());
+  Double d0(4e-324);
+  Double d1(d0.PreviousDouble());
+  Double d2(d1.PreviousDouble());
+  CHECK_EQ(0.0, d1.value());
+  CHECK(d1.Sign() > 0);
+  CHECK_EQ(-0.0, d2.value());
+  CHECK(d2.Sign() < 0);
+  CHECK_EQ(-4e-324, d2.PreviousDouble());
+  CHECK_EQ(1.7976931348623157e308, Double(Double::Infinity()).PreviousDouble());
+  CHECK_EQ(-Double::Infinity(),
+           Double(UINT64_2PART_C(0xffefffff, ffffffff)).PreviousDouble());
+}

+ 751 - 0
third-party/double-conversion-1.1.6/test/cctest/test-strtod.cc

@@ -0,0 +1,751 @@
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
+
+#include <stdlib.h>
+
+#include "bignum.h"
+#include "cctest.h"
+#include "diy-fp.h"
+#include "ieee.h"
+#include "strtod.h"
+#include "utils.h"
+
+using namespace double_conversion;
+
+static Vector<const char> StringToVector(const char* str) {
+  return Vector<const char>(str, strlen(str));
+}
+
+
+static double StrtodChar(const char* str, int exponent) {
+  return Strtod(StringToVector(str), exponent);
+}
+
+
+static float StrtofChar(const char* str, int exponent) {
+  return Strtof(StringToVector(str), exponent);
+}
+
+
+TEST(Strtod) {
+  Vector<const char> vector;
+
+  vector = StringToVector("0");
+  CHECK_EQ(0.0, Strtod(vector, 1));
+  CHECK_EQ(0.0, Strtod(vector, 2));
+  CHECK_EQ(0.0, Strtod(vector, -2));
+  CHECK_EQ(0.0, Strtod(vector, -999));
+  CHECK_EQ(0.0, Strtod(vector, +999));
+
+  vector = StringToVector("1");
+  CHECK_EQ(1.0, Strtod(vector, 0));
+  CHECK_EQ(10.0, Strtod(vector, 1));
+  CHECK_EQ(100.0, Strtod(vector, 2));
+  CHECK_EQ(1e20, Strtod(vector, 20));
+  CHECK_EQ(1e22, Strtod(vector, 22));
+  CHECK_EQ(1e23, Strtod(vector, 23));
+  CHECK_EQ(1e35, Strtod(vector, 35));
+  CHECK_EQ(1e36, Strtod(vector, 36));
+  CHECK_EQ(1e37, Strtod(vector, 37));
+  CHECK_EQ(1e-1, Strtod(vector, -1));
+  CHECK_EQ(1e-2, Strtod(vector, -2));
+  CHECK_EQ(1e-5, Strtod(vector, -5));
+  CHECK_EQ(1e-20, Strtod(vector, -20));
+  CHECK_EQ(1e-22, Strtod(vector, -22));
+  CHECK_EQ(1e-23, Strtod(vector, -23));
+  CHECK_EQ(1e-25, Strtod(vector, -25));
+  CHECK_EQ(1e-39, Strtod(vector, -39));
+
+  vector = StringToVector("2");
+  CHECK_EQ(2.0, Strtod(vector, 0));
+  CHECK_EQ(20.0, Strtod(vector, 1));
+  CHECK_EQ(200.0, Strtod(vector, 2));
+  CHECK_EQ(2e20, Strtod(vector, 20));
+  CHECK_EQ(2e22, Strtod(vector, 22));
+  CHECK_EQ(2e23, Strtod(vector, 23));
+  CHECK_EQ(2e35, Strtod(vector, 35));
+  CHECK_EQ(2e36, Strtod(vector, 36));
+  CHECK_EQ(2e37, Strtod(vector, 37));
+  CHECK_EQ(2e-1, Strtod(vector, -1));
+  CHECK_EQ(2e-2, Strtod(vector, -2));
+  CHECK_EQ(2e-5, Strtod(vector, -5));
+  CHECK_EQ(2e-20, Strtod(vector, -20));
+  CHECK_EQ(2e-22, Strtod(vector, -22));
+  CHECK_EQ(2e-23, Strtod(vector, -23));
+  CHECK_EQ(2e-25, Strtod(vector, -25));
+  CHECK_EQ(2e-39, Strtod(vector, -39));
+
+  vector = StringToVector("9");
+  CHECK_EQ(9.0, Strtod(vector, 0));
+  CHECK_EQ(90.0, Strtod(vector, 1));
+  CHECK_EQ(900.0, Strtod(vector, 2));
+  CHECK_EQ(9e20, Strtod(vector, 20));
+  CHECK_EQ(9e22, Strtod(vector, 22));
+  CHECK_EQ(9e23, Strtod(vector, 23));
+  CHECK_EQ(9e35, Strtod(vector, 35));
+  CHECK_EQ(9e36, Strtod(vector, 36));
+  CHECK_EQ(9e37, Strtod(vector, 37));
+  CHECK_EQ(9e-1, Strtod(vector, -1));
+  CHECK_EQ(9e-2, Strtod(vector, -2));
+  CHECK_EQ(9e-5, Strtod(vector, -5));
+  CHECK_EQ(9e-20, Strtod(vector, -20));
+  CHECK_EQ(9e-22, Strtod(vector, -22));
+  CHECK_EQ(9e-23, Strtod(vector, -23));
+  CHECK_EQ(9e-25, Strtod(vector, -25));
+  CHECK_EQ(9e-39, Strtod(vector, -39));
+
+  vector = StringToVector("12345");
+  CHECK_EQ(12345.0, Strtod(vector, 0));
+  CHECK_EQ(123450.0, Strtod(vector, 1));
+  CHECK_EQ(1234500.0, Strtod(vector, 2));
+  CHECK_EQ(12345e20, Strtod(vector, 20));
+  CHECK_EQ(12345e22, Strtod(vector, 22));
+  CHECK_EQ(12345e23, Strtod(vector, 23));
+  CHECK_EQ(12345e30, Strtod(vector, 30));
+  CHECK_EQ(12345e31, Strtod(vector, 31));
+  CHECK_EQ(12345e32, Strtod(vector, 32));
+  CHECK_EQ(12345e35, Strtod(vector, 35));
+  CHECK_EQ(12345e36, Strtod(vector, 36));
+  CHECK_EQ(12345e37, Strtod(vector, 37));
+  CHECK_EQ(12345e-1, Strtod(vector, -1));
+  CHECK_EQ(12345e-2, Strtod(vector, -2));
+  CHECK_EQ(12345e-5, Strtod(vector, -5));
+  CHECK_EQ(12345e-20, Strtod(vector, -20));
+  CHECK_EQ(12345e-22, Strtod(vector, -22));
+  CHECK_EQ(12345e-23, Strtod(vector, -23));
+  CHECK_EQ(12345e-25, Strtod(vector, -25));
+  CHECK_EQ(12345e-39, Strtod(vector, -39));
+
+  vector = StringToVector("12345678901234");
+  CHECK_EQ(12345678901234.0, Strtod(vector, 0));
+  CHECK_EQ(123456789012340.0, Strtod(vector, 1));
+  CHECK_EQ(1234567890123400.0, Strtod(vector, 2));
+  CHECK_EQ(12345678901234e20, Strtod(vector, 20));
+  CHECK_EQ(12345678901234e22, Strtod(vector, 22));
+  CHECK_EQ(12345678901234e23, Strtod(vector, 23));
+  CHECK_EQ(12345678901234e30, Strtod(vector, 30));
+  CHECK_EQ(12345678901234e31, Strtod(vector, 31));
+  CHECK_EQ(12345678901234e32, Strtod(vector, 32));
+  CHECK_EQ(12345678901234e35, Strtod(vector, 35));
+  CHECK_EQ(12345678901234e36, Strtod(vector, 36));
+  CHECK_EQ(12345678901234e37, Strtod(vector, 37));
+  CHECK_EQ(12345678901234e-1, Strtod(vector, -1));
+  CHECK_EQ(12345678901234e-2, Strtod(vector, -2));
+  CHECK_EQ(12345678901234e-5, Strtod(vector, -5));
+  CHECK_EQ(12345678901234e-20, Strtod(vector, -20));
+  CHECK_EQ(12345678901234e-22, Strtod(vector, -22));
+  CHECK_EQ(12345678901234e-23, Strtod(vector, -23));
+  CHECK_EQ(12345678901234e-25, Strtod(vector, -25));
+  CHECK_EQ(12345678901234e-39, Strtod(vector, -39));
+
+  vector = StringToVector("123456789012345");
+  CHECK_EQ(123456789012345.0, Strtod(vector, 0));
+  CHECK_EQ(1234567890123450.0, Strtod(vector, 1));
+  CHECK_EQ(12345678901234500.0, Strtod(vector, 2));
+  CHECK_EQ(123456789012345e20, Strtod(vector, 20));
+  CHECK_EQ(123456789012345e22, Strtod(vector, 22));
+  CHECK_EQ(123456789012345e23, Strtod(vector, 23));
+  CHECK_EQ(123456789012345e35, Strtod(vector, 35));
+  CHECK_EQ(123456789012345e36, Strtod(vector, 36));
+  CHECK_EQ(123456789012345e37, Strtod(vector, 37));
+  CHECK_EQ(123456789012345e39, Strtod(vector, 39));
+  CHECK_EQ(123456789012345e-1, Strtod(vector, -1));
+  CHECK_EQ(123456789012345e-2, Strtod(vector, -2));
+  CHECK_EQ(123456789012345e-5, Strtod(vector, -5));
+  CHECK_EQ(123456789012345e-20, Strtod(vector, -20));
+  CHECK_EQ(123456789012345e-22, Strtod(vector, -22));
+  CHECK_EQ(123456789012345e-23, Strtod(vector, -23));
+  CHECK_EQ(123456789012345e-25, Strtod(vector, -25));
+  CHECK_EQ(123456789012345e-39, Strtod(vector, -39));
+
+  CHECK_EQ(0.0, StrtodChar("0", 12345));
+  CHECK_EQ(0.0, StrtodChar("", 1324));
+  CHECK_EQ(0.0, StrtodChar("000000000", 123));
+  CHECK_EQ(0.0, StrtodChar("2", -324));
+  CHECK_EQ(4e-324, StrtodChar("3", -324));
+  // It would be more readable to put non-zero literals on the left side (i.e.
+  //   CHECK_EQ(1e-325, StrtodChar("1", -325))), but then Gcc complains that
+  // they are truncated to zero.
+  CHECK_EQ(0.0, StrtodChar("1", -325));
+  CHECK_EQ(0.0, StrtodChar("1", -325));
+  CHECK_EQ(0.0, StrtodChar("20000", -328));
+  CHECK_EQ(40000e-328, StrtodChar("30000", -328));
+  CHECK_EQ(0.0, StrtodChar("10000", -329));
+  CHECK_EQ(0.0, StrtodChar("90000", -329));
+  CHECK_EQ(0.0, StrtodChar("000000001", -325));
+  CHECK_EQ(0.0, StrtodChar("000000001", -325));
+  CHECK_EQ(0.0, StrtodChar("0000000020000", -328));
+  CHECK_EQ(40000e-328, StrtodChar("00000030000", -328));
+  CHECK_EQ(0.0, StrtodChar("0000000010000", -329));
+  CHECK_EQ(0.0, StrtodChar("0000000090000", -329));
+
+  // It would be more readable to put the literals (and not Double::Infinity())
+  // on the left side (i.e. CHECK_EQ(1e309, StrtodChar("1", 309))), but then Gcc
+  // complains that the floating constant exceeds range of 'double'.
+  CHECK_EQ(Double::Infinity(), StrtodChar("1", 309));
+  CHECK_EQ(1e308, StrtodChar("1", 308));
+  CHECK_EQ(1234e305, StrtodChar("1234", 305));
+  CHECK_EQ(1234e304, StrtodChar("1234", 304));
+  CHECK_EQ(Double::Infinity(), StrtodChar("18", 307));
+  CHECK_EQ(17e307, StrtodChar("17", 307));
+  CHECK_EQ(Double::Infinity(), StrtodChar("0000001", 309));
+  CHECK_EQ(1e308, StrtodChar("00000001", 308));
+  CHECK_EQ(1234e305, StrtodChar("00000001234", 305));
+  CHECK_EQ(1234e304, StrtodChar("000000001234", 304));
+  CHECK_EQ(Double::Infinity(), StrtodChar("0000000018", 307));
+  CHECK_EQ(17e307, StrtodChar("0000000017", 307));
+  CHECK_EQ(Double::Infinity(), StrtodChar("1000000", 303));
+  CHECK_EQ(1e308, StrtodChar("100000", 303));
+  CHECK_EQ(1234e305, StrtodChar("123400000", 300));
+  CHECK_EQ(1234e304, StrtodChar("123400000", 299));
+  CHECK_EQ(Double::Infinity(), StrtodChar("180000000", 300));
+  CHECK_EQ(17e307, StrtodChar("170000000", 300));
+  CHECK_EQ(Double::Infinity(), StrtodChar("00000001000000", 303));
+  CHECK_EQ(1e308, StrtodChar("000000000000100000", 303));
+  CHECK_EQ(1234e305, StrtodChar("00000000123400000", 300));
+  CHECK_EQ(1234e304, StrtodChar("0000000123400000", 299));
+  CHECK_EQ(Double::Infinity(), StrtodChar("00000000180000000", 300));
+  CHECK_EQ(17e307, StrtodChar("00000000170000000", 300));
+  CHECK_EQ(1.7976931348623157E+308, StrtodChar("17976931348623157", 292));
+  CHECK_EQ(1.7976931348623158E+308, StrtodChar("17976931348623158", 292));
+  CHECK_EQ(Double::Infinity(), StrtodChar("17976931348623159", 292));
+
+  // The following number is the result of 89255.0/1e-22. Both floating-point
+  // numbers can be accurately represented with doubles. However on Linux,x86
+  // the floating-point stack is set to 80bits and the double-rounding
+  // introduces an error.
+  CHECK_EQ(89255e-22, StrtodChar("89255", -22));
+
+  // Some random values.
+  CHECK_EQ(358416272e-33, StrtodChar("358416272", -33));
+  CHECK_EQ(104110013277974872254e-225,
+           StrtodChar("104110013277974872254", -225));
+
+  CHECK_EQ(123456789e108, StrtodChar("123456789", 108));
+  CHECK_EQ(123456789e109, StrtodChar("123456789", 109));
+  CHECK_EQ(123456789e110, StrtodChar("123456789", 110));
+  CHECK_EQ(123456789e111, StrtodChar("123456789", 111));
+  CHECK_EQ(123456789e112, StrtodChar("123456789", 112));
+  CHECK_EQ(123456789e113, StrtodChar("123456789", 113));
+  CHECK_EQ(123456789e114, StrtodChar("123456789", 114));
+  CHECK_EQ(123456789e115, StrtodChar("123456789", 115));
+
+  CHECK_EQ(1234567890123456789012345e108,
+           StrtodChar("1234567890123456789012345", 108));
+  CHECK_EQ(1234567890123456789012345e109,
+           StrtodChar("1234567890123456789012345", 109));
+  CHECK_EQ(1234567890123456789012345e110,
+           StrtodChar("1234567890123456789012345", 110));
+  CHECK_EQ(1234567890123456789012345e111,
+           StrtodChar("1234567890123456789012345", 111));
+  CHECK_EQ(1234567890123456789012345e112,
+           StrtodChar("1234567890123456789012345", 112));
+  CHECK_EQ(1234567890123456789012345e113,
+           StrtodChar("1234567890123456789012345", 113));
+  CHECK_EQ(1234567890123456789012345e114,
+           StrtodChar("1234567890123456789012345", 114));
+  CHECK_EQ(1234567890123456789012345e115,
+           StrtodChar("1234567890123456789012345", 115));
+
+  CHECK_EQ(1234567890123456789052345e108,
+           StrtodChar("1234567890123456789052345", 108));
+  CHECK_EQ(1234567890123456789052345e109,
+           StrtodChar("1234567890123456789052345", 109));
+  CHECK_EQ(1234567890123456789052345e110,
+           StrtodChar("1234567890123456789052345", 110));
+  CHECK_EQ(1234567890123456789052345e111,
+           StrtodChar("1234567890123456789052345", 111));
+  CHECK_EQ(1234567890123456789052345e112,
+           StrtodChar("1234567890123456789052345", 112));
+  CHECK_EQ(1234567890123456789052345e113,
+           StrtodChar("1234567890123456789052345", 113));
+  CHECK_EQ(1234567890123456789052345e114,
+           StrtodChar("1234567890123456789052345", 114));
+  CHECK_EQ(1234567890123456789052345e115,
+           StrtodChar("1234567890123456789052345", 115));
+
+  CHECK_EQ(5.445618932859895e-255,
+           StrtodChar("5445618932859895362967233318697132813618813095743952975"
+                      "4392982234069699615600475529427176366709107287468930197"
+                      "8628345413991790019316974825934906752493984055268219809"
+                      "5012176093045431437495773903922425632551857520884625114"
+                      "6241265881735209066709685420744388526014389929047617597"
+                      "0302268848374508109029268898695825171158085457567481507"
+                      "4162979705098246243690189880319928315307816832576838178"
+                      "2563074014542859888710209237525873301724479666744537857"
+                      "9026553346649664045621387124193095870305991178772256504"
+                      "4368663670643970181259143319016472430928902201239474588"
+                      "1392338901353291306607057623202353588698746085415097902"
+                      "6640064319118728664842287477491068264828851624402189317"
+                      "2769161449825765517353755844373640588822904791244190695"
+                      "2998382932630754670573838138825217065450843010498555058"
+                      "88186560731", -1035));
+
+  // Boundary cases. Boundaries themselves should round to even.
+  //
+  // 0x1FFFFFFFFFFFF * 2^3 = 72057594037927928
+  //                   next: 72057594037927936
+  //               boundary: 72057594037927932  should round up.
+  CHECK_EQ(72057594037927928.0, StrtodChar("72057594037927928", 0));
+  CHECK_EQ(72057594037927936.0, StrtodChar("72057594037927936", 0));
+  CHECK_EQ(72057594037927936.0, StrtodChar("72057594037927932", 0));
+  CHECK_EQ(72057594037927928.0, StrtodChar("7205759403792793199999", -5));
+  CHECK_EQ(72057594037927936.0, StrtodChar("7205759403792793200001", -5));
+
+  // 0x1FFFFFFFFFFFF * 2^10 = 9223372036854774784
+  //                    next: 9223372036854775808
+  //                boundary: 9223372036854775296 should round up.
+  CHECK_EQ(9223372036854774784.0, StrtodChar("9223372036854774784", 0));
+  CHECK_EQ(9223372036854775808.0, StrtodChar("9223372036854775808", 0));
+  CHECK_EQ(9223372036854775808.0, StrtodChar("9223372036854775296", 0));
+  CHECK_EQ(9223372036854774784.0, StrtodChar("922337203685477529599999", -5));
+  CHECK_EQ(9223372036854775808.0, StrtodChar("922337203685477529600001", -5));
+
+  // 0x1FFFFFFFFFFFF * 2^50 = 10141204801825834086073718800384
+  //                    next: 10141204801825835211973625643008
+  //                boundary: 10141204801825834649023672221696 should round up.
+  CHECK_EQ(10141204801825834086073718800384.0,
+           StrtodChar("10141204801825834086073718800384", 0));
+  CHECK_EQ(10141204801825835211973625643008.0,
+           StrtodChar("10141204801825835211973625643008", 0));
+  CHECK_EQ(10141204801825835211973625643008.0,
+           StrtodChar("10141204801825834649023672221696", 0));
+  CHECK_EQ(10141204801825834086073718800384.0,
+           StrtodChar("1014120480182583464902367222169599999", -5));
+  CHECK_EQ(10141204801825835211973625643008.0,
+           StrtodChar("1014120480182583464902367222169600001", -5));
+
+  // 0x1FFFFFFFFFFFF * 2^99 = 5708990770823838890407843763683279797179383808
+  //                    next: 5708990770823839524233143877797980545530986496
+  //                boundary: 5708990770823839207320493820740630171355185152
+  // The boundary should round up.
+  CHECK_EQ(5708990770823838890407843763683279797179383808.0,
+           StrtodChar("5708990770823838890407843763683279797179383808", 0));
+  CHECK_EQ(5708990770823839524233143877797980545530986496.0,
+           StrtodChar("5708990770823839524233143877797980545530986496", 0));
+  CHECK_EQ(5708990770823839524233143877797980545530986496.0,
+           StrtodChar("5708990770823839207320493820740630171355185152", 0));
+  CHECK_EQ(5708990770823838890407843763683279797179383808.0,
+           StrtodChar("5708990770823839207320493820740630171355185151999", -3));
+  CHECK_EQ(5708990770823839524233143877797980545530986496.0,
+           StrtodChar("5708990770823839207320493820740630171355185152001", -3));
+
+  // The following test-cases got some public attention in early 2011 when they
+  // sent Java and PHP into an infinite loop.
+  CHECK_EQ(2.225073858507201e-308, StrtodChar("22250738585072011", -324));
+  CHECK_EQ(2.22507385850720138309e-308,
+           StrtodChar("22250738585072011360574097967091319759348195463516456480"
+                      "23426109724822222021076945516529523908135087914149158913"
+                      "03962110687008643869459464552765720740782062174337998814"
+                      "10632673292535522868813721490129811224514518898490572223"
+                      "07285255133155755015914397476397983411801999323962548289"
+                      "01710708185069063066665599493827577257201576306269066333"
+                      "26475653000092458883164330377797918696120494973903778297"
+                      "04905051080609940730262937128958950003583799967207254304"
+                      "36028407889577179615094551674824347103070260914462157228"
+                      "98802581825451803257070188608721131280795122334262883686"
+                      "22321503775666622503982534335974568884423900265498198385"
+                      "48794829220689472168983109969836584681402285424333066033"
+                      "98508864458040010349339704275671864433837704860378616227"
+                      "71738545623065874679014086723327636718751", -1076));
+}
+
+
+TEST(Strtof) {
+  Vector<const char> vector;
+
+  vector = StringToVector("0");
+  CHECK_EQ(0.0f, Strtof(vector, 1));
+  CHECK_EQ(0.0f, Strtof(vector, 2));
+  CHECK_EQ(0.0f, Strtof(vector, -2));
+  CHECK_EQ(0.0f, Strtof(vector, -999));
+  CHECK_EQ(0.0f, Strtof(vector, +999));
+
+  vector = StringToVector("1");
+  CHECK_EQ(1.0f, Strtof(vector, 0));
+  CHECK_EQ(10.0f, Strtof(vector, 1));
+  CHECK_EQ(100.0f, Strtof(vector, 2));
+  CHECK_EQ(1e20f, Strtof(vector, 20));
+  CHECK_EQ(1e22f, Strtof(vector, 22));
+  CHECK_EQ(1e23f, Strtof(vector, 23));
+  CHECK_EQ(1e35f, Strtof(vector, 35));
+  CHECK_EQ(1e36f, Strtof(vector, 36));
+  CHECK_EQ(1e37f, Strtof(vector, 37));
+  CHECK_EQ(1e-1f, Strtof(vector, -1));
+  CHECK_EQ(1e-2f, Strtof(vector, -2));
+  CHECK_EQ(1e-5f, Strtof(vector, -5));
+  CHECK_EQ(1e-20f, Strtof(vector, -20));
+  CHECK_EQ(1e-22f, Strtof(vector, -22));
+  CHECK_EQ(1e-23f, Strtof(vector, -23));
+  CHECK_EQ(1e-25f, Strtof(vector, -25));
+  CHECK_EQ(1e-39f, Strtof(vector, -39));
+
+  vector = StringToVector("2");
+  CHECK_EQ(2.0f, Strtof(vector, 0));
+  CHECK_EQ(20.0f, Strtof(vector, 1));
+  CHECK_EQ(200.0f, Strtof(vector, 2));
+  CHECK_EQ(2e20f, Strtof(vector, 20));
+  CHECK_EQ(2e22f, Strtof(vector, 22));
+  CHECK_EQ(2e23f, Strtof(vector, 23));
+  CHECK_EQ(2e35f, Strtof(vector, 35));
+  CHECK_EQ(2e36f, Strtof(vector, 36));
+  CHECK_EQ(2e37f, Strtof(vector, 37));
+  CHECK_EQ(2e-1f, Strtof(vector, -1));
+  CHECK_EQ(2e-2f, Strtof(vector, -2));
+  CHECK_EQ(2e-5f, Strtof(vector, -5));
+  CHECK_EQ(2e-20f, Strtof(vector, -20));
+  CHECK_EQ(2e-22f, Strtof(vector, -22));
+  CHECK_EQ(2e-23f, Strtof(vector, -23));
+  CHECK_EQ(2e-25f, Strtof(vector, -25));
+  CHECK_EQ(2e-39f, Strtof(vector, -39));
+
+  vector = StringToVector("9");
+  CHECK_EQ(9.0f, Strtof(vector, 0));
+  CHECK_EQ(90.0f, Strtof(vector, 1));
+  CHECK_EQ(900.0f, Strtof(vector, 2));
+  CHECK_EQ(9e20f, Strtof(vector, 20));
+  CHECK_EQ(9e22f, Strtof(vector, 22));
+  CHECK_EQ(9e23f, Strtof(vector, 23));
+  CHECK_EQ(9e35f, Strtof(vector, 35));
+  CHECK_EQ(9e36f, Strtof(vector, 36));
+  CHECK_EQ(9e37f, Strtof(vector, 37));
+  CHECK_EQ(9e-1f, Strtof(vector, -1));
+  CHECK_EQ(9e-2f, Strtof(vector, -2));
+  CHECK_EQ(9e-5f, Strtof(vector, -5));
+  CHECK_EQ(9e-20f, Strtof(vector, -20));
+  CHECK_EQ(9e-22f, Strtof(vector, -22));
+  CHECK_EQ(9e-23f, Strtof(vector, -23));
+  CHECK_EQ(9e-25f, Strtof(vector, -25));
+  CHECK_EQ(9e-39f, Strtof(vector, -39));
+
+  vector = StringToVector("12345");
+  CHECK_EQ(12345.0f, Strtof(vector, 0));
+  CHECK_EQ(123450.0f, Strtof(vector, 1));
+  CHECK_EQ(1234500.0f, Strtof(vector, 2));
+  CHECK_EQ(12345e20f, Strtof(vector, 20));
+  CHECK_EQ(12345e22f, Strtof(vector, 22));
+  CHECK_EQ(12345e23f, Strtof(vector, 23));
+  CHECK_EQ(12345e30f, Strtof(vector, 30));
+  CHECK_EQ(12345e31f, Strtof(vector, 31));
+  CHECK_EQ(12345e32f, Strtof(vector, 32));
+  CHECK_EQ(12345e-1f, Strtof(vector, -1));
+  CHECK_EQ(12345e-2f, Strtof(vector, -2));
+  CHECK_EQ(12345e-5f, Strtof(vector, -5));
+  CHECK_EQ(12345e-20f, Strtof(vector, -20));
+  CHECK_EQ(12345e-22f, Strtof(vector, -22));
+  CHECK_EQ(12345e-23f, Strtof(vector, -23));
+  CHECK_EQ(12345e-25f, Strtof(vector, -25));
+  CHECK_EQ(12345e-39f, Strtof(vector, -39));
+
+  vector = StringToVector("12345678901234");
+  CHECK_EQ(12345678901234.0f, Strtof(vector, 0));
+  CHECK_EQ(123456789012340.0f, Strtof(vector, 1));
+  CHECK_EQ(1234567890123400.0f, Strtof(vector, 2));
+  CHECK_EQ(12345678901234e20f, Strtof(vector, 20));
+  CHECK_EQ(12345678901234e22f, Strtof(vector, 22));
+  CHECK_EQ(12345678901234e23f, Strtof(vector, 23));
+  CHECK_EQ(12345678901234e-1f, Strtof(vector, -1));
+  CHECK_EQ(12345678901234e-2f, Strtof(vector, -2));
+  CHECK_EQ(12345678901234e-5f, Strtof(vector, -5));
+  CHECK_EQ(12345678901234e-20f, Strtof(vector, -20));
+  CHECK_EQ(12345678901234e-22f, Strtof(vector, -22));
+  CHECK_EQ(12345678901234e-23f, Strtof(vector, -23));
+  CHECK_EQ(12345678901234e-25f, Strtof(vector, -25));
+  CHECK_EQ(12345678901234e-39f, Strtof(vector, -39));
+
+  vector = StringToVector("123456789012345");
+  CHECK_EQ(123456789012345.0f, Strtof(vector, 0));
+  CHECK_EQ(1234567890123450.0f, Strtof(vector, 1));
+  CHECK_EQ(12345678901234500.0f, Strtof(vector, 2));
+  CHECK_EQ(123456789012345e20f, Strtof(vector, 20));
+  CHECK_EQ(123456789012345e22f, Strtof(vector, 22));
+  CHECK_EQ(123456789012345e23f, Strtof(vector, 23));
+  CHECK_EQ(123456789012345e-1f, Strtof(vector, -1));
+  CHECK_EQ(123456789012345e-2f, Strtof(vector, -2));
+  CHECK_EQ(123456789012345e-5f, Strtof(vector, -5));
+  CHECK_EQ(123456789012345e-20f, Strtof(vector, -20));
+  CHECK_EQ(123456789012345e-22f, Strtof(vector, -22));
+  CHECK_EQ(123456789012345e-23f, Strtof(vector, -23));
+  CHECK_EQ(123456789012345e-25f, Strtof(vector, -25));
+  CHECK_EQ(123456789012345e-39f, Strtof(vector, -39));
+
+  CHECK_EQ(0.0f, StrtofChar("0", 12345));
+  CHECK_EQ(0.0f, StrtofChar("", 1324));
+  CHECK_EQ(0.0f, StrtofChar("000000000", 123));
+  CHECK_EQ(0.0f, StrtofChar("2", -324));
+  CHECK_EQ(1e-45f, StrtofChar("1", -45));
+  // It would be more readable to put non-zero literals on the left side (i.e.
+  //   CHECK_EQ(1e-46, StrtofChar("1", -45))), but then Gcc complains that
+  // they are truncated to zero.
+  CHECK_EQ(0.0f, StrtofChar("1", -46));
+  CHECK_EQ(0.0f, StrtofChar("1", -47));
+  CHECK_EQ(1e-45f, StrtofChar("1", -45));
+  CHECK_EQ(1e-45f, StrtofChar("8", -46));
+  CHECK_EQ(0.0f, StrtofChar("200000", -51));
+  CHECK_EQ(100000e-50f, StrtofChar("100000", -50));
+  CHECK_EQ(0.0f, StrtofChar("100000", -51));
+  CHECK_EQ(0.0f, StrtofChar("900000", -52));
+  CHECK_EQ(0.0f, StrtofChar("000000001", -47));
+  CHECK_EQ(0.0f, StrtofChar("000000001", -47));
+  CHECK_EQ(0.0f, StrtofChar("00000000200000", -51));
+  CHECK_EQ(800000e-50f, StrtofChar("000000800000", -50));
+  CHECK_EQ(0.0f, StrtofChar("00000000100000", -51));
+  CHECK_EQ(1e-45f, StrtofChar("00000000900000", -51));
+
+  // It would be more readable to put the literals (and not Double::Infinity())
+  // on the left side (i.e. CHECK_EQ(3e38, StrtofChar("3", 38))), but then Gcc
+  // complains that the floating constant exceeds range of 'double'.
+  CHECK_EQ(Single::Infinity(), StrtofChar("3", 39));
+  CHECK_EQ(3e38f, StrtofChar("3", 38));
+  CHECK_EQ(3401e35f, StrtofChar("3401", 35));
+  CHECK_EQ(3401e34f, StrtofChar("3401", 34));
+  CHECK_EQ(Single::Infinity(), StrtofChar("3410", 35));
+  CHECK_EQ(34e37f, StrtofChar("34", 37));
+  CHECK_EQ(Single::Infinity(), StrtofChar("0000001", 39));
+  CHECK_EQ(3401e35f, StrtofChar("0000003401", 35));
+  CHECK_EQ(3401e34f, StrtofChar("0000003401", 34));
+  CHECK_EQ(Single::Infinity(), StrtofChar("0000003410", 35));
+  CHECK_EQ(34e37f, StrtofChar("00000034", 37));
+  CHECK_EQ(1e38f, StrtofChar("100000", 33));
+  CHECK_EQ(3401e35f, StrtofChar("340100000", 30));
+  CHECK_EQ(3401e34f, StrtofChar("340100000", 29));
+  CHECK_EQ(Single::Infinity(), StrtofChar("341000000", 30));
+  CHECK_EQ(34e37f, StrtofChar("3400000", 32));
+  CHECK_EQ(1e38f, StrtofChar("00000100000", 33));
+  CHECK_EQ(3401e35f, StrtofChar("00000340100000", 30));
+  CHECK_EQ(3401e34f, StrtofChar("00000340100000", 29));
+  CHECK_EQ(Single::Infinity(), StrtofChar("00000341000000", 30));
+  CHECK_EQ(34e37f, StrtofChar("000003400000", 32));
+  CHECK_EQ(3.4028234e+38f, StrtofChar("34028235676", 28));
+  CHECK_EQ(3.4028234e+38f, StrtofChar("34028235677", 28));
+  CHECK_EQ(Single::Infinity(), StrtofChar("34028235678", 28));
+
+  // The following number is the result of 89255.0/1e-22. Both floating-point
+  // numbers can be accurately represented with doubles. However on Linux,x86
+  // the floating-point stack is set to 80bits and the double-rounding
+  // introduces an error.
+  CHECK_EQ(89255e-22f, StrtofChar("89255", -22));
+
+  // Boundary cases. Boundaries themselves should round to even.
+  //
+  // 0x4f012334 = 2166567936
+  //      next:   2166568192
+  //  boundary:   2166568064 should round down.
+  CHECK_EQ(2166567936.0f, StrtofChar("2166567936", 0));
+  CHECK_EQ(2166568192.0f, StrtofChar("2166568192", 0));
+  CHECK_EQ(2166567936.0f, StrtofChar("2166568064", 0));
+  CHECK_EQ(2166567936.0f, StrtofChar("216656806399999", -5));
+  CHECK_EQ(2166568192.0f, StrtofChar("216656806400001", -5));
+  // Verify that we don't double round.
+  // Get the boundary of the boundary.
+  CHECK_EQ(2.1665680640000002384185791015625e9, 2166568064.0);
+  // Visual Studio gets this wrong and believes that these two numbers are the
+  // same doubles. We want to test our conversion and not the compiler. We
+  // therefore disable the check.
+#ifndef _MSC_VER
+  CHECK(2.16656806400000023841857910156251e9 != 2166568064.0);
+#endif
+  CHECK_EQ(2166568192.0f, StrtofChar("21665680640000002384185791015625", -22));
+
+  // 0x4fffffff = 8589934080
+  //      next:   8589934592
+  //  boundary:   8589934336 should round up.
+  CHECK_EQ(8589934080.0f, StrtofChar("8589934080", 0));
+  CHECK_EQ(8589934592.0f, StrtofChar("8589934592", 0));
+  CHECK_EQ(8589934592.0f, StrtofChar("8589934336", 0));
+  CHECK_EQ(8589934080.0f, StrtofChar("858993433599999", -5));
+  CHECK_EQ(8589934592.0f, StrtofChar("858993433600001", -5));
+  // Verify that we don't double round.
+  // Get the boundary of the boundary.
+  // Visual Studio gets this wrong. To avoid failing tests because of a broken
+  // compiler we disable the following two tests. They were only testing the
+  // compiler. The real test is still active.
+#ifndef _MSC_VER
+  CHECK_EQ(8.589934335999999523162841796875e+09, 8589934336.0);
+  CHECK(8.5899343359999995231628417968749e+09 != 8589934336.0);
+#endif
+  CHECK_EQ(8589934080.0f, StrtofChar("8589934335999999523162841796875", -21));
+
+  // 0x4f000000 = 2147483648
+  //      next:   2147483904
+  //  boundary:   2147483776 should round down.
+  CHECK_EQ(2147483648.0f, StrtofChar("2147483648", 0));
+  CHECK_EQ(2147483904.0f, StrtofChar("2147483904", 0));
+  CHECK_EQ(2147483648.0f, StrtofChar("2147483776", 0));
+  CHECK_EQ(2147483648.0f, StrtofChar("214748377599999", -5));
+  CHECK_EQ(2147483904.0f, StrtofChar("214748377600001", -5));
+
+}
+
+
+static int CompareBignumToDiyFp(const Bignum& bignum_digits,
+                                int bignum_exponent,
+                                DiyFp diy_fp) {
+  Bignum bignum;
+  bignum.AssignBignum(bignum_digits);
+  Bignum other;
+  other.AssignUInt64(diy_fp.f());
+  if (bignum_exponent >= 0) {
+    bignum.MultiplyByPowerOfTen(bignum_exponent);
+  } else {
+    other.MultiplyByPowerOfTen(-bignum_exponent);
+  }
+  if (diy_fp.e() >= 0) {
+    other.ShiftLeft(diy_fp.e());
+  } else {
+    bignum.ShiftLeft(-diy_fp.e());
+  }
+  return Bignum::Compare(bignum, other);
+}
+
+
+static bool CheckDouble(Vector<const char> buffer,
+                        int exponent,
+                        double to_check) {
+  DiyFp lower_boundary;
+  DiyFp upper_boundary;
+  Bignum input_digits;
+  input_digits.AssignDecimalString(buffer);
+  if (to_check == 0.0) {
+    const double kMinDouble = 4e-324;
+    // Check that the buffer*10^exponent < (0 + kMinDouble)/2.
+    Double d(kMinDouble);
+    d.NormalizedBoundaries(&lower_boundary, &upper_boundary);
+    return CompareBignumToDiyFp(input_digits, exponent, lower_boundary) <= 0;
+  }
+  if (to_check == Double::Infinity()) {
+    const double kMaxDouble = 1.7976931348623157e308;
+    // Check that the buffer*10^exponent >= boundary between kMaxDouble and inf.
+    Double d(kMaxDouble);
+    d.NormalizedBoundaries(&lower_boundary, &upper_boundary);
+    return CompareBignumToDiyFp(input_digits, exponent, upper_boundary) >= 0;
+  }
+  Double d(to_check);
+  d.NormalizedBoundaries(&lower_boundary, &upper_boundary);
+  if ((d.Significand() & 1) == 0) {
+    return CompareBignumToDiyFp(input_digits, exponent, lower_boundary) >= 0 &&
+        CompareBignumToDiyFp(input_digits, exponent, upper_boundary) <= 0;
+  } else {
+    return CompareBignumToDiyFp(input_digits, exponent, lower_boundary) > 0 &&
+        CompareBignumToDiyFp(input_digits, exponent, upper_boundary) < 0;
+  }
+}
+
+
+// Copied from v8.cc and adapted to make the function deterministic.
+static uint32_t DeterministicRandom() {
+  // Random number generator using George Marsaglia's MWC algorithm.
+  static uint32_t hi = 0;
+  static uint32_t lo = 0;
+
+  // Initialization values don't have any special meaning. (They are the result
+  // of two calls to random().)
+  if (hi == 0) hi = 0xbfe166e7;
+  if (lo == 0) lo = 0x64d1c3c9;
+
+  // Mix the bits.
+  hi = 36969 * (hi & 0xFFFF) + (hi >> 16);
+  lo = 18273 * (lo & 0xFFFF) + (lo >> 16);
+  return (hi << 16) + (lo & 0xFFFF);
+}
+
+
+static const int kBufferSize = 1024;
+static const int kShortStrtodRandomCount = 2;
+static const int kLargeStrtodRandomCount = 2;
+
+TEST(RandomStrtod) {
+  char buffer[kBufferSize];
+  for (int length = 1; length < 15; length++) {
+    for (int i = 0; i < kShortStrtodRandomCount; ++i) {
+      int pos = 0;
+      for (int j = 0; j < length; ++j) {
+        buffer[pos++] = DeterministicRandom() % 10 + '0';
+      }
+      int exponent = DeterministicRandom() % (25*2 + 1) - 25 - length;
+      buffer[pos] = '\0';
+      Vector<const char> vector(buffer, pos);
+      double strtod_result = Strtod(vector, exponent);
+      CHECK(CheckDouble(vector, exponent, strtod_result));
+    }
+  }
+  for (int length = 15; length < 800; length += 2) {
+    for (int i = 0; i < kLargeStrtodRandomCount; ++i) {
+      int pos = 0;
+      for (int j = 0; j < length; ++j) {
+        buffer[pos++] = DeterministicRandom() % 10 + '0';
+      }
+      int exponent = DeterministicRandom() % (308*2 + 1) - 308 - length;
+      buffer[pos] = '\0';
+      Vector<const char> vector(buffer, pos);
+      double strtod_result = Strtod(vector, exponent);
+      CHECK(CheckDouble(vector, exponent, strtod_result));
+    }
+  }
+}
+
+
+static bool CheckFloat(Vector<const char> buffer,
+                        int exponent,
+                        float to_check) {
+  DiyFp lower_boundary;
+  DiyFp upper_boundary;
+  Bignum input_digits;
+  input_digits.AssignDecimalString(buffer);
+  if (to_check == 0.0) {
+    const float kMinFloat = 1e-45f;
+    // Check that the buffer*10^exponent < (0 + kMinFloat)/2.
+    Single s(kMinFloat);
+    s.NormalizedBoundaries(&lower_boundary, &upper_boundary);
+    return CompareBignumToDiyFp(input_digits, exponent, lower_boundary) <= 0;
+  }
+  if (to_check == static_cast<float>(Double::Infinity())) {
+    const float kMaxFloat = 3.4028234e38f;
+    // Check that the buffer*10^exponent >= boundary between kMaxFloat and inf.
+    Single s(kMaxFloat);
+    s.NormalizedBoundaries(&lower_boundary, &upper_boundary);
+    return CompareBignumToDiyFp(input_digits, exponent, upper_boundary) >= 0;
+  }
+  Single s(to_check);
+  s.NormalizedBoundaries(&lower_boundary, &upper_boundary);
+  if ((s.Significand() & 1) == 0) {
+    return CompareBignumToDiyFp(input_digits, exponent, lower_boundary) >= 0 &&
+        CompareBignumToDiyFp(input_digits, exponent, upper_boundary) <= 0;
+  } else {
+    return CompareBignumToDiyFp(input_digits, exponent, lower_boundary) > 0 &&
+        CompareBignumToDiyFp(input_digits, exponent, upper_boundary) < 0;
+  }
+}
+
+
+static const int kShortStrtofRandomCount = 2;
+static const int kLargeStrtofRandomCount = 2;
+
+TEST(RandomStrtof) {
+  char buffer[kBufferSize];
+  for (int length = 1; length < 15; length++) {
+    for (int i = 0; i < kShortStrtofRandomCount; ++i) {
+      int pos = 0;
+      for (int j = 0; j < length; ++j) {
+        buffer[pos++] = DeterministicRandom() % 10 + '0';
+      }
+      int exponent = DeterministicRandom() % (5*2 + 1) - 5 - length;
+      buffer[pos] = '\0';
+      Vector<const char> vector(buffer, pos);
+      float strtof_result = Strtof(vector, exponent);
+      CHECK(CheckFloat(vector, exponent, strtof_result));
+    }
+  }
+  for (int length = 15; length < 800; length += 2) {
+    for (int i = 0; i < kLargeStrtofRandomCount; ++i) {
+      int pos = 0;
+      for (int j = 0; j < length; ++j) {
+        buffer[pos++] = DeterministicRandom() % 10 + '0';
+      }
+      int exponent = DeterministicRandom() % (38*2 + 1) - 38 - length;
+      buffer[pos] = '\0';
+      Vector<const char> vector(buffer, pos);
+      float strtof_result = Strtof(vector, exponent);
+      CHECK(CheckFloat(vector, exponent, strtof_result));
+    }
+  }
+}

+ 4 - 0
third-party/glog-0.3.5/.gitignore

@@ -0,0 +1,4 @@
+autom4te.cache
+glog-*.tar.gz
+packages/rpm-unknown
+packages/debian-*

+ 22 - 0
third-party/glog-0.3.5/AUTHORS

@@ -0,0 +1,22 @@
+# This is the official list of glog authors for copyright purposes.
+# This file is distinct from the CONTRIBUTORS files.
+# See the latter for an explanation.
+#
+# Names should be added to this file as:
+#	Name or Organization <email address>
+# The email address is not required for organizations.
+#
+# Please keep the list sorted.
+
+Abhishek Dasgupta <abhi2743@gmail.com>
+Abhishek Parmar <abhishek@orng.net>
+Andy Ying <andy@trailofbits.com>
+Brian Silverman <bsilver16384@gmail.com>
+Google Inc.
+Guillaume Dumont <dumont.guillaume@gmail.com>
+Michael Tanner <michael@tannertaxpro.com>
+MiniLight <MiniLightAR@Gmail.com>
+romange <romange@users.noreply.github.com>
+Sergiu Deitsch <sergiu.deitsch@gmail.com>
+tbennun <tbennun@gmail.com>
+Teddy Reed <teddy@prosauce.org>

+ 583 - 0
third-party/glog-0.3.5/CMakeLists.txt

@@ -0,0 +1,583 @@
+cmake_minimum_required (VERSION 3.0)
+
+if (POLICY CMP0042)
+  cmake_policy (SET CMP0042 NEW)
+endif (POLICY CMP0042)
+
+if (POLICY CMP0063)
+  cmake_policy (SET CMP0063 NEW)
+endif (POLICY CMP0063)
+
+project (google-glog)
+
+enable_testing ()
+
+set (GLOG_MAJOR_VERSION 0)
+set (GLOG_MINOR_VERSION 3)
+set (GLOG_PATCH_VERSION 5)
+
+set (GLOG_VERSION
+  ${GLOG_MAJOR_VERSION}.${GLOG_MINOR_VERSION}.${GLOG_PATCH_VERSION})
+
+set (CPACK_PACKAGE_NAME glog)
+set (CPACK_PACKAGE_DESCRIPTION_SUMMARY "")
+set (CPACK_PACKAGE_VERSION_MAJOR ${GLOG_MAJOR_VERSION})
+set (CPACK_PACKAGE_VERSION_MINOR ${GLOG_MINOR_VERSION})
+set (CPACK_PACKAGE_VERSION_PATCH ${GLOG_PATCH_VERSION})
+set (CPACK_PACKAGE_VERSION ${GLOG_VERSION})
+
+option (WITH_GFLAGS "Use gflags" ON)
+option (WITH_THREADS "Enable multithreading support" ON)
+
+list (APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
+
+include (CheckCSourceCompiles)
+include (CheckCXXCompilerFlag)
+include (CheckCXXSourceCompiles)
+include (CheckFunctionExists)
+include (CheckIncludeFile)
+include (CheckIncludeFileCXX)
+include (CheckLibraryExists)
+include (CheckStructHasMember)
+include (CheckSymbolExists)
+include (CheckTypeSize)
+include (CMakePackageConfigHelpers)
+include (CPack)
+include (CTest)
+include (DetermineGflagsNamespace)
+
+set (CMAKE_THREAD_PREFER_PTHREAD 1)
+
+if (WITH_GFLAGS)
+  find_package (gflags)
+
+  if (gflags_FOUND)
+    set (HAVE_LIB_GFLAGS 1)
+    determine_gflags_namespace (gflags_NAMESPACE)
+  endif (gflags_FOUND)
+endif (WITH_GFLAGS)
+
+if (WITH_THREADS)
+  find_package (Threads)
+endif (WITH_THREADS)
+
+check_include_file (dlfcn.h HAVE_DLFCN_H)
+check_include_file (execinfo.h HAVE_EXECINFO_H)
+check_include_file (glob.h HAVE_GLOB_H)
+check_include_file (inttypes.h HAVE_INTTYPES_H)
+check_include_file (libunwind.h HAVE_LIBUNWIND_H)
+check_include_file (memory.h HAVE_MEMORY_H)
+check_include_file (pwd.h HAVE_PWD_H)
+check_include_file (stdint.h HAVE_STDINT_H)
+check_include_file (stdlib.h HAVE_STDLIB_H)
+check_include_file (string.h HAVE_STRING_H)
+check_include_file (strings.h HAVE_STRINGS_H)
+check_include_file (sys/stat.h HAVE_SYS_STAT_H)
+check_include_file (sys/syscall.h HAVE_SYS_SYSCALL_H)
+check_include_file (sys/time.h HAVE_SYS_TIME_H)
+check_include_file (sys/types.h HAVE_SYS_TYPES_H)
+check_include_file (sys/utsname.h HAVE_SYS_UTSNAME_H)
+check_include_file (syscall.h HAVE_SYSCALL_H)
+check_include_file (syslog.h HAVE_SYSLOG_H)
+check_include_file (ucontext.h HAVE_UCONTEXT_H)
+check_include_file (unistd.h HAVE_UNISTD_H)
+check_include_file (unwind.h HAVE_UNWIND_H)
+
+check_include_file_cxx ("ext/hash_map" HAVE_EXT_HASH_MAP)
+check_include_file_cxx ("ext/hash_set" HAVE_EXT_HASH_SET)
+check_include_file_cxx ("ext/slist" HAVE_EXT_SLIST)
+check_include_file_cxx ("tr1/unordered_map" HAVE_TR1_UNORDERED_MAP)
+check_include_file_cxx ("tr1/unordered_set" HAVE_TR1_UNORDERED_SET)
+check_include_file_cxx ("unordered_map" HAVE_UNORDERED_MAP)
+check_include_file_cxx ("unordered_set" HAVE_UNORDERED_SET)
+
+check_type_size ("unsigned __int16" HAVE___UINT16)
+check_type_size (u_int16_t HAVE_U_INT16_T)
+check_type_size (uint16_t HAVE_UINT16_T)
+
+check_function_exists (dladdr HAVE_DLADDR)
+check_function_exists (fcntl HAVE_FCNTL)
+check_function_exists (pread HAVE_PREAD)
+check_function_exists (pwrite HAVE_PWRITE)
+check_function_exists (sigaction HAVE_SIGACTION)
+check_function_exists (sigaltstack HAVE_SIGALSTACK)
+
+# NOTE gcc does not fail if you pass a non-existent -Wno-* option as an
+# argument. However, it will happily fail if you pass the corresponding -W*
+# option. So, we check whether options that disable warnings exist by testing
+# the availability of the corresponding option that enables the warning. This
+# eliminates the need to check for compiler for several (mainly Clang) options.
+
+check_cxx_compiler_flag (-Wdeprecated HAVE_NO_DEPRECATED)
+check_cxx_compiler_flag (-Wunnamed-type-template-args
+    HAVE_NO_UNNAMED_TYPE_TEMPLATE_ARGS)
+
+# NOTE: Cannot use check_function_exists here since >=vc-14.0 can define
+# snprintf as an inline function
+check_symbol_exists (snprintf stdio.h HAVE_SNPRINTF)
+
+check_library_exists (unwind get_static_proc_name "" HAVE_LIB_UNWIND)
+
+find_library (UNWIND_LIBRARY NAMES unwind DOC "unwind library")
+mark_as_advanced (UNWIND_LIBRARY)
+
+check_c_source_compiles ("
+#include <stdlib.h>
+static void foo(void) __attribute__ ((unused));
+int main(void) { return 0; }
+" HAVE___ATTRIBUTE__)
+
+check_c_source_compiles ("
+#include <stdlib.h>
+static void foo(void) __attribute__ ((visibility(\"default\")));
+int main(void) { return 0; }
+" HAVE___ATTRIBUTE__VISIBILITY_DEFAULT)
+
+check_c_source_compiles ("
+#include <stdlib.h>
+static void foo(void) __attribute__ ((visibility(\"hidden\")));
+int main(void) { return 0; }
+" HAVE___ATTRIBUTE__VISIBILITY_HIDDEN)
+
+check_c_source_compiles ("
+int main(void) { if (__builtin_expect(0, 0)) return 1; return 0; }
+" HAVE___BUILTIN_EXPECT)
+
+check_c_source_compiles ("
+int main(void)
+{
+  int a; if (__sync_val_compare_and_swap(&a, 0, 1)) return 1; return 0;
+}
+" HAVE___SYNC_VAL_COMPARE_AND_SWAP)
+
+check_c_source_compiles ("
+#define _XOPEN_SOURCE 500
+#include <pthread.h>
+int main(void)
+{
+  pthread_rwlock_t l;
+  pthread_rwlock_init(&l, NULL);
+  pthread_rwlock_rdlock(&l);
+  return 0;
+}
+" HAVE_RWLOCK)
+
+check_c_source_compiles ("
+__declspec(selectany) int a;
+int main(void) { return 0; }
+" HAVE___DECLSPEC)
+
+check_cxx_source_compiles ("
+#include <vector>
+vector<int> t; int main() { }
+" STL_NO_NAMESPACE)
+
+check_cxx_source_compiles ("
+#include <vector>
+std::vector<int> t; int main() { }
+" STL_STD_NAMESPACE)
+
+check_cxx_source_compiles ("
+#include <iostream>
+std::ostream& operator<<(std::ostream&, struct s);
+using ::operator<<;
+int main() { }
+" HAVE_USING_OPERATOR)
+
+check_cxx_source_compiles ("
+namespace Outer { namespace Inner { int i = 0; }}
+using namespace Outer::Inner;;
+int main() { return i; }
+" HAVE_NAMESPACES)
+
+set (_PC_FIELDS
+  "gregs[REG_PC]"
+  "gregs[REG_EIP]"
+  "gregs[REG_RIP]"
+  "sc_ip"
+  "uc_regs->gregs[PT_NIP]"
+  "gregs[R15]"
+  "arm_pc"
+  "mc_eip"
+  "mc_rip"
+  "__gregs[REG_EIP]"
+  "__gregs[REG_RIP]"
+  "ss.eip"
+  "__ss.__eip"
+  "ss.rip"
+  "__ss.__rip"
+  "ss.srr0"
+  "__ss.__srr0"
+)
+
+set (_PC_HEADERS ucontext.h signal.h)
+
+if (HAVE_UCONTEXT_H AND NOT PC_FROM_UCONTEXT)
+  foreach (_PC_FIELD ${_PC_FIELDS})
+    foreach (_PC_HEADER ${_PC_HEADERS})
+      set (_TMP
+      ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/uctfield.c)
+      file (WRITE ${_TMP} "
+#define _GNU_SOURCE 1
+#include <${_PC_HEADER}>
+int main(void)
+{
+  ucontext_t u;
+  return u.${_PC_FIELD} == 0;
+}
+")
+      try_compile (HAVE_PC_FROM_UCONTEXT ${CMAKE_CURRENT_BINARY_DIR} ${_TMP}
+        COMPILE_DEFINITIONS _GNU_SOURCE=1)
+
+      if (HAVE_PC_FROM_UCONTEXT)
+        set (PC_FROM_UCONTEXT ${_PC_FIELD} CACHE)
+      endif (HAVE_PC_FROM_UCONTEXT)
+    endforeach (_PC_HEADER)
+  endforeach (_PC_FIELD)
+endif  (HAVE_UCONTEXT_H AND NOT PC_FROM_UCONTEXT)
+
+if (STL_STD_NAMESPACE)
+  set (STL_NAMESPACE std)
+else (STL_STD_NAMESPACE)
+  set (STL_NAMESPACE "")
+endif (STL_STD_NAMESPACE)
+
+set (GOOGLE_NAMESPACE google)
+set (_START_GOOGLE_NAMESPACE_ "namespace ${GOOGLE_NAMESPACE} {")
+set (_END_GOOGLE_NAMESPACE_ "}")
+
+if (HAVE___UINT16)
+  set (ac_cv_have___uint16 1)
+else (HAVE___UINT16)
+  set (ac_cv_have___uint16 0)
+endif (HAVE___UINT16)
+
+if (HAVE_INTTYPES_H)
+  set (ac_cv_have_inttypes_h 1)
+else (HAVE_INTTYPES_H)
+  set (ac_cv_have_inttypes_h 0)
+endif (HAVE_INTTYPES_H)
+
+if (HAVE_LIB_GFLAGS)
+  set (ac_cv_have_libgflags 1)
+else (HAVE_LIB_GFLAGS)
+  set (ac_cv_have_libgflags 0)
+endif (HAVE_LIB_GFLAGS)
+
+if (HAVE_STDINT_H)
+  set (ac_cv_have_stdint_h 1)
+else (HAVE_STDINT_H)
+  set (ac_cv_have_stdint_h 0)
+endif (HAVE_STDINT_H)
+
+if (HAVE_SYS_TYPES_H)
+  set (ac_cv_have_systypes_h 1)
+else (HAVE_SYS_TYPES_H)
+  set (ac_cv_have_systypes_h 0)
+endif (HAVE_SYS_TYPES_H)
+
+if (HAVE_U_INT16_T)
+  set (ac_cv_have_u_int16_t 1)
+else (HAVE_U_INT16_T)
+  set (ac_cv_have_u_int16_t 0)
+endif (HAVE_U_INT16_T)
+
+if (HAVE_UINT16_T)
+  set (ac_cv_have_uint16_t 1)
+else (HAVE_UINT16_T)
+  set (ac_cv_have_uint16_t 0)
+endif (HAVE_UINT16_T)
+
+if (HAVE_UNISTD_H)
+  set (ac_cv_have_unistd_h 1)
+else (HAVE_UNISTD_H)
+  set (ac_cv_have_unistd_h 0)
+endif (HAVE_UNISTD_H)
+
+set (ac_google_namespace ${GOOGLE_NAMESPACE})
+set (ac_google_end_namespace ${_END_GOOGLE_NAMESPACE_})
+set (ac_google_start_namespace ${_START_GOOGLE_NAMESPACE_})
+
+if (HAVE___ATTRIBUTE__)
+  set (ac_cv___attribute___noreturn "__attribute__((noreturn))")
+  set (ac_cv___attribute___noinline "__attribute__((noinline))")
+elseif (HAVE___DECLSPEC)
+  set (ac_cv___attribute___noreturn "__declspec(noreturn)")
+  #set (ac_cv___attribute___noinline "__declspec(noinline)")
+endif (HAVE___ATTRIBUTE__)
+
+if (HAVE___BUILTIN_EXPECT)
+  set (ac_cv_have___builtin_expect 1)
+else (HAVE___BUILTIN_EXPECT)
+  set (ac_cv_have___builtin_expect 0)
+endif (HAVE___BUILTIN_EXPECT)
+
+if (HAVE_USING_OPERATOR)
+  set (ac_cv_cxx_using_operator 1)
+else (HAVE_USING_OPERATOR)
+  set (ac_cv_cxx_using_operator 0)
+endif (HAVE_USING_OPERATOR)
+
+set (SIZEOF_VOID_P ${CMAKE_SIZEOF_VOID_P})
+
+if (WITH_THREADS AND Threads_FOUND)
+  if (CMAKE_USE_PTHREADS_INIT)
+    set (HAVE_PTHREAD 1)
+  endif (CMAKE_USE_PTHREADS_INIT)
+else (WITH_THREADS AND Threads_FOUND)
+  set (NO_THREADS 1)
+endif (WITH_THREADS AND Threads_FOUND)
+
+set (TEST_SRC_DIR \"${CMAKE_CURRENT_SOURCE_DIR}\")
+
+configure_file (src/config.h.cmake.in config.h)
+configure_file (src/glog/logging.h.in glog/logging.h @ONLY)
+configure_file (src/glog/raw_logging.h.in glog/raw_logging.h @ONLY)
+configure_file (src/glog/stl_logging.h.in glog/stl_logging.h @ONLY)
+configure_file (src/glog/vlog_is_on.h.in glog/vlog_is_on.h @ONLY)
+
+set (CMAKE_CXX_VISIBILITY_PRESET default)
+set (CMAKE_VISIBILITY_INLINES_HIDDEN 1)
+
+set (GLOG_PUBLIC_H
+  ${CMAKE_CURRENT_BINARY_DIR}/config.h
+  ${CMAKE_CURRENT_BINARY_DIR}/glog/logging.h
+  ${CMAKE_CURRENT_BINARY_DIR}/glog/raw_logging.h
+  ${CMAKE_CURRENT_BINARY_DIR}/glog/stl_logging.h
+  ${CMAKE_CURRENT_BINARY_DIR}/glog/vlog_is_on.h
+  src/glog/log_severity.h
+)
+
+set (GLOG_SRCS
+  ${GLOG_PUBLIC_H}
+  src/base/commandlineflags.h
+  src/base/googleinit.h
+  src/base/mutex.h
+  src/demangle.cc
+  src/demangle.h
+  src/logging.cc
+  src/raw_logging.cc
+  src/symbolize.cc
+  src/symbolize.h
+  src/utilities.cc
+  src/utilities.h
+  src/vlog_is_on.cc
+)
+
+if (HAVE_PTHREAD)
+  list (APPEND GLOG_SRCS src/signalhandler.cc)
+endif (HAVE_PTHREAD)
+
+if (WIN32)
+  list (APPEND GLOG_SRCS
+    src/windows/port.cc
+    src/windows/port.h
+  )
+endif (WIN32)
+
+add_compile_options ($<$<BOOL:${HAVE_NO_UNNAMED_TYPE_TEMPLATE_ARGS}>:-Wno-unnamed-type-template-args>)
+
+add_library (glog
+  ${GLOG_SRCS}
+)
+
+set_target_properties (glog PROPERTIES POSITION_INDEPENDENT_CODE ON)
+
+if (UNWIND_LIBRARY)
+  target_link_libraries (glog PUBLIC ${UNWIND_LIBRARY})
+endif (UNWIND_LIBRARY)
+
+if (HAVE_PTHREAD)
+  target_link_libraries (glog PUBLIC ${CMAKE_THREAD_LIBS_INIT})
+endif (HAVE_PTHREAD)
+
+if (WIN32 AND HAVE_SNPRINTF)
+  set_property (SOURCE src/windows/port.cc APPEND PROPERTY COMPILE_DEFINITIONS
+    HAVE_SNPRINTF)
+endif (WIN32 AND HAVE_SNPRINTF)
+
+if (gflags_FOUND)
+  target_include_directories (glog PUBLIC $<BUILD_INTERFACE:${gflags_INCLUDE_DIR}>)
+  target_link_libraries (glog PUBLIC ${gflags_LIBRARIES})
+
+  if (NOT BUILD_SHARED_LIBS)
+    # Don't use __declspec(dllexport|dllimport) if this is a static build
+    targeT_compile_definitions (glog PUBLIC GFLAGS_DLL_DECLARE_FLAG= GFLAGS_DLL_DEFINE_FLAG=)
+  endif (NOT BUILD_SHARED_LIBS)
+endif (gflags_FOUND)
+
+set_target_properties (glog PROPERTIES VERSION ${GLOG_MAJOR_VERSION})
+set_target_properties (glog PROPERTIES SOVERSION ${GLOG_VERSION})
+
+if (WIN32)
+  target_compile_definitions (glog PUBLIC GLOG_NO_ABBREVIATED_SEVERITIES)
+endif (WIN32)
+
+set_target_properties (glog PROPERTIES PUBLIC_HEADER "${GLOG_PUBLIC_H}")
+
+target_include_directories (glog BEFORE PUBLIC
+  "$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>"
+  "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>"
+  "$<INSTALL_INTERFACE:include>"
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src)
+
+if (WIN32)
+  target_include_directories (glog PUBLIC
+    "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src/windows>"
+    PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src/windows)
+endif (WIN32)
+
+set_target_properties (glog PROPERTIES DEFINE_SYMBOL LIBGLOG_EXPORTS)
+
+if (NOT BUILD_SHARED_LIBS)
+  target_compile_definitions (glog PUBLIC GOOGLE_GLOG_DLL_DECL=)
+else (NOT BUILD_SHARED_LIBS)
+  target_compile_definitions (glog PRIVATE GOOGLE_GLOG_IS_A_DLL=1)
+
+  if (HAVE___ATTRIBUTE__VISIBILITY_DEFAULT)
+    set (_EXPORT "__attribute__((visibility(\"default\")))")
+    set (_IMPORT "")
+  elseif (HAVE___DECLSPEC)
+    set (_EXPORT "__declspec(dllexport)")
+    set (_IMPORT "__declspec(dllimport)")
+  endif (HAVE___ATTRIBUTE__VISIBILITY_DEFAULT)
+
+  target_compile_definitions (glog PRIVATE
+    "GOOGLE_GLOG_DLL_DECL=${_EXPORT}")
+  target_compile_definitions (glog INTERFACE
+    "GOOGLE_GLOG_DLL_DECL=${_IMPORT}")
+  target_compile_definitions (glog INTERFACE
+    "GOOGLE_GLOG_DLL_DECL_FOR_UNITTESTS=${_IMPORT}")
+endif (NOT BUILD_SHARED_LIBS)
+
+if (HAVE_EXECINFO_H)
+  set (HAVE_STACKTRACE 1)
+endif (HAVE_EXECINFO_H)
+
+if (UNIX OR (APPLE AND HAVE_DLADDR))
+  set (HAVE_SYMBOLIZE 1)
+endif (UNIX OR (APPLE AND HAVE_DLADDR))
+
+# Unit testing
+
+if (BUILD_TESTING)
+  add_executable (logging_unittest
+    src/logging_unittest.cc
+  )
+
+  target_link_libraries (logging_unittest PRIVATE glog)
+
+  add_executable (stl_logging_unittest
+    src/stl_logging_unittest.cc
+  )
+
+  target_link_libraries (stl_logging_unittest PRIVATE glog)
+
+  if (HAVE_NO_DEPRECATED)
+    set_property (TARGET stl_logging_unittest APPEND PROPERTY COMPILE_OPTIONS
+      -Wno-deprecated)
+  endif (HAVE_NO_DEPRECATED)
+
+  if (HAVE_UNORDERED_MAP AND HAVE_UNORDERED_SET)
+    target_compile_definitions (stl_logging_unittest PRIVATE
+      GLOG_STL_LOGGING_FOR_UNORDERED)
+  endif (HAVE_UNORDERED_MAP AND HAVE_UNORDERED_SET)
+
+  if (HAVE_TR1_UNORDERED_MAP AND HAVE_TR1_UNORDERED_SET)
+    target_compile_definitions (stl_logging_unittest PRIVATE
+      GLOG_STL_LOGGING_FOR_TR1_UNORDERED)
+  endif (HAVE_TR1_UNORDERED_MAP AND HAVE_TR1_UNORDERED_SET)
+
+  if (HAVE_EXT_HASH_MAP AND HAVE_EXT_HASH_SET)
+    target_compile_definitions (stl_logging_unittest PRIVATE
+      GLOG_STL_LOGGING_FOR_EXT_HASH)
+  endif (HAVE_EXT_HASH_MAP AND HAVE_EXT_HASH_SET)
+
+  if (HAVE_EXT_SLIST)
+    target_compile_definitions (stl_logging_unittest PRIVATE
+      GLOG_STL_LOGGING_FOR_EXT_SLIST)
+  endif (HAVE_EXT_SLIST)
+
+  if (HAVE_SYMBOLIZE)
+    add_executable (symbolize_unittest
+      src/symbolize_unittest.cc
+    )
+
+    target_link_libraries (symbolize_unittest PRIVATE glog)
+  endif (HAVE_SYMBOLIZE)
+
+  add_executable (demangle_unittest
+    src/demangle_unittest.cc
+  )
+
+  target_link_libraries (demangle_unittest PRIVATE glog)
+
+  if (HAVE_STACKTRACE)
+    add_executable (stacktrace_unittest
+      src/stacktrace_unittest.cc
+    )
+
+    target_link_libraries (stacktrace_unittest PRIVATE glog)
+  endif (HAVE_STACKTRACE)
+
+  add_executable (utilities_unittest
+    src/utilities_unittest.cc
+  )
+
+  target_link_libraries (utilities_unittest PRIVATE glog)
+
+  if (HAVE_STACKTRACE AND HAVE_SYMBOLIZE)
+    add_executable (signalhandler_unittest
+      src/signalhandler_unittest.cc
+    )
+
+    target_link_libraries (signalhandler_unittest PRIVATE glog)
+  endif (HAVE_STACKTRACE AND HAVE_SYMBOLIZE)
+
+  add_test (NAME demangle COMMAND demangle_unittest)
+  add_test (NAME logging COMMAND logging_unittest)
+
+  if (TARGET signalhandler_unittest)
+    add_test (NAME signalhandler COMMAND signalhandler_unittest)
+  endif (TARGET signalhandler_unittest)
+
+  if (TARGET stacktrace_unittest)
+    add_test (NAME stacktrace COMMAND stacktrace_unittest)
+  endif (TARGET stacktrace_unittest)
+
+  add_test (NAME stl_logging COMMAND stl_logging_unittest)
+
+  if (TARGET symbolize_unittest)
+    add_test (NAME symbolize COMMAND symbolize_unittest)
+  endif (TARGET symbolize_unittest)
+endif (BUILD_TESTING)
+
+install (TARGETS glog
+  EXPORT glog-targets
+  RUNTIME DESTINATION bin
+  PUBLIC_HEADER DESTINATION include/glog
+  LIBRARY DESTINATION lib
+  ARCHIVE DESTINATION lib)
+
+if (gflags_FOUND)
+  set (gflags_DEPENDENCY "find_dependency (gflags ${gflags_VERSION})")
+endif (gflags_FOUND)
+
+configure_package_config_file (glog-config.cmake.in
+  ${CMAKE_CURRENT_BINARY_DIR}/glog-config.cmake
+  INSTALL_DESTINATION lib/cmake/glog
+  NO_CHECK_REQUIRED_COMPONENTS_MACRO)
+
+write_basic_package_version_file (glog-config-version.cmake VERSION
+  ${GLOG_VERSION} COMPATIBILITY SameMajorVersion)
+
+export (TARGETS glog NAMESPACE glog:: FILE glog-targets.cmake)
+export (PACKAGE glog)
+
+install (FILES
+  ${CMAKE_CURRENT_BINARY_DIR}/glog-config.cmake
+  ${CMAKE_CURRENT_BINARY_DIR}/glog-config-version.cmake
+  DESTINATION lib/cmake/glog)
+
+install (EXPORT glog-targets NAMESPACE glog:: DESTINATION lib/cmake/glog)

+ 58 - 0
third-party/glog-0.3.5/CONTRIBUTING.md

@@ -0,0 +1,58 @@
+# How to contribute #
+
+We'd love to accept your patches and contributions to this project.  There are
+a just a few small guidelines you need to follow.
+
+
+## Contributor License Agreement ##
+
+Contributions to any Google project must be accompanied by a Contributor
+License Agreement.  This is not a copyright **assignment**, it simply gives
+Google permission to use and redistribute your contributions as part of the
+project.
+
+  * If you are an individual writing original source code and you're sure you
+    own the intellectual property, then you'll need to sign an [individual
+    CLA][].
+
+  * If you work for a company that wants to allow you to contribute your work,
+    then you'll need to sign a [corporate CLA][].
+
+You generally only need to submit a CLA once, so if you've already submitted
+one (even if it was for a different project), you probably don't need to do it
+again.
+
+[individual CLA]: https://developers.google.com/open-source/cla/individual
+[corporate CLA]: https://developers.google.com/open-source/cla/corporate
+
+Once your CLA is submitted (or if you already submitted one for
+another Google project), make a commit adding yourself to the
+[AUTHORS][] and [CONTRIBUTORS][] files. This commit can be part
+of your first [pull request][].
+
+[AUTHORS]: AUTHORS
+[CONTRIBUTORS]: CONTRIBUTORS
+
+
+## Submitting a patch ##
+
+  1. It's generally best to start by opening a new issue describing the bug or
+     feature you're intending to fix.  Even if you think it's relatively minor,
+     it's helpful to know what people are working on.  Mention in the initial
+     issue that you are planning to work on that bug or feature so that it can
+     be assigned to you.
+
+  1. Follow the normal process of [forking][] the project, and setup a new
+     branch to work in.  It's important that each group of changes be done in
+     separate branches in order to ensure that a pull request only includes the
+     commits related to that bug or feature.
+
+  1. Do your best to have [well-formed commit messages][] for each change.
+     This provides consistency throughout the project, and ensures that commit
+     messages are able to be formatted properly by various git tools.
+
+  1. Finally, push the commits to your fork and submit a [pull request][].
+
+[forking]: https://help.github.com/articles/fork-a-repo
+[well-formed commit messages]: http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html
+[pull request]: https://help.github.com/articles/creating-a-pull-request

+ 40 - 0
third-party/glog-0.3.5/CONTRIBUTORS

@@ -0,0 +1,40 @@
+# People who have agreed to one of the CLAs and can contribute patches.
+# The AUTHORS file lists the copyright holders; this file
+# lists people.  For example, Google employees are listed here
+# but not in AUTHORS, because Google holds the copyright.
+#
+# Names should be added to this file only after verifying that
+# the individual or the individual's organization has agreed to
+# the appropriate Contributor License Agreement, found here:
+#
+# https://developers.google.com/open-source/cla/individual
+# https://developers.google.com/open-source/cla/corporate
+#
+# The agreement for individuals can be filled out on the web.
+#
+# When adding J Random Contributor's name to this file,
+# either J's name or J's organization's name should be
+# added to the AUTHORS file, depending on whether the
+# individual or corporate CLA was used.
+#
+# Names should be added to this file as:
+#     Name <email address>
+#
+# Please keep the list sorted.
+
+Abhishek Dasgupta <abhi2743@gmail.com>
+Abhishek Parmar <abhishek@orng.net>
+Andy Ying <andy@trailofbits.com>
+Brian Silverman <bsilver16384@gmail.com>
+Fumitoshi Ukai <ukai@google.com>
+Guillaume Dumont <dumont.guillaume@gmail.com>
+Håkan L. S. Younes <hyounes@google.com>
+Ivan Penkov <ivanpe@google.com>
+Michael Tanner <michael@tannertaxpro.com>
+MiniLight <MiniLightAR@Gmail.com>
+Peter Collingbourne <pcc@google.com>
+romange <romange@users.noreply.github.com>
+Sergiu Deitsch <sergiu.deitsch@gmail.com>
+Shinichiro Hamaji <hamaji@google.com>
+tbennun <tbennun@gmail.com>
+Teddy Reed <teddy@prosauce.org>

+ 65 - 0
third-party/glog-0.3.5/COPYING

@@ -0,0 +1,65 @@
+Copyright (c) 2008, Google Inc.
+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.
+
+
+A function gettimeofday in utilities.cc is based on
+
+http://www.google.com/codesearch/p?hl=en#dR3YEbitojA/COPYING&q=GetSystemTimeAsFileTime%20license:bsd
+
+The license of this code is:
+
+Copyright (c) 2003-2008, Jouni Malinen <j@w1.fi> and contributors
+All Rights Reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+
+2. 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.
+
+3. Neither the name(s) of the above-listed copyright holder(s) 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.

+ 84 - 0
third-party/glog-0.3.5/ChangeLog

@@ -0,0 +1,84 @@
+2013-02-01  Google Inc. <opensource@google.com>
+
+	* google-glog: version 0.3.3
+	* Add --disable-rtti option for configure.
+	* Visual Studio build and test fix.
+	* QNX build fix (thanks vanuan).
+	* Reduce warnings.
+	* Fixed LOG_SYSRESULT (thanks ukai).
+	* FreeBSD build fix (thanks yyanagisawa).
+	* Clang build fix.
+	* Now users can re-initialize glog after ShutdownGoogleLogging.
+	* Color output support by GLOG_colorlogtostderr (thanks alexs).
+	* Now glog's ABI around flags are compatible with gflags.
+	* Document mentions how to modify flags from user programs.
+
+2012-01-12  Google Inc. <opensource@google.com>
+
+	* google-glog: version 0.3.2
+	* Clang support.
+	* Demangler and stacktrace improvement for newer GCCs.
+	* Now fork(2) doesn't mess up log files.
+	* Make valgrind happier.
+	* Reduce warnings for more -W options.
+	* Provide a workaround for ERROR defined by windows.h.
+
+2010-06-15  Google Inc. <opensource@google.com>
+
+	* google-glog: version 0.3.1
+	* GLOG_* environment variables now work even when gflags is installed.
+	* Snow leopard support.
+	* Now we can build and test from out side tree.
+	* Add DCHECK_NOTNULL.
+	* Add ShutdownGoogleLogging to close syslog (thanks DGunchev)
+	* Fix --enable-frame-pointers option (thanks kazuki.ohta)
+	* Fix libunwind detection (thanks giantchen)
+
+2009-07-30  Google Inc. <opensource@google.com>
+
+	* google-glog: version 0.3.0
+	* Fix a deadlock happened when user uses glog with recent gflags.
+	* Suppress several unnecessary warnings (thanks keir).
+	* NetBSD and OpenBSD support.
+	* Use Win32API GetComputeNameA properly (thanks magila).
+	* Fix user name detection for Windows (thanks ademin).
+	* Fix several minor bugs.
+
+2009-04-10  Google Inc. <opensource@google.com>
+	* google-glog: version 0.2.1
+	* Fix timestamps of VC++ version.
+	* Add pkg-config support (thanks Tomasz)
+	* Fix build problem when building with gtest (thanks Michael)
+	* Add --with-gflags option for configure (thanks Michael)
+	* Fixes for GCC 4.4 (thanks John)
+
+2009-01-23  Google Inc. <opensource@google.com>
+	* google-glog: version 0.2
+	* Add initial Windows VC++ support.
+	* Google testing/mocking frameworks integration.
+	* Link pthread library automatically.
+	* Flush logs in signal handlers.
+	* Add macros LOG_TO_STRING, LOG_AT_LEVEL, DVLOG, and LOG_TO_SINK_ONLY.
+	* Log microseconds.
+	* Add --log_backtrace_at option.
+	* Fix some minor bugs.
+
+2008-11-18  Google Inc. <opensource@google.com>
+	* google-glog: version 0.1.2
+	* Add InstallFailureSignalHandler(). (satorux)
+	* Re-organize the way to produce stacktraces.
+	* Don't define unnecessary macro DISALLOW_EVIL_CONSTRUCTORS.
+
+2008-10-15  Google Inc. <opensource@google.com>
+	* google-glog: version 0.1.1
+	* Support symbolize for MacOSX 10.5.
+	* BUG FIX: --vmodule didn't work with gflags.
+	* BUG FIX: symbolize_unittest failed with GCC 4.3.
+	* Several fixes on the document.
+
+2008-10-07  Google Inc. <opensource@google.com>
+
+	* google-glog: initial release:
+	The glog package contains a library that implements application-level
+	logging.  This library provides logging APIs based on C++-style
+	streams and various helper macros.

+ 297 - 0
third-party/glog-0.3.5/INSTALL

@@ -0,0 +1,297 @@
+Installation Instructions
+*************************
+
+Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005,
+2006, 2007 Free Software Foundation, Inc.
+
+This file is free documentation; the Free Software Foundation gives
+unlimited permission to copy, distribute and modify it.
+
+Glog-Specific Install Notes
+================================
+
+*** NOTE FOR 64-BIT LINUX SYSTEMS
+
+The glibc built-in stack-unwinder on 64-bit systems has some problems
+with the glog libraries.  (In particular, if you are using
+InstallFailureSignalHandler(), the signal may be raised in the middle
+of malloc, holding some malloc-related locks when they invoke the
+stack unwinder.  The built-in stack unwinder may call malloc
+recursively, which may require the thread to acquire a lock it already
+holds: deadlock.)
+
+For that reason, if you use a 64-bit system and you need
+InstallFailureSignalHandler(), we strongly recommend you install
+libunwind before trying to configure or install google glog.
+libunwind can be found at
+
+   http://download.savannah.nongnu.org/releases/libunwind/libunwind-snap-070410.tar.gz
+
+Even if you already have libunwind installed, you will probably still
+need to install from the snapshot to get the latest version.
+
+CAUTION: if you install libunwind from the URL above, be aware that
+you may have trouble if you try to statically link your binary with
+glog: that is, if you link with 'gcc -static -lgcc_eh ...'.  This
+is because both libunwind and libgcc implement the same C++ exception
+handling APIs, but they implement them differently on some platforms.
+This is not likely to be a problem on ia64, but may be on x86-64.
+
+Also, if you link binaries statically, make sure that you add
+-Wl,--eh-frame-hdr to your linker options. This is required so that
+libunwind can find the information generated by the compiler required
+for stack unwinding.
+
+Using -static is rare, though, so unless you know this will affect you
+it probably won't.
+
+If you cannot or do not wish to install libunwind, you can still try
+to use two kinds of stack-unwinder: 1. glibc built-in stack-unwinder
+and 2. frame pointer based stack-unwinder.
+
+1. As we already mentioned, glibc's unwinder has a deadlock issue.
+However, if you don't use InstallFailureSignalHandler() or you don't
+worry about the rare possibilities of deadlocks, you can use this
+stack-unwinder.  If you specify no options and libunwind isn't
+detected on your system, the configure script chooses this unwinder by
+default.
+
+2. The frame pointer based stack unwinder requires that your
+application, the glog library, and system libraries like libc, all be
+compiled with a frame pointer.  This is *not* the default for x86-64.
+
+If you are on x86-64 system, know that you have a set of system
+libraries with frame-pointers enabled, and compile all your
+applications with -fno-omit-frame-pointer, then you can enable the
+frame pointer based stack unwinder by passing the
+--enable-frame-pointers flag to configure.
+
+
+Basic Installation
+==================
+
+Briefly, the shell commands `./configure; make; make install' should
+configure, build, and install this package.  The following
+more-detailed instructions are generic; see the `README' file for
+instructions specific to this package.
+
+   The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation.  It uses
+those values to create a `Makefile' in each directory of the package.
+It may also create one or more `.h' files containing system-dependent
+definitions.  Finally, it creates a shell script `config.status' that
+you can run in the future to recreate the current configuration, and a
+file `config.log' containing compiler output (useful mainly for
+debugging `configure').
+
+   It can also use an optional file (typically called `config.cache'
+and enabled with `--cache-file=config.cache' or simply `-C') that saves
+the results of its tests to speed up reconfiguring.  Caching is
+disabled by default to prevent problems with accidental use of stale
+cache files.
+
+   If you need to do unusual things to compile the package, please try
+to figure out how `configure' could check whether to do them, and mail
+diffs or instructions to the address given in the `README' so they can
+be considered for the next release.  If you are using the cache, and at
+some point `config.cache' contains results you don't want to keep, you
+may remove or edit it.
+
+   The file `configure.ac' (or `configure.in') is used to create
+`configure' by a program called `autoconf'.  You need `configure.ac' if
+you want to change it or regenerate `configure' using a newer version
+of `autoconf'.
+
+The simplest way to compile this package is:
+
+  1. `cd' to the directory containing the package's source code and type
+     `./configure' to configure the package for your system.
+
+     Running `configure' might take a while.  While running, it prints
+     some messages telling which features it is checking for.
+
+  2. Type `make' to compile the package.
+
+  3. Optionally, type `make check' to run any self-tests that come with
+     the package.
+
+  4. Type `make install' to install the programs and any data files and
+     documentation.
+
+  5. You can remove the program binaries and object files from the
+     source code directory by typing `make clean'.  To also remove the
+     files that `configure' created (so you can compile the package for
+     a different kind of computer), type `make distclean'.  There is
+     also a `make maintainer-clean' target, but that is intended mainly
+     for the package's developers.  If you use it, you may have to get
+     all sorts of other programs in order to regenerate files that came
+     with the distribution.
+
+  6. Often, you can also type `make uninstall' to remove the installed
+     files again.
+
+Compilers and Options
+=====================
+
+Some systems require unusual options for compilation or linking that the
+`configure' script does not know about.  Run `./configure --help' for
+details on some of the pertinent environment variables.
+
+   You can give `configure' initial values for configuration parameters
+by setting variables in the command line or in the environment.  Here
+is an example:
+
+     ./configure CC=c99 CFLAGS=-g LIBS=-lposix
+
+   *Note Defining Variables::, for more details.
+
+Compiling For Multiple Architectures
+====================================
+
+You can compile the package for more than one kind of computer at the
+same time, by placing the object files for each architecture in their
+own directory.  To do this, you can use GNU `make'.  `cd' to the
+directory where you want the object files and executables to go and run
+the `configure' script.  `configure' automatically checks for the
+source code in the directory that `configure' is in and in `..'.
+
+   With a non-GNU `make', it is safer to compile the package for one
+architecture at a time in the source code directory.  After you have
+installed the package for one architecture, use `make distclean' before
+reconfiguring for another architecture.
+
+Installation Names
+==================
+
+By default, `make install' installs the package's commands under
+`/usr/local/bin', include files under `/usr/local/include', etc.  You
+can specify an installation prefix other than `/usr/local' by giving
+`configure' the option `--prefix=PREFIX'.
+
+   You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files.  If you
+pass the option `--exec-prefix=PREFIX' to `configure', the package uses
+PREFIX as the prefix for installing programs and libraries.
+Documentation and other data files still use the regular prefix.
+
+   In addition, if you use an unusual directory layout you can give
+options like `--bindir=DIR' to specify different values for particular
+kinds of files.  Run `configure --help' for a list of the directories
+you can set and what kinds of files go in them.
+
+   If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving `configure' the
+option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+
+Optional Features
+=================
+
+Some packages pay attention to `--enable-FEATURE' options to
+`configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to `--with-PACKAGE' options, where PACKAGE
+is something like `gnu-as' or `x' (for the X Window System).  The
+`README' should mention any `--enable-' and `--with-' options that the
+package recognizes.
+
+   For packages that use the X Window System, `configure' can usually
+find the X include and library files automatically, but if it doesn't,
+you can use the `configure' options `--x-includes=DIR' and
+`--x-libraries=DIR' to specify their locations.
+
+Specifying the System Type
+==========================
+
+There may be some features `configure' cannot figure out automatically,
+but needs to determine by the type of machine the package will run on.
+Usually, assuming the package is built to be run on the _same_
+architectures, `configure' can figure that out, but if it prints a
+message saying it cannot guess the machine type, give it the
+`--build=TYPE' option.  TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name which has the form:
+
+     CPU-COMPANY-SYSTEM
+
+where SYSTEM can have one of these forms:
+
+     OS KERNEL-OS
+
+   See the file `config.sub' for the possible values of each field.  If
+`config.sub' isn't included in this package, then this package doesn't
+need to know the machine type.
+
+   If you are _building_ compiler tools for cross-compiling, you should
+use the option `--target=TYPE' to select the type of system they will
+produce code for.
+
+   If you want to _use_ a cross compiler, that generates code for a
+platform different from the build platform, you should specify the
+"host" platform (i.e., that on which the generated programs will
+eventually be run) with `--host=TYPE'.
+
+Sharing Defaults
+================
+
+If you want to set default values for `configure' scripts to share, you
+can create a site shell script called `config.site' that gives default
+values for variables like `CC', `cache_file', and `prefix'.
+`configure' looks for `PREFIX/share/config.site' if it exists, then
+`PREFIX/etc/config.site' if it exists.  Or, you can set the
+`CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all `configure' scripts look for a site script.
+
+Defining Variables
+==================
+
+Variables not defined in a site shell script can be set in the
+environment passed to `configure'.  However, some packages may run
+configure again during the build, and the customized values of these
+variables may be lost.  In order to avoid this problem, you should set
+them in the `configure' command line, using `VAR=value'.  For example:
+
+     ./configure CC=/usr/local2/bin/gcc
+
+causes the specified `gcc' to be used as the C compiler (unless it is
+overridden in the site shell script).
+
+Unfortunately, this technique does not work for `CONFIG_SHELL' due to
+an Autoconf bug.  Until the bug is fixed you can use this workaround:
+
+     CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
+
+`configure' Invocation
+======================
+
+`configure' recognizes the following options to control how it operates.
+
+`--help'
+`-h'
+     Print a summary of the options to `configure', and exit.
+
+`--version'
+`-V'
+     Print the version of Autoconf used to generate the `configure'
+     script, and exit.
+
+`--cache-file=FILE'
+     Enable the cache: use and save the results of the tests in FILE,
+     traditionally `config.cache'.  FILE defaults to `/dev/null' to
+     disable caching.
+
+`--config-cache'
+`-C'
+     Alias for `--cache-file=config.cache'.
+
+`--quiet'
+`--silent'
+`-q'
+     Do not print messages saying which checks are being made.  To
+     suppress all normal output, redirect it to `/dev/null' (any error
+     messages will still be shown).
+
+`--srcdir=DIR'
+     Look for the package's source code in directory DIR.  Usually
+     `configure' can determine that directory automatically.
+
+`configure' also accepts some other, not widely useful, options.  Run
+`configure --help' for more details.
+

+ 249 - 0
third-party/glog-0.3.5/Makefile.am

@@ -0,0 +1,249 @@
+## Process this file with automake to produce Makefile.in
+
+AUTOMAKE_OPTIONS=subdir-objects
+
+# Make sure that when we re-make ./configure, we get the macros we need
+ACLOCAL_AMFLAGS = -I m4
+
+# This is so we can #include <glog/foo>
+AM_CPPFLAGS = -I$(top_srcdir)/src
+
+# This is mostly based on configure options
+AM_CXXFLAGS =
+
+# These are good warnings to turn on by default
+if GCC
+  AM_CXXFLAGS += -Wall -Wwrite-strings -Woverloaded-virtual -Wno-sign-compare
+endif
+
+# These are x86-specific, having to do with frame-pointers
+if X86_64
+if ENABLE_FRAME_POINTERS
+  AM_CXXFLAGS += -fno-omit-frame-pointer
+else
+  # TODO(csilvers): check if -fomit-frame-pointer might be in $(CXXFLAGS),
+  #                 before setting this.
+  AM_CXXFLAGS += -DNO_FRAME_POINTER
+endif
+endif
+
+if DISABLE_RTTI
+  AM_CXXFLAGS += -fno-rtti
+endif
+
+glogincludedir = $(includedir)/glog
+## The .h files you want to install (that is, .h files that people
+## who install this package can include in their own applications.)
+## We have to include both the .h and .h.in forms.  The latter we
+## put in noinst_HEADERS.
+gloginclude_HEADERS = src/glog/log_severity.h
+nodist_gloginclude_HEADERS = src/glog/logging.h src/glog/raw_logging.h src/glog/vlog_is_on.h src/glog/stl_logging.h
+noinst_HEADERS = src/glog/logging.h.in src/glog/raw_logging.h.in src/glog/vlog_is_on.h.in src/glog/stl_logging.h.in
+
+docdir = $(prefix)/share/doc/$(PACKAGE)-$(VERSION)
+## This is for HTML and other documentation you want to install.
+## Add your documentation files (in doc/) in addition to these
+## top-level boilerplate files.  Also add a TODO file if you have one.
+dist_doc_DATA = AUTHORS COPYING ChangeLog INSTALL NEWS README README.windows \
+                doc/designstyle.css doc/glog.html
+
+## The libraries (.so's) you want to install
+lib_LTLIBRARIES =
+
+# The libraries libglog depends on.
+COMMON_LIBS = $(PTHREAD_LIBS) $(GFLAGS_LIBS) $(UNWIND_LIBS)
+# Compile switches for our unittest.
+TEST_CFLAGS = $(GTEST_CFLAGS) $(GMOCK_CFLAGS) $(GFLAGS_CFLAGS) \
+              $(MINGW_CFLAGS) $(AM_CXXFLAGS)
+# Libraries for our unittest.
+TEST_LIBS = $(GTEST_LIBS) $(GMOCK_LIBS) $(GFLAGS_LIBS)
+
+## unittests you want to run when people type 'make check'.
+## TESTS is for binary unittests, check_SCRIPTS for script-based unittests.
+## TESTS_ENVIRONMENT sets environment variables for when you run unittest,
+## but it only seems to take effect for *binary* unittests (argh!)
+TESTS =
+TESTS_ENVIRONMENT =
+check_SCRIPTS =
+# Every time you add a unittest to check_SCRIPTS, add it here too
+noinst_SCRIPTS =
+# Binaries used for script-based unittests.
+TEST_BINARIES =
+
+TESTS += logging_unittest
+logging_unittest_SOURCES = $(gloginclude_HEADERS) \
+                           src/logging_unittest.cc \
+                           src/config_for_unittests.h \
+                           src/mock-log.h
+nodist_logging_unittest_SOURCES = $(nodist_gloginclude_HEADERS)
+logging_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(TEST_CFLAGS)
+logging_unittest_LDFLAGS = $(PTHREAD_CFLAGS)
+logging_unittest_LDADD = libglog.la $(COMMON_LIBS) $(TEST_LIBS)
+
+check_SCRIPTS += logging_striplog_test_sh
+noinst_SCRIPTS += src/logging_striplog_test.sh
+logging_striplog_test_sh: logging_striptest0 logging_striptest2 logging_striptest10
+	$(top_srcdir)/src/logging_striplog_test.sh
+
+check_SCRIPTS += demangle_unittest_sh
+noinst_SCRIPTS += src/demangle_unittest.sh
+demangle_unittest_sh: demangle_unittest
+	$(builddir)/demangle_unittest  # force to create lt-demangle_unittest
+	$(top_srcdir)/src/demangle_unittest.sh
+
+check_SCRIPTS += signalhandler_unittest_sh
+noinst_SCRIPTS += src/signalhandler_unittest.sh
+signalhandler_unittest_sh: signalhandler_unittest
+	$(builddir)/signalhandler_unittest  # force to create lt-signalhandler_unittest
+	$(top_srcdir)/src/signalhandler_unittest.sh
+
+TEST_BINARIES += logging_striptest0
+logging_striptest0_SOURCES = $(gloginclude_HEADERS) \
+                             src/logging_striptest_main.cc
+nodist_logging_striptest0_SOURCES = $(nodist_gloginclude_HEADERS)
+logging_striptest0_CXXFLAGS = $(PTHREAD_CFLAGS) $(TEST_CFLAGS)
+logging_striptest0_LDFLAGS = $(PTHREAD_CFLAGS)
+logging_striptest0_LDADD = libglog.la $(COMMON_LIBS)
+
+TEST_BINARIES += logging_striptest2
+logging_striptest2_SOURCES = $(gloginclude_HEADERS) \
+                             src/logging_striptest2.cc
+nodist_logging_striptest2_SOURCES = $(nodist_gloginclude_HEADERS)
+logging_striptest2_CXXFLAGS = $(PTHREAD_CFLAGS) $(TEST_CFLAGS)
+logging_striptest2_LDFLAGS = $(PTHREAD_CFLAGS)
+logging_striptest2_LDADD = libglog.la $(COMMON_LIBS)
+
+TEST_BINARIES += logging_striptest10
+logging_striptest10_SOURCES = $(gloginclude_HEADERS) \
+                              src/logging_striptest10.cc
+nodist_logging_striptest10_SOURCES = $(nodist_gloginclude_HEADERS)
+logging_striptest10_CXXFLAGS = $(PTHREAD_CFLAGS) $(TEST_CFLAGS)
+logging_striptest10_LDFLAGS = $(PTHREAD_CFLAGS)
+logging_striptest10_LDADD = libglog.la $(COMMON_LIBS)
+
+TESTS += demangle_unittest
+demangle_unittest_SOURCES = $(gloginclude_HEADERS) \
+                            src/demangle_unittest.cc
+nodist_demangle_unittest_SOURCES = $(nodist_gloginclude_HEADERS)
+demangle_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(TEST_CFLAGS)
+demangle_unittest_LDFLAGS = $(PTHREAD_CFLAGS)
+demangle_unittest_LDADD = libglog.la $(COMMON_LIBS) $(TEST_LIBS)
+
+TESTS += stacktrace_unittest
+stacktrace_unittest_SOURCES = $(gloginclude_HEADERS) \
+                              src/stacktrace_unittest.cc
+nodist_stacktrace_unittest_SOURCES = $(nodist_gloginclude_HEADERS)
+stacktrace_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(TEST_CFLAGS)
+stacktrace_unittest_LDFLAGS = $(PTHREAD_CFLAGS)
+stacktrace_unittest_LDADD = libglog.la $(COMMON_LIBS)
+
+TESTS += symbolize_unittest
+symbolize_unittest_SOURCES = $(gloginclude_HEADERS) \
+                              src/symbolize_unittest.cc
+nodist_symbolize_unittest_SOURCES = $(nodist_gloginclude_HEADERS)
+symbolize_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(TEST_CFLAGS)
+symbolize_unittest_LDFLAGS = $(PTHREAD_CFLAGS)
+symbolize_unittest_LDADD = libglog.la $(COMMON_LIBS) $(TEST_LIBS)
+
+TESTS += stl_logging_unittest
+stl_logging_unittest_SOURCES = $(gloginclude_HEADERS) \
+                               src/stl_logging_unittest.cc
+nodist_stl_logging_unittest_SOURCES = $(nodist_gloginclude_HEADERS)
+stl_logging_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(TEST_CFLAGS)
+stl_logging_unittest_LDFLAGS = $(PTHREAD_CFLAGS)
+stl_logging_unittest_LDADD = libglog.la $(COMMON_LIBS) $(TEST_LIBS)
+
+TEST_BINARIES += signalhandler_unittest
+signalhandler_unittest_SOURCES = $(gloginclude_HEADERS) \
+                               src/signalhandler_unittest.cc
+nodist_signalhandler_unittest_SOURCES = $(nodist_gloginclude_HEADERS)
+signalhandler_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(TEST_CFLAGS)
+signalhandler_unittest_LDFLAGS = $(PTHREAD_CFLAGS)
+signalhandler_unittest_LDADD = libglog.la $(COMMON_LIBS) $(TEST_LIBS)
+
+TESTS += utilities_unittest
+utilities_unittest_SOURCES = $(gloginclude_HEADERS) \
+                             src/utilities_unittest.cc
+nodist_utilities_unittest_SOURCES = $(nodist_gloginclude_HEADERS)
+utilities_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(TEST_CFLAGS)
+utilities_unittest_LDFLAGS = $(PTHREAD_CFLAGS)
+utilities_unittest_LDADD = libglog.la $(COMMON_LIBS) $(TEST_LIBS)
+
+if HAVE_GMOCK
+TESTS += mock_log_test
+mock_log_test_SOURCES = $(gloginclude_HEADERS) \
+                        src/mock-log_test.cc
+nodist_mock_log_test_SOURCES = $(nodist_gloginclude_HEADERS)
+mock_log_test_CXXFLAGS = $(PTHREAD_CFLAGS) $(TEST_CFLAGS)
+mock_log_test_LDFLAGS = $(PTHREAD_CFLAGS)
+mock_log_test_LDADD = libglog.la $(COMMON_LIBS) $(TEST_LIBS)
+endif
+
+## vvvv RULES TO MAKE THE LIBRARIES, BINARIES, AND UNITTESTS
+
+lib_LTLIBRARIES += libglog.la
+libglog_la_SOURCES = $(gloginclude_HEADERS) \
+                       src/logging.cc src/raw_logging.cc src/vlog_is_on.cc \
+                       src/utilities.cc src/utilities.h \
+                       src/demangle.cc src/demangle.h \
+                       src/stacktrace.h \
+                       src/stacktrace_generic-inl.h \
+                       src/stacktrace_libunwind-inl.h \
+                       src/stacktrace_powerpc-inl.h \
+                       src/stacktrace_x86-inl.h \
+                       src/stacktrace_x86_64-inl.h \
+                       src/symbolize.cc src/symbolize.h \
+                       src/signalhandler.cc \
+                       src/base/mutex.h src/base/googleinit.h \
+                       src/base/commandlineflags.h src/googletest.h
+nodist_libglog_la_SOURCES = $(nodist_gloginclude_HEADERS)
+
+libglog_la_CXXFLAGS = $(PTRHEAD_CFLAGS) $(GFLAGS_CFLAGS) $(MINGW_CFLAGS) \
+                      $(AM_CXXFLAGS) -DNDEBUG
+libglog_la_LDFLAGS = $(PTRHEAD_CFLAGS) $(GFLAGS_LDFLAGS)
+libglog_la_LIBADD = $(COMMON_LIBS)
+
+## The location of the windows project file for each binary we make
+WINDOWS_PROJECTS = google-glog.sln
+WINDOWS_PROJECTS += vsprojects/libglog/libglog.vcproj
+WINDOWS_PROJECTS += vsprojects/logging_unittest/logging_unittest.vcproj
+WINDOWS_PROJECTS += vsprojects/libglog_static/libglog_static.vcproj
+WINDOWS_PROJECTS += vsprojects/logging_unittest_static/logging_unittest_static.vcproj
+
+## ^^^^ END OF RULES TO MAKE THE LIBRARIES, BINARIES, AND UNITTESTS
+
+
+## This should always include $(TESTS), but may also include other
+## binaries that you compile but don't want automatically installed.
+noinst_PROGRAMS = $(TESTS) $(TEST_BINARIES)
+
+rpm: dist-gzip packages/rpm.sh packages/rpm/rpm.spec
+	@cd packages && ./rpm.sh ${PACKAGE} ${VERSION}
+
+deb: dist-gzip packages/deb.sh packages/deb/*
+	@cd packages && ./deb.sh ${PACKAGE} ${VERSION}
+
+# Windows wants write permission to .vcproj files and maybe even sln files.
+dist-hook:
+	test -e "$(distdir)/vsprojects" \
+	   && chmod -R u+w $(distdir)/*.sln $(distdir)/vsprojects/
+
+libtool: $(LIBTOOL_DEPS)
+	$(SHELL) ./config.status --recheck
+
+EXTRA_DIST = packages/rpm.sh packages/rpm/rpm.spec \
+	packages/deb.sh packages/deb/* \
+	$(SCRIPTS) src/logging_unittest.err src/demangle_unittest.txt \
+	src/windows/config.h src/windows/port.h src/windows/port.cc \
+	src/windows/preprocess.sh \
+	src/windows/glog/log_severity.h src/windows/glog/logging.h \
+	src/windows/glog/raw_logging.h src/windows/glog/stl_logging.h \
+	src/windows/glog/vlog_is_on.h \
+	$(WINDOWS_PROJECTS)
+
+CLEANFILES = core demangle.dm demangle.nm signalhandler.out* \
+	signalhandler_unittest.*.log.INFO.*
+
+# Add pkgconfig file
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = libglog.pc

文件差异内容过多而无法显示
+ 2071 - 0
third-party/glog-0.3.5/Makefile.in


+ 0 - 0
third-party/glog-0.3.5/NEWS


+ 5 - 0
third-party/glog-0.3.5/README

@@ -0,0 +1,5 @@
+This repository contains a C++ implementation of the Google logging
+module.  Documentation for the implementation is in doc/.
+
+See INSTALL for (generic) installation instructions for C++: basically
+   ./configure && make && make install

+ 26 - 0
third-party/glog-0.3.5/README.windows

@@ -0,0 +1,26 @@
+This project has begun being ported to Windows.  A working solution
+file exists in this directory:
+    google-glog.sln
+
+You can load this solution file into VC++ 9.0 (Visual Studio
+2008).  You may also be able to use this solution file with older
+Visual Studios by converting the solution file.
+
+Note that stack tracing and some unittests are not ported
+yet.
+
+You can also link glog code in statically -- see the example project
+libglog_static and logging_unittest_static, which does this.  For this
+to work, you'll need to add "/D GOOGLE_GLOG_DLL_DECL=" to the compile
+line of every glog's .cc file.
+
+I have little experience with Windows programming, so there may be
+better ways to set this up than I've done!  If you run across any
+problems, please post to the google-glog Google Group, or report
+them on the google-glog Google Code site:
+   http://groups.google.com/group/google-glog
+   https://github.com/google/glog/issues
+
+-- Shinichiro Hamaji
+
+Last modified: 23 January 2009

文件差异内容过多而无法显示
+ 1193 - 0
third-party/glog-0.3.5/aclocal.m4


+ 69 - 0
third-party/glog-0.3.5/cmake/DetermineGflagsNamespace.cmake

@@ -0,0 +1,69 @@
+macro(determine_gflags_namespace VARIABLE)
+  if (NOT DEFINED "${VARIABLE}")
+    if (CMAKE_REQUIRED_INCLUDES)
+      set (CHECK_INCLUDE_FILE_CXX_INCLUDE_DIRS "-DINCLUDE_DIRECTORIES=${CMAKE_REQUIRED_INCLUDES}")
+    else ()
+      set (CHECK_INCLUDE_FILE_CXX_INCLUDE_DIRS)
+    endif ()
+
+    set(MACRO_CHECK_INCLUDE_FILE_FLAGS ${CMAKE_REQUIRED_FLAGS})
+
+    set(_NAMESPACES gflags google)
+    set(_check_code
+"
+#include <gflags/gflags.h>
+
+int main(int argc, char**argv)
+{
+  GFLAGS_NAMESPACE::ParseCommandLineFlags(&argc, &argv, true);
+}
+")
+    if (NOT CMAKE_REQUIRED_QUIET)
+      message (STATUS "Looking for gflags namespace")
+    endif ()
+    if (${ARGC} EQUAL 3)
+      set (CMAKE_CXX_FLAGS_SAVE ${CMAKE_CXX_FLAGS})
+      set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${ARGV2}")
+    endif ()
+
+    set (_check_file
+        ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/DetermineGflagsNamespace.cxx)
+
+    foreach (_namespace ${_NAMESPACES})
+      file (WRITE "${_check_file}" "${_check_code}")
+      try_compile (${VARIABLE}
+        "${CMAKE_BINARY_DIR}" "${_check_file}"
+        COMPILE_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS}" -DGFLAGS_NAMESPACE=${_namespace}
+        LINK_LIBRARIES "${gflags_LIBRARIES}"
+        CMAKE_FLAGS -DINCLUDE_DIRECTORIES:STRING="${gflags_INCLUDE_DIR}"
+        OUTPUT_VARIABLE OUTPUT)
+
+      if (${VARIABLE})
+        set (${VARIABLE} ${_namespace} CACHE INTERNAL "gflags namespace" FORCE)
+        break ()
+      else ()
+        file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+          "Determining the gflags namespace ${_namespace} failed with the following output:\n"
+          "${OUTPUT}\n\n")
+      endif ()
+    endforeach (_namespace)
+
+    if (${ARGC} EQUAL 3)
+      set (CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS_SAVE})
+    endif ()
+
+    if (${VARIABLE})
+      if (NOT CMAKE_REQUIRED_QUIET)
+        message (STATUS "Looking for gflags namespace - ${${VARIABLE}}")
+      endif ()
+      file (APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+        "Determining the gflags namespace passed with the following output:\n"
+        "${OUTPUT}\n\n")
+    else ()
+      if (NOT CMAKE_REQUIRED_QUIET)
+        message (STATUS "Looking for gflags namespace - failed")
+      endif ()
+      set (${VARIABLE} ${_namespace} CACHE INTERNAL "gflags namespace")
+    endif ()
+  endif ()
+endmacro ()

+ 30 - 0
third-party/glog-0.3.5/cmake/INSTALL.md

@@ -0,0 +1,30 @@
+Building Glog with CMake
+========================
+
+1. Create a build directory and `cd` to it.
+2. Run
+    ```bash
+    cmake path/to/glog
+    ```
+
+3. Afterwards, generated files (GNU make, Visual Studio, etc.) can be used to
+   compile the project.
+
+
+Consuming Glog in a CMake Project
+=================================
+
+To use Glog in your project `myproj`, use:
+
+```cmake
+cmake_minimum_required (VERSION 3.0)
+project (myproj)
+
+find_package (glog 0.3.5 REQUIRED)
+
+add_executable (myapp main.cpp)
+target_link_libraries (myapp glog::glog)
+```
+
+Compile definitions and options will be added automatically to your target as
+needed.

+ 99 - 0
third-party/glog-0.3.5/compile

@@ -0,0 +1,99 @@
+#! /bin/sh
+
+# Wrapper for compilers which do not understand `-c -o'.
+
+# Copyright 1999, 2000 Free Software Foundation, Inc.
+# Written by Tom Tromey <tromey@cygnus.com>.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Usage:
+# compile PROGRAM [ARGS]...
+# `-o FOO.o' is removed from the args passed to the actual compile.
+
+prog=$1
+shift
+
+ofile=
+cfile=
+args=
+while test $# -gt 0; do
+   case "$1" in
+    -o)
+       # configure might choose to run compile as `compile cc -o foo foo.c'.
+       # So we do something ugly here.
+       ofile=$2
+       shift
+       case "$ofile" in
+	*.o | *.obj)
+	   ;;
+	*)
+	   args="$args -o $ofile"
+	   ofile=
+	   ;;
+       esac
+       ;;
+    *.c)
+       cfile=$1
+       args="$args $1"
+       ;;
+    *)
+       args="$args $1"
+       ;;
+   esac
+   shift
+done
+
+if test -z "$ofile" || test -z "$cfile"; then
+   # If no `-o' option was seen then we might have been invoked from a
+   # pattern rule where we don't need one.  That is ok -- this is a
+   # normal compilation that the losing compiler can handle.  If no
+   # `.c' file was seen then we are probably linking.  That is also
+   # ok.
+   exec "$prog" $args
+fi
+
+# Name of file we expect compiler to create.
+cofile=`echo $cfile | sed -e 's|^.*/||' -e 's/\.c$/.o/'`
+
+# Create the lock directory.
+# Note: use `[/.-]' here to ensure that we don't use the same name
+# that we are using for the .o file.  Also, base the name on the expected
+# object file name, since that is what matters with a parallel build.
+lockdir=`echo $cofile | sed -e 's|[/.-]|_|g'`.d
+while true; do
+   if mkdir $lockdir > /dev/null 2>&1; then
+      break
+   fi
+   sleep 1
+done
+# FIXME: race condition here if user kills between mkdir and trap.
+trap "rmdir $lockdir; exit 1" 1 2 15
+
+# Run the compile.
+"$prog" $args
+status=$?
+
+if test -f "$cofile"; then
+   mv "$cofile" "$ofile"
+fi
+
+rmdir $lockdir
+exit $status

文件差异内容过多而无法显示
+ 1519 - 0
third-party/glog-0.3.5/config.guess


文件差异内容过多而无法显示
+ 1626 - 0
third-party/glog-0.3.5/config.sub


文件差异内容过多而无法显示
+ 20101 - 0
third-party/glog-0.3.5/configure


+ 236 - 0
third-party/glog-0.3.5/configure.ac

@@ -0,0 +1,236 @@
+## Process this file with autoconf to produce configure.
+## In general, the safest way to proceed is to run the following:
+##    % aclocal -I . -I `pwd`/../autoconf && autoheader && autoconf && automake
+
+# make sure we're interpreted by some minimal autoconf
+AC_PREREQ(2.57)
+
+AC_INIT(glog, 0.3.5, opensource@google.com)
+# The argument here is just something that should be in the current directory
+# (for sanity checking)
+AC_CONFIG_SRCDIR(README)
+AC_CONFIG_MACRO_DIR([m4])
+AM_INIT_AUTOMAKE
+AM_CONFIG_HEADER(src/config.h)
+
+AC_LANG(C++)
+
+# Checks for programs.
+AC_PROG_CC
+AC_PROG_CPP
+AC_PROG_CXX
+AM_CONDITIONAL(GCC, test "$GCC" = yes)   # let the Makefile know if we're gcc
+
+AC_PROG_LIBTOOL
+AC_SUBST(LIBTOOL_DEPS)
+
+# Check whether some low-level functions/files are available
+AC_HEADER_STDC
+
+# These are tested for by AC_HEADER_STDC, but I check again to set the var
+AC_CHECK_HEADER(stdint.h, ac_cv_have_stdint_h=1, ac_cv_have_stdint_h=0)
+AC_CHECK_HEADER(sys/types.h, ac_cv_have_systypes_h=1, ac_cv_have_systypes_h=0)
+AC_CHECK_HEADER(inttypes.h, ac_cv_have_inttypes_h=1, ac_cv_have_inttypes_h=0)
+AC_CHECK_HEADERS(unistd.h, ac_cv_have_unistd_h=1, ac_cv_have_unistd_h=0)
+AC_CHECK_HEADERS(syscall.h)
+AC_CHECK_HEADERS(sys/syscall.h)
+# For backtrace with glibc.
+AC_CHECK_HEADERS(execinfo.h)
+# For backtrace with libunwind.
+AC_CHECK_HEADERS(libunwind.h, ac_cv_have_libunwind_h=1, ac_cv_have_libunwind_h=0)
+AC_CHECK_HEADERS(ucontext.h)
+AC_CHECK_HEADERS(sys/utsname.h)
+AC_CHECK_HEADERS(pwd.h)
+AC_CHECK_HEADERS(syslog.h)
+AC_CHECK_HEADERS(sys/time.h)
+AC_CHECK_HEADERS(glob.h)
+# For backtrace with gcc.
+AC_CHECK_HEADERS(unwind.h)
+
+AC_CHECK_HEADER(windows.h, ac_cv_have_windows_h=1, ac_cv_have_windows_h=0)
+if test x"$ac_cv_have_windows_h" = x"1"; then
+  MINGW_CFLAGS=-Isrc/windows
+fi
+
+AC_CHECK_SIZEOF(void *)
+
+# These are the types I need.  We look for them in either stdint.h,
+# sys/types.h, or inttypes.h, all of which are part of the default-includes.
+AC_CHECK_TYPE(uint16_t, ac_cv_have_uint16_t=1, ac_cv_have_uint16_t=0)
+AC_CHECK_TYPE(u_int16_t, ac_cv_have_u_int16_t=1, ac_cv_have_u_int16_t=0)
+AC_CHECK_TYPE(__uint16, ac_cv_have___uint16=1, ac_cv_have___uint16=0)
+
+AC_CHECK_FUNC(sigaltstack,
+              AC_DEFINE(HAVE_SIGALTSTACK, 1,
+                        [Define if you have the `sigaltstack' function]))
+AC_CHECK_FUNC(sigaction,
+              AC_DEFINE(HAVE_SIGACTION, 1,
+                        [Define if you have the 'sigaction' function]))
+AC_CHECK_FUNC(dladdr,
+              AC_DEFINE(HAVE_DLADDR, 1,
+                        [Define if you have the `dladdr' function]))
+AC_CHECK_FUNC(fcntl,
+              AC_DEFINE(HAVE_FCNTL, 1,
+                        [Define if you have the `fcntl' function]))
+AC_CHECK_FUNC(pread,
+              AC_DEFINE(HAVE_PREAD, 1,
+                        [Define if you have the 'pread' function]))
+AC_CHECK_FUNC(pwrite,
+              AC_DEFINE(HAVE_PWRITE, 1,
+                        [Define if you have the 'pwrite' function]))
+
+AX_C___ATTRIBUTE__
+# We only care about these two attributes.
+if test x"$ac_cv___attribute__" = x"yes"; then
+  ac_cv___attribute___noreturn="__attribute__ ((noreturn))"
+  ac_cv___attribute___noinline="__attribute__ ((noinline))"
+  ac_cv___attribute___printf_4_5="__attribute__((__format__ (__printf__, 4, 5)))"
+else
+  ac_cv___attribute___noreturn=
+  ac_cv___attribute___noinline=
+  ac_cv___attribute___printf_4_5=
+fi
+
+AX_C___BUILTIN_EXPECT
+if test x"$ac_cv___builtin_expect" = x"yes"; then
+  ac_cv_have___builtin_expect=1
+else
+  ac_cv_have___builtin_expect=0
+fi
+
+AX_C___SYNC_VAL_COMPARE_AND_SWAP
+
+# On x86_64, instead of libunwind, we can choose to compile with frame-pointers
+# (This isn't needed on i386, where -fno-omit-frame-pointer is the default).
+AC_ARG_ENABLE(frame_pointers,
+              AS_HELP_STRING([--enable-frame-pointers],
+                             [On x86_64 systems, compile with -fno-omit-frame-pointer (see INSTALL)]),,
+              enable_frame_pointers=no)
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM(, [return __x86_64__ == 1 ? 0 : 1])],
+                  [is_x86_64=yes], [is_x86_64=no])
+AM_CONDITIONAL(ENABLE_FRAME_POINTERS, test "$enable_frame_pointers" = yes)
+AM_CONDITIONAL(X86_64, test "$is_x86_64" = yes)
+
+AC_ARG_ENABLE(rtti,
+              AS_HELP_STRING([--disable-rtti],
+                             [Disable RTTI in glog]))
+AM_CONDITIONAL(DISABLE_RTTI, test x"$enable_rtti" = x"no")
+if test x"$enable_rtti" = x"no"; then
+  AC_DEFINE(DISABLE_RTTI, 1, [define if glog doesn't use RTTI])
+fi
+
+# Some of the code in this directory depends on pthreads
+ACX_PTHREAD
+if test x"$acx_pthread_ok" = x"yes"; then
+  # To make libglog depend on libpthread on Linux, we need to add
+  # -lpthread in addition to -pthread.
+  AC_CHECK_LIB(pthread, pthread_self)
+fi
+
+# Check if there is google-gflags library installed.
+SAVE_CFLAGS="$CFLAGS"
+SAVE_LIBS="$LIBS"
+AC_ARG_WITH(gflags, AS_HELP_STRING[--with-gflags=GFLAGS_DIR],
+  GFLAGS_CFLAGS="-I${with_gflags}/include"
+  GFLAGS_LIBS="-L${with_gflags}/lib -lgflags"
+  CFLAGS="$CFLAGS $GFLAGS_CFLAGS"
+  LIBS="$LIBS $GFLAGS_LIBS"
+)
+AC_CHECK_LIB(gflags, main, ac_cv_have_libgflags=1, ac_cv_have_libgflags=0)
+if test x"$ac_cv_have_libgflags" = x"1"; then
+  AC_DEFINE(HAVE_LIB_GFLAGS, 1, [define if you have google gflags library])
+  if test x"$GFLAGS_LIBS" = x""; then
+    GFLAGS_LIBS="-lgflags"
+  fi
+else
+  GFLAGS_CFLAGS=
+  GFLAGS_LIBS=
+fi
+CFLAGS="$SAVE_CFLAGS"
+LIBS="$SAVE_LIBS"
+
+# TODO(hamaji): Use official m4 macros provided by testing libraries
+#               once the m4 macro of Google Mocking becomes ready.
+# Check if there is Google Test library installed.
+AC_CHECK_PROG(GTEST_CONFIG, gtest-config, "yes")
+AC_CHECK_LIB(gtest, main, have_gtest_lib="yes")
+if test x"$GTEST_CONFIG" = "xyes" -a x"$have_gtest_lib" = "xyes"; then
+  GTEST_CFLAGS=`gtest-config --cppflags --cxxflags`
+  GTEST_LIBS=`gtest-config --ldflags --libs`
+  AC_DEFINE(HAVE_LIB_GTEST, 1, [define if you have google gtest library])
+
+  # Check if there is Google Mocking library installed.
+  AC_CHECK_PROG(GMOCK_CONFIG, gmock-config, "yes")
+  if test x"$GMOCK_CONFIG" = "xyes"; then
+    GMOCK_CFLAGS=`gmock-config --cppflags --cxxflags`
+    GMOCK_LIBS=`gmock-config --ldflags --libs`
+    AC_DEFINE(HAVE_LIB_GMOCK, 1, [define if you have google gmock library])
+  else
+    # We don't run test cases which use Google Mocking framework.
+    GMOCK_CFLAGS=
+    GMOCK_LIBS=
+  fi
+else
+  # We'll use src/googletest.h for our unittests.
+  GTEST_CFLAGS=
+  GTEST_LIBS=
+fi
+AM_CONDITIONAL(HAVE_GMOCK, test x"$GMOCK_CONFIG" = "xyes")
+
+# We want to link in libunwind if it exists
+UNWIND_LIBS=
+# Unfortunately, we need to check the header file in addition to the
+# lib file to check if libunwind is available since libunwind-0.98
+# doesn't install all necessary header files.
+if test x"$ac_cv_have_libunwind_h" = x"1"; then
+ AC_CHECK_LIB(unwind, backtrace, UNWIND_LIBS=-lunwind)
+fi
+AC_SUBST(UNWIND_LIBS)
+if test x"$UNWIND_LIBS" != x""; then
+  AC_DEFINE(HAVE_LIB_UNWIND, 1, [define if you have libunwind])
+fi
+
+# We'd like to use read/write locks in several places in the code.
+# See if our pthreads support extends to that.  Note: for linux, it
+# does as long as you define _XOPEN_SOURCE appropriately.
+AC_RWLOCK
+
+# Find out what namespace 'normal' STL code lives in, and also what namespace
+# the user wants our classes to be defined in
+AC_CXX_STL_NAMESPACE
+AC_DEFINE_GOOGLE_NAMESPACE(google)
+
+AC_CXX_USING_OPERATOR
+
+AC_PC_FROM_UCONTEXT(AC_MSG_WARN(Could not find the PC.  Will not output failed addresses...))
+
+AC_DEFINE_UNQUOTED(TEST_SRC_DIR, "$srcdir", [location of source code])
+
+# These are what's needed by logging.h.in and raw_logging.h.in
+AC_SUBST(ac_google_start_namespace)
+AC_SUBST(ac_google_end_namespace)
+AC_SUBST(ac_google_namespace)
+AC_SUBST(ac_cv_cxx_using_operator)
+AC_SUBST(ac_cv___attribute___noreturn)
+AC_SUBST(ac_cv___attribute___noinline)
+AC_SUBST(ac_cv___attribute___printf_4_5)
+AC_SUBST(ac_cv_have___builtin_expect)
+AC_SUBST(ac_cv_have_stdint_h)
+AC_SUBST(ac_cv_have_systypes_h)
+AC_SUBST(ac_cv_have_inttypes_h)
+AC_SUBST(ac_cv_have_unistd_h)
+AC_SUBST(ac_cv_have_uint16_t)
+AC_SUBST(ac_cv_have_u_int16_t)
+AC_SUBST(ac_cv_have___uint16)
+AC_SUBST(ac_cv_have_libgflags)
+AC_SUBST(GFLAGS_CFLAGS)
+AC_SUBST(GTEST_CFLAGS)
+AC_SUBST(GMOCK_CFLAGS)
+AC_SUBST(MINGW_CFLAGS)
+AC_SUBST(GFLAGS_LIBS)
+AC_SUBST(GTEST_LIBS)
+AC_SUBST(GMOCK_LIBS)
+
+# Write generated configuration file
+AC_CONFIG_FILES([Makefile src/glog/logging.h src/glog/raw_logging.h src/glog/vlog_is_on.h src/glog/stl_logging.h])
+AC_OUTPUT(libglog.pc)

+ 589 - 0
third-party/glog-0.3.5/depcomp

@@ -0,0 +1,589 @@
+#! /bin/sh
+# depcomp - compile a program generating dependencies as side-effects
+
+scriptversion=2007-03-29.01
+
+# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007 Free Software
+# Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
+
+case $1 in
+  '')
+     echo "$0: No command.  Try \`$0 --help' for more information." 1>&2
+     exit 1;
+     ;;
+  -h | --h*)
+    cat <<\EOF
+Usage: depcomp [--help] [--version] PROGRAM [ARGS]
+
+Run PROGRAMS ARGS to compile a file, generating dependencies
+as side-effects.
+
+Environment variables:
+  depmode     Dependency tracking mode.
+  source      Source file read by `PROGRAMS ARGS'.
+  object      Object file output by `PROGRAMS ARGS'.
+  DEPDIR      directory where to store dependencies.
+  depfile     Dependency file to output.
+  tmpdepfile  Temporary file to use when outputing dependencies.
+  libtool     Whether libtool is used (yes/no).
+
+Report bugs to <bug-automake@gnu.org>.
+EOF
+    exit $?
+    ;;
+  -v | --v*)
+    echo "depcomp $scriptversion"
+    exit $?
+    ;;
+esac
+
+if test -z "$depmode" || test -z "$source" || test -z "$object"; then
+  echo "depcomp: Variables source, object and depmode must be set" 1>&2
+  exit 1
+fi
+
+# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
+depfile=${depfile-`echo "$object" |
+  sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
+tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
+
+rm -f "$tmpdepfile"
+
+# Some modes work just like other modes, but use different flags.  We
+# parameterize here, but still list the modes in the big case below,
+# to make depend.m4 easier to write.  Note that we *cannot* use a case
+# here, because this file can only contain one case statement.
+if test "$depmode" = hp; then
+  # HP compiler uses -M and no extra arg.
+  gccflag=-M
+  depmode=gcc
+fi
+
+if test "$depmode" = dashXmstdout; then
+   # This is just like dashmstdout with a different argument.
+   dashmflag=-xM
+   depmode=dashmstdout
+fi
+
+case "$depmode" in
+gcc3)
+## gcc 3 implements dependency tracking that does exactly what
+## we want.  Yay!  Note: for some reason libtool 1.4 doesn't like
+## it if -MD -MP comes after the -MF stuff.  Hmm.
+## Unfortunately, FreeBSD c89 acceptance of flags depends upon
+## the command line argument order; so add the flags where they
+## appear in depend2.am.  Note that the slowdown incurred here
+## affects only configure: in makefiles, %FASTDEP% shortcuts this.
+  for arg
+  do
+    case $arg in
+    -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;;
+    *)  set fnord "$@" "$arg" ;;
+    esac
+    shift # fnord
+    shift # $arg
+  done
+  "$@"
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  mv "$tmpdepfile" "$depfile"
+  ;;
+
+gcc)
+## There are various ways to get dependency output from gcc.  Here's
+## why we pick this rather obscure method:
+## - Don't want to use -MD because we'd like the dependencies to end
+##   up in a subdir.  Having to rename by hand is ugly.
+##   (We might end up doing this anyway to support other compilers.)
+## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
+##   -MM, not -M (despite what the docs say).
+## - Using -M directly means running the compiler twice (even worse
+##   than renaming).
+  if test -z "$gccflag"; then
+    gccflag=-MD,
+  fi
+  "$@" -Wp,"$gccflag$tmpdepfile"
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
+## The second -e expression handles DOS-style file names with drive letters.
+  sed -e 's/^[^:]*: / /' \
+      -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
+## This next piece of magic avoids the `deleted header file' problem.
+## The problem is that when a header file which appears in a .P file
+## is deleted, the dependency causes make to die (because there is
+## typically no way to rebuild the header).  We avoid this by adding
+## dummy dependencies for each header file.  Too bad gcc doesn't do
+## this for us directly.
+  tr ' ' '
+' < "$tmpdepfile" |
+## Some versions of gcc put a space before the `:'.  On the theory
+## that the space means something, we add a space to the output as
+## well.
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly.  Breaking it into two sed invocations is a workaround.
+    sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+hp)
+  # This case exists only to let depend.m4 do its work.  It works by
+  # looking at the text of this script.  This case will never be run,
+  # since it is checked for above.
+  exit 1
+  ;;
+
+sgi)
+  if test "$libtool" = yes; then
+    "$@" "-Wp,-MDupdate,$tmpdepfile"
+  else
+    "$@" -MDupdate "$tmpdepfile"
+  fi
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+
+  if test -f "$tmpdepfile"; then  # yes, the sourcefile depend on other files
+    echo "$object : \\" > "$depfile"
+
+    # Clip off the initial element (the dependent).  Don't try to be
+    # clever and replace this with sed code, as IRIX sed won't handle
+    # lines with more than a fixed number of characters (4096 in
+    # IRIX 6.2 sed, 8192 in IRIX 6.5).  We also remove comment lines;
+    # the IRIX cc adds comments like `#:fec' to the end of the
+    # dependency line.
+    tr ' ' '
+' < "$tmpdepfile" \
+    | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
+    tr '
+' ' ' >> $depfile
+    echo >> $depfile
+
+    # The second pass generates a dummy entry for each header file.
+    tr ' ' '
+' < "$tmpdepfile" \
+   | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
+   >> $depfile
+  else
+    # The sourcefile does not contain any dependencies, so just
+    # store a dummy comment line, to avoid errors with the Makefile
+    # "include basename.Plo" scheme.
+    echo "#dummy" > "$depfile"
+  fi
+  rm -f "$tmpdepfile"
+  ;;
+
+aix)
+  # The C for AIX Compiler uses -M and outputs the dependencies
+  # in a .u file.  In older versions, this file always lives in the
+  # current directory.  Also, the AIX compiler puts `$object:' at the
+  # start of each line; $object doesn't have directory information.
+  # Version 6 uses the directory in both cases.
+  dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
+  test "x$dir" = "x$object" && dir=
+  base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+  if test "$libtool" = yes; then
+    tmpdepfile1=$dir$base.u
+    tmpdepfile2=$base.u
+    tmpdepfile3=$dir.libs/$base.u
+    "$@" -Wc,-M
+  else
+    tmpdepfile1=$dir$base.u
+    tmpdepfile2=$dir$base.u
+    tmpdepfile3=$dir$base.u
+    "$@" -M
+  fi
+  stat=$?
+
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+    exit $stat
+  fi
+
+  for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+  do
+    test -f "$tmpdepfile" && break
+  done
+  if test -f "$tmpdepfile"; then
+    # Each line is of the form `foo.o: dependent.h'.
+    # Do two passes, one to just change these to
+    # `$object: dependent.h' and one to simply `dependent.h:'.
+    sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
+    # That's a tab and a space in the [].
+    sed -e 's,^.*\.[a-z]*:[	 ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
+  else
+    # The sourcefile does not contain any dependencies, so just
+    # store a dummy comment line, to avoid errors with the Makefile
+    # "include basename.Plo" scheme.
+    echo "#dummy" > "$depfile"
+  fi
+  rm -f "$tmpdepfile"
+  ;;
+
+icc)
+  # Intel's C compiler understands `-MD -MF file'.  However on
+  #    icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c
+  # ICC 7.0 will fill foo.d with something like
+  #    foo.o: sub/foo.c
+  #    foo.o: sub/foo.h
+  # which is wrong.  We want:
+  #    sub/foo.o: sub/foo.c
+  #    sub/foo.o: sub/foo.h
+  #    sub/foo.c:
+  #    sub/foo.h:
+  # ICC 7.1 will output
+  #    foo.o: sub/foo.c sub/foo.h
+  # and will wrap long lines using \ :
+  #    foo.o: sub/foo.c ... \
+  #     sub/foo.h ... \
+  #     ...
+
+  "$@" -MD -MF "$tmpdepfile"
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+  # Each line is of the form `foo.o: dependent.h',
+  # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
+  # Do two passes, one to just change these to
+  # `$object: dependent.h' and one to simply `dependent.h:'.
+  sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
+  # Some versions of the HPUX 10.20 sed can't process this invocation
+  # correctly.  Breaking it into two sed invocations is a workaround.
+  sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" |
+    sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+hp2)
+  # The "hp" stanza above does not work with aCC (C++) and HP's ia64
+  # compilers, which have integrated preprocessors.  The correct option
+  # to use with these is +Maked; it writes dependencies to a file named
+  # 'foo.d', which lands next to the object file, wherever that
+  # happens to be.
+  # Much of this is similar to the tru64 case; see comments there.
+  dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
+  test "x$dir" = "x$object" && dir=
+  base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+  if test "$libtool" = yes; then
+    tmpdepfile1=$dir$base.d
+    tmpdepfile2=$dir.libs/$base.d
+    "$@" -Wc,+Maked
+  else
+    tmpdepfile1=$dir$base.d
+    tmpdepfile2=$dir$base.d
+    "$@" +Maked
+  fi
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+     rm -f "$tmpdepfile1" "$tmpdepfile2"
+     exit $stat
+  fi
+
+  for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2"
+  do
+    test -f "$tmpdepfile" && break
+  done
+  if test -f "$tmpdepfile"; then
+    sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile"
+    # Add `dependent.h:' lines.
+    sed -ne '2,${; s/^ *//; s/ \\*$//; s/$/:/; p;}' "$tmpdepfile" >> "$depfile"
+  else
+    echo "#dummy" > "$depfile"
+  fi
+  rm -f "$tmpdepfile" "$tmpdepfile2"
+  ;;
+
+tru64)
+   # The Tru64 compiler uses -MD to generate dependencies as a side
+   # effect.  `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
+   # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
+   # dependencies in `foo.d' instead, so we check for that too.
+   # Subdirectories are respected.
+   dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
+   test "x$dir" = "x$object" && dir=
+   base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+
+   if test "$libtool" = yes; then
+      # With Tru64 cc, shared objects can also be used to make a
+      # static library.  This mechanism is used in libtool 1.4 series to
+      # handle both shared and static libraries in a single compilation.
+      # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d.
+      #
+      # With libtool 1.5 this exception was removed, and libtool now
+      # generates 2 separate objects for the 2 libraries.  These two
+      # compilations output dependencies in $dir.libs/$base.o.d and
+      # in $dir$base.o.d.  We have to check for both files, because
+      # one of the two compilations can be disabled.  We should prefer
+      # $dir$base.o.d over $dir.libs/$base.o.d because the latter is
+      # automatically cleaned when .libs/ is deleted, while ignoring
+      # the former would cause a distcleancheck panic.
+      tmpdepfile1=$dir.libs/$base.lo.d   # libtool 1.4
+      tmpdepfile2=$dir$base.o.d          # libtool 1.5
+      tmpdepfile3=$dir.libs/$base.o.d    # libtool 1.5
+      tmpdepfile4=$dir.libs/$base.d      # Compaq CCC V6.2-504
+      "$@" -Wc,-MD
+   else
+      tmpdepfile1=$dir$base.o.d
+      tmpdepfile2=$dir$base.d
+      tmpdepfile3=$dir$base.d
+      tmpdepfile4=$dir$base.d
+      "$@" -MD
+   fi
+
+   stat=$?
+   if test $stat -eq 0; then :
+   else
+      rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
+      exit $stat
+   fi
+
+   for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
+   do
+     test -f "$tmpdepfile" && break
+   done
+   if test -f "$tmpdepfile"; then
+      sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
+      # That's a tab and a space in the [].
+      sed -e 's,^.*\.[a-z]*:[	 ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
+   else
+      echo "#dummy" > "$depfile"
+   fi
+   rm -f "$tmpdepfile"
+   ;;
+
+#nosideeffect)
+  # This comment above is used by automake to tell side-effect
+  # dependency tracking mechanisms from slower ones.
+
+dashmstdout)
+  # Important note: in order to support this mode, a compiler *must*
+  # always write the preprocessed file to stdout, regardless of -o.
+  "$@" || exit $?
+
+  # Remove the call to Libtool.
+  if test "$libtool" = yes; then
+    while test $1 != '--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+
+  # Remove `-o $object'.
+  IFS=" "
+  for arg
+  do
+    case $arg in
+    -o)
+      shift
+      ;;
+    $object)
+      shift
+      ;;
+    *)
+      set fnord "$@" "$arg"
+      shift # fnord
+      shift # $arg
+      ;;
+    esac
+  done
+
+  test -z "$dashmflag" && dashmflag=-M
+  # Require at least two characters before searching for `:'
+  # in the target name.  This is to cope with DOS-style filenames:
+  # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise.
+  "$@" $dashmflag |
+    sed 's:^[  ]*[^: ][^:][^:]*\:[    ]*:'"$object"'\: :' > "$tmpdepfile"
+  rm -f "$depfile"
+  cat < "$tmpdepfile" > "$depfile"
+  tr ' ' '
+' < "$tmpdepfile" | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly.  Breaking it into two sed invocations is a workaround.
+    sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+dashXmstdout)
+  # This case only exists to satisfy depend.m4.  It is never actually
+  # run, as this mode is specially recognized in the preamble.
+  exit 1
+  ;;
+
+makedepend)
+  "$@" || exit $?
+  # Remove any Libtool call
+  if test "$libtool" = yes; then
+    while test $1 != '--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+  # X makedepend
+  shift
+  cleared=no
+  for arg in "$@"; do
+    case $cleared in
+    no)
+      set ""; shift
+      cleared=yes ;;
+    esac
+    case "$arg" in
+    -D*|-I*)
+      set fnord "$@" "$arg"; shift ;;
+    # Strip any option that makedepend may not understand.  Remove
+    # the object too, otherwise makedepend will parse it as a source file.
+    -*|$object)
+      ;;
+    *)
+      set fnord "$@" "$arg"; shift ;;
+    esac
+  done
+  obj_suffix="`echo $object | sed 's/^.*\././'`"
+  touch "$tmpdepfile"
+  ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
+  rm -f "$depfile"
+  cat < "$tmpdepfile" > "$depfile"
+  sed '1,2d' "$tmpdepfile" | tr ' ' '
+' | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly.  Breaking it into two sed invocations is a workaround.
+    sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile" "$tmpdepfile".bak
+  ;;
+
+cpp)
+  # Important note: in order to support this mode, a compiler *must*
+  # always write the preprocessed file to stdout.
+  "$@" || exit $?
+
+  # Remove the call to Libtool.
+  if test "$libtool" = yes; then
+    while test $1 != '--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+
+  # Remove `-o $object'.
+  IFS=" "
+  for arg
+  do
+    case $arg in
+    -o)
+      shift
+      ;;
+    $object)
+      shift
+      ;;
+    *)
+      set fnord "$@" "$arg"
+      shift # fnord
+      shift # $arg
+      ;;
+    esac
+  done
+
+  "$@" -E |
+    sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
+       -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
+    sed '$ s: \\$::' > "$tmpdepfile"
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  cat < "$tmpdepfile" >> "$depfile"
+  sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+msvisualcpp)
+  # Important note: in order to support this mode, a compiler *must*
+  # always write the preprocessed file to stdout, regardless of -o,
+  # because we must use -o when running libtool.
+  "$@" || exit $?
+  IFS=" "
+  for arg
+  do
+    case "$arg" in
+    "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
+	set fnord "$@"
+	shift
+	shift
+	;;
+    *)
+	set fnord "$@" "$arg"
+	shift
+	shift
+	;;
+    esac
+  done
+  "$@" -E |
+  sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile"
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::	\1 \\:p' >> "$depfile"
+  echo "	" >> "$depfile"
+  . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+none)
+  exec "$@"
+  ;;
+
+*)
+  echo "Unknown depmode $depmode" 1>&2
+  exit 1
+  ;;
+esac
+
+exit 0
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:

+ 115 - 0
third-party/glog-0.3.5/doc/designstyle.css

@@ -0,0 +1,115 @@
+body {
+  background-color: #ffffff;
+  color: black;
+  margin-right: 1in;
+  margin-left: 1in;
+}
+
+
+h1, h2, h3, h4, h5, h6 {
+  color: #3366ff;
+  font-family: sans-serif;
+}
+@media print {
+  /* Darker version for printing */
+  h1, h2, h3, h4, h5, h6 {
+    color: #000080;
+    font-family: helvetica, sans-serif;
+  }
+}
+
+h1 { 
+  text-align: center;
+  font-size: 18pt;
+}
+h2 {
+  margin-left: -0.5in;
+}
+h3 {
+  margin-left: -0.25in;
+}
+h4 {
+  margin-left: -0.125in;
+}
+hr {
+  margin-left: -1in;
+}
+
+/* Definition lists: definition term bold */
+dt {
+  font-weight: bold;
+}
+
+address {
+  text-align: right;
+}
+/* Use the <code> tag for bits of code and <var> for variables and objects. */
+code,pre,samp,var {
+  color: #006000;
+}
+/* Use the <file> tag for file and directory paths and names. */
+file {
+  color: #905050;
+  font-family: monospace;
+}
+/* Use the <kbd> tag for stuff the user should type. */
+kbd {
+  color: #600000;
+}
+div.note p {
+  float: right;
+  width: 3in;
+  margin-right: 0%;
+  padding: 1px;
+  border: 2px solid #6060a0;
+  background-color: #fffff0;
+}
+
+UL.nobullets {
+  list-style-type: none;
+  list-style-image: none;
+  margin-left: -1em;
+}
+
+/*
+body:after {
+  content: "Google Confidential";
+}
+*/
+
+/* pretty printing styles.  See prettify.js */
+.str { color: #080; }
+.kwd { color: #008; }
+.com { color: #800; }
+.typ { color: #606; }
+.lit { color: #066; }
+.pun { color: #660; }
+.pln { color: #000; }
+.tag { color: #008; }
+.atn { color: #606; }
+.atv { color: #080; }
+pre.prettyprint { padding: 2px; border: 1px solid #888; }
+
+.embsrc { background: #eee; }
+
+@media print {
+  .str { color: #060; }
+  .kwd { color: #006; font-weight: bold; }
+  .com { color: #600; font-style: italic; }
+  .typ { color: #404; font-weight: bold; }
+  .lit { color: #044; }
+  .pun { color: #440; }
+  .pln { color: #000; }
+  .tag { color: #006; font-weight: bold; }
+  .atn { color: #404; }
+  .atv { color: #060; }
+}
+
+/* Table Column Headers */
+.hdr { 
+  color: #006; 
+  font-weight: bold; 
+  background-color: #dddddd; }
+.hdr2 { 
+  color: #006; 
+  background-color: #eeeeee; }

+ 613 - 0
third-party/glog-0.3.5/doc/glog.html

@@ -0,0 +1,613 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+
+<html>
+<head>
+<title>How To Use Google Logging Library (glog)</title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<link href="http://www.google.com/favicon.ico" type="image/x-icon"
+      rel="shortcut icon">
+<link href="designstyle.css" type="text/css" rel="stylesheet">
+<style type="text/css">
+<!--
+  ol.bluelist li {
+    color: #3366ff;
+    font-family: sans-serif;
+  }
+  ol.bluelist li p {
+    color: #000;
+    font-family: "Times Roman", times, serif;
+  }
+  ul.blacklist li {
+    color: #000;
+    font-family: "Times Roman", times, serif;
+  }
+//-->
+</style>
+</head>
+
+<body>
+
+<h1>How To Use Google Logging Library (glog)</h1>
+<small>(as of
+<script type=text/javascript>
+  var lm = new Date(document.lastModified);
+  document.write(lm.toDateString());
+</script>)
+</small>
+<br>
+
+<h2> <A NAME=intro>Introduction</A> </h2>
+
+<p><b>Google glog</b> is a library that implements application-level
+logging.  This library provides logging APIs based on C++-style
+streams and various helper macros.
+You can log a message by simply streaming things to LOG(&lt;a
+particular <a href="#severity">severity level</a>&gt;), e.g.
+
+<pre>
+   #include &lt;glog/logging.h&gt;
+
+   int main(int argc, char* argv[]) {
+     // Initialize Google's logging library.
+     google::InitGoogleLogging(argv[0]);
+
+     // ...
+     LOG(INFO) &lt;&lt; "Found " &lt;&lt; num_cookies &lt;&lt; " cookies";
+   }
+</pre>
+
+<p>Google glog defines a series of macros that simplify many common logging
+tasks.  You can log messages by severity level, control logging
+behavior from the command line, log based on conditionals, abort the
+program when expected conditions are not met, introduce your own
+verbose logging levels, and more.  This document describes the
+functionality supported by glog.  Please note that this document
+doesn't describe all features in this library, but the most useful
+ones.  If you want to find less common features, please check
+header files under <code>src/glog</code> directory.
+
+<h2> <A NAME=severity>Severity Level</A> </h2>
+
+<p>
+You can specify one of the following severity levels (in
+increasing order of severity): <code>INFO</code>, <code>WARNING</code>,
+<code>ERROR</code>, and <code>FATAL</code>.
+Logging a <code>FATAL</code> message terminates the program (after the
+message is logged).
+Note that messages of a given severity are logged not only in the
+logfile for that severity, but also in all logfiles of lower severity.
+E.g., a message of severity <code>FATAL</code> will be logged to the
+logfiles of severity <code>FATAL</code>, <code>ERROR</code>,
+<code>WARNING</code>, and <code>INFO</code>.
+
+<p>
+The <code>DFATAL</code> severity logs a <code>FATAL</code> error in
+debug mode (i.e., there is no <code>NDEBUG</code> macro defined), but
+avoids halting the program in production by automatically reducing the
+severity to <code>ERROR</code>.
+
+<p>Unless otherwise specified, glog writes to the filename
+"/tmp/&lt;program name&gt;.&lt;hostname&gt;.&lt;user name&gt;.log.&lt;severity level&gt;.&lt;date&gt;.&lt;time&gt;.&lt;pid&gt;"
+(e.g., "/tmp/hello_world.example.com.hamaji.log.INFO.20080709-222411.10474").
+By default, glog copies the log messages of severity level
+<code>ERROR</code> or <code>FATAL</code> to standard error (stderr)
+in addition to log files.
+
+<h2><A NAME=flags>Setting Flags</A></h2>
+
+<p>Several flags influence glog's output behavior.
+If the <a href="http://code.google.com/p/google-gflags/">Google
+gflags library</a> is installed on your machine, the
+<code>configure</code> script (see the INSTALL file in the package for
+detail of this script) will automatically detect and use it,
+allowing you to pass flags on the command line.  For example, if you
+want to turn the flag <code>--logtostderr</code> on, you can start
+your application with the following command line:
+
+<pre>
+   ./your_application --logtostderr=1
+</pre>
+
+If the Google gflags library isn't installed, you set flags via
+environment variables, prefixing the flag name with "GLOG_", e.g.
+
+<pre>
+   GLOG_logtostderr=1 ./your_application
+</pre>
+
+<!-- TODO(hamaji): Fill the version number
+<p>By glog version 0.x.x, you can use GLOG_* environment variables
+even if you have gflags. If both an environment variable and a flag
+are specified, the value specified by a flag wins. E.g., if GLOG_v=0
+and --v=1, the verbosity will be 1, not 0.
+-->
+
+<p>The following flags are most commonly used:
+
+<dl>
+<dt><code>logtostderr</code> (<code>bool</code>, default=<code>false</code>)
+<dd>Log messages to stderr instead of logfiles.<br>
+Note: you can set binary flags to <code>true</code> by specifying
+<code>1</code>, <code>true</code>, or <code>yes</code> (case
+insensitive).
+Also, you can set binary flags to <code>false</code> by specifying
+<code>0</code>, <code>false</code>, or <code>no</code> (again, case
+insensitive).
+<dt><code>stderrthreshold</code> (<code>int</code>, default=2, which
+is <code>ERROR</code>)
+<dd>Copy log messages at or above this level to stderr in
+addition to logfiles.  The numbers of severity levels
+<code>INFO</code>, <code>WARNING</code>, <code>ERROR</code>, and
+<code>FATAL</code> are 0, 1, 2, and 3, respectively.
+<dt><code>minloglevel</code> (<code>int</code>, default=0, which
+is <code>INFO</code>)
+<dd>Log messages at or above this level.  Again, the numbers of
+severity levels <code>INFO</code>, <code>WARNING</code>,
+<code>ERROR</code>, and <code>FATAL</code> are 0, 1, 2, and 3,
+respectively.
+<dt><code>log_dir</code> (<code>string</code>, default="")
+<dd>If specified, logfiles are written into this directory instead
+of the default logging directory.
+<dt><code>v</code> (<code>int</code>, default=0)
+<dd>Show all <code>VLOG(m)</code> messages for <code>m</code> less or
+equal the value of this flag.  Overridable by --vmodule.
+See <a href="#verbose">the section about verbose logging</a> for more
+detail.
+<dt><code>vmodule</code> (<code>string</code>, default="")
+<dd>Per-module verbose level.  The argument has to contain a
+comma-separated list of &lt;module name&gt;=&lt;log level&gt;.
+&lt;module name&gt;
+is a glob pattern (e.g., <code>gfs*</code> for all modules whose name
+starts with "gfs"), matched against the filename base
+(that is, name ignoring .cc/.h./-inl.h).
+&lt;log level&gt; overrides any value given by --v.
+See also <a href="#verbose">the section about verbose logging</a>.
+</dl>
+
+<p>There are some other flags defined in logging.cc.  Please grep the
+source code for "DEFINE_" to see a complete list of all flags.
+
+<p>You can also modify flag values in your program by modifying global
+variables <code>FLAGS_*</code> . Most settings start working
+immediately after you update <code>FLAGS_*</code> . The exceptions are
+the flags related to destination files. For example, you might want to
+set <code>FLAGS_log_dir</code> before
+calling <code>google::InitGoogleLogging</code> . Here is an example:
+
+<pre>
+   LOG(INFO) << "file";
+   // Most flags work immediately after updating values.
+   FLAGS_logtostderr = 1;
+   LOG(INFO) << "stderr";
+   FLAGS_logtostderr = 0;
+   // This won't change the log destination. If you want to set this
+   // value, you should do this before google::InitGoogleLogging .
+   FLAGS_log_dir = "/some/log/directory";
+   LOG(INFO) << "the same file";
+</pre>
+
+<h2><A NAME=conditional>Conditional / Occasional Logging</A></h2>
+
+<p>Sometimes, you may only want to log a message under certain
+conditions. You can use the following macros to perform conditional
+logging:
+
+<pre>
+   LOG_IF(INFO, num_cookies &gt; 10) &lt;&lt; "Got lots of cookies";
+</pre>
+
+The "Got lots of cookies" message is logged only when the variable
+<code>num_cookies</code> exceeds 10.
+
+If a line of code is executed many times, it may be useful to only log
+a message at certain intervals.  This kind of logging is most useful
+for informational messages.
+
+<pre>
+   LOG_EVERY_N(INFO, 10) &lt;&lt; "Got the " &lt;&lt; google::COUNTER &lt;&lt; "th cookie";
+</pre>
+
+<p>The above line outputs a log messages on the 1st, 11th,
+21st, ... times it is executed.  Note that the special
+<code>google::COUNTER</code> value is used to identify which repetition is
+happening.
+
+<p>You can combine conditional and occasional logging with the
+following macro.
+
+<pre>
+   LOG_IF_EVERY_N(INFO, (size &gt; 1024), 10) &lt;&lt; "Got the " &lt;&lt; google::COUNTER
+                                           &lt;&lt; "th big cookie";
+</pre>
+
+<p>Instead of outputting a message every nth time, you can also limit
+the output to the first n occurrences:
+
+<pre>
+   LOG_FIRST_N(INFO, 20) &lt;&lt; "Got the " &lt;&lt; google::COUNTER &lt;&lt; "th cookie";
+</pre>
+
+<p>Outputs log messages for the first 20 times it is executed.  Again,
+the <code>google::COUNTER</code> identifier indicates which repetition is
+happening.
+
+<h2><A NAME=debug>Debug Mode Support</A></h2>
+
+<p>Special "debug mode" logging macros only have an effect in debug
+mode and are compiled away to nothing for non-debug mode
+compiles.  Use these macros to avoid slowing down your production
+application due to excessive logging.
+
+<pre>
+   DLOG(INFO) &lt;&lt; "Found cookies";
+
+   DLOG_IF(INFO, num_cookies &gt; 10) &lt;&lt; "Got lots of cookies";
+
+   DLOG_EVERY_N(INFO, 10) &lt;&lt; "Got the " &lt;&lt; google::COUNTER &lt;&lt; "th cookie";
+</pre>
+
+<h2><A NAME=check>CHECK Macros</A></h2>
+
+<p>It is a good practice to check expected conditions in your program
+frequently to detect errors as early as possible. The
+<code>CHECK</code> macro provides the ability to abort the application
+when a condition is not met, similar to the <code>assert</code> macro
+defined in the standard C library.
+
+<p><code>CHECK</code> aborts the application if a condition is not
+true.  Unlike <code>assert</code>, it is *not* controlled by
+<code>NDEBUG</code>, so the check will be executed regardless of
+compilation mode.  Therefore, <code>fp-&gt;Write(x)</code> in the
+following example is always executed:
+
+<pre>
+   CHECK(fp-&gt;Write(x) == 4) &lt;&lt; "Write failed!";
+</pre>
+
+<p>There are various helper macros for
+equality/inequality checks - <code>CHECK_EQ</code>,
+<code>CHECK_NE</code>, <code>CHECK_LE</code>, <code>CHECK_LT</code>,
+<code>CHECK_GE</code>, and <code>CHECK_GT</code>.
+They compare two values, and log a
+<code>FATAL</code> message including the two values when the result is
+not as expected.  The values must have <code>operator&lt;&lt;(ostream,
+...)</code> defined.
+
+<p>You may append to the error message like so:
+
+<pre>
+   CHECK_NE(1, 2) &lt;&lt; ": The world must be ending!";
+</pre>
+
+<p>We are very careful to ensure that each argument is evaluated exactly
+once, and that anything which is legal to pass as a function argument is
+legal here.  In particular, the arguments may be temporary expressions
+which will end up being destroyed at the end of the apparent statement,
+for example:
+
+<pre>
+   CHECK_EQ(string("abc")[1], 'b');
+</pre>
+
+<p>The compiler reports an error if one of the arguments is a
+pointer and the other is NULL. To work around this, simply static_cast
+NULL to the type of the desired pointer.
+
+<pre>
+   CHECK_EQ(some_ptr, static_cast&lt;SomeType*&gt;(NULL));
+</pre>
+
+<p>Better yet, use the CHECK_NOTNULL macro:
+
+<pre>
+   CHECK_NOTNULL(some_ptr);
+   some_ptr-&gt;DoSomething();
+</pre>
+
+<p>Since this macro returns the given pointer, this is very useful in
+constructor initializer lists.
+
+<pre>
+   struct S {
+     S(Something* ptr) : ptr_(CHECK_NOTNULL(ptr)) {}
+     Something* ptr_;
+   };
+</pre>
+
+<p>Note that you cannot use this macro as a C++ stream due to this
+feature.  Please use <code>CHECK_EQ</code> described above to log a
+custom message before aborting the application.
+
+<p>If you are comparing C strings (char *), a handy set of macros
+performs case sensitive as well as case insensitive comparisons -
+<code>CHECK_STREQ</code>, <code>CHECK_STRNE</code>,
+<code>CHECK_STRCASEEQ</code>, and <code>CHECK_STRCASENE</code>.  The
+CASE versions are case-insensitive.  You can safely pass <code>NULL</code>
+pointers for this macro.  They treat <code>NULL</code> and any
+non-<code>NULL</code> string as not equal.  Two <code>NULL</code>s are
+equal.
+
+<p>Note that both arguments may be temporary strings which are
+destructed at the end of the current "full expression"
+(e.g., <code>CHECK_STREQ(Foo().c_str(), Bar().c_str())</code> where
+<code>Foo</code> and <code>Bar</code> return C++'s
+<code>std::string</code>).
+
+<p>The <code>CHECK_DOUBLE_EQ</code> macro checks the equality of two
+floating point values, accepting a small error margin.
+<code>CHECK_NEAR</code> accepts a third floating point argument, which
+specifies the acceptable error margin.
+
+<h2><A NAME=verbose>Verbose Logging</A></h2>
+
+<p>When you are chasing difficult bugs, thorough log messages are very
+useful.  However, you may want to ignore too verbose messages in usual
+development.  For such verbose logging, glog provides the
+<code>VLOG</code> macro, which allows you to define your own numeric
+logging levels.  The <code>--v</code> command line option controls
+which verbose messages are logged:
+
+<pre>
+   VLOG(1) &lt;&lt; "I'm printed when you run the program with --v=1 or higher";
+   VLOG(2) &lt;&lt; "I'm printed when you run the program with --v=2 or higher";
+</pre>
+
+<p>With <code>VLOG</code>, the lower the verbose level, the more
+likely messages are to be logged.  For example, if
+<code>--v==1</code>, <code>VLOG(1)</code> will log, but
+<code>VLOG(2)</code> will not log.  This is opposite of the severity
+level, where <code>INFO</code> is 0, and <code>ERROR</code> is 2.
+<code>--minloglevel</code> of 1 will log <code>WARNING</code> and
+above.  Though you can specify any integers for both <code>VLOG</code>
+macro and <code>--v</code> flag, the common values for them are small
+positive integers.  For example, if you write <code>VLOG(0)</code>,
+you should specify <code>--v=-1</code> or lower to silence it.  This
+is less useful since we may not want verbose logs by default in most
+cases.  The <code>VLOG</code> macros always log at the
+<code>INFO</code> log level (when they log at all).
+
+<p>Verbose logging can be controlled from the command line on a
+per-module basis:
+
+<pre>
+   --vmodule=mapreduce=2,file=1,gfs*=3 --v=0
+</pre>
+
+<p>will:
+
+<ul>
+  <li>a. Print VLOG(2) and lower messages from mapreduce.{h,cc}
+  <li>b. Print VLOG(1) and lower messages from file.{h,cc}
+  <li>c. Print VLOG(3) and lower messages from files prefixed with "gfs"
+  <li>d. Print VLOG(0) and lower messages from elsewhere
+</ul>
+
+<p>The wildcarding functionality shown by (c) supports both '*'
+(matches 0 or more characters) and '?' (matches any single character)
+wildcards.  Please also check the section about <a
+href="#flags">command line flags</a>.
+
+<p>There's also <code>VLOG_IS_ON(n)</code> "verbose level" condition
+macro.  This macro returns true when the <code>--v</code> is equal or
+greater than <code>n</code>.  To be used as
+
+<pre>
+   if (VLOG_IS_ON(2)) {
+     // do some logging preparation and logging
+     // that can't be accomplished with just VLOG(2) &lt;&lt; ...;
+   }
+</pre>
+
+<p>Verbose level condition macros <code>VLOG_IF</code>,
+<code>VLOG_EVERY_N</code> and <code>VLOG_IF_EVERY_N</code> behave
+analogous to <code>LOG_IF</code>, <code>LOG_EVERY_N</code>,
+<code>LOF_IF_EVERY</code>, but accept a numeric verbosity level as
+opposed to a severity level.
+
+<pre>
+   VLOG_IF(1, (size &gt; 1024))
+      &lt;&lt; "I'm printed when size is more than 1024 and when you run the "
+         "program with --v=1 or more";
+   VLOG_EVERY_N(1, 10)
+      &lt;&lt; "I'm printed every 10th occurrence, and when you run the program "
+         "with --v=1 or more. Present occurence is " &lt;&lt; google::COUNTER;
+   VLOG_IF_EVERY_N(1, (size &gt; 1024), 10)
+      &lt;&lt; "I'm printed on every 10th occurence of case when size is more "
+         " than 1024, when you run the program with --v=1 or more. ";
+         "Present occurence is " &lt;&lt; google::COUNTER;
+</pre>
+
+<h2> <A name="signal">Failure Signal Handler</A> </h2>
+
+<p>
+The library provides a convenient signal handler that will dump useful
+information when the program crashes on certain signals such as SIGSEGV.
+The signal handler can be installed by
+google::InstallFailureSignalHandler().  The following is an example of output
+from the signal handler.
+
+<pre>
+*** Aborted at 1225095260 (unix time) try "date -d @1225095260" if you are using GNU date ***
+*** SIGSEGV (@0x0) received by PID 17711 (TID 0x7f893090a6f0) from PID 0; stack trace: ***
+PC: @           0x412eb1 TestWaitingLogSink::send()
+    @     0x7f892fb417d0 (unknown)
+    @           0x412eb1 TestWaitingLogSink::send()
+    @     0x7f89304f7f06 google::LogMessage::SendToLog()
+    @     0x7f89304f35af google::LogMessage::Flush()
+    @     0x7f89304f3739 google::LogMessage::~LogMessage()
+    @           0x408cf4 TestLogSinkWaitTillSent()
+    @           0x4115de main
+    @     0x7f892f7ef1c4 (unknown)
+    @           0x4046f9 (unknown)
+</pre>
+
+<p>
+By default, the signal handler writes the failure dump to the standard
+error.  You can customize the destination by InstallFailureWriter().
+
+<h2> <A name="misc">Miscellaneous Notes</A> </h2>
+
+<h3><A NAME=message>Performance of Messages</A></h3>
+
+<p>The conditional logging macros provided by glog (e.g.,
+<code>CHECK</code>, <code>LOG_IF</code>, <code>VLOG</code>, ...) are
+carefully implemented and don't execute the right hand side
+expressions when the conditions are false.  So, the following check
+may not sacrifice the performance of your application.
+
+<pre>
+   CHECK(obj.ok) &lt;&lt; obj.CreatePrettyFormattedStringButVerySlow();
+</pre>
+
+<h3><A NAME=failure>User-defined Failure Function</A></h3>
+
+<p><code>FATAL</code> severity level messages or unsatisfied
+<code>CHECK</code> condition terminate your program.  You can change
+the behavior of the termination by
+<code>InstallFailureFunction</code>.
+
+<pre>
+   void YourFailureFunction() {
+     // Reports something...
+     exit(1);
+   }
+
+   int main(int argc, char* argv[]) {
+     google::InstallFailureFunction(&amp;YourFailureFunction);
+   }
+</pre>
+
+<p>By default, glog tries to dump stacktrace and makes the program
+exit with status 1.  The stacktrace is produced only when you run the
+program on an architecture for which glog supports stack tracing (as
+of September 2008, glog supports stack tracing for x86 and x86_64).
+
+<h3><A NAME=raw>Raw Logging</A></h3>
+
+<p>The header file <code>&lt;glog/raw_logging.h&gt;</code> can be
+used for thread-safe logging, which does not allocate any memory or
+acquire any locks.  Therefore, the macros defined in this
+header file can be used by low-level memory allocation and
+synchronization code.
+Please check <code>src/glog/raw_logging.h.in</code> for detail.
+</p>
+
+<h3><A NAME=plog>Google Style perror()</A></h3>
+
+<p><code>PLOG()</code> and <code>PLOG_IF()</code> and
+<code>PCHECK()</code> behave exactly like their <code>LOG*</code> and
+<code>CHECK</code> equivalents with the addition that they append a
+description of the current state of errno to their output lines.
+E.g.
+
+<pre>
+   PCHECK(write(1, NULL, 2) &gt;= 0) &lt;&lt; "Write NULL failed";
+</pre>
+
+<p>This check fails with the following error message.
+
+<pre>
+   F0825 185142 test.cc:22] Check failed: write(1, NULL, 2) &gt;= 0 Write NULL failed: Bad address [14]
+</pre>
+
+<h3><A NAME=syslog>Syslog</A></h3>
+
+<p><code>SYSLOG</code>, <code>SYSLOG_IF</code>, and
+<code>SYSLOG_EVERY_N</code> macros are available.
+These log to syslog in addition to the normal logs.  Be aware that
+logging to syslog can drastically impact performance, especially if
+syslog is configured for remote logging!  Make sure you understand the
+implications of outputting to syslog before you use these macros. In
+general, it's wise to use these macros sparingly.
+
+<h3><A NAME=strip>Strip Logging Messages</A></h3>
+
+<p>Strings used in log messages can increase the size of your binary
+and present a privacy concern.  You can therefore instruct glog to
+remove all strings which fall below a certain severity level by using
+the GOOGLE_STRIP_LOG macro:
+
+<p>If your application has code like this:
+
+<pre>
+   #define GOOGLE_STRIP_LOG 1    // this must go before the #include!
+   #include &lt;glog/logging.h&gt;
+</pre>
+
+<p>The compiler will remove the log messages whose severities are less
+than the specified integer value.  Since
+<code>VLOG</code> logs at the severity level <code>INFO</code>
+(numeric value <code>0</code>),
+setting <code>GOOGLE_STRIP_LOG</code> to 1 or greater removes
+all log messages associated with <code>VLOG</code>s as well as
+<code>INFO</code> log statements.
+
+<h3><A NAME=windows>Notes for Windows users</A></h3>
+
+<p>Google glog defines a severity level <code>ERROR</code>, which is
+also defined in <code>windows.h</code> . You can make glog not define
+<code>INFO</code>, <code>WARNING</code>, <code>ERROR</code>,
+and <code>FATAL</code> by defining
+<code>GLOG_NO_ABBREVIATED_SEVERITIES</code> before
+including <code>glog/logging.h</code> . Even with this macro, you can
+still use the iostream like logging facilities:
+
+<pre>
+  #define GLOG_NO_ABBREVIATED_SEVERITIES
+  #include &lt;windows.h&gt;
+  #include &lt;glog/logging.h&gt;
+
+  // ...
+
+  LOG(ERROR) &lt;&lt; "This should work";
+  LOG_IF(ERROR, x &gt; y) &lt;&lt; "This should be also OK";
+</pre>
+
+<p>
+However, you cannot
+use <code>INFO</code>, <code>WARNING</code>, <code>ERROR</code>,
+and <code>FATAL</code> anymore for functions defined
+in <code>glog/logging.h</code> .
+
+<pre>
+  #define GLOG_NO_ABBREVIATED_SEVERITIES
+  #include &lt;windows.h&gt;
+  #include &lt;glog/logging.h&gt;
+
+  // ...
+
+  // This won't work.
+  // google::FlushLogFiles(google::ERROR);
+
+  // Use this instead.
+  google::FlushLogFiles(google::GLOG_ERROR);
+</pre>
+
+<p>
+If you don't need <code>ERROR</code> defined
+by <code>windows.h</code>, there are a couple of more workarounds
+which sometimes don't work:
+
+<ul>
+  <li>#define <code>WIN32_LEAN_AND_MEAN</code> or <code>NOGDI</code>
+      <strong>before</strong> you #include <code>windows.h</code> .
+  <li>#undef <code>ERROR</code> <strong>after</strong> you #include
+      <code>windows.h</code> .
+</ul>
+
+<p>See <a href="http://code.google.com/p/google-glog/issues/detail?id=33">
+this issue</a> for more detail.
+
+<hr>
+<address>
+Shinichiro Hamaji<br>
+Gregor Hohpe<br>
+<script type=text/javascript>
+  var lm = new Date(document.lastModified);
+  document.write(lm.toDateString());
+</script>
+</address>
+
+</body>
+</html>

+ 7 - 0
third-party/glog-0.3.5/glog-config.cmake.in

@@ -0,0 +1,7 @@
+@PACKAGE_INIT@
+
+include (CMakeFindDependencyMacro)
+
+@gflags_DEPENDENCY@
+
+include ("${CMAKE_CURRENT_LIST_DIR}/glog-targets.cmake")

+ 44 - 0
third-party/glog-0.3.5/google-glog.sln

@@ -0,0 +1,44 @@
+
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual C++ Express 2008
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libglog", "vsprojects\libglog\libglog.vcproj", "{34BD04BD-BC1D-4BFC-AAFC-ED02D9E960F1}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "logging_unittest", "vsprojects\logging_unittest\logging_unittest.vcproj", "{DD0690AA-5E09-46B5-83FD-4B28604CABA8}"
+	ProjectSection(ProjectDependencies) = postProject
+		{34BD04BD-BC1D-4BFC-AAFC-ED02D9E960F1} = {34BD04BD-BC1D-4BFC-AAFC-ED02D9E960F1}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libglog_static", "vsprojects\libglog_static\libglog_static.vcproj", "{772C2111-BBBF-49E6-B912-198A7F7A88E5}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "logging_unittest_static", "vsprojects\logging_unittest_static\logging_unittest_static.vcproj", "{9B239B45-84A9-4E06-AC46-8E220CD43974}"
+	ProjectSection(ProjectDependencies) = postProject
+		{772C2111-BBBF-49E6-B912-198A7F7A88E5} = {772C2111-BBBF-49E6-B912-198A7F7A88E5}
+	EndProjectSection
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Win32 = Debug|Win32
+		Release|Win32 = Release|Win32
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{34BD04BD-BC1D-4BFC-AAFC-ED02D9E960F1}.Debug|Win32.ActiveCfg = Debug|Win32
+		{34BD04BD-BC1D-4BFC-AAFC-ED02D9E960F1}.Debug|Win32.Build.0 = Debug|Win32
+		{34BD04BD-BC1D-4BFC-AAFC-ED02D9E960F1}.Release|Win32.ActiveCfg = Release|Win32
+		{34BD04BD-BC1D-4BFC-AAFC-ED02D9E960F1}.Release|Win32.Build.0 = Release|Win32
+		{DD0690AA-5E09-46B5-83FD-4B28604CABA8}.Debug|Win32.ActiveCfg = Debug|Win32
+		{DD0690AA-5E09-46B5-83FD-4B28604CABA8}.Debug|Win32.Build.0 = Debug|Win32
+		{DD0690AA-5E09-46B5-83FD-4B28604CABA8}.Release|Win32.ActiveCfg = Release|Win32
+		{DD0690AA-5E09-46B5-83FD-4B28604CABA8}.Release|Win32.Build.0 = Release|Win32
+		{772C2111-BBBF-49E6-B912-198A7F7A88E5}.Debug|Win32.ActiveCfg = Debug|Win32
+		{772C2111-BBBF-49E6-B912-198A7F7A88E5}.Debug|Win32.Build.0 = Debug|Win32
+		{772C2111-BBBF-49E6-B912-198A7F7A88E5}.Release|Win32.ActiveCfg = Release|Win32
+		{772C2111-BBBF-49E6-B912-198A7F7A88E5}.Release|Win32.Build.0 = Release|Win32
+		{9B239B45-84A9-4E06-AC46-8E220CD43974}.Debug|Win32.ActiveCfg = Debug|Win32
+		{9B239B45-84A9-4E06-AC46-8E220CD43974}.Debug|Win32.Build.0 = Debug|Win32
+		{9B239B45-84A9-4E06-AC46-8E220CD43974}.Release|Win32.ActiveCfg = Release|Win32
+		{9B239B45-84A9-4E06-AC46-8E220CD43974}.Release|Win32.Build.0 = Release|Win32
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal

+ 519 - 0
third-party/glog-0.3.5/install-sh

@@ -0,0 +1,519 @@
+#!/bin/sh
+# install - install a program, script, or datafile
+
+scriptversion=2006-12-25.00
+
+# This originates from X11R5 (mit/util/scripts/install.sh), which was
+# later released in X11R6 (xc/config/util/install.sh) with the
+# following copyright and license.
+#
+# Copyright (C) 1994 X Consortium
+#
+# 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
+# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
+# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+# Except as contained in this notice, the name of the X Consortium shall not
+# be used in advertising or otherwise to promote the sale, use or other deal-
+# ings in this Software without prior written authorization from the X Consor-
+# tium.
+#
+#
+# FSF changes to this file are in the public domain.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.
+
+nl='
+'
+IFS=" ""	$nl"
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit=${DOITPROG-}
+if test -z "$doit"; then
+  doit_exec=exec
+else
+  doit_exec=$doit
+fi
+
+# Put in absolute file names if you don't have them in your path;
+# or use environment vars.
+
+chgrpprog=${CHGRPPROG-chgrp}
+chmodprog=${CHMODPROG-chmod}
+chownprog=${CHOWNPROG-chown}
+cmpprog=${CMPPROG-cmp}
+cpprog=${CPPROG-cp}
+mkdirprog=${MKDIRPROG-mkdir}
+mvprog=${MVPROG-mv}
+rmprog=${RMPROG-rm}
+stripprog=${STRIPPROG-strip}
+
+posix_glob='?'
+initialize_posix_glob='
+  test "$posix_glob" != "?" || {
+    if (set -f) 2>/dev/null; then
+      posix_glob=
+    else
+      posix_glob=:
+    fi
+  }
+'
+
+posix_mkdir=
+
+# Desired mode of installed file.
+mode=0755
+
+chgrpcmd=
+chmodcmd=$chmodprog
+chowncmd=
+mvcmd=$mvprog
+rmcmd="$rmprog -f"
+stripcmd=
+
+src=
+dst=
+dir_arg=
+dst_arg=
+
+copy_on_change=false
+no_target_directory=
+
+usage="\
+Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
+   or: $0 [OPTION]... SRCFILES... DIRECTORY
+   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
+   or: $0 [OPTION]... -d DIRECTORIES...
+
+In the 1st form, copy SRCFILE to DSTFILE.
+In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
+In the 4th, create DIRECTORIES.
+
+Options:
+     --help     display this help and exit.
+     --version  display version info and exit.
+
+  -c            (ignored)
+  -C            install only if different (preserve the last data modification time)
+  -d            create directories instead of installing files.
+  -g GROUP      $chgrpprog installed files to GROUP.
+  -m MODE       $chmodprog installed files to MODE.
+  -o USER       $chownprog installed files to USER.
+  -s            $stripprog installed files.
+  -t DIRECTORY  install into DIRECTORY.
+  -T            report an error if DSTFILE is a directory.
+
+Environment variables override the default commands:
+  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
+  RMPROG STRIPPROG
+"
+
+while test $# -ne 0; do
+  case $1 in
+    -c) ;;
+
+    -C) copy_on_change=true;;
+
+    -d) dir_arg=true;;
+
+    -g) chgrpcmd="$chgrpprog $2"
+	shift;;
+
+    --help) echo "$usage"; exit $?;;
+
+    -m) mode=$2
+	case $mode in
+	  *' '* | *'	'* | *'
+'*	  | *'*'* | *'?'* | *'['*)
+	    echo "$0: invalid mode: $mode" >&2
+	    exit 1;;
+	esac
+	shift;;
+
+    -o) chowncmd="$chownprog $2"
+	shift;;
+
+    -s) stripcmd=$stripprog;;
+
+    -t) dst_arg=$2
+	shift;;
+
+    -T) no_target_directory=true;;
+
+    --version) echo "$0 $scriptversion"; exit $?;;
+
+    --)	shift
+	break;;
+
+    -*)	echo "$0: invalid option: $1" >&2
+	exit 1;;
+
+    *)  break;;
+  esac
+  shift
+done
+
+if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
+  # When -d is used, all remaining arguments are directories to create.
+  # When -t is used, the destination is already specified.
+  # Otherwise, the last argument is the destination.  Remove it from $@.
+  for arg
+  do
+    if test -n "$dst_arg"; then
+      # $@ is not empty: it contains at least $arg.
+      set fnord "$@" "$dst_arg"
+      shift # fnord
+    fi
+    shift # arg
+    dst_arg=$arg
+  done
+fi
+
+if test $# -eq 0; then
+  if test -z "$dir_arg"; then
+    echo "$0: no input file specified." >&2
+    exit 1
+  fi
+  # It's OK to call `install-sh -d' without argument.
+  # This can happen when creating conditional directories.
+  exit 0
+fi
+
+if test -z "$dir_arg"; then
+  trap '(exit $?); exit' 1 2 13 15
+
+  # Set umask so as not to create temps with too-generous modes.
+  # However, 'strip' requires both read and write access to temps.
+  case $mode in
+    # Optimize common cases.
+    *644) cp_umask=133;;
+    *755) cp_umask=22;;
+
+    *[0-7])
+      if test -z "$stripcmd"; then
+	u_plus_rw=
+      else
+	u_plus_rw='% 200'
+      fi
+      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
+    *)
+      if test -z "$stripcmd"; then
+	u_plus_rw=
+      else
+	u_plus_rw=,u+rw
+      fi
+      cp_umask=$mode$u_plus_rw;;
+  esac
+fi
+
+for src
+do
+  # Protect names starting with `-'.
+  case $src in
+    -*) src=./$src;;
+  esac
+
+  if test -n "$dir_arg"; then
+    dst=$src
+    dstdir=$dst
+    test -d "$dstdir"
+    dstdir_status=$?
+  else
+
+    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
+    # might cause directories to be created, which would be especially bad
+    # if $src (and thus $dsttmp) contains '*'.
+    if test ! -f "$src" && test ! -d "$src"; then
+      echo "$0: $src does not exist." >&2
+      exit 1
+    fi
+
+    if test -z "$dst_arg"; then
+      echo "$0: no destination specified." >&2
+      exit 1
+    fi
+
+    dst=$dst_arg
+    # Protect names starting with `-'.
+    case $dst in
+      -*) dst=./$dst;;
+    esac
+
+    # If destination is a directory, append the input filename; won't work
+    # if double slashes aren't ignored.
+    if test -d "$dst"; then
+      if test -n "$no_target_directory"; then
+	echo "$0: $dst_arg: Is a directory" >&2
+	exit 1
+      fi
+      dstdir=$dst
+      dst=$dstdir/`basename "$src"`
+      dstdir_status=0
+    else
+      # Prefer dirname, but fall back on a substitute if dirname fails.
+      dstdir=`
+	(dirname "$dst") 2>/dev/null ||
+	expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	     X"$dst" : 'X\(//\)[^/]' \| \
+	     X"$dst" : 'X\(//\)$' \| \
+	     X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
+	echo X"$dst" |
+	    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+		   s//\1/
+		   q
+		 }
+		 /^X\(\/\/\)[^/].*/{
+		   s//\1/
+		   q
+		 }
+		 /^X\(\/\/\)$/{
+		   s//\1/
+		   q
+		 }
+		 /^X\(\/\).*/{
+		   s//\1/
+		   q
+		 }
+		 s/.*/./; q'
+      `
+
+      test -d "$dstdir"
+      dstdir_status=$?
+    fi
+  fi
+
+  obsolete_mkdir_used=false
+
+  if test $dstdir_status != 0; then
+    case $posix_mkdir in
+      '')
+	# Create intermediate dirs using mode 755 as modified by the umask.
+	# This is like FreeBSD 'install' as of 1997-10-28.
+	umask=`umask`
+	case $stripcmd.$umask in
+	  # Optimize common cases.
+	  *[2367][2367]) mkdir_umask=$umask;;
+	  .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
+
+	  *[0-7])
+	    mkdir_umask=`expr $umask + 22 \
+	      - $umask % 100 % 40 + $umask % 20 \
+	      - $umask % 10 % 4 + $umask % 2
+	    `;;
+	  *) mkdir_umask=$umask,go-w;;
+	esac
+
+	# With -d, create the new directory with the user-specified mode.
+	# Otherwise, rely on $mkdir_umask.
+	if test -n "$dir_arg"; then
+	  mkdir_mode=-m$mode
+	else
+	  mkdir_mode=
+	fi
+
+	posix_mkdir=false
+	case $umask in
+	  *[123567][0-7][0-7])
+	    # POSIX mkdir -p sets u+wx bits regardless of umask, which
+	    # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
+	    ;;
+	  *)
+	    tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
+	    trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
+
+	    if (umask $mkdir_umask &&
+		exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
+	    then
+	      if test -z "$dir_arg" || {
+		   # Check for POSIX incompatibilities with -m.
+		   # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
+		   # other-writeable bit of parent directory when it shouldn't.
+		   # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
+		   ls_ld_tmpdir=`ls -ld "$tmpdir"`
+		   case $ls_ld_tmpdir in
+		     d????-?r-*) different_mode=700;;
+		     d????-?--*) different_mode=755;;
+		     *) false;;
+		   esac &&
+		   $mkdirprog -m$different_mode -p -- "$tmpdir" && {
+		     ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
+		     test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
+		   }
+		 }
+	      then posix_mkdir=:
+	      fi
+	      rmdir "$tmpdir/d" "$tmpdir"
+	    else
+	      # Remove any dirs left behind by ancient mkdir implementations.
+	      rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
+	    fi
+	    trap '' 0;;
+	esac;;
+    esac
+
+    if
+      $posix_mkdir && (
+	umask $mkdir_umask &&
+	$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
+      )
+    then :
+    else
+
+      # The umask is ridiculous, or mkdir does not conform to POSIX,
+      # or it failed possibly due to a race condition.  Create the
+      # directory the slow way, step by step, checking for races as we go.
+
+      case $dstdir in
+	/*) prefix='/';;
+	-*) prefix='./';;
+	*)  prefix='';;
+      esac
+
+      eval "$initialize_posix_glob"
+
+      oIFS=$IFS
+      IFS=/
+      $posix_glob set -f
+      set fnord $dstdir
+      shift
+      $posix_glob set +f
+      IFS=$oIFS
+
+      prefixes=
+
+      for d
+      do
+	test -z "$d" && continue
+
+	prefix=$prefix$d
+	if test -d "$prefix"; then
+	  prefixes=
+	else
+	  if $posix_mkdir; then
+	    (umask=$mkdir_umask &&
+	     $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
+	    # Don't fail if two instances are running concurrently.
+	    test -d "$prefix" || exit 1
+	  else
+	    case $prefix in
+	      *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
+	      *) qprefix=$prefix;;
+	    esac
+	    prefixes="$prefixes '$qprefix'"
+	  fi
+	fi
+	prefix=$prefix/
+      done
+
+      if test -n "$prefixes"; then
+	# Don't fail if two instances are running concurrently.
+	(umask $mkdir_umask &&
+	 eval "\$doit_exec \$mkdirprog $prefixes") ||
+	  test -d "$dstdir" || exit 1
+	obsolete_mkdir_used=true
+      fi
+    fi
+  fi
+
+  if test -n "$dir_arg"; then
+    { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
+    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
+    { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
+      test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
+  else
+
+    # Make a couple of temp file names in the proper directory.
+    dsttmp=$dstdir/_inst.$$_
+    rmtmp=$dstdir/_rm.$$_
+
+    # Trap to clean up those temp files at exit.
+    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
+
+    # Copy the file name to the temp name.
+    (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
+
+    # and set any options; do chmod last to preserve setuid bits.
+    #
+    # If any of these fail, we abort the whole thing.  If we want to
+    # ignore errors from any of these, just make sure not to ignore
+    # errors from the above "$doit $cpprog $src $dsttmp" command.
+    #
+    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
+    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
+    { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
+    { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
+
+    # If -C, don't bother to copy if it wouldn't change the file.
+    if $copy_on_change &&
+       old=`LC_ALL=C ls -dlL "$dst"	2>/dev/null` &&
+       new=`LC_ALL=C ls -dlL "$dsttmp"	2>/dev/null` &&
+
+       eval "$initialize_posix_glob" &&
+       $posix_glob set -f &&
+       set X $old && old=:$2:$4:$5:$6 &&
+       set X $new && new=:$2:$4:$5:$6 &&
+       $posix_glob set +f &&
+
+       test "$old" = "$new" &&
+       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
+    then
+      rm -f "$dsttmp"
+    else
+      # Rename the file to the real destination.
+      $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
+
+      # The rename failed, perhaps because mv can't rename something else
+      # to itself, or perhaps because mv is so ancient that it does not
+      # support -f.
+      {
+	# Now remove or move aside any old file at destination location.
+	# We try this two ways since rm can't unlink itself on some
+	# systems and the destination file might be busy for other
+	# reasons.  In this case, the final cleanup might fail but the new
+	# file should still install successfully.
+	{
+	  test ! -f "$dst" ||
+	  $doit $rmcmd -f "$dst" 2>/dev/null ||
+	  { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
+	    { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
+	  } ||
+	  { echo "$0: cannot unlink or rename $dst" >&2
+	    (exit 1); exit 1
+	  }
+	} &&
+
+	# Now rename the file to the real destination.
+	$doit $mvcmd "$dsttmp" "$dst"
+      }
+    fi || exit 1
+
+    trap '' 0
+  fi
+done
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:

+ 10 - 0
third-party/glog-0.3.5/libglog.pc.in

@@ -0,0 +1,10 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: libglog
+Description: Google Log (glog) C++ logging framework
+Version: @VERSION@
+Libs: -L${libdir} -lglog
+Cflags: -I${includedir}

文件差异内容过多而无法显示
+ 9661 - 0
third-party/glog-0.3.5/ltmain.sh


+ 16 - 0
third-party/glog-0.3.5/m4/ac_have_attribute.m4

@@ -0,0 +1,16 @@
+AC_DEFUN([AX_C___ATTRIBUTE__], [
+  AC_MSG_CHECKING(for __attribute__)
+  AC_CACHE_VAL(ac_cv___attribute__, [
+    AC_TRY_COMPILE(
+      [#include <stdlib.h>
+       static void foo(void) __attribute__ ((unused));
+       void foo(void) { exit(1); }],
+      [],
+      ac_cv___attribute__=yes,
+      ac_cv___attribute__=no
+    )])
+  if test "$ac_cv___attribute__" = "yes"; then
+    AC_DEFINE(HAVE___ATTRIBUTE__, 1, [define if your compiler has __attribute__])
+  fi
+  AC_MSG_RESULT($ac_cv___attribute__)
+])

+ 14 - 0
third-party/glog-0.3.5/m4/ac_have_builtin_expect.m4

@@ -0,0 +1,14 @@
+AC_DEFUN([AX_C___BUILTIN_EXPECT], [
+  AC_MSG_CHECKING(for __builtin_expect)
+  AC_CACHE_VAL(ac_cv___builtin_expect, [
+    AC_TRY_COMPILE(
+      [int foo(void) { if (__builtin_expect(0, 0)) return 1; return 0; }],
+      [],
+      ac_cv___builtin_expect=yes,
+      ac_cv___builtin_expect=no
+    )])
+  if test "$ac_cv___builtin_expect" = "yes"; then
+    AC_DEFINE(HAVE___BUILTIN_EXPECT, 1, [define if your compiler has __builtin_expect])
+  fi
+  AC_MSG_RESULT($ac_cv___builtin_expect)
+])

+ 14 - 0
third-party/glog-0.3.5/m4/ac_have_sync_val_compare_and_swap.m4

@@ -0,0 +1,14 @@
+AC_DEFUN([AX_C___SYNC_VAL_COMPARE_AND_SWAP], [
+  AC_MSG_CHECKING(for __sync_val_compare_and_swap)
+  AC_CACHE_VAL(ac_cv___sync_val_compare_and_swap, [
+    AC_TRY_LINK(
+      [],
+      [int a; if (__sync_val_compare_and_swap(&a, 0, 1)) return 1; return 0;],
+      ac_cv___sync_val_compare_and_swap=yes,
+      ac_cv___sync_val_compare_and_swap=no
+    )])
+  if test "$ac_cv___sync_val_compare_and_swap" = "yes"; then
+    AC_DEFINE(HAVE___SYNC_VAL_COMPARE_AND_SWAP, 1, [define if your compiler has __sync_val_compare_and_swap])
+  fi
+  AC_MSG_RESULT($ac_cv___sync_val_compare_and_swap)
+])

+ 31 - 0
third-party/glog-0.3.5/m4/ac_rwlock.m4

@@ -0,0 +1,31 @@
+# TODO(csilvers): it would be better to actually try to link against
+# -pthreads, to make sure it defines these methods, but that may be
+# too hard, since pthread support is really tricky.
+
+# Check for support for pthread_rwlock_init() etc.
+# These aren't posix, but are widely supported.  To get them on linux,
+# you need to define _XOPEN_SOURCE first, so this check assumes your
+# application does that.
+#
+# Note: OS X (as of 6/1/06) seems to support pthread_rwlock, but
+# doesn't define PTHREAD_RWLOCK_INITIALIZER.  Therefore, we don't test
+# that particularly macro.  It's probably best if you don't use that
+# macro in your code either.
+
+AC_DEFUN([AC_RWLOCK],
+[AC_CACHE_CHECK(support for pthread_rwlock_* functions,
+ac_cv_rwlock,
+[AC_LANG_SAVE
+ AC_LANG_C
+ AC_TRY_COMPILE([#define _XOPEN_SOURCE 500
+                 #include <pthread.h>],
+		[pthread_rwlock_t l; pthread_rwlock_init(&l, NULL);
+                 pthread_rwlock_rdlock(&l); 
+                 return 0;],
+                ac_cv_rwlock=yes, ac_cv_rwlock=no)
+ AC_LANG_RESTORE
+])
+if test "$ac_cv_rwlock" = yes; then
+  AC_DEFINE(HAVE_RWLOCK,1,[define if the compiler implements pthread_rwlock_*])
+fi
+])

+ 363 - 0
third-party/glog-0.3.5/m4/acx_pthread.m4

@@ -0,0 +1,363 @@
+# This was retrieved from
+#    http://svn.0pointer.de/viewvc/trunk/common/acx_pthread.m4?revision=1277&root=avahi
+# See also (perhaps for new versions?)
+#    http://svn.0pointer.de/viewvc/trunk/common/acx_pthread.m4?root=avahi
+#
+# We've rewritten the inconsistency check code (from avahi), to work
+# more broadly.  In particular, it no longer assumes ld accepts -zdefs.
+# This caused a restructing of the code, but the functionality has only
+# changed a little.
+
+dnl @synopsis ACX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
+dnl
+dnl @summary figure out how to build C programs using POSIX threads
+dnl
+dnl This macro figures out how to build C programs using POSIX threads.
+dnl It sets the PTHREAD_LIBS output variable to the threads library and
+dnl linker flags, and the PTHREAD_CFLAGS output variable to any special
+dnl C compiler flags that are needed. (The user can also force certain
+dnl compiler flags/libs to be tested by setting these environment
+dnl variables.)
+dnl
+dnl Also sets PTHREAD_CC to any special C compiler that is needed for
+dnl multi-threaded programs (defaults to the value of CC otherwise).
+dnl (This is necessary on AIX to use the special cc_r compiler alias.)
+dnl
+dnl NOTE: You are assumed to not only compile your program with these
+dnl flags, but also link it with them as well. e.g. you should link
+dnl with $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS
+dnl $LIBS
+dnl
+dnl If you are only building threads programs, you may wish to use
+dnl these variables in your default LIBS, CFLAGS, and CC:
+dnl
+dnl        LIBS="$PTHREAD_LIBS $LIBS"
+dnl        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+dnl        CC="$PTHREAD_CC"
+dnl
+dnl In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute
+dnl constant has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to
+dnl that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX).
+dnl
+dnl ACTION-IF-FOUND is a list of shell commands to run if a threads
+dnl library is found, and ACTION-IF-NOT-FOUND is a list of commands to
+dnl run it if it is not found. If ACTION-IF-FOUND is not specified, the
+dnl default action will define HAVE_PTHREAD.
+dnl
+dnl Please let the authors know if this macro fails on any platform, or
+dnl if you have any other suggestions or comments. This macro was based
+dnl on work by SGJ on autoconf scripts for FFTW (www.fftw.org) (with
+dnl help from M. Frigo), as well as ac_pthread and hb_pthread macros
+dnl posted by Alejandro Forero Cuervo to the autoconf macro repository.
+dnl We are also grateful for the helpful feedback of numerous users.
+dnl
+dnl @category InstalledPackages
+dnl @author Steven G. Johnson <stevenj@alum.mit.edu>
+dnl @version 2006-05-29
+dnl @license GPLWithACException
+dnl 
+dnl Checks for GCC shared/pthread inconsistency based on work by
+dnl Marcin Owsiany <marcin@owsiany.pl>
+
+
+AC_DEFUN([ACX_PTHREAD], [
+AC_REQUIRE([AC_CANONICAL_HOST])
+AC_LANG_SAVE
+AC_LANG_C
+acx_pthread_ok=no
+
+# We used to check for pthread.h first, but this fails if pthread.h
+# requires special compiler flags (e.g. on True64 or Sequent).
+# It gets checked for in the link test anyway.
+
+# First of all, check if the user has set any of the PTHREAD_LIBS,
+# etcetera environment variables, and if threads linking works using
+# them:
+if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
+        save_CFLAGS="$CFLAGS"
+        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+        save_LIBS="$LIBS"
+        LIBS="$PTHREAD_LIBS $LIBS"
+        AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS])
+        AC_TRY_LINK_FUNC(pthread_join, acx_pthread_ok=yes)
+        AC_MSG_RESULT($acx_pthread_ok)
+        if test x"$acx_pthread_ok" = xno; then
+                PTHREAD_LIBS=""
+                PTHREAD_CFLAGS=""
+        fi
+        LIBS="$save_LIBS"
+        CFLAGS="$save_CFLAGS"
+fi
+
+# We must check for the threads library under a number of different
+# names; the ordering is very important because some systems
+# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
+# libraries is broken (non-POSIX).
+
+# Create a list of thread flags to try.  Items starting with a "-" are
+# C compiler flags, and other items are library names, except for "none"
+# which indicates that we try without any flags at all, and "pthread-config"
+# which is a program returning the flags for the Pth emulation library.
+
+acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
+
+# The ordering *is* (sometimes) important.  Some notes on the
+# individual items follow:
+
+# pthreads: AIX (must check this before -lpthread)
+# none: in case threads are in libc; should be tried before -Kthread and
+#       other compiler flags to prevent continual compiler warnings
+# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
+# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
+# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
+# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads)
+# -pthreads: Solaris/gcc
+# -mthreads: Mingw32/gcc, Lynx/gcc
+# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
+#      doesn't hurt to check since this sometimes defines pthreads too;
+#      also defines -D_REENTRANT)
+#      ... -mt is also the pthreads flag for HP/aCC
+# pthread: Linux, etcetera
+# --thread-safe: KAI C++
+# pthread-config: use pthread-config program (for GNU Pth library)
+
+case "${host_cpu}-${host_os}" in
+        *solaris*)
+
+        # On Solaris (at least, for some versions), libc contains stubbed
+        # (non-functional) versions of the pthreads routines, so link-based
+        # tests will erroneously succeed.  (We need to link with -pthreads/-mt/
+        # -lpthread.)  (The stubs are missing pthread_cleanup_push, or rather
+        # a function called by this macro, so we could check for that, but
+        # who knows whether they'll stub that too in a future libc.)  So,
+        # we'll just look for -pthreads and -lpthread first:
+
+        acx_pthread_flags="-pthreads pthread -mt -pthread $acx_pthread_flags"
+        ;;
+esac
+
+if test x"$acx_pthread_ok" = xno; then
+for flag in $acx_pthread_flags; do
+
+        case $flag in
+                none)
+                AC_MSG_CHECKING([whether pthreads work without any flags])
+                ;;
+
+                -*)
+                AC_MSG_CHECKING([whether pthreads work with $flag])
+                PTHREAD_CFLAGS="$flag"
+                ;;
+
+		pthread-config)
+		AC_CHECK_PROG(acx_pthread_config, pthread-config, yes, no)
+		if test x"$acx_pthread_config" = xno; then continue; fi
+		PTHREAD_CFLAGS="`pthread-config --cflags`"
+		PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
+		;;
+
+                *)
+                AC_MSG_CHECKING([for the pthreads library -l$flag])
+                PTHREAD_LIBS="-l$flag"
+                ;;
+        esac
+
+        save_LIBS="$LIBS"
+        save_CFLAGS="$CFLAGS"
+        LIBS="$PTHREAD_LIBS $LIBS"
+        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+
+        # Check for various functions.  We must include pthread.h,
+        # since some functions may be macros.  (On the Sequent, we
+        # need a special flag -Kthread to make this header compile.)
+        # We check for pthread_join because it is in -lpthread on IRIX
+        # while pthread_create is in libc.  We check for pthread_attr_init
+        # due to DEC craziness with -lpthreads.  We check for
+        # pthread_cleanup_push because it is one of the few pthread
+        # functions on Solaris that doesn't have a non-functional libc stub.
+        # We try pthread_create on general principles.
+        AC_TRY_LINK([#include <pthread.h>],
+                    [pthread_t th; pthread_join(th, 0);
+                     pthread_attr_init(0); pthread_cleanup_push(0, 0);
+                     pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
+                    [acx_pthread_ok=yes])
+
+        LIBS="$save_LIBS"
+        CFLAGS="$save_CFLAGS"
+
+        AC_MSG_RESULT($acx_pthread_ok)
+        if test "x$acx_pthread_ok" = xyes; then
+                break;
+        fi
+
+        PTHREAD_LIBS=""
+        PTHREAD_CFLAGS=""
+done
+fi
+
+# Various other checks:
+if test "x$acx_pthread_ok" = xyes; then
+        save_LIBS="$LIBS"
+        LIBS="$PTHREAD_LIBS $LIBS"
+        save_CFLAGS="$CFLAGS"
+        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+
+        # Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
+	AC_MSG_CHECKING([for joinable pthread attribute])
+	attr_name=unknown
+	for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
+	    AC_TRY_LINK([#include <pthread.h>], [int attr=$attr; return attr;],
+                        [attr_name=$attr; break])
+	done
+        AC_MSG_RESULT($attr_name)
+        if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then
+            AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name,
+                               [Define to necessary symbol if this constant
+                                uses a non-standard name on your system.])
+        fi
+
+        AC_MSG_CHECKING([if more special flags are required for pthreads])
+        flag=no
+        case "${host_cpu}-${host_os}" in
+            *-aix* | *-freebsd* | *-darwin*) flag="-D_THREAD_SAFE";;
+            *solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";;
+        esac
+        AC_MSG_RESULT(${flag})
+        if test "x$flag" != xno; then
+            PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS"
+        fi
+
+        LIBS="$save_LIBS"
+        CFLAGS="$save_CFLAGS"
+        # More AIX lossage: must compile with xlc_r or cc_r
+	if test x"$GCC" != xyes; then
+          AC_CHECK_PROGS(PTHREAD_CC, xlc_r cc_r, ${CC})
+        else
+          PTHREAD_CC=$CC
+	fi
+
+	# The next part tries to detect GCC inconsistency with -shared on some
+	# architectures and systems. The problem is that in certain
+	# configurations, when -shared is specified, GCC "forgets" to
+	# internally use various flags which are still necessary.
+	
+	#
+	# Prepare the flags
+	#
+	save_CFLAGS="$CFLAGS"
+	save_LIBS="$LIBS"
+	save_CC="$CC"
+	
+	# Try with the flags determined by the earlier checks.
+	#
+	# -Wl,-z,defs forces link-time symbol resolution, so that the
+	# linking checks with -shared actually have any value
+	#
+	# FIXME: -fPIC is required for -shared on many architectures,
+	# so we specify it here, but the right way would probably be to
+	# properly detect whether it is actually required.
+	CFLAGS="-shared -fPIC -Wl,-z,defs $CFLAGS $PTHREAD_CFLAGS"
+	LIBS="$PTHREAD_LIBS $LIBS"
+	CC="$PTHREAD_CC"
+	
+	# In order not to create several levels of indentation, we test
+	# the value of "$done" until we find the cure or run out of ideas.
+	done="no"
+	
+	# First, make sure the CFLAGS we added are actually accepted by our
+	# compiler.  If not (and OS X's ld, for instance, does not accept -z),
+	# then we can't do this test.
+	if test x"$done" = xno; then
+	   AC_MSG_CHECKING([whether to check for GCC pthread/shared inconsistencies])
+	   AC_TRY_LINK(,, , [done=yes])
+	
+	   if test "x$done" = xyes ; then
+	      AC_MSG_RESULT([no])
+	   else
+	      AC_MSG_RESULT([yes])
+	   fi
+	fi
+	
+	if test x"$done" = xno; then
+	   AC_MSG_CHECKING([whether -pthread is sufficient with -shared])
+	   AC_TRY_LINK([#include <pthread.h>],
+	      [pthread_t th; pthread_join(th, 0);
+	      pthread_attr_init(0); pthread_cleanup_push(0, 0);
+	      pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
+	      [done=yes])
+	   
+	   if test "x$done" = xyes; then
+	      AC_MSG_RESULT([yes])
+	   else
+	      AC_MSG_RESULT([no])
+	   fi
+	fi
+	
+	#
+	# Linux gcc on some architectures such as mips/mipsel forgets
+	# about -lpthread
+	#
+	if test x"$done" = xno; then
+	   AC_MSG_CHECKING([whether -lpthread fixes that])
+	   LIBS="-lpthread $PTHREAD_LIBS $save_LIBS"
+	   AC_TRY_LINK([#include <pthread.h>],
+	      [pthread_t th; pthread_join(th, 0);
+	      pthread_attr_init(0); pthread_cleanup_push(0, 0);
+	      pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
+	      [done=yes])
+	
+	   if test "x$done" = xyes; then
+	      AC_MSG_RESULT([yes])
+	      PTHREAD_LIBS="-lpthread $PTHREAD_LIBS"
+	   else
+	      AC_MSG_RESULT([no])
+	   fi
+	fi
+	#
+	# FreeBSD 4.10 gcc forgets to use -lc_r instead of -lc
+	#
+	if test x"$done" = xno; then
+	   AC_MSG_CHECKING([whether -lc_r fixes that])
+	   LIBS="-lc_r $PTHREAD_LIBS $save_LIBS"
+	   AC_TRY_LINK([#include <pthread.h>],
+	       [pthread_t th; pthread_join(th, 0);
+	        pthread_attr_init(0); pthread_cleanup_push(0, 0);
+	        pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
+	       [done=yes])
+	
+	   if test "x$done" = xyes; then
+	      AC_MSG_RESULT([yes])
+	      PTHREAD_LIBS="-lc_r $PTHREAD_LIBS"
+	   else
+	      AC_MSG_RESULT([no])
+	   fi
+	fi
+	if test x"$done" = xno; then
+	   # OK, we have run out of ideas
+	   AC_MSG_WARN([Impossible to determine how to use pthreads with shared libraries])
+	
+	   # so it's not safe to assume that we may use pthreads
+	   acx_pthread_ok=no
+	fi
+	
+	CFLAGS="$save_CFLAGS"
+	LIBS="$save_LIBS"
+	CC="$save_CC"
+else
+        PTHREAD_CC="$CC"
+fi
+
+AC_SUBST(PTHREAD_LIBS)
+AC_SUBST(PTHREAD_CFLAGS)
+AC_SUBST(PTHREAD_CC)
+
+# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
+if test x"$acx_pthread_ok" = xyes; then
+        ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1])
+        :
+else
+        acx_pthread_ok=no
+        $2
+fi
+AC_LANG_RESTORE
+])dnl ACX_PTHREAD

+ 36 - 0
third-party/glog-0.3.5/m4/google_namespace.m4

@@ -0,0 +1,36 @@
+# Allow users to override the namespace we define our application's classes in
+# Arg $1 is the default namespace to use if --enable-namespace isn't present.
+
+# In general, $1 should be 'google', so we put all our exported symbols in a
+# unique namespace that is not likely to conflict with anyone else.  However,
+# when it makes sense -- for instance, when publishing stl-like code -- you
+# may want to go with a different default, like 'std'.
+
+AC_DEFUN([AC_DEFINE_GOOGLE_NAMESPACE],
+  [google_namespace_default=[$1]
+   AC_ARG_ENABLE(namespace, [  --enable-namespace=FOO to define these Google
+                             classes in the FOO namespace. --disable-namespace
+                             to define them in the global namespace. Default
+                             is to define them in namespace $1.],
+                 [case "$enableval" in
+                    yes) google_namespace="$google_namespace_default" ;;
+                     no) google_namespace="" ;;
+                      *) google_namespace="$enableval" ;;
+                  esac],
+                 [google_namespace="$google_namespace_default"])
+   if test -n "$google_namespace"; then
+     ac_google_namespace="$google_namespace"
+     ac_google_start_namespace="namespace $google_namespace {"
+     ac_google_end_namespace="}"
+   else
+     ac_google_namespace=""
+     ac_google_start_namespace=""
+     ac_google_end_namespace=""
+   fi
+   AC_DEFINE_UNQUOTED(GOOGLE_NAMESPACE, $ac_google_namespace,
+                      Namespace for Google classes)
+   AC_DEFINE_UNQUOTED(_START_GOOGLE_NAMESPACE_, $ac_google_start_namespace,
+                      Puts following code inside the Google namespace)
+   AC_DEFINE_UNQUOTED(_END_GOOGLE_NAMESPACE_,  $ac_google_end_namespace,
+                      Stops putting the code inside the Google namespace)
+])

文件差异内容过多而无法显示
+ 8001 - 0
third-party/glog-0.3.5/m4/libtool.m4


+ 384 - 0
third-party/glog-0.3.5/m4/ltoptions.m4

@@ -0,0 +1,384 @@
+# Helper functions for option handling.                    -*- Autoconf -*-
+#
+#   Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation,
+#   Inc.
+#   Written by Gary V. Vaughan, 2004
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# serial 7 ltoptions.m4
+
+# This is to help aclocal find these macros, as it can't see m4_define.
+AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])])
+
+
+# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME)
+# ------------------------------------------
+m4_define([_LT_MANGLE_OPTION],
+[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])])
+
+
+# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME)
+# ---------------------------------------
+# Set option OPTION-NAME for macro MACRO-NAME, and if there is a
+# matching handler defined, dispatch to it.  Other OPTION-NAMEs are
+# saved as a flag.
+m4_define([_LT_SET_OPTION],
+[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl
+m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]),
+        _LT_MANGLE_DEFUN([$1], [$2]),
+    [m4_warning([Unknown $1 option `$2'])])[]dnl
+])
+
+
+# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET])
+# ------------------------------------------------------------
+# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
+m4_define([_LT_IF_OPTION],
+[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])])
+
+
+# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET)
+# -------------------------------------------------------
+# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME
+# are set.
+m4_define([_LT_UNLESS_OPTIONS],
+[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
+	    [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option),
+		      [m4_define([$0_found])])])[]dnl
+m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3
+])[]dnl
+])
+
+
+# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST)
+# ----------------------------------------
+# OPTION-LIST is a space-separated list of Libtool options associated
+# with MACRO-NAME.  If any OPTION has a matching handler declared with
+# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about
+# the unknown option and exit.
+m4_defun([_LT_SET_OPTIONS],
+[# Set options
+m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
+    [_LT_SET_OPTION([$1], _LT_Option)])
+
+m4_if([$1],[LT_INIT],[
+  dnl
+  dnl Simply set some default values (i.e off) if boolean options were not
+  dnl specified:
+  _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no
+  ])
+  _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no
+  ])
+  dnl
+  dnl If no reference was made to various pairs of opposing options, then
+  dnl we run the default mode handler for the pair.  For example, if neither
+  dnl `shared' nor `disable-shared' was passed, we enable building of shared
+  dnl archives by default:
+  _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED])
+  _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC])
+  _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC])
+  _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install],
+  		   [_LT_ENABLE_FAST_INSTALL])
+  ])
+])# _LT_SET_OPTIONS
+
+
+## --------------------------------- ##
+## Macros to handle LT_INIT options. ##
+## --------------------------------- ##
+
+# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME)
+# -----------------------------------------
+m4_define([_LT_MANGLE_DEFUN],
+[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])])
+
+
+# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE)
+# -----------------------------------------------
+m4_define([LT_OPTION_DEFINE],
+[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl
+])# LT_OPTION_DEFINE
+
+
+# dlopen
+# ------
+LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes
+])
+
+AU_DEFUN([AC_LIBTOOL_DLOPEN],
+[_LT_SET_OPTION([LT_INIT], [dlopen])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you
+put the `dlopen' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], [])
+
+
+# win32-dll
+# ---------
+# Declare package support for building win32 dll's.
+LT_OPTION_DEFINE([LT_INIT], [win32-dll],
+[enable_win32_dll=yes
+
+case $host in
+*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*)
+  AC_CHECK_TOOL(AS, as, false)
+  AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+  AC_CHECK_TOOL(OBJDUMP, objdump, false)
+  ;;
+esac
+
+test -z "$AS" && AS=as
+_LT_DECL([], [AS],      [1], [Assembler program])dnl
+
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl
+
+test -z "$OBJDUMP" && OBJDUMP=objdump
+_LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl
+])# win32-dll
+
+AU_DEFUN([AC_LIBTOOL_WIN32_DLL],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+_LT_SET_OPTION([LT_INIT], [win32-dll])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you
+put the `win32-dll' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [])
+
+
+# _LT_ENABLE_SHARED([DEFAULT])
+# ----------------------------
+# implement the --enable-shared flag, and supports the `shared' and
+# `disable-shared' LT_INIT options.
+# DEFAULT is either `yes' or `no'.  If omitted, it defaults to `yes'.
+m4_define([_LT_ENABLE_SHARED],
+[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl
+AC_ARG_ENABLE([shared],
+    [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@],
+	[build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])],
+    [p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_shared=yes ;;
+    no) enable_shared=no ;;
+    *)
+      enable_shared=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+	IFS="$lt_save_ifs"
+	if test "X$pkg" = "X$p"; then
+	  enable_shared=yes
+	fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac],
+    [enable_shared=]_LT_ENABLE_SHARED_DEFAULT)
+
+    _LT_DECL([build_libtool_libs], [enable_shared], [0],
+	[Whether or not to build shared libraries])
+])# _LT_ENABLE_SHARED
+
+LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])])
+LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])])
+
+# Old names:
+AC_DEFUN([AC_ENABLE_SHARED],
+[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared])
+])
+
+AC_DEFUN([AC_DISABLE_SHARED],
+[_LT_SET_OPTION([LT_INIT], [disable-shared])
+])
+
+AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)])
+AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_ENABLE_SHARED], [])
+dnl AC_DEFUN([AM_DISABLE_SHARED], [])
+
+
+
+# _LT_ENABLE_STATIC([DEFAULT])
+# ----------------------------
+# implement the --enable-static flag, and support the `static' and
+# `disable-static' LT_INIT options.
+# DEFAULT is either `yes' or `no'.  If omitted, it defaults to `yes'.
+m4_define([_LT_ENABLE_STATIC],
+[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl
+AC_ARG_ENABLE([static],
+    [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@],
+	[build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])],
+    [p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_static=yes ;;
+    no) enable_static=no ;;
+    *)
+     enable_static=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+	IFS="$lt_save_ifs"
+	if test "X$pkg" = "X$p"; then
+	  enable_static=yes
+	fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac],
+    [enable_static=]_LT_ENABLE_STATIC_DEFAULT)
+
+    _LT_DECL([build_old_libs], [enable_static], [0],
+	[Whether or not to build static libraries])
+])# _LT_ENABLE_STATIC
+
+LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])])
+LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])])
+
+# Old names:
+AC_DEFUN([AC_ENABLE_STATIC],
+[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static])
+])
+
+AC_DEFUN([AC_DISABLE_STATIC],
+[_LT_SET_OPTION([LT_INIT], [disable-static])
+])
+
+AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)])
+AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_ENABLE_STATIC], [])
+dnl AC_DEFUN([AM_DISABLE_STATIC], [])
+
+
+
+# _LT_ENABLE_FAST_INSTALL([DEFAULT])
+# ----------------------------------
+# implement the --enable-fast-install flag, and support the `fast-install'
+# and `disable-fast-install' LT_INIT options.
+# DEFAULT is either `yes' or `no'.  If omitted, it defaults to `yes'.
+m4_define([_LT_ENABLE_FAST_INSTALL],
+[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl
+AC_ARG_ENABLE([fast-install],
+    [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@],
+    [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])],
+    [p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_fast_install=yes ;;
+    no) enable_fast_install=no ;;
+    *)
+      enable_fast_install=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+	IFS="$lt_save_ifs"
+	if test "X$pkg" = "X$p"; then
+	  enable_fast_install=yes
+	fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac],
+    [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT)
+
+_LT_DECL([fast_install], [enable_fast_install], [0],
+	 [Whether or not to optimize for fast installation])dnl
+])# _LT_ENABLE_FAST_INSTALL
+
+LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])])
+LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])])
+
+# Old names:
+AU_DEFUN([AC_ENABLE_FAST_INSTALL],
+[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you put
+the `fast-install' option into LT_INIT's first parameter.])
+])
+
+AU_DEFUN([AC_DISABLE_FAST_INSTALL],
+[_LT_SET_OPTION([LT_INIT], [disable-fast-install])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you put
+the `disable-fast-install' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], [])
+dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], [])
+
+
+# _LT_WITH_PIC([MODE])
+# --------------------
+# implement the --with-pic flag, and support the `pic-only' and `no-pic'
+# LT_INIT options.
+# MODE is either `yes' or `no'.  If omitted, it defaults to `both'.
+m4_define([_LT_WITH_PIC],
+[AC_ARG_WITH([pic],
+    [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@],
+	[try to use only PIC/non-PIC objects @<:@default=use both@:>@])],
+    [lt_p=${PACKAGE-default}
+    case $withval in
+    yes|no) pic_mode=$withval ;;
+    *)
+      pic_mode=default
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for lt_pkg in $withval; do
+	IFS="$lt_save_ifs"
+	if test "X$lt_pkg" = "X$lt_p"; then
+	  pic_mode=yes
+	fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac],
+    [pic_mode=default])
+
+test -z "$pic_mode" && pic_mode=m4_default([$1], [default])
+
+_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl
+])# _LT_WITH_PIC
+
+LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])])
+LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])])
+
+# Old name:
+AU_DEFUN([AC_LIBTOOL_PICMODE],
+[_LT_SET_OPTION([LT_INIT], [pic-only])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you
+put the `pic-only' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_PICMODE], [])
+
+## ----------------- ##
+## LTDL_INIT Options ##
+## ----------------- ##
+
+m4_define([_LTDL_MODE], [])
+LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive],
+		 [m4_define([_LTDL_MODE], [nonrecursive])])
+LT_OPTION_DEFINE([LTDL_INIT], [recursive],
+		 [m4_define([_LTDL_MODE], [recursive])])
+LT_OPTION_DEFINE([LTDL_INIT], [subproject],
+		 [m4_define([_LTDL_MODE], [subproject])])
+
+m4_define([_LTDL_TYPE], [])
+LT_OPTION_DEFINE([LTDL_INIT], [installable],
+		 [m4_define([_LTDL_TYPE], [installable])])
+LT_OPTION_DEFINE([LTDL_INIT], [convenience],
+		 [m4_define([_LTDL_TYPE], [convenience])])

+ 123 - 0
third-party/glog-0.3.5/m4/ltsugar.m4

@@ -0,0 +1,123 @@
+# ltsugar.m4 -- libtool m4 base layer.                         -*-Autoconf-*-
+#
+# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
+# Written by Gary V. Vaughan, 2004
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# serial 6 ltsugar.m4
+
+# This is to help aclocal find these macros, as it can't see m4_define.
+AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])])
+
+
+# lt_join(SEP, ARG1, [ARG2...])
+# -----------------------------
+# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their
+# associated separator.
+# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier
+# versions in m4sugar had bugs.
+m4_define([lt_join],
+[m4_if([$#], [1], [],
+       [$#], [2], [[$2]],
+       [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])])
+m4_define([_lt_join],
+[m4_if([$#$2], [2], [],
+       [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])])
+
+
+# lt_car(LIST)
+# lt_cdr(LIST)
+# ------------
+# Manipulate m4 lists.
+# These macros are necessary as long as will still need to support
+# Autoconf-2.59 which quotes differently.
+m4_define([lt_car], [[$1]])
+m4_define([lt_cdr],
+[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])],
+       [$#], 1, [],
+       [m4_dquote(m4_shift($@))])])
+m4_define([lt_unquote], $1)
+
+
+# lt_append(MACRO-NAME, STRING, [SEPARATOR])
+# ------------------------------------------
+# Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'.
+# Note that neither SEPARATOR nor STRING are expanded; they are appended
+# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked).
+# No SEPARATOR is output if MACRO-NAME was previously undefined (different
+# than defined and empty).
+#
+# This macro is needed until we can rely on Autoconf 2.62, since earlier
+# versions of m4sugar mistakenly expanded SEPARATOR but not STRING.
+m4_define([lt_append],
+[m4_define([$1],
+	   m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])])
+
+
+
+# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...])
+# ----------------------------------------------------------
+# Produce a SEP delimited list of all paired combinations of elements of
+# PREFIX-LIST with SUFFIX1 through SUFFIXn.  Each element of the list
+# has the form PREFIXmINFIXSUFFIXn.
+# Needed until we can rely on m4_combine added in Autoconf 2.62.
+m4_define([lt_combine],
+[m4_if(m4_eval([$# > 3]), [1],
+       [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl
+[[m4_foreach([_Lt_prefix], [$2],
+	     [m4_foreach([_Lt_suffix],
+		]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[,
+	[_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])])
+
+
+# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ])
+# -----------------------------------------------------------------------
+# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited
+# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ.
+m4_define([lt_if_append_uniq],
+[m4_ifdef([$1],
+	  [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1],
+		 [lt_append([$1], [$2], [$3])$4],
+		 [$5])],
+	  [lt_append([$1], [$2], [$3])$4])])
+
+
+# lt_dict_add(DICT, KEY, VALUE)
+# -----------------------------
+m4_define([lt_dict_add],
+[m4_define([$1($2)], [$3])])
+
+
+# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE)
+# --------------------------------------------
+m4_define([lt_dict_add_subkey],
+[m4_define([$1($2:$3)], [$4])])
+
+
+# lt_dict_fetch(DICT, KEY, [SUBKEY])
+# ----------------------------------
+m4_define([lt_dict_fetch],
+[m4_ifval([$3],
+	m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]),
+    m4_ifdef([$1($2)], [m4_defn([$1($2)])]))])
+
+
+# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE])
+# -----------------------------------------------------------------
+m4_define([lt_if_dict_fetch],
+[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4],
+	[$5],
+    [$6])])
+
+
+# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...])
+# --------------------------------------------------------------
+m4_define([lt_dict_filter],
+[m4_if([$5], [], [],
+  [lt_join(m4_quote(m4_default([$4], [[, ]])),
+           lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]),
+		      [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl
+])

+ 23 - 0
third-party/glog-0.3.5/m4/ltversion.m4

@@ -0,0 +1,23 @@
+# ltversion.m4 -- version numbers			-*- Autoconf -*-
+#
+#   Copyright (C) 2004 Free Software Foundation, Inc.
+#   Written by Scott James Remnant, 2004
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# @configure_input@
+
+# serial 3337 ltversion.m4
+# This file is part of GNU Libtool
+
+m4_define([LT_PACKAGE_VERSION], [2.4.2])
+m4_define([LT_PACKAGE_REVISION], [1.3337])
+
+AC_DEFUN([LTVERSION_VERSION],
+[macro_version='2.4.2'
+macro_revision='1.3337'
+_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])
+_LT_DECL(, macro_revision, 0)
+])

+ 98 - 0
third-party/glog-0.3.5/m4/lt~obsolete.m4

@@ -0,0 +1,98 @@
+# lt~obsolete.m4 -- aclocal satisfying obsolete definitions.    -*-Autoconf-*-
+#
+#   Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc.
+#   Written by Scott James Remnant, 2004.
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# serial 5 lt~obsolete.m4
+
+# These exist entirely to fool aclocal when bootstrapping libtool.
+#
+# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN)
+# which have later been changed to m4_define as they aren't part of the
+# exported API, or moved to Autoconf or Automake where they belong.
+#
+# The trouble is, aclocal is a bit thick.  It'll see the old AC_DEFUN
+# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us
+# using a macro with the same name in our local m4/libtool.m4 it'll
+# pull the old libtool.m4 in (it doesn't see our shiny new m4_define
+# and doesn't know about Autoconf macros at all.)
+#
+# So we provide this file, which has a silly filename so it's always
+# included after everything else.  This provides aclocal with the
+# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything
+# because those macros already exist, or will be overwritten later.
+# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. 
+#
+# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here.
+# Yes, that means every name once taken will need to remain here until
+# we give up compatibility with versions before 1.7, at which point
+# we need to keep only those names which we still refer to.
+
+# This is to help aclocal find these macros, as it can't see m4_define.
+AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])])
+
+m4_ifndef([AC_LIBTOOL_LINKER_OPTION],	[AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])])
+m4_ifndef([AC_PROG_EGREP],		[AC_DEFUN([AC_PROG_EGREP])])
+m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH],	[AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])])
+m4_ifndef([_LT_AC_SHELL_INIT],		[AC_DEFUN([_LT_AC_SHELL_INIT])])
+m4_ifndef([_LT_AC_SYS_LIBPATH_AIX],	[AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])])
+m4_ifndef([_LT_PROG_LTMAIN],		[AC_DEFUN([_LT_PROG_LTMAIN])])
+m4_ifndef([_LT_AC_TAGVAR],		[AC_DEFUN([_LT_AC_TAGVAR])])
+m4_ifndef([AC_LTDL_ENABLE_INSTALL],	[AC_DEFUN([AC_LTDL_ENABLE_INSTALL])])
+m4_ifndef([AC_LTDL_PREOPEN],		[AC_DEFUN([AC_LTDL_PREOPEN])])
+m4_ifndef([_LT_AC_SYS_COMPILER],	[AC_DEFUN([_LT_AC_SYS_COMPILER])])
+m4_ifndef([_LT_AC_LOCK],		[AC_DEFUN([_LT_AC_LOCK])])
+m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE],	[AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])])
+m4_ifndef([_LT_AC_TRY_DLOPEN_SELF],	[AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])])
+m4_ifndef([AC_LIBTOOL_PROG_CC_C_O],	[AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])])
+m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])])
+m4_ifndef([AC_LIBTOOL_OBJDIR],		[AC_DEFUN([AC_LIBTOOL_OBJDIR])])
+m4_ifndef([AC_LTDL_OBJDIR],		[AC_DEFUN([AC_LTDL_OBJDIR])])
+m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])])
+m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP],	[AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])])
+m4_ifndef([AC_PATH_MAGIC],		[AC_DEFUN([AC_PATH_MAGIC])])
+m4_ifndef([AC_PROG_LD_GNU],		[AC_DEFUN([AC_PROG_LD_GNU])])
+m4_ifndef([AC_PROG_LD_RELOAD_FLAG],	[AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])])
+m4_ifndef([AC_DEPLIBS_CHECK_METHOD],	[AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])])
+m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])])
+m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])])
+m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])])
+m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS],	[AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])])
+m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP],	[AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])])
+m4_ifndef([LT_AC_PROG_EGREP],		[AC_DEFUN([LT_AC_PROG_EGREP])])
+m4_ifndef([LT_AC_PROG_SED],		[AC_DEFUN([LT_AC_PROG_SED])])
+m4_ifndef([_LT_CC_BASENAME],		[AC_DEFUN([_LT_CC_BASENAME])])
+m4_ifndef([_LT_COMPILER_BOILERPLATE],	[AC_DEFUN([_LT_COMPILER_BOILERPLATE])])
+m4_ifndef([_LT_LINKER_BOILERPLATE],	[AC_DEFUN([_LT_LINKER_BOILERPLATE])])
+m4_ifndef([_AC_PROG_LIBTOOL],		[AC_DEFUN([_AC_PROG_LIBTOOL])])
+m4_ifndef([AC_LIBTOOL_SETUP],		[AC_DEFUN([AC_LIBTOOL_SETUP])])
+m4_ifndef([_LT_AC_CHECK_DLFCN],		[AC_DEFUN([_LT_AC_CHECK_DLFCN])])
+m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER],	[AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])])
+m4_ifndef([_LT_AC_TAGCONFIG],		[AC_DEFUN([_LT_AC_TAGCONFIG])])
+m4_ifndef([AC_DISABLE_FAST_INSTALL],	[AC_DEFUN([AC_DISABLE_FAST_INSTALL])])
+m4_ifndef([_LT_AC_LANG_CXX],		[AC_DEFUN([_LT_AC_LANG_CXX])])
+m4_ifndef([_LT_AC_LANG_F77],		[AC_DEFUN([_LT_AC_LANG_F77])])
+m4_ifndef([_LT_AC_LANG_GCJ],		[AC_DEFUN([_LT_AC_LANG_GCJ])])
+m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG],	[AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])])
+m4_ifndef([_LT_AC_LANG_C_CONFIG],	[AC_DEFUN([_LT_AC_LANG_C_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG],	[AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])])
+m4_ifndef([_LT_AC_LANG_CXX_CONFIG],	[AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG],	[AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])])
+m4_ifndef([_LT_AC_LANG_F77_CONFIG],	[AC_DEFUN([_LT_AC_LANG_F77_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG],	[AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])])
+m4_ifndef([_LT_AC_LANG_GCJ_CONFIG],	[AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG],	[AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])])
+m4_ifndef([_LT_AC_LANG_RC_CONFIG],	[AC_DEFUN([_LT_AC_LANG_RC_CONFIG])])
+m4_ifndef([AC_LIBTOOL_CONFIG],		[AC_DEFUN([AC_LIBTOOL_CONFIG])])
+m4_ifndef([_LT_AC_FILE_LTDLL_C],	[AC_DEFUN([_LT_AC_FILE_LTDLL_C])])
+m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS],	[AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])])
+m4_ifndef([_LT_AC_PROG_CXXCPP],		[AC_DEFUN([_LT_AC_PROG_CXXCPP])])
+m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS],	[AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])])
+m4_ifndef([_LT_PROG_ECHO_BACKSLASH],	[AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])])
+m4_ifndef([_LT_PROG_F77],		[AC_DEFUN([_LT_PROG_F77])])
+m4_ifndef([_LT_PROG_FC],		[AC_DEFUN([_LT_PROG_FC])])
+m4_ifndef([_LT_PROG_CXX],		[AC_DEFUN([_LT_PROG_CXX])])

+ 0 - 0
third-party/glog-0.3.5/m4/namespaces.m4


部分文件因为文件数量过多而无法显示