diff options
author | albert-github <albert.tests@gmail.com> | 2019-03-07 15:40:37 (GMT) |
---|---|---|
committer | albert-github <albert.tests@gmail.com> | 2019-03-07 15:40:37 (GMT) |
commit | a205b6c6d69d593fc34f942c82e43c22f214e690 (patch) | |
tree | 418ecedd609ca39034477283b8c76fbcc2f8f57a | |
parent | 169a67186780c191749b958de0f71a17fa090248 (diff) | |
download | Doxygen-a205b6c6d69d593fc34f942c82e43c22f214e690.zip Doxygen-a205b6c6d69d593fc34f942c82e43c22f214e690.tar.gz Doxygen-a205b6c6d69d593fc34f942c82e43c22f214e690.tar.bz2 |
Continuation lines and labels
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 `;`.
-rw-r--r-- | src/fortrancode.l | 6 | ||||
-rw-r--r-- | src/fortranscanner.l | 73 |
2 files changed, 59 insertions, 20 deletions
diff --git a/src/fortrancode.l b/src/fortrancode.l index 7a30deb..31924fa 100644 --- a/src/fortrancode.l +++ b/src/fortrancode.l @@ -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"); @@ -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"); diff --git a/src/fortranscanner.l b/src/fortranscanner.l index 1f0c356..0935974 100644 --- a/src/fortranscanner.l +++ b/src/fortranscanner.l @@ -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_} { // @@ -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(); @@ -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(); @@ -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 @@ -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; @@ -1521,18 +1522,41 @@ 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) @@ -1540,6 +1564,11 @@ const char* prepassFixedForm(const char* contents, int *hasContLine) prevLineLength=column; prevLineAmpOrExclIndex=getAmpOrExclAtTheEnd(&contents[i-prevLineLength+1], prevLineLength,prevQuote); if (prevLineAmpOrExclIndex == -1) prevLineAmpOrExclIndex = column - 1; + if (skipped) + { + prevLineAmpOrExclIndex = -1; + skipped = 0; + } } else { @@ -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; @@ -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; @@ -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; |