diff --git a/Sources/Ecc/Main.cpp b/Sources/Ecc/Main.cpp index 3cc2987..a175910 100644 --- a/Sources/Ecc/Main.cpp +++ b/Sources/Ecc/Main.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2002-2012 Croteam Ltd. +/* 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 @@ -63,7 +63,7 @@ char *LineDirective(int i) return strdup(str); } -SType SType::operator+(const SType &other) +SType SType::operator+(const SType &other) { SType sum; sum.strString = stradd(strString, other.strString); @@ -116,7 +116,7 @@ FILE *FOpen(const char *strFileName, char *strMode) /* * Print a header to an output file. */ -static void PrintHeader(FILE *f) +static void PrintHeader(FILE *f) { fprintf(f, "/*\n"); fprintf(f, " * This file is generated by Entity Class Compiler, (c) CroTeam 1997-98\n"); @@ -174,13 +174,13 @@ void ReplaceFileRL(const char *strOld, const char *strNew) { continue; } - + // process each charachter for(int ich=0;ich0) && (*(pchNew-1)=='\\')) { } else bQuotes = !bQuotes; } @@ -227,8 +227,111 @@ void ReplaceFile(const char *strOld, const char *strNew) remove(strOld); rename(strNew, strOld); } + +enum ESStatus +{ + /* Appears to be non-empty, ready to parse. */ + Good, + /* Appears to be empty, ignore it. */ + Empty, + /* Error occured during status check. */ + Error, +}; + +/* Determine whether or not our target ES file is indeed valid input. */ +ESStatus GetESStatus(char *filename) +{ + ESStatus result = ESStatus::Empty; + + // Read a temporary buffer of the entire file contents + fseek(_fInput, 0, SEEK_END); + size_t length = ftell(_fInput); + char* temporaryBuffer = (char*)malloc(length); + fseek(_fInput, 0, SEEK_SET); + fread(temporaryBuffer, length, 1, _fInput); + fclose(_fInput); + + // Loop through each line + char* currentSequence = strtok(temporaryBuffer, "\n"); + + // No newlines, but it might still be valid. + if (!currentSequence) + currentSequence = temporaryBuffer; + + bool inBlockComment = false; + do + { + size_t sequenceLength = strlen(currentSequence); + + for (size_t iteration = 0; iteration < sequenceLength; iteration++) + { + // If we're still in a block comment, find the closing */ + if (inBlockComment) + { + char* blockClosing = strstr(currentSequence, "*/"); + if (!blockClosing) + break; + else + { + inBlockComment = false; + iteration = ((size_t)blockClosing - (size_t)currentSequence) + 2; + } + } + + // If we find a // sequence, simply skip this line + if (currentSequence[iteration] == '/' && currentSequence[iteration + 1] == '/') + break; + + // If we find a /* on this line but not a closing */, skip this line + if (currentSequence[iteration] == '/' && currentSequence[iteration + 1] == '*') + { + // Is there a closing */ on this line? + char* blockClosing = strstr(currentSequence, "*/"); + + if (!blockClosing) + { + inBlockComment = true; + break; + } + else + { + iteration = ((size_t)blockClosing - (size_t)currentSequence) + 2; + inBlockComment = false; + continue; + } + } + + if (iteration >= sequenceLength) + break; + + // If we got to this point, we should be able to read only a number on this line + for (size_t checkIteration = 0; checkIteration < sequenceLength; checkIteration++) + if (currentSequence[checkIteration] != '\n' && currentSequence[checkIteration] != 0x20 && !isdigit(currentSequence[checkIteration])) + { + result = ESStatus::Error; + break; + } + else if (currentSequence[checkIteration] != '\n' && currentSequence[checkIteration] != 0x20) + result = ESStatus::Good; + + free(temporaryBuffer); + if (result == ESStatus::Good) + _fInput = FOpen(filename, "r"); + + return result; + } + } + while(currentSequence = strtok(NULL, "\n")); + + free(temporaryBuffer); + if (result == ESStatus::Good) + _fInput = FOpen(filename, "r"); + + return result; +} + /* Replace a file with a new file if they are different. - * Used to keep .h files from constantly changing when you change the implementation. + * Used to keep .h files from constantly changing when you change the implementation. */ void ReplaceIfChanged(const char *strOld, const char *strNew) { @@ -240,7 +343,7 @@ void ReplaceIfChanged(const char *strOld, const char *strNew) 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); @@ -283,6 +386,18 @@ int main(int argc, char *argv[]) } // open the input file _fInput = FOpen(argv[1], "r"); + + // Make sure we're loading a valid ES file + ESStatus status = GetESStatus(argv[1]); + + switch (status) + { + case ESStatus::Empty: + return EXIT_SUCCESS; + case ESStatus::Error: + return EXIT_FAILURE; + } + //printf("%s\n", argv[1]); // open all the output files char *strImplementation = ChangeFileNameExtension(argv[1], ".cpp_tmp"); @@ -333,7 +448,7 @@ int main(int argc, char *argv[]) ReplaceFile(strImplementationOld, strImplementation); ReplaceIfChanged(strDeclarationOld, strDeclaration); ReplaceIfChanged(strTablesOld, strTables); - + return EXIT_SUCCESS; // if there were errors } else { diff --git a/Sources/Ecc/StdH.h b/Sources/Ecc/StdH.h index 6def450..3482ed6 100644 --- a/Sources/Ecc/StdH.h +++ b/Sources/Ecc/StdH.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2002-2012 Croteam Ltd. +/* 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 @@ -13,6 +13,7 @@ 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 #include #include #include @@ -27,4 +28,3 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #define _fullpath(x, y, z) realpath(y, x) #endif -