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 <qcstringlist.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(QCString &str, QCStringList &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);
388 if (Tcl_SplitList(str,&argc,&argv) != TCL_OK)
394 for (int i = 0; i < argc; i++)
396 list.append(argv[i]);
398 ckfree((char *) argv);
403 //! Structure containing information about current scan context.
406 char type[2]; // type of scan context: "\"" "{" "[" "?" " "
407 int line0; // start line of scan context
408 int line1; // end line of scan context
409 YY_BUFFER_STATE buffer_state; // value of scan context
410 QCString ns; // current namespace
411 Entry *entry_fn; // if set contains the current proc/method/constructor/destructor
412 Entry *entry_cl; // if set contain the current class
413 Entry *entry_scan; // current scan entry
414 Protection protection; // current protections state
415 QCStringList after; // option/value list (options: NULL comment keyword script)
418 //* Structure containing all internal global variables.
421 CodeOutputInterface * code; // if set then we are codifying the file
422 int code_line; // current line of code
423 int code_linenumbers; // if true create line numbers in code
424 const char *code_font; // used font to codify
425 bool config_autobrief; // value of configuration option
426 QMap<QString,QString> config_subst; // map of configuration option values
427 QCString input_string; // file contents
428 int input_position; // position in file
429 QCString file_name; // name of used file
430 ParserInterface *this_parser; // myself
431 int command; // true if command was found
432 int comment; // set true if comment was scanned
433 int brace_level; // bookkeeping of braces
434 int bracket_level; // bookkeeping of brackets
435 int bracket_quote; // bookkeeping of quotes (toggles)
436 char word_is; // type of current word: "\"" "{" "[" "?" " "
437 int line_comment; // line number of comment
438 int line_commentline; // line number of comment after command
439 int line_command; // line number of command
440 int line_body0; // start line of body
441 int line_body1; // end line of body
442 QCString string_command; // contain current command
443 QCString string_commentline; // contain current comment after command
444 QCString string_commentcodify; // current comment string used in codifying
445 QCString string_comment; // contain current comment
446 QCString string_last; // contain last read word or part of word
447 QCString string; // temporary string value
448 Entry* entry_main; // top level entry
449 Entry* entry_file; // entry of current file
450 Entry* entry_current; // currently used entry
451 Entry* entry_inside; // contain entry of current scan context
452 QCStringList list_commandwords; // list of command words
453 QList<tcl_scan> scan; // stack of scan contexts
454 QAsciiDict<Entry> ns; // all read namespace entries
455 QAsciiDict<Entry> cl; // all read class entries
456 QAsciiDict<Entry> fn; // all read function entries
457 QList<Entry> entry; // list of all created entries, will be deleted after codifying
458 Protection protection; // current protections state
459 MemberDef *memberdef; // contain current MemberDef when codifying
464 static int yyread(char *buf,int max_size);
465 static tcl_scan *tcl_scan_start(char type, QString content, QCString ns, Entry *entry_cls, Entry *entry_fn);
466 static void tcl_scan_end();
467 static void tcl_comment(int what,const char *text);
468 static void tcl_word(int what,const char *text);
469 static void tcl_command(int what,const char *text);
473 //! Create new entry.
474 // @return new initialised entry
475 Entry* tcl_entry_new()
477 Entry *myEntry = new Entry;
478 myEntry->section = Entry::EMPTY_SEC;
480 // myEntry->type = "";
482 // myEntry->doc = "";
483 myEntry->protection = Public;
484 // myEntry->mtype = Method;
485 // myEntry->virt = Normal;
486 // myEntry->stat = FALSE;
487 myEntry->fileName = tcl.file_name;
488 myEntry->lang = SrcLangExt_Tcl;
489 initGroupInfo(myEntry);
493 tcl.entry.insert(0,myEntry);
498 //! Set protection level.
499 void tcl_protection(Entry *entry)
501 if (entry->protection!=Public&&entry->protection!=Protected&&entry->protection!=Private)
503 entry->protection = tcl.protection;
505 if (entry->protection!=Protected&&entry->protection!=Private)
507 entry->protection = Public;
512 // @return 'ns' and 'name' of given current 'ns0' and 'name0'
513 static void tcl_name(const QCString &ns0, const QCString &name0, QCString &ns, QCString &name)
518 if (qstrncmp(name0.data(),"::",2)==0)
522 else if (ns0.length() && ns0 != " ")
524 myNm = ns0 + "::" + name0;
530 myStart = myNm.findRev("::");
538 ns = myNm.mid(0,myStart);
539 name = myNm.mid(myStart+2);
543 //! Check name. Strip namespace qualifiers from name0 if inside inlined code segment.
544 // @return 'ns' and 'name' of given current 'ns0' and 'name0'
545 static void tcl_name_SnippetAware(const QCString &ns0, const QCString &name0, QCString &ns, QCString &name)
547 // If we are inside an inlined code snippet then ns0
548 // already contains the complete namespace path.
549 // Any namespace qualifiers in name0 are redundant.
550 int i = name0.findRev("::");
551 if (i>=0 && tcl.memberdef)
553 tcl_name(ns0, name0.mid(i+2), ns, name);
557 tcl_name(ns0, name0, ns, name);
561 // Check and return namespace entry.
562 // @return namespace entry
563 Entry* tcl_entry_namespace(const QCString ns)
568 myEntry = tcl.ns.find(ns);
572 myEntry = tcl.ns.find("::");
576 myEntry = tcl_entry_new();
577 myEntry->section = Entry::NAMESPACE_SEC;
579 tcl.entry_main->addSubEntry(myEntry);
580 tcl.ns.insert(ns,myEntry);
585 // Check and return class entry.
586 // @return class entry
587 Entry* tcl_entry_class(const QCString cl)
590 if (!cl.length()) return(NULL);
592 myEntry = tcl.cl.find(cl);
595 myEntry = tcl_entry_new();
596 myEntry->section = Entry::CLASS_SEC;
598 tcl.entry_main->addSubEntry(myEntry);
599 tcl.cl.insert(cl,myEntry);
604 //! Check for keywords.
605 // @return 1 if keyword and 0 otherwise
606 static int tcl_keyword(QCString str)
608 static QCStringList myList;
613 myList <<"append"<<"apply"<<"array"<<"auto_execok"<<"auto_import"<<"auto_load"<<"auto_mkindex"<<"auto_qualify"<<"auto_reset";
615 myList <<"catch"<<"cd"<<"close"<<"clock"<<"concat";
616 myList <<"eof"<<"eval"<<"exec"<<"exit"<<"expr";
617 myList <<"fblocked"<<"fconfigure"<<"file"<<"fileevent"<<"flush"<<"for"<<"foreach"<<"format";
618 myList <<"gets"<<"global";
620 myList <<"if"<<"incr"<<"info"<<"interp";
622 myList <<"lappend"<<"lassign"<<"lindex"<<"linsert"<<"llength"<<"load"<<"lrange"<<"lrepeat"<<"lreplace"<<"lreverse"<<"lset";
623 myList <<"namespace";
624 myList <<"package"<<"parray"<<"pid"<<"pkg_mkIndex"<<"proc"<<"puts"<<"pwd";
625 myList <<"registry"<<"rename"<<"return";
626 myList <<"scan"<<"set"<<"split"<<"string"<<"switch";
627 myList <<"tclLog"<<"tcl_endOfWord"<<"tcl_findLibrary"<<"tcl_startOfNextWord"<<"tcl_startOfPreviousWord"<<"tcl_wordBreakAfter"<<"tcl_wordBreakBefore"<<"tell"<<"time";
628 myList <<"unknown"<<"upvar";
629 myList <<"variable"<<"vwait";
631 myList <<"bell"<<"bind"<<"bindtags";
632 myList <<"clipboard"<<"console"<<"consoleinterp";
639 myList <<"pack"<<"place";
642 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";
643 myList <<"winfo"<<"wm";
644 myList <<"button"<<"canvas"<<"checkbutton"<<"entry"<<"frame"<<"image"<<"label"<<"labelframe"<<"listbox"<<"menu"<<"menubutton"<<"message"<<"panedwindow"<<"radiobutton"<<"scale"<<"scrollbar"<<"spinbox"<<"toplevel";
648 str=str.stripWhiteSpace();
649 if (str.left(2)=="::") {str=str.mid(2);}
650 if (myList.findIndex(str) != -1) return(1);
654 //! End codifying with special font class.
655 static void tcl_font_end()
657 if (!tcl.code) return;
660 tcl.code->endFontClass();
665 //! Codify 'str' with special font class 's'.
666 static void tcl_codify(const char *s,const char *str)
668 if (!tcl.code || !str) return;
669 if (s && qstrcmp(s,"NULL")!=0)
672 tcl.code->startFontClass(s);
675 char *tmp = (char *) malloc(strlen(str)+1);
683 while ((c=*p++) && c!='\n') {}
687 *(p-1)='\0'; // Dimitri: is this really needed?
688 // wtschueller: As far as I can see: yes.
689 // Deletes that \n that would produce ugly source listings otherwise.
690 // However, there may exist more sophisticated solutions.
691 tcl.code->codify(sp);
694 tcl.code->endFontClass();
696 tcl.code->endCodeLine();
697 tcl.code->startCodeLine(tcl.code_linenumbers);
698 if (tcl.code_linenumbers)
700 tcl.code->writeLineNumber(0,0,0,tcl.code_line);
704 tcl.code->startFontClass(tcl.code_font);
709 if (*(p-2)==0x1A) *(p-2) = '\0'; // remove ^Z
710 tcl.code->codify(sp);
719 //! Codify 'str' with special font class 's'.
720 static void tcl_codify(const char *s,const char *str)
722 if (tcl.code==NULL) return;
723 char *tmp= (char *) malloc(strlen(str)+1);
729 //! Codify 'str' with special font class 's'.
730 static void tcl_codify(const char *s,const QString &str)
732 if (tcl.code==NULL) return;
736 //! Codify 'str' with special font class 's'.
737 static void tcl_codify(const char *s,const QCString &str)
739 if (!tcl.code) return;
740 tcl_codify(s,str.data());
744 static void tcl_codify_cmd(const char *s,int i)
746 tcl_codify(s,(*tcl.list_commandwords.at(i)));
748 //! codify a string token
750 // codifies string according to type.
751 // Starts a new scan context if needed (*myScan==0 and type == "script").
752 // Returns NULL or the created scan context.
754 static tcl_scan *tcl_codify_token(tcl_scan *myScan, const QCString type, const QCString string)
760 myScan->after << type << string;
764 myScan->after << "NULL" << string;
769 if (qstrcmp(type, "script") == 0)
771 myScan = tcl.scan.at(0);
772 myScan = tcl_scan_start('?', string,
773 myScan->ns, myScan->entry_cl, myScan->entry_fn);
777 tcl_codify((const char*)type, string);
783 //-----------------------------------------------------------------------------
785 #define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size);
786 //-----------------------------------------------------------------------------
811 if (tcl.scan.count()<1)
814 tcl_err("Tcl parser stack empty! Parser error in file '%s'.\n",tcl.file_name.data());
817 else if (tcl.scan.count()==1)
818 {// exit, check on input?
832 tcl.line_comment=yylineno;
835 <TOP>({ws}|[\;\n])+ {
837 tcl_codify(NULL,yytext);
842 tcl.line_command=yylineno;
848 tcl_codify("comment",yytext);
852 tcl_codify("comment",yytext);
853 tcl_comment(2,yytext+1);
855 <COMMENT>"##".*\\\n {
857 tcl_codify("comment",yytext);
859 t = t.mid(2,t.length()-3);
861 tcl_comment(1,t.data());
862 yy_push_state(COMMENT_NL);
866 tcl_codify("comment",yytext);
867 tcl_comment(1,yytext+2);
869 <COMMENT>"#"[@\\]"code"\n[ \t]*[^#] {
872 tcl_codify("comment",t.left(7));
873 tcl_comment(2,"\n@code\n");
875 yy_push_state(COMMENT_CODE);
877 <COMMENT>"#"[@\\]"verbatim"\n[ \t]*[^#] {
880 tcl_codify("comment",t.left(11));
881 tcl_comment(2,"\n@verbatim\n");
883 yy_push_state(COMMENT_VERB);
887 tcl_codify("comment",yytext);
889 t = t.mid(1,t.length()-3);
891 tcl_comment(2,t.data());
892 yy_push_state(COMMENT_NL);
896 tcl_codify("comment",yytext);
897 tcl_comment(2,yytext+1);
902 t = t.mid(0,t.length()-1);
903 tcl_codify("comment",t.data());
904 t = t.mid(1,t.length());
905 tcl_comment(-2,t.data());
915 tcl_comment(-2,yytext);
919 <COMMENT_CODE>"#"[@\\]"endcode"\n {
922 t = t.left(t.length()-10);
923 tcl_comment(2,t.data());
924 tcl_comment(2,"\n@endcode\n");
932 <COMMENT_CODE>.*\x1A {
938 <COMMENT_VERB>"#"[@\\]"endverbatim"\n {
941 t = t.left(t.length()-14);
942 tcl_comment(2,t.data());
943 tcl_comment(2,"\n@endverbatim\n");
951 <COMMENT_VERB>.*\x1A {
959 tcl_codify("comment",yytext);
960 tcl_comment(2,yytext);
964 tcl_codify("comment",yytext);
965 tcl_comment(2,yytext);
974 <COMMENTLINE>.*\x1A {
979 <COMMENTLINE>[ \t]* {
981 tcl.string_commentcodify += yytext;
983 <COMMENTLINE>"#<".*\\\n {
985 tcl.string_commentcodify += yytext;
987 t = t.mid(2,t.length()-4);
989 tcl.string_commentline += t;
990 yy_push_state(COMMENTLINE_NL);
992 <COMMENTLINE>"#<".*\n {
994 tcl.string_commentcodify += yytext;
995 tcl.string_commentline += (yytext+2);
1000 if (tcl.string_commentline.length())
1002 tcl.entry_current->brief = tcl.string_commentline;
1003 tcl.entry_current->briefLine = tcl.line_commentline;
1004 tcl.entry_current->briefFile = tcl.file_name;
1007 tcl_command(-1,tcl.string_commentcodify.data());
1008 tcl.string_commentline="";
1009 tcl.string_commentcodify="";
1012 <COMMENTLINE_NL>.*\\\n {
1014 tcl.string_commentcodify += yytext;
1016 t = t.left(t.length()-3);
1018 tcl.string_commentline += t;
1020 <COMMENTLINE_NL>.*\n {
1022 tcl.string_commentcodify += yytext;
1023 tcl.string_commentline += yytext;
1026 <COMMENTLINE_NL>.*\x1A {
1029 t = t.left(t.length()-1);
1030 tcl.string_commentcodify += t;
1031 tcl.string_commentline += t;
1036 <COMMAND>{ws}*[\;]{ws}*"#<" {
1038 tcl.string_commentcodify = yytext;
1039 tcl.string_commentcodify = tcl.string_commentcodify.left(tcl.string_commentcodify.length()-2);
1040 tcl.string_commentline = "";
1041 tcl.line_commentline = yylineno;
1042 tcl.line_body1=yylineno;
1045 yy_push_state(COMMENTLINE);
1047 <COMMAND>{ws}*\x1A {
1049 tcl.string_commentcodify = "";
1050 tcl.string_commentline = "";
1051 tcl.line_body1=yylineno;
1056 tcl.string_commentcodify = "";
1057 tcl.string_commentline = "";
1058 tcl.line_body1=yylineno;
1059 tcl_command(-1,yytext);
1063 tcl.string_commentcodify = "";
1064 tcl.string_commentline = "";
1065 tcl.line_body1=yylineno-1;
1066 tcl_command(-1,yytext);
1070 tcl_command(1,yytext);
1075 tcl.string_last = "{*}";
1076 tcl_word(0,&yytext[3]);
1078 <COMMAND>"\\"[\{\}\[\]\;\" \t] {
1081 tcl.string_last = "";
1087 if (yytext[0]=='{'||yytext[0]=='['||yytext[0]=='"') tcl.word_is = yytext[0];
1088 tcl.string_last = "";
1093 <WORD>"\\"[\{\}\[\]\;\" \t] {
1121 tcl_word(10,yytext);
1124 tcl_word(11,yytext);
1127 tcl_word(12,yytext);
1134 //! Start new scan context for given 'content'.
1135 // @return created new scan context.
1136 static tcl_scan *tcl_scan_start(char type, QString content, QCString ns, Entry *entry_cl, Entry *entry_fn)
1138 tcl_scan *myScan=tcl.scan.at(0);
1139 tcl_inf("line=%d type=%d '%s'\n",tcl.line_body0,type,content.ascii());
1141 myScan->line1=yylineno;
1144 myScan=new tcl_scan;
1145 myScan->type[0] =' ';
1146 myScan->type[1] = '\0';
1151 myScan->type[0] = type;
1154 if (content[0]=='"' && content[content.length()-1]=='"') myScan->type[0]='"';
1155 if (content[0]=='{' && content[content.length()-1]=='}') myScan->type[0]='{';
1156 if (content[0]=='[' && content[content.length()-1]==']') myScan->type[0]='[';
1158 if (myScan->type[0]!=' ')
1160 tcl_codify(NULL,&myScan->type[0]);
1161 content = content.mid(1,content.length()-2);
1163 content += (char)0x1A;// for detection end of scan context
1165 myScan->entry_cl = entry_cl;
1166 myScan->entry_fn = entry_fn;
1167 myScan->entry_scan = tcl.entry_current;
1168 myScan->buffer_state=yy_scan_string(content.ascii());
1169 myScan->line0=tcl.line_body0;
1170 myScan->line1=tcl.line_body1;
1171 myScan->after.clear();
1172 yylineno=myScan->line0;
1173 myScan->protection = tcl.protection;
1175 tcl.entry_inside = myScan->entry_scan;
1176 tcl.entry_current = tcl_entry_new();
1177 tcl.scan.insert(0,myScan);
1178 yy_switch_to_buffer(myScan->buffer_state);
1182 //! Close current scan context.
1183 static void tcl_scan_end()
1185 tcl_scan *myScan=tcl.scan.at(0);
1186 tcl_scan *myScan1=tcl.scan.at(1);
1187 tcl_inf("line=%d\n",myScan->line1);
1189 if (myScan->type[0]=='{') myScan->type[0]='}';
1190 if (myScan->type[0]=='[') myScan->type[0]=']';
1191 if (myScan->type[0]!=' ') tcl_codify(NULL,&myScan->type[0]);
1193 for (unsigned int i=0;i<myScan->after.count();i=i+2)
1195 if (myScan->after[i]=="script") {
1199 tcl_codify(myScan->after[i],myScan->after[i+1]);
1201 yy_delete_buffer(myScan->buffer_state);
1203 tcl.entry_inside = myScan1->entry_scan;
1204 yy_switch_to_buffer(myScan1->buffer_state);
1205 yylineno=myScan1->line1;
1206 tcl.protection = myScan1->protection;
1209 myScan1 = tcl_scan_start('?', myScan->after[myStart+1], myScan->ns, myScan->entry_cl, myScan->entry_fn);
1210 for (unsigned int i=myStart+2;i<myScan->after.count();i++)
1212 myScan1->after.append(myScan->after[i]);
1218 tcl.scan.removeFirst();
1222 //! Handling of word parsing.
1223 static void tcl_word(int what,const char *text)
1225 static char myList[1024]="";// nesting level list
1226 static int myLevel=0;// number of current nesting level
1227 static int myWhite=0;// set true when next char should be whitespace
1228 static char myWord;// internal state
1233 yy_push_state(WORD);
1238 case '"': myWord = text[0]; break;
1239 default: myWord = '.';
1245 case 1:// all other chars
1248 tcl_err("expected word separator: %s\n",text);
1264 tcl_inf("(\\\n) ?%s?\n",tcl.string_last.data());
1267 switch (myList[myLevel-1])
1279 tcl_inf("(\\\n) ?%s?\n",tcl.string_last.data());
1289 tcl_err("expected word separator: %s\n",text);
1292 switch (myList[myLevel-1])
1296 myList[myLevel++]='{';
1307 tcl_err("expected word separator: %s\n",text);
1310 switch (myList[myLevel-1])
1314 if (myLevel==0 && !tcl.code)
1328 tcl_err("expected word separator: %s\n",text);
1331 switch (myList[myLevel-1])
1338 myList[myLevel++]='[';
1346 tcl_err("expected word separator: %s\n",text);
1349 switch (myList[myLevel-1])
1365 tcl_err("expected word separator: %s\n",text);
1368 switch (myList[myLevel-1])
1373 myList[myLevel++]='"';
1390 tcl_inf("(%d) ?%s?\n",what,tcl.string_last.data());
1393 switch (myList[myLevel-1])
1405 tcl_inf("(.%d) ?%s?\n",what,tcl.string_last.data());
1422 tcl_inf("(%d) ?%s?\n",what,tcl.string_last.data());
1425 if (myLevel!=1 || myList[0] != '.')
1427 tcl_war("level=%d expected=%c\n",myLevel,myList[myLevel-1]);
1432 tcl_inf("(.%d) ?%s?\n",what,tcl.string_last.data());
1436 tcl_err("wrong state: %d\n",what);
1439 tcl.string_last += text;
1442 //! Handling of comment parsing.
1443 static void tcl_comment(int what,const char *text)
1446 { // begin of comment
1449 tcl_err("comment in comment\n");
1452 yy_push_state(COMMENT);
1453 tcl_inf("<- %s\n",text);
1454 tcl.string_comment="";
1458 { // start new comment
1461 tcl_comment(99,""); // inbody
1463 tcl.string_comment=text;
1470 tcl.string_comment+=text;
1473 else if (what==-1 || what == -2)
1474 { // end of comment without/with command
1477 tcl.string_last=tcl.string_comment;
1478 tcl_comment(100+what,"");
1482 tcl.string_last = "";
1483 tcl_inf("-> %s\n",(const char *)tcl.string_comment);
1486 tcl.string_comment="";
1489 else if (what==98 || what==99)
1490 { // 98=new 99=inbody
1491 if (tcl.this_parser && tcl.string_comment.length())
1493 tcl_inf("-> %s\n",(const char *)tcl.string_comment);
1496 int myLine=tcl.line_comment;
1499 Protection myProt=tcl.protection;
1502 myI.addArray("/*!",3);
1503 myI.addArray(tcl.string_comment.data(),tcl.string_comment.length());
1504 myI.addArray("*/",2);
1505 convertCppComments(&myI,&myO,tcl.file_name);
1506 myO.dropFromStart(3);
1507 myO.shrink(myO.curPos()-2);
1509 QCString myDoc = myO.data();
1511 { // inbody comment file or namespace or class or proc/method
1514 Entry myEntry0; // used to test parsing
1517 Entry *myEntry1=NULL;
1518 if (tcl.scan.at(0)->entry_fn)
1520 myEntry1=tcl.scan.at(0)->entry_fn;
1522 else if (tcl.scan.at(0)->entry_cl)
1524 myEntry1=tcl.scan.at(0)->entry_cl;
1529 while (parseCommentBlock(tcl.this_parser, &myEntry0, myDoc, tcl.file_name,
1530 myLine, FALSE, tcl.config_autobrief, FALSE, myProt, myPos, myNew))
1533 { // we need a new entry in this case
1535 myEntry = tcl_entry_new();
1536 parseCommentBlock(tcl.this_parser, myEntry, myDoc, tcl.file_name,
1537 myLine0, FALSE, tcl.config_autobrief, FALSE, myProt, myPos0, myNew);
1538 tcl.entry_inside->addSubEntry(myEntry);
1541 { // we can add to current entry in this case
1544 myEntry1=tcl_entry_namespace(tcl.scan.at(0)->ns);
1546 parseCommentBlock(tcl.this_parser, myEntry1, myDoc, tcl.file_name,
1547 myLine0, FALSE, tcl.config_autobrief, FALSE, myProt, myPos0, myNew);
1553 { // we need a new entry
1555 myEntry = tcl_entry_new();
1556 parseCommentBlock(tcl.this_parser, myEntry, myDoc, tcl.file_name,
1557 myLine0, FALSE, tcl.config_autobrief, FALSE, myProt, myPos0, myNew);
1558 tcl.entry_inside->addSubEntry(myEntry);
1561 { // we can add to current entry
1564 myEntry1=tcl_entry_namespace(tcl.scan.at(0)->ns);
1566 parseCommentBlock(tcl.this_parser, myEntry1, myDoc, tcl.file_name,
1567 myLine0, FALSE, tcl.config_autobrief, FALSE, myProt, myPos0, myNew);
1572 tcl.entry_current = tcl_entry_new();
1573 while (parseCommentBlock(tcl.this_parser, tcl.entry_current, myDoc,
1574 tcl.file_name, myLine, FALSE, tcl.config_autobrief, FALSE,
1575 myProt, myPos, myNew))
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;
1590 tcl.entry_inside->addSubEntry(tcl.entry_current);
1591 tcl.entry_current = tcl_entry_new();
1595 tcl.entry_current->section = tcl.entry_inside->section;
1596 tcl.entry_current->name = tcl.entry_inside->name;
1599 if (tcl.protection != myProt)
1601 tcl.scan.at(0)->protection = tcl.protection = myProt;
1607 tcl_err("what %d\n",what);
1612 //! Parse given \c arglist .
1613 static void tcl_command_ARGLIST(QCString &arglist)
1617 QCStringList myArgs;
1618 QCString myArglist="";
1620 if (!tcl.entry_current->argList)
1622 tcl.entry_current->argList=new ArgumentList;
1624 tcl_split_list(arglist,myArgs);
1625 for (uint i=0;i<myArgs.count();i++)
1627 QCStringList myArgs1;
1630 tcl_split_list(*myArgs.at(i),myArgs1);
1631 if (myArgs1.count()==2)
1633 myArg->name= (*myArgs1.at(0));
1634 myArg->defval= (*myArgs1.at(1));
1635 if (myArg->defval.isEmpty())
1637 myArg->defval = " ";
1639 myArglist += "?" + QCString(myArg->name) + "? ";
1643 myArg->name= (*myArgs.at(i));
1644 myArglist += myArg->name + " ";
1646 tcl.entry_current->argList->append(myArg);
1648 arglist = myArglist;
1649 tcl.entry_current->args = arglist;
1653 static void tcl_codify_link(QCString name)
1655 if (tcl.code == NULL || name.isEmpty()) return;
1657 static QAsciiDict<MemberDef> fn;
1661 MemberNameSDict::Iterator mni(*Doxygen::memberNameSDict);
1662 MemberNameSDict::Iterator fni(*Doxygen::functionNameSDict);
1665 for (mni.toFirst();(mn=mni.current());++mni)
1667 MemberNameIterator mi(*mn);
1668 for (mi.toFirst();(md=mi.current());++mi)
1670 fn.insert(md->qualifiedName(),md);
1673 for (fni.toFirst();(mn=fni.current());++fni)
1675 MemberNameIterator fi(*mn);
1676 for (fi.toFirst();(md=fi.current());++fi)
1678 fn.insert(md->qualifiedName(),md);
1683 QCString myName=name;
1684 if (name.mid(0,2)=="::") // fully qualified global command
1686 myName = myName.mid(2);
1687 myDef = fn.find(myName);
1689 else // not qualified name
1691 QCString myName1=myName;
1693 myName1 = tcl.scan.at(0)->ns;
1694 if (myName1 == " " || myName1 == "")
1700 myName1 = myName1 + "::" + myName;
1702 myDef = fn.find(myName1); // search namespace command
1705 myDef = fn.find(myName); // search global command
1708 if (myDef != NULL) // documented command
1710 tcl.code->writeCodeLink(myDef->getReference().data(),
1711 myDef->getOutputFileBase().data(),
1712 myDef->anchor().data(),
1714 myDef->qualifiedName().data());
1717 myDef->addSourceReferencedBy(tcl.memberdef);
1718 tcl.memberdef->addSourceReferences(myDef);
1722 // walk the stack of scan contexts and find the enclosing method or proc
1723 for (i=0;i<tcl.scan.count();i++)
1725 callerEntry=tcl.scan.at(i)->entry_scan;
1726 if (callerEntry->mtype==Method && !callerEntry->name.isEmpty())
1731 if (i<tcl.scan.count())
1733 // enclosing method found
1734 QCString callerName = callerEntry->name;
1735 if (callerName.mid(0,2)=="::") // fully qualified global command
1737 callerName = callerName.mid(2);
1741 if (!(tcl.scan.at(0)->ns.stripWhiteSpace().isEmpty()))
1743 callerName = tcl.scan.at(0)->ns + "::" + callerEntry->name;
1746 MemberDef *callerDef=NULL;
1747 callerDef = fn.find(callerName);
1748 if (callerDef!=NULL && myDef!= NULL && tcl.collectXRefs)
1750 addDocCrossReference(callerDef,myDef);
1755 else if (tcl_keyword(myName)) // check keyword
1757 tcl_codify("keyword",name);
1761 tcl_codify(NULL,name); // something else
1766 //! scan general argument for brackets
1768 // parses (*tcl.list_commandwords.at(i)) and checks for brackets.
1769 // Starts a new scan context if needed (*myScan==0 and brackets found).
1770 // Returns NULL or the created scan context.
1772 static tcl_scan *tcl_command_ARG(tcl_scan *myScan, unsigned int i, bool ignoreOutermostBraces)
1775 bool insideQuotes=false;
1776 unsigned int insideBrackets=0;
1777 unsigned int insideBraces=0;
1778 myName = (*tcl.list_commandwords.at(i));
1781 // handle white space
1782 myScan = tcl_codify_token(myScan, "NULL", myName);
1786 QCString myStr = "";
1788 for (j=0;j<myName.length();j++)
1790 QChar c = myName[j];
1791 bool backslashed = false;
1794 backslashed = myName[j-1]=='\\';
1796 // this is a state machine
1798 // internal state is myScan and insideXXX
1799 // these are the transitions:
1800 if (c=='[' && !backslashed && insideBraces==0)
1804 if (c==']' && !backslashed && insideBraces==0 && insideBrackets>0)
1808 if (c=='{' && !backslashed && !insideQuotes && !(ignoreOutermostBraces && j==0))
1812 if (c=='}' && !backslashed && !insideQuotes && insideBraces>0)
1816 if (c=='"' && !backslashed && insideBraces==0)
1818 insideQuotes=!insideQuotes;
1820 // all output, depending on state and input
1821 if (c=='[' && !backslashed && insideBrackets==1 && insideBraces==0)
1823 // the first opening bracket, output what we have so far
1825 myScan = tcl_codify_token(myScan, "NULL", myStr);
1828 else if (c==']' && !backslashed && insideBrackets==0 && insideBraces==0)
1830 // the last closing bracket, start recursion, switch to deferred
1831 myScan = tcl_codify_token(myScan, "script", myStr);
1840 if (i == 0 && myScan == NULL)
1842 tcl_codify_link(myStr);
1846 myScan = tcl_codify_token(myScan, "NULL", myStr);
1852 //! Handle internal tcl commands.
1853 // "eval arg ?arg ...?"
1854 static void tcl_command_EVAL()
1857 tcl_codify_cmd("keyword", 0);
1858 tcl_scan *myScan = tcl.scan.at(0);
1859 QCString myString = "";
1860 // we simply rescan the line without the eval
1861 // we include leading whitespace because tcl_scan_start will examine
1862 // the first char. If it finds a bracket it will assume one expression in brackets.
1863 // Example: eval [list set] [list NotInvoked] [Invoked NotInvoked]
1864 for (unsigned int i = 1; i < tcl.list_commandwords.count(); i++)
1866 myString += (*tcl.list_commandwords.at(i));
1868 myScan = tcl_scan_start('?', myString,
1869 myScan->ns, myScan->entry_cl, myScan->entry_fn);
1872 //! Handle internal tcl commands.
1873 // switch ?options? string pattern body ?pattern body ...?
1874 // switch ?options? string {pattern body ?pattern body ...?}
1875 static void tcl_command_SWITCH()
1878 tcl_codify_cmd("keyword",0);
1879 tcl_codify_cmd(NULL,1);
1880 tcl_scan *myScan=NULL;
1883 // first: find the last option token
1884 unsigned int lastOptionIndex = 0;
1885 for (i = 2; i<tcl.list_commandwords.count(); i += 2)
1887 token = (*tcl.list_commandwords.at(i));
1890 lastOptionIndex = i;
1893 if (token[0] == '-' && i - lastOptionIndex == 2)
1895 // options start with dash and should form a continuous chain
1896 lastOptionIndex = i;
1899 // second: eat up options
1900 for (i = 2; i <= lastOptionIndex; i++)
1902 myScan = tcl_command_ARG(myScan, i, false);
1904 // third: how many tokens are left?
1905 if (tcl.list_commandwords.count() - lastOptionIndex == 5)
1907 //printf("syntax: switch ?options? string {pattern body ?pattern body ...?}\n");
1908 myScan = tcl_command_ARG(myScan, lastOptionIndex + 1, false);
1909 myScan = tcl_command_ARG(myScan, lastOptionIndex + 2, false);
1910 myScan = tcl_command_ARG(myScan, lastOptionIndex + 3, false);
1911 // walk trough the list step by step
1912 // this way we can preserve whitespace
1913 bool inBraces = false;
1914 bool nextIsPattern = true;
1918 token = (*tcl.list_commandwords.at(lastOptionIndex + 4));
1919 if (token[0] == '{')
1922 token = token.mid(1, token.length() - 2);
1923 myScan = tcl_codify_token(myScan, "NULL", QCString("{"));
1925 // ToDo: check if multibyte chars are handled correctly
1926 while (token.length() > 0)
1928 TclFindElement((const char*)token, token.length(), &elem, &next, &size, NULL);
1929 //printf("%s\nstart=%d, elem=%d, next=%d, size=%d, brace=%d\n",
1930 // (const char*) token, (const char*) token, elem, next, size, brace);
1932 // handle leading whitespace/opening brace/double quotes
1933 if (elem - token > 0)
1935 myScan = tcl_codify_token(myScan, "NULL", token.left(elem - token));
1937 // handle actual element without braces/double quotes
1940 myScan = tcl_codify_token(myScan, "NULL", token.mid(elem - token,size));
1941 //printf("pattern=%s\n",(const char*) token.mid(elem - token, size));
1944 myScan = tcl_codify_token(myScan, "script", token.mid(elem - token, size));
1945 //printf("script =%s\n", (const char*) token.mid(elem - token, size));
1947 // handle trailing whitespace/closing brace/double quotes
1948 if (next - elem - size > 0)
1950 myScan = tcl_codify_token(myScan, "NULL", token.mid(elem - token + size, next - elem - size));
1952 nextIsPattern = !nextIsPattern;
1953 token = token.mid(next - token);
1957 myScan = tcl_codify_token(myScan, "NULL", QCString("}"));
1961 tcl_war("Invalid switch syntax: last token is not a list of even elements.\n");
1962 //tcl_war("%s\n", tcl.list_commandwords.join(" ").ascii());
1965 else if ((tcl.list_commandwords.count() - lastOptionIndex > 6) &&
1966 ((tcl.list_commandwords.count() - lastOptionIndex-3) % 4 == 0))
1968 //printf("detected: switch ?options? string pattern body ?pattern body ...?\n");
1969 myScan = tcl_command_ARG(myScan, lastOptionIndex + 1, false);
1970 myScan = tcl_command_ARG(myScan, lastOptionIndex + 2, false);
1971 //printf("value=%s\n",(const char*) (*tcl.list_commandwords.at(lastOptionIndex + 2)));
1972 for (i = lastOptionIndex + 3; i < tcl.list_commandwords.count(); i += 4)
1974 myScan = tcl_command_ARG(myScan, i + 0, false); // whitespace
1975 myScan = tcl_command_ARG(myScan, i + 1, false); // pattern
1976 myScan = tcl_command_ARG(myScan, i + 2, false); // whitespace
1977 myScan = tcl_codify_token(myScan, "script", (*tcl.list_commandwords.at(i+3))); // script
1978 //printf("pattern=%s\n",(const char*) (*tcl.list_commandwords.at(i+1))));
1979 //printf("script=%s\n",(const char*) (*tcl.list_commandwords.at(i+3)));
1984 // not properly detected syntax
1985 tcl_war("Invalid switch syntax: %d options followed by %d tokens.\n",
1986 lastOptionIndex / 2, (tcl.list_commandwords.count() - 1) / 2 - lastOptionIndex / 2);
1987 for (i = lastOptionIndex + 1; i <= tcl.list_commandwords.count(); i++)
1989 myScan = tcl_command_ARG(myScan, i, false);
1994 //! Handle internal tcl commands.
1995 // "catch script ?resultVarName? ?optionsVarName?"
1996 static void tcl_command_CATCH()
1999 tcl_codify_cmd("keyword", 0);
2000 tcl_codify_cmd(NULL, 1);
2001 tcl_scan *myScan = tcl.scan.at(0);
2002 myScan = tcl_scan_start('?', *tcl.list_commandwords.at(2),
2003 myScan->ns, myScan->entry_cl, myScan->entry_fn);
2004 for (unsigned int i = 3; i < tcl.list_commandwords.count(); i++)
2006 myScan = tcl_command_ARG(myScan, i, false);
2010 //! Handle internal tcl commands.
2011 // "if expr1 ?then? body1 elseif expr2 ?then? body2 elseif ... ?else? ?bodyN?"
2012 static void tcl_command_IF(QCStringList type)
2015 tcl_codify_cmd("keyword",0);
2016 tcl_codify_cmd(NULL,1);
2017 tcl_scan *myScan = NULL;
2018 myScan = tcl_command_ARG(myScan, 2, true);
2019 for (unsigned int i = 3;i<tcl.list_commandwords.count();i++)
2021 if (type[i] == "expr")
2023 myScan = tcl_command_ARG(myScan, i, true);
2029 myScan->after << type[i] << tcl.list_commandwords[i];
2033 myScan=tcl.scan.at(0);
2034 myScan = tcl_scan_start('?',*tcl.list_commandwords.at(i),
2035 myScan->ns,myScan->entry_cl,myScan->entry_fn);
2040 //! Handle internal tcl commands.
2041 // "for start test next body"
2042 static void tcl_command_FOR()
2045 tcl_codify_cmd("keyword",0);
2046 tcl_codify_cmd(NULL,1);
2047 tcl_scan *myScan=tcl.scan.at(0);
2048 myScan = tcl_scan_start('?',*tcl.list_commandwords.at(2),
2049 myScan->ns,myScan->entry_cl,myScan->entry_fn);
2050 myScan->after << "NULL" << tcl.list_commandwords[3];
2051 myScan = tcl_command_ARG(myScan, 4, true);
2052 myScan->after << "NULL" << tcl.list_commandwords[5];
2053 myScan->after << "script" << tcl.list_commandwords[6];
2054 myScan->after << "NULL" << tcl.list_commandwords[7];
2055 myScan->after << "script" << tcl.list_commandwords[8];
2058 ///! Handle internal tcl commands.
2059 // "foreach varname list body" and
2060 // "foreach varlist1 list1 ?varlist2 list2 ...? body"
2061 static void tcl_command_FOREACH()
2065 tcl_scan *myScan=NULL;
2066 tcl_codify_cmd("keyword",0);
2067 for (i = 1;i<tcl.list_commandwords.count()-1;i++)
2069 myScan = tcl_command_ARG(myScan, i, false);
2073 myScan->after << "script" << tcl.list_commandwords[tcl.list_commandwords.count()-1];
2077 myScan=tcl.scan.at(0);
2078 myScan = tcl_scan_start('?',*tcl.list_commandwords.at(tcl.list_commandwords.count()-1),
2079 myScan->ns,myScan->entry_cl,myScan->entry_fn);
2083 ///! Handle internal tcl commands.
2084 // "while test body"
2085 static void tcl_command_WHILE()
2088 tcl_codify_cmd("keyword",0);
2089 tcl_codify_cmd(NULL,1);
2090 tcl_scan *myScan = NULL;
2091 myScan = tcl_command_ARG(myScan, 2, true);
2092 myScan = tcl_command_ARG(myScan, 3, false);
2095 myScan->after << "script" << tcl.list_commandwords[4];
2099 myScan=tcl.scan.at(0);
2100 myScan = tcl_scan_start('?',*tcl.list_commandwords.at(4),
2101 myScan->ns,myScan->entry_cl,myScan->entry_fn);
2105 //! Handle all other commands.
2106 // Create links of first command word or first command word inside [].
2107 static void tcl_command_OTHER()
2109 tcl_scan *myScan=NULL;
2110 for (unsigned int i=0; i< tcl.list_commandwords.count(); i++)
2112 myScan = tcl_command_ARG(myScan, i, false);
2116 //! Handle \c proc statements.
2117 static void tcl_command_PROC()
2120 QCString myNs, myName;
2123 tcl_scan *myScan = tcl.scan.at(0);
2125 tcl_codify_cmd("keyword",0);
2126 tcl_codify_cmd(NULL,1);
2127 tcl_codify_cmd(NULL,2);
2128 tcl_codify_cmd(NULL,3);
2129 tcl_codify_cmd(NULL,4);
2130 tcl_codify_cmd(NULL,5);
2131 tcl_name_SnippetAware(myScan->ns,(*tcl.list_commandwords.at(2)),myNs,myName);
2134 myEntryNs = tcl_entry_namespace(myNs);
2138 myEntryNs = tcl_entry_namespace(myScan->ns);
2140 //why not needed here? tcl.fn.remove(myName);
2141 tcl.entry_current->section = Entry::FUNCTION_SEC;
2142 tcl.entry_current->mtype = Method;
2143 tcl.entry_current->name = myName;
2144 tcl.entry_current->startLine = tcl.line_command;
2145 tcl.entry_current->bodyLine = tcl.line_body0;
2146 tcl.entry_current->endBodyLine = tcl.line_body1;
2147 tcl_protection(tcl.entry_current);
2148 tcl_command_ARGLIST(*tcl.list_commandwords.at(4));
2149 myEntryNs->addSubEntry(tcl.entry_current);
2150 myEntry = tcl.entry_current;
2151 tcl.fn.insert(myName,myEntry);
2152 myScan = tcl_scan_start(tcl.word_is,*tcl.list_commandwords.at(6),
2153 myEntryNs->name,NULL,myEntry);
2156 //! Handle \c itcl::body statements and \c oo::define method and method inside \c itcl::class statements.
2157 static void tcl_command_METHOD()
2160 QCString myNs, myName;
2161 Entry *myEntryCl, *myEntry;
2162 tcl_scan *myScan = tcl.scan.at(0);
2164 tcl_codify_cmd("keyword",0);
2165 tcl_codify_cmd(NULL,1);
2166 tcl_codify_cmd(NULL,2);
2167 tcl_codify_cmd(NULL,3);
2168 tcl_codify_cmd(NULL,4);
2169 tcl_codify_cmd(NULL,5);
2170 tcl_name(myScan->ns,(*tcl.list_commandwords.at(2)),myNs,myName);
2173 myEntryCl = tcl_entry_class(myNs);
2178 myEntryCl = myScan->entry_cl;
2180 // needed in case of more then one definition p.e. itcl::method and itcl::body
2182 tcl.fn.remove(myName);
2183 tcl.entry_current->section = Entry::FUNCTION_SEC;
2184 tcl.entry_current->mtype = Method;
2185 tcl.entry_current->name = myName;
2186 tcl.entry_current->startLine = tcl.line_command;
2187 tcl.entry_current->bodyLine = tcl.line_body0;
2188 tcl.entry_current->endBodyLine = tcl.line_body1;
2189 tcl_protection(tcl.entry_current);
2190 tcl_command_ARGLIST(*tcl.list_commandwords.at(4));
2191 myEntryCl->addSubEntry(tcl.entry_current);
2192 tcl.fn.insert(myName,tcl.entry_current);
2193 myEntry = tcl.entry_current;
2194 myScan = tcl_scan_start(tcl.word_is,*tcl.list_commandwords.at(6),
2195 myNs, myEntryCl, myEntry);
2198 //! Handle \c constructor statements inside class definitions.
2199 static void tcl_command_CONSTRUCTOR()
2202 QCString myNs, myName;
2203 Entry *myEntryCl, *myEntry;
2204 tcl_scan *myScan = tcl.scan.at(0);
2206 tcl_codify_cmd("keyword",0);
2207 tcl_codify_cmd(NULL,1);
2208 tcl_codify_cmd(NULL,2);
2209 tcl_codify_cmd(NULL,3);
2210 tcl_name(myScan->ns,(*tcl.list_commandwords.at(0)),myNs,myName);
2213 myEntryCl = tcl_entry_class(myNs);
2218 myEntryCl = myScan->entry_cl;
2220 tcl.entry_current->section = Entry::FUNCTION_SEC;
2221 tcl.entry_current->mtype = Method;
2222 tcl.entry_current->name = myName;
2223 tcl.entry_current->startLine = tcl.line_command;
2224 tcl.entry_current->bodyLine = tcl.line_body0;
2225 tcl.entry_current->endBodyLine = tcl.line_body1;
2226 tcl_protection(tcl.entry_current);
2227 tcl_command_ARGLIST(*tcl.list_commandwords.at(2));
2228 if (myEntryCl) myEntryCl->addSubEntry(tcl.entry_current);
2229 myEntry = tcl.entry_current;
2230 tcl.fn.insert(myName,myEntry);
2231 myScan = tcl_scan_start(tcl.word_is,*tcl.list_commandwords.at(4),
2232 myNs, myEntryCl, myEntry);
2235 //! Handle \c destructor statements inside class definitions.
2236 static void tcl_command_DESTRUCTOR()
2239 QCString myNs, myName;
2240 Entry *myEntryCl, *myEntry;
2241 tcl_scan *myScan = tcl.scan.at(0);
2243 tcl_codify_cmd("keyword",0);
2244 tcl_codify_cmd(NULL,1);
2245 tcl_name(myScan->ns,(*tcl.list_commandwords.at(0)),myNs,myName);
2248 myEntryCl = tcl_entry_class(myNs);
2253 myEntryCl = myScan->entry_cl;
2255 tcl.entry_current->section = Entry::FUNCTION_SEC;
2256 tcl.entry_current->mtype = Method;
2257 tcl.entry_current->name = myName;
2258 tcl.entry_current->startLine = tcl.line_command;
2259 tcl.entry_current->bodyLine = tcl.line_body0;
2260 tcl.entry_current->endBodyLine = tcl.line_body1;
2261 tcl_protection(tcl.entry_current);
2262 myEntryCl->addSubEntry(tcl.entry_current);
2263 myEntry = tcl.entry_current;
2264 tcl.fn.insert(myName,myEntry);
2265 myScan = tcl_scan_start(tcl.word_is,*tcl.list_commandwords.at(2),
2266 myNs, myEntryCl, myEntry);
2269 //! Handle \c namespace statements.
2270 static void tcl_command_NAMESPACE()
2273 QCString myNs, myName, myStr;
2274 //Entry *myEntryNs=NULL;
2275 tcl_scan *myScan = tcl.scan.at(0);
2277 tcl_codify_cmd("keyword",0);
2278 tcl_codify_cmd(NULL,1);
2279 tcl_codify_cmd("keyword",2);
2280 tcl_codify_cmd(NULL,3);
2281 tcl_codify_cmd(NULL,4);
2282 tcl_codify_cmd(NULL,5);
2283 tcl_name(myScan->ns,(*tcl.list_commandwords.at(4)),myNs,myName);
2286 myName = myNs+"::"+myName;
2288 tcl.entry_current->section = Entry::NAMESPACE_SEC;
2289 tcl.entry_current->name = myName;
2290 tcl.entry_current->startLine = tcl.line_command;
2291 tcl.entry_current->bodyLine = tcl.line_body0;
2292 tcl.entry_current->endBodyLine = tcl.line_body1;
2293 tcl.entry_main->addSubEntry(tcl.entry_current);
2294 tcl.ns.insert(myName,tcl.entry_current);
2295 //myEntryNs = tcl.entry_current;
2296 myStr = (*tcl.list_commandwords.at(6));
2297 if (tcl.list_commandwords.count() > 7)
2299 for (uint i=7;i<tcl.list_commandwords.count();i++)
2301 myStr.append((*tcl.list_commandwords.at(i)));
2305 myScan = tcl_scan_start(tcl.word_is,myStr, myName, NULL, NULL);
2308 //! Handle \c itcl::class statements.
2309 static void tcl_command_ITCL_CLASS()
2312 QCString myNs, myName;
2314 tcl_scan *myScan = tcl.scan.at(0);
2316 tcl_codify_cmd("keyword",0);
2317 tcl_codify_cmd(NULL,1);
2318 tcl_codify_cmd("NULL",2);
2319 tcl_codify_cmd("NULL",3);
2320 tcl_name(myScan->ns,(*tcl.list_commandwords.at(2)),myNs,myName);
2323 myName = myNs+"::"+myName;
2325 tcl.entry_current->section = Entry::CLASS_SEC;
2326 tcl.entry_current->name = myName;
2327 tcl.entry_current->startLine = tcl.line_command;
2328 tcl.entry_current->bodyLine = tcl.line_body0;
2329 tcl.entry_current->endBodyLine = tcl.line_body1;
2330 tcl.entry_main->addSubEntry(tcl.entry_current);
2331 tcl.cl.insert(myName,tcl.entry_current);
2332 myEntryCl = tcl.entry_current;
2333 myScan = tcl_scan_start(tcl.word_is,*tcl.list_commandwords.at(4),
2334 myName, myEntryCl, NULL);
2337 //! Handle \c oo::class statements.
2338 static void tcl_command_OO_CLASS()
2341 QCString myNs, myName;
2344 tcl_scan *myScan = tcl.scan.at(0);
2346 tcl_codify_cmd("keyword",0);
2347 tcl_codify_cmd(NULL,1);
2348 tcl_codify_cmd("NULL",2);
2349 tcl_codify_cmd("NULL",3);
2350 tcl_codify_cmd("NULL",4);
2351 tcl_codify_cmd("NULL",5);
2352 tcl_name(myScan->ns,(*tcl.list_commandwords.at(4)),myNs,myName);
2355 myName = myNs+"::"+myName;
2357 tcl.entry_current->section = Entry::CLASS_SEC;
2358 tcl.entry_current->name = myName;
2359 tcl.entry_current->startLine = tcl.line_command;
2360 tcl.entry_current->bodyLine = tcl.line_body0;
2361 tcl.entry_current->endBodyLine = tcl.line_body1;
2362 tcl.entry_main->addSubEntry(tcl.entry_current);
2363 //myEntryNs = tcl_entry_namespace(myName);
2364 tcl.cl.insert(myName,tcl.entry_current);
2365 myEntryCl = tcl.entry_current;
2366 myScan = tcl_scan_start(tcl.word_is,*tcl.list_commandwords.at(6),
2367 myName, myEntryCl, NULL);
2370 //! Handle \c oo::define statements.
2371 static void tcl_command_OO_DEFINE()
2374 QCString myNs, myName, myStr;
2376 tcl_scan *myScan = tcl.scan.at(0);
2378 tcl_codify_cmd("keyword",0);
2379 tcl_codify_cmd(NULL,1);
2380 tcl_codify_cmd("NULL",2);
2381 tcl_codify_cmd("NULL",3);
2382 tcl_name(myScan->ns,(*tcl.list_commandwords.at(2)),myNs,myName);
2385 myName = myNs+"::"+myName;
2387 myEntryCl = tcl_entry_class(myName);
2388 myStr = (*tcl.list_commandwords.at(4));
2390 // special cases first
2391 // oo::define classname method methodname args script
2392 // oo::define classname constructor argList bodyScript
2393 // oo::define classname destructor bodyScript
2394 unsigned int n =tcl.list_commandwords.count();
2395 if ((myStr == "method" && n == 11) ||
2396 (myStr == "constructor" && n == 9) ||
2397 (myStr == "destructor" && n == 7))
2399 for (unsigned int i = 4; i < n-1; i++)
2401 tcl_codify_cmd("NULL",i);
2405 tcl_name(myScan->ns,(*tcl.list_commandwords.at(n==11?6:4)),myNs,myMethod);
2406 // code snippet taken from tcl_command_METHOD()/tcl_command_CONSTRUCTOR
2407 tcl.fn.remove(myMethod);
2408 tcl.entry_current->section = Entry::FUNCTION_SEC;
2409 tcl.entry_current->mtype = Method;
2410 tcl.entry_current->name = myMethod;
2411 tcl.entry_current->startLine = tcl.line_command;
2412 tcl.entry_current->bodyLine = tcl.line_body0;
2413 tcl.entry_current->endBodyLine = tcl.line_body1;
2414 tcl_protection(tcl.entry_current);
2417 tcl_command_ARGLIST(*tcl.list_commandwords.at(8));
2421 tcl_command_ARGLIST(*tcl.list_commandwords.at(6));
2423 if (myEntryCl) myEntryCl->addSubEntry(tcl.entry_current);
2424 tcl.fn.insert(myMethod,tcl.entry_current);
2425 myEntry = tcl.entry_current;
2426 myScan = tcl_scan_start('?',*tcl.list_commandwords.at(n-1),
2427 myNs, myEntryCl, myEntry);
2432 // Simply concat all arguments into a script.
2433 // Note: all documentation collected just before the
2434 // oo::define command is lost
2435 if (tcl.list_commandwords.count() > 5)
2437 for (uint i=5;i<tcl.list_commandwords.count();i++)
2439 myStr.append((*tcl.list_commandwords.at(i)));
2443 myScan = tcl_scan_start(tcl.word_is,myStr,myName,myEntryCl,NULL);
2447 //! Handle \c variable statements.
2448 static void tcl_command_VARIABLE(int inclass)
2451 QCString myNs, myName;
2453 tcl_scan *myScan = tcl.scan.at(0);
2455 tcl_codify_cmd("keyword",0);
2456 for (unsigned int i=1; i< tcl.list_commandwords.count(); i++)
2458 tcl_codify_cmd(NULL,i);
2460 tcl_name(myScan->ns,(*tcl.list_commandwords.at(2)),myNs,myName);
2462 {// qualified variables go into namespace
2463 myEntry = tcl_entry_namespace(myNs);
2464 tcl.entry_current->stat = true;
2470 myEntry = myScan->entry_cl;
2471 tcl.entry_current->stat = false;
2475 myEntry = tcl_entry_namespace(myScan->ns);
2476 tcl.entry_current->stat = true;
2479 tcl.entry_current->section = Entry::VARIABLE_SEC;
2480 tcl.entry_current->name = myName;
2481 tcl.entry_current->startLine = tcl.line_command;
2482 tcl.entry_current->bodyLine = tcl.line_body0;
2483 tcl.entry_current->endBodyLine = tcl.line_body1;
2484 tcl_protection(tcl.entry_current);
2485 myEntry->addSubEntry(tcl.entry_current);
2486 tcl.entry_current = tcl_entry_new();
2489 //! Handling of command parsing.
2493 static void tcl_command(int what,const char *text)
2498 tcl.scan.at(0)->line1=yylineno;// current line in scan context
2499 tcl.line_body0=yylineno;// start line of command
2500 tcl_inf("<- %s\n",text);
2501 yy_push_state(COMMAND);
2502 tcl.list_commandwords.clear();
2503 tcl.string_command="";
2510 if (tcl.string_last.length())
2512 tcl.list_commandwords.append(tcl.string_last);
2517 tcl.list_commandwords.append(text);
2522 {// should not happen
2523 tcl_err("what %d\n",what);
2526 QCString myText = text;
2530 return; //TODO check on inside comment
2532 if (tcl.string_last != "")
2534 tcl.list_commandwords.append(tcl.string_last);
2540 QCString myStr = (*tcl.list_commandwords.at(0));
2541 tcl_scan *myScanBackup=tcl.scan.at(0);
2543 Protection myProt = tcl.protection;
2545 if (tcl.list_commandwords.count() < 3)
2547 tcl_command_OTHER();
2550 // remove leading "::" and apply TCL_SUBST
2551 if (myStr.left(2)=="::") myStr = myStr.mid(2);
2552 if (tcl.config_subst.contains(myStr))
2554 myStr=tcl.config_subst[myStr].utf8();
2556 if (myStr=="private")
2558 tcl.protection = Private;
2561 else if (myStr=="protected")
2563 tcl.protection = Protected;
2566 else if (myStr=="public")
2568 tcl.protection = Public;
2573 tcl_codify_cmd("keyword",0);
2574 tcl_codify_cmd(NULL,1);
2575 tcl.list_commandwords.remove(tcl.list_commandwords.at(1));
2576 tcl.list_commandwords.remove(tcl.list_commandwords.at(0));
2577 if (tcl.list_commandwords.count()==1)
2579 tcl_scan *myScan = tcl.scan.at(0);
2580 myScan = tcl_scan_start(tcl.word_is,*tcl.list_commandwords.at(0),
2581 myScan->ns,myScan->entry_cl,myScan->entry_fn);
2582 myProt = tcl.protection;
2585 myStr = (*tcl.list_commandwords.at(0));
2586 // remove leading "::" and apply TCL_SUBST
2587 if (myStr.left(2)=="::") myStr = myStr.mid(2);
2588 if (tcl.config_subst.contains(myStr))
2590 myStr=tcl.config_subst[myStr].utf8();
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;}
2604 if (myStr=="method")
2606 if (tcl.list_commandwords.count() == 5)
2608 tcl.list_commandwords.append("");
2609 tcl.list_commandwords.append("");
2611 if (tcl.list_commandwords.count() != 7) {myLine=__LINE__;goto command_warn;}
2612 tcl_command_METHOD();
2615 if (myStr=="constructor")
2617 if (tcl.list_commandwords.count() != 5) {myLine=__LINE__;goto command_warn;}
2618 tcl_command_CONSTRUCTOR();
2621 if (myStr=="destructor")
2623 if (tcl.list_commandwords.count() != 3) {myLine=__LINE__;goto command_warn;}
2624 tcl_command_DESTRUCTOR();
2627 if (myStr=="namespace")
2629 if ((*tcl.list_commandwords.at(2))=="eval")
2631 if (tcl.list_commandwords.count() < 7) {myLine=__LINE__;goto command_warn;}
2632 tcl_command_NAMESPACE();
2635 tcl_command_OTHER();
2638 if (myStr=="itcl::class")
2640 if (tcl.list_commandwords.count() != 5) {myLine=__LINE__;goto command_warn;}
2641 tcl_command_ITCL_CLASS();
2644 if (myStr=="itcl::body")
2646 if (tcl.list_commandwords.count() != 7) {myLine=__LINE__;goto command_warn;}
2647 tcl_command_METHOD();
2650 if (myStr=="oo::class")
2652 if ((*tcl.list_commandwords.at(2))=="create")
2654 if (tcl.list_commandwords.count() != 7) {myLine=__LINE__;goto command_warn;}
2655 tcl_command_OO_CLASS();
2658 tcl_command_OTHER();
2661 if (myStr=="oo::define")
2663 if (tcl.list_commandwords.count() < 5) {myLine=__LINE__;goto command_warn;}
2664 tcl_command_OO_DEFINE();
2667 if (myStr=="variable")
2669 if (tcl.list_commandwords.count() < 3) {myLine=__LINE__;goto command_warn;}
2670 if (tcl.scan.at(0)->entry_fn == NULL)
2671 {// only parsed outside functions
2672 tcl_command_VARIABLE(tcl.scan.at(0)->entry_cl && tcl.scan.at(0)->entry_cl->name!="");
2676 if (myStr=="common")
2678 if (tcl.list_commandwords.count() < 3) {myLine=__LINE__;goto command_warn;}
2679 if (tcl.scan.at(0)->entry_fn == NULL)
2680 {// only parsed outside functions
2681 tcl_command_VARIABLE(0);
2685 if (myStr=="inherit" || myStr=="superclass")
2687 if (tcl.list_commandwords.count() < 3) {myLine=__LINE__;goto command_warn;}
2688 if (tcl.scan.at(0)->entry_cl && tcl.scan.at(0)->entry_cl->name!="")
2690 for (unsigned int i = 2; i < tcl.list_commandwords.count(); i = i + 2)
2692 tcl.scan.at(0)->entry_cl->extends->append(new BaseInfo((*tcl.list_commandwords.at(i)),Public,Normal));
2698 * Start of internal tcl keywords
2699 * Ready: switch, eval, catch, if, for, foreach, while
2701 if (myStr=="switch")
2703 if (tcl.list_commandwords.count() < 5) {myLine=__LINE__;goto command_warn;}
2704 tcl_command_SWITCH();
2709 if (tcl.list_commandwords.count() < 3) {myLine=__LINE__;goto command_warn;}
2715 if (tcl.list_commandwords.count() < 3) {myLine=__LINE__;goto command_warn;}
2716 tcl_command_CATCH();
2721 if (tcl.list_commandwords.count() != 9) {myLine=__LINE__;goto command_warn;}
2725 if (myStr=="foreach")
2727 if (tcl.list_commandwords.count() < 7 || tcl.list_commandwords.count()%2==0) {myLine=__LINE__;goto command_warn;}
2728 tcl_command_FOREACH();
2732 if expr1 ?then? body1 elseif expr2 ?then? body2 elseif ... ?else? ?bodyN?
2734 if (myStr=="if" && tcl.list_commandwords.count() > 4)
2736 QCStringList myType;
2737 myType << "keyword" << "NULL" << "expr" << "NULL";
2738 char myState='x';// last word: e'x'pr 't'hen 'b'ody 'e'lse else'i'f..
2739 for (unsigned int i = 4; i < tcl.list_commandwords.count(); i = i + 2)
2741 QCString myStr=(*tcl.list_commandwords.at(i));
2747 myType << "keyword" << "NULL";
2752 myType << "script" << "NULL";
2755 else if (myState=='t')
2758 myType << "script" << "NULL";
2760 else if (myState=='b')
2762 if (myStr=="elseif") {
2764 myType << "keyword" << "NULL";
2766 else if (myStr=="else" && i==tcl.list_commandwords.count()-3)
2769 myType << "keyword" << "NULL" << "script";
2770 i = tcl.list_commandwords.count();
2772 else if (i==tcl.list_commandwords.count()-1)
2776 i = tcl.list_commandwords.count();
2780 myLine=__LINE__;goto command_warn;
2783 else if (myState=='i')
2786 myType << "expr" << "NULL";
2789 if (myState != 'b') {myLine=__LINE__;goto command_warn;}
2790 tcl_command_IF(myType);
2795 if (tcl.list_commandwords.count() != 5) {myLine=__LINE__;goto command_warn;}
2796 tcl_command_WHILE();
2799 tcl_command_OTHER();
2801 command_warn:// print warning message because of wrong used syntax
2802 tcl_war("%d count=%d: %s\n",myLine,tcl.list_commandwords.count(),tcl.list_commandwords.join(" ").data());
2803 tcl_command_OTHER();
2804 command_end:// add remaining text to current context
2805 if (!myText.isEmpty())
2807 if(myScanBackup==tcl.scan.at(0))
2809 tcl_codify("comment",myText);
2813 tcl.scan.at(0)->after << "comment" << myText;
2816 tcl.list_commandwords.clear();
2818 tcl.protection = myProt;
2821 //----------------------------------------------------------------------------
2822 //! Common initializations.
2823 static void tcl_init()
2825 // Get values from option TCL_SUBST
2826 tcl.config_subst.clear();
2827 QStrList myStrList = Config_getList(TCL_SUBST);
2828 const char *s=myStrList.first();
2832 int i=myStr.find('=');
2835 QCString myName=myStr.left(i).stripWhiteSpace();
2836 QCString myValue=myStr.right(myStr.length()-i-1).stripWhiteSpace();
2837 if (!myName.isEmpty() && !myValue.isEmpty())
2838 tcl_inf("TCL_SUBST: use '%s'\n",s);
2839 tcl.config_subst[myName] = myValue;
2841 s = myStrList.next();
2844 if (tcl.input_string.at(tcl.input_string.length()-1) == 0x1A)
2847 else if (tcl.input_string.at(tcl.input_string.length()-1) == '\n')
2849 tcl.input_string[tcl.input_string.length()-1] = 0x1A;
2853 tcl.input_string += 0x1A;
2859 tcl.code_linenumbers=1;
2860 tcl.config_autobrief = Config_getBool(JAVADOC_AUTOBRIEF);
2861 tcl.input_position = 0;
2862 tcl.file_name = NULL;
2863 tcl.this_parser = NULL;
2867 tcl.bracket_level=0;
2868 tcl.bracket_quote=0;
2870 tcl.string_command="";
2871 tcl.string_commentline="";
2872 tcl.string_commentcodify="";
2873 tcl.string_comment = "";
2874 tcl.string_last = "";
2875 tcl.entry_main = NULL;
2876 tcl.entry_file = NULL;
2877 tcl.entry_current = NULL;
2878 tcl.entry_inside = NULL;
2879 tcl.list_commandwords.clear();
2885 tcl.protection = Public;
2886 tcl.memberdef = NULL;
2890 static void tcl_parse(const QCString ns, const QCString cls)
2894 tcl.entry_file = tcl_entry_new();
2895 tcl.entry_file->name = tcl.file_name;
2896 tcl.entry_file->section = Entry::SOURCE_SEC;
2897 tcl.entry_file->protection = Public;
2898 tcl.entry_main->addSubEntry(tcl.entry_file);
2899 Entry *myEntry=tcl_entry_new();
2901 tcl.entry_main->addSubEntry(myEntry);
2902 tcl.ns.insert("::",myEntry);
2903 tcl.entry_current = tcl_entry_new();
2905 tclscannerYYrestart( tclscannerYYin );
2908 myScan = new tcl_scan;
2909 myScan->type[0]=' ';myScan->type[1]='\n';
2910 myScan->after.clear();
2911 myScan->line0=yylineno;
2912 myScan->line1=yylineno;
2913 myScan->buffer_state=YY_CURRENT_BUFFER;
2915 myScan->entry_cl=tcl_entry_class(cls);
2916 myScan->entry_fn=NULL;
2917 tcl.entry_inside = tcl.entry_file;
2918 myScan->entry_scan = tcl.entry_inside;
2919 tcl.scan.insert(0,myScan);
2928 //! Parse text file and build up entry tree.
2929 void TclLanguageScanner::parseInput(const char *fileName,
2932 bool /*sameTranslationUnit*/,
2933 QStrList & /*filesInSameTranslationUnit*/)
2936 tcl_inf("%s\n",fileName);
2937 myFile.setName(fileName);
2938 if (!myFile.open(IO_ReadOnly)) return;
2939 if (strlen(input)<1) return;
2941 tcl.input_string = input;
2942 if (tcl.input_string.length()<1) return;
2943 printlex(yy_flex_debug, TRUE, __FILE__, fileName);
2945 msg("Parsing %s...\n",fileName);
2946 groupEnterFile(fileName,yylineno);
2950 tcl.file_name = fileName;
2951 tcl.this_parser = this;
2952 tcl.entry_main = root; /* toplevel entry */
2954 groupLeaveFile(tcl.file_name,yylineno);
2955 root->program.resize(0);
2957 printlex(yy_flex_debug, FALSE, __FILE__, fileName);
2960 //! Parse file and codify.
2961 void TclLanguageScanner::parseCode(CodeOutputInterface & codeOutIntf,
2962 const char * scopeName,
2963 const QCString & input,
2965 bool isExampleBlock,
2966 const char * exampleName,
2970 bool inlineFragment,
2971 MemberDef *memberDef,
2972 bool showLineNumbers,
2973 Definition *searchCtx,
2982 (void)inlineFragment;
2986 if (input.length()<1) return;
2987 printlex(yy_flex_debug, TRUE, __FILE__, fileDef ? fileDef->fileName().data(): NULL);
2988 tcl.input_string = input;
2994 if (memberDef->getClassDef())
2996 myCls = memberDef->getClassDef()->displayName();
2999 else if (memberDef->getNamespaceDef())
3001 myNs = memberDef->getNamespaceDef()->displayName();
3005 QString myStr="Codifying..";
3019 myStr+=memberDef->memberTypeName();
3021 myStr+=memberDef->qualifiedName();
3026 myStr+=fileDef->fileName();
3028 tcl_inf("%s (%d,%d) %d %d\n",myStr.ascii(),startLine,endLine,isExampleBlock,inlineFragment);
3029 //tcl_inf("%s\n"input.data());
3031 tcl.collectXRefs = collectXRefs;
3032 tcl.memberdef = memberDef;
3033 tcl.code = &codeOutIntf;
3039 tcl.code_linenumbers = showLineNumbers;
3040 tcl.code_line=yylineno;
3041 tcl.code->startCodeLine(tcl.code_linenumbers);
3042 if (tcl.code_linenumbers)
3044 tcl.code->writeLineNumber(0,0,0,tcl.code_line);
3047 tcl.this_parser = NULL;
3050 tcl_codify(NULL,input);
3054 tcl.entry_main = tcl_entry_new();
3055 tcl_parse(myNs,myCls);
3057 tcl.code->endCodeLine();
3063 printlex(yy_flex_debug, FALSE, __FILE__, fileDef ? fileDef->fileName().data(): NULL);
3066 bool TclLanguageScanner::needsPreprocessing(const QCString &extension)
3072 void TclLanguageScanner::resetCodeParserState()
3076 void TclLanguageScanner::parsePrototype(const char *text)
3081 static int yyread(char *buf,int max_size)
3086 while ( c < max_size && tcl.input_string.at(tcl.input_position) )
3088 *buf = tcl.input_string.at(tcl.input_position++) ;
3091 //printf("Read from=%d size=%d max=%d c=%d\n",tcl.input_position,strlen(&tcl.input_string[tcl.input_position]),max_size,c);
3095 //----------------------------------------------------------------------------
3097 // to avoid a warning
3103 #if !defined(YY_FLEX_SUBMINOR_VERSION)
3104 //----------------------------------------------------------------------------
3105 extern "C" { // some bogus code to keep the compiler happy
3106 void tclscannerYYdummy() { yy_flex_realloc(0,0); }