diff options
Diffstat (limited to 'graftest/blob2c.c')
-rw-r--r-- | graftest/blob2c.c | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/graftest/blob2c.c b/graftest/blob2c.c new file mode 100644 index 0000000..779b79f --- /dev/null +++ b/graftest/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; +} |