summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2016-09-05 18:18:32 (GMT)
committerBrad King <brad.king@kitware.com>2016-09-06 19:52:40 (GMT)
commitd28da906fed16ab7f45440db65c8c84e15b53996 (patch)
tree0fdac920d680d9ea403add5875bcdc789983ae00
parent8c65a5017fe6a6dfe6d57018e28decd7649588d4 (diff)
downloadCMake-d28da906fed16ab7f45440db65c8c84e15b53996.zip
CMake-d28da906fed16ab7f45440db65c8c84e15b53996.tar.gz
CMake-d28da906fed16ab7f45440db65c8c84e15b53996.tar.bz2
cmFortranParser: Inject a newline at end-of-file when missing
Our parser grammar expects all statements to end in an `EOSTMT` token such as a newline. Ensure that the last statement in a file can be parsed even if it is missing a newline.
-rw-r--r--Source/cmFortranParser.h2
-rw-r--r--Source/cmFortranParserImpl.cxx15
2 files changed, 15 insertions, 2 deletions
diff --git a/Source/cmFortranParser.h b/Source/cmFortranParser.h
index d27a192..2b58375 100644
--- a/Source/cmFortranParser.h
+++ b/Source/cmFortranParser.h
@@ -118,11 +118,13 @@ struct cmFortranFile
: File(file)
, Buffer(buffer)
, Directory(dir)
+ , LastCharWasNewline(false)
{
}
FILE* File;
YY_BUFFER_STATE Buffer;
std::string Directory;
+ bool LastCharWasNewline;
};
struct cmFortranParser_s
diff --git a/Source/cmFortranParserImpl.cxx b/Source/cmFortranParserImpl.cxx
index d43d47c..639b3f0 100644
--- a/Source/cmFortranParserImpl.cxx
+++ b/Source/cmFortranParserImpl.cxx
@@ -119,8 +119,19 @@ int cmFortranParser_Input(cmFortranParser* parser, char* buffer,
// Read from the file on top of the stack. If the stack is empty,
// the end of the translation unit has been reached.
if (!parser->FileStack.empty()) {
- FILE* file = parser->FileStack.top().File;
- return (int)fread(buffer, 1, bufferSize, file);
+ cmFortranFile& ff = parser->FileStack.top();
+ FILE* file = ff.File;
+ size_t n = fread(buffer, 1, bufferSize, file);
+ if (n > 0) {
+ ff.LastCharWasNewline = buffer[n - 1] == '\n';
+ } else if (!ff.LastCharWasNewline) {
+ // The file ended without a newline. Inject one so
+ // that the file always ends in an end-of-statement.
+ buffer[0] = '\n';
+ n = 1;
+ ff.LastCharWasNewline = true;
+ }
+ return (int)n;
}
return 0;
}