/* * Copyright (c) 2014-2015, Claudio Lapilli and the newRPL Team * All rights reserved. * This file is released under the 3-clause BSD license. * See the file LICENSE.txt that shipped with this distribution. */ #include "newrpl.h" #include "libraries.h" #include "ui.h" #include #include extern void lib4079_handler(); // DISPLAY AN ERROR MESSAGE // USES ERROR CODE FROM SYSTEM Exceptions // OUTPUTS THE ERROR TO THE GIVEN STREAM (USUALLY stderr) void compShowErrorMsg(char *inputfile,char *mainbuffer,FILE *stream) { int errbit; if(!Exceptions) return; char *position = (char *)TokenStart; char *linestart=NULL; // COMPUTE LINE NUMBER int linenum=1; while(position>mainbuffer) { --position; if(*position=='\n') { ++linenum; if(!linestart) linestart=position+1; } } // COUNT CHARACTERS FROM START OF LINE position=(char *)TokenStart; while(*linestart=='\r') ++linestart; int posnum=utf8nlen(linestart,position)+1; fprintf(stream,"%s:%d:%d:",inputfile,linenum,posnum); if(Exceptions!=EX_ERRORCODE) { if(ExceptionPointer && (*ExceptionPointer!=0)) { // ONLY IF THERE'S A VALID COMMAND TO BLAME WORDPTR cmdname=halGetCommandName(ExceptionPointer); if(cmdname) { BYTEPTR start=(BYTEPTR)(cmdname+1); BYTEPTR end=start+rplStrSize(cmdname); fwrite(start,1,end-start,stream); } } fprintf(stream," Exception: "); BINT ecode; for(errbit=0;errbit<8;++errbit) // THERE'S ONLY A FEW EXCEPTIONS IN THE NEW ERROR MODEL { if(Exceptions&(1<] \n"); printf("\nOptions:\n"); printf("\t\t-c\tOutput will be as C source code.\n"); printf("\t\t-o \tSpecify a output file name (defaults to filename.c or filename.binrpl)\n\n\n"); return 0; } int argidx=1; int outputtype=OUTPUT_BINARY; int needoutputname=0; int needcleanup=0; char *outputfile=NULL; char *inputfile=NULL; while(argidxinputfile)&&(*end!='.')&&(*end!='/')&&(*end!='\\')) --end; if(end<=inputfile) end=inputfile+strlen(inputfile); else if(*end!='.') end=inputfile+strlen(inputfile); needcleanup++; outputfile=malloc(end-inputfile+10); if(!outputfile) { fprintf(stderr,"error: Memory allocation error\n"); return 1; } memmove(outputfile,inputfile,end-inputfile); strcpy(outputfile+(end-inputfile),(outputtype==OUTPUT_C)? ".c":".binrpl"); } // READ THE INPUT FILE INTO A BUFFER FILE *f=fopen(inputfile,"rb"); if(f==NULL) { fprintf(stderr,"error: File not found %s\n",inputfile); if(needcleanup) free(outputfile); return 1; } fseek(f,0,SEEK_END); long long length=ftell(f); fseek(f,0,SEEK_SET); mainbuffer=malloc(length); if(!mainbuffer) { fprintf(stderr,"error: Memory allocation error\n"); if(needcleanup) free(outputfile); return 1; } if(fread(mainbuffer,1,length,f)!=(size_t)length) { fprintf(stderr,"error: Can't read from input file\n"); if(needcleanup) free(outputfile); free(mainbuffer); return 1; } fclose(f); // HERE WE HAVE THE MAIN FILE rplInitMemoryAllocator(); rplInit(); rplSetSystemFlag(FL_STRIPCOMMENTS); rplInstallLibrary(lib4079_handler); // IDENTIFY CHUNKS OF CODE char *chunk=mainbuffer; int numchunks=0; char *chunkstart[65537]; // MAXIMUM NUMBER OF VARIABLES IN A SINGLE FILE while(chunk-mainbuffer65535) { fprintf(stderr,"error: Too many chunks in same file.\n"); if(needcleanup) free(outputfile); free(mainbuffer); return 1; } } //SKIP TO THE NEXT LINE while( (*chunk!='\n')&&(*chunk!='\r')&&(chunk-mainbufferstart) { WORDPTR newobject=rplCompile((BYTEPTR)start,end-start,1); if(Exceptions) { compShowErrorMsg(inputfile,mainbuffer,stderr); fclose(f); remove(outputfile); if(needcleanup) free(outputfile); free(mainbuffer); return 1; } // OUTPUT THE CHUNK if(outputtype==OUTPUT_C) { if(rplObjSize(newobject)>2) { // OUTPUT C FORMATTED CODE char *objname; char *nameend; if(!utf8ncmp2(chunkstart[k],chunkstart[k+1],"@#name",6)) { objname=chunkstart[k]+6; while( (*objname==' ') || (*objname=='\t')) ++objname; nameend=objname; while( (*nameend!='\n') && (*nameend!='\r') && (*nameend!=' ') && (*nameend!='\t')) ++nameend; } else { nameend=objname=NULL; } fprintf(f,"ROMOBJECT "); if(nameend<=objname) fprintf(f,"chunk%05d",k+1); else fwrite(objname,1,nameend-objname,f); fprintf(f,"[]= {\n"); WORDPTR p=newobject+1,endp=rplSkipOb(newobject)-1; int wordcount=0; while(p0) { char *foundtext=end-textoffset,*endtext; if(foundtext>=start) { // IT'S A VALID POINTER INTO THE TEXT! // FIND THE END OF THE TEXT givenwords=1; endtext=foundtext; while(endtext7) fprintf(f,"\n"); wordcount+=storedwords; continue; //} } rplError(ERR_SYNTAXERROR); TokenStart=(WORDPTR)foundtext; compShowErrorMsg(inputfile,mainbuffer,stderr); } // IF IT FALLS THROUGH, THEN IT'S AN INVALID SPECIAL SEQUENCE // JUST CONTINUE NORMALLY, AS IT COULD BE RANDOM DATA } fprintf(f,"0x%08X",*p); if(p!=endp-1) fprintf(f,","); wordcount++; if((wordcount&7)==0) fprintf(f,"\n"); ++p; } if((wordcount&7)!=0) fprintf(f,"\n"); fprintf(f,"};\n\n\n"); } } else { if(rplObjSize(newobject)>2) { // RAW BINARY OUTPUT fwrite(newobject+1,4,rplObjSize(newobject)-2,f); } } } // AND MOVE ON TO THE NEXT ONE } // CLOSE THE OUTPUT FILE fclose(f); return 0; }