/* carray.c : PUBLIC DOMAIN - Jon Mayo - August 30, 2006 * - You may remove any comments you wish, modify this code any way you wish, * and distribute any way you wish.*/ /* dumps binary or text into a fully escaped C array. * useful for creating UTF-8 and UTF-16 string constants */ /* TODO: * accept a list of arguments to dump. * dump multiple files to multiple arrays, for a simple filesystem * optionally output a directory index holding all the file information */ #include #include #include enum { METHOD_STRING, METHOD_DECIMAL, METHOD_HEXDUMP, METHOD_CHARHEX }; static char *name = "data"; static int method = METHOD_STRING; static int max_width = 78; static void usage(const char *argv0) { printf("usage: %s\n", argv0); printf( "\t-s\t\tstring mode\n" "\t-d\t\tdecimal mode\n" "\t-x\t\thex mode\n" "\t-c\t\tchar and hex mode\n" "\t-w \tselects the width to use (default=78, minimum=20)\n" , max_width ); exit(EXIT_FAILURE); } /* I am not proud of this code, I prefer to use getopt() */ static int parse_args(int argc, char **argv) { int i,j; char ch; for(i=1;i=max_width) { printf("\"\n\t\""); *width=8+adj; } } static void dump_string(FILE *f) { int len; int width; int ch; len=0; printf("\t\""); width=8; while((ch=fgetc(f))!=EOF) { len++; if(isprint(ch)) { if(ch=='\\') { check_width(&width, 2); printf("\\\\"); } else if(ch=='"') { check_width(&width, 2); printf("\\\""); } else { check_width(&width, 1); putc(ch, stdout); } } else { if(ch=='\0') { check_width(&width, 2); printf("\\0"); } else if(ch=='\n') { check_width(&width, 2); printf("\\n"); } else if(ch=='\r') { check_width(&width, 2); printf("\\r"); } else if(ch=='\t') { check_width(&width, 2); printf("\\t"); } else if(ch=='\a') { check_width(&width, 2); printf("\\a"); } else if(ch=='\v') { check_width(&width, 2); printf("\\v"); } else { check_width(&width, ch<010 ? 3 : ch<0100 ? 4 : 5); printf("\\0%o", ch); } } } printf("\";\n"); printf("const int %s_len=%d;\n", name, len); } /* style 2 - decimal */ void dump_decimal(FILE *f) { int len; int ch; int width; int cw; printf("{"); width=max_width; len=0; while((ch=fgetc(stdin))!=EOF) { len++; cw=ch<10 ? 2 : ch<100 ? 3 : 4; /* width of this entry */ if(width+cw+1>=max_width) { printf("\n\t"); width=8+cw; } else { printf(" "); width+=cw+1; } printf("%u,", ch); } printf("\n};\n"); printf("const int %s_len=%d;\n", name, len); } /* style 3 - hexdump */ void dump_hex(FILE *f) { int len; int ch; int width; printf("{"); width=max_width; len=0; while((ch=fgetc(stdin))!=EOF) { len++; width+=6; if(width>=max_width) { printf("\n\t"); width=8+5; } else { printf(" "); } printf("0x%02x,", ch); } printf("\n};"); printf("const int %s_len=%d;\n", name, len); } /* style 4 - charhex */ void dump_charhex(FILE *f) { int len; int ch; int width; int cw; printf("{"); width=max_width; len=0; while((ch=fgetc(stdin))!=EOF) { len++; if(ch=='\'' || ch=='\\') { cw=5; } else if(isprint(ch)) { cw=4; } else { cw=5; } if(width+cw+1>=max_width) { printf("\n\t"); width=8+cw; } else { printf(" "); width+=cw+1; } if(ch=='\'' || ch=='\\') { printf("'\\%c',", ch); } else if(isprint(ch)) { printf("'%c',", ch); } else { printf("0x%02x,", ch); } } printf("\n};\n"); printf("const int %s_len=%d;\n", name, len); } int main(int argc, char **argv) { int optind; optind=parse_args(argc, argv); printf("const unsigned char %s[] =\n", name); if(max_width<20) { usage(argv[0]); } switch(method) { case METHOD_STRING: dump_string(stdin); break; case METHOD_DECIMAL: dump_decimal(stdin); break; case METHOD_HEXDUMP: dump_hex(stdin); break; case METHOD_CHARHEX: dump_charhex(stdin); break; default: usage(argv[0]); } return 0; }