summaryrefslogtreecommitdiffstats
path: root/src/tclscanner.l
diff options
context:
space:
mode:
authorDimitri van Heesch <doxygen@gmail.com>2020-03-15 13:32:12 (GMT)
committerDimitri van Heesch <doxygen@gmail.com>2020-03-15 13:32:12 (GMT)
commit48a7afc0caf69857a42b0fe1963db3440cb4000f (patch)
tree9a63e2b3750a56174811aace9992b34542e5ae1d /src/tclscanner.l
parent43420bd77408559cb66c83e9ce601426b371bc74 (diff)
downloadDoxygen-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.l3156
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