40%option never-interactive
41%option case-insensitive
42%option prefix="fortranscannerYY"
44%option extra-type="struct fortranscannerYY_state *"
48#define YY_TYPEDEF_YY_SCANNER_T
81#define DBG_CTX(x) do { } while(0)
84#define YY_NO_UNISTD_H 1
135 "",
"intent(in)",
"intent(out)",
"intent(inout)"
139 "",
"[in]",
"[out]",
"[in,out]"
210 std::map<Entry*,std::map<std::string,SymbolModifiers> >
modifiers;
241static void copyEntry(std::shared_ptr<Entry> dest,
const std::shared_ptr<Entry> &src);
258#define YY_INPUT(buf,result,max_size) result=yyread(yyscanner,buf,max_size);
263#define YY_USER_ACTION yyextra->colNr+=(int)yyleng;
264#define INVALID_ENTRY ((Entry*)0x8)
Represents an unstructured piece of information, about an entity found in the sources.
Abstract interface for outline parsers.
This is an alternative implementation of QCString.
std::vector< std::shared_ptr< Entry > > EntryList
static int getAmpersandAtTheStart(const char *buf, int length)
static const char * directionParam[]
static void resolveModuleProcedures(yyscan_t yyscanner, Entry *current_root)
fill empty interface module procedures with info from corresponding module subprogs
static void newLine(yyscan_t yyscanner)
static void addCurrentEntry(yyscan_t yyscanner, bool case_insens)
adds yyextra->current entry to yyextra->current_root and creates new yyextra->current
static QCString extractFromParens(const QCString &name)
static int computeIndent(const char *s)
static void startCommentBlock(yyscan_t yyscanner, bool)
static void startScope(yyscan_t yyscanner, Entry *scope)
static void addModule(yyscan_t yyscanner, const QCString &name=QCString(), bool isModule=FALSE)
static int getAmpOrExclAtTheEnd(const char *buf, int length, char ch)
static const CommentInPrepass * locatePrepassComment(yyscan_t yyscanner, int from, int to)
static bool endScope(yyscan_t yyscanner, Entry *scope, bool isGlobalRoot=FALSE)
static int yyread(yyscan_t yyscanner, char *buf, int max_size)
static const char * stateToString(int state)
static void popBuffer(yyscan_t yyscanner)
static void copyEntry(std::shared_ptr< Entry > dest, const std::shared_ptr< Entry > &src)
used to copy entry to an interface module procedure
static Argument * getParameter(yyscan_t yyscanner, const QCString &name)
static void subrHandleCommentBlock(yyscan_t yyscanner, const QCString &doc, bool brief)
Handle parameter description as defined after the declaration of the parameter.
static const char * directionStrs[]
static void subrHandleCommentBlockResult(yyscan_t yyscanner, const QCString &doc, bool brief)
Handle result description as defined after the declaration of the parameter.
static void scanner_abort(yyscan_t yyscanner)
static void pop_state(yyscan_t yyscanner)
static void resolveTypeBoundProcedures(Entry *scope)
static void updateVariablePrepassComment(yyscan_t yyscanner, int from, int to)
static void handleCommentBlock(yyscan_t yyscanner, const QCString &doc, bool brief)
static void pushBuffer(yyscan_t yyscanner, const QCString &buffer)
static void addSubprogram(yyscan_t yyscanner, const QCString &text)
static QCString extractBind(const QCString &name)
static void addInterface(yyscan_t yyscanner, QCString name, InterfaceType type)
static const char * getLexerFILE()
static void truncatePrepass(yyscan_t yyscanner, int index)
static void initEntry(yyscan_t yyscanner)
This class contains the information about the argument of a function or template.
Holds yyextra->modifiers (ie attributes) for one symbol (variable, function, etc)
QCString type
This is only used with function return value.
SymbolModifiers & operator|=(const SymbolModifiers &mdfs)
std::map< Entry *, std::map< std::string, SymbolModifiers > > modifiers
Holds program scope->symbol name->symbol modifiers.
QCString inputStringSemi
Input string after command separator ';'.
QCString inputStringPrepass
Input string for prepass of line cont. '&'.
YY_BUFFER_STATE * includeStack
std::shared_ptr< Entry > last_enum
OutlineParserInterface * thisParser
SymbolModifiers currentModifiers
Accumulated modifiers of current statement, eg variable declaration.
unsigned int inputPositionPrepass
std::shared_ptr< Entry > global_root
std::vector< CommentInPrepass > comments
EntryList moduleProcedures
CommentScanner commentScanner
int initializerArrayScope
std::shared_ptr< Entry > last_entry
Protection defaultProtection
Protection typeProtection
int mainPrograms
counter for the number of main programs in this file
std::shared_ptr< Entry > current
std::shared_ptr< Entry > file_root
Protection
Protection level of members.
A bunch of utility functions.
276ID [a-z_A-Z%]+{IDSYM}*
277ID_ [a-z_A-Z%]*{IDSYM}*
278OPERATOR_ID (operator{BS}"("{BS}(\.[a-z_A-Z]+\.|"="|"/="|"//"|"=="|"<"|"<="|">"|">="|"+"|"*"|"**"|"/"|"-"){BS}")")
279SUBPROG (subroutine|function)
283BT_ ([ \t]+|[ \t]*"(")
286ARGS_L1a [^()]*"("[^)]*")"[^)]*
287ARGS_L1 ("("{ARGS_L1a}*")")
288ARGS_L2 "("({ARGS_L0}|[^()]|{ARGS_L1a}|{ARGS_L1})*")"
289ARGS {BS}({ARGS_L0}|{ARGS_L1}|{ARGS_L2})
296NUM_TYPE (complex|integer|logical|real)
297LOG_OPER (\.and\.|\.eq\.|\.eqv\.|\.ge\.|\.gt\.|\.le\.|\.lt\.|\.ne\.|\.neqv\.|\.or\.|\.not\.)
299CHAR (CHARACTER{ARGS}?|CHARACTER{BS}"*"({BS}[0-9]+|{ARGS}))
300TYPE_SPEC (({NUM_TYPE}({BS}"*"{BS}[0-9]+)?)|({NUM_TYPE}{KIND})|DOUBLE{BS}COMPLEX|DOUBLE{BS}PRECISION|ENUMERATOR|{CHAR}|TYPE{ARGS}|CLASS{ARGS}|PROCEDURE{ARGS}?)
302INTENT_SPEC intent{BS}"("{BS}(in|out|in{BS}out){BS}")"
303ATTR_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)
304LANGUAGE_BIND_SPEC BIND{BS}"("{BS}C{BS}((,{BS}NAME{BS}"="{BS}"\""(.*)"\""{BS})|(,{BS}NAME{BS}"="{BS}"'"(.*)"'"{BS}))?")"
306ATTR_STMT {ATTR_SPEC}|DIMENSION
307EXTERNAL_STMT (EXTERNAL)
310PREFIX ((NON_)?RECURSIVE{BS_}|IMPURE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,4}((NON_)?RECURSIVE|IMPURE|PURE|ELEMENTAL)?
311SCOPENAME ({ID}{BS}"::"{BS})*
313LINENR {B}*[1-9][0-9]*
314FILEICHAR [a-z_A-Z0-9\x80-\xFF\\:\\\/\-\+=&#@]
315FILEECHAR [a-z_A-Z0-9\x80-\xFF\-\+=&#@]
316FILECHARS {FILEICHAR}*{FILEECHAR}+
317HFILEMASK {FILEICHAR}*("."{FILEICHAR}+)+{FILECHARS}*
318VFILEMASK {FILECHARS}("."{FILECHARS})*
319FILEMASK {VFILEMASK}|{HFILEMASK}
333%x SubprogBodyContains
347%x TypedefBodyContains
373<Prepass>^{BS}[&]*{BS}!.*\n {
374 yyextra->lineCountPrepass ++;
377 yyextra->lineCountPrepass ++;
380 yyextra->functionLine =
FALSE;
382 DBG_CTX((stderr,
"---%s", yytext));
386 if (indexEnd>=0 && yytext[indexEnd]!=
'&')
393 if (YY_START == Prepass)
397 yyextra->inputStringPrepass+=(
const char*)(yytext+(indexStart+1));
400 pushBuffer(yyscanner,yyextra->inputStringPrepass);
412 if (YY_START != Prepass)
414 yyextra->comments.clear();
415 yyextra->inputStringPrepass=
QCString();
416 yy_push_state(Prepass,yyscanner);
419 size_t length = yyextra->inputStringPrepass.length();
422 yyextra->inputStringPrepass+=(
const char*)(yytext+(indexStart+1));
423 yyextra->lineCountPrepass ++;
426 truncatePrepass(yyscanner,
static_cast<int>(length) + indexEnd - indexStart - 1);
static void pop_state(yyscan_t yyscanner)
433 if (yytext[0]!=yyextra->stringStartSymbol)
435 yyextra->colNr -= (int)yyleng;
438 if (yy_top_state(yyscanner) == Initialization ||
439 yy_top_state(yyscanner) == ArrayInitializer)
441 yyextra->initializer+=yytext;
445<String>[\x80-\xFF]* |
446<String>. {
if (yy_top_state(yyscanner) == Initialization ||
447 yy_top_state(yyscanner) == ArrayInitializer)
449 yyextra->initializer+=yytext;
453 if (YY_START == StrIgnore)
454 { yyextra->colNr -= (int)yyleng;
457 yy_push_state(YY_START,yyscanner);
458 if (yy_top_state(yyscanner) == Initialization ||
459 yy_top_state(yyscanner) == ArrayInitializer)
461 yyextra->initializer+=yytext;
463 yyextra->stringStartSymbol=yytext[0];
469<*>"!"/[^<>\n] {
if (YY_START == String || YY_START == DocCopyBlock)
470 { yyextra->colNr -= (int)yyleng;
475 if ((YY_START != StrIgnore) && (YY_START != String))
477 yy_push_state(YY_START,yyscanner);
479 yyextra->debugStr=
"*!";
480 DBG_CTX((stderr,
"start comment %d\n",yyextra->lineNr));
484 DBG_CTX((stderr,
"end comment %d %s\n",yyextra->lineNr,
qPrint(yyextra->debugStr)));
const char * qPrint(const char *s)
486<StrIgnore>[\x80-\xFF]* |
487<StrIgnore>. { yyextra->debugStr+=yytext; }
492<Start,ModuleBody,SubprogBody>"use"{BS_} {
493 if (YY_START == Start)
496 yy_push_state(ModuleBody,yyscanner);
498 yy_push_state(Use,yyscanner);
501 DBG_CTX((stderr,
"using dir %s\n",yytext));
502 yyextra->current->name=yytext;
503 yyextra->current->name=yyextra->current->name.lower();
504 yyextra->current->fileName = yyextra->fileName;
505 yyextra->current->section=EntryType::makeUsingDir();
506 yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
511 yyextra->useModuleName=yytext;
512 yyextra->useModuleName=yyextra->useModuleName.lower();
514<Use>,{BS}"ONLY" { BEGIN(UseOnly);
518 yyextra->current->name= yyextra->useModuleName+
"::"+yytext;
519 yyextra->current->name=yyextra->current->name.lower();
520 yyextra->current->fileName = yyextra->fileName;
521 yyextra->current->section=EntryType::makeUsingDecl();
522 yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
532<Start,ModuleBody,SubprogBody>{
533^{BS}interface{IDSYM}+ { }
535 yy_push_state(InterfaceBody,yyscanner);
540^{BS}abstract{BS_}interface { yyextra->ifType =
IF_ABSTRACT;
541 yy_push_state(InterfaceBody,yyscanner);
546^{BS}interface{BS_}{ID}{ARGS}? { yyextra->ifType =
IF_GENERIC;
547 yyextra->current->bodyLine = yyextra->lineNr + yyextra->lineCountPrepass + 1;
548 yy_push_state(InterfaceBody,yyscanner);
554 startScope(yyscanner,yyextra->last_entry.get());
size_t length() const
Returns the length of the string, not counting the 0-terminator.
QCString stripWhiteSpace() const
returns a copy of this string with leading and trailing whitespace removed
QCString right(size_t len) const
static void startScope(yyscan_t yyscanner)
start scope
558<InterfaceBody>^{BS}end{BS}interface({BS_}{ID})? {
562 yyextra->last_entry->parent()->endBodyLine = yyextra->lineNr - 1;
static void endScope(yyscan_t yyscanner)
end scope
571<InterfaceBody>module{BS}procedure { yy_push_state(YY_START,yyscanner);
572 BEGIN(ModuleProcedure);
578 startScope(yyscanner,yyextra->last_entry.get());
581 yyextra->current->section = EntryType::makeFunction();
582 yyextra->current->name = name;
583 yyextra->moduleProcedures.push_back(yyextra->current);
586<ModuleProcedure>"\n" { yyextra->colNr -= 1;
593<Start>^{BS}{CONTAINS}/({BS}|\n|!|;) {
594 if (YY_START == Start)
597 yy_push_state(ModuleBodyContains,yyscanner);
600<ModuleBody>^{BS}{CONTAINS}/({BS}|\n|!|;) { BEGIN(ModuleBodyContains); }
601<SubprogBody>^{BS}{CONTAINS}/({BS}|\n|!|;) { BEGIN(SubprogBodyContains); }
602<TypedefBody>^{BS}{CONTAINS}/({BS}|\n|!|;) { BEGIN(TypedefBodyContains); }
605<Start>block{BS}data{BS}{ID_} {
607 yy_push_state(BlockData,yyscanner);
610<Start>module|program{BS_} {
612 if (yytext[0]==
'm' || yytext[0]==
'M')
614 yy_push_state(
Module,yyscanner);
618 yy_push_state(Program,yyscanner);
622<BlockData>^{BS}"end"({BS}(block{BS}data)({BS_}{ID})?)?{BS}/(\n|!|;) {
628<Start,ModuleBody,ModuleBodyContains>"end"({BS}(module|program)({BS_}{ID})?)?{BS}/(\n|!|;) {
630 if (!
endScope(yyscanner,yyextra->current_root))
635 if (yyextra->global_scope)
639 yy_push_state(Start,yyscanner);
648 yy_push_state(Start,yyscanner);
663<ModuleBody,TypedefBody,TypedefBodyContains>private/{BS}(\n|"!") {
665 yyextra->current->protection = yyextra->defaultProtection ;
667<ModuleBody,TypedefBody,TypedefBodyContains>public/{BS}(\n|"!") {
669 yyextra->current->protection = yyextra->defaultProtection ;
674<ModuleBody>^{BS}type{BS}"=" {}
675<Start,ModuleBody>^{BS}type/[^a-z0-9_] {
676 if (YY_START == Start)
679 yy_push_state(ModuleBody,yyscanner);
682 yy_push_state(
Typedef,yyscanner);
685 yyextra->typeMode =
true;
693 yyextra->current->spec.setAbstractClass(
true);
705{LANGUAGE_BIND_SPEC} {
709 yyextra->current->section = EntryType::makeClass();
710 yyextra->current->spec.setStruct(
true);
711 yyextra->current->name = yytext;
712 yyextra->current->fileName = yyextra->fileName;
713 yyextra->current->bodyLine = yyextra->lineNr;
714 yyextra->current->startLine = yyextra->lineNr;
717 if (yyextra->current_root &&
718 (yyextra->current_root->section.isClass() ||
719 yyextra->current_root->section.isNamespace()))
721 yyextra->current->name = yyextra->current_root->name +
"::" + yyextra->current->name;
727 yyextra->current->protection = yyextra->defaultProtection;
731 yyextra->modifiers[yyextra->current_root][yyextra->current->name.lower().str()] |=
QCString(
"public");
735 yyextra->modifiers[yyextra->current_root][yyextra->current->name.lower().str()] |=
QCString(
"private");
739 startScope(yyscanner,yyextra->last_entry.get());
744<TypedefBodyContains>{
745^{BS}PROCEDURE{ARGS}? {
QCString simplifyWhiteSpace() const
return a copy of this string with leading and trailing whitespace removed and multiple whitespace cha...
749 yyextra->current->spec.setFinal(
true);
764 yyextra->modifiers[yyextra->current_root][name.
lower().
str()] |= yyextra->currentModifiers;
765 yyextra->current->section = EntryType::makeFunction();
766 yyextra->current->name = name;
768 if (yyextra->current->type.find(
'(') != -1)
774 yyextra->current->args = name.
lower();
776 yyextra->current->fileName = yyextra->fileName;
777 yyextra->current->bodyLine = yyextra->lineNr;
778 yyextra->current->startLine = yyextra->lineNr;
const std::string & str() const
783 int i = tmp.
find(
"=>");
789 if (yyextra->last_entry->type ==
"generic")
797 copyEntry(yyextra->current, yyextra->last_entry);
798 yyextra->current->name = yyextra->last_entry->name;
799 yyextra->current->section = EntryType::makeFunction();
808 yyextra->last_entry->args = tmp;
int find(char c, int index=0, bool cs=TRUE) const
QCString & remove(size_t index, size_t len)
QCString left(size_t len) const
813 yyextra->docBlock.clear();
818<TypedefBody,TypedefBodyContains>{
819^{BS}"end"{BS}"type"({BS_}{ID})?{BS}/(\n|!|;) {
820 yyextra->last_entry->parent()->endBodyLine = yyextra->lineNr;
821 if (!
endScope(yyscanner,yyextra->current_root))
825 yyextra->typeMode =
false;
828^{BS}"end"{BS}/(\n|!|;) {
829 warn(yyextra->fileName,yyextra->lineNr,
"Found 'END' instead of 'END TYPE'");
830 yyextra->last_entry->parent()->endBodyLine = yyextra->lineNr;
831 if (!
endScope(yyscanner,yyextra->current_root))
835 yyextra->typeMode =
false;
#define warn(file, line, fmt,...)
842<SubprogBody,SubprogBodyContains>^{BS}[0-9]*{BS}"end"({BS}{SUBPROG}({BS_}{ID})?)?{BS}/(\n|!|;) {
850 endScope(yyscanner,yyextra->current_root);
851 yyextra->last_entry->endBodyLine = yyextra->lineNr - 1;
853 yyextra->current_root->endBodyLine = yyextra->lineNr - 1;
855 if (!
endScope(yyscanner,yyextra->current_root))
859 yyextra->subrCurrent.pop_back();
867<Start,ModuleBody,TypedefBody,SubprogBody,FEnum>{
868^{BS}{TYPE_SPEC}/{SEPARATE} {
869 yyextra->last_enum.reset();
870 if (YY_START == FEnum)
872 yyextra->argType =
"@";
878 yyextra->current->bodyLine = yyextra->lineNr + 1;
879 yyextra->current->endBodyLine = yyextra->lineNr + yyextra->lineCountPrepass;
881 if (YY_START == Start)
884 yy_push_state(ModuleBody,yyscanner);
886 yy_push_state(AttributeList,yyscanner);
888{EXTERNAL_STMT}/({BS}"::"|{BS_}{ID}) {
890 if (YY_START == Start)
893 yy_push_state(ModuleBody,yyscanner);
898 yy_push_state(AttributeList,yyscanner);
900{ATTR_STMT}/{BS_}{ID} |
901{ATTR_STMT}/{BS}"::" {
903 DBG_CTX((stderr,
"5=========> Attribute statement: %s\n", yytext));
904 if (YY_START == Start)
907 yy_push_state(ModuleBody,yyscanner);
912 yy_push_state(YY_START,yyscanner);
913 BEGIN( AttributeList ) ;
916 if (YY_START == Start)
919 yy_push_state(ModuleBody,yyscanner);
923 if (YY_START == Start)
926 yy_push_state(ModuleBody,yyscanner);
929^{BS}"type"{BS_}"is"/{BT_} {}
931^{BS}"class"{BS_}"is"/{BT_} {}
932^{BS}"class"{BS_}"default" {}
937{LANGUAGE_BIND_SPEC} {
938 yyextra->currentModifiers |= yytext;
942 char chr = yytext[(int)yyleng-1];
945 yyextra->colNr -= (int)yyleng;
953 unput(yytext[(
int)yyleng-1]);
954 yyextra->currentModifiers |= (tmp);
969<FVariable>{OPERATOR_ID} {
973 int currentState = YY_START;
975 int outerState = YY_START;
976 yy_push_state(currentState,yyscanner);
977 if( outerState == Start || outerState == ModuleBody )
979 if ((yyextra->current_root) &&
980 (yyextra->current_root->section.isClass() ||
981 yyextra->current_root->section.isNamespace()))
983 name = yyextra->current_root->name +
"::" + name;
987 yyextra->modifiers[yyextra->current_root][name.
str()] |= yyextra->currentModifiers;
995 if ((yyextra->current_root) && yyextra->current_root->section.isNamespace())
997 name = yyextra->current_root->name +
"::" + name;
1000 yyextra->modifiers[yyextra->current_root][name.
lower().
str()] |= yyextra->currentModifiers;
1001 yyextra->argName= name;
1004 if (!yyextra->argType.isEmpty() && !yyextra->current_root->section.isFunction())
1007 yyextra->current->section = EntryType::makeVariable();
1008 yyextra->current->name = yyextra->argName;
1009 yyextra->current->type = yyextra->argType;
1010 yyextra->current->fileName = yyextra->fileName;
1011 yyextra->current->bodyLine = yyextra->lineNr;
1012 yyextra->current->startLine = yyextra->lineNr;
1013 if (yyextra->argType ==
"@")
1015 yyextra->current_root->copyToSubEntry(yyextra->current);
1017 yyextra->last_enum = yyextra->current;
1018 yyextra->current_root->parent()->moveToSubEntryAndRefresh(yyextra->current);
1026 else if (!yyextra->argType.isEmpty())
1033 if (!yyextra->docBlock.isEmpty())
1041 yyextra->modifiers[yyextra->current_root][name.
lower().
str()].type = yyextra->argType;
1045 if ((yyextra->current_root->name.lower() == yyextra->argName.lower()) ||
1046 (yyextra->modifiers[yyextra->current_root->parent()][yyextra->current_root->name.lower().str()].returnName.lower() == yyextra->argName.lower()))
1048 int strt = yyextra->current_root->type.find(
"function");
1057 if ((yyextra->current_root->type.length() - strt - strlen(
"function"))!= 0)
1059 rght = yyextra->current_root->type.
right(yyextra->current_root->type.length() - strt - (
int)strlen(
"function")).
stripWhiteSpace();
1061 yyextra->current_root->type = lft;
1064 if (yyextra->current_root->type.length() > 0) yyextra->current_root->type +=
" ";
1065 yyextra->current_root->type += rght;
1067 if (yyextra->argType.stripWhiteSpace().length() > 0)
1069 if (yyextra->current_root->type.length() > 0) yyextra->current_root->type +=
" ";
1070 yyextra->current_root->type += yyextra->argType.stripWhiteSpace();
1072 if (yyextra->current_root->type.length() > 0) yyextra->current_root->type +=
" ";
1073 yyextra->current_root->type +=
"function";
1074 if (!yyextra->docBlock.isEmpty())
1081 yyextra->current_root->type +=
" " + yyextra->argType.stripWhiteSpace();
1083 yyextra->current_root->type = yyextra->current_root->type.
stripWhiteSpace();
1084 yyextra->modifiers[yyextra->current_root][name.
lower().
str()].type = yyextra->current_root->type;
1088 yyextra->modifiers[yyextra->current_root][name.
lower().
str()].type = yyextra->argType;
1094 yyextra->current->doc.clear();
1095 yyextra->current->brief.clear();
1102 yyextra->modifiers[yyextra->current_root][name.
lower().
str()] |= attr;
1109 yy_push_state(YY_START,yyscanner);
1110 yyextra->initializer=
"=";
1111 yyextra->initializerScope = yyextra->initializerArrayScope = 0;
1112 BEGIN(Initialization);
1117 yyextra->docBlock.clear();
1121 yyextra->docBlock.clear();
1122 yyextra->inputStringSemi =
" \n"+
QCString(yytext+1);
1124 pushBuffer(yyscanner,yyextra->inputStringSemi);
1127 if (YY_START == FVariable) REJECT;
1128 if (YY_START == String) REJECT;
1129 if (YY_START == StrIgnore) REJECT;
1130 if (YY_START == DocBlock) REJECT;
1131 yyextra->inputStringSemi =
" \n"+
QCString(yytext+1);
1133 pushBuffer(yyscanner,yyextra->inputStringSemi);
1136<Initialization,ArrayInitializer>"[" |
1137<Initialization,ArrayInitializer>"(/" { yyextra->initializer+=yytext;
1138 yyextra->initializerArrayScope++;
1139 BEGIN(ArrayInitializer);
1141<ArrayInitializer>"]" |
1142<ArrayInitializer>"/)" { yyextra->initializer+=yytext;
1143 yyextra->initializerArrayScope--;
1144 if (yyextra->initializerArrayScope<=0)
1146 yyextra->initializerArrayScope = 0;
1147 BEGIN(Initialization);
1150<ArrayInitializer>. { yyextra->initializer+=yytext; }
1151<Initialization>"(" { yyextra->initializerScope++;
1152 yyextra->initializer+=yytext;
1154<Initialization>")" { yyextra->initializerScope--;
1155 yyextra->initializer+=yytext;
1157<Initialization>{COMMA} {
if (yyextra->initializerScope == 0)
1161 if (yyextra->last_enum)
1163 yyextra->last_enum->initializer.str(yyextra->initializer.str());
1167 if (yyextra->vtype ==
V_VARIABLE) yyextra->last_entry->initializer.str(yyextra->initializer.str());
1172 yyextra->initializer+=
", ";
1175<Initialization>"\n"|"!" {
1177 if (yyextra->last_enum)
1179 yyextra->last_enum->initializer.str(yyextra->initializer.str());
1183 if (yyextra->vtype ==
V_VARIABLE) yyextra->last_entry->initializer.str(yyextra->initializer.str());
1185 yyextra->colNr -= 1;
1188<Initialization>. { yyextra->initializer+=yytext; }
1190<*>{BS}"enum"{BS}","{BS}"bind"{BS}"("{BS}"c"{BS}")"{BS} {
1191 if (YY_START == Start)
1194 yy_push_state(ModuleBody,yyscanner);
1197 yy_push_state(FEnum,yyscanner);
1198 yyextra->current->protection = yyextra->defaultProtection;
1199 yyextra->typeProtection = yyextra->defaultProtection;
1200 yyextra->typeMode =
true;
1202 yyextra->current->spec.setStruct(
true);
1203 yyextra->current->name.clear();
1204 yyextra->current->args.clear();
1205 yyextra->current->name.sprintf(
"@%d",yyextra->anonCount++);
1207 yyextra->current->section = EntryType::makeEnum();
1208 yyextra->current->fileName = yyextra->fileName;
1209 yyextra->current->startLine = yyextra->lineNr;
1210 yyextra->current->bodyLine = yyextra->lineNr;
1211 if ((yyextra->current_root) &&
1212 (yyextra->current_root->section.isClass() ||
1213 yyextra->current_root->section.isNamespace()))
1215 yyextra->current->name = yyextra->current_root->name +
"::" + yyextra->current->name;
1219 startScope(yyscanner,yyextra->last_entry.get());
1222<FEnum>"end"{BS}"enum" {
1223 yyextra->last_entry->parent()->endBodyLine = yyextra->lineNr;
1224 if (!
endScope(yyscanner,yyextra->current_root))
1228 yyextra->typeMode =
false;
1234<Start,ModuleBody,SubprogBody,InterfaceBody,ModuleBodyContains,SubprogBodyContains>^{BS}({PREFIX}{BS_})?{TYPE_SPEC}{BS}({PREFIX}{BS_})?/{SUBPROG}{BS_} {
1237 addInterface(yyscanner,
"$interface$", yyextra->ifType);
1238 startScope(yyscanner,yyextra->last_entry.get());
1243 yy_push_state(SubprogPrefix,yyscanner);
1246<SubprogPrefix>{BS}{SUBPROG}{BS_} {
1253 yyextra->current->bodyLine = yyextra->lineNr + yyextra->lineCountPrepass + 1;
1254 yyextra->current->startLine = yyextra->lineNr;
1257<Start,ModuleBody,SubprogBody,InterfaceBody,ModuleBodyContains,SubprogBodyContains>^{BS}({PREFIX}{BS_})?{SUBPROG}{BS_} {
1262 addInterface(yyscanner,
"$interface$", yyextra->ifType);
1263 startScope(yyscanner,yyextra->last_entry.get());
1268 yy_push_state(Subprog,yyscanner);
1269 yyextra->current->bodyLine = yyextra->lineNr + yyextra->lineCountPrepass + 1;
1270 yyextra->current->startLine = yyextra->lineNr;
1274<Subprog>{ID} { yyextra->current->name = yytext;
1278 if ((yyextra->current_root) &&
1279 (yyextra->current_root->section.isClass() ||
1280 yyextra->current_root->section.isNamespace()))
1282 yyextra->current->name= yyextra->current_root->name +
"::" + yyextra->current->name;
1284 yyextra->modifiers[yyextra->current_root][yyextra->current->name.lower().str()].returnName = std::move(returnName);
1289 yyextra->current_root->name,
"$interface$",
QCString(yytext).lower());
1292 BEGIN(Parameterlist);
QCString substitute(const QCString &s, const QCString &src, const QCString &dst)
substitute all occurrences of src in s by dst
1294<Parameterlist>"(" { yyextra->current->args =
"("; }
1296 yyextra->current->args +=
")";
1299 startScope(yyscanner,yyextra->last_entry.get());
QCString removeRedundantWhiteSpace(const QCString &s)
1302<Parameterlist>{COMMA}|{BS} { yyextra->current->args += yytext;
1306 if (!yyextra->current->argList.empty())
1308 yyextra->current->argList.back().docs = c->
str;
1312<Parameterlist>{ID} {
1316 yyextra->current->args += param;
1320 yyextra->current->argList.push_back(arg);
1322<Parameterlist>{NOARGS} {
1326 startScope(yyscanner,yyextra->last_entry.get());
1329<SubprogBody>result{BS}\({BS}{ID} {
1330 if (yyextra->functionLine)
1335 yyextra->modifiers[yyextra->current_root->parent()][yyextra->current_root->name.lower().str()].returnName = result;
1342<FVariable,SubprogBody,ModuleBody,TypedefBody,TypedefBodyContains>"!<" {
1345 yyextra->current->docLine = yyextra->lineNr;
1346 yyextra->docBlockJavaStyle =
FALSE;
1347 yyextra->docBlock.clear();
1350 yy_push_state(DocBackLine,yyscanner);
1355 if (YY_START == String)
1357 yyextra->colNr -= (int)yyleng;
1362 if ((YY_START != StrIgnore) && (YY_START != String))
1364 yy_push_state(YY_START,yyscanner);
1366 yyextra->debugStr=
"*!";
#define Config_getBool(name)
1371 yyextra->docBlock+=yytext;
1373<DocBackLine>"\n"{BS}"!"("<"|"!"+) {
1374 yyextra->docBlock+=
"\n";
1379 yyextra->colNr -= 1;
1383 std::shared_ptr<Entry> tmp_entry = yyextra->current;
1385 if (yyextra->last_enum)
1387 yyextra->current = yyextra->last_enum;
1391 yyextra->current = yyextra->last_entry;
1395 yyextra->current = std::move(tmp_entry);
1401 else if (yyextra->vtype ==
V_RESULT)
1406 yyextra->docBlock.clear();
QCString stripIndentation(const QCString &s)
1409<Start,SubprogBody,ModuleBody,TypedefBody,InterfaceBody,ModuleBodyContains,SubprogBodyContains,TypedefBodyContains,FEnum>^{BS} {
1412<Start,SubprogBody,ModuleBody,TypedefBody,InterfaceBody,ModuleBodyContains,SubprogBodyContains,TypedefBodyContains,FEnum>"!>" {
1413 yy_push_state(YY_START,yyscanner);
1414 yyextra->current->docLine = yyextra->lineNr;
1415 yyextra->docBlockJavaStyle =
FALSE;
1416 if (YY_START==SubprogBody) yyextra->docBlockInBody =
TRUE;
1417 yyextra->docBlock.clear();
1425<DocBlock>({CMD}{CMD}){ID}/[^a-z_A-Z0-9] {
1426 yyextra->docBlock += yytext;
1428<DocBlock>{CMD}("f$"|"f["|"f{"|"f(") {
1429 yyextra->docBlock += yytext;
1430 yyextra->docBlockName=&yytext[1];
1431 if (yyextra->docBlockName.at(1)==
'[')
1433 yyextra->docBlockName.at(1)=
']';
1435 if (yyextra->docBlockName.at(1)==
'{')
1437 yyextra->docBlockName.at(1)=
'}';
1439 if (yyextra->docBlockName.at(1)==
'(')
1441 yyextra->docBlockName.at(1)=
')';
1443 yyextra->fencedSize=0;
1444 yyextra->blockString=yytext;
1445 yyextra->blockLineNr=yyextra->lineNr;
1446 BEGIN(DocCopyBlock);
1448<DocBlock>{CMD}"ifile"{B}+"\""[^\n\"]+"\"" {
1449 yyextra->fileName = &yytext[6];
1450 yyextra->fileName = yyextra->fileName.stripWhiteSpace();
1451 yyextra->fileName = yyextra->fileName.mid(1,yyextra->fileName.length()-2);
1452 yyextra->docBlock += yytext;
1454<DocBlock>{CMD}"ifile"{B}+{FILEMASK} {
1455 yyextra->fileName = &yytext[6];
1456 yyextra->fileName = yyextra->fileName.stripWhiteSpace();
1457 yyextra->docBlock += yytext;
1459<DocBlock>{CMD}"iline"{LINENR}/[\n\.] |
1460<DocBlock>{CMD}"iline"{LINENR}{B} {
1465 warn(yyextra->fileName,yyextra->lineNr,
"Invalid line number '%s' for iline command",yytext);
1469 yyextra->lineNr = nr;
1471 yyextra->docBlock += yytext;
int toInt(bool *ok=nullptr, int base=10) const
1473<DocBlock>{B}*"<"{PRE}">" {
1474 yyextra->docBlock += yytext;
1475 yyextra->docBlockName=
"<pre>";
1476 yyextra->fencedSize=0;
1477 yyextra->blockString=yytext;
1478 yyextra->blockLineNr=yyextra->lineNr;
1479 BEGIN(DocCopyBlock);
1481<DocBlock>{B}*"<"<CODE>">" {
1482 yyextra->docBlock += yytext;
1483 yyextra->docBlockName=
"<code>";
1484 yyextra->fencedSize=0;
1485 yyextra->blockString=yytext;
1486 yyextra->blockLineNr=yyextra->lineNr;
1487 BEGIN(DocCopyBlock);
1489<DocBlock>{CMD}"startuml"/[^a-z_A-Z0-9\-] {
1490 yyextra->docBlock += yytext;
1491 yyextra->docBlockName=
"uml";
1492 yyextra->fencedSize=0;
1493 yyextra->blockString=yytext;
1494 yyextra->blockLineNr=yyextra->lineNr;
1495 BEGIN(DocCopyBlock);
1497<DocBlock>{CMD}("verbatim"|"iliteral"|"latexonly"|"htmlonly"|"xmlonly"|"manonly"|"rtfonly"|"docbookonly"|"dot"|"msc"|"code")/[^a-z_A-Z0-9\-] {
1498 yyextra->docBlock += yytext;
1499 yyextra->docBlockName=&yytext[1];
1500 yyextra->fencedSize=0;
1501 yyextra->blockString=yytext;
1502 yyextra->blockLineNr=yyextra->lineNr;
1503 BEGIN(DocCopyBlock);
1505<DocBlock>"~~~"[~]* {
1507 yyextra->docBlock += pat;
1508 yyextra->docBlockName=
"~~~";
1509 yyextra->fencedSize=pat.
length();
1510 yyextra->blockString=yytext;
1511 yyextra->blockLineNr=yyextra->lineNr;
1512 BEGIN(DocCopyBlock);
1514<DocBlock>"```"[`]*/(".")?[a-zA-Z0-9#_-]+ |
1515<DocBlock>"```"[`]*/"{"[^}]+"}" |
1516<DocBlock>"```"[`]* {
1518 yyextra->docBlock += pat;
1519 yyextra->docBlockName=
"```";
1520 yyextra->fencedSize=pat.
length();
1521 yyextra->blockString=yytext;
1522 yyextra->blockLineNr=yyextra->lineNr;
1523 BEGIN(DocCopyBlock);
1525<DocBlock>"\\ilinebr "{BS} {
1527 int extraSpaces = std::max(0,
static_cast<int>(yyleng-9-yyextra->curIndent-2));
1528 indent.
fill(
' ',extraSpaces);
1530 yyextra->docBlock +=
"\\ilinebr ";
1531 yyextra->docBlock += indent;
void fill(char c, int len=-1)
Fills a string with a predefined character.
1534<DocBlock>[^@*`~\/\\\n]+ {
1535 yyextra->docBlock += yytext;
1537<DocBlock>"\n"{BS}"!"(">"|"!"+) {
1538 yyextra->docBlock+=
"\n";
1543 yyextra->colNr -= 1;
1549 yyextra->docBlock += *yytext;
1554<DocCopyBlock>"</"{PRE}">" {
1555 yyextra->docBlock += yytext;
1556 if (yyextra->docBlockName==
"<pre>")
1558 yyextra->docBlockName=
"";
1559 yyextra->blockString.clear();
1560 yyextra->blockLineNr=-1;
1564<DocCopyBlock>"</"{CODE}">" {
1565 yyextra->docBlock += yytext;
1566 if (yyextra->docBlockName==
"<code>")
1568 yyextra->docBlockName=
"";
1569 yyextra->blockString.clear();
1570 yyextra->blockLineNr=-1;
1574<DocCopyBlock>[\\@]("f$"|"f]"|"f}"|"f)") {
1575 yyextra->docBlock += yytext;
1576 if (yyextra->docBlockName==&yytext[1])
1578 yyextra->docBlockName=
"";
1579 yyextra->blockString.clear();
1580 yyextra->blockLineNr=-1;
1584<DocCopyBlock>[\\@]("endverbatim"|"endiliteral"|"endlatexonly"|"endhtmlonly"|"endxmlonly"|"enddocbookonly"|"endmanonly"|"endrtfonly"|"enddot"|"endmsc"|"enduml"|"endcode")/[^a-z_A-Z0-9] {
1585 yyextra->docBlock += yytext;
1586 if (&yytext[4]==yyextra->docBlockName)
1588 yyextra->docBlockName=
"";
1589 yyextra->blockString.clear();
1590 yyextra->blockLineNr=-1;
1595<DocCopyBlock>^{B}*{COMM} {
1596 if (yyextra->docBlockName==
"verbatim")
1604 yyextra->docBlock += indent;
1607<DocCopyBlock>"~~~"[~]* {
1609 yyextra->docBlock += pat;
1610 if (yyextra->docBlockName ==
"~~~" && yyextra->fencedSize==pat.
length())
1612 yyextra->blockString.clear();
1613 yyextra->blockLineNr=-1;
1617<DocCopyBlock>"```"[`]* {
1619 yyextra->docBlock += pat;
1620 if (yyextra->docBlockName ==
"```" && yyextra->fencedSize==pat.
length())
1622 yyextra->blockString.clear();
1623 yyextra->blockLineNr=-1;
1628<DocCopyBlock>[^<@/\*\]!`~"\$\\\n]+ {
1629 yyextra->docBlock += yytext;
1632 yyextra->docBlock += *yytext;
1636 yyextra->docBlock += *yytext;
1640<Prototype>{BS}{SUBPROG}{BS_} {
1641 BEGIN(PrototypeSubprog);
1643<Prototype,PrototypeSubprog>{BS}{SCOPENAME}?{BS}{ID} {
1646 BEGIN(PrototypeArgs);
1649"("|")"|","|{BS_} { yyextra->current->args += yytext; }
1650{ID} { yyextra->current->args += yytext;
1653 yyextra->current->argList.push_back(a);
1662 yyextra->debugStr=
"";
1669 if (yyextra->parsingPrototype)
1673 else if ( yyextra->includeStackPtr <= 0 )
1675 if (YY_START!=INITIAL && YY_START!=Start)
1677 DBG_CTX((stderr,
"==== Error: EOF reached in wrong state (end missing)"));
1702 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
1704 yyextra->lineNr+=yyextra->lineCountPrepass;
1705 yyextra->lineCountPrepass=0;
1706 yyextra->comments.clear();
1717 if (c==
'\t') col+=tabSize-(col%tabSize);
1718 else if (c==
'\n') col=0;
1726 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
1728 for (
const auto &cip : yyextra->comments)
1732 if (c>=from && c<=to)
1743 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
1747 yyextra->last_entry->brief = c->
str;
1752 if (parameter) parameter->
docs = c->
str;
1758 for(
int i=0; i<length; i++)
1778 int parseState = Start;
1779 char quoteSymbol = 0;
1781 int commentIndex = -1;
1783 if (ch !=
'\0') parseState = String;
1785 for(
int i=0; i<length && parseState!=Comment; i++)
1789 if (parseState==String)
1791 if (buf[i]==
'\\') i++;
1800 if (buf[i]==quoteSymbol)
1806 else if (parseState==Start)
1808 parseState = String;
1809 quoteSymbol = buf[i];
1815 if (parseState==Start)
1817 parseState = Comment;
1836 return commentIndex;
1844 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
1845 size_t length = yyextra->inputStringPrepass.length();
1846 for (
size_t i=index+1; i<length; i++) {
1847 if (yyextra->inputStringPrepass[i]==
'!' && i<length-1 && yyextra->inputStringPrepass[i+1]==
'<') {
1848 yyextra->comments.emplace_back(index, yyextra->inputStringPrepass.right(length-i-2));
1851 yyextra->inputStringPrepass.resize(index);
1858 for(
int i=length; i>pos; i--)
1859 contents[i]=contents[i-1];
1869 int prevLineLength=0;
1870 int prevLineAmpOrExclIndex=-1;
1872 char prevQuote =
'\0';
1873 char thisQuote =
'\0';
1874 bool emptyLabel=
TRUE;
1875 bool commented=
FALSE;
1876 bool inSingle=
FALSE;
1877 bool inDouble=
FALSE;
1878 bool inBackslash=
FALSE;
1879 bool fullCommentLine=
TRUE;
1880 bool artificialComment=
FALSE;
1882 int newContentsSize = (int)strlen(contents)+3;
1883 char* newContents = (
char*)malloc(newContentsSize);
1888 sizCont = strlen(contents);
1889 for(
size_t i=0;i<sizCont;i++) {
1891 char c = contents[i];
1892 if (artificialComment && c !=
'\n')
1894 if (c ==
'!' && spaces)
1896 newContents[j++] = c;
1897 artificialComment =
FALSE;
1902 else if (c ==
' ' || c ==
'\t')
continue;
1912 if (j>=newContentsSize-3) {
1913 newContents = (
char*)realloc(newContents, newContentsSize+1000);
1914 newContentsSize = newContentsSize+1000;
1919 if (!fullCommentLine)
1921 prevLineLength=column;
1922 prevLineAmpOrExclIndex=
getAmpOrExclAtTheEnd(&contents[i-prevLineLength+1], prevLineLength,prevQuote);
1923 if (prevLineAmpOrExclIndex == -1) prevLineAmpOrExclIndex = column - 1;
1926 prevLineAmpOrExclIndex = -1;
1932 prevLineLength+=column;
1936 hasContLine[curLine - 1] = 1;
1939 artificialComment=
FALSE;
1941 fullCommentLine=
TRUE;
1946 prevQuote = thisQuote;
1959 newContents[j]=
'\000';
1960 newContentsSize = (int)strlen(newContents);
1961 if (newContents[newContentsSize - 1] !=
'\n')
1964 newContents = (
char*)realloc(newContents, newContentsSize+2);
1965 newContents[newContentsSize] =
'\n';
1966 newContents[newContentsSize + 1] =
'\000';
1972 if ((column <= fixedCommentAfter) && (column!=6) && !commented)
1975 fullCommentLine=
FALSE;
1979 inBackslash = !inBackslash;
1986 inSingle = !inSingle;
1987 if (inSingle) thisQuote = c;
1988 else thisQuote =
'\0';
1996 inDouble = !inDouble;
1997 if (inDouble) thisQuote = c;
1998 else thisQuote =
'\0';
2003 inBackslash =
FALSE;
2010 if ((column <= fixedCommentAfter) && (column!=6))
2018 else if ((c ==
'!') && !inDouble && !inSingle)
2025 if (!commented) fullCommentLine=
FALSE;
2032 if (!commented && (column < 6) && ((c -
'0') >= 0) && ((c -
'0') <= 9))
2036 else if (column==6 && emptyLabel)
2038 if (!commented) fullCommentLine=
FALSE;
2043 if (prevLineAmpOrExclIndex==-1)
2052 if (curLine != 1)
insertCharacter(newContents, j+1, (j+1)-6-prevLineLength+prevLineAmpOrExclIndex+skipped,
'&');
2058 hasContLine[curLine - 1] = 1;
2067 else if ((column > fixedCommentAfter) && !commented)
2078 artificialComment =
TRUE;
2090 if (!commented) fullCommentLine=
FALSE;
2106 newContents = (
char*)realloc(newContents, 2);
2107 newContents[0] =
'\n';
2108 newContents[1] =
'\000';
2110 else if (newContents[j] ==
'\n')
2112 newContents = (
char*)realloc(newContents, j+2);
2113 newContents[j + 1] =
'\000';
2117 newContents = (
char*)realloc(newContents, j+3);
2118 newContents[j + 1] =
'\n';
2119 newContents[j + 2] =
'\000';
2126 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
2127 if (yyextra->includeStackCnt <= yyextra->includeStackPtr)
2129 yyextra->includeStackCnt++;
2130 yyextra->includeStack = (YY_BUFFER_STATE *)realloc(yyextra->includeStack, yyextra->includeStackCnt *
sizeof(YY_BUFFER_STATE));
2132 yyextra->includeStack[yyextra->includeStackPtr++] = YY_CURRENT_BUFFER;
2133 yy_switch_to_buffer(yy_scan_string(buffer.
data(),yyscanner),yyscanner);
2140 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
2142 yyextra->includeStackPtr --;
2143 yy_delete_buffer( YY_CURRENT_BUFFER, yyscanner );
2144 yy_switch_to_buffer( yyextra->includeStack[yyextra->includeStackPtr], yyscanner );
2148static void copyEntry(std::shared_ptr<Entry> dest,
const std::shared_ptr<Entry> &src)
2150 dest->type = src->type;
2151 dest->fileName = src->fileName;
2152 dest->startLine = src->startLine;
2153 dest->bodyLine = src->bodyLine;
2154 dest->endBodyLine = src->endBodyLine;
2155 dest->args = src->args;
2156 dest->argList = src->argList;
2157 dest->doc = src->doc;
2158 dest->docLine = src->docLine;
2159 dest->docFile = src->docFile;
2160 dest->brief = src->brief;
2161 dest->briefLine= src->briefLine;
2162 dest->briefFile= src->briefFile;
2172 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
2173 if (yyextra->moduleProcedures.empty())
return;
2176 std::map<std::string,std::shared_ptr<Entry>> procMap;
2178 for (
const auto& cf: current_root->
children())
2180 if (!cf->section.isFunction())
2191 procMap.emplace(name.
str(), cf);
2197 for (
const auto& ce1: yyextra->moduleProcedures)
2199 if (procMap.find(ce1->name.str())!=procMap.end())
2201 std::shared_ptr<Entry> proc = procMap[ce1->name.str()];
2205 yyextra->moduleProcedures.clear();
2212 int start = extracted.
find(
"(");
2215 extracted.
remove(0, start+1);
2220 size_t length = extracted.
length();
2232 if (parensPart.
length() == 1)
2247 return "bind(C, name=" + parensPart +
")";
2284 if (mdfString.
find(
"dimension")==0)
2288 else if (mdfString.
contains(
"intent"))
2292 bool isout = tmp.
contains(
"out")!=0;
2297 else if (mdfString==
"public")
2301 else if (mdfString==
"private")
2305 else if (mdfString==
"protected")
2309 else if (mdfString==
"optional")
2313 else if (mdfString==
"allocatable")
2317 else if (mdfString==
"external")
2321 else if (mdfString==
"intrinsic")
2325 else if (mdfString==
"parameter")
2329 else if (mdfString==
"pointer")
2333 else if (mdfString==
"target")
2337 else if (mdfString==
"save")
2341 else if (mdfString==
"nopass")
2345 else if (mdfString==
"deferred")
2349 else if (mdfString==
"non_overridable")
2353 else if (mdfString==
"contiguous")
2357 else if (mdfString==
"volatile")
2361 else if (mdfString==
"value")
2365 else if (mdfString.
contains(
"pass"))
2399 if ((!byTypeName && arg.
name.
lower() == cname) ||
2400 (byTypeName && arg.
type.
lower() == cname)
2415 if (!typeName.
isEmpty()) typeName +=
", ";
2420 if (!typeName.
isEmpty()) typeName +=
", ";
2425 if (!typeName.
isEmpty()) typeName +=
", ";
2426 typeName +=
"optional";
2430 if (!typeName.
isEmpty()) typeName +=
", ";
2431 typeName +=
"allocatable";
2435 if (!typeName.
contains(
"external"))
2437 if (!typeName.
isEmpty()) typeName +=
", ";
2438 typeName +=
"external";
2443 if (!typeName.
isEmpty()) typeName +=
", ";
2444 typeName +=
"intrinsic";
2448 if (!typeName.
isEmpty()) typeName +=
", ";
2449 typeName +=
"parameter";
2453 if (!typeName.
isEmpty()) typeName +=
", ";
2454 typeName +=
"pointer";
2458 if (!typeName.
isEmpty()) typeName +=
", ";
2459 typeName +=
"target";
2463 if (!typeName.
isEmpty()) typeName +=
", ";
2468 if (!typeName.
isEmpty()) typeName +=
", ";
2469 typeName +=
"deferred";
2473 if (!typeName.
isEmpty()) typeName +=
", ";
2474 typeName +=
"non_overridable";
2478 if (!typeName.
isEmpty()) typeName +=
", ";
2479 typeName +=
"nopass";
2483 if (!typeName.
isEmpty()) typeName +=
", ";
2486 typeName +=
"(" + mdfs.
passVar +
")";
2490 if (!typeName.
isEmpty()) typeName +=
", ";
2495 if (!typeName.
isEmpty()) typeName +=
", ";
2496 typeName +=
"public";
2500 if (!typeName.
isEmpty()) typeName +=
", ";
2501 typeName +=
"private";
2505 if (!typeName.
isEmpty()) typeName +=
", ";
2506 typeName +=
"protected";
2510 if (!typeName.
isEmpty()) typeName +=
", ";
2511 typeName +=
"contiguous";
2515 if (!typeName.
isEmpty()) typeName +=
", ";
2516 typeName +=
"volatile";
2520 if (!typeName.
isEmpty()) typeName +=
", ";
2521 typeName +=
"value";
2544 ent->
spec.setFinal(
true);
2557 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
2559 yyextra->current_root= scope;
2561 yyextra->modifiers.emplace(scope, std::map<std::string,SymbolModifiers>());
2564 yyextra->current = std::make_shared<Entry>();
2573 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
2574 if (yyextra->global_scope == scope)
2576 yyextra->global_scope =
nullptr;
2584 if (yyextra->current_root->parent() || isGlobalRoot)
2586 yyextra->current_root= yyextra->current_root->parent();
2590 fprintf(stderr,
"parse error in end <scopename>\n");
2596 yyextra->current = std::make_shared<Entry>();
2600 std::map<std::string,SymbolModifiers>& mdfsMap = yyextra->modifiers[scope];
2602 if (scope->
section.isFunction())
2605 for (
const auto &kv : mdfsMap)
2619 if (yyextra->modifiers[scope].find(returnName.
str())!=yyextra->modifiers[scope].end())
2621 scope->
type = yyextra->modifiers[scope][returnName.
str()].type;
2626 if (scope->
section.isClass() && scope->
spec.isInterface())
2633 for (
const auto &ce : scope->
children())
2635 if (!ce->section.isFunction())
2649 arg->
type =
"external " + ce->type +
"(";
2650 for (
unsigned int i=0; i<ce->argList.size(); i++)
2656 const Argument &subarg = ce->argList.at(i);
2664 yyextra->modifiers.erase(scope);
2670 if (!scope->
section.isFunction())
2673 for (
const auto &ce : scope->
children())
2675 if (!ce->section.isVariable() && !ce->section.isFunction() && !ce->section.isClass())
2679 if (mdfsMap.find(ce->name.lower().str())!=mdfsMap.end())
2683 if (ce->section.isVariable() || ce->section.isFunction())
2685 int end = ce->name.findRev(
":");
2687 ce->name.remove(0,
end+1);
2693 yyextra->modifiers.erase(scope);
2707 bool procMapCreated =
false;
2708 std::unordered_map<std::string,std::shared_ptr<Entry>> procMap;
2711 bool interfMapCreated =
false;
2712 std::unordered_map<std::string,std::shared_ptr<Entry>> interfMap;
2715 for (
const auto &ce: scope->
children())
2717 if (!ce->section.isClass())
2721 std::unordered_map<std::string,std::shared_ptr<Entry>> methodMap;
2722 for (
auto &ct: ce->children())
2724 if (!ct->section.isFunction())
2727 if (ct->type==
"generic")
2734 if (!procMapCreated)
2736 for (
const auto &cf: scope->
children())
2738 if (cf->section.isFunction())
2740 procMap.emplace(cf->name.str(), cf);
2743 procMapCreated =
true;
2748 if (procMap.find(implName.
str())!=procMap.end())
2750 std::shared_ptr<Entry> proc = procMap[implName.
str()];
2751 ct->args = proc->args;
2753 if (ct->brief.isEmpty())
2755 ct->brief = proc->brief;
2756 ct->briefLine = proc->briefLine;
2757 ct->briefFile = proc->briefFile;
2759 if (ct->doc.isEmpty())
2761 ct->doc = proc->doc;
2762 ct->docLine = proc->docLine;
2763 ct->docFile = proc->docFile;
2765 methodMap.emplace(ct->name.str(), ct);
2770 for (
auto &ct: ce->children())
2772 if (!ct->section.isFunction())
2779 if (!interfMapCreated)
2781 for(
const auto &cf: scope->
children())
2783 if (cf->section.isClass() && cf->spec.isInterface() && cf->type==
"abstract")
2785 std::shared_ptr<Entry> ci = cf->children().front();
2786 interfMap.emplace(ci->name.str(), ci);
2789 interfMapCreated =
true;
2794 if (interfMap.find(implName.
str())!= interfMap.end() )
2796 std::shared_ptr<Entry> proc = interfMap[implName.
str()];
2797 ct->args = proc->args;
2799 if (ct->brief.isEmpty())
2801 ct->brief = proc->brief;
2802 ct->briefLine = proc->briefLine;
2803 ct->briefFile = proc->briefFile;
2805 if (ct->doc.isEmpty())
2807 ct->doc = proc->doc;
2808 ct->docLine = proc->docLine;
2809 ct->docFile = proc->docFile;
2812 methodMap.emplace(ct->name.str(), ct);
2818 for (
auto &ct: ce->children())
2820 if (!ct->section.isFunction())
2823 if (ct->type!=
"generic")
2828 if (methodMap.find(methodName.
str()) != methodMap.end())
2830 std::shared_ptr<Entry> method = methodMap[methodName.
str()];
2831 ct->args = method->args;
2833 if (ct->brief.isEmpty())
2835 ct->brief = method->brief;
2836 ct->briefLine = method->briefLine;
2837 ct->briefFile = method->briefFile;
2839 if (ct->doc.isEmpty())
2841 ct->doc = method->doc;
2842 ct->docLine = method->docLine;
2843 ct->docFile = method->docFile;
2853 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
2855 while ( c < max_size && yyextra->inputString[yyextra->inputPosition] )
2857 *buf = yyextra->inputString[yyextra->inputPosition++] ;
2865 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
2866 yyextra->last_entry.reset();
2871 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
2872 if (yyextra->typeMode)
2874 yyextra->current->protection = yyextra->typeProtection;
2876 else if (yyextra->current_root && yyextra->current_root->section.isClass() && yyextra->current_root->spec.isInterface())
2880 else if (yyextra->current_root && yyextra->current_root->section.isFunction())
2886 yyextra->current->protection = yyextra->defaultProtection;
2890 yyextra->current->isStatic =
false;
2892 yyextra->commentScanner.initGroupInfo(yyextra->current.get());
2900 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
2901 if (case_insens) yyextra->current->name = yyextra->current->name.lower();
2903 yyextra->last_entry = yyextra->current;
2904 yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
2910 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
2911 DBG_CTX((stderr,
"0=========> got module %s\n",
qPrint(name)));
2914 yyextra->current->section = EntryType::makeNamespace();
2916 yyextra->current->section = EntryType::makeFunction();
2920 yyextra->current->name = name;
2924 QCString fname = yyextra->fileName;
2927 if (yyextra->mainPrograms) fname +=
"__" +
QCString().
setNum(yyextra->mainPrograms);
2928 yyextra->mainPrograms++;
2930 yyextra->current->name =
substitute(fname,
".",
"_");
2932 yyextra->current->type =
"program";
2933 yyextra->current->fileName = yyextra->fileName;
2934 yyextra->current->bodyLine = yyextra->lineNr;
2935 yyextra->current->startLine = yyextra->lineNr;
2938 startScope(yyscanner,yyextra->last_entry.get());
2944 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
2945 DBG_CTX((stderr,
"1=========> got subprog, type: %s\n",
qPrint(text)));
2946 yyextra->subrCurrent.push_back(yyextra->current);
2947 yyextra->current->section = EntryType::makeFunction();
2949 yyextra->functionLine = (subtype.
find(
"function") != -1);
2950 yyextra->current->type +=
" " + subtype;
2956 yyextra->current->fileName = yyextra->fileName;
2957 yyextra->current->bodyLine = yyextra->lineNr;
2958 yyextra->current->startLine = yyextra->lineNr;
2959 yyextra->current->args.
clear();
2960 yyextra->current->argList.clear();
2961 yyextra->docBlock.clear();
2970 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
2971 if (YY_START == Start)
2974 yy_push_state(ModuleBody,yyscanner);
2977 yyextra->current->section = EntryType::makeClass();
2978 yyextra->current->spec =
TypeSpecifier().setInterface(
true);
2979 yyextra->current->name = name;
2984 yyextra->current->type =
"abstract";
2988 yyextra->current->type =
"generic";
2994 yyextra->current->type =
"";
2998 if ((yyextra->current_root) &&
2999 (yyextra->current_root->section.isClass() ||
3000 yyextra->current_root->section.isNamespace()))
3002 yyextra->current->name= yyextra->current_root->name +
"::" + yyextra->current->name;
3005 yyextra->current->fileName = yyextra->fileName;
3006 yyextra->current->bodyLine = yyextra->lineNr;
3007 yyextra->current->startLine = yyextra->lineNr;
3018 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
3021 for (
Argument &a:yyextra->current_root->argList)
3036 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
3039 yyextra->current->briefFile = yyextra->fileName;
3040 yyextra->current->briefLine = yyextra->lineNr;
3044 yyextra->current->docFile = yyextra->fileName;
3045 yyextra->current->docLine = yyextra->lineNr;
3053 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
3055 if (yyextra->docBlockInBody && hideInBodyDocs)
3057 yyextra->docBlockInBody =
FALSE;
3060 DBG_CTX((stderr,
"call parseCommentBlock [%s]\n",
qPrint(doc)));
3061 int lineNr = brief ? yyextra->current->briefLine : yyextra->current->docLine;
3063 bool needsEntry =
FALSE;
3064 Markdown markdown(yyextra->fileName,lineNr);
3068 while (yyextra->commentScanner.parseCommentBlock(
3069 yyextra->thisParser,
3070 yyextra->docBlockInBody ? yyextra->subrCurrent.back().get() : yyextra->current.get(),
3074 yyextra->docBlockInBody ?
FALSE : brief,
3075 yyextra->docBlockInBody ?
FALSE : yyextra->docBlockJavaStyle,
3076 yyextra->docBlockInBody,
3077 yyextra->defaultProtection,
3084 DBG_CTX((stderr,
"parseCommentBlock position=%d [%s] needsEntry=%d\n",position,doc.
data()+position,needsEntry));
3087 DBG_CTX((stderr,
"parseCommentBlock position=%d [%s] needsEntry=%d\n",position,doc.
data()+position,needsEntry));
3090 yyextra->docBlockInBody =
FALSE;
3097 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
3101 std::shared_ptr<Entry> tmp_entry = yyextra->current;
3102 yyextra->current = yyextra->subrCurrent.back();
3105 yyextra->current->inbodyDocs =
"";
3114 int dir1 = yyextra->modifiers[yyextra->current_root][yyextra->argName.lower().str()].direction;
3129 yyextra->argName +
" " + loc_doc,brief);
3135 warn(yyextra->fileName,yyextra->lineNr,
"Routine: %s%s inconsistency between intent attribute and documentation for parameter %s:",
3136 qPrint(yyextra->current->name),
qPrint(yyextra->current->args),
qPrint(yyextra->argName));
3138 yyextra->argName +
" " + loc_doc,brief);
3151 yyextra->current = tmp_entry;
3155 yyextra->argName +
" " + loc_doc,brief);
3159 warn(yyextra->fileName,yyextra->lineNr,
"Routine: %s%s inconsistency between intent attribute and documentation for parameter %s:",
3160 qPrint(yyextra->current->name),
qPrint(yyextra->current->args),
qPrint(yyextra->argName));
3162 yyextra->argName +
" " + loc_doc,brief);
3176 yyextra->argName +
" " + loc_doc,brief);
3181 warn(yyextra->fileName,yyextra->lineNr,
"Routine: %s%s inconsistency between intent attribute and documentation for parameter %s:",
3182 qPrint(yyextra->current->name),
qPrint(yyextra->current->args),
qPrint(yyextra->argName));
3184 yyextra->argName +
" " + loc_doc,brief);
3191 yyextra->argName +
" " + loc_doc,brief);
3195 yyextra->current = tmp_entry;
3201 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
3205 std::shared_ptr<Entry> tmp_entry = yyextra->current;
3206 yyextra->current = yyextra->subrCurrent.back();
3209 yyextra->current->inbodyDocs =
"";
3225 yyextra->current = std::move(tmp_entry);
3233 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
3234 char *tmpBuf =
nullptr;
3237 if (fileBuf==
nullptr || fileBuf[0]==
'\0')
return;
3240 yyextra->inputString = fileBuf;
3241 yyextra->inputPosition = 0;
3242 yyextra->inputStringPrepass =
nullptr;
3243 yyextra->inputPositionPrepass = 0;
3246 yyextra->current_root = rt.get();
3247 yyextra->global_root = rt;
3251 if (yyextra->isFixedForm)
3253 yyextra->fixedCommentAfter =
Config_getInt(FORTRAN_COMMENT_AFTER);
3254 msg(
"Prepassing fixed form of %s\n",
qPrint(fileName));
3260 yyextra->inputString =
prepassFixedForm(fileBuf,
nullptr,yyextra->fixedCommentAfter);
3269 else if (yyextra->inputString[strlen(fileBuf)-1] !=
'\n')
3271 tmpBuf = (
char *)malloc(strlen(fileBuf)+2);
3272 strcpy(tmpBuf,fileBuf);
3273 tmpBuf[strlen(fileBuf)]=
'\n';
3274 tmpBuf[strlen(fileBuf)+1]=
'\000';
3275 yyextra->inputString = tmpBuf;
3278 yyextra->lineNr= 1 ;
3279 yyextra->fileName = fileName;
3280 msg(
"Parsing file %s...\n",
qPrint(yyextra->fileName));
3282 yyextra->global_scope = rt.get();
3285 yyextra->commentScanner.enterFile(yyextra->fileName,yyextra->lineNr);
3288 yyextra->current = std::make_shared<Entry>();
3290 yyextra->current->name = yyextra->fileName;
3291 yyextra->current->section = EntryType::makeSource();
3292 yyextra->file_root = yyextra->current;
3293 yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
3296 fortranscannerYYrestart(
nullptr, yyscanner );
3301 fortranscannerYYlex(yyscanner);
3302 yyextra->commentScanner.leaveFile(yyextra->fileName,yyextra->lineNr);
3304 if (yyextra->global_scope && yyextra->global_scope !=
INVALID_ENTRY)
3311 rt->program.str(std::string());
3313 yyextra->moduleProcedures.clear();
3316 free((
char*)tmpBuf);
3317 yyextra->inputString=
nullptr;
3319 if (yyextra->isFixedForm)
3321 free((
char*)yyextra->inputString);
3322 yyextra->inputString=
nullptr;
3344 :
p(std::make_unique<
Private>(format))
3350 fortranscannerYYlex_destroy(
p->yyscanner);
3354 const char *fileBuf,
3355 const std::shared_ptr<Entry> &root,
3358 struct yyguts_t *yyg = (
struct yyguts_t*)
p->yyscanner;
3359 yyextra->thisParser =
this;
3368 return extension!=extension.
lower();
3373 struct yyguts_t *yyg = (
struct yyguts_t*)
p->yyscanner;
3375 yyextra->parsingPrototype =
TRUE;
3377 fortranscannerYYlex(
p->yyscanner);
3378 yyextra->parsingPrototype =
FALSE;
3386 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
3387 fprintf(stderr,
"********************************************************************\n");
3388 if (yyextra->blockLineNr == -1)
3390 fprintf(stderr,
"Error in file %s line: %d, state: %d(%s)\n",
3395 fprintf(stderr,
"Error in file %s line: %d, state: %d(%s), starting command: '%s' probable line reference: %d\n",
3396 qPrint(yyextra->fileName),yyextra->lineNr,YY_START,
stateToString(YY_START),
qPrint(yyextra->blockString),yyextra->blockLineNr);
3398 fprintf(stderr,
"********************************************************************\n");
3402 for (
const auto &ce : yyextra->global_root->children())
3404 if (ce == yyextra->file_root) start=
TRUE;
3405 if (start) ce->reset();
3409 (void)yy_top_state(yyscanner);
3417 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
3418 if ( yyg->yy_start_stack_ptr <= 0 )
3419 warn(yyextra->fileName,yyextra->lineNr,
"Unexpected statement '%s'",yytext );
3421 yy_pop_state(yyscanner);
3425#include "fortranscanner.l.h"
This class represents an function or template argument list.
Clang parser object for a single translation unit, which consists of a source file and the directly o...
static void print(DebugMask mask, int prio, const char *fmt,...)
static bool isFlagSet(const DebugMask mask)
const std::vector< std::shared_ptr< Entry > > & children() const
ArgumentList argList
member arguments as a list
EntryType section
entry type (see Sections);
Specifier virt
virtualness of the entry
Protection protection
class protection
TypeSpecifier spec
class/member specifiers
void removeSubEntry(const Entry *e)
bool needsPreprocessing(const QCString &extension) const override
Returns TRUE if the language identified by extension needs the C preprocessor to be run before feed t...
std::unique_ptr< Private > p
void parsePrototype(const QCString &text) override
Callback function called by the comment block scanner.
~FortranOutlineParser() override
FortranOutlineParser(FortranFormat format=FortranFormat::Unknown)
void parseInput(const QCString &fileName, const char *fileBuf, const std::shared_ptr< Entry > &root, ClangTUParser *clangParser) override
Parses a single input file with the goal to build an Entry tree.
Helper class to process markdown formatted text.
QCString process(const QCString &input, int &startNewlines, bool fromParseInput=false)
QCString & prepend(const char *s)
bool startsWith(const char *s) const
QCString mid(size_t index, size_t len=static_cast< size_t >(-1)) const
bool isEmpty() const
Returns TRUE iff the string is empty.
QCString & setNum(short n)
QCString & append(char c)
int findRev(char c, int index=-1, bool cs=TRUE) const
const char * data() const
Returns a pointer to the contents of the string in the form of a 0-terminated C string.
int contains(char c, bool cs=TRUE) const
bool stripPrefix(const QCString &prefix)
Wrapper class for a number of boolean properties.
static const char * stateToString(int state)
#define Config_getInt(name)
DirIterator end(const DirIterator &) noexcept
const char * prepassFixedForm(const char *contents, int *hasContLine, int fixedCommentAfter)
const char * prepassFixedForm(const char *contents, int *hasContLine, int fixedCommentAfter)
static void parseMain(yyscan_t yyscanner, const QCString &fileName, const char *fileBuf, const std::shared_ptr< Entry > &rt, FortranFormat format)
static void initParser(yyscan_t yyscanner)
static QCString applyModifiers(QCString typeName, const SymbolModifiers &mdfs)
static Argument * findArgument(Entry *subprog, QCString name, bool byTypeName=FALSE)
static void insertCharacter(char *contents, int length, int pos, char c)
void msg(const char *fmt,...)
fortranscannerYY_state extra
Private(FortranFormat fmt)
bool recognizeFixedForm(const QCString &contents, FortranFormat format)