1 /*****************************************************************************
2 * Parser for Tcl subset
4 * Copyright (C) 2010 by Rene Zaumseil
5 * based on the work of Dimitri van Heesch.
7 * Permission to use, copy, modify, and distribute this software and its
8 * documentation under the terms of the GNU General Public License is hereby
9 * granted. No representations are made about the suitability of this software
10 * for any purpose. It is provided "as is" without express or implied warranty.
11 * See the GNU General Public License for more details.
13 * Documents produced by Doxygen are derivative works derived from the
14 * input used in their production; they are not affected by this license.
25 #include <qstringlist.h>
41 #include "commentscan.h"
43 #include "tclscanner.h"
44 #include "outputlist.h"
45 #include "membername.h"
46 #include "searchindex.h"
47 #include "commentcnv.h"
50 #include "arguments.h"
51 #include "namespacedef.h"
54 #define YY_NEVER_INTERACTIVE 1
57 #define MAX_INCLUDE_DEPTH 10
59 //! Application error.
61 printf("Error %d %s() at line %d! ",__LINE__,tcl.file_name.data(),yylineno); \
62 yy_push_state(ERROR); \
66 //! Application warning.
68 printf("Warning %d %s() at line %d: ",__LINE__,tcl.file_name.data(),yylineno); \
71 //! Application message.
73 if (0) printf("--- %.4d %d@%d: ",__LINE__,yylineno,yy_start_stack_ptr) && printf
77 if (0) printf("--- %.4d %d@%d: %s\n",__LINE__,yylineno,yy_start_stack_ptr,yytext);
79 // BEGIN of copy from tclUtil.c
80 // - Tcl_Interp removed
81 // - changes are marked with RZ
82 // #define's to adapt the code:
84 #define UCHAR (unsigned char)
87 #define ckalloc malloc
89 #define TclCopyAndCollapse(size,src,dest) memcpy(dest,src,size); *(dest+size)=0
91 CONST char *list, /* Points to the first byte of a string
92 * containing a Tcl list with zero or more
93 * elements (possibly in braces). */
94 int listLength, /* Number of bytes in the list's string. */
95 CONST char **elementPtr, /* Where to put address of first significant
96 * character in first element of list. */
97 CONST char **nextPtr, /* Fill in with location of character just
98 * after all white space following end of
99 * argument (next arg or end of list). */
100 int *sizePtr, /* If non-zero, fill in with size of
102 int *bracePtr) /* If non-zero, fill in with non-zero/zero to
103 * indicate that arg was/wasn't in braces. */
105 CONST char *p = list;
106 CONST char *elemStart; /* Points to first byte of first element. */
107 CONST char *limit; /* Points just after list's last byte. */
108 int openBraces = 0; /* Brace nesting level during parse. */
110 int size = 0; /* lint. */
114 * Skim off leading white space and check for an opening brace or quote.
115 * We treat embedded NULLs in the list as bytes belonging to a list
119 limit = (list + listLength);
120 while ((p < limit) && (isspace(UCHAR(*p))))
121 { /* INTL: ISO space. */
125 { /* no element found */
130 if (*p == '{') /* } to keep vi happy */
143 *bracePtr = openBraces;
147 * Find element's end (a space, close brace, or the end of the string).
155 * Open brace: don't treat specially unless the element is in
156 * braces. In this case, keep a nesting count.
167 * Close brace: if element is in braces, keep nesting count and
168 * quit when the last close brace is seen.
176 else if (openBraces == 1)
178 size = (int)(p - elemStart);
180 if ((p >= limit) || isspace(UCHAR(*p)))
181 { /* INTL: ISO space. */
186 * Garbage after the closing brace; return an error.
194 * Backslash: skip over everything up to the end of the backslash
199 //RZ Tcl_UtfBackslash(p, &numChars, NULL);
200 //RZ p += (numChars - 1);
205 * Space: ignore if element is in braces or quotes; otherwise
215 if ((openBraces == 0) && !inQuotes)
217 size = (int)(p - elemStart);
223 * Double-quote: if element is in quotes then terminate it.
229 size = (int)(p - elemStart);
231 if ((p >= limit) || isspace(UCHAR(*p)))
232 { /* INTL: ISO space */
237 * Garbage after the closing quote; return an error.
247 * End of list: terminate element.
260 size = (int)(p - elemStart);
264 while ((p < limit) && (isspace(UCHAR(*p))))
265 { /* INTL: ISO space. */
268 *elementPtr = elemStart;
278 CONST char *list, /* Pointer to string with list structure. */
279 int *argcPtr, /* Pointer to location to fill in with the
280 * number of elements in the list. */
281 CONST char ***argvPtr) /* Pointer to place to store pointer to array
282 * of pointers to list elements. */
284 CONST char **argv, *l, *element;
286 int length, size, i, result, elSize, brace;
289 * Figure out how much space to allocate. There must be enough space for
290 * both the array of pointers and also for a copy of the list. To estimate
291 * the number of pointers needed, count the number of space characters in
295 for (size = 2, l = list; *l != 0; l++)
297 if (isspace(UCHAR(*l)))
298 { /* INTL: ISO space. */
302 * Consecutive space can only count as a single list delimiter.
307 char next = *(l + 1);
314 if (isspace(UCHAR(next)))
315 { /* INTL: ISO space. */
322 length = (int)(l - list);
323 argv = (CONST char **) ckalloc((unsigned)
324 ((size * sizeof(char *)) + length + 1));
325 for (i = 0, p = ((char *) argv) + size*sizeof(char *);
328 CONST char *prevList = list;
330 result = TclFindElement(list, length, &element, &list,
332 length -= (int)(list - prevList);
333 if (result != TCL_OK)
335 ckfree((char *) argv);
344 ckfree((char *) argv);
350 memcpy(p, element, (size_t) elSize);
357 TclCopyAndCollapse(elSize, element, p);
369 void tcl_split_list(QString &str, QStringList &list)
375 if (str.left(1)=="{" && str.right(1)=="}")
377 str=str.mid(1,str.length()-2);
379 else if (str.left(1)=="\"" && str.right(1)=="\"")
381 str=str.mid(1,str.length()-2);
383 if (Tcl_SplitList(str.ascii(),&argc,&argv) != TCL_OK)
389 for (int i = 0; i < argc; i++)
391 list.append(argv[i]);
393 ckfree((char *) argv);
397 //! Structure containing information about current scan context.
400 char type[2]; // type of scan context: "\"" "{" "[" "?" " "
401 int line0; // start line of scan context
402 int line1; // end line of scan context
403 YY_BUFFER_STATE buffer_state; // value of scan context
404 QCString ns; // current namespace
405 Entry *entry_fn; // if set contains the current proc/method/constructor/destructor
406 Entry *entry_cl; // if set contain the current class
407 Entry *entry_scan; // current scan entry
408 Protection protection; // current protections state
409 QStringList after; // option/value list (options: NULL comment keyword script)
412 //* Structure containing all internal global variables.
415 CodeOutputInterface * code; // if set then we are codifying the file
416 int code_line; // current line of code
417 int code_linenumbers; // if true create line numbers in code
418 const char *code_font; // used font to codify
419 bool config_autobrief; // value of configuration option
420 QMap<QString,QString> config_subst; // map of configuration option values
421 QCString input_string; // file contents
422 int input_position; // position in file
423 QCString file_name; // name of used file
424 ParserInterface *this_parser; // myself
425 int command; // true if command was found
426 int comment; // set true if comment was scaned
427 int brace_level; // bookkeeping of braces
428 int bracket_level; // bookkeeping of brackets
429 int bracket_quote; // bookkeeping of quotes (toggles)
430 char word_is; // type of current word: "\"" "{" "[" "?" " "
431 int line_comment; // line number of comment
432 int line_commentline; // line number of comment after command
433 int line_command; // line number of command
434 int line_body0; // start line of body
435 int line_body1; // end line of body
436 QCString string_command; // contain current command
437 QCString string_commentline; // contain current comment after command
438 QCString string_commentcodify; // current comment string used in codifying
439 QCString string_comment; // contain current comment
440 QCString string_last; // contain last read word or part of word
441 QCString string; // temporary string value
442 Entry* entry_main; // top level entry
443 Entry* entry_file; // entry of current file
444 Entry* entry_current; // currently used entry
445 Entry* entry_inside; // contain entry of current scan context
446 QStringList list_commandwords; // list of command words
447 QList<tcl_scan> scan; // stack of scan contexts
448 QAsciiDict<Entry> ns; // all read namespace entries
449 QAsciiDict<Entry> cl; // all read class entries
450 QAsciiDict<Entry> fn; // all read function entries
451 QList<Entry> entry; // list of all created entries, will be deleted after codifying
452 Protection protection; // current protections state
453 MemberDef *memberdef; // contain current MemberDef when codifying
458 static int yyread(char *buf,int max_size);
459 static tcl_scan *tcl_scan_start(char type, QString content, QCString ns, Entry *entry_cls, Entry *entry_fn);
460 static void tcl_scan_end();
461 static void tcl_comment(int what,const char *text);
462 static void tcl_word(int what,const char *text);
463 static void tcl_command(int what,const char *text);
467 //! Create new entry.
468 // @return new initialised entry
469 Entry* tcl_entry_new()
471 Entry *myEntry = new Entry;
472 myEntry->section = Entry::EMPTY_SEC;
474 // myEntry->type = "";
476 // myEntry->doc = "";
477 myEntry->protection = Public;
478 // myEntry->mtype = Method;
479 // myEntry->virt = Normal;
480 // myEntry->stat = FALSE;
481 myEntry->fileName = tcl.file_name;
482 myEntry->lang = SrcLangExt_Tcl;
483 initGroupInfo(myEntry);
487 tcl.entry.insert(0,myEntry);
492 //! Set protection level.
493 void tcl_protection(Entry *entry)
495 if (entry->protection!=Public&&entry->protection!=Protected&&entry->protection!=Private)
497 entry->protection = tcl.protection;
499 if (entry->protection!=Protected&&entry->protection!=Private)
501 entry->protection = Public;
506 // @return 'ns' and 'name' of given current 'ns0' and 'name0'
507 static void tcl_name(const QCString &ns0, const QCString &name0, QCString &ns, QCString &name)
512 if (qstrncmp(name0.data(),"::",2)==0)
516 else if (ns0.length() && ns0 != " ")
518 myNm = ns0 + "::" + name0;
524 myStart = myNm.findRev("::");
532 ns = myNm.mid(0,myStart);
533 name = myNm.mid(myStart+2);
537 //! Check name. Strip namespace qualifiers from name0 if inside inlined code segment.
538 // @return 'ns' and 'name' of given current 'ns0' and 'name0'
539 static void tcl_name_SnippetAware(const QCString &ns0, const QCString &name0, QCString &ns, QCString &name)
541 // If we are inside an inlined code snippet then ns0
542 // already containes the complete namespace path.
543 // Any namespace qualifiers in name0 are redundant.
544 int i = name0.findRev("::");
545 if (i>=0 && tcl.memberdef)
547 tcl_name(ns0, name0.mid(i+2), ns, name);
551 tcl_name(ns0, name0, ns, name);
555 // Check and return namespace entry.
556 // @return namespace entry
557 Entry* tcl_entry_namespace(const QCString ns)
562 myEntry = tcl.ns.find(ns);
566 myEntry = tcl.ns.find("::");
570 myEntry = tcl_entry_new();
571 myEntry->section = Entry::NAMESPACE_SEC;
573 tcl.entry_main->addSubEntry(myEntry);
574 tcl.ns.insert(ns,myEntry);
579 // Check and return class entry.
580 // @return class entry
581 Entry* tcl_entry_class(const QCString cl)
584 if (!cl.length()) return(NULL);
586 myEntry = tcl.cl.find(cl);
589 myEntry = tcl_entry_new();
590 myEntry->section = Entry::CLASS_SEC;
592 tcl.entry_main->addSubEntry(myEntry);
593 tcl.cl.insert(cl,myEntry);
598 //! Check for keywords.
599 // @return 1 if keyword and 0 otherwise
600 static int tcl_keyword(QCString str)
602 static QStringList myList;
607 myList <<"append"<<"apply"<<"array"<<"auto_execok"<<"auto_import"<<"auto_load"<<"auto_mkindex"<<"auto_qualify"<<"auto_reset";
609 myList <<"catch"<<"cd"<<"close"<<"clock"<<"concat";
610 myList <<"eof"<<"eval"<<"exec"<<"exit"<<"expr";
611 myList <<"fblocked"<<"fconfigure"<<"file"<<"fileevent"<<"flush"<<"for"<<"foreach"<<"format";
612 myList <<"gets"<<"global";
614 myList <<"if"<<"incr"<<"info"<<"interp";
616 myList <<"lappend"<<"lassign"<<"lindex"<<"linsert"<<"llength"<<"load"<<"lrange"<<"lrepeat"<<"lreplace"<<"lreverse"<<"lset";
617 myList <<"namespace";
618 myList <<"package"<<"parray"<<"pid"<<"pkg_mkIndex"<<"proc"<<"puts"<<"pwd";
619 myList <<"registry"<<"rename"<<"return";
620 myList <<"scan"<<"set"<<"split"<<"string"<<"switch";
621 myList <<"tclLog"<<"tcl_endOfWord"<<"tcl_findLibrary"<<"tcl_startOfNextWord"<<"tcl_startOfPreviousWord"<<"tcl_wordBreakAfter"<<"tcl_wordBreakBefore"<<"tell"<<"time";
622 myList <<"unknown"<<"upvar";
623 myList <<"variable"<<"vwait";
625 myList <<"bell"<<"bind"<<"bindtags";
626 myList <<"clipboard"<<"console"<<"consoleinterp";
633 myList <<"pack"<<"place";
636 myList <<"tkerror"<<"tkwait"<<"tk_bisque"<<"tk_focusNext"<<"tk_focusPrev"<<"tk_focusFollowsMouse"<<"tk_popup"<<"tk_setPalette"<<"tk_textCut"<<"tk_TextCopy"<<"tk_textPaste"<<"chooseColor"<<"tk_chooseColor"<<"tk_chooseDirectory"<<"tk_dialog"<<"tk_getOpenFile"<<"tkDialog"<<"tk_getSaveFile"<<"tk_messageBox";
637 myList <<"winfo"<<"wm";
638 myList <<"button"<<"canvas"<<"checkbutton"<<"entry"<<"frame"<<"image"<<"label"<<"labelframe"<<"listbox"<<"menu"<<"menubutton"<<"message"<<"panedwindow"<<"radiobutton"<<"scale"<<"scrollbar"<<"spinbox"<<"toplevel";
642 str=str.stripWhiteSpace();
643 if (str.left(2)=="::") {str=str.mid(2);}
644 if (myList.findIndex(str) != -1) return(1);
648 //! End codifying with special font class.
649 static void tcl_font_end()
651 if (!tcl.code) return;
654 tcl.code->endFontClass();
659 //! Codify 'str' with special font class 's'.
660 static void tcl_codify(const char *s,char *str)
662 if (!tcl.code || !str) return;
663 if (s && qstrcmp(s,"NULL")!=0)
666 tcl.code->startFontClass(s);
675 while ((c=*p++) && c!='\n') {}
680 tcl.code->codify(sp);
683 tcl.code->endFontClass();
685 tcl.code->endCodeLine();
686 tcl.code->startCodeLine(tcl.code_linenumbers);
687 if (tcl.code_linenumbers)
689 tcl.code->writeLineNumber(0,0,0,tcl.code_line);
693 tcl.code->startFontClass(tcl.code_font);
698 tcl.code->codify(sp);
706 //! Codify 'str' with special font class 's'.
707 static void tcl_codify(const char *s,const char *str)
709 if (tcl.code==NULL) return;
710 char *tmp= (char *) malloc(strlen(str)+1);
716 //! Codify 'str' with special font class 's'.
717 static void tcl_codify(const char *s,const QString &str)
719 if (tcl.code==NULL) return;
720 tcl_codify(s,str.utf8());
724 //! Codify 'str' with special font class 's'.
725 static void tcl_codify(const char *s,const QCString &str)
727 if (!tcl.code) return;
728 tcl_codify(s,str.data());
731 static void tcl_codify_cmd(const char *s,int i)
733 tcl_codify(s,(*tcl.list_commandwords.at(i)).utf8());
735 //! codify a string token
737 // codifies string according to type.
738 // Starts a new scan context if needed (*myScan==0 and type == "script").
739 // Returns NULL or the created scan context.
741 static tcl_scan *tcl_codify_token(tcl_scan *myScan, const QCString type, const QCString string)
747 myScan->after << type << string;
751 myScan->after << "NULL" << string;
756 if (qstrcmp(type, "script") == 0)
758 myScan = tcl.scan.at(0);
759 myScan = tcl_scan_start('?', string,
760 myScan->ns, myScan->entry_cl, myScan->entry_fn);
764 tcl_codify((const char*)type, string);
770 //-----------------------------------------------------------------------------
772 #define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size);
773 //-----------------------------------------------------------------------------
798 if (tcl.scan.count()<1)
801 tcl_err("Tcl parser stack empty! Parser error in file '%s'.\n",tcl.file_name.data());
804 else if (tcl.scan.count()==1)
805 {// exit, check on input?
819 tcl.line_comment=yylineno;
822 <TOP>({ws}|[\;\n])+ {
824 tcl_codify(NULL,yytext);
829 tcl.line_command=yylineno;
835 tcl_codify("comment",yytext);
839 tcl_codify("comment",yytext);
840 tcl_comment(2,yytext+1);
842 <COMMENT>"##".*\\\n {
844 tcl_codify("comment",yytext);
846 t = t.mid(2,t.length()-3);
848 tcl_comment(1,t.data());
849 yy_push_state(COMMENT_NL);
853 tcl_codify("comment",yytext);
854 tcl_comment(1,yytext+2);
856 <COMMENT>"#"[@\\]"code"\n[ \t]*[^#] {
859 tcl_codify("comment",t.left(7));
860 tcl_comment(2,"\n@code\n");
862 yy_push_state(COMMENT_CODE);
864 <COMMENT>"#"[@\\]"verbatim"\n[ \t]*[^#] {
867 tcl_codify("comment",t.left(11));
868 tcl_comment(2,"\n@verbatim\n");
870 yy_push_state(COMMENT_VERB);
874 tcl_codify("comment",yytext);
876 t = t.mid(1,t.length()-3);
878 tcl_comment(2,t.data());
879 yy_push_state(COMMENT_NL);
883 tcl_codify("comment",yytext);
884 tcl_comment(2,yytext+1);
889 t = t.mid(0,t.length()-1);
890 tcl_codify("comment",t.data());
891 t = t.mid(1,t.length());
892 tcl_comment(-2,t.data());
902 tcl_comment(-2,yytext);
906 <COMMENT_CODE>"#"[@\\]"endcode"\n {
909 t = t.left(t.length()-10);
910 tcl_comment(2,t.data());
911 tcl_comment(2,"\n@endcode\n");
919 <COMMENT_CODE>.*\x1A {
925 <COMMENT_VERB>"#"[@\\]"endverbatim"\n {
928 t = t.left(t.length()-14);
929 tcl_comment(2,t.data());
930 tcl_comment(2,"\n@endverbatim\n");
938 <COMMENT_VERB>.*\x1A {
946 tcl_codify("comment",yytext);
947 tcl_comment(2,yytext);
951 tcl_codify("comment",yytext);
952 tcl_comment(2,yytext);
961 <COMMENTLINE>.*\x1A {
966 <COMMENTLINE>[ \t]* {
968 tcl.string_commentcodify += yytext;
970 <COMMENTLINE>"#<".*\\\n {
972 tcl.string_commentcodify += yytext;
974 t = t.mid(2,t.length()-4);
976 tcl.string_commentline += t;
977 yy_push_state(COMMENTLINE_NL);
979 <COMMENTLINE>"#<".*\n {
981 tcl.string_commentcodify += yytext;
982 tcl.string_commentline += (yytext+2);
987 if (tcl.string_commentline.length())
989 tcl.entry_current->brief = tcl.string_commentline;
990 tcl.entry_current->briefLine = tcl.line_commentline;
991 tcl.entry_current->briefFile = tcl.file_name;
994 tcl_command(-1,tcl.string_commentcodify.data());
995 tcl.string_commentline="";
996 tcl.string_commentcodify="";
999 <COMMENTLINE_NL>.*\\\n {
1001 tcl.string_commentcodify += yytext;
1003 t = t.left(t.length()-3);
1005 tcl.string_commentline += t;
1007 <COMMENTLINE_NL>.*\n {
1009 tcl.string_commentcodify += yytext;
1010 tcl.string_commentline += yytext;
1013 <COMMENTLINE_NL>.*\x1A {
1016 t = t.left(t.length()-1);
1017 tcl.string_commentcodify += t;
1018 tcl.string_commentline += t;
1023 <COMMAND>{ws}*[\;]{ws}*"#<" {
1025 tcl.string_commentcodify = yytext;
1026 tcl.string_commentcodify = tcl.string_commentcodify.left(tcl.string_commentcodify.length()-2);
1027 tcl.string_commentline = "";
1028 tcl.line_commentline = yylineno;
1029 tcl.line_body1=yylineno;
1032 yy_push_state(COMMENTLINE);
1034 <COMMAND>{ws}*\x1A {
1036 tcl.string_commentcodify = "";
1037 tcl.string_commentline = "";
1038 tcl.line_body1=yylineno;
1043 tcl.string_commentcodify = "";
1044 tcl.string_commentline = "";
1045 tcl.line_body1=yylineno;
1046 tcl_command(-1,yytext);
1050 tcl.string_commentcodify = "";
1051 tcl.string_commentline = "";
1052 tcl.line_body1=yylineno-1;
1053 tcl_command(-1,yytext);
1057 tcl_command(1,yytext);
1062 tcl.string_last = "{*}";
1063 tcl_word(0,&yytext[3]);
1065 <COMMAND>"\\"[\{\}\[\]\;\" \t] {
1068 tcl.string_last = "";
1074 if (yytext[0]=='{'||yytext[0]=='['||yytext[0]=='"') tcl.word_is = yytext[0];
1075 tcl.string_last = "";
1080 <WORD>"\\"[\{\}\[\]\;\" \t] {
1108 tcl_word(10,yytext);
1111 tcl_word(11,yytext);
1114 tcl_word(12,yytext);
1121 //! Start new scan context for given 'content'.
1122 // @return created new scan context.
1123 static tcl_scan *tcl_scan_start(char type, QString content, QCString ns, Entry *entry_cl, Entry *entry_fn)
1125 tcl_scan *myScan=tcl.scan.at(0);
1127 tcl_inf("line=%d type=%d '%s'\n",tcl.line_body0,type,content.ascii());
1129 myScan->line1=yylineno;
1132 myScan=new tcl_scan;
1133 myScan->type[0] =' ';
1134 myScan->type[1] = '\0';
1139 myScan->type[0] = type;
1142 if (content[0]=='"' && content[content.length()-1]=='"') myScan->type[0]='"';
1143 if (content[0]=='{' && content[content.length()-1]=='}') myScan->type[0]='{';
1144 if (content[0]=='[' && content[content.length()-1]==']') myScan->type[0]='[';
1146 if (myScan->type[0]!=' ')
1148 tcl_codify(NULL,&myScan->type[0]);
1149 content = content.mid(1,content.length()-2);
1151 content += (char)0x1A;// for detection end of scan context
1153 myScan->entry_cl = entry_cl;
1154 myScan->entry_fn = entry_fn;
1155 myScan->entry_scan = tcl.entry_current;
1156 myScan->buffer_state=yy_scan_string(content.ascii());
1157 myScan->line0=tcl.line_body0;
1158 myScan->line1=tcl.line_body1;
1159 myScan->after.clear();
1160 yylineno=myScan->line0;
1161 myScan->protection = tcl.protection;
1163 tcl.entry_inside = myScan->entry_scan;
1164 tcl.entry_current = tcl_entry_new();
1165 tcl.scan.insert(0,myScan);
1166 yy_switch_to_buffer(myScan->buffer_state);
1170 //! Close current scan context.
1171 static void tcl_scan_end()
1173 tcl_scan *myScan=tcl.scan.at(0);
1174 tcl_scan *myScan1=tcl.scan.at(1);
1175 tcl_inf("line=%d\n",myScan->line1);
1177 if (myScan->type[0]=='{') myScan->type[0]='}';
1178 if (myScan->type[0]=='[') myScan->type[0]=']';
1179 if (myScan->type[0]!=' ') tcl_codify(NULL,&myScan->type[0]);
1181 for (unsigned int i=0;i<myScan->after.count();i=i+2)
1183 if (myScan->after[i]=="script") {
1187 tcl_codify(myScan->after[i].utf8(),myScan->after[i+1].utf8());
1189 yy_delete_buffer(myScan->buffer_state);
1191 tcl.entry_inside = myScan1->entry_scan;
1192 yy_switch_to_buffer(myScan1->buffer_state);
1193 yylineno=myScan1->line1;
1194 tcl.protection = myScan1->protection;
1197 myScan1 = tcl_scan_start('?', myScan->after[myStart+1], myScan->ns, myScan->entry_cl, myScan->entry_fn);
1198 for (unsigned int i=myStart+2;i<myScan->after.count();i++)
1200 myScan1->after.append(myScan->after[i]);
1206 tcl.scan.removeFirst();
1210 //! Handling of word parsing.
1211 static void tcl_word(int what,const char *text)
1213 static char myList[1024]="";// nesting level list
1214 static int myLevel=0;// number of current nesting level
1215 static int myWhite=0;// set true when next char should be whitespace
1216 static char myWord;// internal state
1221 yy_push_state(WORD);
1226 case '"': myWord = text[0]; break;
1227 default: myWord = '.';
1233 case 1:// all other chars
1236 tcl_err("expected word separator: %s\n",text);
1252 tcl_inf("(\\\n) ?%s?\n",tcl.string_last.data());
1255 switch (myList[myLevel-1])
1267 tcl_inf("(\\\n) ?%s?\n",tcl.string_last.data());
1277 tcl_err("expected word separator: %s\n",text);
1280 switch (myList[myLevel-1])
1284 myList[myLevel++]='{';
1295 tcl_err("expected word separator: %s\n",text);
1298 switch (myList[myLevel-1])
1302 if (myLevel==0 && !tcl.code)
1316 tcl_err("expected word separator: %s\n",text);
1319 switch (myList[myLevel-1])
1326 myList[myLevel++]='[';
1334 tcl_err("expected word separator: %s\n",text);
1337 switch (myList[myLevel-1])
1353 tcl_err("expected word separator: %s\n",text);
1356 switch (myList[myLevel-1])
1361 myList[myLevel++]='"';
1378 tcl_inf("(%d) ?%s?\n",what,tcl.string_last.data());
1381 switch (myList[myLevel-1])
1393 tcl_inf("(.%d) ?%s?\n",what,tcl.string_last.data());
1410 tcl_inf("(%d) ?%s?\n",what,tcl.string_last.data());
1413 if (myLevel!=1 || myList[0] != '.')
1415 tcl_war("level=%d expected=%c\n",myLevel,myList[myLevel-1]);
1420 tcl_inf("(.%d) ?%s?\n",what,tcl.string_last.data());
1425 tcl_err("wrong state: %d\n",what);
1428 tcl.string_last += text;
1431 //! Handling of comment parsing.
1432 static void tcl_comment(int what,const char *text)
1435 { // begin of comment
1438 tcl_err("comment in comment\n");
1441 yy_push_state(COMMENT);
1442 tcl_inf("<- %s\n",text);
1443 tcl.string_comment="";
1447 { // start new comment
1450 tcl_comment(99,""); // inbody
1452 tcl.string_comment=text;
1459 tcl.string_comment+=text;
1462 else if (what==-1 || what == -2)
1463 { // end of comment without/with command
1466 tcl.string_last=tcl.string_comment;
1467 tcl_comment(100+what,"");
1471 tcl.string_last = "";
1472 tcl_inf("-> %s\n",(const char *)tcl.string_comment);
1475 tcl.string_comment="";
1478 else if (what==98 || what==99)
1479 { // 98=new 99=inbody
1480 if (tcl.this_parser && tcl.string_comment.length())
1482 tcl_inf("-> %s\n",(const char *)tcl.string_comment);
1485 int myLine=tcl.line_comment;
1488 Protection myProt=tcl.protection;
1491 myI.addArray("/*!",3);
1492 myI.addArray(tcl.string_comment.data(),tcl.string_comment.length());
1493 myI.addArray("*/",2);
1494 convertCppComments(&myI,&myO,tcl.file_name);
1495 myO.dropFromStart(3);
1496 myO.shrink(myO.curPos()-2);
1498 QCString myDoc = myO.data();
1500 { // inbody comment file or namespace or class or proc/method
1503 Entry myEntry0; // used to test parsing
1506 Entry *myEntry1=NULL;
1507 if (tcl.scan.at(0)->entry_fn)
1509 myEntry1=tcl.scan.at(0)->entry_fn;
1511 else if (tcl.scan.at(0)->entry_cl)
1513 myEntry1=tcl.scan.at(0)->entry_cl;
1518 while (parseCommentBlock(tcl.this_parser, &myEntry0, myDoc, tcl.file_name,
1519 myLine, FALSE, tcl.config_autobrief, FALSE, myProt, myPos, myNew))
1522 { // we need a new entry in this case
1524 myEntry = tcl_entry_new();
1525 parseCommentBlock(tcl.this_parser, myEntry, myDoc, tcl.file_name,
1526 myLine0, FALSE, tcl.config_autobrief, FALSE, myProt, myPos0, myNew);
1527 tcl.entry_inside->addSubEntry(myEntry);
1530 { // we can add to current entry in this case
1533 myEntry1=tcl_entry_namespace(tcl.scan.at(0)->ns);
1535 parseCommentBlock(tcl.this_parser, myEntry1, myDoc, tcl.file_name,
1536 myLine0, FALSE, tcl.config_autobrief, FALSE, myProt, myPos0, myNew);
1542 { // we need a new entry
1544 myEntry = tcl_entry_new();
1545 parseCommentBlock(tcl.this_parser, myEntry, myDoc, tcl.file_name,
1546 myLine0, FALSE, tcl.config_autobrief, FALSE, myProt, myPos0, myNew);
1547 tcl.entry_inside->addSubEntry(myEntry);
1550 { // we can add to current entry
1553 myEntry1=tcl_entry_namespace(tcl.scan.at(0)->ns);
1555 parseCommentBlock(tcl.this_parser, myEntry1, myDoc, tcl.file_name,
1556 myLine0, FALSE, tcl.config_autobrief, FALSE, myProt, myPos0, myNew);
1561 tcl.entry_current = tcl_entry_new();
1562 while (parseCommentBlock(tcl.this_parser, tcl.entry_current, myDoc,
1563 tcl.file_name, myLine, FALSE, tcl.config_autobrief, FALSE,
1564 myProt, myPos, myNew))
1568 tcl.entry_inside->addSubEntry(tcl.entry_current);
1569 tcl.entry_current = tcl_entry_new();
1573 tcl.entry_current->section = tcl.entry_inside->section;
1574 tcl.entry_current->name = tcl.entry_inside->name;
1579 tcl.entry_inside->addSubEntry(tcl.entry_current);
1580 tcl.entry_current = tcl_entry_new();
1584 tcl.entry_current->section = tcl.entry_inside->section;
1585 tcl.entry_current->name = tcl.entry_inside->name;
1588 if (tcl.protection != myProt)
1590 tcl.scan.at(0)->protection = tcl.protection = myProt;
1596 tcl_err("what %d\n",what);
1601 //! Parse given \c arglist .
1602 static void tcl_command_ARGLIST(QString &arglist)
1607 QString myArglist="";
1609 if (!tcl.entry_current->argList)
1611 tcl.entry_current->argList=new ArgumentList;
1613 tcl_split_list(arglist,myArgs);
1614 for (uint i=0;i<myArgs.count();i++)
1616 QStringList myArgs1;
1619 tcl_split_list(*myArgs.at(i),myArgs1);
1620 if (myArgs1.count()==2)
1622 myArg->name= (*myArgs1.at(0)).utf8();
1623 myArg->defval= (*myArgs1.at(1)).utf8();
1624 if (myArg->defval.isEmpty())
1626 myArg->defval = " ";
1628 myArglist += "?" + QCString(myArg->name) + "? ";
1632 myArg->name= (*myArgs.at(i)).utf8();
1633 myArglist += QString(myArg->name) + " ";
1635 tcl.entry_current->argList->append(myArg);
1637 arglist = myArglist;
1638 tcl.entry_current->args = arglist.utf8();
1642 static void tcl_codify_link(QCString name)
1644 if (tcl.code == NULL || name.isEmpty()) return;
1646 static QAsciiDict<MemberDef> fn;
1650 MemberNameSDict::Iterator mni(*Doxygen::memberNameSDict);
1651 MemberNameSDict::Iterator fni(*Doxygen::functionNameSDict);
1654 for (mni.toFirst();(mn=mni.current());++mni)
1656 MemberNameIterator mi(*mn);
1657 for (mi.toFirst();(md=mi.current());++mi)
1659 fn.insert(md->qualifiedName(),md);
1662 for (fni.toFirst();(mn=fni.current());++fni)
1664 MemberNameIterator fi(*mn);
1665 for (fi.toFirst();(md=fi.current());++fi)
1667 fn.insert(md->qualifiedName(),md);
1672 QCString myName=name;
1673 if (name.mid(0,2)=="::") // fully qualified global command
1675 myName = myName.mid(2);
1676 myDef = fn.find(myName);
1678 else // not qualified name
1680 QCString myName1=myName;
1682 myName1 = tcl.scan.at(0)->ns;
1683 if (myName1 == " " || myName1 == "")
1689 myName1 = myName1 + "::" + myName;
1691 myDef = fn.find(myName1); // search namespace command
1694 myDef = fn.find(myName); // search global command
1697 if (myDef != NULL) // documented command
1699 tcl.code->writeCodeLink(myDef->getReference().data(),
1700 myDef->getOutputFileBase().data(),
1701 myDef->anchor().data(),
1703 myDef->qualifiedName().data());
1706 myDef->addSourceReferencedBy(tcl.memberdef);
1707 tcl.memberdef->addSourceReferences(myDef);
1711 // walk the stack of scan contexts and find the enclosing method or proc
1712 for (i=0;i<tcl.scan.count();i++)
1714 callerEntry=tcl.scan.at(i)->entry_scan;
1715 if (callerEntry->mtype==Method && !callerEntry->name.isEmpty())
1720 if (i<tcl.scan.count())
1722 // enclosing method found
1723 QCString callerName = callerEntry->name;
1724 if (callerName.mid(0,2)=="::") // fully qualified global command
1726 callerName = callerName.mid(2);
1730 if (!(tcl.scan.at(0)->ns.stripWhiteSpace().isEmpty()))
1732 callerName = tcl.scan.at(0)->ns + "::" + callerEntry->name;
1735 MemberDef *callerDef=NULL;
1736 callerDef = fn.find(callerName);
1737 if (callerDef!=NULL && myDef!= NULL && tcl.collectXRefs)
1739 addDocCrossReference(callerDef,myDef);
1744 else if (tcl_keyword(myName)) // check keyword
1746 tcl_codify("keyword",name);
1750 tcl_codify(NULL,name); // something else
1755 //! scan general argument for brackets
1757 // parses (*tcl.list_commandwords.at(i)).utf8() and checks for brackets.
1758 // Starts a new scan context if needed (*myScan==0 and brackets found).
1759 // Returns NULL or the created scan context.
1761 static tcl_scan *tcl_command_ARG(tcl_scan *myScan, unsigned int i, bool ignoreOutermostBraces)
1764 bool insideQuotes=false;
1765 unsigned int insideBrackets=0;
1766 unsigned int insideBraces=0;
1767 myName = (*tcl.list_commandwords.at(i)).utf8();
1770 // handle white space
1771 myScan = tcl_codify_token(myScan, "NULL", myName);
1775 QCString myStr = "";
1777 for (j=0;j<myName.length();j++)
1779 QChar c = myName[j];
1780 bool backslashed = false;
1783 backslashed = myName[j-1]=='\\';
1785 // this is a state machine
1787 // internal state is myScan and insideXXX
1788 // these are the transitions:
1789 if (c=='[' && !backslashed && insideBraces==0)
1793 if (c==']' && !backslashed && insideBraces==0 && insideBrackets>0)
1797 if (c=='{' && !backslashed && !insideQuotes && !(ignoreOutermostBraces && j==0))
1801 if (c=='}' && !backslashed && !insideQuotes && insideBraces>0)
1805 if (c=='"' && !backslashed && insideBraces==0)
1807 insideQuotes=!insideQuotes;
1809 // all output, depending on state and input
1810 if (c=='[' && !backslashed && insideBrackets==1 && insideBraces==0)
1812 // the first opening bracket, output what we have so far
1814 myScan = tcl_codify_token(myScan, "NULL", myStr);
1817 else if (c==']' && !backslashed && insideBrackets==0 && insideBraces==0)
1819 // the last closing bracket, start recursion, switch to deferred
1820 myScan = tcl_codify_token(myScan, "script", myStr);
1829 if (i == 0 && myScan == NULL)
1831 tcl_codify_link(myStr);
1835 myScan = tcl_codify_token(myScan, "NULL", myStr);
1841 //! Handle internal tcl commands.
1842 // "eval arg ?arg ...?"
1843 static void tcl_command_EVAL()
1846 tcl_codify_cmd("keyword", 0);
1847 tcl_scan *myScan = tcl.scan.at(0);
1848 QCString myString = "";
1849 // we simply rescan the line without the eval
1850 // we include leading whitespace because tcl_scan_start will examine
1851 // the first char. If it finds a bracket it will assume one expression in brackets.
1852 // Example: eval [list set] [list NotInvoked] [Invoked NotInvoked]
1853 for (unsigned int i = 1; i < tcl.list_commandwords.count(); i++)
1855 myString += (*tcl.list_commandwords.at(i)).utf8();
1857 myScan = tcl_scan_start('?', myString,
1858 myScan->ns, myScan->entry_cl, myScan->entry_fn);
1861 //! Handle internal tcl commands.
1862 // switch ?options? string pattern body ?pattern body ...?
1863 // switch ?options? string {pattern body ?pattern body ...?}
1864 static void tcl_command_SWITCH()
1867 tcl_codify_cmd("keyword",0);
1868 tcl_codify_cmd(NULL,1);
1869 tcl_scan *myScan=NULL;
1872 // first: find the last option token
1873 unsigned int lastOptionIndex = 0;
1874 for (i = 2; i<tcl.list_commandwords.count(); i += 2)
1876 token = (*tcl.list_commandwords.at(i)).utf8();
1879 lastOptionIndex = i;
1882 if (token[0] == '-' && i - lastOptionIndex == 2)
1884 // options start with dash and should form a continuous chain
1885 lastOptionIndex = i;
1888 // second: eat up options
1889 for (i = 2; i <= lastOptionIndex; i++)
1891 myScan = tcl_command_ARG(myScan, i, false);
1893 // third: how many tokens are left?
1894 if (tcl.list_commandwords.count() - lastOptionIndex == 5)
1896 //printf("syntax: switch ?options? string {pattern body ?pattern body ...?}\n");
1897 myScan = tcl_command_ARG(myScan, lastOptionIndex + 1, false);
1898 myScan = tcl_command_ARG(myScan, lastOptionIndex + 2, false);
1899 myScan = tcl_command_ARG(myScan, lastOptionIndex + 3, false);
1900 // walk trough the list step by step
1901 // this way we can preserve whitespace
1902 bool inBraces = false;
1903 bool nextIsPattern = true;
1907 token = (*tcl.list_commandwords.at(lastOptionIndex + 4)).utf8();
1908 if (token[0] == '{')
1911 token = token.mid(1, token.length() - 2);
1912 myScan = tcl_codify_token(myScan, "NULL", QCString("{"));
1914 // ToDo: check if multibyte chars are handled correctly
1915 while (token.length() > 0)
1917 TclFindElement((const char*)token, token.length(), &elem, &next, &size, NULL);
1918 //printf("%s\nstart=%d, elem=%d, next=%d, size=%d, brace=%d\n",
1919 // (const char*) token, (const char*) token, elem, next, size, brace);
1921 // handle leading whitespace/opening brace/double quotes
1922 if (elem - token > 0)
1924 myScan = tcl_codify_token(myScan, "NULL", token.left(elem - token));
1926 // handle actual element without braces/double quotes
1929 myScan = tcl_codify_token(myScan, "NULL", token.mid(elem - token,size));
1930 //printf("pattern=%s\n",(const char*) token.mid(elem - token, size));
1933 myScan = tcl_codify_token(myScan, "script", token.mid(elem - token, size));
1934 //printf("script =%s\n", (const char*) token.mid(elem - token, size));
1936 // handle trailing whitespace/closing brace/double quotes
1937 if (next - elem - size > 0)
1939 myScan = tcl_codify_token(myScan, "NULL", token.mid(elem - token + size, next - elem - size));
1941 nextIsPattern = !nextIsPattern;
1942 token = token.mid(next - token);
1946 myScan = tcl_codify_token(myScan, "NULL", QCString("}"));
1950 tcl_war("Invalid switch syntax: last token is not a list of even elements.\n");
1951 //tcl_war("%s\n", tcl.list_commandwords.join(" ").ascii());
1954 else if ((tcl.list_commandwords.count() - lastOptionIndex > 6) &&
1955 ((tcl.list_commandwords.count() - lastOptionIndex-3) % 4 == 0))
1957 //printf("detected: switch ?options? string pattern body ?pattern body ...?\n");
1958 myScan = tcl_command_ARG(myScan, lastOptionIndex + 1, false);
1959 myScan = tcl_command_ARG(myScan, lastOptionIndex + 2, false);
1960 //printf("value=%s\n",(const char*) (*tcl.list_commandwords.at(lastOptionIndex + 2)).utf8());
1961 for (i = lastOptionIndex + 3; i < tcl.list_commandwords.count(); i += 4)
1963 myScan = tcl_command_ARG(myScan, i + 0, false); // whitespace
1964 myScan = tcl_command_ARG(myScan, i + 1, false); // pattern
1965 myScan = tcl_command_ARG(myScan, i + 2, false); // whitespace
1966 myScan = tcl_codify_token(myScan, "script", (*tcl.list_commandwords.at(i+3)).utf8()); // script
1967 //printf("pattern=%s\n",(const char*) (*tcl.list_commandwords.at(i+1)).utf8());
1968 //printf("script=%s\n",(const char*) (*tcl.list_commandwords.at(i+3)).utf8());
1973 // not properly detected syntax
1974 tcl_war("Invalid switch syntax: %d options followed by %d tokens.\n",
1975 lastOptionIndex / 2, (tcl.list_commandwords.count() - 1) / 2 - lastOptionIndex / 2);
1976 for (i = lastOptionIndex + 1; i <= tcl.list_commandwords.count(); i++)
1978 myScan = tcl_command_ARG(myScan, i, false);
1983 //! Handle internal tcl commands.
1984 // "catch script ?resultVarName? ?optionsVarName?"
1985 static void tcl_command_CATCH()
1988 tcl_codify_cmd("keyword", 0);
1989 tcl_codify_cmd(NULL, 1);
1990 tcl_scan *myScan = tcl.scan.at(0);
1991 myScan = tcl_scan_start('?', *tcl.list_commandwords.at(2),
1992 myScan->ns, myScan->entry_cl, myScan->entry_fn);
1993 for (unsigned int i = 3; i < tcl.list_commandwords.count(); i++)
1995 myScan = tcl_command_ARG(myScan, i, false);
1999 //! Handle internal tcl commands.
2000 // "if expr1 ?then? body1 elseif expr2 ?then? body2 elseif ... ?else? ?bodyN?"
2001 static void tcl_command_IF(QStringList type)
2004 tcl_codify_cmd("keyword",0);
2005 tcl_codify_cmd(NULL,1);
2006 tcl_scan *myScan = NULL;
2007 myScan = tcl_command_ARG(myScan, 2, true);
2008 for (unsigned int i = 3;i<tcl.list_commandwords.count();i++)
2010 if (type[i] == "expr")
2012 myScan = tcl_command_ARG(myScan, i, true);
2018 myScan->after << type[i] << tcl.list_commandwords[i];
2022 myScan=tcl.scan.at(0);
2023 myScan = tcl_scan_start('?',*tcl.list_commandwords.at(i),
2024 myScan->ns,myScan->entry_cl,myScan->entry_fn);
2029 //! Handle internal tcl commands.
2030 // "for start test next body"
2031 static void tcl_command_FOR()
2034 tcl_codify_cmd("keyword",0);
2035 tcl_codify_cmd(NULL,1);
2036 tcl_scan *myScan=tcl.scan.at(0);
2037 myScan = tcl_scan_start('?',*tcl.list_commandwords.at(2),
2038 myScan->ns,myScan->entry_cl,myScan->entry_fn);
2039 myScan->after << "NULL" << tcl.list_commandwords[3];
2040 myScan = tcl_command_ARG(myScan, 4, true);
2041 myScan->after << "NULL" << tcl.list_commandwords[5];
2042 myScan->after << "script" << tcl.list_commandwords[6];
2043 myScan->after << "NULL" << tcl.list_commandwords[7];
2044 myScan->after << "script" << tcl.list_commandwords[8];
2047 ///! Handle internal tcl commands.
2048 // "foreach varname list body" and
2049 // "foreach varlist1 list1 ?varlist2 list2 ...? body"
2050 static void tcl_command_FOREACH()
2054 tcl_scan *myScan=NULL;
2055 tcl_codify_cmd("keyword",0);
2056 for (i = 1;i<tcl.list_commandwords.count()-1;i++)
2058 myScan = tcl_command_ARG(myScan, i, false);
2062 myScan->after << "script" << tcl.list_commandwords[tcl.list_commandwords.count()-1];
2066 myScan=tcl.scan.at(0);
2067 myScan = tcl_scan_start('?',*tcl.list_commandwords.at(tcl.list_commandwords.count()-1),
2068 myScan->ns,myScan->entry_cl,myScan->entry_fn);
2072 ///! Handle internal tcl commands.
2073 // "while test body"
2074 static void tcl_command_WHILE()
2077 tcl_codify_cmd("keyword",0);
2078 tcl_codify_cmd(NULL,1);
2079 tcl_scan *myScan = NULL;
2080 myScan = tcl_command_ARG(myScan, 2, true);
2081 myScan = tcl_command_ARG(myScan, 3, false);
2084 myScan->after << "script" << tcl.list_commandwords[4];
2088 myScan=tcl.scan.at(0);
2089 myScan = tcl_scan_start('?',*tcl.list_commandwords.at(4),
2090 myScan->ns,myScan->entry_cl,myScan->entry_fn);
2094 //! Handle all other commands.
2095 // Create links of first command word or first command word inside [].
2096 static void tcl_command_OTHER()
2098 tcl_scan *myScan=NULL;
2099 for (unsigned int i=0; i< tcl.list_commandwords.count(); i++)
2101 myScan = tcl_command_ARG(myScan, i, false);
2105 //! Handle \c proc statements.
2106 static void tcl_command_PROC()
2109 QCString myNs, myName;
2112 tcl_scan *myScan = tcl.scan.at(0);
2114 tcl_codify_cmd("keyword",0);
2115 tcl_codify_cmd(NULL,1);
2116 tcl_codify_cmd(NULL,2);
2117 tcl_codify_cmd(NULL,3);
2118 tcl_codify_cmd(NULL,4);
2119 tcl_codify_cmd(NULL,5);
2120 tcl_name_SnippetAware(myScan->ns,(*tcl.list_commandwords.at(2)).utf8(),myNs,myName);
2123 myEntryNs = tcl_entry_namespace(myNs);
2127 myEntryNs = tcl_entry_namespace(myScan->ns);
2129 //why not needed here? tcl.fn.remove(myName);
2130 tcl.entry_current->section = Entry::FUNCTION_SEC;
2131 tcl.entry_current->mtype = Method;
2132 tcl.entry_current->name = myName;
2133 tcl.entry_current->startLine = tcl.line_command;
2134 tcl.entry_current->bodyLine = tcl.line_body0;
2135 tcl.entry_current->endBodyLine = tcl.line_body1;
2136 tcl_protection(tcl.entry_current);
2137 tcl_command_ARGLIST(*tcl.list_commandwords.at(4));
2138 myEntryNs->addSubEntry(tcl.entry_current);
2139 myEntry = tcl.entry_current;
2140 tcl.fn.insert(myName,myEntry);
2141 myScan = tcl_scan_start(tcl.word_is,*tcl.list_commandwords.at(6),
2142 myEntryNs->name,NULL,myEntry);
2145 //! Handle \c itcl::body statements and \c oo::define method and method inside \c itcl::class statements.
2146 static void tcl_command_METHOD()
2149 QCString myNs, myName;
2150 Entry *myEntryCl, *myEntry;
2151 tcl_scan *myScan = tcl.scan.at(0);
2153 tcl_codify_cmd("keyword",0);
2154 tcl_codify_cmd(NULL,1);
2155 tcl_codify_cmd(NULL,2);
2156 tcl_codify_cmd(NULL,3);
2157 tcl_codify_cmd(NULL,4);
2158 tcl_codify_cmd(NULL,5);
2159 tcl_name(myScan->ns,(*tcl.list_commandwords.at(2)).utf8(),myNs,myName);
2162 myEntryCl = tcl_entry_class(myNs);
2167 myEntryCl = myScan->entry_cl;
2169 // needed in case of more then one definition p.e. itcl::method and itcl::body
2171 tcl.fn.remove(myName);
2172 tcl.entry_current->section = Entry::FUNCTION_SEC;
2173 tcl.entry_current->mtype = Method;
2174 tcl.entry_current->name = myName;
2175 tcl.entry_current->startLine = tcl.line_command;
2176 tcl.entry_current->bodyLine = tcl.line_body0;
2177 tcl.entry_current->endBodyLine = tcl.line_body1;
2178 tcl_protection(tcl.entry_current);
2179 tcl_command_ARGLIST(*tcl.list_commandwords.at(4));
2180 myEntryCl->addSubEntry(tcl.entry_current);
2181 tcl.fn.insert(myName,tcl.entry_current);
2182 myEntry = tcl.entry_current;
2183 myScan = tcl_scan_start(tcl.word_is,*tcl.list_commandwords.at(6),
2184 myNs, myEntryCl, myEntry);
2187 //! Handle \c constructor statements inside class definitions.
2188 static void tcl_command_CONSTRUCTOR()
2191 QCString myNs, myName;
2192 Entry *myEntryCl, *myEntry;
2193 tcl_scan *myScan = tcl.scan.at(0);
2195 tcl_codify_cmd("keyword",0);
2196 tcl_codify_cmd(NULL,1);
2197 tcl_codify_cmd(NULL,2);
2198 tcl_codify_cmd(NULL,3);
2199 tcl_name(myScan->ns,(*tcl.list_commandwords.at(0)).utf8(),myNs,myName);
2202 myEntryCl = tcl_entry_class(myNs);
2207 myEntryCl = myScan->entry_cl;
2209 tcl.entry_current->section = Entry::FUNCTION_SEC;
2210 tcl.entry_current->mtype = Method;
2211 tcl.entry_current->name = myName;
2212 tcl.entry_current->startLine = tcl.line_command;
2213 tcl.entry_current->bodyLine = tcl.line_body0;
2214 tcl.entry_current->endBodyLine = tcl.line_body1;
2215 tcl_protection(tcl.entry_current);
2216 tcl_command_ARGLIST(*tcl.list_commandwords.at(2));
2217 if (myEntryCl) myEntryCl->addSubEntry(tcl.entry_current);
2218 myEntry = tcl.entry_current;
2219 tcl.fn.insert(myName,myEntry);
2220 myScan = tcl_scan_start(tcl.word_is,*tcl.list_commandwords.at(4),
2221 myNs, myEntryCl, myEntry);
2224 //! Handle \c destructor statements inside class definitions.
2225 static void tcl_command_DESTRUCTOR()
2228 QCString myNs, myName;
2229 Entry *myEntryCl, *myEntry;
2230 tcl_scan *myScan = tcl.scan.at(0);
2232 tcl_codify_cmd("keyword",0);
2233 tcl_codify_cmd(NULL,1);
2234 tcl_name(myScan->ns,(*tcl.list_commandwords.at(0)).utf8(),myNs,myName);
2237 myEntryCl = tcl_entry_class(myNs);
2242 myEntryCl = myScan->entry_cl;
2244 tcl.entry_current->section = Entry::FUNCTION_SEC;
2245 tcl.entry_current->mtype = Method;
2246 tcl.entry_current->name = myName;
2247 tcl.entry_current->startLine = tcl.line_command;
2248 tcl.entry_current->bodyLine = tcl.line_body0;
2249 tcl.entry_current->endBodyLine = tcl.line_body1;
2250 tcl_protection(tcl.entry_current);
2251 myEntryCl->addSubEntry(tcl.entry_current);
2252 myEntry = tcl.entry_current;
2253 tcl.fn.insert(myName,myEntry);
2254 myScan = tcl_scan_start(tcl.word_is,*tcl.list_commandwords.at(2),
2255 myNs, myEntryCl, myEntry);
2258 //! Handle \c namespace statements.
2259 static void tcl_command_NAMESPACE()
2262 QCString myNs, myName, myStr;
2263 //Entry *myEntryNs=NULL;
2264 tcl_scan *myScan = tcl.scan.at(0);
2266 tcl_codify_cmd("keyword",0);
2267 tcl_codify_cmd(NULL,1);
2268 tcl_codify_cmd("keyword",2);
2269 tcl_codify_cmd(NULL,3);
2270 tcl_codify_cmd(NULL,4);
2271 tcl_codify_cmd(NULL,5);
2272 tcl_name(myScan->ns,(*tcl.list_commandwords.at(4)).utf8(),myNs,myName);
2275 myName = myNs+"::"+myName;
2277 tcl.entry_current->section = Entry::NAMESPACE_SEC;
2278 tcl.entry_current->name = myName;
2279 tcl.entry_current->startLine = tcl.line_command;
2280 tcl.entry_current->bodyLine = tcl.line_body0;
2281 tcl.entry_current->endBodyLine = tcl.line_body1;
2282 tcl.entry_main->addSubEntry(tcl.entry_current);
2283 tcl.ns.insert(myName,tcl.entry_current);
2284 //myEntryNs = tcl.entry_current;
2285 myStr = (*tcl.list_commandwords.at(6)).utf8();
2286 if (tcl.list_commandwords.count() > 7)
2288 for (uint i=7;i<tcl.list_commandwords.count();i++)
2290 myStr.append((*tcl.list_commandwords.at(i)).utf8());
2294 myScan = tcl_scan_start(tcl.word_is,myStr, myName, NULL, NULL);
2297 //! Handle \c itcl::class statements.
2298 static void tcl_command_ITCL_CLASS()
2301 QCString myNs, myName, myStr;
2303 tcl_scan *myScan = tcl.scan.at(0);
2305 tcl_codify_cmd("keyword",0);
2306 tcl_codify_cmd(NULL,1);
2307 tcl_codify_cmd("NULL",2);
2308 tcl_codify_cmd("NULL",3);
2309 tcl_name(myScan->ns,(*tcl.list_commandwords.at(2)).utf8(),myNs,myName);
2312 myName = myNs+"::"+myName;
2314 tcl.entry_current->section = Entry::CLASS_SEC;
2315 tcl.entry_current->name = myName;
2316 tcl.entry_current->startLine = tcl.line_command;
2317 tcl.entry_current->bodyLine = tcl.line_body0;
2318 tcl.entry_current->endBodyLine = tcl.line_body1;
2319 tcl.entry_main->addSubEntry(tcl.entry_current);
2320 tcl.cl.insert(myName,tcl.entry_current);
2321 myEntryCl = tcl.entry_current;
2322 myScan = tcl_scan_start(tcl.word_is,*tcl.list_commandwords.at(4),
2323 myName, myEntryCl, NULL);
2326 //! Handle \c oo::class statements.
2327 static void tcl_command_OO_CLASS()
2330 QCString myNs, myName, myStr;
2333 tcl_scan *myScan = tcl.scan.at(0);
2335 tcl_codify_cmd("keyword",0);
2336 tcl_codify_cmd(NULL,1);
2337 tcl_codify_cmd("NULL",2);
2338 tcl_codify_cmd("NULL",3);
2339 tcl_codify_cmd("NULL",4);
2340 tcl_codify_cmd("NULL",5);
2341 tcl_name(myScan->ns,(*tcl.list_commandwords.at(4)).utf8(),myNs,myName);
2344 myName = myNs+"::"+myName;
2346 tcl.entry_current->section = Entry::CLASS_SEC;
2347 tcl.entry_current->name = myName;
2348 tcl.entry_current->startLine = tcl.line_command;
2349 tcl.entry_current->bodyLine = tcl.line_body0;
2350 tcl.entry_current->endBodyLine = tcl.line_body1;
2351 tcl.entry_main->addSubEntry(tcl.entry_current);
2352 //myEntryNs = tcl_entry_namespace(myName);
2353 tcl.cl.insert(myName,tcl.entry_current);
2354 myEntryCl = tcl.entry_current;
2355 myScan = tcl_scan_start(tcl.word_is,*tcl.list_commandwords.at(6),
2356 myName, myEntryCl, NULL);
2359 //! Handle \c oo::define statements.
2360 static void tcl_command_OO_DEFINE()
2363 QCString myNs, myName, myStr;
2365 tcl_scan *myScan = tcl.scan.at(0);
2367 tcl_codify_cmd("keyword",0);
2368 tcl_codify_cmd(NULL,1);
2369 tcl_codify_cmd("NULL",2);
2370 tcl_codify_cmd("NULL",3);
2371 tcl_name(myScan->ns,(*tcl.list_commandwords.at(2)).utf8(),myNs,myName);
2374 myName = myNs+"::"+myName;
2376 myEntryCl = tcl_entry_class(myName);
2377 myStr = (*tcl.list_commandwords.at(4)).utf8();
2379 // special cases first
2380 // oo::define classname method methodname args script
2381 // oo::define classname constructor argList bodyScript
2382 // oo::define classname destructor bodyScript
2383 unsigned int n =tcl.list_commandwords.count();
2384 if ((myStr == "method" && n == 11) ||
2385 (myStr == "constructor" && n == 9) ||
2386 (myStr == "destructor" && n == 7))
2388 for (unsigned int i = 4; i < n-1; i++)
2390 tcl_codify_cmd("NULL",i);
2394 tcl_name(myScan->ns,(*tcl.list_commandwords.at(n==11?6:4)).utf8(),myNs,myMethod);
2395 // code snippet taken from tcl_command_METHOD()/tcl_command_CONSTRUCTOR
2396 tcl.fn.remove(myMethod);
2397 tcl.entry_current->section = Entry::FUNCTION_SEC;
2398 tcl.entry_current->mtype = Method;
2399 tcl.entry_current->name = myMethod;
2400 tcl.entry_current->startLine = tcl.line_command;
2401 tcl.entry_current->bodyLine = tcl.line_body0;
2402 tcl.entry_current->endBodyLine = tcl.line_body1;
2403 tcl_protection(tcl.entry_current);
2406 tcl_command_ARGLIST(*tcl.list_commandwords.at(8));
2410 tcl_command_ARGLIST(*tcl.list_commandwords.at(6));
2412 if (myEntryCl) myEntryCl->addSubEntry(tcl.entry_current);
2413 tcl.fn.insert(myMethod,tcl.entry_current);
2414 myEntry = tcl.entry_current;
2415 myScan = tcl_scan_start('?',*tcl.list_commandwords.at(n-1),
2416 myNs, myEntryCl, myEntry);
2421 // Simply concat all arguments into a script.
2422 // Note: all documentation collected just before the
2423 // oo::define command is lost
2424 if (tcl.list_commandwords.count() > 5)
2426 for (uint i=5;i<tcl.list_commandwords.count();i++)
2428 myStr.append((*tcl.list_commandwords.at(i)).utf8());
2432 myScan = tcl_scan_start(tcl.word_is,myStr,myName,myEntryCl,NULL);
2436 //! Handle \c variable statements.
2437 static void tcl_command_VARIABLE(int inclass)
2440 QCString myNs, myName;
2442 tcl_scan *myScan = tcl.scan.at(0);
2444 tcl_codify_cmd("keyword",0);
2445 for (unsigned int i=1; i< tcl.list_commandwords.count(); i++)
2447 tcl_codify_cmd(NULL,i);
2449 tcl_name(myScan->ns,(*tcl.list_commandwords.at(2)).utf8(),myNs,myName);
2451 {// qualified variables go into namespace
2452 myEntry = tcl_entry_namespace(myNs);
2453 tcl.entry_current->stat = true;
2459 myEntry = myScan->entry_cl;
2460 tcl.entry_current->stat = false;
2464 myEntry = tcl_entry_namespace(myScan->ns);
2465 tcl.entry_current->stat = true;
2468 tcl.entry_current->section = Entry::VARIABLE_SEC;
2469 tcl.entry_current->name = myName;
2470 tcl.entry_current->startLine = tcl.line_command;
2471 tcl.entry_current->bodyLine = tcl.line_body0;
2472 tcl.entry_current->endBodyLine = tcl.line_body1;
2473 tcl_protection(tcl.entry_current);
2474 myEntry->addSubEntry(tcl.entry_current);
2475 tcl.entry_current = tcl_entry_new();
2478 //! Handling of command parsing.
2482 static void tcl_command(int what,const char *text)
2487 tcl.scan.at(0)->line1=yylineno;// current line in scan context
2488 tcl.line_body0=yylineno;// start line of command
2489 tcl_inf("<- %s\n",text);
2490 yy_push_state(COMMAND);
2491 tcl.list_commandwords.clear();
2492 tcl.string_command="";
2499 if (tcl.string_last.length())
2501 tcl.list_commandwords.append(tcl.string_last);
2506 tcl.list_commandwords.append(text);
2511 {// should not happen
2512 tcl_err("what %d\n",what);
2515 QCString myText = text;
2519 return; //TODO check on inside comment
2521 if (tcl.string_last != "")
2523 tcl.list_commandwords.append(tcl.string_last);
2529 QCString myStr = (*tcl.list_commandwords.at(0)).utf8();
2530 tcl_scan *myScanBackup=tcl.scan.at(0);
2532 Protection myProt = tcl.protection;
2534 if (tcl.list_commandwords.count() < 3)
2536 tcl_command_OTHER();
2539 // remove leading "::" and apply TCL_SUBST
2540 if (myStr.left(2)=="::") myStr = myStr.mid(2);
2541 if (tcl.config_subst.contains(myStr))
2543 myStr=tcl.config_subst[myStr].utf8();
2545 if (myStr=="private")
2547 tcl.protection = Private;
2550 else if (myStr=="protected")
2552 tcl.protection = Protected;
2555 else if (myStr=="public")
2557 tcl.protection = Public;
2562 tcl_codify_cmd("keyword",0);
2563 tcl_codify_cmd(NULL,1);
2564 tcl.list_commandwords.remove(tcl.list_commandwords.at(1));
2565 tcl.list_commandwords.remove(tcl.list_commandwords.at(0));
2566 if (tcl.list_commandwords.count()==1)
2568 tcl_scan *myScan = tcl.scan.at(0);
2569 myScan = tcl_scan_start(tcl.word_is,*tcl.list_commandwords.at(0),
2570 myScan->ns,myScan->entry_cl,myScan->entry_fn);
2571 myProt = tcl.protection;
2574 myStr = (*tcl.list_commandwords.at(0)).utf8();
2575 // remove leading "::" and apply TCL_SUBST
2576 if (myStr.left(2)=="::") myStr = myStr.mid(2);
2577 if (tcl.config_subst.contains(myStr))
2579 myStr=tcl.config_subst[myStr].utf8();
2584 if (tcl.list_commandwords.count() == 5)
2586 tcl.list_commandwords.append("");
2587 tcl.list_commandwords.append("");
2589 if (tcl.list_commandwords.count() != 7) {myLine=__LINE__;goto command_warn;}
2593 if (myStr=="method")
2595 if (tcl.list_commandwords.count() == 5)
2597 tcl.list_commandwords.append("");
2598 tcl.list_commandwords.append("");
2600 if (tcl.list_commandwords.count() != 7) {myLine=__LINE__;goto command_warn;}
2601 tcl_command_METHOD();
2604 if (myStr=="constructor")
2606 if (tcl.list_commandwords.count() != 5) {myLine=__LINE__;goto command_warn;}
2607 tcl_command_CONSTRUCTOR();
2610 if (myStr=="destructor")
2612 if (tcl.list_commandwords.count() != 3) {myLine=__LINE__;goto command_warn;}
2613 tcl_command_DESTRUCTOR();
2616 if (myStr=="namespace")
2618 if ((*tcl.list_commandwords.at(2)).utf8()=="eval")
2620 if (tcl.list_commandwords.count() < 7) {myLine=__LINE__;goto command_warn;}
2621 tcl_command_NAMESPACE();
2624 tcl_command_OTHER();
2627 if (myStr=="itcl::class")
2629 if (tcl.list_commandwords.count() != 5) {myLine=__LINE__;goto command_warn;}
2630 tcl_command_ITCL_CLASS();
2633 if (myStr=="itcl::body")
2635 if (tcl.list_commandwords.count() != 7) {myLine=__LINE__;goto command_warn;}
2636 tcl_command_METHOD();
2639 if (myStr=="oo::class")
2641 if ((*tcl.list_commandwords.at(2)).utf8()=="create")
2643 if (tcl.list_commandwords.count() != 7) {myLine=__LINE__;goto command_warn;}
2644 tcl_command_OO_CLASS();
2647 tcl_command_OTHER();
2650 if (myStr=="oo::define")
2652 if (tcl.list_commandwords.count() < 5) {myLine=__LINE__;goto command_warn;}
2653 tcl_command_OO_DEFINE();
2656 if (myStr=="variable")
2658 if (tcl.list_commandwords.count() < 3) {myLine=__LINE__;goto command_warn;}
2659 if (tcl.scan.at(0)->entry_fn == NULL)
2660 {// only parsed outside functions
2661 tcl_command_VARIABLE(tcl.scan.at(0)->entry_cl && tcl.scan.at(0)->entry_cl->name!="");
2665 if (myStr=="common")
2667 if (tcl.list_commandwords.count() < 3) {myLine=__LINE__;goto command_warn;}
2668 if (tcl.scan.at(0)->entry_fn == NULL)
2669 {// only parsed outside functions
2670 tcl_command_VARIABLE(0);
2674 if (myStr=="inherit" || myStr=="superclass")
2676 if (tcl.list_commandwords.count() < 3) {myLine=__LINE__;goto command_warn;}
2677 if (tcl.scan.at(0)->entry_cl && tcl.scan.at(0)->entry_cl->name!="")
2679 for (unsigned int i = 2; i < tcl.list_commandwords.count(); i = i + 2)
2681 tcl.scan.at(0)->entry_cl->extends->append(new BaseInfo((*tcl.list_commandwords.at(i)).utf8(),Public,Normal));
2687 * Start of internal tcl keywords
2688 * Ready: switch, eval, catch, if, for, foreach, while
2690 if (myStr=="switch")
2692 if (tcl.list_commandwords.count() < 5) {myLine=__LINE__;goto command_warn;}
2693 tcl_command_SWITCH();
2698 if (tcl.list_commandwords.count() < 3) {myLine=__LINE__;goto command_warn;}
2704 if (tcl.list_commandwords.count() < 3) {myLine=__LINE__;goto command_warn;}
2705 tcl_command_CATCH();
2710 if (tcl.list_commandwords.count() != 9) {myLine=__LINE__;goto command_warn;}
2714 if (myStr=="foreach")
2716 if (tcl.list_commandwords.count() < 7 || tcl.list_commandwords.count()%2==0) {myLine=__LINE__;goto command_warn;}
2717 tcl_command_FOREACH();
2721 if expr1 ?then? body1 elseif expr2 ?then? body2 elseif ... ?else? ?bodyN?
2723 if (myStr=="if" && tcl.list_commandwords.count() > 4)
2726 myType << "keyword" << "NULL" << "expr" << "NULL";
2727 char myState='x';// last word: e'x'pr 't'hen 'b'ody 'e'lse else'i'f..
2728 for (unsigned int i = 4; i < tcl.list_commandwords.count(); i = i + 2)
2730 QCString myStr=(*tcl.list_commandwords.at(i)).utf8();
2736 myType << "keyword" << "NULL";
2741 myType << "script" << "NULL";
2744 else if (myState=='t')
2747 myType << "script" << "NULL";
2749 else if (myState=='b')
2751 if (myStr=="elseif") {
2753 myType << "keyword" << "NULL";
2755 else if (myStr=="else" && i==tcl.list_commandwords.count()-3)
2758 myType << "keyword" << "NULL" << "script";
2759 i = tcl.list_commandwords.count();
2761 else if (i==tcl.list_commandwords.count()-1)
2765 i = tcl.list_commandwords.count();
2769 myLine=__LINE__;goto command_warn;
2772 else if (myState=='i')
2775 myType << "expr" << "NULL";
2778 if (myState != 'b') {myLine=__LINE__;goto command_warn;}
2779 tcl_command_IF(myType);
2784 if (tcl.list_commandwords.count() != 5) {myLine=__LINE__;goto command_warn;}
2785 tcl_command_WHILE();
2788 tcl_command_OTHER();
2790 command_warn:// print warning message because of wrong used syntax
2791 tcl_war("%d count=%d: %s\n",myLine,tcl.list_commandwords.count(),tcl.list_commandwords.join(" ").ascii());
2792 tcl_command_OTHER();
2793 command_end:// add remaining text to current context
2794 if (!myText.isEmpty())
2796 if(myScanBackup==tcl.scan.at(0))
2798 tcl_codify("comment",myText);
2802 tcl.scan.at(0)->after << "comment" << myText;
2805 tcl.list_commandwords.clear();
2807 tcl.protection = myProt;
2810 //----------------------------------------------------------------------------
2811 //! Common initializations.
2812 static void tcl_init()
2814 // Get values from option TCL_SUBST
2815 tcl.config_subst.clear();
2816 if (Config::instance()->get("TCL_SUBST"))
2818 QStrList myStrList = Config_getList("TCL_SUBST");
2819 const char *s=myStrList.first();
2823 int i=myStr.find('=');
2826 QCString myName=myStr.left(i).stripWhiteSpace();
2827 QCString myValue=myStr.right(myStr.length()-i-1).stripWhiteSpace();
2828 if (!myName.isEmpty() && !myValue.isEmpty())
2829 tcl_inf("TCL_SUBST: use '%s'\n",s);
2830 tcl.config_subst[myName] = myValue;
2832 s = myStrList.next();
2836 if (tcl.input_string.at(tcl.input_string.length()-1) == '\n')
2838 tcl.input_string[tcl.input_string.length()-1] = 0x1A;
2842 tcl.input_string += 0x1A;
2847 tcl.code_linenumbers=1;
2848 tcl.config_autobrief = Config_getBool("JAVADOC_AUTOBRIEF");
2849 tcl.input_position = 0;
2850 tcl.file_name = NULL;
2851 tcl.this_parser = NULL;
2855 tcl.bracket_level=0;
2856 tcl.bracket_quote=0;
2858 tcl.string_command="";
2859 tcl.string_commentline="";
2860 tcl.string_commentcodify="";
2861 tcl.string_comment = "";
2862 tcl.string_last = "";
2863 tcl.entry_main = NULL;
2864 tcl.entry_file = NULL;
2865 tcl.entry_current = NULL;
2866 tcl.entry_inside = NULL;
2867 tcl.list_commandwords.clear();
2873 tcl.protection = Public;
2874 tcl.memberdef = NULL;
2878 static void tcl_parse(const QCString ns, const QCString cls)
2882 tcl.entry_file = tcl_entry_new();
2883 tcl.entry_file->name = tcl.file_name;
2884 tcl.entry_file->section = Entry::SOURCE_SEC;
2885 tcl.entry_file->protection = Public;
2886 tcl.entry_main->addSubEntry(tcl.entry_file);
2887 Entry *myEntry=tcl_entry_new();
2889 tcl.entry_main->addSubEntry(myEntry);
2890 tcl.ns.insert("::",myEntry);
2891 tcl.entry_current = tcl_entry_new();
2893 tclscannerYYrestart( tclscannerYYin );
2896 myScan = new tcl_scan;
2897 myScan->type[0]=' ';myScan->type[1]='\n';
2898 myScan->after.clear();
2899 myScan->line0=yylineno;
2900 myScan->line1=yylineno;
2901 myScan->buffer_state=YY_CURRENT_BUFFER;
2903 myScan->entry_cl=tcl_entry_class(cls);
2904 myScan->entry_fn=NULL;
2905 tcl.entry_inside = tcl.entry_file;
2906 myScan->entry_scan = tcl.entry_inside;
2907 tcl.scan.insert(0,myScan);
2916 //! Parse text file and build up entry tree.
2917 void TclLanguageScanner::parseInput(const char *fileName,
2920 bool /*sameTranslationUnit*/,
2921 QStrList & /*filesInSameTranslationUnit*/)
2924 tcl_inf("%s\n",fileName);
2925 myFile.setName(fileName);
2926 if (!myFile.open(IO_ReadOnly)) return;
2927 if (strlen(input)<1) return;
2929 tcl.input_string = input;
2930 if (tcl.input_string.length()<1) return;
2931 printlex(yy_flex_debug, TRUE, __FILE__, fileName);
2933 msg("Parsing %s...\n",fileName);
2934 groupEnterFile(fileName,yylineno);
2938 tcl.file_name = fileName;
2939 tcl.this_parser = this;
2940 tcl.entry_main = root; /* toplevel entry */
2942 groupLeaveFile(tcl.file_name,yylineno);
2943 root->program.resize(0);
2945 printlex(yy_flex_debug, FALSE, __FILE__, fileName);
2948 //! Parse file and codify.
2949 void TclLanguageScanner::parseCode(CodeOutputInterface & codeOutIntf,
2950 const char * scopeName,
2951 const QCString & input,
2953 bool isExampleBlock,
2954 const char * exampleName,
2958 bool inlineFragment,
2959 MemberDef *memberDef,
2960 bool showLineNumbers,
2961 Definition *searchCtx,
2970 (void)inlineFragment;
2974 if (input.length()<1) return;
2975 printlex(yy_flex_debug, TRUE, __FILE__, fileDef ? fileDef->fileName().data(): NULL);
2976 tcl.input_string = input;
2982 if (memberDef->getClassDef())
2984 myCls = memberDef->getClassDef()->displayName();
2987 else if (memberDef->getNamespaceDef())
2989 myNs = memberDef->getNamespaceDef()->displayName();
2993 QString myStr="Codifying..";
3007 myStr+=memberDef->memberTypeName();
3009 myStr+=memberDef->qualifiedName();
3014 myStr+=fileDef->fileName();
3016 tcl_inf("%s (%d,%d) %d %d\n",myStr.ascii(),startLine,endLine,isExampleBlock,inlineFragment);
3017 //tcl_inf("%s\n"input.data());
3020 tcl_codify(NULL,input);
3024 tcl.collectXRefs = collectXRefs;
3025 tcl.memberdef = memberDef;
3026 tcl.code = &codeOutIntf;
3032 tcl.code_linenumbers = showLineNumbers;
3033 tcl.code_line=yylineno;
3034 tcl.code->startCodeLine(tcl.code_linenumbers);
3035 if (tcl.code_linenumbers)
3037 tcl.code->writeLineNumber(0,0,0,tcl.code_line);
3040 tcl.this_parser = NULL;
3041 tcl.entry_main = tcl_entry_new();
3042 tcl_parse(myNs,myCls);
3043 tcl.code->endCodeLine();
3049 printlex(yy_flex_debug, FALSE, __FILE__, fileDef ? fileDef->fileName().data(): NULL);
3052 bool TclLanguageScanner::needsPreprocessing(const QCString &extension)
3058 void TclLanguageScanner::resetCodeParserState()
3062 void TclLanguageScanner::parsePrototype(const char *text)
3067 static int yyread(char *buf,int max_size)
3072 while ( c < max_size && tcl.input_string.at(tcl.input_position) )
3074 *buf = tcl.input_string.at(tcl.input_position++) ;
3077 //printf("Read from=%d size=%d max=%d c=%d\n",tcl.input_position,strlen(&tcl.input_string[tcl.input_position]),max_size,c);
3081 //----------------------------------------------------------------------------
3083 // to avoid a warning
3089 #if !defined(YY_FLEX_SUBMINOR_VERSION)
3090 //----------------------------------------------------------------------------
3091 extern "C" { // some bogus code to keep the compiler happy
3092 void tclscannerYYdummy() { yy_flex_realloc(0,0); }