tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

atod_manual_test.cc (6477B)


      1 // Copyright 2022 The Abseil Authors
      2 //
      3 // Licensed under the Apache License, Version 2.0 (the "License");
      4 // you may not use this file except in compliance with the License.
      5 // You may obtain a copy of the License at
      6 //
      7 //     https://www.apache.org/licenses/LICENSE-2.0
      8 //
      9 // Unless required by applicable law or agreed to in writing, software
     10 // distributed under the License is distributed on an "AS IS" BASIS,
     11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 // See the License for the specific language governing permissions and
     13 // limitations under the License.
     14 
     15 // This program tests the absl::SimpleAtod and absl::SimpleAtof functions. Run
     16 // it as "atod_manual_test pnftd/data/*.txt" where the pnftd directory is a
     17 // local checkout of the https://github.com/nigeltao/parse-number-fxx-test-data
     18 // repository. The test suite lives in a separate repository because its more
     19 // than 5 million test cases weigh over several hundred megabytes and because
     20 // the test cases are also useful to other software projects, not just Abseil.
     21 // Its data/*.txt files contain one test case per line, like:
     22 //
     23 // 3C00 3F800000 3FF0000000000000 1
     24 // 3D00 3FA00000 3FF4000000000000 1.25
     25 // 3D9A 3FB33333 3FF6666666666666 1.4
     26 // 57B7 42F6E979 405EDD2F1A9FBE77 123.456
     27 // 622A 44454000 4088A80000000000 789
     28 // 7C00 7F800000 7FF0000000000000 123.456e789
     29 //
     30 // For each line (and using 0-based column indexes), columns [5..13] and
     31 // [14..30] contain the 32-bit float and 64-bit double result of parsing
     32 // columns [31..].
     33 //
     34 // For example, parsing "1.4" as a float gives the bits 0x3FB33333.
     35 //
     36 // In this 6-line example, the final line's float and double values are all
     37 // infinity. The largest finite float and double values are approximately
     38 // 3.40e+38 and 1.80e+308.
     39 
     40 #include <cstdint>
     41 #include <cstdio>
     42 #include <string>
     43 
     44 #include "absl/base/casts.h"
     45 #include "absl/strings/numbers.h"
     46 #include "absl/strings/str_format.h"
     47 #include "absl/strings/string_view.h"
     48 #include "absl/types/optional.h"
     49 
     50 static constexpr uint8_t kUnhex[256] = {
     51    0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,  //
     52    0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,  //
     53    0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,  //
     54    0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,  //
     55    0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,  //
     56    0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,  //
     57    0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,  // '0' ..= '7'
     58    0x8, 0x9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,  // '8' ..= '9'
     59 
     60    0x0, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, 0x0,  // 'A' ..= 'F'
     61    0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,  //
     62    0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,  //
     63    0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,  //
     64    0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,  //
     65    0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,  //
     66    0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,  //
     67    0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,  //
     68 
     69    0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,  //
     70    0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,  //
     71    0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,  //
     72    0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,  //
     73    0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,  //
     74    0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,  //
     75    0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,  //
     76    0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,  //
     77 
     78    0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,  //
     79    0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,  //
     80    0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,  //
     81    0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,  //
     82    0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,  //
     83    0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,  //
     84    0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,  //
     85    0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,  //
     86 };
     87 
     88 static absl::optional<std::string> ReadFileToString(const char* filename) {
     89  FILE* f = fopen(filename, "rb");
     90  if (!f) {
     91    return absl::nullopt;
     92  }
     93  fseek(f, 0, SEEK_END);
     94  size_t size = ftell(f);
     95  fseek(f, 0, SEEK_SET);
     96  std::string s(size, '\x00');
     97  size_t n = fread(&s[0], 1, size, f);
     98  fclose(f);
     99  if (n != size) {
    100    return absl::nullopt;
    101  }
    102  return s;
    103 }
    104 
    105 static bool ProcessOneTestFile(const char* filename) {
    106  absl::optional<std::string> contents = ReadFileToString(filename);
    107  if (!contents) {
    108    absl::FPrintF(stderr, "Invalid file: %s\n", filename);
    109    return false;
    110  }
    111 
    112  int num_cases = 0;
    113  for (absl::string_view v(*contents); !v.empty();) {
    114    size_t new_line = v.find('\n');
    115    if ((new_line == absl::string_view::npos) || (new_line < 32)) {
    116      break;
    117    }
    118    absl::string_view input = v.substr(31, new_line - 31);
    119 
    120    // Test absl::SimpleAtof.
    121    {
    122      float f;
    123      if (!absl::SimpleAtof(input, &f)) {
    124        absl::FPrintF(stderr, "Could not parse \"%s\" in %s\n", input,
    125                      filename);
    126        return false;
    127      }
    128      uint32_t have32 = absl::bit_cast<uint32_t>(f);
    129 
    130      uint32_t want32 = 0;
    131      for (int i = 0; i < 8; i++) {
    132        want32 = (want32 << 4) | kUnhex[static_cast<unsigned char>(v[5 + i])];
    133      }
    134 
    135      if (have32 != want32) {
    136        absl::FPrintF(stderr,
    137                      "absl::SimpleAtof failed parsing \"%s\" in %s\n  have  "
    138                      "%08X\n  want  %08X\n",
    139                      input, filename, have32, want32);
    140        return false;
    141      }
    142    }
    143 
    144    // Test absl::SimpleAtod.
    145    {
    146      double d;
    147      if (!absl::SimpleAtod(input, &d)) {
    148        absl::FPrintF(stderr, "Could not parse \"%s\" in %s\n", input,
    149                      filename);
    150        return false;
    151      }
    152      uint64_t have64 = absl::bit_cast<uint64_t>(d);
    153 
    154      uint64_t want64 = 0;
    155      for (int i = 0; i < 16; i++) {
    156        want64 = (want64 << 4) | kUnhex[static_cast<unsigned char>(v[14 + i])];
    157      }
    158 
    159      if (have64 != want64) {
    160        absl::FPrintF(stderr,
    161                      "absl::SimpleAtod failed parsing \"%s\" in %s\n  have  "
    162                      "%016X\n  want  %016X\n",
    163                      input, filename, have64, want64);
    164        return false;
    165      }
    166    }
    167 
    168    num_cases++;
    169    v = v.substr(new_line + 1);
    170  }
    171  printf("%8d OK in %s\n", num_cases, filename);
    172  return true;
    173 }
    174 
    175 int main(int argc, char** argv) {
    176  if (argc < 2) {
    177    absl::FPrintF(
    178        stderr,
    179        "Usage: %s pnftd/data/*.txt\nwhere the pnftd directory is a local "
    180        "checkout of "
    181        "the\nhttps://github.com/nigeltao/parse-number-fxx-test-data "
    182        "repository.\n",
    183        argv[0]);
    184    return 1;
    185  }
    186 
    187  for (int i = 1; i < argc; i++) {
    188    if (!ProcessOneTestFile(argv[i])) {
    189      return 1;
    190    }
    191  }
    192  return 0;
    193 }