aboutsummaryrefslogtreecommitdiff
path: root/blob2c.c
diff options
context:
space:
mode:
authorB. Watson <urchlay@slackware.uk>2022-08-29 16:11:13 -0400
committerB. Watson <urchlay@slackware.uk>2022-08-29 16:11:13 -0400
commite2ba8458a5cfdfacfaf103e7ba97d610afa6c970 (patch)
treecd665e602e6e2b636578a7d3d7894380605dafcc /blob2c.c
downloadbw-atari8-tools-e2ba8458a5cfdfacfaf103e7ba97d610afa6c970.tar.gz
initial commit
Diffstat (limited to 'blob2c.c')
-rw-r--r--blob2c.c117
1 files changed, 117 insertions, 0 deletions
diff --git a/blob2c.c b/blob2c.c
new file mode 100644
index 0000000..779b79f
--- /dev/null
+++ b/blob2c.c
@@ -0,0 +1,117 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <ctype.h>
+
+/* since we're emitting C source, the comments containing the
+ ASCII dump better not contain C comment markers! */
+void fixasc(char *asc, int len) {
+ int j;
+
+ for(j=0; j<(len-1); j++) {
+ /* slash-star or slash-slash become slash-dot */
+ if(asc[j] == '/' && (asc[j+1] == '*' || asc[j+1] == '/'))
+ asc[j+1] = '.';
+ /* star-slash becomes dot-slash */
+ else if(asc[j] == '*' && asc[j+1] == '/')
+ asc[j] = '.';
+ }
+}
+
+int main(int argc, char **argv) {
+ int i, j, count = 0;
+ char *p, asc[9];
+ FILE *in;
+
+ if(argc != 2) {
+ fprintf(stderr,
+ "#error usage: %s blobfile >blobfile.c 2>blobfile.h\n", argv[0]);
+ exit(1);
+ }
+
+ if( !(in = fopen(argv[1], "rb")) ) {
+ fprintf(stderr, "/* %s: %s */\n", argv[1], strerror(errno));
+ exit(1);
+ }
+
+ printf("/* C source created by blob2c from input file %s */\n\n", argv[1]);
+ fprintf(stderr,
+ "/* C header created by blob2c from input file %s */\n\n", argv[1]);
+
+ for(p = argv[1]; *p; p++)
+ if(!isalnum(*p)) *p = '_';
+
+ fprintf(stderr,
+ "#ifndef %s_H\n"
+ "#define %s_H\n\n",
+ argv[1], argv[1]);
+
+ /* start array definition */
+ printf("unsigned char %s[] = {", argv[1]);
+
+ asc[8] = '\0';
+
+ /* read/process each input byte in loop, until EOF */
+ while( (i = getc(in)) != EOF ) {
+ if(count) putchar(',');
+
+ if(count % 8 == 0) {
+ if(count) {
+ /* fix & print ASCII dump */
+ fixasc(asc, 8);
+ printf(" /* %s */", asc);
+ }
+
+ /* start next line */
+ printf("\n\t/* %6d */ ", count);
+ }
+
+ /* store this byte of ASCII dump */
+ asc[count % 8] = isprint(i) ? i : '.';
+
+ /* print this byte of hex data */
+ printf("0x%02x", i);
+
+ count++;
+ }
+
+ /* fix ASCII dump for last line */
+ i = count % 8;
+ if(!i) i = 8;
+ fixasc(asc, i);
+ asc[i] = '\0';
+
+ /* line it up with the previous lines */
+ j = (8 - i) * 5;
+ for(i=0; i<j; i++)
+ putchar(' ');
+
+ /* print it */
+ printf(" /* %s */", asc);
+
+ /* end of array definition */
+ printf("\n}; /* %s */\n\n", argv[1]);
+
+ /* array_len definition */
+ printf("int %s_len = %d;\n", argv[1], count);
+
+ /* check for read errors */
+ i = 0;
+ if(ferror(in)) {
+ fprintf(stderr, "#error %s: %s\n", argv[1], strerror(errno));
+ i = 1;
+ }
+
+ fclose(in);
+
+ /* extern declarations to stderr */
+ fprintf(stderr,
+ "extern unsigned char %s[];\nextern int %s_len;\n",
+ argv[1], argv[1]);
+
+ fprintf(stderr, "\n#endif /* %s_H */\n", argv[1]);
+
+ return i;
+}