diff options
author | Dimitri van Heesch <doxygen@gmail.com> | 2020-03-15 13:32:12 (GMT) |
---|---|---|
committer | Dimitri van Heesch <doxygen@gmail.com> | 2020-03-15 13:32:12 (GMT) |
commit | 48a7afc0caf69857a42b0fe1963db3440cb4000f (patch) | |
tree | 9a63e2b3750a56174811aace9992b34542e5ae1d /src/tclscanner.l | |
parent | 43420bd77408559cb66c83e9ce601426b371bc74 (diff) | |
download | Doxygen-48a7afc0caf69857a42b0fe1963db3440cb4000f.zip Doxygen-48a7afc0caf69857a42b0fe1963db3440cb4000f.tar.gz Doxygen-48a7afc0caf69857a42b0fe1963db3440cb4000f.tar.bz2 |
Remove support for TCL (code is too buggy and unmaintained, language not very popular)
Diffstat (limited to 'src/tclscanner.l')
-rw-r--r-- | src/tclscanner.l | 3156 |
1 files changed, 0 insertions, 3156 deletions
diff --git a/src/tclscanner.l b/src/tclscanner.l deleted file mode 100644 index 10aba97..0000000 --- a/src/tclscanner.l +++ /dev/null @@ -1,3156 +0,0 @@ -/***************************************************************************** - * Parser for Tcl subset - * - * Copyright (C) 2010 by Rene Zaumseil - * based on the work of Dimitri van Heesch. - * - * Permission to use, copy, modify, and distribute this software and its - * documentation under the terms of the GNU General Public License is hereby - * granted. No representations are made about the suitability of this software - * for any purpose. It is provided "as is" without express or implied warranty. - * See the GNU General Public License for more details. - * - * Documents produced by Doxygen are derivative works derived from the - * input used in their production; they are not affected by this license. - * - */ -%option never-interactive -%option case-insensitive -%option prefix="tclscannerYY" -%top{ -#include <stdint.h> -} - -%{ -#include <stdio.h> -#include <stdlib.h> -#include <assert.h> -#include <ctype.h> - -#include <qstring.h> -#include <qcstringlist.h> -#include <qlist.h> -#include <qmap.h> -#include <qarray.h> -#include <qstack.h> -#include <qregexp.h> -#include <qfile.h> -#include <qdict.h> - -#include "entry.h" -#include "message.h" -#include "config.h" -#include "doxygen.h" -#include "util.h" -#include "defargs.h" -#include "language.h" -#include "commentscan.h" -#include "pre.h" -#include "tclscanner.h" -#include "outputlist.h" -#include "membername.h" -#include "searchindex.h" -#include "commentcnv.h" -#include "bufstr.h" -#include "portable.h" -#include "arguments.h" -#include "namespacedef.h" -#include "filedef.h" -#include "markdown.h" - -#define YY_NO_INPUT 1 -#define YY_NO_UNISTD_H 1 - -#define MAX_INCLUDE_DEPTH 10 - -#define USE_STATE2STRING 0 - -#if USE_STATE2STRING -static const char *stateToString(int state); -#endif - -//! Application error. -#define tcl_err \ - printf("Error %d %s() at line %d! ",__LINE__,tcl.file_name.data(),yylineno); \ - yy_push_state(ERROR); \ - yyless(0); \ - printf - -//! Application warning. -#define tcl_war \ - printf("Warning %d %s() at line %d: ",__LINE__,tcl.file_name.data(),yylineno); \ - printf - -//! Application message. -#define tcl_inf \ - if (0) printf("--- %.4d %d@%d: ",__LINE__,yylineno,yy_start_stack_ptr) && printf - -//! Debug message. -#define D\ - if (0) printf("--- %.4d %d@%d: %s\n",__LINE__,yylineno,yy_start_stack_ptr,yytext); - -// BEGIN of copy from tclUtil.c -// - Tcl_Interp removed -// - changes are marked with RZ -// #define's to adapt the code: -#define CONST const -#define UCHAR (unsigned char) -#define TCL_ERROR 1 -#define TCL_OK 0 -#define ckalloc malloc -#define ckfree free -#define TclCopyAndCollapse(size,src,dest) memcpy(dest,src,size); *(dest+size)=0 -int TclFindElement( - CONST char *list, /* Points to the first byte of a string - * containing a Tcl list with zero or more - * elements (possibly in braces). */ - int listLength, /* Number of bytes in the list's string. */ - CONST char **elementPtr, /* Where to put address of first significant - * character in first element of list. */ - CONST char **nextPtr, /* Fill in with location of character just - * after all white space following end of - * argument (next arg or end of list). */ - int *sizePtr, /* If non-zero, fill in with size of - * element. */ - int *bracePtr) /* If non-zero, fill in with non-zero/zero to - * indicate that arg was/wasn't in braces. */ -{ - CONST char *p = list; - CONST char *elemStart; /* Points to first byte of first element. */ - CONST char *limit; /* Points just after list's last byte. */ - int openBraces = 0; /* Brace nesting level during parse. */ - int inQuotes = 0; - int size = 0; /* lint. */ - //RZ int numChars; - - /* - * Skim off leading white space and check for an opening brace or quote. - * We treat embedded NULLs in the list as bytes belonging to a list - * element. - */ - - limit = (list + listLength); - while ((p < limit) && (isspace(UCHAR(*p)))) - { /* INTL: ISO space. */ - p++; - } - if (p == limit) - { /* no element found */ - elemStart = limit; - goto done; - } - - if (*p == '{') /* } to keep vi happy */ - { - openBraces = 1; - p++; - } - else if (*p == '"') - { - inQuotes = 1; - p++; - } - elemStart = p; - if (bracePtr != 0) - { - *bracePtr = openBraces; - } - - /* - * Find element's end (a space, close brace, or the end of the string). - */ - - while (p < limit) - { - switch (*p) - { - /* - * Open brace: don't treat specially unless the element is in - * braces. In this case, keep a nesting count. - */ - - case '{': - if (openBraces != 0) - { - openBraces++; - } - break; - - /* - * Close brace: if element is in braces, keep nesting count and - * quit when the last close brace is seen. - */ - - case '}': - if (openBraces > 1) - { - openBraces--; - } - else if (openBraces == 1) - { - size = (int)(p - elemStart); - p++; - if ((p >= limit) || isspace(UCHAR(*p))) - { /* INTL: ISO space. */ - goto done; - } - - /* - * Garbage after the closing brace; return an error. - */ - - return TCL_ERROR; - } - break; - - /* - * Backslash: skip over everything up to the end of the backslash - * sequence. - */ - - case '\\': - //RZ Tcl_UtfBackslash(p, &numChars, NULL); - //RZ p += (numChars - 1); - p++; //RZ - break; - - /* - * Space: ignore if element is in braces or quotes; otherwise - * terminate element. - */ - - case ' ': - case '\f': - case '\n': - case '\r': - case '\t': - case '\v': - if ((openBraces == 0) && !inQuotes) - { - size = (int)(p - elemStart); - goto done; - } - break; - - /* - * Double-quote: if element is in quotes then terminate it. - */ - - case '"': - if (inQuotes) - { - size = (int)(p - elemStart); - p++; - if ((p >= limit) || isspace(UCHAR(*p))) - { /* INTL: ISO space */ - goto done; - } - - /* - * Garbage after the closing quote; return an error. - */ - return TCL_ERROR; - } - break; - } - p++; - } - - /* - * End of list: terminate element. - */ - - if (p == limit) - { - if (openBraces != 0) - { - return TCL_ERROR; - } - else if (inQuotes) - { - return TCL_ERROR; - } - size = (int)(p - elemStart); - } - -done: - while ((p < limit) && (isspace(UCHAR(*p)))) - { /* INTL: ISO space. */ - p++; - } - *elementPtr = elemStart; - *nextPtr = p; - if (sizePtr != 0) - { - *sizePtr = size; - } - return TCL_OK; -} - -int Tcl_SplitList( - CONST char *list, /* Pointer to string with list structure. */ - int *argcPtr, /* Pointer to location to fill in with the - * number of elements in the list. */ - CONST char ***argvPtr) /* Pointer to place to store pointer to array - * of pointers to list elements. */ -{ - CONST char **argv, *l, *element; - char *p; - int length, size, i, result, elSize, brace; - - /* - * Figure out how much space to allocate. There must be enough space for - * both the array of pointers and also for a copy of the list. To estimate - * the number of pointers needed, count the number of space characters in - * the list. - */ - - for (size = 2, l = list; *l != 0; l++) - { - if (isspace(UCHAR(*l))) - { /* INTL: ISO space. */ - size++; - - /* - * Consecutive space can only count as a single list delimiter. - */ - - while (1) - { - char next = *(l + 1); - - if (next == '\0') - { - break; - } - ++l; - if (isspace(UCHAR(next))) - { /* INTL: ISO space. */ - continue; - } - break; - } - } - } - length = (int)(l - list); - argv = (CONST char **) ckalloc((unsigned) - ((size * sizeof(char *)) + length + 1)); - for (i = 0, p = ((char *) argv) + size*sizeof(char *); - *list != 0; i++) - { - CONST char *prevList = list; - - result = TclFindElement(list, length, &element, &list, - &elSize, &brace); - length -= (int)(list - prevList); - if (result != TCL_OK) - { - ckfree((char *) argv); - return result; - } - if (*element == 0) - { - break; - } - if (i >= size) - { - ckfree((char *) argv); - return TCL_ERROR; - } - argv[i] = p; - if (brace) - { - memcpy(p, element, (size_t) elSize); - p += elSize; - *p = 0; - p++; - } - else - { - TclCopyAndCollapse(elSize, element, p); - p += elSize+1; - } - } - - argv[i] = NULL; - *argvPtr = argv; - *argcPtr = i; - return TCL_OK; -} -// END of tclUtil.c - -void tcl_split_list(QCString &str, QCStringList &list) -{ - int argc; - const char **argv; - - list.clear(); - if (str.left(1)=="{" && str.right(1)=="}") - { - str=str.mid(1,str.length()-2); - } - else if (str.left(1)=="\"" && str.right(1)=="\"") - { - str=str.mid(1,str.length()-2); - } - if (!str.isEmpty()) - { - if (Tcl_SplitList(str,&argc,&argv) != TCL_OK) - { - list.append(str); - } - else - { - for (int i = 0; i < argc; i++) - { - list.append(argv[i]); - } - ckfree((char *) argv); - } - } -} - -//! Structure containing information about current scan context. -typedef struct -{ - char type[2]; // type of scan context: "\"" "{" "[" "?" " " - int line0; // start line of scan context - int line1; // end line of scan context - YY_BUFFER_STATE buffer_state; // value of scan context - QCString ns; // current namespace - Entry *entry_fn; // if set contains the current proc/method/constructor/destructor - Entry *entry_cl; // if set contain the current class - Entry *entry_scan; // current scan entry - Protection protection; // current protections state - QCStringList after; // option/value list (options: NULL comment keyword script) -} tcl_scan; - -//* Structure containing all internal global variables. -struct tcl_struct -{ - CodeOutputInterface * code; // if set then we are codifying the file - int code_line; // current line of code - int code_linenumbers; // if true create line numbers in code - const char *code_font; // used font to codify - bool config_autobrief; // value of configuration option - QMap<QCString,QCString> config_subst; // map of configuration option values - QCString input_string; // file contents - int input_position; // position in file - QCString file_name; // name of used file - OutlineParserInterface *this_parser; // myself - CommentScanner commentScanner; - int command; // true if command was found - int comment; // set true if comment was scanned - int brace_level; // bookkeeping of braces - int bracket_level; // bookkeeping of brackets - int bracket_quote; // bookkeeping of quotes (toggles) - char word_is; // type of current word: "\"" "{" "[" "?" " " - int line_comment; // line number of comment - int line_commentline; // line number of comment after command - int line_command; // line number of command - int line_body0; // start line of body - int line_body1; // end line of body - QCString string_command; // contain current command - QCString string_commentline; // contain current comment after command - QCString string_commentcodify; // current comment string used in codifying - QCString string_comment; // contain current comment - QCString string_last; // contain last read word or part of word - QCString string; // temporary string value - Entry* entry_main; // top level entry - Entry* entry_file; // entry of current file - Entry* entry_current; // currently used entry - Entry* entry_inside; // contain entry of current scan context - QCStringList list_commandwords; // list of command words - QList<tcl_scan> scan; // stack of scan contexts - QAsciiDict<Entry> ns; // all read namespace entries - QAsciiDict<Entry> cl; // all read class entries - QAsciiDict<Entry> fn; // all read function entries - QList<Entry> entry; // list of all created entries, will be deleted after codifying - Protection protection; // current protections state - const MemberDef *memberdef; // contain current MemberDef when codifying - bool collectXRefs; -}; - -static tcl_struct tcl; - -// scanner functions -static yy_size_t yyread(char *buf,yy_size_t max_size); -static tcl_scan *tcl_scan_start(char type, QCString content, QCString ns, Entry *entry_cls, Entry *entry_fn); -static void tcl_scan_end(); -static void tcl_comment(int what,const char *text); -static void tcl_word(int what,const char *text); -static void tcl_command(int what,const char *text); - -// helper functions - -//! Create new entry. -// @return new initialised entry -Entry* tcl_entry_new() -{ - Entry *myEntry = new Entry; - myEntry->section = Entry::EMPTY_SEC; - myEntry->name = ""; -// myEntry->type = ""; - myEntry->brief = ""; -// myEntry->doc = ""; - myEntry->protection = Public; -// myEntry->mtype = Method; -// myEntry->virt = Normal; -// myEntry->stat = FALSE; - myEntry->docFile = tcl.file_name; - myEntry->inbodyFile = tcl.file_name; - myEntry->fileName = tcl.file_name; - myEntry->lang = SrcLangExt_Tcl; - tcl.commentScanner.initGroupInfo(myEntry); - // collect entries - if (!tcl.code) - { - tcl.entry.insert(0,myEntry); - } - return myEntry; -} - -//! Set protection level. -void tcl_protection(Entry *entry) -{ - if (entry->protection!=Public&&entry->protection!=Protected&&entry->protection!=Private) - { - entry->protection = tcl.protection; - } - if (entry->protection!=Protected&&entry->protection!=Private) - { - entry->protection = Public; - } -} - -//! Check name. -// @return 'ns' and 'name' of given current 'ns0' and 'name0' -static void tcl_name(const QCString &ns0, const QCString &name0, QCString &ns, QCString &name) -{ - QCString myNm; - int myStart; - - if (qstrncmp(name0.data(),"::",2)==0) - { - myNm = name0.mid(2); - } - else if (ns0.length() && ns0 != " ") - { - myNm = ns0 + "::" + name0; - } - else - { - myNm = name0; - } - myStart = myNm.findRev("::"); - if (myStart == -1) - { - ns = ""; - name = myNm; - } - else if (myNm.length()-myStart == 2) - { - // ending with :: so get name equal to last component - ns = myNm.mid(0,myStart); - myStart = ns.findRev("::"); - name = myNm.mid(myStart+2); - } - else - { - ns = myNm.mid(0,myStart); - name = myNm.mid(myStart+2); - } -} - -//! Check name. Strip namespace qualifiers from name0 if inside inlined code segment. -// @return 'ns' and 'name' of given current 'ns0' and 'name0' -static void tcl_name_SnippetAware(const QCString &ns0, const QCString &name0, QCString &ns, QCString &name) -{ - // If we are inside an inlined code snippet then ns0 - // already contains the complete namespace path. - // Any namespace qualifiers in name0 are redundant. - int i = name0.findRev("::"); - if (i>=0 && tcl.memberdef) - { - tcl_name(ns0, name0.mid(i+2), ns, name); - } - else - { - tcl_name(ns0, name0, ns, name); - } -} - -// Check and return namespace entry. -// @return namespace entry -Entry* tcl_entry_namespace(const QCString ns) -{ - Entry *myEntry; - if (ns.length()) - { - myEntry = tcl.ns.find(ns); - } - else - { - myEntry = tcl.ns.find("::"); - } - if (myEntry == NULL) - { - myEntry = tcl_entry_new(); - myEntry->section = Entry::NAMESPACE_SEC; - myEntry->name = ns; - tcl.entry_main->moveToSubEntryAndKeep(myEntry); - tcl.ns.insert(ns,myEntry); - } - return myEntry; -} - -// Check and return class entry. -// @return class entry -Entry* tcl_entry_class(const QCString cl) -{ - Entry *myEntry; - if (!cl.length()) return(NULL); - - myEntry = tcl.cl.find(cl); - if (myEntry == NULL) - { - myEntry = tcl_entry_new(); - myEntry->section = Entry::CLASS_SEC; - myEntry->name = cl; - tcl.entry_main->moveToSubEntryAndKeep(myEntry); - tcl.cl.insert(cl,myEntry); - } - return myEntry; -} - -//! Check for keywords. -// @return 1 if keyword and 0 otherwise -static int tcl_keyword(QCString str) -{ - static QCStringList myList; - static int myInit=1; - if (myInit) - { - // tcl keywords - myList <<"append"<<"apply"<<"array"<<"auto_execok"<<"auto_import"<<"auto_load"<<"auto_mkindex"<<"auto_qualify"<<"auto_reset"; - myList <<"binary"; - myList <<"catch"<<"cd"<<"close"<<"clock"<<"concat"; - myList <<"eof"<<"eval"<<"exec"<<"exit"<<"expr"; - myList <<"fblocked"<<"fconfigure"<<"file"<<"fileevent"<<"flush"<<"for"<<"foreach"<<"format"; - myList <<"gets"<<"global"; - myList <<"http"; - myList <<"if"<<"incr"<<"info"<<"interp"; - myList <<"join"; - myList <<"lappend"<<"lassign"<<"lindex"<<"linsert"<<"llength"<<"load"<<"lrange"<<"lrepeat"<<"lreplace"<<"lreverse"<<"lset"; - myList <<"namespace"; - myList <<"package"<<"parray"<<"pid"<<"pkg_mkIndex"<<"proc"<<"puts"<<"pwd"; - myList <<"registry"<<"rename"<<"return"; - myList <<"scan"<<"set"<<"split"<<"string"<<"switch"; - myList <<"tclLog"<<"tcl_endOfWord"<<"tcl_findLibrary"<<"tcl_startOfNextWord"<<"tcl_startOfPreviousWord"<<"tcl_wordBreakAfter"<<"tcl_wordBreakBefore"<<"tell"<<"time"; - myList <<"unknown"<<"upvar"; - myList <<"variable"<<"vwait"; -// tk keywords - myList <<"bell"<<"bind"<<"bindtags"; - myList <<"clipboard"<<"console"<<"consoleinterp"; - myList <<"destroy"; - myList <<"event"; - myList <<"focus"; - myList <<"grid"; - myList <<"lower"; - myList <<"option"; - myList <<"pack"<<"place"; - myList <<"raise"; - myList <<"send"; - 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"; - myList <<"winfo"<<"wm"; - myList <<"button"<<"canvas"<<"checkbutton"<<"entry"<<"frame"<<"image"<<"label"<<"labelframe"<<"listbox"<<"menu"<<"menubutton"<<"message"<<"panedwindow"<<"radiobutton"<<"scale"<<"scrollbar"<<"spinbox"<<"toplevel"; - //myList.sort(); - myInit=0; - } - str=str.stripWhiteSpace(); - if (str.left(2)=="::") {str=str.mid(2);} - if (myList.findIndex(str) != -1) return(1); - return 0; -} - -//! End codifying with special font class. -static void tcl_font_end() -{ - if (!tcl.code) return; - if (tcl.code_font) - { - tcl.code->endFontClass(); - tcl.code_font=NULL; - } -} - -//! Codify 'str' with special font class 's'. -static void tcl_codify(const char *s,const char *str) -{ - if (!tcl.code || !str) return; - if (s && qstrcmp(s,"NULL")!=0) - { - tcl_font_end(); - tcl.code->startFontClass(s); - tcl.code_font=s; - } - char *tmp = (char *) malloc(strlen(str)+1); - strcpy(tmp, str); - char *p=tmp,*sp=p; - char c; - bool done=FALSE; - while (!done) - { - sp=p; - while ((c=*p++) && c!='\n') {} - if (c=='\n') - { - tcl.code_line++; - *(p-1)='\0'; // Dimitri: is this really needed? - // wtschueller: As far as I can see: yes. - // Deletes that \n that would produce ugly source listings otherwise. - // However, there may exist more sophisticated solutions. - tcl.code->codify(sp); - if (tcl.code_font) - { - tcl.code->endFontClass(); - } - tcl.code->endCodeLine(); - tcl.code->startCodeLine(tcl.code_linenumbers); - if (tcl.code_linenumbers) - { - tcl.code->writeLineNumber(0,0,0,tcl.code_line); - } - if (tcl.code_font) - { - tcl.code->startFontClass(tcl.code_font); - } - } - else - { - if (*(p-2)==0x1A) *(p-2) = '\0'; // remove ^Z - tcl.code->codify(sp); - done=TRUE; - } - } - free(tmp); - tcl_font_end(); -} - -#if 0 -//! Codify 'str' with special font class 's'. -static void tcl_codify(const char *s,const char *str) -{ - if (tcl.code==NULL) return; - char *tmp= (char *) malloc(strlen(str)+1); - strcpy(tmp, str); - tcl_codify(s,tmp); - free(tmp); -} - -//! Codify 'str' with special font class 's'. -static void tcl_codify(const char *s,const QCString &str) -{ - if (tcl.code==NULL) return; - tcl_codify(s,str); -} - -//! Codify 'str' with special font class 's'. -static void tcl_codify(const char *s,const QCString &str) -{ - if (!tcl.code) return; - tcl_codify(s,str.data()); -} -#endif - -static void tcl_codify_cmd(const char *s,int i) -{ - tcl_codify(s,(*tcl.list_commandwords.at(i))); -} -//! codify a string token -// -// codifies string according to type. -// Starts a new scan context if needed (*myScan==0 and type == "script"). -// Returns NULL or the created scan context. -// -static tcl_scan *tcl_codify_token(tcl_scan *myScan, const QCString type, const QCString string) -{ - if (myScan != NULL) - { - if (type != NULL) - { - myScan->after << type << string; - } - else - { - myScan->after << "NULL" << string; - } - } - else - { - if (qstrcmp(type, "script") == 0) - { - myScan = tcl.scan.at(0); - myScan = tcl_scan_start('?', string, - myScan->ns, myScan->entry_cl, myScan->entry_fn); - } - else - { - tcl_codify((const char*)type, string); - } - } - return myScan; -} - -//----------------------------------------------------------------------------- -#undef YY_INPUT -#define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size); -//----------------------------------------------------------------------------- -%} -ws ([ \t]|\\\n) - -%option yylineno -%option noyywrap -%option stack - -%x ERROR -%x TOP -%x COMMAND -%x WORD -%x COMMENT -%x COMMENT_NL -%x COMMENT_CODE -%x COMMENT_VERB -%x COMMENTLINE -%x COMMENTLINE_NL -%% -<ERROR>. { -D - yyterminate(); -} -<<EOF>> { -D - if (tcl.scan.count()<1) - {// error -D - tcl_err("Tcl parser stack empty! Parser error in file '%s'.\n",tcl.file_name.data()); - yyterminate(); - } - else if (tcl.scan.count()==1) - {// exit, check on input? -D - yyterminate(); - } - else - {// continue -D - tcl_command(-1,""); - tcl_scan_end(); - } -} -<TOP>"#" { -D - yyless(0); - tcl.line_comment=yylineno; - tcl_comment(0,""); -} -<TOP>({ws}|[\;\n])+ { -D - tcl_codify(NULL,yytext); -} -<TOP>. { -D - yyless(0); - tcl.line_command=yylineno; - tcl_command(0,""); -} - -<COMMENT>[ \t]* { -D - tcl_codify("comment",yytext); -} -<COMMENT>"###".*\n { -D - tcl_codify("comment",yytext); - tcl_comment(2,yytext+1); -} -<COMMENT>"##".*\\\n { -D - tcl_codify("comment",yytext); - QCString t=yytext; - t = t.mid(2,t.length()-3); - t.append("\n"); - tcl_comment(1,t.data()); - yy_push_state(COMMENT_NL); -} -<COMMENT>"##".*\n { -D - tcl_codify("comment",yytext); - tcl_comment(1,yytext+2); -} -<COMMENT>"#"[@\\]"code"\n[ \t]*[^#] { -D - QCString t=yytext; - tcl_codify("comment",t.left(7)); - tcl_comment(2,"\n@code\n"); - yyless(7); - yy_push_state(COMMENT_CODE); -} -<COMMENT>"#"[@\\]"verbatim"\n[ \t]*[^#] { -D - QCString t=yytext; - tcl_codify("comment",t.left(11)); - tcl_comment(2,"\n@verbatim\n"); - yyless(11); - yy_push_state(COMMENT_VERB); -} -<COMMENT>"#".*\\\n { -D - tcl_codify("comment",yytext); - QCString t=yytext; - t = t.mid(1,t.length()-3); - t.append("\n"); - tcl_comment(2,t.data()); - yy_push_state(COMMENT_NL); -} -<COMMENT>"#".*\n { -D - tcl_codify("comment",yytext); - tcl_comment(2,yytext+1); -} -<COMMENT>"#".*\x1A { -D - QCString t=yytext; - t = t.mid(0,t.length()-1); - tcl_codify("comment",t.data()); - t = t.mid(1,t.length()); - tcl_comment(-2,t.data()); - unput(0x1A); -} -<COMMENT>\x1A { -D - tcl_comment(-2,""); - unput(0x1A); -} -<COMMENT>.|\n { -D - tcl_comment(-2,yytext); - yyless(0); -} - -<COMMENT_CODE>"#"[@\\]"endcode"\n { -D - QCString t=yytext; - t = t.left(t.length()-10); - tcl_comment(2,t.data()); - tcl_comment(2,"\n@endcode\n"); - yy_pop_state(); - yyless(0); -} -<COMMENT_CODE>.*\n { -D - yymore(); -} -<COMMENT_CODE>.*\x1A { -D - yy_pop_state(); - yyless(0); -} - -<COMMENT_VERB>"#"[@\\]"endverbatim"\n { -D - QCString t=yytext; - t = t.left(t.length()-14); - tcl_comment(2,t.data()); - tcl_comment(2,"\n@endverbatim\n"); - yy_pop_state(); - yyless(0); -} -<COMMENT_VERB>.*\n { -D - yymore(); -} -<COMMENT_VERB>.*\x1A { -D - yy_pop_state(); - yyless(0); -} - -<COMMENT_NL>.*\\\n { -D - tcl_codify("comment",yytext); - tcl_comment(2,yytext); -} -<COMMENT_NL>.*\n { -D - tcl_codify("comment",yytext); - tcl_comment(2,yytext); - yy_pop_state(); -} -<COMMENT_NL>.*\x1A { -D - yy_pop_state(); - yyless(0); -} - -<COMMENTLINE>.*\x1A { -D - yy_pop_state(); - yyless(0); -} -<COMMENTLINE>[ \t]* { -D - tcl.string_commentcodify += yytext; -} -<COMMENTLINE>"#<".*\\\n { -D - tcl.string_commentcodify += yytext; - QCString t=yytext; - t = t.mid(2,t.length()-4); - t.append("\n"); - tcl.string_commentline += t; - yy_push_state(COMMENTLINE_NL); -} -<COMMENTLINE>"#<".*\n { -D - tcl.string_commentcodify += yytext; - tcl.string_commentline += (yytext+2); -} -<COMMENTLINE>.|\n { -D - yy_pop_state(); - if (tcl.string_commentline.length()) - { - tcl.entry_current->brief = tcl.string_commentline; - tcl.entry_current->briefLine = tcl.line_commentline; - tcl.entry_current->briefFile = tcl.file_name; - } - yyless(0); - tcl_command(-1,tcl.string_commentcodify.data()); - tcl.string_commentline=""; - tcl.string_commentcodify=""; -} - -<COMMENTLINE_NL>.*\\\n { -D - tcl.string_commentcodify += yytext; - QCString t=yytext; - t = t.left(t.length()-3); - t.append("\n"); - tcl.string_commentline += t; -} -<COMMENTLINE_NL>.*\n { -D - tcl.string_commentcodify += yytext; - tcl.string_commentline += yytext; - yy_pop_state(); -} -<COMMENTLINE_NL>.*\x1A { -D - QCString t=yytext; - t = t.left(t.length()-1); - tcl.string_commentcodify += t; - tcl.string_commentline += t; - yy_pop_state(); - unput(0x1A); -} - -<COMMAND>{ws}*[\;]{ws}*"#<" { -D - tcl.string_commentcodify = yytext; - tcl.string_commentcodify = tcl.string_commentcodify.left(tcl.string_commentcodify.length()-2); - tcl.string_commentline = ""; - tcl.line_commentline = yylineno; - tcl.line_body1=yylineno; - unput('<'); - unput('#'); - yy_push_state(COMMENTLINE); -} -<COMMAND>{ws}*\x1A { -D - tcl.string_commentcodify = ""; - tcl.string_commentline = ""; - tcl.line_body1=yylineno; - tcl_command(-1,yytext); -} -<COMMAND>{ws}*; { -D - tcl.string_commentcodify = ""; - tcl.string_commentline = ""; - tcl.line_body1=yylineno; - tcl_command(-1,yytext); -} -<COMMAND>{ws}*\n { -D - tcl.string_commentcodify = ""; - tcl.string_commentline = ""; - tcl.line_body1=yylineno-1; - tcl_command(-1,yytext); -} -<COMMAND>{ws}+ { -D - tcl_command(1,yytext); -} -<COMMAND>"{*}". { -D - tcl.word_is = ' '; - tcl.string_last = "{*}"; - tcl_word(0,&yytext[3]); -} -<COMMAND>"\\"[\{\}\[\]\;\" \t] { -D - tcl.word_is=' '; - tcl.string_last = ""; - tcl_word(0,yytext); -} -<COMMAND>. { -D - tcl.word_is=' '; - if (yytext[0]=='{'||yytext[0]=='['||yytext[0]=='"') tcl.word_is = yytext[0]; - tcl.string_last = ""; - tcl_word(0,yytext); -} - -<WORD>"\\\\" | -<WORD>"\\"[\{\}\[\]\;\" \t] { - tcl_word(1,yytext); -} -<WORD>"\\\n" { - tcl_word(2,yytext); -} -<WORD>"{" { - tcl_word(3,yytext); -} -<WORD>"}" { - tcl_word(4,yytext); -} -<WORD>"[" { - tcl_word(5,yytext); -} -<WORD>"]" { - tcl_word(6,yytext); -} -<WORD>"\"" { - tcl_word(7,yytext); -} -<WORD>" " { - tcl_word(8,yytext); -} -<WORD>"\t" { - tcl_word(9,yytext); -} -<WORD>";" { - tcl_word(10,yytext); -} -<WORD>"\n" { - tcl_word(11,yytext); -} -<WORD>\x1A { - tcl_word(12,yytext); -} -<WORD>. { - tcl_word(1,yytext); -} -%% - -//! Start new scan context for given 'content'. -// @return created new scan context. -static tcl_scan *tcl_scan_start(char type, QCString content, QCString ns, Entry *entry_cl, Entry *entry_fn) -{ - tcl_scan *myScan=tcl.scan.at(0); -tcl_inf("line=%d type=%d '%s'\n",tcl.line_body0,type,content.data()); - - myScan->line1=yylineno; - yy_push_state(TOP); - - myScan=new tcl_scan; - myScan->type[0] =' '; - myScan->type[1] = '\0'; - switch (type) { - case '"': - case '{': - case '[': - myScan->type[0] = type; - break; - case '?': - if (content[0]=='"' && content[content.length()-1]=='"') myScan->type[0]='"'; - if (content[0]=='{' && content[content.length()-1]=='}') myScan->type[0]='{'; - if (content[0]=='[' && content[content.length()-1]==']') myScan->type[0]='['; - } - if (myScan->type[0]!=' ') - { - tcl_codify(NULL,&myScan->type[0]); - content = content.mid(1,content.length()-2); - } - content += (char)0x1A;// for detection end of scan context - myScan->ns = ns; - myScan->entry_cl = entry_cl; - myScan->entry_fn = entry_fn; - myScan->entry_scan = tcl.entry_current; - myScan->buffer_state=yy_scan_string(content.data()); - myScan->line0=tcl.line_body0; - myScan->line1=tcl.line_body1; - myScan->after.clear(); - yylineno=myScan->line0; - myScan->protection = tcl.protection; - - tcl.entry_inside = myScan->entry_scan; - tcl.entry_current = tcl_entry_new(); - tcl.scan.insert(0,myScan); - yy_switch_to_buffer(myScan->buffer_state); - return (myScan); -} - -//! Close current scan context. -static void tcl_scan_end() -{ - tcl_scan *myScan=tcl.scan.at(0); - tcl_scan *myScan1=tcl.scan.at(1); -tcl_inf("line=%d\n",myScan->line1); - - if (myScan->type[0]=='{') myScan->type[0]='}'; - if (myScan->type[0]=='[') myScan->type[0]=']'; - if (myScan->type[0]!=' ') tcl_codify(NULL,&myScan->type[0]); - int myStart=-1; - for (unsigned int i=0;i<myScan->after.count();i=i+2) - { - if (myScan->after[i]=="script") { - myStart=i; - break; - } - tcl_codify(myScan->after[i],myScan->after[i+1]); - } - yy_delete_buffer(myScan->buffer_state); - yy_pop_state(); - tcl.entry_inside = myScan1->entry_scan; - yy_switch_to_buffer(myScan1->buffer_state); - yylineno=myScan1->line1; - tcl.protection = myScan1->protection; - if (myStart>=0) - { - myScan1 = tcl_scan_start('?', myScan->after[myStart+1], myScan->ns, myScan->entry_cl, myScan->entry_fn); - for (unsigned int i=myStart+2;i<myScan->after.count();i++) - { - myScan1->after.append(myScan->after[i]); - } - tcl.scan.remove(1); - } - else - { - tcl.scan.removeFirst(); - } -} - -//! Handling of word parsing. -static void tcl_word(int what,const char *text) -{ - static char myList[1024]="";// nesting level list - static int myLevel=0;// number of current nesting level - static int myWhite=0;// set true when next char should be whitespace - static char myWord;// internal state - - switch (what) - { - case 0:// start - yy_push_state(WORD); - switch (text[0]) - { - case '{': - case '[': - case '"': myWord = text[0]; break; - default: myWord = '.'; - } - myList[0]=myWord; - myLevel=1; - myWhite=0; - break; - case 1:// all other chars - if (myWhite) - {// {x}y "x"y - tcl_err("expected word separator: %s\n",text); - return; - } - if (myLevel==0) - { - myWord='.'; - myList[0]=myWord; - myLevel=1; - } - break; - case 2:// \\\n - if (myLevel==0) - { - myWord=' '; - yy_pop_state(); - yyless(0); -tcl_inf("(\\\n) ?%s?\n",tcl.string_last.data()); - return; - } - switch (myList[myLevel-1]) - { - case '{': - case '[': - case '"': - break; - case '.': - if (myLevel==1) - { - myWord=' '; - yy_pop_state(); - yyless(0); -tcl_inf("(\\\n) ?%s?\n",tcl.string_last.data()); - return; - } - break; - } - myWhite=0; - break; - case 3:// { - if (myWhite) - {// {x}{ "x"{ - tcl_err("expected word separator: %s\n",text); - return; - } - switch (myList[myLevel-1]) - { - case '{': - case '[': - myList[myLevel++]='{'; - break; - case '"': - case '.': - break; - } - myWhite=0; - break; - case 4:// } - if (myWhite) - {// {x}{ "x"{ - tcl_err("expected word separator: %s\n",text); - return; - } - switch (myList[myLevel-1]) - { - case '{':// {{x}} - myLevel--; - if (myLevel==0 && !tcl.code) - { - myWhite=1; - } - break; - case '[': - case '"': - case '.': - break; - } - break; - case 5:// [ - if (myWhite) - {// {x}[ - tcl_err("expected word separator: %s\n",text); - return; - } - switch (myList[myLevel-1]) - { - case '{': - break; - case '[': - case '"': - case '.': - myList[myLevel++]='['; - break; - } - myWhite=0; - break; - case 6:// ] - if (myWhite) - {// {x}] - tcl_err("expected word separator: %s\n",text); - return; - } - switch (myList[myLevel-1]) - { - case '{': - break; - case '[': - myLevel--; - break; - case '"': - case '.': - break; - } - myWhite=0; - break; - case 7:// " - if (myWhite) - {// {x}" - tcl_err("expected word separator: %s\n",text); - return; - } - switch (myList[myLevel-1]) - { - case '{': - break; - case '[': - myList[myLevel++]='"'; - break; - case '"': - myLevel--; - case '.': - break; - } - break; - case 8:// ' ' - case 9:// \t - case 10:// ; - case 11:// \n - if (myLevel==0) - { - myWord=' '; - yy_pop_state(); - yyless(0); -tcl_inf("(%d) ?%s?\n",what,tcl.string_last.data()); - return; - } - switch (myList[myLevel-1]) - { - case '{': - case '[': - case '"': - break; - case '.': - if (myLevel==1) - { - myWord=' '; - yy_pop_state(); - yyless(0); -tcl_inf("(.%d) ?%s?\n",what,tcl.string_last.data()); - return; - } - else - { - myLevel--; - } - break; - } - myWhite=0; - break; - case 12:// \x1A - if (myLevel==0) - { - myWord=' '; - yy_pop_state(); - yyless(0); -tcl_inf("(%d) ?%s?\n",what,tcl.string_last.data()); - return; - } - if (myLevel!=1 || myList[0] != '.') - { - tcl_war("level=%d expected=%c\n",myLevel,myList[myLevel-1]); - } - myWord=' '; - yy_pop_state(); - yyless(0); -tcl_inf("(.%d) ?%s?\n",what,tcl.string_last.data()); - return; - break; - default: - tcl_err("wrong state: %d\n",what); - return; - } - tcl.string_last += text; -} - -//! Handling of comment parsing. -static void tcl_comment(int what,const char *text) -{ - if (what==0) - { // begin of comment - if (tcl.comment) - { - tcl_err("comment in comment\n"); - return; - } - yy_push_state(COMMENT); -tcl_inf("<- %s\n",text); - tcl.string_comment=""; - tcl.comment=0; - } - else if (what==1) - { // start new comment - if (tcl.comment) - { - tcl_comment(99,""); // inbody - } - tcl.string_comment=text; - tcl.comment=1; - } - else if (what==2) - { // add to comment - if (tcl.comment) - { - tcl.string_comment+=text; - } - } - else if (what==-1 || what == -2) - { // end of comment without/with command - if (tcl.comment) - { - tcl.string_last=tcl.string_comment; - tcl_comment(100+what,""); - } - else - { - tcl.string_last = ""; -tcl_inf("-> %s\n",(const char *)tcl.string_comment); - } - yy_pop_state(); - tcl.string_comment=""; - tcl.comment=0; - } - else if (what==98 || what==99) - { // 98=new 99=inbody - if (tcl.this_parser && tcl.string_comment.length()) - { -tcl_inf("-> %s\n",(const char *)tcl.string_comment); - int myPos=0; - bool myNew=false; - int myLine=tcl.line_comment; - BufStr myI(1024); - BufStr myO(1024); - Protection myProt=tcl.protection; - - // resolve ALIASES - myI.addArray("/*!",3); - myI.addArray(tcl.string_comment.data(),tcl.string_comment.length()); - myI.addArray("*/",2); - convertCppComments(&myI,&myO,tcl.file_name); - myO.dropFromStart(3); - myO.shrink(myO.curPos()-2); - myO.addChar('\0'); - QCString myDoc = myO.data(); - QCString processedDoc; - if (what==99) - { // inbody comment file or namespace or class or proc/method - int myPos0; - int myLine0; - Entry myEntry0; // used to test parsing - Entry *myEntry; - - Entry *myEntry1=NULL; - if (tcl.scan.at(0)->entry_fn) - { - myEntry1=tcl.scan.at(0)->entry_fn; - } - else if (tcl.scan.at(0)->entry_cl) - { - myEntry1=tcl.scan.at(0)->entry_cl; - } - - myPos0=myPos; - myLine0=myLine; - processedDoc = processMarkdownForCommentBlock(myDoc,tcl.file_name,myLine); - while (tcl.commentScanner.parseCommentBlock(tcl.this_parser, &myEntry0, processedDoc, tcl.file_name, - myLine, FALSE, tcl.config_autobrief, FALSE, myProt, myPos, myNew)) - { - if (myNew) - { // we need a new entry in this case - myNew=0; - myEntry = tcl_entry_new(); - processedDoc = processMarkdownForCommentBlock(myDoc,tcl.file_name,myLine0); - tcl.commentScanner.parseCommentBlock(tcl.this_parser, myEntry, processedDoc, tcl.file_name, - myLine0, FALSE, tcl.config_autobrief, FALSE, myProt, myPos0, myNew); - tcl.entry_inside->moveToSubEntryAndRefresh(myEntry); - } - else - { // we can add to current entry in this case - if (!myEntry1) - { - myEntry1=tcl_entry_namespace(tcl.scan.at(0)->ns); - } - processedDoc = processMarkdownForCommentBlock(myDoc,tcl.file_name,myLine0); - tcl.commentScanner.parseCommentBlock(tcl.this_parser, myEntry1, processedDoc, tcl.file_name, - myLine0, FALSE, tcl.config_autobrief, FALSE, myProt, myPos0, myNew); - } - myPos0=myPos; - myLine0=myLine; - } - if (myNew) - { // we need a new entry - myNew=0; - myEntry = tcl_entry_new(); - processedDoc = processMarkdownForCommentBlock(myDoc,tcl.file_name,myLine0); - tcl.commentScanner.parseCommentBlock(tcl.this_parser, myEntry, processedDoc, tcl.file_name, - myLine0, FALSE, tcl.config_autobrief, FALSE, myProt, myPos0, myNew); - tcl.entry_inside->moveToSubEntryAndKeep(myEntry); - } - else - { // we can add to current entry - if (!myEntry1) - { - myEntry1=tcl_entry_namespace(tcl.scan.at(0)->ns); - } - processedDoc = processMarkdownForCommentBlock(myDoc,tcl.file_name,myLine0); - tcl.commentScanner.parseCommentBlock(tcl.this_parser, myEntry1, processedDoc, tcl.file_name, - myLine0, FALSE, tcl.config_autobrief, FALSE, myProt, myPos0, myNew); - } - } - else - { // new entry - tcl.entry_current = tcl_entry_new(); - processedDoc = processMarkdownForCommentBlock(myDoc,tcl.file_name,myLine); - while (tcl.commentScanner.parseCommentBlock(tcl.this_parser, tcl.entry_current, processedDoc, - tcl.file_name, myLine, FALSE, tcl.config_autobrief, FALSE, - myProt, myPos, myNew)) - { - if (myNew) - { - tcl.entry_inside->moveToSubEntryAndKeep(tcl.entry_current); - tcl.entry_current = tcl_entry_new(); - } - else - { - tcl.entry_current->section = tcl.entry_inside->section; - tcl.entry_current->name = tcl.entry_inside->name; - } - } - if (myNew) - { - tcl.entry_inside->moveToSubEntryAndKeep(tcl.entry_current); - tcl.entry_current = tcl_entry_new(); - } - else - { - tcl.entry_current->section = tcl.entry_inside->section; - tcl.entry_current->name = tcl.entry_inside->name; - } - } - if (tcl.protection != myProt) - { - tcl.scan.at(0)->protection = tcl.protection = myProt; - } - } - } - else - { - tcl_err("what %d\n",what); - return; - } -} - -//! Parse given \c arglist . -static void tcl_command_ARGLIST(QCString &arglist) -{ -D - QCStringList myArgs; - QCString myArglist=""; - - tcl_split_list(arglist,myArgs); - for (uint i=0;i<myArgs.count();i++) - { - QCStringList myArgs1; - Argument myArg; - - tcl_split_list(*myArgs.at(i),myArgs1); - if (myArgs1.count()==2) - { - myArg.name= (*myArgs1.at(0)); - myArg.defval= (*myArgs1.at(1)); - if (myArg.defval.isEmpty()) - { - myArg.defval = " "; - } - myArglist += "?" + QCString(myArg.name) + "? "; - } - else - { - myArg.name= (*myArgs.at(i)); - myArglist += myArg.name + " "; - } - tcl.entry_current->argList.push_back(myArg); - } - arglist = myArglist; - tcl.entry_current->args = arglist; -} - -//! Create link. -static void tcl_codify_link(QCString name) -{ - if (tcl.code == NULL || name.isEmpty()) return; - static int init=0; - static QAsciiDict<MemberDef> fn; - if (init==0) - { - init=1; - MemberNameSDict::Iterator mni(*Doxygen::memberNameSDict); - MemberNameSDict::Iterator fni(*Doxygen::functionNameSDict); - MemberName *mn=0; - MemberDef *md; - for (mni.toFirst();(mn=mni.current());++mni) - { - MemberNameIterator mi(*mn); - for (mi.toFirst();(md=mi.current());++mi) - { - fn.insert(md->qualifiedName(),md); - } - } - for (fni.toFirst();(mn=fni.current());++fni) - { - MemberNameIterator fi(*mn); - for (fi.toFirst();(md=fi.current());++fi) - { - fn.insert(md->qualifiedName(),md); - } - } - } - MemberDef *myDef; - QCString myName=name; - if (name.mid(0,2)=="::") // fully qualified global command - { - myName = myName.mid(2); - myDef = fn.find(myName); - } - else // not qualified name - { - QCString myName1=myName; - myDef = NULL; - myName1 = tcl.scan.at(0)->ns; - if (myName1 == " " || myName1 == "") - { - myName1 = myName; - } - else - { - myName1 = myName1 + "::" + myName; - } - myDef = fn.find(myName1); // search namespace command - if (myDef == NULL) - { - myDef = fn.find(myName); // search global command - } - } - if (myDef != NULL) // documented command - { - tcl.code->writeCodeLink(myDef->getReference().data(), - myDef->getOutputFileBase().data(), - myDef->anchor().data(), - name, - myDef->qualifiedName().data()); - if (tcl.memberdef) - { - myDef->addSourceReferencedBy(tcl.memberdef); - //tcl.memberdef->addSourceReferences(myDef); - } else { - Entry* callerEntry; - unsigned int i; - // walk the stack of scan contexts and find the enclosing method or proc - for (i=0;i<tcl.scan.count();i++) - { - callerEntry=tcl.scan.at(i)->entry_scan; - if (callerEntry->mtype==Method && !callerEntry->name.isEmpty()) - { - break; - } - } - if (i<tcl.scan.count()) - { - // enclosing method found - QCString callerName = callerEntry->name; - if (callerName.mid(0,2)=="::") // fully qualified global command - { - callerName = callerName.mid(2); - } - else - { - if (!(tcl.scan.at(0)->ns.stripWhiteSpace().isEmpty())) - { - callerName = tcl.scan.at(0)->ns + "::" + callerEntry->name; - } - } - MemberDef *callerDef=NULL; - callerDef = fn.find(callerName); - if (callerDef!=NULL && myDef!= NULL && tcl.collectXRefs) - { - addDocCrossReference(callerDef,myDef); - } - } - } - } - else if (tcl_keyword(myName)) // check keyword - { - tcl_codify("keyword",name); - } - else - { - tcl_codify(NULL,name); // something else - } - -} - -//! scan general argument for brackets -// -// parses (*tcl.list_commandwords.at(i)) and checks for brackets. -// Starts a new scan context if needed (*myScan==0 and brackets found). -// Returns NULL or the created scan context. -// -static tcl_scan *tcl_command_ARG(tcl_scan *myScan, unsigned int i, bool ignoreOutermostBraces) -{ - QCString myName; - bool insideQuotes=false; - unsigned int insideBrackets=0; - unsigned int insideBraces=0; - myName = (*tcl.list_commandwords.at(i)); - if (i%2 != 0) - { - // handle white space - myScan = tcl_codify_token(myScan, "NULL", myName); - } - else - { - QCString myStr = ""; - unsigned int j; - for (j=0;j<myName.length();j++) - { - QChar c = myName[j]; - bool backslashed = false; - if (j>0) - { - backslashed = myName[j-1]=='\\'; - } - // this is a state machine - // input is c - // internal state is myScan and insideXXX - // these are the transitions: - if (c=='[' && !backslashed && insideBraces==0) - { - insideBrackets++; - } - if (c==']' && !backslashed && insideBraces==0 && insideBrackets>0) - { - insideBrackets--; - } - if (c=='{' && !backslashed && !insideQuotes && !(ignoreOutermostBraces && j==0)) - { - insideBraces++; - } - if (c=='}' && !backslashed && !insideQuotes && insideBraces>0) - { - insideBraces--; - } - if (c=='"' && !backslashed && insideBraces==0) - { - insideQuotes=!insideQuotes; - } - // all output, depending on state and input - if (c=='[' && !backslashed && insideBrackets==1 && insideBraces==0) - { - // the first opening bracket, output what we have so far - myStr+=c; - myScan = tcl_codify_token(myScan, "NULL", myStr); - myStr=""; - } - else if (c==']' && !backslashed && insideBrackets==0 && insideBraces==0) - { - // the last closing bracket, start recursion, switch to deferred - myScan = tcl_codify_token(myScan, "script", myStr); - myStr=""; - myStr+=c; - } - else - { - myStr+=c; - } - } - if (i == 0 && myScan == NULL) - { - tcl_codify_link(myStr); - } - else - { - myScan = tcl_codify_token(myScan, "NULL", myStr); - } - } - return (myScan); -} - -//! Handle internal tcl commands. -// "eval arg ?arg ...?" -static void tcl_command_EVAL() -{ -D - tcl_codify_cmd("keyword", 0); - tcl_scan *myScan = tcl.scan.at(0); - QCString myString = ""; - // we simply rescan the line without the eval - // we include leading whitespace because tcl_scan_start will examine - // the first char. If it finds a bracket it will assume one expression in brackets. - // Example: eval [list set] [list NotInvoked] [Invoked NotInvoked] - for (unsigned int i = 1; i < tcl.list_commandwords.count(); i++) - { - myString += (*tcl.list_commandwords.at(i)); - } - myScan = tcl_scan_start('?', myString, - myScan->ns, myScan->entry_cl, myScan->entry_fn); -} - -//! Handle internal tcl commands. -// switch ?options? string pattern body ?pattern body ...? -// switch ?options? string {pattern body ?pattern body ...?} -static void tcl_command_SWITCH() -{ -D - tcl_codify_cmd("keyword",0); - tcl_codify_cmd(NULL,1); - tcl_scan *myScan=NULL; - unsigned int i; - QCString token; - // first: find the last option token - unsigned int lastOptionIndex = 0; - for (i = 2; i<tcl.list_commandwords.count(); i += 2) - { - token = (*tcl.list_commandwords.at(i)); - if (token == "--") - { - lastOptionIndex = i; - break; - } - if (token[0] == '-' && i - lastOptionIndex == 2) - { - // options start with dash and should form a continuous chain - lastOptionIndex = i; - } - } - // second: eat up options - for (i = 2; i <= lastOptionIndex; i++) - { - myScan = tcl_command_ARG(myScan, i, false); - } - // third: how many tokens are left? - if (tcl.list_commandwords.count() - lastOptionIndex == 5) - { - //printf("syntax: switch ?options? string {pattern body ?pattern body ...?}\n"); - myScan = tcl_command_ARG(myScan, lastOptionIndex + 1, false); - myScan = tcl_command_ARG(myScan, lastOptionIndex + 2, false); - myScan = tcl_command_ARG(myScan, lastOptionIndex + 3, false); - // walk trough the list step by step - // this way we can preserve whitespace - bool inBraces = false; - bool nextIsPattern = true; - int size; - const char *elem; - const char *next; - token = (*tcl.list_commandwords.at(lastOptionIndex + 4)); - if (token[0] == '{') - { - inBraces = true; - token = token.mid(1, token.length() - 2); - myScan = tcl_codify_token(myScan, "NULL", QCString("{")); - } - // ToDo: check if multibyte chars are handled correctly - while (token.length() > 0) - { - TclFindElement((const char*)token, token.length(), &elem, &next, &size, NULL); - //printf("%s\nstart=%d, elem=%d, next=%d, size=%d, brace=%d\n", - // (const char*) token, (const char*) token, elem, next, size, brace); - // - // handle leading whitespace/opening brace/double quotes - if (elem - token > 0) - { - myScan = tcl_codify_token(myScan, "NULL", token.left((uint)(elem - token))); - } - // handle actual element without braces/double quotes - if (nextIsPattern) - { - myScan = tcl_codify_token(myScan, "NULL", token.mid((uint)(elem - token),size)); - //printf("pattern=%s\n",(const char*) token.mid(elem - token, size)); - } - else { - myScan = tcl_codify_token(myScan, "script", token.mid((uint)(elem - token), size)); - //printf("script =%s\n", (const char*) token.mid(elem - token, size)); - } - // handle trailing whitespace/closing brace/double quotes - if (next - elem - size > 0) - { - myScan = tcl_codify_token(myScan, "NULL", token.mid((uint)(elem - token + size), (uint)(next - elem - size))); - } - nextIsPattern = !nextIsPattern; - token = token.mid((int)(next - token)); - } - if (inBraces) - { - myScan = tcl_codify_token(myScan, "NULL", QCString("}")); - } - if (!nextIsPattern) - { - tcl_war("Invalid switch syntax: last token is not a list of even elements.\n"); - //tcl_war("%s\n", tcl.list_commandwords.join(" ").ascii()); - } - } - else if ((tcl.list_commandwords.count() - lastOptionIndex > 6) && - ((tcl.list_commandwords.count() - lastOptionIndex-3) % 4 == 0)) - { - //printf("detected: switch ?options? string pattern body ?pattern body ...?\n"); - myScan = tcl_command_ARG(myScan, lastOptionIndex + 1, false); - myScan = tcl_command_ARG(myScan, lastOptionIndex + 2, false); - //printf("value=%s\n",(const char*) (*tcl.list_commandwords.at(lastOptionIndex + 2))); - for (i = lastOptionIndex + 3; i < tcl.list_commandwords.count(); i += 4) - { - myScan = tcl_command_ARG(myScan, i + 0, false); // whitespace - myScan = tcl_command_ARG(myScan, i + 1, false); // pattern - myScan = tcl_command_ARG(myScan, i + 2, false); // whitespace - myScan = tcl_codify_token(myScan, "script", (*tcl.list_commandwords.at(i+3))); // script - //printf("pattern=%s\n",(const char*) (*tcl.list_commandwords.at(i+1)))); - //printf("script=%s\n",(const char*) (*tcl.list_commandwords.at(i+3))); - } - } - else - { - // not properly detected syntax - tcl_war("Invalid switch syntax: %d options followed by %d tokens.\n", - lastOptionIndex / 2, (tcl.list_commandwords.count() - 1) / 2 - lastOptionIndex / 2); - for (i = lastOptionIndex + 1; i <= tcl.list_commandwords.count(); i++) - { - myScan = tcl_command_ARG(myScan, i, false); - } - } -} - -//! Handle internal tcl commands. -// "catch script ?resultVarName? ?optionsVarName?" -static void tcl_command_CATCH() -{ -D - tcl_codify_cmd("keyword", 0); - tcl_codify_cmd(NULL, 1); - tcl_scan *myScan = tcl.scan.at(0); - myScan = tcl_scan_start('?', *tcl.list_commandwords.at(2), - myScan->ns, myScan->entry_cl, myScan->entry_fn); - for (unsigned int i = 3; i < tcl.list_commandwords.count(); i++) - { - myScan = tcl_command_ARG(myScan, i, false); - } -} - -//! Handle internal tcl commands. -// "if expr1 ?then? body1 elseif expr2 ?then? body2 elseif ... ?else? ?bodyN?" -static void tcl_command_IF(QCStringList type) -{ -D - tcl_codify_cmd("keyword",0); - tcl_codify_cmd(NULL,1); - tcl_scan *myScan = NULL; - myScan = tcl_command_ARG(myScan, 2, true); - for (unsigned int i = 3;i<tcl.list_commandwords.count();i++) - { - if (type[i] == "expr") - { - myScan = tcl_command_ARG(myScan, i, true); - } - else - { - if (myScan!=0) - { - myScan->after << type[i] << tcl.list_commandwords[i]; - } - else - { - myScan=tcl.scan.at(0); - myScan = tcl_scan_start('?',*tcl.list_commandwords.at(i), - myScan->ns,myScan->entry_cl,myScan->entry_fn); - } - } - } -} -//! Handle internal tcl commands. -// "for start test next body" -static void tcl_command_FOR() -{ -D - tcl_codify_cmd("keyword",0); - tcl_codify_cmd(NULL,1); - tcl_scan *myScan=tcl.scan.at(0); - myScan = tcl_scan_start('?',*tcl.list_commandwords.at(2), - myScan->ns,myScan->entry_cl,myScan->entry_fn); - myScan->after << "NULL" << tcl.list_commandwords[3]; - myScan = tcl_command_ARG(myScan, 4, true); - myScan->after << "NULL" << tcl.list_commandwords[5]; - myScan->after << "script" << tcl.list_commandwords[6]; - myScan->after << "NULL" << tcl.list_commandwords[7]; - myScan->after << "script" << tcl.list_commandwords[8]; -} - -///! Handle internal tcl commands. -// "foreach varname list body" and -// "foreach varlist1 list1 ?varlist2 list2 ...? body" -static void tcl_command_FOREACH() -{ -D - unsigned int i; - tcl_scan *myScan=NULL; - tcl_codify_cmd("keyword",0); - for (i = 1;i<tcl.list_commandwords.count()-1;i++) - { - myScan = tcl_command_ARG(myScan, i, false); - } - if (myScan!=0) - { - myScan->after << "script" << tcl.list_commandwords[tcl.list_commandwords.count()-1]; - } - else - { - myScan=tcl.scan.at(0); - myScan = tcl_scan_start('?',*tcl.list_commandwords.at(tcl.list_commandwords.count()-1), - myScan->ns,myScan->entry_cl,myScan->entry_fn); - } -} - -///! Handle internal tcl commands. -// "while test body" -static void tcl_command_WHILE() -{ -D - tcl_codify_cmd("keyword",0); - tcl_codify_cmd(NULL,1); - tcl_scan *myScan = NULL; - myScan = tcl_command_ARG(myScan, 2, true); - myScan = tcl_command_ARG(myScan, 3, false); - if (myScan!=0) - { - myScan->after << "script" << tcl.list_commandwords[4]; - } - else - { - myScan=tcl.scan.at(0); - myScan = tcl_scan_start('?',*tcl.list_commandwords.at(4), - myScan->ns,myScan->entry_cl,myScan->entry_fn); - } -} - -//! Handle all other commands. -// Create links of first command word or first command word inside []. -static void tcl_command_OTHER() -{ - tcl_scan *myScan=NULL; - for (unsigned int i=0; i< tcl.list_commandwords.count(); i++) - { - myScan = tcl_command_ARG(myScan, i, false); - } -} - -//! Handle \c proc statements. -static void tcl_command_PROC() -{ -D - QCString myNs, myName; - Entry *myEntryNs; - Entry *myEntry; - tcl_scan *myScan = tcl.scan.at(0); - - tcl_codify_cmd("keyword",0); - tcl_codify_cmd(NULL,1); - tcl_codify_cmd(NULL,2); - tcl_codify_cmd(NULL,3); - tcl_codify_cmd(NULL,4); - tcl_codify_cmd(NULL,5); - tcl_name_SnippetAware(myScan->ns,(*tcl.list_commandwords.at(2)),myNs,myName); - if (myNs.length()) - { - myEntryNs = tcl_entry_namespace(myNs); - } - else - { - myEntryNs = tcl_entry_namespace(myScan->ns); - } - //why not needed here? tcl.fn.remove(myName); - tcl.entry_current->section = Entry::FUNCTION_SEC; - tcl.entry_current->mtype = Method; - tcl.entry_current->name = myName; - tcl.entry_current->startLine = tcl.line_command; - tcl.entry_current->docLine = tcl.line_comment; - tcl.entry_current->inbodyLine = tcl.line_comment; - tcl.entry_current->bodyLine = tcl.line_body0; - tcl.entry_current->endBodyLine = tcl.line_body1; - tcl_protection(tcl.entry_current); - tcl_command_ARGLIST(*tcl.list_commandwords.at(4)); - myEntryNs->moveToSubEntryAndKeep(tcl.entry_current); - myEntry = tcl.entry_current; - tcl.fn.insert(myName,myEntry); - myScan = tcl_scan_start(tcl.word_is,*tcl.list_commandwords.at(6), - myEntryNs->name,NULL,myEntry); -} - -//! Handle \c itcl::body statements and \c oo::define method and method inside \c itcl::class statements. -static void tcl_command_METHOD() -{ -D - QCString myNs, myName; - Entry *myEntryCl, *myEntry; - tcl_scan *myScan = tcl.scan.at(0); - - tcl_codify_cmd("keyword",0); - tcl_codify_cmd(NULL,1); - tcl_codify_cmd(NULL,2); - tcl_codify_cmd(NULL,3); - tcl_codify_cmd(NULL,4); - tcl_codify_cmd(NULL,5); - tcl_name(myScan->ns,(*tcl.list_commandwords.at(2)),myNs,myName); - if (myNs.length()) - { - myEntryCl = tcl_entry_class(myNs); - } - else - { - myNs = myScan->ns; - myEntryCl = myScan->entry_cl; - } - // needed in case of more then one definition p.e. itcl::method and itcl::body - // see also bug # - tcl.fn.remove(myName); - tcl.entry_current->section = Entry::FUNCTION_SEC; - tcl.entry_current->mtype = Method; - tcl.entry_current->name = myName; - tcl.entry_current->startLine = tcl.line_command; - tcl.entry_current->docLine = tcl.line_comment; - tcl.entry_current->inbodyLine = tcl.line_comment; - tcl.entry_current->bodyLine = tcl.line_body0; - tcl.entry_current->endBodyLine = tcl.line_body1; - tcl_protection(tcl.entry_current); - tcl_command_ARGLIST(*tcl.list_commandwords.at(4)); - myEntryCl->moveToSubEntryAndKeep(tcl.entry_current); - tcl.fn.insert(myName,tcl.entry_current); - myEntry = tcl.entry_current; - myScan = tcl_scan_start(tcl.word_is,*tcl.list_commandwords.at(6), - myNs, myEntryCl, myEntry); -} - -//! Handle \c constructor statements inside class definitions. -static void tcl_command_CONSTRUCTOR() -{ -D - QCString myNs, myName; - Entry *myEntryCl, *myEntry; - tcl_scan *myScan = tcl.scan.at(0); - - tcl_codify_cmd("keyword",0); - tcl_codify_cmd(NULL,1); - tcl_codify_cmd(NULL,2); - tcl_codify_cmd(NULL,3); - tcl_name(myScan->ns,(*tcl.list_commandwords.at(0)),myNs,myName); - if (myNs.length()) - { - myEntryCl = tcl_entry_class(myNs); - } - else - { - myNs = myScan->ns; - myEntryCl = myScan->entry_cl; - } - tcl.entry_current->section = Entry::FUNCTION_SEC; - tcl.entry_current->mtype = Method; - tcl.entry_current->name = myName; - tcl.entry_current->startLine = tcl.line_command; - tcl.entry_current->docLine = tcl.line_comment; - tcl.entry_current->inbodyLine = tcl.line_comment; - tcl.entry_current->bodyLine = tcl.line_body0; - tcl.entry_current->endBodyLine = tcl.line_body1; - tcl_protection(tcl.entry_current); - tcl_command_ARGLIST(*tcl.list_commandwords.at(2)); - if (myEntryCl) myEntryCl->moveToSubEntryAndKeep(tcl.entry_current); - myEntry = tcl.entry_current; - tcl.fn.insert(myName,myEntry); - myScan = tcl_scan_start(tcl.word_is,*tcl.list_commandwords.at(4), - myNs, myEntryCl, myEntry); -} - -//! Handle \c destructor statements inside class definitions. -static void tcl_command_DESTRUCTOR() -{ -D - QCString myNs, myName; - Entry *myEntryCl, *myEntry; - tcl_scan *myScan = tcl.scan.at(0); - - tcl_codify_cmd("keyword",0); - tcl_codify_cmd(NULL,1); - tcl_name(myScan->ns,(*tcl.list_commandwords.at(0)),myNs,myName); - if (myNs.length()) - { - myEntryCl = tcl_entry_class(myNs); - } - else - { - myNs = myScan->ns; - myEntryCl = myScan->entry_cl; - } - tcl.entry_current->section = Entry::FUNCTION_SEC; - tcl.entry_current->mtype = Method; - tcl.entry_current->name = myName; - tcl.entry_current->startLine = tcl.line_command; - tcl.entry_current->docLine = tcl.line_comment; - tcl.entry_current->inbodyLine = tcl.line_comment; - tcl.entry_current->bodyLine = tcl.line_body0; - tcl.entry_current->endBodyLine = tcl.line_body1; - tcl_protection(tcl.entry_current); - myEntryCl->moveToSubEntryAndKeep(tcl.entry_current); - myEntry = tcl.entry_current; - tcl.fn.insert(myName,myEntry); - myScan = tcl_scan_start(tcl.word_is,*tcl.list_commandwords.at(2), - myNs, myEntryCl, myEntry); -} - -//! Handle \c namespace statements. -static bool tcl_command_NAMESPACE() -{ -D - QCString myNs, myName, myStr; - //Entry *myEntryNs=NULL; - tcl_scan *myScan = tcl.scan.at(0); - - tcl_name(myScan->ns,(*tcl.list_commandwords.at(4)),myNs,myName); - if (myName.isEmpty()) return false; // not a namespace - tcl_codify_cmd("keyword",0); - tcl_codify_cmd(NULL,1); - tcl_codify_cmd("keyword",2); - tcl_codify_cmd(NULL,3); - tcl_codify_cmd(NULL,4); - tcl_codify_cmd(NULL,5); - if (!myNs.isEmpty()) - { - myName = myNs+"::"+myName; - } - tcl.entry_current->section = Entry::NAMESPACE_SEC; - tcl.entry_current->name = myName; - tcl.entry_current->startLine = tcl.line_command; - tcl.entry_current->docLine = tcl.line_comment; - tcl.entry_current->inbodyLine = tcl.line_comment; - tcl.entry_current->bodyLine = tcl.line_body0; - tcl.entry_current->endBodyLine = tcl.line_body1; - tcl.entry_main->moveToSubEntryAndKeep(tcl.entry_current); - tcl.ns.insert(myName,tcl.entry_current); - //myEntryNs = tcl.entry_current; - myStr = (*tcl.list_commandwords.at(6)); - if (tcl.list_commandwords.count() > 7) - { - for (uint i=7;i<tcl.list_commandwords.count();i++) - { - myStr.append((*tcl.list_commandwords.at(i))); - } - tcl.word_is=' '; - } - myScan = tcl_scan_start(tcl.word_is,myStr, myName, NULL, NULL); - return true; -} - -//! Handle \c itcl::class statements. -static void tcl_command_ITCL_CLASS() -{ -D - QCString myNs, myName; - Entry *myEntryCl; - tcl_scan *myScan = tcl.scan.at(0); - - tcl_codify_cmd("keyword",0); - tcl_codify_cmd(NULL,1); - tcl_codify_cmd("NULL",2); - tcl_codify_cmd("NULL",3); - tcl_name(myScan->ns,(*tcl.list_commandwords.at(2)),myNs,myName); - if (myNs.length()) - { - myName = myNs+"::"+myName; - } - tcl.entry_current->section = Entry::CLASS_SEC; - tcl.entry_current->name = myName; - tcl.entry_current->startLine = tcl.line_command; - tcl.entry_current->docLine = tcl.line_comment; - tcl.entry_current->inbodyLine = tcl.line_comment; - tcl.entry_current->bodyLine = tcl.line_body0; - tcl.entry_current->endBodyLine = tcl.line_body1; - tcl.entry_main->moveToSubEntryAndKeep(tcl.entry_current); - tcl.cl.insert(myName,tcl.entry_current); - myEntryCl = tcl.entry_current; - myScan = tcl_scan_start(tcl.word_is,*tcl.list_commandwords.at(4), - myName, myEntryCl, NULL); -} - -//! Handle \c oo::class statements. -static void tcl_command_OO_CLASS() -{ -D - QCString myNs, myName; - //Entry *myEntryNs; - Entry *myEntryCl; - tcl_scan *myScan = tcl.scan.at(0); - - tcl_codify_cmd("keyword",0); - tcl_codify_cmd(NULL,1); - tcl_codify_cmd("NULL",2); - tcl_codify_cmd("NULL",3); - tcl_codify_cmd("NULL",4); - tcl_codify_cmd("NULL",5); - tcl_name(myScan->ns,(*tcl.list_commandwords.at(4)),myNs,myName); - if (myNs.length()) - { - myName = myNs+"::"+myName; - } - tcl.entry_current->section = Entry::CLASS_SEC; - tcl.entry_current->name = myName; - tcl.entry_current->startLine = tcl.line_command; - tcl.entry_current->docLine = tcl.line_comment; - tcl.entry_current->inbodyLine = tcl.line_comment; - tcl.entry_current->bodyLine = tcl.line_body0; - tcl.entry_current->endBodyLine = tcl.line_body1; - tcl.entry_main->moveToSubEntryAndKeep(tcl.entry_current); - //myEntryNs = tcl_entry_namespace(myName); - tcl.cl.insert(myName,tcl.entry_current); - myEntryCl = tcl.entry_current; - myScan = tcl_scan_start(tcl.word_is,*tcl.list_commandwords.at(6), - myName, myEntryCl, NULL); -} - -//! Handle \c oo::define statements. -static void tcl_command_OO_DEFINE() -{ -D - QCString myNs, myName, myStr; - Entry *myEntryCl; - tcl_scan *myScan = tcl.scan.at(0); - - tcl_codify_cmd("keyword",0); - tcl_codify_cmd(NULL,1); - tcl_codify_cmd("NULL",2); - tcl_codify_cmd("NULL",3); - tcl_name(myScan->ns,(*tcl.list_commandwords.at(2)),myNs,myName); - if (myNs.length()) - { - myName = myNs+"::"+myName; - } - myEntryCl = tcl_entry_class(myName); - myStr = (*tcl.list_commandwords.at(4)); - // - // special cases first - // oo::define classname method methodname args script - // oo::define classname constructor argList bodyScript - // oo::define classname destructor bodyScript - unsigned int n =tcl.list_commandwords.count(); - if ((myStr == "method" && n == 11) || - (myStr == "constructor" && n == 9) || - (myStr == "destructor" && n == 7)) - { - for (unsigned int i = 4; i < n-1; i++) - { - tcl_codify_cmd("NULL",i); - } - Entry *myEntry; - QCString myMethod; - tcl_name(myScan->ns,(*tcl.list_commandwords.at(n==11?6:4)),myNs,myMethod); - // code snippet taken from tcl_command_METHOD()/tcl_command_CONSTRUCTOR - tcl.fn.remove(myMethod); - tcl.entry_current->section = Entry::FUNCTION_SEC; - tcl.entry_current->mtype = Method; - tcl.entry_current->name = myMethod; - tcl.entry_current->startLine = tcl.line_command; - tcl.entry_current->docLine = tcl.line_comment; - tcl.entry_current->inbodyLine = tcl.line_comment; - tcl.entry_current->bodyLine = tcl.line_body0; - tcl.entry_current->endBodyLine = tcl.line_body1; - tcl_protection(tcl.entry_current); - if (n==11) - { - tcl_command_ARGLIST(*tcl.list_commandwords.at(8)); - } - else if (n==9) - { - tcl_command_ARGLIST(*tcl.list_commandwords.at(6)); - } - if (myEntryCl) myEntryCl->moveToSubEntryAndKeep(tcl.entry_current); - tcl.fn.insert(myMethod,tcl.entry_current); - myEntry = tcl.entry_current; - myScan = tcl_scan_start('?',*tcl.list_commandwords.at(n-1), - myNs, myEntryCl, myEntry); - } - else - { - // The general case - // Simply concat all arguments into a script. - // Note: all documentation collected just before the - // oo::define command is lost - if (tcl.list_commandwords.count() > 5) - { - for (uint i=5;i<tcl.list_commandwords.count();i++) - { - myStr.append((*tcl.list_commandwords.at(i))); - } - tcl.word_is=' '; - } - myScan = tcl_scan_start(tcl.word_is,myStr,myName,myEntryCl,NULL); - } -} - -//! Handle \c variable statements. -static void tcl_command_VARIABLE(int inclass) -{ -D - QCString myNs, myName; - Entry *myEntry; - tcl_scan *myScan = tcl.scan.at(0); - - tcl_codify_cmd("keyword",0); - for (unsigned int i=1; i< tcl.list_commandwords.count(); i++) - { - tcl_codify_cmd(NULL,i); - } - tcl_name(myScan->ns,(*tcl.list_commandwords.at(2)),myNs,myName); - if (myNs.length()) - {// qualified variables go into namespace - myEntry = tcl_entry_namespace(myNs); - tcl.entry_current->stat = true; - } - else - { - if (inclass) - { - myEntry = myScan->entry_cl; - tcl.entry_current->stat = false; - } - else - { - myEntry = tcl_entry_namespace(myScan->ns); - tcl.entry_current->stat = true; - } - } - tcl.entry_current->section = Entry::VARIABLE_SEC; - tcl.entry_current->name = myName; - tcl.entry_current->startLine = tcl.line_command; - tcl.entry_current->docLine = tcl.line_comment; - tcl.entry_current->inbodyLine = tcl.line_comment; - tcl.entry_current->bodyLine = tcl.line_body0; - tcl.entry_current->endBodyLine = tcl.line_body1; - tcl_protection(tcl.entry_current); - myEntry->moveToSubEntryAndKeep(tcl.entry_current); - tcl.entry_current = tcl_entry_new(); -} - -//! Handling of command parsing. -//! what=0 -> ... -//! what=1 -> ... -//! what=-1 -> ... -static void tcl_command(int what,const char *text) -{ - int myLine=0; - if (what==0) - { - tcl.scan.at(0)->line1=yylineno;// current line in scan context - tcl.line_body0=yylineno;// start line of command -tcl_inf("<- %s\n",text); - yy_push_state(COMMAND); - tcl.list_commandwords.clear(); - tcl.string_command=""; - tcl.string_last=""; - tcl.command=1; - return; - } - else if (what==1) - { - if (tcl.string_last.length()) - { - tcl.list_commandwords.append(tcl.string_last); - tcl.string_last=""; - } - if (text) - { - tcl.list_commandwords.append(text); - } - return; - } - else if (what!=-1) - {// should not happen - tcl_err("what %d\n",what); - return; - } - QCString myText = text; -tcl_inf("->\n"); - if (tcl.command==0) - { - return; //TODO check on inside comment - } - if (tcl.string_last != "") - {// get last word - tcl.list_commandwords.append(tcl.string_last); - tcl.string_last=""; - } - yy_pop_state(); - - // check command - QCString myStr = (*tcl.list_commandwords.at(0)); - tcl_scan *myScanBackup=tcl.scan.at(0); - int myLevel = 0; - Protection myProt = tcl.protection; - - if (tcl.list_commandwords.count() < 3) - { - tcl_command_OTHER(); - goto command_end; - } - // remove leading "::" and apply TCL_SUBST - if (myStr.left(2)=="::") myStr = myStr.mid(2); - if (tcl.config_subst.contains(myStr)) - { - myStr=tcl.config_subst[myStr]; - } - if (myStr=="private") - { - tcl.protection = Private; - myLevel = 1; - } - else if (myStr=="protected") - { - tcl.protection = Protected; - myLevel = 1; - } - else if (myStr=="public") - { - tcl.protection = Public; - myLevel = 1; - } - if (myLevel) - { - tcl_codify_cmd("keyword",0); - tcl_codify_cmd(NULL,1); - tcl.list_commandwords.remove(tcl.list_commandwords.at(1)); - tcl.list_commandwords.remove(tcl.list_commandwords.at(0)); - if (tcl.list_commandwords.count()==1) - { - tcl_scan *myScan = tcl.scan.at(0); - myScan = tcl_scan_start(tcl.word_is,*tcl.list_commandwords.at(0), - myScan->ns,myScan->entry_cl,myScan->entry_fn); - myProt = tcl.protection; - goto command_end; - } - myStr = (*tcl.list_commandwords.at(0)); - // remove leading "::" and apply TCL_SUBST - if (myStr.left(2)=="::") myStr = myStr.mid(2); - if (tcl.config_subst.contains(myStr)) - { - myStr=tcl.config_subst[myStr]; - } - } - if (myStr=="proc") - { - if (tcl.list_commandwords.count() == 5) - {// itcl::proc - tcl.list_commandwords.append(""); - tcl.list_commandwords.append(""); - } - if (tcl.list_commandwords.count() != 7) {myLine=__LINE__;goto command_warn;} - tcl_command_PROC(); - goto command_end; - } - if (myStr=="method") - { - if (tcl.list_commandwords.count() == 5) - {// itcl::method - tcl.list_commandwords.append(""); - tcl.list_commandwords.append(""); - } - if (tcl.list_commandwords.count() != 7) {myLine=__LINE__;goto command_warn;} - tcl_command_METHOD(); - goto command_end; - } - if (myStr=="constructor") - { - if (tcl.list_commandwords.count() != 5) {myLine=__LINE__;goto command_warn;} - tcl_command_CONSTRUCTOR(); - goto command_end; - } - if (myStr=="destructor") - { - if (tcl.list_commandwords.count() != 3) {myLine=__LINE__;goto command_warn;} - tcl_command_DESTRUCTOR(); - goto command_end; - } - if (myStr=="namespace") - { - if ((*tcl.list_commandwords.at(2))=="eval") - { - if (tcl.list_commandwords.count() < 7) {myLine=__LINE__;goto command_warn;} - if (tcl_command_NAMESPACE()) - { - goto command_end; - } - } - else - { - tcl_command_OTHER(); - goto command_end; - } - } - if (myStr=="itcl::class") - { - if (tcl.list_commandwords.count() != 5) {myLine=__LINE__;goto command_warn;} - tcl_command_ITCL_CLASS(); - goto command_end; - } - if (myStr=="itcl::body") - { - if (tcl.list_commandwords.count() != 7) {myLine=__LINE__;goto command_warn;} - tcl_command_METHOD(); - goto command_end; - } - if (myStr=="oo::class") - { - if ((*tcl.list_commandwords.at(2))=="create") - { - if (tcl.list_commandwords.count() != 7) {myLine=__LINE__;goto command_warn;} - tcl_command_OO_CLASS(); - goto command_end; - } - tcl_command_OTHER(); - goto command_end; - } - if (myStr=="oo::define") - { - if (tcl.list_commandwords.count() < 5) {myLine=__LINE__;goto command_warn;} - tcl_command_OO_DEFINE(); - goto command_end; - } - if (myStr=="variable") - { - if (tcl.list_commandwords.count() < 3) {myLine=__LINE__;goto command_warn;} - if (tcl.scan.at(0)->entry_fn == NULL) - {// only parsed outside functions - tcl_command_VARIABLE(tcl.scan.at(0)->entry_cl && tcl.scan.at(0)->entry_cl->name!=""); - goto command_end; - } - } - if (myStr=="common") - { - if (tcl.list_commandwords.count() < 3) {myLine=__LINE__;goto command_warn;} - if (tcl.scan.at(0)->entry_fn == NULL) - {// only parsed outside functions - tcl_command_VARIABLE(0); - goto command_end; - } - } - if (myStr=="inherit" || myStr=="superclass") - { - if (tcl.list_commandwords.count() < 3) {myLine=__LINE__;goto command_warn;} - if (tcl.scan.at(0)->entry_cl && tcl.scan.at(0)->entry_cl->name!="") - { - for (unsigned int i = 2; i < tcl.list_commandwords.count(); i = i + 2) - { - tcl.scan.at(0)->entry_cl->extends.push_back(BaseInfo((*tcl.list_commandwords.at(i)),Public,Normal)); - } - } - goto command_end; - } - /* - * Start of internal tcl keywords - * Ready: switch, eval, catch, if, for, foreach, while - */ - if (myStr=="switch") - { - if (tcl.list_commandwords.count() < 5) {myLine=__LINE__;goto command_warn;} - tcl_command_SWITCH(); - goto command_end; - } - if (myStr=="eval") - { - if (tcl.list_commandwords.count() < 3) {myLine=__LINE__;goto command_warn;} - tcl_command_EVAL(); - goto command_end; - } - if (myStr=="catch") - { - if (tcl.list_commandwords.count() < 3) {myLine=__LINE__;goto command_warn;} - tcl_command_CATCH(); - goto command_end; - } - if (myStr=="for") - { - if (tcl.list_commandwords.count() != 9) {myLine=__LINE__;goto command_warn;} - tcl_command_FOR(); - goto command_end; - } - if (myStr=="foreach") - { - if (tcl.list_commandwords.count() < 7 || tcl.list_commandwords.count()%2==0) {myLine=__LINE__;goto command_warn;} - tcl_command_FOREACH(); - goto command_end; - } - /* -if expr1 ?then? body1 elseif expr2 ?then? body2 elseif ... ?else? ?bodyN? - */ - if (myStr=="if" && tcl.list_commandwords.count() > 4) - { - QCStringList myType; - myType << "keyword" << "NULL" << "expr" << "NULL"; - char myState='x';// last word: e'x'pr 't'hen 'b'ody 'e'lse else'i'f.. - for (unsigned int i = 4; i < tcl.list_commandwords.count(); i = i + 2) - { - myStr=(*tcl.list_commandwords.at(i)); - if (myState=='x') - { - if (myStr=="then") - { - myState='t'; - myType << "keyword" << "NULL"; - } - else - { - myState='b'; - myType << "script" << "NULL"; - } - } - else if (myState=='t') - { - myState='b'; - myType << "script" << "NULL"; - } - else if (myState=='b') - { - if (myStr=="elseif") { - myState='i'; - myType << "keyword" << "NULL"; - } - else if (myStr=="else" && i==tcl.list_commandwords.count()-3) - { - myState = 'b'; - myType << "keyword" << "NULL" << "script"; - i = tcl.list_commandwords.count(); - } - else if (i==tcl.list_commandwords.count()-1) - { - myState = 'b'; - myType << "script"; - i = tcl.list_commandwords.count(); - } - else - { - myLine=__LINE__;goto command_warn; - } - } - else if (myState=='i') - { - myState='x'; - myType << "expr" << "NULL"; - } - } - if (myState != 'b') {myLine=__LINE__;goto command_warn;} - tcl_command_IF(myType); - goto command_end; - } - if (myStr=="while") - { - if (tcl.list_commandwords.count() != 5) {myLine=__LINE__;goto command_warn;} - tcl_command_WHILE(); - goto command_end; - } - tcl_command_OTHER(); - goto command_end; - command_warn:// print warning message because of wrong used syntax - tcl_war("%d count=%d: %s\n",myLine,tcl.list_commandwords.count(),tcl.list_commandwords.join(" ").data()); - tcl_command_OTHER(); - command_end:// add remaining text to current context - if (!myText.isEmpty()) - { - if(myScanBackup==tcl.scan.at(0)) - { - tcl_codify("comment",myText); - } - else - { - tcl.scan.at(0)->after << "comment" << myText; - } - } - tcl.list_commandwords.clear(); - tcl.command = 0; - tcl.protection = myProt; -} - -//---------------------------------------------------------------------------- -//! Common initializations. -static void tcl_init() -{ - // Get values from option TCL_SUBST - tcl.config_subst.clear(); - QStrList myStrList = Config_getList(TCL_SUBST); - const char *s=myStrList.first(); - while (s) - { - QCString myStr=s; - int i=myStr.find('='); - if (i>0) - { - QCString myName=myStr.left(i).stripWhiteSpace(); - QCString myValue=myStr.right(myStr.length()-i-1).stripWhiteSpace(); - if (!myName.isEmpty() && !myValue.isEmpty()) - tcl_inf("TCL_SUBST: use '%s'\n",s); - tcl.config_subst[myName] = myValue; - } - s = myStrList.next(); - } - - if (tcl.input_string.at(tcl.input_string.length()-1) == 0x1A) - { - } - else if (tcl.input_string.at(tcl.input_string.length()-1) == '\n') - { - tcl.input_string[tcl.input_string.length()-1] = 0x1A; - } - else - { - tcl.input_string += 0x1A; - } - - tcl.code = NULL; - tcl.code_font=NULL; - tcl.code_line=1; - tcl.code_linenumbers=1; - tcl.config_autobrief = Config_getBool(JAVADOC_AUTOBRIEF); - tcl.input_position = 0; - tcl.file_name = NULL; - tcl.this_parser = NULL; - tcl.command=0; - tcl.comment=0; - tcl.brace_level=0; - tcl.bracket_level=0; - tcl.bracket_quote=0; - tcl.word_is=' '; - tcl.string_command=""; - tcl.string_commentline=""; - tcl.string_commentcodify=""; - tcl.string_comment = ""; - tcl.string_last = ""; - tcl.entry_main = NULL; - tcl.entry_file = NULL; - tcl.entry_current = NULL; - tcl.entry_inside = NULL; - tcl.list_commandwords.clear(); - tcl.scan.clear(); - tcl.ns.clear(); - tcl.cl.clear(); - tcl.fn.clear(); - yylineno = 1; - tcl.protection = Public; - tcl.memberdef = NULL; -} - -//! Start parsing. -static void tcl_parse(const QCString ns, const QCString cls) -{ - tcl_scan *myScan; - - tcl.entry_file = tcl_entry_new(); - tcl.entry_file->name = tcl.file_name; - tcl.entry_file->section = Entry::SOURCE_SEC; - tcl.entry_file->protection = Public; - tcl.entry_main->moveToSubEntryAndKeep(tcl.entry_file); - Entry *myEntry=tcl_entry_new(); - myEntry->name=""; - tcl.entry_main->moveToSubEntryAndKeep(myEntry); - tcl.ns.insert("::",myEntry); - tcl.entry_current = tcl_entry_new(); - - tclscannerYYrestart( tclscannerYYin ); - BEGIN( TOP ); - yylineno=1; - myScan = new tcl_scan; - myScan->type[0]=' ';myScan->type[1]='\n'; - myScan->after.clear(); - myScan->line0=yylineno; - myScan->line1=yylineno; - myScan->buffer_state=YY_CURRENT_BUFFER; - myScan->ns=ns; - myScan->entry_cl=tcl_entry_class(cls); - myScan->entry_fn=NULL; - tcl.entry_inside = tcl.entry_file; - myScan->entry_scan = tcl.entry_inside; - tcl.scan.insert(0,myScan); - tclscannerYYlex(); - tcl.scan.clear(); - tcl.ns.clear(); - tcl.cl.clear(); - tcl.fn.clear(); - tcl.entry.clear(); -} - -//! Parse text file and build up entry tree. -void TclOutlineParser::parseInput(const char *fileName, - const char *input, - const std::shared_ptr<Entry> &root, - bool /*sameTranslationUnit*/, - QStrList & /*filesInSameTranslationUnit*/) -{ - QFile myFile; -tcl_inf("%s\n",fileName); - myFile.setName(fileName); - if (!myFile.open(IO_ReadOnly)) return; - if (strlen(input)<1) return; - - tcl.input_string = input; - if (tcl.input_string.length()<1) return; - printlex(yy_flex_debug, TRUE, __FILE__, fileName); - - msg("Parsing %s...\n",fileName); - tcl.commentScanner.enterFile(fileName,yylineno); - - tcl_init(); - tcl.code = NULL; - tcl.file_name = fileName; - tcl.this_parser = this; - tcl.entry_main = root.get(); /* toplevel entry */ - tcl_parse("",""); - tcl.commentScanner.leaveFile(tcl.file_name,yylineno); - root->program.resize(0); - myFile.close(); - printlex(yy_flex_debug, FALSE, __FILE__, fileName); -} - - -bool TclOutlineParser::needsPreprocessing(const QCString &extension) const -{ - (void)extension; - return FALSE; -} - -void TclOutlineParser::parsePrototype(const char *text) -{ - (void)text; -} - -static yy_size_t yyread(char *buf,yy_size_t max_size) -{ - yy_size_t c=0; - - *buf = '\0'; - while ( c < max_size && tcl.input_string.at(tcl.input_position) ) - { - *buf = tcl.input_string.at(tcl.input_position++) ; - c++; buf++; - } - //printf("Read from=%d size=%d max=%d c=%d\n",tcl.input_position,strlen(&tcl.input_string[tcl.input_position]),max_size,c); - return c; -} - -//---------------------------------------------------------------------------- - -void TclCodeParser::resetCodeParserState() -{ -} - -//! Parse file and codify. -void TclCodeParser::parseCode(CodeOutputInterface & codeOutIntf, - const char * scopeName, - const QCString & input, - SrcLangExt lang, - bool isExampleBlock, - const char * exampleName, - FileDef * fileDef, - int startLine, - int endLine, - bool inlineFragment, - const MemberDef *memberDef, - bool showLineNumbers, - const Definition *searchCtx, - bool collectXRefs - ) -{ - (void)scopeName; - (void)lang; - (void)exampleName; - (void)fileDef; - (void)endLine; - (void)inlineFragment; - (void)searchCtx; - (void)collectXRefs; - - if (input.length()<1) return; - printlex(yy_flex_debug, TRUE, __FILE__, fileDef ? fileDef->fileName().data(): NULL); - tcl.input_string = input; - - QCString myNs=""; - QCString myCls=""; - if (memberDef) - { - if (memberDef->getClassDef()) - { - myCls = memberDef->getClassDef()->displayName(); - myNs = myCls; - } - else if (memberDef->getNamespaceDef()) - { - myNs = memberDef->getNamespaceDef()->displayName(); - } - } - - QCString myStr="Codifying.."; - if (scopeName) - { - myStr +=" scope="; - myStr+=scopeName; - } - if (exampleName) - { - myStr+=" example="; - myStr+=exampleName; - } - if (memberDef) - { - myStr+=" member="; - myStr+=memberDef->memberTypeName(); - myStr+=" "; - myStr+=memberDef->qualifiedName(); - } - if (fileDef) - { - myStr+=" file="; - myStr+=fileDef->fileName(); - } -tcl_inf("%s (%d,%d) %d %d\n",myStr.data(),startLine,endLine,isExampleBlock,inlineFragment); -//tcl_inf("%s\n"input.data()); - tcl_init(); - tcl.collectXRefs = collectXRefs; - tcl.memberdef = memberDef; - tcl.code = &codeOutIntf; - if (startLine<0) - { - startLine=1; - } - yylineno=startLine; - tcl.code_linenumbers = showLineNumbers; - tcl.code_line=yylineno; - tcl.code->startCodeLine(tcl.code_linenumbers); - if (tcl.code_linenumbers) - { - tcl.code->writeLineNumber(0,0,0,tcl.code_line); - } - tcl.file_name = ""; - tcl.this_parser = NULL; - if (isExampleBlock) - { - tcl_codify(NULL,input); - } - else - { - tcl.entry_main = tcl_entry_new(); - tcl_parse(myNs,myCls); - } - tcl.code->endCodeLine(); - tcl.scan.clear(); - tcl.ns.clear(); - tcl.cl.clear(); - tcl.fn.clear(); - tcl.entry.clear(); - printlex(yy_flex_debug, FALSE, __FILE__, fileDef ? fileDef->fileName().data(): NULL); -} -//---------------------------------------------------------------------------- - -// to avoid a warning -void tclDummy() -{ - yy_top_state(); -} - -#if USE_STATE2STRING -#include "tclscanner.l.h" -#endif |