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.
17 %option never-interactive
18 %option case-insensitive
19 %option prefix="tclscannerYY"
28 #include <qstringlist.h>
44 #include "commentscan.h"
46 #include "tclscanner.h"
47 #include "outputlist.h"
48 #include "membername.h"
49 #include "searchindex.h"
50 #include "commentcnv.h"
53 #include "arguments.h"
54 #include "namespacedef.h"
58 #define YY_NO_UNISTD_H 1
60 #define MAX_INCLUDE_DEPTH 10
62 //! Application error.
64 printf("Error %d %s() at line %d! ",__LINE__,tcl.file_name.data(),yylineno); \
65 yy_push_state(ERROR); \
69 //! Application warning.
71 printf("Warning %d %s() at line %d: ",__LINE__,tcl.file_name.data(),yylineno); \
74 //! Application message.
76 if (0) printf("--- %.4d %d@%d: ",__LINE__,yylineno,yy_start_stack_ptr) && printf
80 if (0) printf("--- %.4d %d@%d: %s\n",__LINE__,yylineno,yy_start_stack_ptr,yytext);
82 // BEGIN of copy from tclUtil.c
83 // - Tcl_Interp removed
84 // - changes are marked with RZ
85 // #define's to adapt the code:
87 #define UCHAR (unsigned char)
90 #define ckalloc malloc
92 #define TclCopyAndCollapse(size,src,dest) memcpy(dest,src,size); *(dest+size)=0
94 CONST char *list, /* Points to the first byte of a string
95 * containing a Tcl list with zero or more
96 * elements (possibly in braces). */
97 int listLength, /* Number of bytes in the list's string. */
98 CONST char **elementPtr, /* Where to put address of first significant
99 * character in first element of list. */
100 CONST char **nextPtr, /* Fill in with location of character just
101 * after all white space following end of
102 * argument (next arg or end of list). */
103 int *sizePtr, /* If non-zero, fill in with size of
105 int *bracePtr) /* If non-zero, fill in with non-zero/zero to
106 * indicate that arg was/wasn't in braces. */
108 CONST char *p = list;
109 CONST char *elemStart; /* Points to first byte of first element. */
110 CONST char *limit; /* Points just after list's last byte. */
111 int openBraces = 0; /* Brace nesting level during parse. */
113 int size = 0; /* lint. */
117 * Skim off leading white space and check for an opening brace or quote.
118 * We treat embedded NULLs in the list as bytes belonging to a list
122 limit = (list + listLength);
123 while ((p < limit) && (isspace(UCHAR(*p))))
124 { /* INTL: ISO space. */
128 { /* no element found */
133 if (*p == '{') /* } to keep vi happy */
146 *bracePtr = openBraces;
150 * Find element's end (a space, close brace, or the end of the string).
158 * Open brace: don't treat specially unless the element is in
159 * braces. In this case, keep a nesting count.
170 * Close brace: if element is in braces, keep nesting count and
171 * quit when the last close brace is seen.
179 else if (openBraces == 1)
181 size = (int)(p - elemStart);
183 if ((p >= limit) || isspace(UCHAR(*p)))
184 { /* INTL: ISO space. */
189 * Garbage after the closing brace; return an error.
197 * Backslash: skip over everything up to the end of the backslash
202 //RZ Tcl_UtfBackslash(p, &numChars, NULL);
203 //RZ p += (numChars - 1);
208 * Space: ignore if element is in braces or quotes; otherwise
218 if ((openBraces == 0) && !inQuotes)
220 size = (int)(p - elemStart);
226 * Double-quote: if element is in quotes then terminate it.
232 size = (int)(p - elemStart);
234 if ((p >= limit) || isspace(UCHAR(*p)))
235 { /* INTL: ISO space */
240 * Garbage after the closing quote; return an error.
250 * End of list: terminate element.
263 size = (int)(p - elemStart);
267 while ((p < limit) && (isspace(UCHAR(*p))))
268 { /* INTL: ISO space. */
271 *elementPtr = elemStart;
281 CONST char *list, /* Pointer to string with list structure. */
282 int *argcPtr, /* Pointer to location to fill in with the
283 * number of elements in the list. */
284 CONST char ***argvPtr) /* Pointer to place to store pointer to array
285 * of pointers to list elements. */
287 CONST char **argv, *l, *element;
289 int length, size, i, result, elSize, brace;
292 * Figure out how much space to allocate. There must be enough space for
293 * both the array of pointers and also for a copy of the list. To estimate
294 * the number of pointers needed, count the number of space characters in
298 for (size = 2, l = list; *l != 0; l++)
300 if (isspace(UCHAR(*l)))
301 { /* INTL: ISO space. */
305 * Consecutive space can only count as a single list delimiter.
310 char next = *(l + 1);
317 if (isspace(UCHAR(next)))
318 { /* INTL: ISO space. */
325 length = (int)(l - list);
326 argv = (CONST char **) ckalloc((unsigned)
327 ((size * sizeof(char *)) + length + 1));
328 for (i = 0, p = ((char *) argv) + size*sizeof(char *);
331 CONST char *prevList = list;
333 result = TclFindElement(list, length, &element, &list,
335 length -= (int)(list - prevList);
336 if (result != TCL_OK)
338 ckfree((char *) argv);
347 ckfree((char *) argv);
353 memcpy(p, element, (size_t) elSize);
360 TclCopyAndCollapse(elSize, element, p);
372 void tcl_split_list(QString &str, QStringList &list)
378 if (str.left(1)=="{" && str.right(1)=="}")
380 str=str.mid(1,str.length()-2);
382 else if (str.left(1)=="\"" && str.right(1)=="\"")
384 str=str.mid(1,str.length()-2);
386 if (Tcl_SplitList(str.ascii(),&argc,&argv) != TCL_OK)
392 for (int i = 0; i < argc; i++)
394 list.append(argv[i]);
396 ckfree((char *) argv);
400 //! Structure containing information about current scan context.
403 char type[2]; // type of scan context: "\"" "{" "[" "?" " "
404 int line0; // start line of scan context
405 int line1; // end line of scan context
406 YY_BUFFER_STATE buffer_state; // value of scan context
407 QCString ns; // current namespace
408 Entry *entry_fn; // if set contains the current proc/method/constructor/destructor
409 Entry *entry_cl; // if set contain the current class
410 Entry *entry_scan; // current scan entry
411 Protection protection; // current protections state
412 QStringList after; // option/value list (options: NULL comment keyword script)
415 //* Structure containing all internal global variables.
418 CodeOutputInterface * code; // if set then we are codifying the file
419 int code_line; // current line of code
420 int code_linenumbers; // if true create line numbers in code
421 const char *code_font; // used font to codify
422 bool config_autobrief; // value of configuration option
423 QMap<QString,QString> config_subst; // map of configuration option values
424 QCString input_string; // file contents
425 int input_position; // position in file
426 QCString file_name; // name of used file
427 ParserInterface *this_parser; // myself
428 int command; // true if command was found
429 int comment; // set true if comment was scanned
430 int brace_level; // bookkeeping of braces
431 int bracket_level; // bookkeeping of brackets
432 int bracket_quote; // bookkeeping of quotes (toggles)
433 char word_is; // type of current word: "\"" "{" "[" "?" " "
434 int line_comment; // line number of comment
435 int line_commentline; // line number of comment after command
436 int line_command; // line number of command
437 int line_body0; // start line of body
438 int line_body1; // end line of body
439 QCString string_command; // contain current command
440 QCString string_commentline; // contain current comment after command
441 QCString string_commentcodify; // current comment string used in codifying
442 QCString string_comment; // contain current comment
443 QCString string_last; // contain last read word or part of word
444 QCString string; // temporary string value
445 Entry* entry_main; // top level entry
446 Entry* entry_file; // entry of current file
447 Entry* entry_current; // currently used entry
448 Entry* entry_inside; // contain entry of current scan context
449 QStringList list_commandwords; // list of command words
450 QList<tcl_scan> scan; // stack of scan contexts
451 QAsciiDict<Entry> ns; // all read namespace entries
452 QAsciiDict<Entry> cl; // all read class entries
453 QAsciiDict<Entry> fn; // all read function entries
454 QList<Entry> entry; // list of all created entries, will be deleted after codifying
455 Protection protection; // current protections state
456 MemberDef *memberdef; // contain current MemberDef when codifying
461 static int yyread(char *buf,int max_size);
462 static tcl_scan *tcl_scan_start(char type, QString content, QCString ns, Entry *entry_cls, Entry *entry_fn);
463 static void tcl_scan_end();
464 static void tcl_comment(int what,const char *text);
465 static void tcl_word(int what,const char *text);
466 static void tcl_command(int what,const char *text);
470 //! Create new entry.
471 // @return new initialised entry
472 Entry* tcl_entry_new()
474 Entry *myEntry = new Entry;
475 myEntry->section = Entry::EMPTY_SEC;
477 // myEntry->type = "";
479 // myEntry->doc = "";
480 myEntry->protection = Public;
481 // myEntry->mtype = Method;
482 // myEntry->virt = Normal;
483 // myEntry->stat = FALSE;
484 myEntry->fileName = tcl.file_name;
485 myEntry->lang = SrcLangExt_Tcl;
486 initGroupInfo(myEntry);
490 tcl.entry.insert(0,myEntry);
495 //! Set protection level.
496 void tcl_protection(Entry *entry)
498 if (entry->protection!=Public&&entry->protection!=Protected&&entry->protection!=Private)
500 entry->protection = tcl.protection;
502 if (entry->protection!=Protected&&entry->protection!=Private)
504 entry->protection = Public;
509 // @return 'ns' and 'name' of given current 'ns0' and 'name0'
510 static void tcl_name(const QCString &ns0, const QCString &name0, QCString &ns, QCString &name)
515 if (qstrncmp(name0.data(),"::",2)==0)
519 else if (ns0.length() && ns0 != " ")
521 myNm = ns0 + "::" + name0;
527 myStart = myNm.findRev("::");
535 ns = myNm.mid(0,myStart);
536 name = myNm.mid(myStart+2);
540 //! Check name. Strip namespace qualifiers from name0 if inside inlined code segment.
541 // @return 'ns' and 'name' of given current 'ns0' and 'name0'
542 static void tcl_name_SnippetAware(const QCString &ns0, const QCString &name0, QCString &ns, QCString &name)
544 // If we are inside an inlined code snippet then ns0
545 // already contains the complete namespace path.
546 // Any namespace qualifiers in name0 are redundant.
547 int i = name0.findRev("::");
548 if (i>=0 && tcl.memberdef)
550 tcl_name(ns0, name0.mid(i+2), ns, name);
554 tcl_name(ns0, name0, ns, name);
558 // Check and return namespace entry.
559 // @return namespace entry
560 Entry* tcl_entry_namespace(const QCString ns)
565 myEntry = tcl.ns.find(ns);
569 myEntry = tcl.ns.find("::");
573 myEntry = tcl_entry_new();
574 myEntry->section = Entry::NAMESPACE_SEC;
576 tcl.entry_main->addSubEntry(myEntry);
577 tcl.ns.insert(ns,myEntry);
582 // Check and return class entry.
583 // @return class entry
584 Entry* tcl_entry_class(const QCString cl)
587 if (!cl.length()) return(NULL);
589 myEntry = tcl.cl.find(cl);
592 myEntry = tcl_entry_new();
593 myEntry->section = Entry::CLASS_SEC;
595 tcl.entry_main->addSubEntry(myEntry);
596 tcl.cl.insert(cl,myEntry);
601 //! Check for keywords.
602 // @return 1 if keyword and 0 otherwise
603 static int tcl_keyword(QCString str)
605 static QStringList myList;
610 myList <<"append"<<"apply"<<"array"<<"auto_execok"<<"auto_import"<<"auto_load"<<"auto_mkindex"<<"auto_qualify"<<"auto_reset";
612 myList <<"catch"<<"cd"<<"close"<<"clock"<<"concat";
613 myList <<"eof"<<"eval"<<"exec"<<"exit"<<"expr";
614 myList <<"fblocked"<<"fconfigure"<<"file"<<"fileevent"<<"flush"<<"for"<<"foreach"<<"format";
615 myList <<"gets"<<"global";
617 myList <<"if"<<"incr"<<"info"<<"interp";
619 myList <<"lappend"<<"lassign"<<"lindex"<<"linsert"<<"llength"<<"load"<<"lrange"<<"lrepeat"<<"lreplace"<<"lreverse"<<"lset";
620 myList <<"namespace";
621 myList <<"package"<<"parray"<<"pid"<<"pkg_mkIndex"<<"proc"<<"puts"<<"pwd";
622 myList <<"registry"<<"rename"<<"return";
623 myList <<"scan"<<"set"<<"split"<<"string"<<"switch";
624 myList <<"tclLog"<<"tcl_endOfWord"<<"tcl_findLibrary"<<"tcl_startOfNextWord"<<"tcl_startOfPreviousWord"<<"tcl_wordBreakAfter"<<"tcl_wordBreakBefore"<<"tell"<<"time";
625 myList <<"unknown"<<"upvar";
626 myList <<"variable"<<"vwait";
628 myList <<"bell"<<"bind"<<"bindtags";
629 myList <<"clipboard"<<"console"<<"consoleinterp";
636 myList <<"pack"<<"place";
639 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";
640 myList <<"winfo"<<"wm";
641 myList <<"button"<<"canvas"<<"checkbutton"<<"entry"<<"frame"<<"image"<<"label"<<"labelframe"<<"listbox"<<"menu"<<"menubutton"<<"message"<<"panedwindow"<<"radiobutton"<<"scale"<<"scrollbar"<<"spinbox"<<"toplevel";
645 str=str.stripWhiteSpace();
646 if (str.left(2)=="::") {str=str.mid(2);}
647 if (myList.findIndex(str) != -1) return(1);
651 //! End codifying with special font class.
652 static void tcl_font_end()
654 if (!tcl.code) return;
657 tcl.code->endFontClass();
662 //! Codify 'str' with special font class 's'.
663 static void tcl_codify(const char *s,const char *str)
665 if (!tcl.code || !str) return;
666 if (s && qstrcmp(s,"NULL")!=0)
669 tcl.code->startFontClass(s);
672 char *tmp = (char *) malloc(strlen(str)+1);
680 while ((c=*p++) && c!='\n') {}
684 *(p-1)='\0'; // Dimitri: is this really needed?
685 // wtschueller: As far as I can see: yes.
686 // Deletes that \n that would produce ugly source listings otherwise.
687 // However, there may exist more sophisticated solutions.
688 tcl.code->codify(sp);
691 tcl.code->endFontClass();
693 tcl.code->endCodeLine();
694 tcl.code->startCodeLine(tcl.code_linenumbers);
695 if (tcl.code_linenumbers)
697 tcl.code->writeLineNumber(0,0,0,tcl.code_line);
701 tcl.code->startFontClass(tcl.code_font);
706 tcl.code->codify(sp);
715 //! Codify 'str' with special font class 's'.
716 static void tcl_codify(const char *s,const char *str)
718 if (tcl.code==NULL) return;
719 char *tmp= (char *) malloc(strlen(str)+1);
725 //! Codify 'str' with special font class 's'.
726 static void tcl_codify(const char *s,const QString &str)
728 if (tcl.code==NULL) return;
729 tcl_codify(s,str.utf8());
732 //! Codify 'str' with special font class 's'.
733 static void tcl_codify(const char *s,const QCString &str)
735 if (!tcl.code) return;
736 tcl_codify(s,str.data());
740 static void tcl_codify_cmd(const char *s,int i)
742 tcl_codify(s,(*tcl.list_commandwords.at(i)).utf8());
744 //! codify a string token
746 // codifies string according to type.
747 // Starts a new scan context if needed (*myScan==0 and type == "script").
748 // Returns NULL or the created scan context.
750 static tcl_scan *tcl_codify_token(tcl_scan *myScan, const QCString type, const QCString string)
756 myScan->after << type << string;
760 myScan->after << "NULL" << string;
765 if (qstrcmp(type, "script") == 0)
767 myScan = tcl.scan.at(0);
768 myScan = tcl_scan_start('?', string,
769 myScan->ns, myScan->entry_cl, myScan->entry_fn);
773 tcl_codify((const char*)type, string);
779 //-----------------------------------------------------------------------------
781 #define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size);
782 //-----------------------------------------------------------------------------
807 if (tcl.scan.count()<1)
810 tcl_err("Tcl parser stack empty! Parser error in file '%s'.\n",tcl.file_name.data());
813 else if (tcl.scan.count()==1)
814 {// exit, check on input?
828 tcl.line_comment=yylineno;
831 <TOP>({ws}|[\;\n])+ {
833 tcl_codify(NULL,yytext);
838 tcl.line_command=yylineno;
844 tcl_codify("comment",yytext);
848 tcl_codify("comment",yytext);
849 tcl_comment(2,yytext+1);
851 <COMMENT>"##".*\\\n {
853 tcl_codify("comment",yytext);
855 t = t.mid(2,t.length()-3);
857 tcl_comment(1,t.data());
858 yy_push_state(COMMENT_NL);
862 tcl_codify("comment",yytext);
863 tcl_comment(1,yytext+2);
865 <COMMENT>"#"[@\\]"code"\n[ \t]*[^#] {
868 tcl_codify("comment",t.left(7));
869 tcl_comment(2,"\n@code\n");
871 yy_push_state(COMMENT_CODE);
873 <COMMENT>"#"[@\\]"verbatim"\n[ \t]*[^#] {
876 tcl_codify("comment",t.left(11));
877 tcl_comment(2,"\n@verbatim\n");
879 yy_push_state(COMMENT_VERB);
883 tcl_codify("comment",yytext);
885 t = t.mid(1,t.length()-3);
887 tcl_comment(2,t.data());
888 yy_push_state(COMMENT_NL);
892 tcl_codify("comment",yytext);
893 tcl_comment(2,yytext+1);
898 t = t.mid(0,t.length()-1);
899 tcl_codify("comment",t.data());
900 t = t.mid(1,t.length());
901 tcl_comment(-2,t.data());
911 tcl_comment(-2,yytext);
915 <COMMENT_CODE>"#"[@\\]"endcode"\n {
918 t = t.left(t.length()-10);
919 tcl_comment(2,t.data());
920 tcl_comment(2,"\n@endcode\n");
928 <COMMENT_CODE>.*\x1A {
934 <COMMENT_VERB>"#"[@\\]"endverbatim"\n {
937 t = t.left(t.length()-14);
938 tcl_comment(2,t.data());
939 tcl_comment(2,"\n@endverbatim\n");
947 <COMMENT_VERB>.*\x1A {
955 tcl_codify("comment",yytext);
956 tcl_comment(2,yytext);
960 tcl_codify("comment",yytext);
961 tcl_comment(2,yytext);
970 <COMMENTLINE>.*\x1A {
975 <COMMENTLINE>[ \t]* {
977 tcl.string_commentcodify += yytext;
979 <COMMENTLINE>"#<".*\\\n {
981 tcl.string_commentcodify += yytext;
983 t = t.mid(2,t.length()-4);
985 tcl.string_commentline += t;
986 yy_push_state(COMMENTLINE_NL);
988 <COMMENTLINE>"#<".*\n {
990 tcl.string_commentcodify += yytext;
991 tcl.string_commentline += (yytext+2);
996 if (tcl.string_commentline.length())
998 tcl.entry_current->brief = tcl.string_commentline;
999 tcl.entry_current->briefLine = tcl.line_commentline;
1000 tcl.entry_current->briefFile = tcl.file_name;
1003 tcl_command(-1,tcl.string_commentcodify.data());
1004 tcl.string_commentline="";
1005 tcl.string_commentcodify="";
1008 <COMMENTLINE_NL>.*\\\n {
1010 tcl.string_commentcodify += yytext;
1012 t = t.left(t.length()-3);
1014 tcl.string_commentline += t;
1016 <COMMENTLINE_NL>.*\n {
1018 tcl.string_commentcodify += yytext;
1019 tcl.string_commentline += yytext;
1022 <COMMENTLINE_NL>.*\x1A {
1025 t = t.left(t.length()-1);
1026 tcl.string_commentcodify += t;
1027 tcl.string_commentline += t;
1032 <COMMAND>{ws}*[\;]{ws}*"#<" {
1034 tcl.string_commentcodify = yytext;
1035 tcl.string_commentcodify = tcl.string_commentcodify.left(tcl.string_commentcodify.length()-2);
1036 tcl.string_commentline = "";
1037 tcl.line_commentline = yylineno;
1038 tcl.line_body1=yylineno;
1041 yy_push_state(COMMENTLINE);
1043 <COMMAND>{ws}*\x1A {
1045 tcl.string_commentcodify = "";
1046 tcl.string_commentline = "";
1047 tcl.line_body1=yylineno;
1052 tcl.string_commentcodify = "";
1053 tcl.string_commentline = "";
1054 tcl.line_body1=yylineno;
1055 tcl_command(-1,yytext);
1059 tcl.string_commentcodify = "";
1060 tcl.string_commentline = "";
1061 tcl.line_body1=yylineno-1;
1062 tcl_command(-1,yytext);
1066 tcl_command(1,yytext);
1071 tcl.string_last = "{*}";
1072 tcl_word(0,&yytext[3]);
1074 <COMMAND>"\\"[\{\}\[\]\;\" \t] {
1077 tcl.string_last = "";
1083 if (yytext[0]=='{'||yytext[0]=='['||yytext[0]=='"') tcl.word_is = yytext[0];
1084 tcl.string_last = "";
1089 <WORD>"\\"[\{\}\[\]\;\" \t] {
1117 tcl_word(10,yytext);
1120 tcl_word(11,yytext);
1123 tcl_word(12,yytext);
1130 //! Start new scan context for given 'content'.
1131 // @return created new scan context.
1132 static tcl_scan *tcl_scan_start(char type, QString content, QCString ns, Entry *entry_cl, Entry *entry_fn)
1134 tcl_scan *myScan=tcl.scan.at(0);
1135 tcl_inf("line=%d type=%d '%s'\n",tcl.line_body0,type,content.ascii());
1137 myScan->line1=yylineno;
1140 myScan=new tcl_scan;
1141 myScan->type[0] =' ';
1142 myScan->type[1] = '\0';
1147 myScan->type[0] = type;
1150 if (content[0]=='"' && content[content.length()-1]=='"') myScan->type[0]='"';
1151 if (content[0]=='{' && content[content.length()-1]=='}') myScan->type[0]='{';
1152 if (content[0]=='[' && content[content.length()-1]==']') myScan->type[0]='[';
1154 if (myScan->type[0]!=' ')
1156 tcl_codify(NULL,&myScan->type[0]);
1157 content = content.mid(1,content.length()-2);
1159 content += (char)0x1A;// for detection end of scan context
1161 myScan->entry_cl = entry_cl;
1162 myScan->entry_fn = entry_fn;
1163 myScan->entry_scan = tcl.entry_current;
1164 myScan->buffer_state=yy_scan_string(content.ascii());
1165 myScan->line0=tcl.line_body0;
1166 myScan->line1=tcl.line_body1;
1167 myScan->after.clear();
1168 yylineno=myScan->line0;
1169 myScan->protection = tcl.protection;
1171 tcl.entry_inside = myScan->entry_scan;
1172 tcl.entry_current = tcl_entry_new();
1173 tcl.scan.insert(0,myScan);
1174 yy_switch_to_buffer(myScan->buffer_state);
1178 //! Close current scan context.
1179 static void tcl_scan_end()
1181 tcl_scan *myScan=tcl.scan.at(0);
1182 tcl_scan *myScan1=tcl.scan.at(1);
1183 tcl_inf("line=%d\n",myScan->line1);
1185 if (myScan->type[0]=='{') myScan->type[0]='}';
1186 if (myScan->type[0]=='[') myScan->type[0]=']';
1187 if (myScan->type[0]!=' ') tcl_codify(NULL,&myScan->type[0]);
1189 for (unsigned int i=0;i<myScan->after.count();i=i+2)
1191 if (myScan->after[i]=="script") {
1195 tcl_codify(myScan->after[i].utf8(),myScan->after[i+1].utf8());
1197 yy_delete_buffer(myScan->buffer_state);
1199 tcl.entry_inside = myScan1->entry_scan;
1200 yy_switch_to_buffer(myScan1->buffer_state);
1201 yylineno=myScan1->line1;
1202 tcl.protection = myScan1->protection;
1205 myScan1 = tcl_scan_start('?', myScan->after[myStart+1], myScan->ns, myScan->entry_cl, myScan->entry_fn);
1206 for (unsigned int i=myStart+2;i<myScan->after.count();i++)
1208 myScan1->after.append(myScan->after[i]);
1214 tcl.scan.removeFirst();
1218 //! Handling of word parsing.
1219 static void tcl_word(int what,const char *text)
1221 static char myList[1024]="";// nesting level list
1222 static int myLevel=0;// number of current nesting level
1223 static int myWhite=0;// set true when next char should be whitespace
1224 static char myWord;// internal state
1229 yy_push_state(WORD);
1234 case '"': myWord = text[0]; break;
1235 default: myWord = '.';
1241 case 1:// all other chars
1244 tcl_err("expected word separator: %s\n",text);
1260 tcl_inf("(\\\n) ?%s?\n",tcl.string_last.data());
1263 switch (myList[myLevel-1])
1275 tcl_inf("(\\\n) ?%s?\n",tcl.string_last.data());
1285 tcl_err("expected word separator: %s\n",text);
1288 switch (myList[myLevel-1])
1292 myList[myLevel++]='{';
1303 tcl_err("expected word separator: %s\n",text);
1306 switch (myList[myLevel-1])
1310 if (myLevel==0 && !tcl.code)
1324 tcl_err("expected word separator: %s\n",text);
1327 switch (myList[myLevel-1])
1334 myList[myLevel++]='[';
1342 tcl_err("expected word separator: %s\n",text);
1345 switch (myList[myLevel-1])
1361 tcl_err("expected word separator: %s\n",text);
1364 switch (myList[myLevel-1])
1369 myList[myLevel++]='"';
1386 tcl_inf("(%d) ?%s?\n",what,tcl.string_last.data());
1389 switch (myList[myLevel-1])
1401 tcl_inf("(.%d) ?%s?\n",what,tcl.string_last.data());
1418 tcl_inf("(%d) ?%s?\n",what,tcl.string_last.data());
1421 if (myLevel!=1 || myList[0] != '.')
1423 tcl_war("level=%d expected=%c\n",myLevel,myList[myLevel-1]);
1428 tcl_inf("(.%d) ?%s?\n",what,tcl.string_last.data());
1433 tcl_err("wrong state: %d\n",what);
1436 tcl.string_last += text;
1439 //! Handling of comment parsing.
1440 static void tcl_comment(int what,const char *text)
1443 { // begin of comment
1446 tcl_err("comment in comment\n");
1449 yy_push_state(COMMENT);
1450 tcl_inf("<- %s\n",text);
1451 tcl.string_comment="";
1455 { // start new comment
1458 tcl_comment(99,""); // inbody
1460 tcl.string_comment=text;
1467 tcl.string_comment+=text;
1470 else if (what==-1 || what == -2)
1471 { // end of comment without/with command
1474 tcl.string_last=tcl.string_comment;
1475 tcl_comment(100+what,"");
1479 tcl.string_last = "";
1480 tcl_inf("-> %s\n",(const char *)tcl.string_comment);
1483 tcl.string_comment="";
1486 else if (what==98 || what==99)
1487 { // 98=new 99=inbody
1488 if (tcl.this_parser && tcl.string_comment.length())
1490 tcl_inf("-> %s\n",(const char *)tcl.string_comment);
1493 int myLine=tcl.line_comment;
1496 Protection myProt=tcl.protection;
1499 myI.addArray("/*!",3);
1500 myI.addArray(tcl.string_comment.data(),tcl.string_comment.length());
1501 myI.addArray("*/",2);
1502 convertCppComments(&myI,&myO,tcl.file_name);
1503 myO.dropFromStart(3);
1504 myO.shrink(myO.curPos()-2);
1506 QCString myDoc = myO.data();
1508 { // inbody comment file or namespace or class or proc/method
1511 Entry myEntry0; // used to test parsing
1514 Entry *myEntry1=NULL;
1515 if (tcl.scan.at(0)->entry_fn)
1517 myEntry1=tcl.scan.at(0)->entry_fn;
1519 else if (tcl.scan.at(0)->entry_cl)
1521 myEntry1=tcl.scan.at(0)->entry_cl;
1526 while (parseCommentBlock(tcl.this_parser, &myEntry0, myDoc, tcl.file_name,
1527 myLine, FALSE, tcl.config_autobrief, FALSE, myProt, myPos, myNew))
1530 { // we need a new entry in this case
1532 myEntry = tcl_entry_new();
1533 parseCommentBlock(tcl.this_parser, myEntry, myDoc, tcl.file_name,
1534 myLine0, FALSE, tcl.config_autobrief, FALSE, myProt, myPos0, myNew);
1535 tcl.entry_inside->addSubEntry(myEntry);
1538 { // we can add to current entry in this case
1541 myEntry1=tcl_entry_namespace(tcl.scan.at(0)->ns);
1543 parseCommentBlock(tcl.this_parser, myEntry1, myDoc, tcl.file_name,
1544 myLine0, FALSE, tcl.config_autobrief, FALSE, myProt, myPos0, myNew);
1550 { // we need a new entry
1552 myEntry = tcl_entry_new();
1553 parseCommentBlock(tcl.this_parser, myEntry, myDoc, tcl.file_name,
1554 myLine0, FALSE, tcl.config_autobrief, FALSE, myProt, myPos0, myNew);
1555 tcl.entry_inside->addSubEntry(myEntry);
1558 { // we can add to current entry
1561 myEntry1=tcl_entry_namespace(tcl.scan.at(0)->ns);
1563 parseCommentBlock(tcl.this_parser, myEntry1, myDoc, tcl.file_name,
1564 myLine0, FALSE, tcl.config_autobrief, FALSE, myProt, myPos0, myNew);
1569 tcl.entry_current = tcl_entry_new();
1570 while (parseCommentBlock(tcl.this_parser, tcl.entry_current, myDoc,
1571 tcl.file_name, myLine, FALSE, tcl.config_autobrief, FALSE,
1572 myProt, myPos, myNew))
1576 tcl.entry_inside->addSubEntry(tcl.entry_current);
1577 tcl.entry_current = tcl_entry_new();
1581 tcl.entry_current->section = tcl.entry_inside->section;
1582 tcl.entry_current->name = tcl.entry_inside->name;
1587 tcl.entry_inside->addSubEntry(tcl.entry_current);
1588 tcl.entry_current = tcl_entry_new();
1592 tcl.entry_current->section = tcl.entry_inside->section;
1593 tcl.entry_current->name = tcl.entry_inside->name;
1596 if (tcl.protection != myProt)
1598 tcl.scan.at(0)->protection = tcl.protection = myProt;
1604 tcl_err("what %d\n",what);
1609 //! Parse given \c arglist .
1610 static void tcl_command_ARGLIST(QString &arglist)
1615 QString myArglist="";
1617 if (!tcl.entry_current->argList)
1619 tcl.entry_current->argList=new ArgumentList;
1621 tcl_split_list(arglist,myArgs);
1622 for (uint i=0;i<myArgs.count();i++)
1624 QStringList myArgs1;
1627 tcl_split_list(*myArgs.at(i),myArgs1);
1628 if (myArgs1.count()==2)
1630 myArg->name= (*myArgs1.at(0)).utf8();
1631 myArg->defval= (*myArgs1.at(1)).utf8();
1632 if (myArg->defval.isEmpty())
1634 myArg->defval = " ";
1636 myArglist += "?" + QCString(myArg->name) + "? ";
1640 myArg->name= (*myArgs.at(i)).utf8();
1641 myArglist += QString(myArg->name) + " ";
1643 tcl.entry_current->argList->append(myArg);
1645 arglist = myArglist;
1646 tcl.entry_current->args = arglist.utf8();
1650 static void tcl_codify_link(QCString name)
1652 if (tcl.code == NULL || name.isEmpty()) return;
1654 static QAsciiDict<MemberDef> fn;
1658 MemberNameSDict::Iterator mni(*Doxygen::memberNameSDict);
1659 MemberNameSDict::Iterator fni(*Doxygen::functionNameSDict);
1662 for (mni.toFirst();(mn=mni.current());++mni)
1664 MemberNameIterator mi(*mn);
1665 for (mi.toFirst();(md=mi.current());++mi)
1667 fn.insert(md->qualifiedName(),md);
1670 for (fni.toFirst();(mn=fni.current());++fni)
1672 MemberNameIterator fi(*mn);
1673 for (fi.toFirst();(md=fi.current());++fi)
1675 fn.insert(md->qualifiedName(),md);
1680 QCString myName=name;
1681 if (name.mid(0,2)=="::") // fully qualified global command
1683 myName = myName.mid(2);
1684 myDef = fn.find(myName);
1686 else // not qualified name
1688 QCString myName1=myName;
1690 myName1 = tcl.scan.at(0)->ns;
1691 if (myName1 == " " || myName1 == "")
1697 myName1 = myName1 + "::" + myName;
1699 myDef = fn.find(myName1); // search namespace command
1702 myDef = fn.find(myName); // search global command
1705 if (myDef != NULL) // documented command
1707 tcl.code->writeCodeLink(myDef->getReference().data(),
1708 myDef->getOutputFileBase().data(),
1709 myDef->anchor().data(),
1711 myDef->qualifiedName().data());
1714 myDef->addSourceReferencedBy(tcl.memberdef);
1715 tcl.memberdef->addSourceReferences(myDef);
1719 // walk the stack of scan contexts and find the enclosing method or proc
1720 for (i=0;i<tcl.scan.count();i++)
1722 callerEntry=tcl.scan.at(i)->entry_scan;
1723 if (callerEntry->mtype==Method && !callerEntry->name.isEmpty())
1728 if (i<tcl.scan.count())
1730 // enclosing method found
1731 QCString callerName = callerEntry->name;
1732 if (callerName.mid(0,2)=="::") // fully qualified global command
1734 callerName = callerName.mid(2);
1738 if (!(tcl.scan.at(0)->ns.stripWhiteSpace().isEmpty()))
1740 callerName = tcl.scan.at(0)->ns + "::" + callerEntry->name;
1743 MemberDef *callerDef=NULL;
1744 callerDef = fn.find(callerName);
1745 if (callerDef!=NULL && myDef!= NULL && tcl.collectXRefs)
1747 addDocCrossReference(callerDef,myDef);
1752 else if (tcl_keyword(myName)) // check keyword
1754 tcl_codify("keyword",name);
1758 tcl_codify(NULL,name); // something else
1763 //! scan general argument for brackets
1765 // parses (*tcl.list_commandwords.at(i)).utf8() and checks for brackets.
1766 // Starts a new scan context if needed (*myScan==0 and brackets found).
1767 // Returns NULL or the created scan context.
1769 static tcl_scan *tcl_command_ARG(tcl_scan *myScan, unsigned int i, bool ignoreOutermostBraces)
1772 bool insideQuotes=false;
1773 unsigned int insideBrackets=0;
1774 unsigned int insideBraces=0;
1775 myName = (*tcl.list_commandwords.at(i)).utf8();
1778 // handle white space
1779 myScan = tcl_codify_token(myScan, "NULL", myName);
1783 QCString myStr = "";
1785 for (j=0;j<myName.length();j++)
1787 QChar c = myName[j];
1788 bool backslashed = false;
1791 backslashed = myName[j-1]=='\\';
1793 // this is a state machine
1795 // internal state is myScan and insideXXX
1796 // these are the transitions:
1797 if (c=='[' && !backslashed && insideBraces==0)
1801 if (c==']' && !backslashed && insideBraces==0 && insideBrackets>0)
1805 if (c=='{' && !backslashed && !insideQuotes && !(ignoreOutermostBraces && j==0))
1809 if (c=='}' && !backslashed && !insideQuotes && insideBraces>0)
1813 if (c=='"' && !backslashed && insideBraces==0)
1815 insideQuotes=!insideQuotes;
1817 // all output, depending on state and input
1818 if (c=='[' && !backslashed && insideBrackets==1 && insideBraces==0)
1820 // the first opening bracket, output what we have so far
1822 myScan = tcl_codify_token(myScan, "NULL", myStr);
1825 else if (c==']' && !backslashed && insideBrackets==0 && insideBraces==0)
1827 // the last closing bracket, start recursion, switch to deferred
1828 myScan = tcl_codify_token(myScan, "script", myStr);
1837 if (i == 0 && myScan == NULL)
1839 tcl_codify_link(myStr);
1843 myScan = tcl_codify_token(myScan, "NULL", myStr);
1849 //! Handle internal tcl commands.
1850 // "eval arg ?arg ...?"
1851 static void tcl_command_EVAL()
1854 tcl_codify_cmd("keyword", 0);
1855 tcl_scan *myScan = tcl.scan.at(0);
1856 QCString myString = "";
1857 // we simply rescan the line without the eval
1858 // we include leading whitespace because tcl_scan_start will examine
1859 // the first char. If it finds a bracket it will assume one expression in brackets.
1860 // Example: eval [list set] [list NotInvoked] [Invoked NotInvoked]
1861 for (unsigned int i = 1; i < tcl.list_commandwords.count(); i++)
1863 myString += (*tcl.list_commandwords.at(i)).utf8();
1865 myScan = tcl_scan_start('?', myString,
1866 myScan->ns, myScan->entry_cl, myScan->entry_fn);
1869 //! Handle internal tcl commands.
1870 // switch ?options? string pattern body ?pattern body ...?
1871 // switch ?options? string {pattern body ?pattern body ...?}
1872 static void tcl_command_SWITCH()
1875 tcl_codify_cmd("keyword",0);
1876 tcl_codify_cmd(NULL,1);
1877 tcl_scan *myScan=NULL;
1880 // first: find the last option token
1881 unsigned int lastOptionIndex = 0;
1882 for (i = 2; i<tcl.list_commandwords.count(); i += 2)
1884 token = (*tcl.list_commandwords.at(i)).utf8();
1887 lastOptionIndex = i;
1890 if (token[0] == '-' && i - lastOptionIndex == 2)
1892 // options start with dash and should form a continuous chain
1893 lastOptionIndex = i;
1896 // second: eat up options
1897 for (i = 2; i <= lastOptionIndex; i++)
1899 myScan = tcl_command_ARG(myScan, i, false);
1901 // third: how many tokens are left?
1902 if (tcl.list_commandwords.count() - lastOptionIndex == 5)
1904 //printf("syntax: switch ?options? string {pattern body ?pattern body ...?}\n");
1905 myScan = tcl_command_ARG(myScan, lastOptionIndex + 1, false);
1906 myScan = tcl_command_ARG(myScan, lastOptionIndex + 2, false);
1907 myScan = tcl_command_ARG(myScan, lastOptionIndex + 3, false);
1908 // walk trough the list step by step
1909 // this way we can preserve whitespace
1910 bool inBraces = false;
1911 bool nextIsPattern = true;
1915 token = (*tcl.list_commandwords.at(lastOptionIndex + 4)).utf8();
1916 if (token[0] == '{')
1919 token = token.mid(1, token.length() - 2);
1920 myScan = tcl_codify_token(myScan, "NULL", QCString("{"));
1922 // ToDo: check if multibyte chars are handled correctly
1923 while (token.length() > 0)
1925 TclFindElement((const char*)token, token.length(), &elem, &next, &size, NULL);
1926 //printf("%s\nstart=%d, elem=%d, next=%d, size=%d, brace=%d\n",
1927 // (const char*) token, (const char*) token, elem, next, size, brace);
1929 // handle leading whitespace/opening brace/double quotes
1930 if (elem - token > 0)
1932 myScan = tcl_codify_token(myScan, "NULL", token.left(elem - token));
1934 // handle actual element without braces/double quotes
1937 myScan = tcl_codify_token(myScan, "NULL", token.mid(elem - token,size));
1938 //printf("pattern=%s\n",(const char*) token.mid(elem - token, size));
1941 myScan = tcl_codify_token(myScan, "script", token.mid(elem - token, size));
1942 //printf("script =%s\n", (const char*) token.mid(elem - token, size));
1944 // handle trailing whitespace/closing brace/double quotes
1945 if (next - elem - size > 0)
1947 myScan = tcl_codify_token(myScan, "NULL", token.mid(elem - token + size, next - elem - size));
1949 nextIsPattern = !nextIsPattern;
1950 token = token.mid(next - token);
1954 myScan = tcl_codify_token(myScan, "NULL", QCString("}"));
1958 tcl_war("Invalid switch syntax: last token is not a list of even elements.\n");
1959 //tcl_war("%s\n", tcl.list_commandwords.join(" ").ascii());
1962 else if ((tcl.list_commandwords.count() - lastOptionIndex > 6) &&
1963 ((tcl.list_commandwords.count() - lastOptionIndex-3) % 4 == 0))
1965 //printf("detected: switch ?options? string pattern body ?pattern body ...?\n");
1966 myScan = tcl_command_ARG(myScan, lastOptionIndex + 1, false);
1967 myScan = tcl_command_ARG(myScan, lastOptionIndex + 2, false);
1968 //printf("value=%s\n",(const char*) (*tcl.list_commandwords.at(lastOptionIndex + 2)).utf8());
1969 for (i = lastOptionIndex + 3; i < tcl.list_commandwords.count(); i += 4)
1971 myScan = tcl_command_ARG(myScan, i + 0, false); // whitespace
1972 myScan = tcl_command_ARG(myScan, i + 1, false); // pattern
1973 myScan = tcl_command_ARG(myScan, i + 2, false); // whitespace
1974 myScan = tcl_codify_token(myScan, "script", (*tcl.list_commandwords.at(i+3)).utf8()); // script
1975 //printf("pattern=%s\n",(const char*) (*tcl.list_commandwords.at(i+1)).utf8());
1976 //printf("script=%s\n",(const char*) (*tcl.list_commandwords.at(i+3)).utf8());
1981 // not properly detected syntax
1982 tcl_war("Invalid switch syntax: %d options followed by %d tokens.\n",
1983 lastOptionIndex / 2, (tcl.list_commandwords.count() - 1) / 2 - lastOptionIndex / 2);
1984 for (i = lastOptionIndex + 1; i <= tcl.list_commandwords.count(); i++)
1986 myScan = tcl_command_ARG(myScan, i, false);
1991 //! Handle internal tcl commands.
1992 // "catch script ?resultVarName? ?optionsVarName?"
1993 static void tcl_command_CATCH()
1996 tcl_codify_cmd("keyword", 0);
1997 tcl_codify_cmd(NULL, 1);
1998 tcl_scan *myScan = tcl.scan.at(0);
1999 myScan = tcl_scan_start('?', *tcl.list_commandwords.at(2),
2000 myScan->ns, myScan->entry_cl, myScan->entry_fn);
2001 for (unsigned int i = 3; i < tcl.list_commandwords.count(); i++)
2003 myScan = tcl_command_ARG(myScan, i, false);
2007 //! Handle internal tcl commands.
2008 // "if expr1 ?then? body1 elseif expr2 ?then? body2 elseif ... ?else? ?bodyN?"
2009 static void tcl_command_IF(QStringList type)
2012 tcl_codify_cmd("keyword",0);
2013 tcl_codify_cmd(NULL,1);
2014 tcl_scan *myScan = NULL;
2015 myScan = tcl_command_ARG(myScan, 2, true);
2016 for (unsigned int i = 3;i<tcl.list_commandwords.count();i++)
2018 if (type[i] == "expr")
2020 myScan = tcl_command_ARG(myScan, i, true);
2026 myScan->after << type[i] << tcl.list_commandwords[i];
2030 myScan=tcl.scan.at(0);
2031 myScan = tcl_scan_start('?',*tcl.list_commandwords.at(i),
2032 myScan->ns,myScan->entry_cl,myScan->entry_fn);
2037 //! Handle internal tcl commands.
2038 // "for start test next body"
2039 static void tcl_command_FOR()
2042 tcl_codify_cmd("keyword",0);
2043 tcl_codify_cmd(NULL,1);
2044 tcl_scan *myScan=tcl.scan.at(0);
2045 myScan = tcl_scan_start('?',*tcl.list_commandwords.at(2),
2046 myScan->ns,myScan->entry_cl,myScan->entry_fn);
2047 myScan->after << "NULL" << tcl.list_commandwords[3];
2048 myScan = tcl_command_ARG(myScan, 4, true);
2049 myScan->after << "NULL" << tcl.list_commandwords[5];
2050 myScan->after << "script" << tcl.list_commandwords[6];
2051 myScan->after << "NULL" << tcl.list_commandwords[7];
2052 myScan->after << "script" << tcl.list_commandwords[8];
2055 ///! Handle internal tcl commands.
2056 // "foreach varname list body" and
2057 // "foreach varlist1 list1 ?varlist2 list2 ...? body"
2058 static void tcl_command_FOREACH()
2062 tcl_scan *myScan=NULL;
2063 tcl_codify_cmd("keyword",0);
2064 for (i = 1;i<tcl.list_commandwords.count()-1;i++)
2066 myScan = tcl_command_ARG(myScan, i, false);
2070 myScan->after << "script" << tcl.list_commandwords[tcl.list_commandwords.count()-1];
2074 myScan=tcl.scan.at(0);
2075 myScan = tcl_scan_start('?',*tcl.list_commandwords.at(tcl.list_commandwords.count()-1),
2076 myScan->ns,myScan->entry_cl,myScan->entry_fn);
2080 ///! Handle internal tcl commands.
2081 // "while test body"
2082 static void tcl_command_WHILE()
2085 tcl_codify_cmd("keyword",0);
2086 tcl_codify_cmd(NULL,1);
2087 tcl_scan *myScan = NULL;
2088 myScan = tcl_command_ARG(myScan, 2, true);
2089 myScan = tcl_command_ARG(myScan, 3, false);
2092 myScan->after << "script" << tcl.list_commandwords[4];
2096 myScan=tcl.scan.at(0);
2097 myScan = tcl_scan_start('?',*tcl.list_commandwords.at(4),
2098 myScan->ns,myScan->entry_cl,myScan->entry_fn);
2102 //! Handle all other commands.
2103 // Create links of first command word or first command word inside [].
2104 static void tcl_command_OTHER()
2106 tcl_scan *myScan=NULL;
2107 for (unsigned int i=0; i< tcl.list_commandwords.count(); i++)
2109 myScan = tcl_command_ARG(myScan, i, false);
2113 //! Handle \c proc statements.
2114 static void tcl_command_PROC()
2117 QCString myNs, myName;
2120 tcl_scan *myScan = tcl.scan.at(0);
2122 tcl_codify_cmd("keyword",0);
2123 tcl_codify_cmd(NULL,1);
2124 tcl_codify_cmd(NULL,2);
2125 tcl_codify_cmd(NULL,3);
2126 tcl_codify_cmd(NULL,4);
2127 tcl_codify_cmd(NULL,5);
2128 tcl_name_SnippetAware(myScan->ns,(*tcl.list_commandwords.at(2)).utf8(),myNs,myName);
2131 myEntryNs = tcl_entry_namespace(myNs);
2135 myEntryNs = tcl_entry_namespace(myScan->ns);
2137 //why not needed here? tcl.fn.remove(myName);
2138 tcl.entry_current->section = Entry::FUNCTION_SEC;
2139 tcl.entry_current->mtype = Method;
2140 tcl.entry_current->name = myName;
2141 tcl.entry_current->startLine = tcl.line_command;
2142 tcl.entry_current->bodyLine = tcl.line_body0;
2143 tcl.entry_current->endBodyLine = tcl.line_body1;
2144 tcl_protection(tcl.entry_current);
2145 tcl_command_ARGLIST(*tcl.list_commandwords.at(4));
2146 myEntryNs->addSubEntry(tcl.entry_current);
2147 myEntry = tcl.entry_current;
2148 tcl.fn.insert(myName,myEntry);
2149 myScan = tcl_scan_start(tcl.word_is,*tcl.list_commandwords.at(6),
2150 myEntryNs->name,NULL,myEntry);
2153 //! Handle \c itcl::body statements and \c oo::define method and method inside \c itcl::class statements.
2154 static void tcl_command_METHOD()
2157 QCString myNs, myName;
2158 Entry *myEntryCl, *myEntry;
2159 tcl_scan *myScan = tcl.scan.at(0);
2161 tcl_codify_cmd("keyword",0);
2162 tcl_codify_cmd(NULL,1);
2163 tcl_codify_cmd(NULL,2);
2164 tcl_codify_cmd(NULL,3);
2165 tcl_codify_cmd(NULL,4);
2166 tcl_codify_cmd(NULL,5);
2167 tcl_name(myScan->ns,(*tcl.list_commandwords.at(2)).utf8(),myNs,myName);
2170 myEntryCl = tcl_entry_class(myNs);
2175 myEntryCl = myScan->entry_cl;
2177 // needed in case of more then one definition p.e. itcl::method and itcl::body
2179 tcl.fn.remove(myName);
2180 tcl.entry_current->section = Entry::FUNCTION_SEC;
2181 tcl.entry_current->mtype = Method;
2182 tcl.entry_current->name = myName;
2183 tcl.entry_current->startLine = tcl.line_command;
2184 tcl.entry_current->bodyLine = tcl.line_body0;
2185 tcl.entry_current->endBodyLine = tcl.line_body1;
2186 tcl_protection(tcl.entry_current);
2187 tcl_command_ARGLIST(*tcl.list_commandwords.at(4));
2188 myEntryCl->addSubEntry(tcl.entry_current);
2189 tcl.fn.insert(myName,tcl.entry_current);
2190 myEntry = tcl.entry_current;
2191 myScan = tcl_scan_start(tcl.word_is,*tcl.list_commandwords.at(6),
2192 myNs, myEntryCl, myEntry);
2195 //! Handle \c constructor statements inside class definitions.
2196 static void tcl_command_CONSTRUCTOR()
2199 QCString myNs, myName;
2200 Entry *myEntryCl, *myEntry;
2201 tcl_scan *myScan = tcl.scan.at(0);
2203 tcl_codify_cmd("keyword",0);
2204 tcl_codify_cmd(NULL,1);
2205 tcl_codify_cmd(NULL,2);
2206 tcl_codify_cmd(NULL,3);
2207 tcl_name(myScan->ns,(*tcl.list_commandwords.at(0)).utf8(),myNs,myName);
2210 myEntryCl = tcl_entry_class(myNs);
2215 myEntryCl = myScan->entry_cl;
2217 tcl.entry_current->section = Entry::FUNCTION_SEC;
2218 tcl.entry_current->mtype = Method;
2219 tcl.entry_current->name = myName;
2220 tcl.entry_current->startLine = tcl.line_command;
2221 tcl.entry_current->bodyLine = tcl.line_body0;
2222 tcl.entry_current->endBodyLine = tcl.line_body1;
2223 tcl_protection(tcl.entry_current);
2224 tcl_command_ARGLIST(*tcl.list_commandwords.at(2));
2225 if (myEntryCl) myEntryCl->addSubEntry(tcl.entry_current);
2226 myEntry = tcl.entry_current;
2227 tcl.fn.insert(myName,myEntry);
2228 myScan = tcl_scan_start(tcl.word_is,*tcl.list_commandwords.at(4),
2229 myNs, myEntryCl, myEntry);
2232 //! Handle \c destructor statements inside class definitions.
2233 static void tcl_command_DESTRUCTOR()
2236 QCString myNs, myName;
2237 Entry *myEntryCl, *myEntry;
2238 tcl_scan *myScan = tcl.scan.at(0);
2240 tcl_codify_cmd("keyword",0);
2241 tcl_codify_cmd(NULL,1);
2242 tcl_name(myScan->ns,(*tcl.list_commandwords.at(0)).utf8(),myNs,myName);
2245 myEntryCl = tcl_entry_class(myNs);
2250 myEntryCl = myScan->entry_cl;
2252 tcl.entry_current->section = Entry::FUNCTION_SEC;
2253 tcl.entry_current->mtype = Method;
2254 tcl.entry_current->name = myName;
2255 tcl.entry_current->startLine = tcl.line_command;
2256 tcl.entry_current->bodyLine = tcl.line_body0;
2257 tcl.entry_current->endBodyLine = tcl.line_body1;
2258 tcl_protection(tcl.entry_current);
2259 myEntryCl->addSubEntry(tcl.entry_current);
2260 myEntry = tcl.entry_current;
2261 tcl.fn.insert(myName,myEntry);
2262 myScan = tcl_scan_start(tcl.word_is,*tcl.list_commandwords.at(2),
2263 myNs, myEntryCl, myEntry);
2266 //! Handle \c namespace statements.
2267 static void tcl_command_NAMESPACE()
2270 QCString myNs, myName, myStr;
2271 //Entry *myEntryNs=NULL;
2272 tcl_scan *myScan = tcl.scan.at(0);
2274 tcl_codify_cmd("keyword",0);
2275 tcl_codify_cmd(NULL,1);
2276 tcl_codify_cmd("keyword",2);
2277 tcl_codify_cmd(NULL,3);
2278 tcl_codify_cmd(NULL,4);
2279 tcl_codify_cmd(NULL,5);
2280 tcl_name(myScan->ns,(*tcl.list_commandwords.at(4)).utf8(),myNs,myName);
2283 myName = myNs+"::"+myName;
2285 tcl.entry_current->section = Entry::NAMESPACE_SEC;
2286 tcl.entry_current->name = myName;
2287 tcl.entry_current->startLine = tcl.line_command;
2288 tcl.entry_current->bodyLine = tcl.line_body0;
2289 tcl.entry_current->endBodyLine = tcl.line_body1;
2290 tcl.entry_main->addSubEntry(tcl.entry_current);
2291 tcl.ns.insert(myName,tcl.entry_current);
2292 //myEntryNs = tcl.entry_current;
2293 myStr = (*tcl.list_commandwords.at(6)).utf8();
2294 if (tcl.list_commandwords.count() > 7)
2296 for (uint i=7;i<tcl.list_commandwords.count();i++)
2298 myStr.append((*tcl.list_commandwords.at(i)).utf8());
2302 myScan = tcl_scan_start(tcl.word_is,myStr, myName, NULL, NULL);
2305 //! Handle \c itcl::class statements.
2306 static void tcl_command_ITCL_CLASS()
2309 QCString myNs, myName;
2311 tcl_scan *myScan = tcl.scan.at(0);
2313 tcl_codify_cmd("keyword",0);
2314 tcl_codify_cmd(NULL,1);
2315 tcl_codify_cmd("NULL",2);
2316 tcl_codify_cmd("NULL",3);
2317 tcl_name(myScan->ns,(*tcl.list_commandwords.at(2)).utf8(),myNs,myName);
2320 myName = myNs+"::"+myName;
2322 tcl.entry_current->section = Entry::CLASS_SEC;
2323 tcl.entry_current->name = myName;
2324 tcl.entry_current->startLine = tcl.line_command;
2325 tcl.entry_current->bodyLine = tcl.line_body0;
2326 tcl.entry_current->endBodyLine = tcl.line_body1;
2327 tcl.entry_main->addSubEntry(tcl.entry_current);
2328 tcl.cl.insert(myName,tcl.entry_current);
2329 myEntryCl = tcl.entry_current;
2330 myScan = tcl_scan_start(tcl.word_is,*tcl.list_commandwords.at(4),
2331 myName, myEntryCl, NULL);
2334 //! Handle \c oo::class statements.
2335 static void tcl_command_OO_CLASS()
2338 QCString myNs, myName;
2341 tcl_scan *myScan = tcl.scan.at(0);
2343 tcl_codify_cmd("keyword",0);
2344 tcl_codify_cmd(NULL,1);
2345 tcl_codify_cmd("NULL",2);
2346 tcl_codify_cmd("NULL",3);
2347 tcl_codify_cmd("NULL",4);
2348 tcl_codify_cmd("NULL",5);
2349 tcl_name(myScan->ns,(*tcl.list_commandwords.at(4)).utf8(),myNs,myName);
2352 myName = myNs+"::"+myName;
2354 tcl.entry_current->section = Entry::CLASS_SEC;
2355 tcl.entry_current->name = myName;
2356 tcl.entry_current->startLine = tcl.line_command;
2357 tcl.entry_current->bodyLine = tcl.line_body0;
2358 tcl.entry_current->endBodyLine = tcl.line_body1;
2359 tcl.entry_main->addSubEntry(tcl.entry_current);
2360 //myEntryNs = tcl_entry_namespace(myName);
2361 tcl.cl.insert(myName,tcl.entry_current);
2362 myEntryCl = tcl.entry_current;
2363 myScan = tcl_scan_start(tcl.word_is,*tcl.list_commandwords.at(6),
2364 myName, myEntryCl, NULL);
2367 //! Handle \c oo::define statements.
2368 static void tcl_command_OO_DEFINE()
2371 QCString myNs, myName, myStr;
2373 tcl_scan *myScan = tcl.scan.at(0);
2375 tcl_codify_cmd("keyword",0);
2376 tcl_codify_cmd(NULL,1);
2377 tcl_codify_cmd("NULL",2);
2378 tcl_codify_cmd("NULL",3);
2379 tcl_name(myScan->ns,(*tcl.list_commandwords.at(2)).utf8(),myNs,myName);
2382 myName = myNs+"::"+myName;
2384 myEntryCl = tcl_entry_class(myName);
2385 myStr = (*tcl.list_commandwords.at(4)).utf8();
2387 // special cases first
2388 // oo::define classname method methodname args script
2389 // oo::define classname constructor argList bodyScript
2390 // oo::define classname destructor bodyScript
2391 unsigned int n =tcl.list_commandwords.count();
2392 if ((myStr == "method" && n == 11) ||
2393 (myStr == "constructor" && n == 9) ||
2394 (myStr == "destructor" && n == 7))
2396 for (unsigned int i = 4; i < n-1; i++)
2398 tcl_codify_cmd("NULL",i);
2402 tcl_name(myScan->ns,(*tcl.list_commandwords.at(n==11?6:4)).utf8(),myNs,myMethod);
2403 // code snippet taken from tcl_command_METHOD()/tcl_command_CONSTRUCTOR
2404 tcl.fn.remove(myMethod);
2405 tcl.entry_current->section = Entry::FUNCTION_SEC;
2406 tcl.entry_current->mtype = Method;
2407 tcl.entry_current->name = myMethod;
2408 tcl.entry_current->startLine = tcl.line_command;
2409 tcl.entry_current->bodyLine = tcl.line_body0;
2410 tcl.entry_current->endBodyLine = tcl.line_body1;
2411 tcl_protection(tcl.entry_current);
2414 tcl_command_ARGLIST(*tcl.list_commandwords.at(8));
2418 tcl_command_ARGLIST(*tcl.list_commandwords.at(6));
2420 if (myEntryCl) myEntryCl->addSubEntry(tcl.entry_current);
2421 tcl.fn.insert(myMethod,tcl.entry_current);
2422 myEntry = tcl.entry_current;
2423 myScan = tcl_scan_start('?',*tcl.list_commandwords.at(n-1),
2424 myNs, myEntryCl, myEntry);
2429 // Simply concat all arguments into a script.
2430 // Note: all documentation collected just before the
2431 // oo::define command is lost
2432 if (tcl.list_commandwords.count() > 5)
2434 for (uint i=5;i<tcl.list_commandwords.count();i++)
2436 myStr.append((*tcl.list_commandwords.at(i)).utf8());
2440 myScan = tcl_scan_start(tcl.word_is,myStr,myName,myEntryCl,NULL);
2444 //! Handle \c variable statements.
2445 static void tcl_command_VARIABLE(int inclass)
2448 QCString myNs, myName;
2450 tcl_scan *myScan = tcl.scan.at(0);
2452 tcl_codify_cmd("keyword",0);
2453 for (unsigned int i=1; i< tcl.list_commandwords.count(); i++)
2455 tcl_codify_cmd(NULL,i);
2457 tcl_name(myScan->ns,(*tcl.list_commandwords.at(2)).utf8(),myNs,myName);
2459 {// qualified variables go into namespace
2460 myEntry = tcl_entry_namespace(myNs);
2461 tcl.entry_current->stat = true;
2467 myEntry = myScan->entry_cl;
2468 tcl.entry_current->stat = false;
2472 myEntry = tcl_entry_namespace(myScan->ns);
2473 tcl.entry_current->stat = true;
2476 tcl.entry_current->section = Entry::VARIABLE_SEC;
2477 tcl.entry_current->name = myName;
2478 tcl.entry_current->startLine = tcl.line_command;
2479 tcl.entry_current->bodyLine = tcl.line_body0;
2480 tcl.entry_current->endBodyLine = tcl.line_body1;
2481 tcl_protection(tcl.entry_current);
2482 myEntry->addSubEntry(tcl.entry_current);
2483 tcl.entry_current = tcl_entry_new();
2486 //! Handling of command parsing.
2490 static void tcl_command(int what,const char *text)
2495 tcl.scan.at(0)->line1=yylineno;// current line in scan context
2496 tcl.line_body0=yylineno;// start line of command
2497 tcl_inf("<- %s\n",text);
2498 yy_push_state(COMMAND);
2499 tcl.list_commandwords.clear();
2500 tcl.string_command="";
2507 if (tcl.string_last.length())
2509 tcl.list_commandwords.append(tcl.string_last);
2514 tcl.list_commandwords.append(text);
2519 {// should not happen
2520 tcl_err("what %d\n",what);
2523 QCString myText = text;
2527 return; //TODO check on inside comment
2529 if (tcl.string_last != "")
2531 tcl.list_commandwords.append(tcl.string_last);
2537 QCString myStr = (*tcl.list_commandwords.at(0)).utf8();
2538 tcl_scan *myScanBackup=tcl.scan.at(0);
2540 Protection myProt = tcl.protection;
2542 if (tcl.list_commandwords.count() < 3)
2544 tcl_command_OTHER();
2547 // remove leading "::" and apply TCL_SUBST
2548 if (myStr.left(2)=="::") myStr = myStr.mid(2);
2549 if (tcl.config_subst.contains(myStr))
2551 myStr=tcl.config_subst[myStr].utf8();
2553 if (myStr=="private")
2555 tcl.protection = Private;
2558 else if (myStr=="protected")
2560 tcl.protection = Protected;
2563 else if (myStr=="public")
2565 tcl.protection = Public;
2570 tcl_codify_cmd("keyword",0);
2571 tcl_codify_cmd(NULL,1);
2572 tcl.list_commandwords.remove(tcl.list_commandwords.at(1));
2573 tcl.list_commandwords.remove(tcl.list_commandwords.at(0));
2574 if (tcl.list_commandwords.count()==1)
2576 tcl_scan *myScan = tcl.scan.at(0);
2577 myScan = tcl_scan_start(tcl.word_is,*tcl.list_commandwords.at(0),
2578 myScan->ns,myScan->entry_cl,myScan->entry_fn);
2579 myProt = tcl.protection;
2582 myStr = (*tcl.list_commandwords.at(0)).utf8();
2583 // remove leading "::" and apply TCL_SUBST
2584 if (myStr.left(2)=="::") myStr = myStr.mid(2);
2585 if (tcl.config_subst.contains(myStr))
2587 myStr=tcl.config_subst[myStr].utf8();
2592 if (tcl.list_commandwords.count() == 5)
2594 tcl.list_commandwords.append("");
2595 tcl.list_commandwords.append("");
2597 if (tcl.list_commandwords.count() != 7) {myLine=__LINE__;goto command_warn;}
2601 if (myStr=="method")
2603 if (tcl.list_commandwords.count() == 5)
2605 tcl.list_commandwords.append("");
2606 tcl.list_commandwords.append("");
2608 if (tcl.list_commandwords.count() != 7) {myLine=__LINE__;goto command_warn;}
2609 tcl_command_METHOD();
2612 if (myStr=="constructor")
2614 if (tcl.list_commandwords.count() != 5) {myLine=__LINE__;goto command_warn;}
2615 tcl_command_CONSTRUCTOR();
2618 if (myStr=="destructor")
2620 if (tcl.list_commandwords.count() != 3) {myLine=__LINE__;goto command_warn;}
2621 tcl_command_DESTRUCTOR();
2624 if (myStr=="namespace")
2626 if ((*tcl.list_commandwords.at(2)).utf8()=="eval")
2628 if (tcl.list_commandwords.count() < 7) {myLine=__LINE__;goto command_warn;}
2629 tcl_command_NAMESPACE();
2632 tcl_command_OTHER();
2635 if (myStr=="itcl::class")
2637 if (tcl.list_commandwords.count() != 5) {myLine=__LINE__;goto command_warn;}
2638 tcl_command_ITCL_CLASS();
2641 if (myStr=="itcl::body")
2643 if (tcl.list_commandwords.count() != 7) {myLine=__LINE__;goto command_warn;}
2644 tcl_command_METHOD();
2647 if (myStr=="oo::class")
2649 if ((*tcl.list_commandwords.at(2)).utf8()=="create")
2651 if (tcl.list_commandwords.count() != 7) {myLine=__LINE__;goto command_warn;}
2652 tcl_command_OO_CLASS();
2655 tcl_command_OTHER();
2658 if (myStr=="oo::define")
2660 if (tcl.list_commandwords.count() < 5) {myLine=__LINE__;goto command_warn;}
2661 tcl_command_OO_DEFINE();
2664 if (myStr=="variable")
2666 if (tcl.list_commandwords.count() < 3) {myLine=__LINE__;goto command_warn;}
2667 if (tcl.scan.at(0)->entry_fn == NULL)
2668 {// only parsed outside functions
2669 tcl_command_VARIABLE(tcl.scan.at(0)->entry_cl && tcl.scan.at(0)->entry_cl->name!="");
2673 if (myStr=="common")
2675 if (tcl.list_commandwords.count() < 3) {myLine=__LINE__;goto command_warn;}
2676 if (tcl.scan.at(0)->entry_fn == NULL)
2677 {// only parsed outside functions
2678 tcl_command_VARIABLE(0);
2682 if (myStr=="inherit" || myStr=="superclass")
2684 if (tcl.list_commandwords.count() < 3) {myLine=__LINE__;goto command_warn;}
2685 if (tcl.scan.at(0)->entry_cl && tcl.scan.at(0)->entry_cl->name!="")
2687 for (unsigned int i = 2; i < tcl.list_commandwords.count(); i = i + 2)
2689 tcl.scan.at(0)->entry_cl->extends->append(new BaseInfo((*tcl.list_commandwords.at(i)).utf8(),Public,Normal));
2695 * Start of internal tcl keywords
2696 * Ready: switch, eval, catch, if, for, foreach, while
2698 if (myStr=="switch")
2700 if (tcl.list_commandwords.count() < 5) {myLine=__LINE__;goto command_warn;}
2701 tcl_command_SWITCH();
2706 if (tcl.list_commandwords.count() < 3) {myLine=__LINE__;goto command_warn;}
2712 if (tcl.list_commandwords.count() < 3) {myLine=__LINE__;goto command_warn;}
2713 tcl_command_CATCH();
2718 if (tcl.list_commandwords.count() != 9) {myLine=__LINE__;goto command_warn;}
2722 if (myStr=="foreach")
2724 if (tcl.list_commandwords.count() < 7 || tcl.list_commandwords.count()%2==0) {myLine=__LINE__;goto command_warn;}
2725 tcl_command_FOREACH();
2729 if expr1 ?then? body1 elseif expr2 ?then? body2 elseif ... ?else? ?bodyN?
2731 if (myStr=="if" && tcl.list_commandwords.count() > 4)
2734 myType << "keyword" << "NULL" << "expr" << "NULL";
2735 char myState='x';// last word: e'x'pr 't'hen 'b'ody 'e'lse else'i'f..
2736 for (unsigned int i = 4; i < tcl.list_commandwords.count(); i = i + 2)
2738 QCString myStr=(*tcl.list_commandwords.at(i)).utf8();
2744 myType << "keyword" << "NULL";
2749 myType << "script" << "NULL";
2752 else if (myState=='t')
2755 myType << "script" << "NULL";
2757 else if (myState=='b')
2759 if (myStr=="elseif") {
2761 myType << "keyword" << "NULL";
2763 else if (myStr=="else" && i==tcl.list_commandwords.count()-3)
2766 myType << "keyword" << "NULL" << "script";
2767 i = tcl.list_commandwords.count();
2769 else if (i==tcl.list_commandwords.count()-1)
2773 i = tcl.list_commandwords.count();
2777 myLine=__LINE__;goto command_warn;
2780 else if (myState=='i')
2783 myType << "expr" << "NULL";
2786 if (myState != 'b') {myLine=__LINE__;goto command_warn;}
2787 tcl_command_IF(myType);
2792 if (tcl.list_commandwords.count() != 5) {myLine=__LINE__;goto command_warn;}
2793 tcl_command_WHILE();
2796 tcl_command_OTHER();
2798 command_warn:// print warning message because of wrong used syntax
2799 tcl_war("%d count=%d: %s\n",myLine,tcl.list_commandwords.count(),tcl.list_commandwords.join(" ").ascii());
2800 tcl_command_OTHER();
2801 command_end:// add remaining text to current context
2802 if (!myText.isEmpty())
2804 if(myScanBackup==tcl.scan.at(0))
2806 tcl_codify("comment",myText);
2810 tcl.scan.at(0)->after << "comment" << myText;
2813 tcl.list_commandwords.clear();
2815 tcl.protection = myProt;
2818 //----------------------------------------------------------------------------
2819 //! Common initializations.
2820 static void tcl_init()
2822 // Get values from option TCL_SUBST
2823 tcl.config_subst.clear();
2824 QStrList myStrList = Config_getList(TCL_SUBST);
2825 const char *s=myStrList.first();
2829 int i=myStr.find('=');
2832 QCString myName=myStr.left(i).stripWhiteSpace();
2833 QCString myValue=myStr.right(myStr.length()-i-1).stripWhiteSpace();
2834 if (!myName.isEmpty() && !myValue.isEmpty())
2835 tcl_inf("TCL_SUBST: use '%s'\n",s);
2836 tcl.config_subst[myName] = myValue;
2838 s = myStrList.next();
2841 if (tcl.input_string.at(tcl.input_string.length()-1) == 0x1A)
2844 else if (tcl.input_string.at(tcl.input_string.length()-1) == '\n')
2846 tcl.input_string[tcl.input_string.length()-1] = 0x1A;
2850 tcl.input_string += 0x1A;
2856 tcl.code_linenumbers=1;
2857 tcl.config_autobrief = Config_getBool(JAVADOC_AUTOBRIEF);
2858 tcl.input_position = 0;
2859 tcl.file_name = NULL;
2860 tcl.this_parser = NULL;
2864 tcl.bracket_level=0;
2865 tcl.bracket_quote=0;
2867 tcl.string_command="";
2868 tcl.string_commentline="";
2869 tcl.string_commentcodify="";
2870 tcl.string_comment = "";
2871 tcl.string_last = "";
2872 tcl.entry_main = NULL;
2873 tcl.entry_file = NULL;
2874 tcl.entry_current = NULL;
2875 tcl.entry_inside = NULL;
2876 tcl.list_commandwords.clear();
2882 tcl.protection = Public;
2883 tcl.memberdef = NULL;
2887 static void tcl_parse(const QCString ns, const QCString cls)
2891 tcl.entry_file = tcl_entry_new();
2892 tcl.entry_file->name = tcl.file_name;
2893 tcl.entry_file->section = Entry::SOURCE_SEC;
2894 tcl.entry_file->protection = Public;
2895 tcl.entry_main->addSubEntry(tcl.entry_file);
2896 Entry *myEntry=tcl_entry_new();
2898 tcl.entry_main->addSubEntry(myEntry);
2899 tcl.ns.insert("::",myEntry);
2900 tcl.entry_current = tcl_entry_new();
2902 tclscannerYYrestart( tclscannerYYin );
2905 myScan = new tcl_scan;
2906 myScan->type[0]=' ';myScan->type[1]='\n';
2907 myScan->after.clear();
2908 myScan->line0=yylineno;
2909 myScan->line1=yylineno;
2910 myScan->buffer_state=YY_CURRENT_BUFFER;
2912 myScan->entry_cl=tcl_entry_class(cls);
2913 myScan->entry_fn=NULL;
2914 tcl.entry_inside = tcl.entry_file;
2915 myScan->entry_scan = tcl.entry_inside;
2916 tcl.scan.insert(0,myScan);
2925 //! Parse text file and build up entry tree.
2926 void TclLanguageScanner::parseInput(const char *fileName,
2929 bool /*sameTranslationUnit*/,
2930 QStrList & /*filesInSameTranslationUnit*/)
2933 tcl_inf("%s\n",fileName);
2934 myFile.setName(fileName);
2935 if (!myFile.open(IO_ReadOnly)) return;
2936 if (strlen(input)<1) return;
2938 tcl.input_string = input;
2939 if (tcl.input_string.length()<1) return;
2940 printlex(yy_flex_debug, TRUE, __FILE__, fileName);
2942 msg("Parsing %s...\n",fileName);
2943 groupEnterFile(fileName,yylineno);
2947 tcl.file_name = fileName;
2948 tcl.this_parser = this;
2949 tcl.entry_main = root; /* toplevel entry */
2951 groupLeaveFile(tcl.file_name,yylineno);
2952 root->program.resize(0);
2954 printlex(yy_flex_debug, FALSE, __FILE__, fileName);
2957 //! Parse file and codify.
2958 void TclLanguageScanner::parseCode(CodeOutputInterface & codeOutIntf,
2959 const char * scopeName,
2960 const QCString & input,
2962 bool isExampleBlock,
2963 const char * exampleName,
2967 bool inlineFragment,
2968 MemberDef *memberDef,
2969 bool showLineNumbers,
2970 Definition *searchCtx,
2979 (void)inlineFragment;
2983 if (input.length()<1) return;
2984 printlex(yy_flex_debug, TRUE, __FILE__, fileDef ? fileDef->fileName().data(): NULL);
2985 tcl.input_string = input;
2991 if (memberDef->getClassDef())
2993 myCls = memberDef->getClassDef()->displayName();
2996 else if (memberDef->getNamespaceDef())
2998 myNs = memberDef->getNamespaceDef()->displayName();
3002 QString myStr="Codifying..";
3016 myStr+=memberDef->memberTypeName();
3018 myStr+=memberDef->qualifiedName();
3023 myStr+=fileDef->fileName();
3025 tcl_inf("%s (%d,%d) %d %d\n",myStr.ascii(),startLine,endLine,isExampleBlock,inlineFragment);
3026 //tcl_inf("%s\n"input.data());
3029 tcl_codify(NULL,input);
3033 tcl.collectXRefs = collectXRefs;
3034 tcl.memberdef = memberDef;
3035 tcl.code = &codeOutIntf;
3041 tcl.code_linenumbers = showLineNumbers;
3042 tcl.code_line=yylineno;
3043 tcl.code->startCodeLine(tcl.code_linenumbers);
3044 if (tcl.code_linenumbers)
3046 tcl.code->writeLineNumber(0,0,0,tcl.code_line);
3049 tcl.this_parser = NULL;
3050 tcl.entry_main = tcl_entry_new();
3051 tcl_parse(myNs,myCls);
3052 tcl.code->endCodeLine();
3058 printlex(yy_flex_debug, FALSE, __FILE__, fileDef ? fileDef->fileName().data(): NULL);
3061 bool TclLanguageScanner::needsPreprocessing(const QCString &extension)
3067 void TclLanguageScanner::resetCodeParserState()
3071 void TclLanguageScanner::parsePrototype(const char *text)
3076 static int yyread(char *buf,int max_size)
3081 while ( c < max_size && tcl.input_string.at(tcl.input_position) )
3083 *buf = tcl.input_string.at(tcl.input_position++) ;
3086 //printf("Read from=%d size=%d max=%d c=%d\n",tcl.input_position,strlen(&tcl.input_string[tcl.input_position]),max_size,c);
3090 //----------------------------------------------------------------------------
3092 // to avoid a warning
3098 #if !defined(YY_FLEX_SUBMINOR_VERSION)
3099 //----------------------------------------------------------------------------
3100 extern "C" { // some bogus code to keep the compiler happy
3101 void tclscannerYYdummy() { yy_flex_realloc(0,0); }