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