aboutsummaryrefslogtreecommitdiffstats
path: root/tools/file2c/src/file2c.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/file2c/src/file2c.c')
-rw-r--r--tools/file2c/src/file2c.c194
1 files changed, 194 insertions, 0 deletions
diff --git a/tools/file2c/src/file2c.c b/tools/file2c/src/file2c.c
new file mode 100644
index 00000000..29b9da2f
--- /dev/null
+++ b/tools/file2c/src/file2c.c
@@ -0,0 +1,194 @@
+/*
+ ChibiOS/GFX - Copyright (C) 2012, 2013
+ Joel Bodenmann aka Tectu <joel@unormal.org>
+
+ This file is part of ChibiOS/GFX.
+
+ ChibiOS/GFX is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/GFX is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <string.h>
+#ifdef WIN32
+ #include <io.h>
+#endif
+
+static unsigned char buf[1024];
+
+static char *filenameof(char *fname) {
+ char *p;
+
+#ifdef WIN32
+ if (fname[1] == ':')
+ fname = fname+2;
+ p = strrchr(fname, '\\');
+ if (p) fname = p+1;
+#endif
+ p = strrchr(fname, '/');
+ if (p) fname = p+1;
+ p = strchr(fname, '.');
+ if (p) *p = 0;
+ return fname;
+}
+
+static char *clean4c(char *fname) {
+ char *p;
+
+ while((p = strpbrk(fname, "-+ `~!@#$%^&*(){}[]|:;'\",<>?/|=.\\"))) *p = '_';
+ return fname;
+}
+
+int main(int argc, char * argv[])
+{
+char * opt_progname;
+char * opt_inputfile;
+char * opt_outputfile;
+char * opt_arrayname;
+int opt_breakblocks;
+char * opt_static;
+char * opt_const;
+FILE * f_input;
+FILE * f_output;
+unsigned blocknum;
+size_t len;
+size_t i;
+
+ /* Default values for our parameters */
+ opt_progname = filenameof(argv[0]);
+ opt_inputfile = 0;
+ opt_outputfile = 0;
+ opt_arrayname = 0;
+ opt_breakblocks = 0;
+ opt_static = "";
+ opt_const = "";
+
+ /* Read the arguments */
+ while(*++argv) {
+ if (argv[0][0] == '-') {
+ while (*++(argv[0])) {
+ switch(argv[0][0]) {
+ case '?': case 'h': goto usage;
+ case 'b': opt_breakblocks = 1; break;
+ case 'c': opt_const = "const "; break;
+ case 's': opt_static = "static "; break;
+ case 'n': opt_arrayname = *++argv; goto nextarg;
+ default:
+ fprintf(stderr, "Unknown flag -%c\n", argv[0][0]);
+ goto usage;
+ }
+ }
+ } else if (!opt_inputfile)
+ opt_inputfile = argv[0];
+ else if (!opt_outputfile)
+ opt_outputfile = argv[0];
+ else {
+ usage:
+ fprintf(stderr, "Usage:\n\t%s -?\n"
+ "\t%s [-bs] [-n name] [inputfile] [outputfile]\n"
+ "\t\t-?\tThis help\n"
+ "\t\t-h\tThis help\n"
+ "\t\t-b\tBreak the arrays for compilers that won't handle large arrays\n"
+ "\t\t-c\tDeclare the arrays as const (useful to ensure they end up in Flash)\n"
+ "\t\t-s\tDeclare the arrays as static\n"
+ "\t\t-n name\tUse \"name\" as the name of the array\n"
+ , opt_progname, opt_progname);
+ return 1;
+ }
+ nextarg: ;
+ }
+
+ /* Open the input file */
+ if (opt_inputfile) {
+ f_input = fopen(opt_inputfile,
+#ifdef WIN32
+ "rb");
+#else
+ "r");
+#endif
+ if (!f_input) {
+ fprintf(stderr, "Could not open input file '%s'\n", opt_inputfile);
+ goto usage;
+ }
+ } else {
+ f_input = stdin;
+#ifdef WIN32
+ _setmode(_fileno(stdin), _O_BINARY);
+#endif
+ }
+
+ /* Open the output file */
+ if (opt_outputfile) {
+ f_output = fopen(opt_outputfile, "w");
+ if (!f_output) {
+ fprintf(stderr, "Could not open output file '%s'\n", opt_outputfile);
+ goto usage;
+ }
+ } else
+ f_output = stdout;
+
+ /* Print the comment header */
+ fprintf(f_output, "/**\n * This file was generated ");
+ if (opt_inputfile) fprintf(f_output, "from \"%s\" ", opt_inputfile);
+ fprintf(f_output, "using...\n *\n *\t%s", opt_progname);
+ if (opt_arrayname || opt_static[0] || opt_const[0] || opt_breakblocks) {
+ fprintf(f_output, " -");
+ if (opt_breakblocks) fprintf(f_output, "b");
+ if (opt_const[0]) fprintf(f_output, "c");
+ if (opt_static[0]) fprintf(f_output, "s");
+ if (opt_arrayname) fprintf(f_output, "n %s", opt_arrayname);
+ }
+ if (opt_inputfile) fprintf(f_output, " %s", opt_inputfile);
+ if (opt_outputfile) fprintf(f_output, " %s", opt_outputfile);
+ fprintf(f_output, "\n *\n */\n");
+
+ /*
+ * Set the array name.
+ * We do this after printing opt_inputfile for the last time as we
+ * modify opt_inputfile in place to generate opt_arrayname.
+ */
+ if (!opt_arrayname) {
+ if (opt_inputfile)
+ opt_arrayname = filenameof(opt_inputfile);
+ if (!opt_arrayname || !opt_arrayname[0])
+ opt_arrayname = "filearray";
+ }
+ opt_arrayname = clean4c(opt_arrayname);
+
+ /* Read the file processing 1K at a time */
+ blocknum = 0;
+ while((len = fread(buf, 1, sizeof(buf), f_input))) {
+ if (!blocknum++)
+ fprintf(f_output, "%s%sunsigned char %s[] = {", opt_static, opt_const, opt_arrayname);
+ else if (opt_breakblocks)
+ fprintf(f_output, "\n};\n%s%sunsigned char %s_p%u[] = {", opt_static, opt_const, opt_arrayname, blocknum);
+ for(i = 0; i < len; i++) {
+ fprintf(f_output, (i & 0x0F) ? " 0x%02X," : "\n\t0x%02X,", buf[i]);
+ }
+ }
+ fprintf(f_output, "\n};\n");
+
+ /* Clean up */
+ if (ferror(f_input))
+ fprintf(stderr, "Input file read error\n");
+ if (ferror(f_output))
+ fprintf(stderr, "Output file write error - disk full?\n");
+ if (f_input != stdin)
+ fclose(f_input);
+ if (f_output != stdout)
+ fclose(f_output);
+
+ return 0;
+}
+