summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDimitri van Heesch <dimitri@stack.nl>2018-06-10 08:48:05 (GMT)
committerDimitri van Heesch <dimitri@stack.nl>2018-06-10 08:48:05 (GMT)
commit43ec66a8c06ae276e69664cc8e71a01a89fb3b0d (patch)
treebbb091a5bf10feb717536ca511202fffd87d73f4
parent9117548f0ce573b586928a740966844776c4c6ba (diff)
parentf5ffd481a44fa5eae225ce728d1777070c4143e1 (diff)
downloadDoxygen-43ec66a8c06ae276e69664cc8e71a01a89fb3b0d.zip
Doxygen-43ec66a8c06ae276e69664cc8e71a01a89fb3b0d.tar.gz
Doxygen-43ec66a8c06ae276e69664cc8e71a01a89fb3b0d.tar.bz2
Merge branch 'feature/bug_enum' of https://github.com/albert-github/doxygen into albert-github-feature/bug_enum
-rw-r--r--src/fortrancode.l65
-rw-r--r--src/fortranscanner.l112
2 files changed, 143 insertions, 34 deletions
diff --git a/src/fortrancode.l b/src/fortrancode.l
index 14268cf..e64c38e 100644
--- a/src/fortrancode.l
+++ b/src/fortrancode.l
@@ -687,7 +687,7 @@ NUM_TYPE (complex|integer|logical|real)
LOG_OPER (\.and\.|\.eq\.|\.eqv\.|\.ge\.|\.gt\.|\.le\.|\.lt\.|\.ne\.|\.neqv\.|\.or\.|\.not\.)
KIND {ARGS}
CHAR (CHARACTER{ARGS}?|CHARACTER{BS}"*"({BS}[0-9]+|{ARGS}))
-TYPE_SPEC (({NUM_TYPE}({BS}"*"{BS}[0-9]+)?)|({NUM_TYPE}{KIND})|DOUBLE{BS}COMPLEX|DOUBLE{BS}PRECISION|{CHAR}|TYPE|CLASS|PROCEDURE)
+TYPE_SPEC (({NUM_TYPE}({BS}"*"{BS}[0-9]+)?)|({NUM_TYPE}{KIND})|DOUBLE{BS}COMPLEX|DOUBLE{BS}PRECISION|{CHAR}|TYPE|CLASS|PROCEDURE|ENUMERATOR)
INTENT_SPEC intent{BS}"("{BS}(in|out|in{BS}out){BS}")"
ATTR_SPEC (IMPLICIT|ALLOCATABLE|DIMENSION{ARGS}|EXTERNAL|{INTENT_SPEC}|INTRINSIC|OPTIONAL|PARAMETER|POINTER|PROTECTED|PRIVATE|PUBLIC|SAVE|TARGET|(NON_)?RECURSIVE|PURE|IMPURE|ELEMENTAL|VALUE|NOPASS|DEFERRED|CONTIGUOUS|VOLATILE)
@@ -697,7 +697,8 @@ ATTR_STMT {ATTR_SPEC}|DIMENSION
FLOW (DO|SELECT|CASE|SELECT{BS}(CASE|TYPE)|WHERE|IF|THEN|ELSE|WHILE|FORALL|ELSEWHERE|ELSEIF|RETURN|CONTINUE|EXIT|GO{BS}TO)
COMMANDS (FORMAT|CONTAINS|MODULE{BS_}PROCEDURE|WRITE|READ|ALLOCATE|ALLOCATED|ASSOCIATED|PRESENT|DEALLOCATE|NULLIFY|SIZE|INQUIRE|OPEN|CLOSE|FLUSH|DATA|COMMON)
IGNORE (CALL)
-PREFIX ((NON_)?RECURSIVE{BS_}|IMPURE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,4}((NON_)?RECURSIVE|IMPURE|PURE|ELEMENTAL)?
+PREFIX ((NON_)?RECURSIVE{BS_}|IMPURE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,4}((NON_)?RECURSIVE|IMPURE|PURE|ELEMENTAL)?0
+LANGUAGE_BIND_SPEC BIND{BS}"("{BS}C{BS}(,{BS}NAME{BS}"="{BS}"\""(.*)"\""{BS})?")"
/* | */
@@ -778,12 +779,12 @@ PREFIX ((NON_)?RECURSIVE{BS_}|IMPURE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,4}((NON
BEGIN(Use);
}
<Use>"ONLY" { // TODO: rename
- startFontClass("keywordtype");
- codifyLines(yytext);
- endFontClass();
+ startFontClass("keywordtype");
+ codifyLines(yytext);
+ endFontClass();
yy_push_state(YY_START);
- BEGIN(UseOnly);
- }
+ BEGIN(UseOnly);
+ }
<Use>{ID} {
QCString tmp = yytext;
tmp = tmp.lower();
@@ -844,6 +845,20 @@ PREFIX ((NON_)?RECURSIVE{BS_}|IMPURE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,4}((NON
BEGIN(ClassName);
if (!qstricmp(yytext,"module")) currentModule="module";
}
+<Start>("enum")/{BS_}|{BS}{COMMA}{BS}{LANGUAGE_BIND_SPEC}|\n { //
+ startScope();
+ startFontClass("keyword");
+ codifyLines(yytext);
+ endFontClass();
+ yy_push_state(YY_START);
+ BEGIN(ClassName);
+ currentClass="class";
+ }
+<*>{LANGUAGE_BIND_SPEC} { //
+ startFontClass("keyword");
+ codifyLines(yytext);
+ endFontClass();
+ }
<Start>("type")/{BS_}|({COMMA}({ACCESS_SPEC}|ABSTRACT|EXTENDS))|\n { //
startScope();
startFontClass("keyword");
@@ -869,15 +884,19 @@ PREFIX ((NON_)?RECURSIVE{BS_}|IMPURE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,4}((NON
}
<ClassName>\n { // interface may be without name
yy_pop_state();
- YY_FTN_REJECT;
- }
+ YY_FTN_REJECT;
+ }
+<Start>^{BS}"end"({BS_}"enum").* { // just reset currentClass, rest is done in following rule
+ currentClass=0;
+ YY_FTN_REJECT;
+ }
<Start>^{BS}"end"({BS_}"type").* { // just reset currentClass, rest is done in following rule
currentClass=0;
- YY_FTN_REJECT;
+ YY_FTN_REJECT;
}
<Start>^{BS}"end"({BS_}"module").* { // just reset currentModule, rest is done in following rule
currentModule=0;
- YY_FTN_REJECT;
+ YY_FTN_REJECT;
}
/*-------- subprog definition -------------------------------------*/
<Start>({PREFIX}{BS_})?{TYPE_SPEC}{BS_}({PREFIX}{BS_})?{BS}/{SUBPROG}{BS_} { // TYPE_SPEC is for old function style function result
@@ -910,7 +929,7 @@ PREFIX ((NON_)?RECURSIVE{BS_}|IMPURE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,4}((NON
yy_pop_state();
YY_FTN_RESET
}
-<Start>^{BS}"end"{BS}("block"{BS}"data"|{SUBPROG}|"module"|"program"|"type"|"interface")?{BS} { // Fortran subroutine or function ends
+<Start>^{BS}"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");
@@ -923,7 +942,7 @@ PREFIX ((NON_)?RECURSIVE{BS_}|IMPURE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,4}((NON
generateLink(*g_code,yytext);
yy_pop_state();
}
-<Start>^{BS}"end"{BS}("block"{BS}"data"|{SUBPROG}|"module"|"program"|"type"|"interface"){BS}/(\n|!) { // Fortran subroutine or function ends
+<Start>^{BS}"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");
@@ -966,8 +985,11 @@ PREFIX ((NON_)?RECURSIVE{BS_}|IMPURE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,4}((NON
g_code->codify(yytext);
endFontClass();
}
- else if (g_currentMemberDef && ((g_currentMemberDef->isFunction() && (g_currentMemberDef->typeString() != QCString("subroutine") || inTypeDecl)) ||
- g_currentMemberDef->isVariable()))
+ else if (g_currentMemberDef &&
+ ((g_currentMemberDef->isFunction() && (g_currentMemberDef->typeString()!=QCString("subroutine") || inTypeDecl)) ||
+ g_currentMemberDef->isVariable() || g_currentMemberDef->isEnumValue()
+ )
+ )
{
generateLink(*g_code, yytext);
}
@@ -1050,11 +1072,20 @@ PREFIX ((NON_)?RECURSIVE{BS_}|IMPURE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,4}((NON
// fixed form continuation line
YY_FTN_REJECT;
}
+ else if (QCString(yytext).stripWhiteSpace().lower() == "type")
+ {
+ yy_push_state(YY_START);
+ BEGIN(Declaration);
+ startFontClass("keywordtype");
+ g_code->codify(QCString(yytext).stripWhiteSpace());
+ endFontClass();
+ g_code->codify(yytext + 4);
+ }
else
{
- g_insideBody=TRUE;
+ g_insideBody=TRUE;
generateLink(*g_code, yytext);
- g_insideBody=FALSE;
+ g_insideBody=FALSE;
}
}
diff --git a/src/fortranscanner.l b/src/fortranscanner.l
index 774251b..d0503c2 100644
--- a/src/fortranscanner.l
+++ b/src/fortranscanner.l
@@ -164,6 +164,7 @@ static Entry* global_root = 0 ;
static Entry* file_root = 0 ;
static Entry* current = 0 ;
static Entry* last_entry = 0 ;
+static Entry* last_enum = 0 ;
static ScanVar v_type = V_IGNORE; // type of parsed variable
static QList<Entry> moduleProcedures; // list of all interfaces which contain unresolved
// module procedures
@@ -198,8 +199,8 @@ static SymbolModifiers currentModifiers;
//! Holds program scope->symbol name->symbol modifiers.
static QMap<Entry*,QMap<QCString,SymbolModifiers> > modifiers;
-static Entry *global_scope = NULL;
-
+static Entry *global_scope = NULL;
+static int anonCount = 0 ;
//-----------------------------------------------------------------------------
static int yyread(char *buf,int max_size);
@@ -228,6 +229,7 @@ static QCString extractFromParens(const QCString name);
static CommentInPrepass* locatePrepassComment(int from, int to);
static void updateVariablePrepassComment(int from, int to);
static void newLine();
+static void initEntry();
//-----------------------------------------------------------------------------
#undef YY_INPUT
@@ -263,7 +265,7 @@ NUM_TYPE (complex|integer|logical|real)
LOG_OPER (\.and\.|\.eq\.|\.eqv\.|\.ge\.|\.gt\.|\.le\.|\.lt\.|\.ne\.|\.neqv\.|\.or\.|\.not\.)
KIND {ARGS}
CHAR (CHARACTER{ARGS}?|CHARACTER{BS}"*"({BS}[0-9]+|{ARGS}))
-TYPE_SPEC (({NUM_TYPE}({BS}"*"{BS}[0-9]+)?)|({NUM_TYPE}{KIND})|DOUBLE{BS}COMPLEX|DOUBLE{BS}PRECISION|{CHAR}|TYPE{ARGS}|CLASS{ARGS}|PROCEDURE{ARGS}?)
+TYPE_SPEC (({NUM_TYPE}({BS}"*"{BS}[0-9]+)?)|({NUM_TYPE}{KIND})|DOUBLE{BS}COMPLEX|DOUBLE{BS}PRECISION|ENUMERATOR|{CHAR}|TYPE{ARGS}|CLASS{ARGS}|PROCEDURE{ARGS}?)
INTENT_SPEC intent{BS}"("{BS}(in|out|in{BS}out){BS}")"
ATTR_SPEC (EXTERNAL|ALLOCATABLE|DIMENSION{ARGS}|{INTENT_SPEC}|INTRINSIC|OPTIONAL|PARAMETER|POINTER|PROTECTED|PRIVATE|PUBLIC|SAVE|TARGET|NOPASS|PASS{ARGS}?|DEFERRED|NON_OVERRIDABLE|CONTIGUOUS|VOLATILE|VALUE)
@@ -300,6 +302,7 @@ SCOPENAME ({ID}{BS}"::"{BS})*
%x Variable
%x Initialization
%x ArrayInitializer
+%x Enum
%x Typedef
%x TypedefBody
%x TypedefBodyContains
@@ -726,8 +729,17 @@ private {
{ID} {
}
}
-<Start,ModuleBody,TypedefBody,SubprogBody>{
+<Start,ModuleBody,TypedefBody,SubprogBody,Enum>{
^{BS}{TYPE_SPEC}/{SEPARATE} {
+ last_enum = 0;
+ if (YY_START == Enum)
+ {
+ argType = "@"; // enum marker
+ }
+ else
+ {
+ argType = QCString(yytext).simplifyWhiteSpace().lower();
+ }
current->bodyLine = yyLineNr + 1;
current->endBodyLine = yyLineNr + lineCountPrepass;
/* variable declaration starts */
@@ -736,7 +748,6 @@ private {
addModule(NULL);
yy_push_state(ModuleBody); //anon program
}
- argType = QCString(yytext).simplifyWhiteSpace().lower();
yy_push_state(AttributeList);
}
/* Dimitri: macro expansion should already be done during preprocessing not here!
@@ -834,17 +845,30 @@ private {
modifiers[current_root][name.lower()] |= currentModifiers;
argName= name;
- v_type= V_IGNORE;
- if (!argType.isEmpty() && current_root->section!=Entry::FUNCTION_SEC)
- { // new variable entry
- v_type = V_VARIABLE;
+ v_type= V_IGNORE;
+ if (!argType.isEmpty() && current_root->section!=Entry::FUNCTION_SEC)
+ { // new variable entry
+ v_type = V_VARIABLE;
current->section = Entry::VARIABLE_SEC;
- current->name = argName;
- current->type = argType;
- current->fileName = yyFileName;
- current->bodyLine = yyLineNr; // used for source reference
+ current->name = argName;
+ current->type = argType;
+ current->fileName = yyFileName;
+ current->bodyLine = yyLineNr; // used for source reference
current->startLine = yyLineNr;
- addCurrentEntry(1);
+ if (argType == "@")
+ {
+ current_root->addSubEntry(current);
+ current = new Entry(*current);
+ // add to the scope surrounding the enum (copy!)
+ current_root->parent()->addSubEntry(current);
+ last_enum = current;
+ current = new Entry ;
+ initEntry();
+ }
+ else
+ {
+ addCurrentEntry(1);
+ }
}
else if (!argType.isEmpty())
{ // declaration of parameter list: add type for corr. parameter
@@ -980,19 +1004,72 @@ private {
{
updateVariablePrepassComment(yyColNr-(int)yyleng, yyColNr);
yy_pop_state(); // end initialization
- if (v_type == V_VARIABLE) last_entry->initializer= initializer;
+ if (last_enum)
+ {
+ last_enum->initializer= initializer;
+ }
+ else
+ {
+ if (v_type == V_VARIABLE) last_entry->initializer= initializer;
+ }
}
else
initializer+=", ";
}
<Initialization>"\n"|"!" { //|
yy_pop_state(); // end initialization
- if (v_type == V_VARIABLE) last_entry->initializer= initializer;
+ if (last_enum)
+ {
+ last_enum->initializer= initializer;
+ }
+ else
+ {
+ if (v_type == V_VARIABLE) last_entry->initializer= initializer;
+ }
yyColNr -= 1;
unput(*yytext);
}
<Initialization>. { initializer+=yytext; }
+<*>{BS}"enum"{BS}","{BS}"bind"{BS}"("{BS}"c"{BS}")"{BS} {
+ if(YY_START == Start)
+ {
+ addModule(NULL);
+ yy_push_state(ModuleBody); //anon program
+ }
+
+ yy_push_state(Enum);
+ current->protection = defaultProtection;
+ typeProtection = defaultProtection;
+ typeMode = true;
+
+ current->spec |= Entry::Struct;
+ current->name.resize(0);
+ current->args.resize(0);
+ current->name.sprintf("@%d",anonCount++);
+
+ current->section = Entry::ENUM_SEC;
+ current->fileName = yyFileName;
+ current->startLine = yyLineNr;
+ current->bodyLine = yyLineNr;
+ if ((current_root) &&
+ (current_root->section == Entry::CLASS_SEC
+ || current_root->section == Entry::NAMESPACE_SEC))
+ {
+ current->name = current_root->name + "::" + current->name;
+ }
+
+ addCurrentEntry(1);
+ startScope(last_entry);
+ BEGIN( Enum ) ;
+ }
+<Enum>"end"{BS}"enum" {
+ last_entry->parent()->endBodyLine = yyLineNr;
+ if (!endScope(current_root))
+ yyterminate();
+ typeMode = false;
+ yy_pop_state();
+ }
/*------ fortran subroutine/function handling ------------------------------------------------------------*/
/* Start is initial condition */
@@ -1133,6 +1210,7 @@ private {
{
Entry *tmp_entry = current;
current = last_entry; // temporarily switch to the previous entry
+ if (last_enum) current = last_enum;
handleCommentBlock(docBlock,TRUE);
current=tmp_entry;
}
@@ -1148,7 +1226,7 @@ private {
docBlock.resize(0);
}
-<Start,SubprogBody,ModuleBody,TypedefBody,InterfaceBody,ModuleBodyContains,SubprogBodyContains,TypedefBodyContains>"!>" {
+<Start,SubprogBody,ModuleBody,TypedefBody,InterfaceBody,ModuleBodyContains,SubprogBodyContains,TypedefBodyContains,Enum>"!>" {
yy_push_state(YY_START);
current->docLine = yyLineNr;
docBlockJavaStyle = FALSE;