Showing the changes to Source/Tools/EmbedFile/EmbedFile.cpp (1 of 1 file). Show all
Unified · Split
| @@ -1,14 +1,39 @@ | ||
| 1 | −// EmbedFile.cpp : This file contains the 'main' function. Program execution begins and ends there. | |
| 1 | +//****************************************************************************************************** | |
| 2 | +// EmbedFile.cpp - Gbtc | |
| 2 | 3 | // |
| 4 | +// Copyright � 2019, Grid Protection Alliance. All Rights Reserved. | |
| 5 | +// | |
| 6 | +// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See | |
| 7 | +// the NOTICE file distributed with this work for additional information regarding copyright ownership. | |
| 8 | +// The GPA licenses this file to you under the MIT License (MIT), the "License"; you may not use this | |
| 9 | +// file except in compliance with the License. You may obtain a copy of the License at: | |
| 10 | +// | |
| 11 | +// http://opensource.org/licenses/MIT | |
| 12 | +// | |
| 13 | +// Unless agreed to in writing, the subject software distributed under the License is distributed on an | |
| 14 | +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the | |
| 15 | +// License for the specific language governing permissions and limitations. | |
| 16 | +// | |
| 17 | +// Code Modification History: | |
| 18 | +// ---------------------------------------------------------------------------------------------------- | |
| 19 | +// 02/02/2019 - J. Ritchie Carrikk | |
| 20 | +// Generated original version of source code. | |
| 21 | +// | |
| 22 | +//****************************************************************************************************** | |
| 23 | + | |
| 24 | +/* | |
| 25 | + * This application is used to create a portable embedded resource for a C++ application. | |
| 26 | + * The program will take the file name specified as a command line argument and turn it | |
| 27 | + * into a byte array where the array is declared in a .H file and defined in a .CPP file. | |
| 28 | + */ | |
| 3 | 29 | |
| 4 | 30 | #include "pch.h" |
| 5 | 31 | |
| 6 | 32 | FILE* open_or_exit(const char* fname, const char* mode) |
| 7 | 33 | { |
| 8 | 34 | FILE* f; |
| 9 | − errno_t err; | |
| 10 | 35 | |
| 11 | − if ((err = fopen_s(&f, fname, mode)) != 0) { | |
| 36 | + if (fopen_s(&f, fname, mode) != 0) { | |
| 12 | 37 | perror(fname); |
| 13 | 38 | exit(EXIT_FAILURE); |
| 14 | 39 | } |
| @@ -16,11 +41,11 @@ FILE* open_or_exit(const char* fname, const char* mode) · 1 unmodified line | ||
| 16 | 41 | return f; |
| 17 | 42 | } |
| 18 | 43 | |
| 19 | −void write_byte(FILE* out, int32_t& chars, bool& first, unsigned char value) | |
| 44 | +void write_byte(FILE* out, int32_t& chars, unsigned char value) | |
| 20 | 45 | { |
| 21 | 46 | if (chars++ % 10 == 0) |
| 22 | 47 | { |
| 23 | − if (!first) | |
| 48 | + if (chars > 1) | |
| 24 | 49 | fprintf(out, ","); |
| 25 | 50 | |
| 26 | 51 | fprintf(out, "\n "); |
| @@ -31,34 +56,36 @@ void write_byte(FILE* out, int32_t& chars, bool& first, unsigned char value) · 4 unmodified lines | ||
| 31 | 56 | } |
| 32 | 57 | |
| 33 | 58 | fprintf(out, "0x%02X", value); |
| 34 | − first = false; | |
| 35 | 59 | } |
| 36 | 60 | |
| 37 | 61 | int main(int argc, char** argv) |
| 38 | 62 | { |
| 39 | 63 | if (argc < 3) { |
| 40 | 64 | fprintf(stderr, "USAGE: %s {sym} {rsrc} [{namespace}] [addnull]\n\n" |
| 41 | − " Creates {sym}.cpp from the contents of {rsrc}\n", | |
| 65 | + " Creates {sym}.cpp/.h from the contents of {rsrc}\n", | |
| 42 | 66 | argv[0]); |
| 43 | 67 | return EXIT_FAILURE; |
| 44 | 68 | } |
| 45 | 69 | |
| 46 | 70 | const char* sym = argv[1]; |
| 47 | 71 | FILE* in = open_or_exit(argv[2], "r"); |
| 48 | − char empty[1] = ""; | |
| 49 | 72 | const char* prefix = ""; |
| 50 | 73 | bool addNullByte = false; |
| 51 | 74 | |
| 75 | + // Third argument is optional C++ namespace prefix | |
| 52 | 76 | if (argc > 3) |
| 53 | 77 | prefix = argv[3]; |
| 54 | 78 | |
| 79 | + // Fourth argument is optional command to add a null byte to resource | |
| 55 | 80 | if (argc > 4) |
| 56 | 81 | addNullByte = _strcmpi(argv[4], "addnull") == 0; |
| 57 | 82 | |
| 83 | + // Create .H resource file | |
| 58 | 84 | char symfile[256]; |
| 59 | 85 | snprintf(symfile, sizeof(symfile), "%s.h", sym); |
| 60 | 86 | FILE* out = open_or_exit(symfile,"w"); |
| 61 | 87 | |
| 88 | + // Define #ifdef directive symbol used to include header file only once | |
| 62 | 89 | char symdirective[256]; |
| 63 | 90 | const char* s = sym; |
| 64 | 91 | char* d = symdirective; |
| @@ -78,6 +105,7 @@ int main(int argc, char** argv) · 13 unmodified lines | ||
| 78 | 105 | localtime_s(&timeinfo, &rawtime); |
| 79 | 106 | asctime_s(now, 256, &timeinfo); |
| 80 | 107 | |
| 108 | + // Write header for .H resource file | |
| 81 | 109 | fprintf(out, "// Auto-generated on %s", now); |
| 82 | 110 | fprintf(out, "// EmbedFile.exe %s %s %s%s\n\n", sym, argv[2], prefix, addNullByte ? " addnull" : ""); |
| 83 | 111 | fprintf(out, "#ifndef %s\n", symdirective); |
| @@ -86,6 +114,8 @@ int main(int argc, char** argv) · 2 unmodified lines | ||
| 86 | 114 | |
| 87 | 115 | if (strlen(prefix) > 0) |
| 88 | 116 | { |
| 117 | + // When a C++ namespace prefix is provided, break each namespace | |
| 118 | + // component out into separate namespace commands for the .H file | |
| 89 | 119 | char source[256]; |
| 90 | 120 | strcpy_s(source, 256, prefix); |
| 91 | 121 | |
| @@ -117,32 +147,34 @@ int main(int argc, char** argv) · 25 unmodified lines | ||
| 117 | 147 | fprintf(out, "\n\n#endif\n"); |
| 118 | 148 | fclose(out); |
| 119 | 149 | |
| 150 | + // Create .CPP resource file | |
| 120 | 151 | snprintf(symfile, sizeof(symfile), "%s.cpp", sym); |
| 121 | 152 | out = open_or_exit(symfile,"w"); |
| 122 | 153 | |
| 154 | + // Write header for .CPP resource file | |
| 123 | 155 | fprintf(out, "// Auto-generated on %s", now); |
| 124 | 156 | fprintf(out, "// EmbedFile.exe %s %s %s%s\n\n", sym, argv[2], prefix, addNullByte ? " addnull" : ""); |
| 125 | 157 | fprintf(out, "#include \"%s.h\"\n\n", sym); |
| 126 | 158 | fprintf(out, "const uint8_t %s%s[] = {", prefix, sym); |
| 127 | 159 | |
| 128 | 160 | unsigned char buf[256]; |
| 129 | − size_t nread = 0; | |
| 161 | + size_t nread; | |
| 130 | 162 | int32_t chars = 0; |
| 131 | − bool first = true; | |
| 132 | 163 | |
| 164 | + // Write resource bytes | |
| 133 | 165 | do |
| 134 | 166 | { |
| 135 | 167 | nread = fread(buf, 1, sizeof(buf), in); |
| 136 | 168 | size_t i; |
| 137 | 169 | |
| 138 | 170 | for (i = 0; i < nread; i++) |
| 139 | − write_byte(out, chars, first, buf[i]); | |
| 171 | + write_byte(out, chars, buf[i]); | |
| 140 | 172 | } |
| 141 | 173 | while (nread > 0); |
| 142 | 174 | |
| 143 | 175 | // Write NULL as last character, if requested |
| 144 | 176 | if (addNullByte) |
| 145 | − write_byte(out, chars, first, '\0'); | |
| 177 | + write_byte(out, chars, '\0'); | |
| 146 | 178 | |
| 147 | 179 | fprintf(out, "\n};\n\n"); |
| 148 | 180 | fprintf(out, "const uint32_t %s%sLength = sizeof(%s%s);\n", prefix, sym, prefix, sym); |