Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.
 
 
 
 
 
 

143 rader
4.0 KiB

  1. // Copyright (c) 2017, Google Inc.
  2. //
  3. // Permission to use, copy, modify, and/or distribute this software for any
  4. // purpose with or without fee is hereby granted, provided that the above
  5. // copyright notice and this permission notice appear in all copies.
  6. //
  7. // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  8. // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  9. // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
  10. // SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  11. // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  12. // OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  13. // CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
  14. // embed_test_data generates a C++ source file which exports a function,
  15. // GetTestData, which looks up the specified data files.
  16. package main
  17. import (
  18. "bytes"
  19. "fmt"
  20. "io/ioutil"
  21. "os"
  22. "unicode"
  23. )
  24. func quote(in []byte) string {
  25. var buf bytes.Buffer
  26. buf.WriteByte('"')
  27. for _, b := range in {
  28. switch b {
  29. case '\a':
  30. buf.WriteString(`\a`)
  31. case '\b':
  32. buf.WriteString(`\b`)
  33. case '\f':
  34. buf.WriteString(`\f`)
  35. case '\n':
  36. buf.WriteString(`\n`)
  37. case '\r':
  38. buf.WriteString(`\r`)
  39. case '\t':
  40. buf.WriteString(`\t`)
  41. case '\v':
  42. buf.WriteString(`\v`)
  43. case '"':
  44. buf.WriteString(`\"`)
  45. default:
  46. if rune(b) > 127 || unicode.IsPrint(rune(b)) {
  47. buf.WriteByte(b)
  48. } else {
  49. fmt.Fprintf(&buf, "\\x%02x", b)
  50. }
  51. }
  52. }
  53. buf.WriteByte('"')
  54. return buf.String()
  55. }
  56. func main() {
  57. fmt.Printf(`/* Copyright (c) 2017, Google Inc.
  58. *
  59. * Permission to use, copy, modify, and/or distribute this software for any
  60. * purpose with or without fee is hereby granted, provided that the above
  61. * copyright notice and this permission notice appear in all copies.
  62. *
  63. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  64. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  65. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
  66. * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  67. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  68. * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  69. * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
  70. /* This file is generated by:
  71. `)
  72. fmt.Printf(" * go run util/embed_test_data.go")
  73. for _, arg := range os.Args[1:] {
  74. fmt.Printf(" \\\n * %s", arg)
  75. }
  76. fmt.Printf(" */\n")
  77. fmt.Printf(`
  78. /* clang-format off */
  79. #include <stdlib.h>
  80. #include <string.h>
  81. #include <algorithm>
  82. #include <string>
  83. `)
  84. // MSVC limits the length of string constants, so we emit an array of
  85. // them and concatenate at runtime. We could also use a single array
  86. // literal, but this is less compact.
  87. const chunkSize = 8192
  88. for i, arg := range os.Args[1:] {
  89. data, err := ioutil.ReadFile(arg)
  90. if err != nil {
  91. fmt.Fprintf(os.Stderr, "Error reading %s: %s.\n", data, err)
  92. os.Exit(1)
  93. }
  94. fmt.Printf("static const char *kData%d[] = {\n", i)
  95. for i := 0; i < len(data); i += chunkSize {
  96. chunk := chunkSize
  97. if chunk > len(data)-i {
  98. chunk = len(data) - i
  99. }
  100. fmt.Printf(" %s,\n", quote(data[i:i+chunk]))
  101. }
  102. fmt.Printf("};\n")
  103. fmt.Printf("static const size_t kLen%d = %d;\n\n", i, len(data))
  104. }
  105. fmt.Printf(`static std::string AssembleString(const char **data, size_t len) {
  106. std::string ret;
  107. for (size_t i = 0; i < len; i += %d) {
  108. size_t chunk = std::min(static_cast<size_t>(%d), len - i);
  109. ret.append(data[i / %d], chunk);
  110. }
  111. return ret;
  112. }
  113. /* Silence -Wmissing-declarations. */
  114. std::string GetTestData(const char *path);
  115. std::string GetTestData(const char *path) {
  116. `, chunkSize, chunkSize, chunkSize)
  117. for i, arg := range os.Args[1:] {
  118. fmt.Printf(" if (strcmp(path, %s) == 0) {\n", quote([]byte(arg)))
  119. fmt.Printf(" return AssembleString(kData%d, kLen%d);\n", i, i)
  120. fmt.Printf(" }\n")
  121. }
  122. fmt.Printf(` fprintf(stderr, "File not embedded: %%s.\n", path);
  123. abort();
  124. }
  125. `)
  126. }