source: rtems/tools/build/rtems-bin2c.c @ b164303

4.115
Last change on this file since b164303 was b164303, checked in by Josh Oguin <josh.oguin@…>, on 11/25/14 at 21:55:49

tools/build/*.c: Clean up issues reported by CodeSonar?

This code is built without warnings and ignored by Coverity Scan.
CodeSonar? found a wide range of issues including buffer overruns,
buffer underruns, questionable type conversions, leaks, etc. This
set of patches addresses all reported issues.

  • Property mode set to 100644
File size: 6.9 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)
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  const char *cp;
63  size_t len;
64
65  ocfile = NULL;
66  ohfile = NULL;
67
68  /* Error check */
69  if ( !ifname || !ofname ) {
70    fprintf(stderr, "process has NULL filename\n");
71    exit(1);
72  }
73
74  strncpy( obasename, ofname, PATH_MAX );
75  len = strlen( obasename );
76  if ( len >= 2 ) {
77    if ( obasename[len-2] == '.' ) {
78      if ( (obasename[len-1] == 'c') || (obasename[len-1] == 'h') )
79        obasename[len-2] = '\0';
80    }
81  }
82
83  sprintf( ocname, "%s.c", obasename );
84  sprintf( ohname, "%s.h", obasename );
85
86  if ( verbose ) {
87    fprintf(
88      stderr,
89      "in file: %s\n"
90      "c file: %s\n"
91      "h file: %s\n",
92      ifname,
93      ocname,
94      ohname
95    );
96  }
97
98  /* Open input and output files */
99  ifile = fopen(ifname, "rb");
100  if (ifile == NULL) {
101    fprintf(stderr, "cannot open %s for reading\n", ifname);
102    exit(1);
103  }
104
105  if ( createC ) {
106    ocfile = fopen(ocname, "wb");
107    if (ocfile == NULL) {
108      fprintf(stderr, "cannot open %s for writing\n", ocname);
109      exit(1);
110    }
111  }
112
113  if ( createH ) {
114    ohfile = fopen(ohname, "wb");
115    if (ohfile == NULL) {
116      fprintf(stderr, "cannot open %s for writing\n", ohname);
117      exit(1);
118    }
119  }
120
121  /* find basename */
122  char *ifbasename = strdup(ifname);
123  if ( ifbasename == 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  ifbasename = basename(ifbasename);
132
133  strcpy(buf, ifbasename);
134  for (p = buf; *p != '\0'; ++p) {
135    if (!isalnum((unsigned char)*p)) /* cast to avoid negative indexing */
136      *p = '_';
137  }
138
139  if ( createC ) {
140    /* print C file header */
141    fprintf(
142      ocfile,
143      "/*\n"
144      " *  Declarations for C structure representing binary file %s\n"
145      " *\n"
146      " *  WARNING: Automatically generated -- do not edit!\n"
147      " */\n"
148      "\n"
149      "#include <sys/types.h>\n"
150      "\n",
151      ifbasename
152    );
153
154    /* print structure */
155    fprintf(
156      ocfile,
157      "%s%sunsigned char %s[] = {\n  ",
158      ((usestatic) ? "static " : ""),
159      ((useconst) ? "const " : ""),
160      buf
161    );
162    int c, col = 1;
163    while ((c = myfgetc(ifile)) != EOF) {
164      if (col >= 78 - 6) {
165        fprintf(ocfile, "\n  ");
166        col = 1;
167      }
168      fprintf(ocfile, "0x%.2x, ", c);
169      col += 6;
170
171    }
172    fprintf(ocfile, "\n};\n");
173
174    /* print sizeof */
175    fprintf(
176      ocfile,
177      "\n"
178      "%s%ssize_t %s_size = sizeof(%s);\n",
179      ((usestatic) ? "static " : ""),
180      ((useconst) ? "const " : ""),
181      buf,
182      buf
183    );
184  } /* createC */
185
186  /*****************************************************************/
187  /******                    END OF C FILE                     *****/
188  /*****************************************************************/
189
190  if ( createH ) {
191    /* print H file header */
192    char hbasename[PATH_MAX];
193    char* p;
194    /* Clean up the file name if it is an abs path */
195    strcpy(
196      hbasename,
197      obasename
198    );
199    p = hbasename;
200    while (*p != '\0') {
201      if (*p < '0' || *p > 'z')
202        *p = '_';
203      ++p;
204    }
205    fprintf(
206      ohfile,
207      "/*\n"
208      " *  Extern declarations for C structure representing binary file %s\n"
209      " *\n"
210      " *  WARNING: Automatically generated -- do not edit!\n"
211      " */\n"
212      "\n"
213      "#ifndef __%s_h\n"
214      "#define __%s_h\n"
215      "\n"
216      "#include <sys/types.h>\n"
217      "\n",
218      ifbasename,  /* header */
219      hbasename,  /* ifndef */
220      hbasename   /* define */
221    );
222
223    /* print structure */
224    fprintf(
225      ohfile,
226      "extern %s%sunsigned char %s[];",
227      ((usestatic) ? "static " : ""),
228      ((useconst) ? "const " : ""),
229      buf
230    );
231    /* print sizeof */
232    fprintf(
233      ohfile,
234      "\n"
235      "extern %s%ssize_t %s_size;\n",
236      ((usestatic) ? "static " : ""),
237      ((useconst) ? "const " : ""),
238      buf
239    );
240
241    fprintf(
242      ohfile,
243      "\n"
244      "#endif\n"
245    );
246  } /* createH */
247
248  /*****************************************************************/
249  /******                    END OF H FILE                     *****/
250  /*****************************************************************/
251
252  fclose(ifile);
253  if ( createC ) { fclose(ocfile); }
254  if ( createH ) { fclose(ohfile); }
255  free(ifbasename);
256}
257
258void usage(void)
259{
260  fprintf(
261     stderr,
262     "usage: bin2c [-csvzCH] <input_file> <output_file>\n"
263     "  <input_file> is the binary file to convert\n"
264     "  <output_file> should not have a .c or .h extension\n"
265     "\n"
266     "  -c - do NOT use const in declaration\n"
267     "  -s - do use static in declaration\n"
268     "  -v - verbose\n"
269     "  -z - add zero terminator\n"
270     "  -H - create c-header only\n"
271     "  -C - create c-source file only\n"
272    );
273  exit(1);
274}
275
276int main(int argc, char **argv)
277{
278  while (argc > 3) {
279    if (!strcmp(argv[1], "-c")) {
280      useconst = 0;
281      --argc;
282      ++argv;
283    } else if (!strcmp(argv[1], "-s")) {
284      usestatic = 1;
285      --argc;
286      ++argv;
287    } else if (!strcmp(argv[1], "-v")) {
288      verbose = 1;
289      --argc;
290      ++argv;
291    } else if (!strcmp(argv[1], "-z")) {
292      zeroterminated = 1;
293      --argc;
294      ++argv;
295    } else if (!strcmp(argv[1], "-C")) {
296      createH = 0;
297      createC = 1;
298      --argc;
299      ++argv;
300    } else if (!strcmp(argv[1], "-H")) {
301      createC = 0;
302      createH = 1;
303      --argc;
304      ++argv;
305    } else {
306      usage();
307    }
308  }
309  if (argc != 3) {
310    usage();
311  }
312
313  /* process( input_file, output_basename ) */
314  process(argv[1], argv[2]);
315  return 0;
316}
317
Note: See TracBrowser for help on using the repository browser.