source: rtems-tools/misc/bin2c/rtems-bin2c.c @ 1a89c3d

Last change on this file since 1a89c3d was 1a89c3d, checked in by Sebastian Huber <sebastian.huber@…>, on Jun 6, 2018 at 2:29:19 PM

bin2c: Fix warnings

Update #3380.

  • Property mode set to 100644
File size: 7.3 KB
Line 
1/*
2 * bin2c.c
3 *
4 * convert a binary file into a C source array.
5 *
6 * THE "BEER-WARE LICENSE" (Revision 3.1415):
7 * sandro AT sigala DOT it wrote this file. As long as you retain this
8 * notice you can do whatever you want with this stuff.  If we meet some
9 * day, and you think this stuff is worth it, you can buy me a beer in
10 * return.  Sandro Sigala
11 *
12 * Subsequently modified by Joel Sherrill <joel.sherrill@oarcorp.com>
13 * to add a number of capabilities not in the original.
14 *
15 * syntax:  bin2c [-c] [-z] <input_file> <output_file>
16 *
17 *    -c    do NOT add the "const" keyword to definition
18 *    -s    add the "static" keywork to definition
19 *    -v    verbose
20 *    -z    terminate the array with a zero (useful for embedded C strings)
21 *
22 * examples:
23 *     bin2c -c myimage.png myimage_png.cpp
24 *     bin2c -z sometext.txt sometext_txt.cpp
25 *
26 */
27
28#include <ctype.h>
29#include <stdio.h>
30#include <stdlib.h>
31#include <string.h>
32#include <libgen.h>
33
34#ifndef PATH_MAX
35#define PATH_MAX 1024
36#endif
37
38int useconst = 1;
39int usestatic = 0;
40int verbose = 0;
41int zeroterminated = 0;
42int createC = 1;
43int createH = 1;
44
45int myfgetc(FILE *f)
46{
47  int c = fgetc(f);
48  if (c == EOF && zeroterminated) {
49    zeroterminated = 0;
50    return 0;
51  }
52  return c;
53}
54
55void process(const char *ifname, const char *ofname, const char *forced_name)
56{
57  FILE *ifile, *ocfile, *ohfile;
58  char buf[PATH_MAX+1], *p;
59  char obasename[PATH_MAX+1];
60  char ocname[PATH_MAX+1];
61  char ohname[PATH_MAX+1];
62  size_t len;
63
64  ocfile = NULL;
65  ohfile = NULL;
66
67  /* Error check */
68  if ( !ifname || !ofname ) {
69    fprintf(stderr, "process has NULL filename\n");
70    exit(1);
71  }
72
73  strncpy( obasename, ofname, PATH_MAX );
74  len = strnlen( obasename, PATH_MAX );
75  if ( len >= 2 ) {
76    if ( obasename[len-2] == '.' ) {
77      if ( (obasename[len-1] == 'c') || (obasename[len-1] == 'h') )
78        obasename[len-2] = '\0';
79    }
80  }
81
82  sprintf( ocname, "%s.c", obasename );
83  sprintf( ohname, "%s.h", obasename );
84
85  if ( verbose ) {
86    fprintf(
87      stderr,
88      "in file: %s\n"
89      "c file: %s\n"
90      "h file: %s\n",
91      ifname,
92      ocname,
93      ohname
94    );
95  }
96
97  /* Open input and output files */
98  ifile = fopen(ifname, "rb");
99  if (ifile == NULL) {
100    fprintf(stderr, "cannot open %s for reading\n", ifname);
101    exit(1);
102  }
103
104  if ( createC ) {
105    ocfile = fopen(ocname, "wb");
106    if (ocfile == NULL) {
107      fprintf(stderr, "cannot open %s for writing\n", ocname);
108      exit(1);
109    }
110  }
111
112  if ( createH ) {
113    ohfile = fopen(ohname, "wb");
114    if (ohfile == NULL) {
115      fprintf(stderr, "cannot open %s for writing\n", ohname);
116      exit(1);
117    }
118  }
119
120  /* find basename */
121  char *ifbasename_to_free =
122    forced_name != NULL ? strdup(forced_name) : strdup(ifname);
123  if ( ifbasename_to_free == NULL ) {
124    fprintf(stderr, "cannot allocate memory\n" );
125    fclose(ifile);
126    if ( createC ) { fclose(ocfile); }
127    if ( createH ) { fclose(ohfile); }
128    exit(1);
129  }
130
131  char *ifbasename;
132  ifbasename = basename(ifbasename_to_free);
133
134  strcpy(buf, ifbasename);
135  for (p = buf; *p != '\0'; ++p) {
136    if (!isalnum((unsigned char)*p)) /* cast to avoid negative indexing */
137      *p = '_';
138  }
139
140  if ( createC ) {
141    /* print C file header */
142    fprintf(
143      ocfile,
144      "/*\n"
145      " *  Declarations for C structure representing binary file %s\n"
146      " *\n"
147      " *  WARNING: Automatically generated -- do not edit!\n"
148      " */\n"
149      "\n"
150      "#include <sys/types.h>\n"
151      "\n",
152      ifbasename
153    );
154
155    /* print structure */
156    fprintf(
157      ocfile,
158      "%s%sunsigned char %s[] = {\n  ",
159      ((usestatic) ? "static " : ""),
160      ((useconst) ? "const " : ""),
161      buf
162    );
163    int c, col = 1;
164    while ((c = myfgetc(ifile)) != EOF) {
165      if (col >= 78 - 6) {
166        fprintf(ocfile, "\n  ");
167        col = 1;
168      }
169      fprintf(ocfile, "0x%.2x, ", c);
170      col += 6;
171
172    }
173    fprintf(ocfile, "\n};\n");
174
175    /* print sizeof */
176    fprintf(
177      ocfile,
178      "\n"
179      "%s%ssize_t %s_size = sizeof(%s);\n",
180      ((usestatic) ? "static " : ""),
181      ((useconst) ? "const " : ""),
182      buf,
183      buf
184    );
185  } /* createC */
186
187  /*****************************************************************/
188  /******                    END OF C FILE                     *****/
189  /*****************************************************************/
190
191  if ( createH ) {
192    /* print H file header */
193    char hbasename[PATH_MAX];
194    char* p;
195    /* Clean up the file name if it is an abs path */
196    strcpy(
197      hbasename,
198      obasename
199    );
200    p = hbasename;
201    while (*p != '\0') {
202      if (*p < '0' || *p > 'z')
203        *p = '_';
204      ++p;
205    }
206    fprintf(
207      ohfile,
208      "/*\n"
209      " *  Extern declarations for C structure representing binary file %s\n"
210      " *\n"
211      " *  WARNING: Automatically generated -- do not edit!\n"
212      " */\n"
213      "\n"
214      "#ifndef __%s_h\n"
215      "#define __%s_h\n"
216      "\n"
217      "#include <sys/types.h>\n"
218      "\n",
219      ifbasename,  /* header */
220      hbasename,  /* ifndef */
221      hbasename   /* define */
222    );
223
224    /* print structure */
225    fprintf(
226      ohfile,
227      "extern %s%sunsigned char %s[];",
228      ((usestatic) ? "static " : ""),
229      ((useconst) ? "const " : ""),
230      buf
231    );
232    /* print sizeof */
233    fprintf(
234      ohfile,
235      "\n"
236      "extern %s%ssize_t %s_size;\n",
237      ((usestatic) ? "static " : ""),
238      ((useconst) ? "const " : ""),
239      buf
240    );
241
242    fprintf(
243      ohfile,
244      "\n"
245      "#endif\n"
246    );
247  } /* createH */
248
249  /*****************************************************************/
250  /******                    END OF H FILE                     *****/
251  /*****************************************************************/
252
253  fclose(ifile);
254  if ( createC ) { fclose(ocfile); }
255  if ( createH ) { fclose(ohfile); }
256  free(ifbasename_to_free);
257}
258
259void usage(void)
260{
261  fprintf(
262     stderr,
263     "usage: bin2c [-csvzCH] [-N name] <input_file> <output_file>\n"
264     "  <input_file> is the binary file to convert\n"
265     "  <output_file> should not have a .c or .h extension\n"
266     "\n"
267     "  -c - do NOT use const in declaration\n"
268     "  -s - do use static in declaration\n"
269     "  -v - verbose\n"
270     "  -z - add zero terminator\n"
271     "  -H - create c-header only\n"
272     "  -C - create c-source file only\n"
273     "  -N - force name of data array\n"
274    );
275  exit(1);
276}
277
278int main(int argc, char **argv)
279{
280  const char *name = NULL;
281  while (argc > 3) {
282    if (!strcmp(argv[1], "-c")) {
283      useconst = 0;
284      --argc;
285      ++argv;
286    } else if (!strcmp(argv[1], "-s")) {
287      usestatic = 1;
288      --argc;
289      ++argv;
290    } else if (!strcmp(argv[1], "-v")) {
291      verbose = 1;
292      --argc;
293      ++argv;
294    } else if (!strcmp(argv[1], "-z")) {
295      zeroterminated = 1;
296      --argc;
297      ++argv;
298    } else if (!strcmp(argv[1], "-C")) {
299      createH = 0;
300      createC = 1;
301      --argc;
302      ++argv;
303    } else if (!strcmp(argv[1], "-H")) {
304      createC = 0;
305      createH = 1;
306      --argc;
307      ++argv;
308    } else if (!strcmp(argv[1], "-N")) {
309      --argc;
310      ++argv;
311      if (argc <= 1) {
312        fprintf(stderr, "error: -N needs a name\n");
313        usage();
314      }
315      name = argv[1];
316      --argc;
317      ++argv;
318    } else {
319      usage();
320    }
321  }
322  if (argc != 3) {
323    usage();
324  }
325
326  /* process( input_file, output_basename ) */
327  process(argv[1], argv[2], name);
328  return 0;
329}
Note: See TracBrowser for help on using the repository browser.