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.
This commit is contained in:
Brad King 2016-09-05 14:18:32 -04:00
parent 8c65a5017f
commit d28da906fe
2 changed files with 15 additions and 2 deletions

View File

@ -118,11 +118,13 @@ struct cmFortranFile
: File(file) : File(file)
, Buffer(buffer) , Buffer(buffer)
, Directory(dir) , Directory(dir)
, LastCharWasNewline(false)
{ {
} }
FILE* File; FILE* File;
YY_BUFFER_STATE Buffer; YY_BUFFER_STATE Buffer;
std::string Directory; std::string Directory;
bool LastCharWasNewline;
}; };
struct cmFortranParser_s struct cmFortranParser_s

View File

@ -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, // Read from the file on top of the stack. If the stack is empty,
// the end of the translation unit has been reached. // the end of the translation unit has been reached.
if (!parser->FileStack.empty()) { if (!parser->FileStack.empty()) {
FILE* file = parser->FileStack.top().File; cmFortranFile& ff = parser->FileStack.top();
return (int)fread(buffer, 1, bufferSize, file); 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; return 0;
} }