VirtualBox

source: vbox/trunk/src/bldprogs/bin2c.c@ 63501

Last change on this file since 63501 was 63501, checked in by vboxsync, 8 years ago

too long string. oh joy

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 8.6 KB
Line 
1/* $Id: bin2c.c 63501 2016-08-15 20:50:48Z vboxsync $ */
2/** @file
3 * bin2c - Binary 2 C Structure Converter.
4 */
5
6/*
7 * Copyright (C) 2006-2016 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18
19/*********************************************************************************************************************************
20* Header Files *
21*********************************************************************************************************************************/
22#include <ctype.h>
23#include <stdio.h>
24#include <string.h>
25#include <stdlib.h>
26#include <sys/types.h>
27
28
29/**
30 * File size.
31 *
32 * @returns file size in bytes.
33 * @returns 0 on failure.
34 * @param pFile File to size.
35 */
36static size_t fsize(FILE *pFile)
37{
38 long cbFile;
39 off_t Pos = ftell(pFile);
40 if ( Pos >= 0
41 && !fseek(pFile, 0, SEEK_END))
42 {
43 cbFile = ftell(pFile);
44 if ( cbFile >= 0
45 && !fseek(pFile, 0, SEEK_SET))
46 return cbFile;
47 }
48 return 0;
49}
50
51static int usage(const char *argv0)
52{
53 fprintf(stderr,
54 "Syntax: %s [options] <arrayname> <binaryfile> <outname>\n"
55 " --min <n> check if <binaryfile> is not smaller than <n>KB\n"
56 " --max <n> check if <binaryfile> is not bigger than <n>KB\n"
57 " --mask <n> check if size of binaryfile is <n>-aligned\n"
58 " --width <n> number of bytes per line (default: 16)\n"
59 " --break <n> break every <n> lines (default: -1)\n"
60 , argv0);
61 fprintf(stderr,
62 " --ascii show ASCII representation of binary as comment\n"
63 " --export emit DECLEXPORT\n"
64 " --append append to the output file (default: truncate)\n"
65 " --no-size Skip the size.\n"
66 " --static Static data scope.\n"
67 , argv0);
68
69 return 1;
70}
71
72int main(int argc, char *argv[])
73{
74 FILE *pFileIn;
75 FILE *pFileOut;
76 int iArg;
77 size_t cbMin = 0;
78 size_t cbMax = ~0U;
79 size_t uMask = 0;
80 int fAscii = 0;
81 int fAppend = 0;
82 int fExport = 0;
83 int fNoSize = 0;
84 int fStatic = 0;
85 long iBreakEvery = -1;
86 unsigned char abLine[32];
87 size_t cbLine = 16;
88 size_t off;
89 size_t cbRead;
90 size_t cbBin;
91 int rc = 1; /* assume the worst... */
92
93 if (argc < 2)
94 return usage(argv[0]);
95
96 for (iArg = 1; iArg < argc; iArg++)
97 {
98 if (!strcmp(argv[iArg], "--min") || !strcmp(argv[iArg], "-min"))
99 {
100 if (++iArg >= argc)
101 return usage(argv[0]);
102 cbMin = 1024 * strtoul(argv[iArg], NULL, 0);
103 }
104 else if (!strcmp(argv[iArg], "--max") || !strcmp(argv[iArg], "-max"))
105 {
106 if (++iArg >= argc)
107 return usage(argv[0]);
108 cbMax = 1024 * strtoul(argv[iArg], NULL, 0);
109 }
110 else if (!strcmp(argv[iArg], "--mask") || !strcmp(argv[iArg], "-mask"))
111 {
112 if (++iArg >= argc)
113 return usage(argv[0]);
114 uMask = strtoul(argv[iArg], NULL, 0);
115 }
116 else if (!strcmp(argv[iArg], "--ascii") || !strcmp(argv[iArg], "-ascii"))
117 fAscii = 1;
118 else if (!strcmp(argv[iArg], "--append"))
119 fAppend = 1;
120 else if (!strcmp(argv[iArg], "--export") || !strcmp(argv[iArg], "-export"))
121 fExport = 1;
122 else if (!strcmp(argv[iArg], "--no-size"))
123 fNoSize = 1;
124 else if (!strcmp(argv[iArg], "--static"))
125 fStatic = 1;
126 else if (!strcmp(argv[iArg], "--width") || !strcmp(argv[iArg], "-width"))
127 {
128 if (++iArg >= argc)
129 return usage(argv[0]);
130 cbLine = strtoul(argv[iArg], NULL, 0);
131 if (cbLine == 0 || cbLine > sizeof(abLine))
132 {
133 fprintf(stderr, "%s: '%s' is too wide, max %u\n",
134 argv[0], argv[iArg], (unsigned)sizeof(abLine));
135 return 1;
136 }
137 }
138 else if (!strcmp(argv[iArg], "--break") || !strcmp(argv[iArg], "-break"))
139 {
140 if (++iArg >= argc)
141 return usage(argv[0]);
142 iBreakEvery = strtol(argv[iArg], NULL, 0);
143 if (iBreakEvery <= 0 && iBreakEvery != -1)
144 {
145 fprintf(stderr, "%s: -break value '%s' is not >= 1 or -1.\n",
146 argv[0], argv[iArg]);
147 return 1;
148 }
149 }
150 else if (iArg == argc - 3)
151 break;
152 else
153 {
154 fprintf(stderr, "%s: syntax error: Unknown argument '%s'\n",
155 argv[0], argv[iArg]);
156 return usage(argv[0]);
157 }
158 }
159
160 pFileIn = fopen(argv[iArg+1], "rb");
161 if (!pFileIn)
162 {
163 fprintf(stderr, "Error: failed to open input file '%s'!\n", argv[iArg+1]);
164 return 1;
165 }
166
167 pFileOut = fopen(argv[iArg+2], fAppend ? "a" : "w"); /* no b! */
168 if (!pFileOut)
169 {
170 fprintf(stderr, "Error: failed to open output file '%s'!\n", argv[iArg+2]);
171 fclose(pFileIn);
172 return 1;
173 }
174
175 cbBin = fsize(pFileIn);
176
177 fprintf(pFileOut,
178 "/*\n"
179 " * This file was automatically generated\n"
180 " * from %s\n"
181 " * by %s.\n"
182 " */\n"
183 "\n"
184 "#include <iprt/cdefs.h>\n"
185 "\n"
186 "%sconst unsigned char%s g_ab%s[] =\n"
187 "{\n",
188 argv[iArg+1], argv[0], fStatic ? "static " : fExport ? "DECLEXPORT(" : "", !fStatic && fExport ? ")" : "", argv[iArg]);
189
190 /* check size restrictions */
191 if (uMask && (cbBin & uMask))
192 fprintf(stderr, "%s: size=%ld - Not aligned!\n", argv[0], (long)cbBin);
193 else if (cbBin < cbMin || cbBin > cbMax)
194 fprintf(stderr, "%s: size=%ld - Not %ld-%ldb in size!\n",
195 argv[0], (long)cbBin, (long)cbMin, (long)cbMax);
196 else
197 {
198 /* the binary data */
199 off = 0;
200 while ((cbRead = fread(&abLine[0], 1, cbLine, pFileIn)) > 0)
201 {
202 size_t j;
203
204 if ( iBreakEvery > 0
205 && off
206 && (off / cbLine) % iBreakEvery == 0)
207 fprintf(pFileOut, "\n");
208
209 fprintf(pFileOut, " ");
210 for (j = 0; j < cbRead; j++)
211 fprintf(pFileOut, " 0x%02x,", abLine[j]);
212 for (; j < cbLine; j++)
213 fprintf(pFileOut, " ");
214 if (fAscii)
215 {
216 fprintf(pFileOut, " /* 0x%08lx: ", (long)off);
217 for (j = 0; j < cbRead; j++)
218 /* be careful with '/' prefixed/followed by a '*'! */
219 fprintf(pFileOut, "%c",
220 isprint(abLine[j]) && abLine[j] != '/' ? abLine[j] : '.');
221 for (; j < cbLine; j++)
222 fprintf(pFileOut, " ");
223 fprintf(pFileOut, " */");
224 }
225 fprintf(pFileOut, "\n");
226
227 off += cbRead;
228 }
229
230 /* check for errors */
231 if (ferror(pFileIn) && !feof(pFileIn))
232 fprintf(stderr, "%s: read error\n", argv[0]);
233 else if (off != cbBin)
234 fprintf(stderr, "%s: read error off=%ld cbBin=%ld\n", argv[0], (long)off, (long)cbBin);
235 else
236 {
237 /* no errors, finish the structure. */
238 fprintf(pFileOut,
239 "};\n");
240
241 if (!fNoSize)
242 fprintf(pFileOut,
243 "\n"
244 "%sconst unsigned%s g_cb%s = sizeof(g_ab%s);\n",
245 fExport ? "DECLEXPORT(" : "", fExport ? ")" : "", argv[iArg], argv[iArg]);
246
247 fprintf(pFileOut, "/* end of file */\n");
248
249 /* flush output and check for error. */
250 fflush(pFileOut);
251 if (ferror(pFileOut))
252 fprintf(stderr, "%s: write error\n", argv[0]);
253 else
254 rc = 0; /* success! */
255 }
256 }
257
258 /* cleanup, delete the output file on failure. */
259 fclose(pFileOut);
260 fclose(pFileIn);
261 if (rc)
262 remove(argv[iArg+2]);
263
264 return rc;
265}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette