Skip to content

Commit

Permalink
Continuation lines and labels
Browse files Browse the repository at this point in the history
Better handling of continuation lines when converting from fixed form Fortran to free form Fortran, especially handling the information in columns 733 and further (which is in fixed formatted Fortran always comment)
An `end` statement can start not only on lines with spaces in front of it but also when a line has a label or the `end` can be after a `;`.
  • Loading branch information
albert-github committed Mar 7, 2019
1 parent 169a671 commit a205b6c
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 20 deletions.
6 changes: 3 additions & 3 deletions src/fortrancode.l
Original file line number Diff line number Diff line change
Expand Up @@ -934,7 +934,7 @@ LANGUAGE_BIND_SPEC BIND{BS}"("{BS}C{BS}(,{BS}NAME{BS}"="{BS}"\""(.*)"\""{BS})?")
yy_pop_state();
YY_FTN_RESET
}
<Start>^{BS}"end"{BS}("block"{BS}"data"|{SUBPROG}|"module"|"program"|"enum"|"type"|"interface")?{BS} { // Fortran subroutine or function ends
<Start>"end"{BS}("block"{BS}"data"|{SUBPROG}|"module"|"program"|"enum"|"type"|"interface")?{BS} { // Fortran subroutine or function ends
//cout << "===> end function " << yytext << endl;
endScope();
startFontClass("keyword");
Expand All @@ -943,11 +943,11 @@ LANGUAGE_BIND_SPEC BIND{BS}"("{BS}C{BS}(,{BS}NAME{BS}"="{BS}"\""(.*)"\""{BS})?")
yy_push_state(YY_START);
BEGIN(Subprogend);
}
<Subprogend>{ID}/{BS}(\n|!) {
<Subprogend>{ID}/{BS}(\n|!|;) {
generateLink(*g_code,yytext);
yy_pop_state();
}
<Start>^{BS}"end"{BS}("block"{BS}"data"|{SUBPROG}|"module"|"program"|"enum"|"type"|"interface"){BS}/(\n|!) { // Fortran subroutine or function ends
<Start>"end"{BS}("block"{BS}"data"|{SUBPROG}|"module"|"program"|"enum"|"type"|"interface"){BS}/(\n|!|;) { // Fortran subroutine or function ends
//cout << "===> end function " << yytext << endl;
endScope();
startFontClass("keyword");
Expand Down
73 changes: 56 additions & 17 deletions src/fortranscanner.l
Original file line number Diff line number Diff line change
Expand Up @@ -522,16 +522,16 @@ SCOPENAME ({ID}{BS}"::"{BS})*
<InterfaceBody>. {}

/*-- Contains handling --*/
<Start>^{BS}{CONTAINS}/({BS}|\n|!) {
<Start>^{BS}{CONTAINS}/({BS}|\n|!|;) {
if(YY_START == Start)
{
addModule(NULL);
yy_push_state(ModuleBodyContains); //anon program
}
}
<ModuleBody>^{BS}{CONTAINS}/({BS}|\n|!) { BEGIN(ModuleBodyContains); }
<SubprogBody>^{BS}{CONTAINS}/({BS}|\n|!) { BEGIN(SubprogBodyContains); }
<TypedefBody>^{BS}{CONTAINS}/({BS}|\n|!) { BEGIN(TypedefBodyContains); }
<ModuleBody>^{BS}{CONTAINS}/({BS}|\n|!|;) { BEGIN(ModuleBodyContains); }
<SubprogBody>^{BS}{CONTAINS}/({BS}|\n|!|;) { BEGIN(SubprogBodyContains); }
<TypedefBody>^{BS}{CONTAINS}/({BS}|\n|!|;) { BEGIN(TypedefBodyContains); }

/*------ module handling ------------------------------------------------------------*/
<Start>block{BS}data{BS}{ID_} { //
Expand All @@ -547,13 +547,13 @@ SCOPENAME ({ID}{BS}"::"{BS})*
yy_push_state(Program);
defaultProtection = Public;
}
<BlockData>^{BS}"end"({BS}(block{BS}data)({BS_}{ID})?)?{BS}/(\n|!) { // end block data
<BlockData>^{BS}"end"({BS}(block{BS}data)({BS_}{ID})?)?{BS}/(\n|!|;) { // end block data
//if (!endScope(current_root))
// yyterminate();
defaultProtection = Public;
yy_pop_state();
}
<Start,ModuleBody,ModuleBodyContains>^{BS}"end"({BS}(module|program)({BS_}{ID})?)?{BS}/(\n|!) { // end module
<Start,ModuleBody,ModuleBodyContains>"end"({BS}(module|program)({BS_}{ID})?)?{BS}/(\n|!|;) { // end module
resolveModuleProcedures(moduleProcedures, current_root);
if (!endScope(current_root))
yyterminate();
Expand Down Expand Up @@ -690,7 +690,7 @@ private {


<TypedefBody,TypedefBodyContains>{
^{BS}"end"{BS}"type"({BS_}{ID})?{BS}/(\n|!) { /* end type definition */
^{BS}"end"{BS}"type"({BS_}{ID})?{BS}/(\n|!|;) { /* end type definition */
last_entry->parent()->endBodyLine = yyLineNr;
if (!endScope(current_root))
yyterminate();
Expand All @@ -701,7 +701,7 @@ private {

/*------- module/global/typedef variable ---------------------------------------------------*/

<SubprogBody,SubprogBodyContains>^{BS}[0-9]*{BS}"end"({BS}{SUBPROG}({BS_}{ID})?)?{BS}/(\n|!) {
<SubprogBody,SubprogBodyContains>^{BS}[0-9]*{BS}"end"({BS}{SUBPROG}({BS_}{ID})?)?{BS}/(\n|!|;) {
//
// ABSTRACT and specific interfaces are stored
// in a scope of their own, even if multiple
Expand Down Expand Up @@ -1513,6 +1513,7 @@ const char* prepassFixedForm(const char* contents, int *hasContLine)
int column=0;
int prevLineLength=0;
int prevLineAmpOrExclIndex=-1;
int skipped = 0;
char prevQuote = '\0';
char thisQuote = '\0';
bool emptyLabel=TRUE;
Expand All @@ -1521,25 +1522,53 @@ const char* prepassFixedForm(const char* contents, int *hasContLine)
bool inDouble=FALSE;
bool inBackslash=FALSE;
bool fullCommentLine=TRUE;
bool artificialComment=FALSE;
bool spaces=TRUE;
int newContentsSize = strlen(contents)+3; // \000, \n (when necessary) and one spare character (to avoid reallocation)
char* newContents = (char*)malloc(newContentsSize);
int curLine = 1;

for(int i=0, j=0;;i++,j++) {
int j = -1;
for(int i=0;;i++) {
column++;
char c = contents[i];
if (artificialComment && c != '\n')
{
if (c == '!' && spaces)
{
newContents[j++] = c;
artificialComment = FALSE;
spaces = FALSE;
skipped = 0;
continue;
}
else if (c == ' ' || c == '\t') continue;
else
{
spaces = FALSE;
skipped++;
continue;
}
}

j++;
if(j>=newContentsSize-3) { // check for spare characters, which may be eventually used below (by & and '! ')
newContents = (char*)realloc(newContents, newContentsSize+1000);
newContentsSize = newContentsSize+1000;
}

column++;
char c = contents[i];
switch(c) {
case '\n':
if (!fullCommentLine)
{
prevLineLength=column;
prevLineAmpOrExclIndex=getAmpOrExclAtTheEnd(&contents[i-prevLineLength+1], prevLineLength,prevQuote);
if (prevLineAmpOrExclIndex == -1) prevLineAmpOrExclIndex = column - 1;
if (skipped)
{
prevLineAmpOrExclIndex = -1;
skipped = 0;
}
}
else
{
Expand All @@ -1550,6 +1579,8 @@ const char* prepassFixedForm(const char* contents, int *hasContLine)
hasContLine[curLine - 1] = 1;
}
}
artificialComment=FALSE;
spaces=TRUE;
fullCommentLine=TRUE;
column=0;
emptyLabel=TRUE;
Expand Down Expand Up @@ -1654,7 +1685,8 @@ const char* prepassFixedForm(const char* contents, int *hasContLine)
j++;
} else { // add & just before end of previous line comment
/* first line is not a continuation line in code, just in snippets etc. */
if (curLine != 1) insertCharacter(newContents, j+1, (j+1)-6-prevLineLength+prevLineAmpOrExclIndex, '&');
if (curLine != 1) insertCharacter(newContents, j+1, (j+1)-6-prevLineLength+prevLineAmpOrExclIndex+skipped, '&');
skipped = 0;
j++;
}
if (hasContLine) hasContLine[curLine - 1] = 1;
Expand All @@ -1664,13 +1696,20 @@ const char* prepassFixedForm(const char* contents, int *hasContLine)
prevLineLength=0;
} else if ((column > fixedCommentAfter) && !commented) {
// first non commented non blank character after position fixedCommentAfter
if (c != '!') {
if (c == '&') {
newContents[j]=' ';
}
else if (c != '!') {
// I'm not a possible start of doxygen comment
newContents[j++]='!';
newContents[j++]=' '; // so that '<' and '>' as first character are not converted to doxygen comment
newContents[j]=' ';
artificialComment = TRUE;
spaces=TRUE;
skipped = 0;
}
else {
newContents[j]=c;
commented = TRUE;
}
newContents[j]=c;
commented = TRUE;
} else {
if (!commented) fullCommentLine=FALSE;
newContents[j]=c;
Expand Down

0 comments on commit a205b6c

Please sign in to comment.