From f017ddf090f9602e750c7db22d034b4a707fff1f Mon Sep 17 00:00:00 2001 From: tomsmeding Date: Wed, 21 Dec 2016 10:32:51 +0100 Subject: Initial --- .gitignore | 3 ++ Makefile | 17 ++++++++ bin2c.c | 135 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 155 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 bin2c.c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6793ace --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +bin2c +*.o +*.dSYM diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..6e84e3d --- /dev/null +++ b/Makefile @@ -0,0 +1,17 @@ +CC = gcc +CFLAGS = -Wall -Wextra -std=c99 -fwrapv +ifneq ($(DEBUG),) + CFLAGS += -g +else + CFLAGS += -O2 +endif +BIN = bin2c + +.PHONY: all clean remake + +all: $(BIN) + +clean: + rm -rf $(BIN) *.dSYM + +remake: clean all diff --git a/bin2c.c b/bin2c.c new file mode 100644 index 0000000..dcc0b7c --- /dev/null +++ b/bin2c.c @@ -0,0 +1,135 @@ +#include +#include +#include +#include + +#define MAXLINEWIDTH (79) + +void usage(){ + fprintf(stderr, + "Usage: bin2c [inputfile] [outputfile]\n" + "\n" + "Converts a binary file to a C string that denotes the same binary contents, but\n" + "is parseable by a C compiler.\n" + "Default values for the arguments are stdin and stdout; also '-' indicates the\n" + "standard stream.\n"); +} + +// Returns serialised string length +// Keeps state on the previous few characters to aid compression +int serialisechar(char *dst,unsigned char c){ + static bool lastwasoctal=false; + static unsigned char prevc; // Only used if lastwasoctal==true + + switch(c){ + case '\a': lastwasoctal=false; dst[0]='\\'; dst[1]='a'; return 2; + case '\b': lastwasoctal=false; dst[0]='\\'; dst[1]='b'; return 2; + case '\f': lastwasoctal=false; dst[0]='\\'; dst[1]='f'; return 2; + case '\n': lastwasoctal=false; dst[0]='\\'; dst[1]='n'; return 2; + case '\r': lastwasoctal=false; dst[0]='\\'; dst[1]='r'; return 2; + case '\t': lastwasoctal=false; dst[0]='\\'; dst[1]='t'; return 2; + case '\v': lastwasoctal=false; dst[0]='\\'; dst[1]='v'; return 2; + case '"': lastwasoctal=false; dst[0]='\\'; dst[1]='"'; return 2; + case '\\': lastwasoctal=false; dst[0]='\\'; dst[1]='\\'; return 2; + default: + if(c<32||c>=127){ + lastwasoctal=true; + prevc=c; + return sprintf(dst,"\\%o",(int)c); + } else if(isdigit(c)&&lastwasoctal&&prevc<'\100'){ + prevc=c; + return sprintf(dst,"\\%o",(int)c); + } else { + lastwasoctal=false; + dst[0]=c; + return 1; + } + } +} + +// Returns new xposition +int convertbuffer(FILE *output,const char *buffer,int length,int xposition){ + char cbuf[8]; + for(int i=0;iMAXLINEWIDTH){ + fputc('"',output); + fputc('\n',output); + fputc('"',output); + xposition=1; + } + fwrite(cbuf,1,clen,output); + xposition+=clen; + } + return xposition; +} + +void bin2c(FILE *input,FILE *output){ + fputc('"',output); + + char buffer[1024]; + int xposition=1; + + while(true){ + size_t nread=fread(buffer,1,sizeof(buffer),input); + if(nread==0){ + break; + } + xposition=convertbuffer(output,buffer,nread,xposition); + if(feof(input)||ferror(input)){ + break; + } + } + + fputc('"',output); + fputc('\n',output); +} + +int main(int argc,char **argv){ + if(argc==1){ + bin2c(stdin,stdout); + } else if(argc==2){ + if(strcmp(argv[1],"-h")==0||strcmp(argv[1],"--help")==0){ + usage(); + } else if(strcmp(argv[1],"-")==0){ + bin2c(stdin,stdout); + } else { + FILE *f=fopen(argv[1],"rb"); + if(!f){ + fprintf(stderr,"Could not open file '%s'\n",argv[1]); + return 1; + } + bin2c(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],"rb"); + if(!fout){ + fprintf(stderr,"Could not open file '%s'\n",argv[2]); + return 1; + } + } + + bin2c(fin,fout); + + fclose(fin); + fclose(fout); + } else { + usage(); + return 1; + } +} -- cgit v1.2.3