#include #include #include #include #include void usage(){ fprintf(stderr, "Usage: c2bin [inputfile] [outputfile]\n" "\n" "Converts a C string to its parsed contents. The inverse of bin2c.\n" "Default values for the arguments are stdin and stdout; also '-' indicates the\n" "standard stream.\n"); } int unhex(int c){ if(c>='0'&&c<='9'){ return c-'0'; } else if(c>='a'&&c<='f'){ return c-'a'+10; } else if(c>='A'&&c<='F'){ return c-'A'+10; } else { return -1; } } void c2bin(FILE *input,FILE *output){ bool stringmode=false; int c; while((c=fgetc(input))!=EOF){ if(c=='"'){ stringmode=!stringmode; } else if(!stringmode){ if(!isspace(c)){ fprintf(stderr,"Characters outside string\n"); exit(1); } } else if(c=='\n'){ fprintf(stderr,"Invalid newline in string\n"); exit(1); } else if(c!='\\'){ fputc(c,output); } else { c=fgetc(input); if(c==EOF){ fprintf(stderr,"Invalid backslash at end of input\n"); exit(1); } else if(c=='\n'){ continue; } else if(c!='x'&&!isdigit(c)){ switch(c){ case 'a': fputc('\a',output); break; case 'b': fputc('\b',output); break; case 'f': fputc('\f',output); break; case 'n': fputc('\n',output); break; case 'r': fputc('\r',output); break; case 't': fputc('\t',output); break; case 'v': fputc('\v',output); break; default: fputc(c,output); break; } } else if(c=='x'){ int c1=fgetc(input); int c2=fgetc(input); if(c1==-1||c2==-1){ fprintf(stderr,"Invalid end of input\n"); exit(1); } c1=unhex(c1); c2=unhex(c2); if(c1==-1){ fprintf(stderr,"Invalid hexadecimal escape\n"); exit(1); } if(c2==-1){ fputc(c1,output); } else { c=fgetc(input); if(c==-1){ fprintf(stderr,"Invalid end of input\n"); exit(1); } if(unhex(c)!=-1){ fprintf(stderr,"Invalid wide hexadecimal escape\n"); exit(1); } ungetc(c,input); fputc(16*c1+c2,output); } } else { ungetc(c,input); int res=0,i; for(i=0;i<3;i++){ c=fgetc(input); if(c==EOF){ fprintf(stderr,"Invalid end of input\n"); exit(1); } if(c<'0'||c>='8'){ ungetc(c,input); break; } res=8*res+c-'0'; } if(i==0){ fprintf(stderr,"Invalid octal escape\n"); exit(1); } fputc(res,output); } } fflush(output); } } int main(int argc,char **argv){ if(argc==1){ c2bin(stdin,stdout); } else if(argc==2){ if(strcmp(argv[1],"-h")==0||strcmp(argv[1],"--help")==0){ usage(); } else if(strcmp(argv[1],"-")==0){ c2bin(stdin,stdout); } else { FILE *f=fopen(argv[1],"rb"); if(!f){ fprintf(stderr,"Could not open file '%s'\n",argv[1]); return 1; } c2bin(f,stdout); fclose(f); } } else if(argc==3){ FILE *fin,*fout; if(strcmp(argv[1],"-")==0){ fin=stdin; } else { fin=fopen(argv[1],"rb"); if(!fin){ fprintf(stderr,"Could not open file '%s'\n",argv[1]); return 1; } } if(strcmp(argv[2],"-")==0){ fout=stdout; } else { fout=fopen(argv[2],"wb"); if(!fout){ fprintf(stderr,"Could not open file '%s'\n",argv[2]); return 1; } } c2bin(fin,fout); fclose(fin); fclose(fout); } else { usage(); return 1; } }