123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349 |
- /* Copyright (c) 2002-2012 Croteam Ltd.
- This program is free software; you can redistribute it and/or modify
- it under the terms of version 2 of the GNU General Public License as published by
- the Free Software Foundation
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
- #include "StdH.h"
- #include "Main.h"
- FILE *_fInput;
- int _iLinesCt = 1;
- char *_strInputFileName;
- int _bTrackLineInformation=0; // this is set if #line should be inserted in tokens
- bool _bRemoveLineDirective = 0;
- FILE *_fImplementation;
- FILE *_fDeclaration;
- FILE *_fTables;
- FILE *_fExports;
- char *_strFileNameBase;
- char *_strFileNameBaseIdentifier;
- extern FILE *yyin;
- extern "C" int yywrap(void)
- {
- return 1;
- }
- int ctErrors = 0;
- char *stradd(char *str1, char *str2)
- {
- char *strResult;
- strResult = (char*)malloc(strlen(str1)+strlen(str2)+1);
- strcpy(strResult, str1);
- strcat(strResult, str2);
- return strResult;
- }
- char *stradd(char *str1, char *str2, char *str3)
- {
- char *strResult;
- strResult = (char*)malloc(strlen(str1)+strlen(str2)+strlen(str3)+1);
- strcpy(strResult, str1);
- strcat(strResult, str2);
- strcat(strResult, str3);
- return strResult;
- }
- char *LineDirective(int i)
- {
- char str[256];
- sprintf(str, "\n#line %d %s\n", i, _strInputFileName);
- return strdup(str);
- }
- SType SType::operator+(const SType &other)
- {
- SType sum;
- sum.strString = stradd(strString, other.strString);
- sum.iLine = -1;
- sum.bCrossesStates = bCrossesStates||other.bCrossesStates;
- return sum;
- };
- /*
- * Function used for reporting errors.
- */
- void yyerror(char *s)
- {
- fprintf( stderr, "%s(%d): Error: %s\n", _strInputFileName, _iLinesCt, s);
- ctErrors++;
- }
- /*
- * Change the extension of the filename.
- */
- char *ChangeFileNameExtension(char *strFileName, char *strNewExtension)
- {
- char *strChanged = (char*)malloc(strlen(strFileName)+strlen(strNewExtension)+2);
- strcpy(strChanged, strFileName);
- char *pchDot = strrchr(strChanged, '.');
- if (pchDot==NULL) {
- pchDot = strChanged+strlen(strChanged);
- }
- strcpy(pchDot, strNewExtension);
- return strChanged;
- }
- /*
- * Open a file and report an error if failed.
- */
- FILE *FOpen(const char *strFileName, char *strMode)
- {
- // open the input file
- FILE *f = fopen(strFileName, strMode);
- // if not successful
- if (f==NULL) {
- // report error
- fprintf(stderr, "Can't open file '%s': %s\n", strFileName, strerror(errno));
- //quit
- exit(EXIT_FAILURE);
- }
- return f;
- }
- /*
- * Print a header to an output file.
- */
- static void PrintHeader(FILE *f)
- {
- fprintf(f, "/*\n");
- fprintf(f, " * This file is generated by Entity Class Compiler, (c) CroTeam 1997-98\n");
- fprintf(f, " */\n");
- fprintf(f, "\n");
- }
- void TranslateBackSlashes(char *str)
- {
- char *strNextSlash = str;
- while((strNextSlash = strchr(strNextSlash, '\\'))!=NULL) {
- *strNextSlash = '/';
- }
- }
- #define READSIZE 1024
- /* Relpace File and remove #line directive from file */
- void ReplaceFileRL(const char *strOld, const char *strNew)
- {
- char strOldBuff[READSIZE*3+1];
- char strNewBuff[READSIZE+1];
- int iOldch=0;
- FILE *pfNew = NULL;
- FILE *pfOld = NULL;
- bool bQuotes = 0;
- bool bComment = 0;
- // open files
- pfNew = fopen(strNew,"rb");
- if(!pfNew) goto Error;
- pfOld = fopen(strOld,"wb");
- if(!pfOld) goto Error;
- // until eof
- while(!feof(pfNew))
- {
- // clear buffers
- memset(&strOldBuff,0,sizeof(strOldBuff));
- memset(&strNewBuff,0,sizeof(strNewBuff));
- iOldch = 0;
- bQuotes = 0;
- bComment = 0;
- // read one line from file
- int iRead = fread(strNewBuff,1,READSIZE,pfNew);
- char *chLineEnd = strchr(strNewBuff,13);
- if(chLineEnd) *(chLineEnd+2) = 0;
- // get line length
- int ctch = strlen(strNewBuff);
- int iSeek = -iRead+ctch;
- // seek file for extra characters read
- if(iSeek!=0) fseek(pfNew,iSeek ,SEEK_CUR);
- if(strncmp(strNewBuff,"#line",5)==0)
- {
- continue;
- }
- // process each charachter
- for(int ich=0;ich<ctch;ich++)
- {
- char *pchOld = &strOldBuff[iOldch];
- char *pchNew = &strNewBuff[ich];
- if((*pchNew == '{') || (*pchNew == '}') || *pchNew == ';')
- {
- if((!bComment) && (!bQuotes) && (*(pchNew+1) != 13))
- {
- strOldBuff[iOldch++] = strNewBuff[ich];
- strOldBuff[iOldch++] = 13;
- strOldBuff[iOldch++] = 10;
- continue;
- }
- }
- if(*pchNew == '"')
- {
- // if this is quote
- if((ich>0) && (*(pchNew-1)=='\\')) { }
- else bQuotes = !bQuotes;
- }
- else if((*pchNew == '/') && (*(pchNew+1) == '/'))
- {
- // if this is comment
- bComment = 1;
- }
- strOldBuff[iOldch++] = strNewBuff[ich];
- }
- fwrite(&strOldBuff,1,iOldch,pfOld);
- }
- if(pfNew) fclose(pfNew);
- if(pfOld) fclose(pfOld);
- remove(strNew);
- return;
- Error:
- if(pfNew) fclose(pfNew);
- if(pfOld) fclose(pfOld);
- }
- /* Replace a file with a new file. */
- void ReplaceFile(const char *strOld, const char *strNew)
- {
- if(_bRemoveLineDirective)
- {
- ReplaceFileRL(strOld,strNew);
- return;
- }
- remove(strOld);
- rename(strNew, strOld);
- }
- /* Replace a file with a new file if they are different.
- * Used to keep .h files from constantly changing when you change the implementation.
- */
- void ReplaceIfChanged(const char *strOld, const char *strNew)
- {
- int iChanged = 1;
- FILE *fOld = fopen(strOld, "r");
- if (fOld!=NULL) {
- iChanged = 0;
- FILE *fNew = FOpen(strNew, "r");
- while (!feof(fOld)) {
- char strOldLine[4096] = "#l";
- char strNewLine[4096] = "#l";
- // skip #line directives
- while(strNewLine[0]=='#' && strNewLine[1]=='l' && !feof(fNew)) {
- fgets(strNewLine, sizeof(strNewLine)-1, fNew);
- }
- while(strOldLine[0]=='#' && strOldLine[1]=='l' && !feof(fOld)) {
- fgets(strOldLine, sizeof(strOldLine)-1, fOld);
- }
- if (strcmp(strNewLine, strOldLine)!=0) {
- iChanged = 1;
- break;
- }
- }
- fclose(fNew);
- fclose(fOld);
- }
- if (iChanged) {
- remove(strOld);
- rename(strNew, strOld);
- } else {
- remove(strNew);
- }
- }
- int main(int argc, char *argv[])
- {
- // if there is not one argument on the command line
- if (argc<1+1) {
- // print usage
- printf("Usage: Ecc <es_file_name>\n -line\n");
- //quit
- return EXIT_FAILURE;
- }
- if(argc>2)
- {
- if(strcmp(argv[2],"-line")==0)
- {
- _bRemoveLineDirective=1;
- }
- }
- // open the input file
- _fInput = FOpen(argv[1], "r");
- //printf("%s\n", argv[1]);
- // open all the output files
- char *strImplementation = ChangeFileNameExtension(argv[1], ".cpp_tmp");
- char *strImplementationOld = ChangeFileNameExtension(argv[1], ".cpp");
- char *strDeclaration = ChangeFileNameExtension(argv[1], ".h_tmp");
- char *strDeclarationOld = ChangeFileNameExtension(argv[1], ".h");
- char *strTables = ChangeFileNameExtension(argv[1], "_tables.h_tmp");
- char *strTablesOld = ChangeFileNameExtension(argv[1], "_tables.h");
- _fImplementation = FOpen(strImplementation, "w");
- _fDeclaration = FOpen(strDeclaration , "w");
- _fTables = FOpen(strTables , "w");
- // get the filename as preprocessor usable identifier
- _strFileNameBase = ChangeFileNameExtension(argv[1], "");
- _strFileNameBaseIdentifier = strdup(_strFileNameBase);
- {char *strNextSlash = _strFileNameBaseIdentifier;
- while((strNextSlash = strchr(strNextSlash, '/'))!=NULL) {
- *strNextSlash = '_';
- }}
- {char *strNextSlash = _strFileNameBaseIdentifier;
- while((strNextSlash = strchr(strNextSlash, '\\'))!=NULL) {
- *strNextSlash = '_';
- }}
- // print their headers
- PrintHeader(_fImplementation );
- PrintHeader(_fDeclaration );
- PrintHeader(_fTables );
- // remember input filename
- char strFullInputName[MAXPATHLEN];
- _fullpath(strFullInputName, argv[1], MAXPATHLEN);
- _strInputFileName = strFullInputName;
- TranslateBackSlashes(_strInputFileName);
- // make lex use the input file
- yyin = _fInput;
- // parse input file and generate the output files
- yyparse();
- // close all files
- fclose(_fImplementation);
- fclose(_fDeclaration);
- fclose(_fTables);
- // if there were no errors
- if (ctErrors==0) {
- // update the files that have changed
- ReplaceFile(strImplementationOld, strImplementation);
- ReplaceIfChanged(strDeclarationOld, strDeclaration);
- ReplaceIfChanged(strTablesOld, strTables);
- return EXIT_SUCCESS;
- // if there were errors
- } else {
- // delete all files (the old declaration file is left intact!)
- remove(strImplementation);
- remove(strDeclaration );
- remove(strTables );
- return EXIT_FAILURE;
- }
- }
|