VirtualBox

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

Last change on this file since 56013 was 51770, checked in by vboxsync, 10 years ago

Merged in iprt++ dev branch.

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