/* unhexify.c - input hex file, output binary */ /* * laugh also: hexify.c, hexsum.c, coagulate.c */ /* * a hex file has some bytes, each represented as a pair of hex digits (hits) * to %02x format. * any whitespace may occur between bytes, but whitespace is forbidden * between the hits of a byte. * an odd number of hits in a file is silly. */ /* * after reading 'recsiz' bytes, we output a files-11 record of that many bytes * if the last record output is shorter than the rest: so be it. * because magtapes etc want minimum record sizes, we allow padding the last * (possibly short) record with 'pad' bytes up to 'recsiz' */ #include #include #define BUFSIZ 4096 /* maximum output record size (bytes) */ helpless() BEGIN fprintf(stderr,"\7usage: UNHEXIFY recsiz {pad}\n"); fprintf(stderr,"std input is a hex file.\n"); fprintf(stderr,"std output is binary records\n"); fprintf(stderr,"every recsiz bytes we make a new record\n"); fprintf(stderr,"the last record is padded to recsiz with pad bytes\n"); fprintf(stderr,"pad is hexadecimal\n"); fprintf(stderr,"the maximum record size for this edition is %d.\n",BUFSIZ); exit(); END int recsiz; /* number of bytes per output record */ FILE * winge; /* where to send error messages */ int line; /* 0-org line number last read from input */ int got1st; /* TRUE if seen 1st hit of a byte & not 2nd */ char buf[BUFSIZ]; /* output record built here */ char * ptr; /* tracks buf[] */ int hexbyte; /* build up a byte here */ int pad; /* what to pad last record with -1==don't pad */ main(argc,argv) int argc; char * * argv; BEGIN int c; /* suspicious character */ winge = stderr; IF (argc<2 || argc>3) THEN helpless(); FI sscanf(argv[1],"%d",&recsiz); IF (recsiz<=0 || recsiz>BUFSIZ) THEN helpless(); FI IF (argc==3) THEN sscanf(argv[2],"%x",&pad); pad &= 0xFF; ELSE pad = -1; FI line = 0; got1st = FALSE; ptr = buf; while ((c=getchar())>=0) { if (!iswhite(c)) { hexacc(c); }else{ if (got1st) { fprintf(winge,"whitespace within hexadecimal digits of byte"); panic(); }; }; if (c=='\n') { line++; }; }; if (got1st) { fprintf(winge,"odd number of hex digits"); panic(); }; IF (pad>-1) THEN WHILE (ptr < buf+recsiz) DO * ptr ++ = pad; OD FI fart(); } hexacc(c) int c; { int h; if ((h=hexconv(c))>=0) { if (got1st) { hexbyte = (hexbyte<<4) | h; IF (ptr >= buf+recsiz) THEN fart(); FI *ptr ++ = hexbyte; }else{ hexbyte = h; }; got1st = ! got1st; }else{ fprintf(winge,"char=%xx invalid",c); panic(); }; } fart() BEGIN fput(buf,ptr-buf,stdout); IF (ferror(stdout)) THEN fprintf(winge,"output error $$ferr=%oo\7\n",$$ferr); FI ptr = buf; END panic() { fprintf(winge,"\n\7line=%d.\n",line); exit(42); }; int hexconv(c) int c; { c = tolower(c); if (isdigit(c)) { c = c - '0'; }else{ if (c>='a' && c<='f') { c = c-'a' + 10; }else{ c = -1; }; }; return(c); } iswhite(c) int c; { int r; char * index(); r=index(" \t\n\r\b\f",c); return(r); } int isdigit(c) int c; { int r; char * index(); r=index("0123456789",c); return(r); } int tolower(c) int c; { if (c<='Z' && c>='A') { c = c-'Z'+'z'; }; return(c); } char * index(s,c) char *s; char c; { while (*s) { if ( (*s++)==c ) { return(--s); }; }; return(0); }