diff options
author | wtschueller <wtschueller@users.noreply.github.com> | 2014-06-11 20:02:02 (GMT) |
---|---|---|
committer | wtschueller <wtschueller@users.noreply.github.com> | 2014-06-11 20:02:02 (GMT) |
commit | 9d315a987d7d0ea2f38809aa74e36c92281910df (patch) | |
tree | 4a9e4d87a5bf9fe26772e9000bc24391e4c8762f /src/tclscanner.l | |
parent | 6245ef410358f332330195f9f2bfa458cfb6a2b8 (diff) | |
download | Doxygen-9d315a987d7d0ea2f38809aa74e36c92281910df.zip Doxygen-9d315a987d7d0ea2f38809aa74e36c92281910df.tar.gz Doxygen-9d315a987d7d0ea2f38809aa74e36c92281910df.tar.bz2 |
Tcl: recurse for []
Diffstat (limited to 'src/tclscanner.l')
-rw-r--r-- | src/tclscanner.l | 256 |
1 files changed, 182 insertions, 74 deletions
diff --git a/src/tclscanner.l b/src/tclscanner.l index 7201088..48e8214 100644 --- a/src/tclscanner.l +++ b/src/tclscanner.l @@ -1700,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) @@ -1707,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. @@ -1726,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]; @@ -1740,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. @@ -1757,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); } } @@ -2200,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); @@ -2294,7 +2395,7 @@ tcl_inf("->\n"); goto command_end; } tcl_command_OTHER(); - goto command_text; + goto command_end; } if (myStr=="itcl::class") { @@ -2317,7 +2418,7 @@ tcl_inf("->\n"); goto command_end; } tcl_command_OTHER(); - goto command_text; + goto command_end; } if (myStr=="oo::define") { @@ -2331,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") @@ -2340,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") @@ -2378,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) { @@ -2427,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;} @@ -2441,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; |