summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDimitri van Heesch <dimitri@stack.nl>2014-06-16 18:06:47 (GMT)
committerDimitri van Heesch <dimitri@stack.nl>2014-06-16 18:06:47 (GMT)
commit0921dea6f50b31b217cb70a6c1e2327a17591b5f (patch)
treeb25f5083e50c657e498c5f269ca53fc94162782a /src
parent4827ec0ce8b7094f0afd06ad87eb3edd0c2f1b8f (diff)
parent9d315a987d7d0ea2f38809aa74e36c92281910df (diff)
downloadDoxygen-0921dea6f50b31b217cb70a6c1e2327a17591b5f.zip
Doxygen-0921dea6f50b31b217cb70a6c1e2327a17591b5f.tar.gz
Doxygen-0921dea6f50b31b217cb70a6c1e2327a17591b5f.tar.bz2
Merge pull request #181 from wtschueller/master
Tcl: collect XRefs also if INLINE_SOURCES = no
Diffstat (limited to 'src')
-rw-r--r--src/tclscanner.l292
1 files changed, 218 insertions, 74 deletions
diff --git a/src/tclscanner.l b/src/tclscanner.l
index 1fd20cd..48e8214 100644
--- a/src/tclscanner.l
+++ b/src/tclscanner.l
@@ -451,6 +451,7 @@ static struct
QList<Entry> entry; // list of all created entries, will be deleted after codifying
Protection protection; // current protections state
MemberDef *memberdef; // contain current MemberDef when codifying
+ bool collectXRefs;
} tcl;
// scanner functions
@@ -1652,6 +1653,40 @@ static void tcl_codify_link(QCString name)
{
myDef->addSourceReferencedBy(tcl.memberdef);
tcl.memberdef->addSourceReferences(myDef);
+ } else {
+ Entry* callerEntry;
+ unsigned int i;
+ // walk the stack of scan contexts and find the enclosing method or proc
+ for (i=0;i<tcl.scan.count();i++)
+ {
+ callerEntry=tcl.scan.at(i)->entry_scan;
+ if (callerEntry->mtype==Method && !callerEntry->name.isEmpty())
+ {
+ break;
+ }
+ }
+ if (i<tcl.scan.count())
+ {
+ // enclosing method found
+ QCString callerName = callerEntry->name;
+ if (callerName.mid(0,2)=="::") // fully qualified global command
+ {
+ callerName = callerName.mid(2);
+ }
+ else
+ {
+ if (!(tcl.scan.at(0)->ns.stripWhiteSpace().isEmpty()))
+ {
+ callerName = tcl.scan.at(0)->ns + "::" + callerEntry->name;
+ }
+ }
+ MemberDef *callerDef=NULL;
+ callerDef = fn.find(callerName);
+ if (callerDef!=NULL && myDef!= NULL && tcl.collectXRefs)
+ {
+ addDocCrossReference(callerDef,myDef);
+ }
+ }
}
}
else if (tcl_keyword(myName)) // check keyword
@@ -1665,6 +1700,122 @@ static void tcl_codify_link(QCString name)
}
+//! scan general argument for brackets
+//
+// parses (*tcl.list_commandwords.at(i)).utf8() and checks for brackets.
+// Starts a new scan context if needed (*myScan==0 and brackets found).
+// Returns NULL or the created scan context.
+//
+static tcl_scan *tcl_command_ARG(tcl_scan *myScan, unsigned int i, bool ignoreOutermostBraces)
+{
+ QCString myName;
+ bool insideQuotes=false;
+ unsigned int insideBrackets=0;
+ unsigned int insideBraces=0;
+ myName = (*tcl.list_commandwords.at(i)).utf8();
+ if (i%2 != 0)
+ {
+ // handle white space
+ if (myScan!=NULL)
+ {
+ myScan->after << "NULL" << myName;
+ }
+ else
+ {
+ tcl_codify(NULL,myName);
+ }
+ }
+ else
+ {
+ QCString myStr = "";
+ unsigned int j;
+ for (j=0;j<myName.length();j++)
+ {
+ QChar c = myName[j];
+ bool backslashed = false;
+ if (j>0)
+ {
+ backslashed = myName[j-1]=='\\';
+ }
+ // this is a state machine
+ // input is c
+ // internal state is myScan and insideXXX
+ // these are the transitions:
+ if (c=='[' && !backslashed && insideBraces==0)
+ {
+ insideBrackets++;
+ }
+ if (c==']' && !backslashed && insideBraces==0 && insideBrackets>0)
+ {
+ insideBrackets--;
+ }
+ if (c=='{' && !backslashed && !insideQuotes && !(ignoreOutermostBraces && j==0))
+ {
+ insideBraces++;
+ }
+ if (c=='}' && !backslashed && !insideQuotes && insideBraces>0)
+ {
+ insideBraces--;
+ }
+ if (c=='"' && !backslashed && insideBraces==0)
+ {
+ insideQuotes=!insideQuotes;
+ }
+ // all output, depending on state and input
+ if (c=='[' && !backslashed && insideBrackets==1 && insideBraces==0)
+ {
+ // the first opening bracket, output what we have so far
+ myStr+=c;
+ if (myScan!=NULL)
+ {
+ myScan->after << "NULL" << myStr;
+ }
+ else
+ {
+ tcl_codify(NULL,myStr);
+ }
+ myStr="";
+ }
+ else if (c==']' && !backslashed && insideBrackets==0 && insideBraces==0)
+ {
+ // the last closing bracket, start recursion, switch to deferred
+ if (myScan!=NULL)
+ {
+ myScan->after << "script" << myStr;
+ }
+ else
+ {
+ myScan=tcl.scan.at(0);
+ myScan = tcl_scan_start('?',myStr,
+ myScan->ns,myScan->entry_cl,myScan->entry_fn);
+ }
+ myStr="";
+ myStr+=c;
+ }
+ else
+ {
+ myStr+=c;
+ }
+ }
+ if (myScan!=NULL)
+ {
+ myScan->after << "NULL" << myStr;
+ }
+ else
+ {
+ if (i==0)
+ {
+ tcl_codify_link(myStr);
+ }
+ else
+ {
+ tcl_codify(NULL,myStr);
+ }
+ }
+ }
+ return (myScan);
+}
+
//! Handle internal tcl commands.
// "if expr1 ?then? body1 elseif expr2 ?then? body2 elseif ... ?else? ?bodyN?"
static void tcl_command_IF(QStringList type)
@@ -1672,12 +1823,27 @@ static void tcl_command_IF(QStringList type)
D
tcl_codify_cmd("keyword",0);
tcl_codify_cmd(NULL,1);
- tcl_scan *myScan=tcl.scan.at(0);
- myScan = tcl_scan_start('?',*tcl.list_commandwords.at(2),
- myScan->ns,myScan->entry_cl,myScan->entry_fn);
+ tcl_scan *myScan = NULL;
+ myScan = tcl_command_ARG(myScan, 2, true);
for (unsigned int i = 3;i<tcl.list_commandwords.count();i++)
{
- myScan->after << type[i] << tcl.list_commandwords[i];
+ if (type[i] == "expr")
+ {
+ myScan = tcl_command_ARG(myScan, i, true);
+ }
+ else
+ {
+ if (myScan!=0)
+ {
+ myScan->after << type[i] << tcl.list_commandwords[i];
+ }
+ else
+ {
+ myScan=tcl.scan.at(0);
+ myScan = tcl_scan_start('?',*tcl.list_commandwords.at(i),
+ myScan->ns,myScan->entry_cl,myScan->entry_fn);
+ }
+ }
}
}
//! Handle internal tcl commands.
@@ -1691,7 +1857,7 @@ D
myScan = tcl_scan_start('?',*tcl.list_commandwords.at(2),
myScan->ns,myScan->entry_cl,myScan->entry_fn);
myScan->after << "NULL" << tcl.list_commandwords[3];
- myScan->after << "script" << tcl.list_commandwords[4];
+ myScan = tcl_command_ARG(myScan, 4, true);
myScan->after << "NULL" << tcl.list_commandwords[5];
myScan->after << "script" << tcl.list_commandwords[6];
myScan->after << "NULL" << tcl.list_commandwords[7];
@@ -1705,14 +1871,22 @@ static void tcl_command_FOREACH()
{
D
unsigned int i;
+ tcl_scan *myScan=NULL;
tcl_codify_cmd("keyword",0);
for (i = 1;i<tcl.list_commandwords.count()-1;i++)
{
- tcl_codify_cmd(NULL,i);
+ myScan = tcl_command_ARG(myScan, i, false);
+ }
+ if (myScan!=0)
+ {
+ myScan->after << "script" << tcl.list_commandwords[tcl.list_commandwords.count()-1];
+ }
+ else
+ {
+ myScan=tcl.scan.at(0);
+ myScan = tcl_scan_start('?',*tcl.list_commandwords.at(tcl.list_commandwords.count()-1),
+ myScan->ns,myScan->entry_cl,myScan->entry_fn);
}
- tcl_scan *myScan=tcl.scan.at(0);
- myScan = tcl_scan_start('?',*tcl.list_commandwords.at(tcl.list_commandwords.count()-1),
- myScan->ns,myScan->entry_cl,myScan->entry_fn);
}
///! Handle internal tcl commands.
@@ -1722,68 +1896,29 @@ static void tcl_command_WHILE()
D
tcl_codify_cmd("keyword",0);
tcl_codify_cmd(NULL,1);
- tcl_scan *myScan=tcl.scan.at(0);
- myScan = tcl_scan_start('?',*tcl.list_commandwords.at(2),
+ tcl_scan *myScan = NULL;
+ myScan = tcl_command_ARG(myScan, 2, true);
+ myScan = tcl_command_ARG(myScan, 3, false);
+ if (myScan!=0)
+ {
+ myScan->after << "script" << tcl.list_commandwords[4];
+ }
+ else
+ {
+ myScan=tcl.scan.at(0);
+ myScan = tcl_scan_start('?',*tcl.list_commandwords.at(4),
myScan->ns,myScan->entry_cl,myScan->entry_fn);
- myScan->after << "NULL" << tcl.list_commandwords[3];
- myScan->after << "script" << tcl.list_commandwords[4];
+ }
}
//! Handle all other commands.
// Create links of first command word or first command word inside [].
static void tcl_command_OTHER()
{
- if (tcl.code == NULL) return;
-D
- QCString myName;
+ tcl_scan *myScan=NULL;
for (unsigned int i=0; i< tcl.list_commandwords.count(); i++)
{
- myName = (*tcl.list_commandwords.at(i)).utf8();
- if (i==0)
- {
- tcl_codify_link(myName);
- }
- else if (i%2 != 0)
- {
- tcl_codify(NULL,myName);
- }
- else
- {
- QCString myStr="";
- int myCmd=0;
- unsigned int i;
- for (i=0;i<myName.length();i++)
- {
- QChar c = myName[i];
- if (myCmd)
- {
- if (c==' '||c=='\t'||c=='\n'||c==']')
- {//end of command
- tcl_codify_link(myStr);
- myStr="";
- myCmd=0;
- }
- myStr+=c;
- }
- else
- {
- myStr+=c;
- if (c=='[')
- {//start of command
- for (;i<myName.length();i++)
- {
- c = myName[i+1];
- if (c!=' ' && c!='\t' && c!='\n') break;
- myStr+=c;
- }
- tcl_codify(NULL,myStr);
- myStr="";
- myCmd=1;
- }
- }
- }
- tcl_codify(NULL,myStr);
- }
+ myScan = tcl_command_ARG(myScan, i, false);
}
}
@@ -2165,13 +2300,14 @@ tcl_inf("->\n");
// check command
QCString myStr = (*tcl.list_commandwords.at(0)).utf8();
+ tcl_scan *myScanBackup=tcl.scan.at(0);
int myLevel = 0;
Protection myProt = tcl.protection;
if (tcl.list_commandwords.count() < 3)
{
tcl_command_OTHER();
- goto command_text;
+ goto command_end;
}
// remove leading "::" and apply TCL_SUBST
if (myStr.left(2)=="::") myStr = myStr.mid(2);
@@ -2259,7 +2395,7 @@ tcl_inf("->\n");
goto command_end;
}
tcl_command_OTHER();
- goto command_text;
+ goto command_end;
}
if (myStr=="itcl::class")
{
@@ -2282,7 +2418,7 @@ tcl_inf("->\n");
goto command_end;
}
tcl_command_OTHER();
- goto command_text;
+ goto command_end;
}
if (myStr=="oo::define")
{
@@ -2296,7 +2432,7 @@ tcl_inf("->\n");
if (tcl.scan.at(0)->entry_fn == NULL)
{// only parsed outside functions
tcl_command_VARIABLE(tcl.scan.at(0)->entry_cl && tcl.scan.at(0)->entry_cl->name!="");
- goto command_text;
+ goto command_end;
}
}
if (myStr=="common")
@@ -2305,7 +2441,7 @@ tcl_inf("->\n");
if (tcl.scan.at(0)->entry_fn == NULL)
{// only parsed outside functions
tcl_command_VARIABLE(0);
- goto command_text;
+ goto command_end;
}
}
if (myStr=="inherit" || myStr=="superclass")
@@ -2343,7 +2479,7 @@ if expr1 ?then? body1 elseif expr2 ?then? body2 elseif ... ?else? ?bodyN?
if (myStr=="if" && tcl.list_commandwords.count() > 4)
{
QStringList myType;
- myType << "keyword" << "NULL" << "script" << "NULL";
+ myType << "keyword" << "NULL" << "expr" << "NULL";
char myState='x';// last word: e'x'pr 't'hen 'b'ody 'e'lse else'i'f..
for (unsigned int i = 4; i < tcl.list_commandwords.count(); i = i + 2)
{
@@ -2392,7 +2528,7 @@ if expr1 ?then? body1 elseif expr2 ?then? body2 elseif ... ?else? ?bodyN?
else if (myState=='i')
{
myState='x';
- myType << "script" << "NULL";
+ myType << "expr" << "NULL";
}
}
if (myState != 'b') {myLine=__LINE__;goto command_warn;}
@@ -2406,15 +2542,22 @@ if expr1 ?then? body1 elseif expr2 ?then? body2 elseif ... ?else? ?bodyN?
goto command_end;
}
tcl_command_OTHER();
- goto command_text;
+ goto command_end;
command_warn:// print warning message because of wrong used syntax
tcl_war("%d count=%d: %s\n",myLine,tcl.list_commandwords.count(),tcl.list_commandwords.join(" ").ascii());
tcl_command_OTHER();
- command_text:// print remaining text as comment
- if (!myText.isEmpty()) tcl_codify("comment",myText);
- myText = "";
command_end:// add remaining text to current context
- if (!myText.isEmpty()) tcl.scan.at(0)->after << "comment" << myText;
+ if (!myText.isEmpty())
+ {
+ if(myScanBackup==tcl.scan.at(0))
+ {
+ tcl_codify("comment",myText);
+ }
+ else
+ {
+ tcl.scan.at(0)->after << "comment" << myText;
+ }
+ }
tcl.list_commandwords.clear();
tcl.command = 0;
tcl.protection = myProt;
@@ -2634,6 +2777,7 @@ tcl_inf("%s (%d,%d) %d %d\n",myStr.ascii(),startLine,endLine,isExampleBlock,inli
return;
}
tcl_init();
+ tcl.collectXRefs = collectXRefs;
tcl.memberdef = memberDef;
tcl.code = &codeOutIntf;
if (startLine<0)