VirtualBox

root/trunk/src/bldprogs/bin2c.c

Revision 12192, 6.5 kB (checked in by vboxsync, 4 months ago)

bin2c: removed some gotos, corrected the file header and caught a case where the output file wasn't deleted on error.

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

© 2008 Sun Microsystems, Inc.
ContactPrivacy policy