Orb/Doxygen/src/code.l
changeset 3 d8fccb2cd802
parent 0 42188c7ea2d9
child 4 468f4c8d3d5b
equal deleted inserted replaced
2:932c358ece3e 3:d8fccb2cd802
       
     1 /******************************************************************************
       
     2  *
       
     3  * 
       
     4  *
       
     5  * Copyright (C) 1997-2008 by Dimitri van Heesch.
       
     6  *
       
     7  * Permission to use, copy, modify, and distribute this software and its
       
     8  * documentation under the terms of the GNU General Public License is hereby 
       
     9  * granted. No representations are made about the suitability of this software 
       
    10  * for any purpose. It is provided "as is" without express or implied warranty.
       
    11  * See the GNU General Public License for more details.
       
    12  *
       
    13  * Documents produced by Doxygen are derivative works derived from the
       
    14  * input used in their production; they are not affected by this license.
       
    15  *
       
    16  */
       
    17 
       
    18 %{
       
    19 
       
    20 /*
       
    21  *	includes
       
    22  */
       
    23 #include <stdio.h>
       
    24 #include <assert.h>
       
    25 #include <ctype.h>
       
    26 #include <qregexp.h>
       
    27 #include <qdir.h>
       
    28 
       
    29 #include "qtbc.h"
       
    30 #include "entry.h"
       
    31 #include "doxygen.h"
       
    32 #include "message.h"
       
    33 #include "outputlist.h"
       
    34 #include "util.h"
       
    35 #include "membername.h"
       
    36 #include "searchindex.h"
       
    37 
       
    38 #define YY_NEVER_INTERACTIVE 1
       
    39   
       
    40 // Toggle for some debugging info
       
    41 //#define DBG_CTX(x) fprintf x
       
    42 #define DBG_CTX(x) do { } while(0)
       
    43   
       
    44 #define CLASSBLOCK (int *)4
       
    45 #define SCOPEBLOCK (int *)8
       
    46 #define INNERBLOCK (int *)12
       
    47 
       
    48 /* -----------------------------------------------------------------
       
    49  *	statics
       
    50  */
       
    51   
       
    52 static CodeOutputInterface * g_code;
       
    53 
       
    54 static ClassSDict    *g_codeClassSDict = 0;
       
    55 static QCString      g_curClassName;
       
    56 static QStrList      g_curClassBases;
       
    57 
       
    58 static QCString      g_parmType;
       
    59 static QCString      g_parmName;
       
    60 
       
    61 static const char *  g_inputString;     //!< the code fragment as text
       
    62 static int	     g_inputPosition;   //!< read offset during parsing 
       
    63 static int           g_inputLines;      //!< number of line in the code fragment
       
    64 static int	     g_yyLineNr;        //!< current line number
       
    65 static bool          g_needsTermination;
       
    66 
       
    67 static bool          g_exampleBlock;
       
    68 static QCString      g_exampleName;
       
    69 static QCString      g_exampleFile;
       
    70 
       
    71 static bool          g_insideTemplate = FALSE;
       
    72 static QCString      g_type;
       
    73 static QCString      g_name;
       
    74 static QCString      g_args;
       
    75 static QCString      g_classScope;
       
    76 static QCString      g_realScope;
       
    77 static QStack<int>   g_scopeStack;      //!< 1 if bracket starts a scope, 
       
    78                                         //   2 for internal blocks 
       
    79 static int           g_anchorCount;
       
    80 static FileDef *     g_sourceFileDef;
       
    81 static bool          g_lineNumbers;
       
    82 static Definition *  g_currentDefinition;
       
    83 static MemberDef *   g_currentMemberDef;
       
    84 static bool          g_includeCodeFragment;
       
    85 static const char *  g_currentFontClass;
       
    86 static bool          g_searchingForBody;
       
    87 static bool          g_insideBody;
       
    88 static int           g_bodyCurlyCount;
       
    89 static QCString      g_saveName;
       
    90 static QCString      g_saveType;
       
    91 
       
    92 static int	     g_bracketCount = 0;
       
    93 static int	     g_curlyCount   = 0;
       
    94 static int	     g_sharpCount   = 0;
       
    95 static bool          g_inFunctionTryBlock = FALSE;
       
    96 static bool          g_inForEachExpression = FALSE;
       
    97 
       
    98 static int           g_lastTemplCastContext;
       
    99 static int	     g_lastSpecialCContext;
       
   100 static int           g_lastStringContext;
       
   101 static int           g_lastSkipCppContext;
       
   102 static int           g_lastVerbStringContext;
       
   103 static int           g_memCallContext;
       
   104 static int	     g_lastCContext;
       
   105 
       
   106 static bool          g_insideObjC;
       
   107 static bool          g_insideProtocolList;
       
   108 
       
   109 static bool          g_lexInit = FALSE;
       
   110 
       
   111 static QStack<int>   g_classScopeLengthStack;
       
   112 
       
   113 // context for an Objective-C method call
       
   114 struct ObjCCallCtx
       
   115 {
       
   116   int id;
       
   117   QCString methodName;
       
   118   QCString objectTypeOrName;
       
   119   ClassDef *objectType;
       
   120   MemberDef *objectVar;
       
   121   MemberDef *method;
       
   122   QCString format;
       
   123   int lexState;
       
   124   int braceCount;
       
   125 };
       
   126 
       
   127 // globals for objective-C method calls 
       
   128 static ObjCCallCtx *g_currentCtx=0;
       
   129 static int g_currentCtxId=0;
       
   130 static int g_currentNameId=0;
       
   131 static int g_currentObjId=0;
       
   132 static int g_currentWordId=0;
       
   133 static QStack<ObjCCallCtx> g_contextStack;
       
   134 static QIntDict<ObjCCallCtx> g_contextDict;
       
   135 static QIntDict<QCString> g_nameDict;
       
   136 static QIntDict<QCString> g_objectDict;
       
   137 static QIntDict<QCString> g_wordDict;
       
   138 static int g_braceCount=0;
       
   139   
       
   140 static void saveObjCContext();
       
   141 static void restoreObjCContext();
       
   142 
       
   143 
       
   144 
       
   145 //-------------------------------------------------------------------
       
   146 
       
   147 /*! Represents a stack of variable to class mappings as found in the
       
   148  *  code. Each scope is enclosed in pushScope() and popScope() calls.
       
   149  *  Variables are added by calling addVariables() and one can search
       
   150  *  for variable using findVariable().
       
   151  */
       
   152 class VariableContext
       
   153 {
       
   154   public:
       
   155     static const ClassDef *dummyContext;
       
   156     
       
   157     class Scope : public SDict<ClassDef>
       
   158     {
       
   159       public:
       
   160 	Scope() : SDict<ClassDef>(17) {}
       
   161     };
       
   162     
       
   163     VariableContext() 
       
   164     {
       
   165       m_scopes.setAutoDelete(TRUE);
       
   166     }
       
   167     virtual ~VariableContext()
       
   168     {
       
   169     }
       
   170     
       
   171     void pushScope()
       
   172     {
       
   173       m_scopes.append(new Scope);
       
   174       DBG_CTX((stderr,"** Push var context %d\n",m_scopes.count()));
       
   175     }
       
   176 
       
   177     void popScope()
       
   178     {
       
   179       if (m_scopes.count()>0)
       
   180       {
       
   181         DBG_CTX((stderr,"** Pop var context %d\n",m_scopes.count()));
       
   182 	m_scopes.remove(m_scopes.count()-1);
       
   183       }
       
   184       else
       
   185       {
       
   186         DBG_CTX((stderr,"** ILLEGAL: Pop var context\n"));
       
   187       }
       
   188     }
       
   189 
       
   190     void clear()
       
   191     {
       
   192       m_scopes.clear();
       
   193       m_globalScope.clear();
       
   194     }
       
   195 
       
   196     void clearExceptGlobal()
       
   197     {
       
   198       DBG_CTX((stderr,"** Clear var context\n"));
       
   199       m_scopes.clear();
       
   200     }
       
   201 
       
   202     void addVariable(const QCString &type,const QCString &name);
       
   203     ClassDef *findVariable(const QCString &name);
       
   204 
       
   205     int count() const { return m_scopes.count(); }
       
   206     
       
   207   private:
       
   208     Scope        m_globalScope;
       
   209     QList<Scope> m_scopes;
       
   210 };
       
   211 
       
   212 void VariableContext::addVariable(const QCString &type,const QCString &name)
       
   213 {
       
   214   //printf("VariableContext::addVariable(%s,%s)\n",type.data(),name.data());
       
   215   QCString ltype = type.simplifyWhiteSpace();
       
   216   QCString lname = name.simplifyWhiteSpace();
       
   217   if (ltype.left(7)=="struct ") 
       
   218   {
       
   219     ltype = ltype.right(ltype.length()-7);
       
   220   }
       
   221   else if (ltype.left(6)=="union ")
       
   222   {
       
   223     ltype = ltype.right(ltype.length()-6);
       
   224   }
       
   225   if (ltype.isEmpty() || lname.isEmpty()) return;
       
   226   DBG_CTX((stderr,"** addVariable trying: type='%s' name='%s' g_currentDefinition=%s\n",
       
   227 	ltype.data(),lname.data(),g_currentDefinition?g_currentDefinition->name().data():"<none>"));
       
   228   Scope *scope = m_scopes.count()==0 ? &m_globalScope : m_scopes.getLast();
       
   229   ClassDef *varType;
       
   230   int i=0;
       
   231   if (
       
   232       (varType=g_codeClassSDict->find(ltype)) ||  // look for class definitions inside the code block
       
   233       (varType=getResolvedClass(g_currentDefinition,g_sourceFileDef,ltype)) // look for global class definitions
       
   234      ) 
       
   235   {
       
   236     DBG_CTX((stderr,"** addVariable type='%s' name='%s'\n",ltype.data(),lname.data()));
       
   237     scope->append(lname,varType); // add it to a list
       
   238   }
       
   239   else if ((i=ltype.find('<'))!=-1)
       
   240   {
       
   241     // probably a template class
       
   242     QCString typeName(ltype.left(i));
       
   243     ClassDef* newDef = 0;
       
   244     QCString templateArgs(ltype.right(ltype.length() - i));
       
   245     if (  
       
   246          ( // look for class definitions inside the code block
       
   247 	   (varType=g_codeClassSDict->find(typeName)) ||
       
   248            // otherwise look for global class definitions
       
   249            (varType=getResolvedClass(g_currentDefinition,g_sourceFileDef,typeName))
       
   250 	 ) && // and it must be a template
       
   251          varType->templateArguments())
       
   252     {
       
   253       newDef = varType->getVariableInstance( templateArgs );
       
   254     }
       
   255     if (newDef)
       
   256     {
       
   257       DBG_CTX((stderr,"** addVariable type='%s' templ='%s' name='%s'\n",typeName.data(),templateArgs.data(),lname.data()));
       
   258       scope->append(lname, newDef);
       
   259     }
       
   260     else
       
   261     {
       
   262       // Doesn't seem to be a template. Try just the base name.
       
   263       addVariable(typeName,name);
       
   264     }
       
   265   }
       
   266   else 
       
   267   {
       
   268     if (m_scopes.count()>0) // for local variables add a dummy entry so the name 
       
   269                             // is hidden to avoid false links to global variables with the same name
       
   270                             // TODO: make this work for namespaces as well!
       
   271     {
       
   272       DBG_CTX((stderr,"** addVariable: dummy context for '%s'\n",lname.data()));
       
   273       scope->append(lname,dummyContext);
       
   274     }
       
   275     else
       
   276     {
       
   277       DBG_CTX((stderr,"** addVariable: not adding variable!\n"));
       
   278     }
       
   279   }
       
   280 }
       
   281 
       
   282 ClassDef *VariableContext::findVariable(const QCString &name)
       
   283 {
       
   284   if (name.isEmpty()) return 0;
       
   285   ClassDef *result = 0;
       
   286   QListIterator<Scope> sli(m_scopes);
       
   287   Scope *scope;
       
   288   QCString key = name;
       
   289   // search from inner to outer scope
       
   290   for (sli.toLast();(scope=sli.current());--sli)
       
   291   {
       
   292     result = scope->find(key);
       
   293     if (result) 
       
   294     {
       
   295       DBG_CTX((stderr,"** findVariable(%s)=%p\n",name.data(),result));
       
   296       return result;
       
   297     }
       
   298   }
       
   299   // nothing found -> also try the global scope
       
   300   result=m_globalScope.find(name);
       
   301   DBG_CTX((stderr,"** findVariable(%s)=%p\n",name.data(),result));
       
   302   return result;
       
   303 }
       
   304 
       
   305 static VariableContext g_theVarContext;
       
   306 const ClassDef *VariableContext::dummyContext = (ClassDef*)0x8;
       
   307 
       
   308 //-------------------------------------------------------------------
       
   309 
       
   310 class CallContext
       
   311 {
       
   312   public:
       
   313     struct Ctx
       
   314     {
       
   315       Ctx() : name(g_name), type(g_type), cd(0) {}
       
   316       QCString name;
       
   317       QCString type;
       
   318       ClassDef *cd;
       
   319     };
       
   320 
       
   321     CallContext() 
       
   322     {
       
   323       m_classList.append(new Ctx);
       
   324       m_classList.setAutoDelete(TRUE);
       
   325     }
       
   326     virtual ~CallContext() {}
       
   327     void setClass(ClassDef *cd)
       
   328     {
       
   329       Ctx *ctx = m_classList.getLast();
       
   330       if (ctx)
       
   331       {
       
   332 	DBG_CTX((stderr,"** Set call context %s (%p)\n",cd==0 ? "<null>" : cd->name().data(),cd));
       
   333         ctx->cd=cd;
       
   334       }
       
   335     }
       
   336     void pushScope()
       
   337     {
       
   338       m_classList.append(new Ctx);
       
   339       DBG_CTX((stderr,"** Push call context %d\n",m_classList.count()));
       
   340     }
       
   341     void popScope()
       
   342     {
       
   343       if (m_classList.count()>1)
       
   344       {
       
   345         DBG_CTX((stderr,"** Pop call context %d\n",m_classList.count()));
       
   346 	Ctx *ctx = m_classList.getLast();
       
   347 	if (ctx)
       
   348 	{
       
   349 	  g_name = ctx->name;
       
   350 	  g_type = ctx->type;
       
   351 	}
       
   352 	m_classList.removeLast();
       
   353       }
       
   354       else
       
   355       {
       
   356         DBG_CTX((stderr,"** ILLEGAL: Pop call context\n"));
       
   357       }
       
   358     }
       
   359     void clear()
       
   360     {
       
   361       DBG_CTX((stderr,"** Clear call context\n"));
       
   362       m_classList.clear();
       
   363       m_classList.append(new Ctx);
       
   364     }
       
   365     ClassDef *getClass() const
       
   366     {
       
   367       Ctx *ctx = m_classList.getLast();
       
   368       if (ctx) return ctx->cd; else return 0;
       
   369     }
       
   370 
       
   371   private:
       
   372     QList<Ctx> m_classList;    
       
   373 };
       
   374 
       
   375 static CallContext g_theCallContext;
       
   376 
       
   377 //-------------------------------------------------------------------
       
   378 
       
   379 /*! add class/namespace name s to the scope */
       
   380 static void pushScope(const char *s)
       
   381 {
       
   382   g_classScopeLengthStack.push(new int(g_classScope.length()));
       
   383   if (g_classScope.isEmpty())
       
   384   {
       
   385     g_classScope = s;
       
   386   }
       
   387   else
       
   388   {
       
   389     g_classScope += "::";
       
   390     g_classScope += s;
       
   391   }
       
   392   //printf("pushScope(%s) result: `%s'\n",s,g_classScope.data());
       
   393 }
       
   394 
       
   395 /*! remove the top class/namespace name from the scope */
       
   396 static void popScope()
       
   397 {
       
   398   if (!g_classScopeLengthStack.isEmpty())
       
   399   {
       
   400     int *pLength = g_classScopeLengthStack.pop();
       
   401     g_classScope.truncate(*pLength);
       
   402     delete pLength;
       
   403   }
       
   404   else
       
   405   {
       
   406     //err("Error: Too many end of scopes found!\n");
       
   407   }
       
   408   //printf("popScope() result: `%s'\n",g_classScope.data());
       
   409 }
       
   410 
       
   411 static void setCurrentDoc(const QCString &name,const QCString &base,const QCString &anchor="")
       
   412 {
       
   413   if (Doxygen::searchIndex)
       
   414   {
       
   415     Doxygen::searchIndex->setCurrentDoc(name,base,anchor);
       
   416   }
       
   417 }
       
   418 
       
   419 static void addToSearchIndex(const char *text)
       
   420 {
       
   421   if (Doxygen::searchIndex)
       
   422   {
       
   423     Doxygen::searchIndex->addWord(text,FALSE);
       
   424   }
       
   425 }
       
   426 
       
   427 static void setClassScope(const QCString &name)
       
   428 {
       
   429   //printf("setClassScope(%s)\n",name.data());
       
   430   QCString n=name;
       
   431   n=n.simplifyWhiteSpace();
       
   432   int ts=n.find('<'); // start of template
       
   433   int te=n.findRev('>'); // end of template
       
   434   //printf("ts=%d te=%d\n",ts,te);
       
   435   if (ts!=-1 && te!=-1 && te>ts)
       
   436   {
       
   437     // remove template from scope
       
   438     n=n.left(ts)+n.right(n.length()-te-1);
       
   439   }
       
   440   while (!g_classScopeLengthStack.isEmpty())
       
   441   {
       
   442     popScope();
       
   443   }
       
   444   g_classScope.resize(0);
       
   445   int i;
       
   446   while ((i=n.find("::"))!=-1)
       
   447   {
       
   448     pushScope(n.left(i));
       
   449     n = n.mid(i+2);
       
   450   }
       
   451   pushScope(n);
       
   452   //printf("--->New class scope `%s'\n",g_classScope.data());
       
   453 }
       
   454 
       
   455 /*! start a new line of code, inserting a line number if g_sourceFileDef
       
   456  * is TRUE. If a definition starts at the current line, then the line
       
   457  * number is linked to the documentation of that definition.
       
   458  */
       
   459 static void startCodeLine()
       
   460 {
       
   461   //if (g_currentFontClass) { g_code->endFontClass(); }
       
   462   if (g_sourceFileDef && g_lineNumbers)
       
   463   {
       
   464     //QCString lineNumber,lineAnchor;
       
   465     //lineNumber.sprintf("%05d",g_yyLineNr);
       
   466     //lineAnchor.sprintf("l%05d",g_yyLineNr);
       
   467    
       
   468     Definition *d   = g_sourceFileDef->getSourceDefinition(g_yyLineNr);
       
   469     if (!g_includeCodeFragment && d)
       
   470     {
       
   471       g_currentDefinition = d;
       
   472       g_currentMemberDef = g_sourceFileDef->getSourceMember(g_yyLineNr);
       
   473       g_insideBody = FALSE;
       
   474       g_searchingForBody = TRUE;
       
   475       g_realScope = d->name().copy();
       
   476       g_type.resize(0);
       
   477       g_name.resize(0);
       
   478       g_args.resize(0);
       
   479       g_parmType.resize(0);
       
   480       g_parmName.resize(0);
       
   481       //printf("Real scope: `%s'\n",g_realScope.data());
       
   482       g_bodyCurlyCount = 0;
       
   483       QCString lineAnchor;
       
   484       lineAnchor.sprintf("l%05d",g_yyLineNr);
       
   485       if (g_currentMemberDef)
       
   486       {
       
   487         g_code->writeLineNumber(g_currentMemberDef->getReference(),
       
   488 	                        g_currentMemberDef->getOutputFileBase(),
       
   489 	                        g_currentMemberDef->anchor(),g_yyLineNr);
       
   490         setCurrentDoc(
       
   491                                 g_currentMemberDef->qualifiedName(),
       
   492 	                        g_sourceFileDef->getSourceFileBase(),
       
   493 	                        lineAnchor);
       
   494       }
       
   495       else if (d->isLinkableInProject())
       
   496       {
       
   497         g_code->writeLineNumber(d->getReference(),
       
   498 	                        d->getOutputFileBase(),
       
   499 	                        0,g_yyLineNr);
       
   500         setCurrentDoc(
       
   501                                 d->qualifiedName(),
       
   502 	                        g_sourceFileDef->getSourceFileBase(),
       
   503 	                        lineAnchor);
       
   504       }
       
   505     }
       
   506     else
       
   507     {
       
   508       g_code->writeLineNumber(0,0,0,g_yyLineNr);
       
   509     }
       
   510   }
       
   511   g_code->startCodeLine(); 
       
   512   if (g_currentFontClass)
       
   513   {
       
   514     g_code->startFontClass(g_currentFontClass);
       
   515   }
       
   516 }
       
   517 
       
   518 
       
   519 static void endFontClass();
       
   520 static void startFontClass(const char *s);
       
   521 
       
   522 static void endCodeLine()
       
   523 {
       
   524   endFontClass();
       
   525   g_code->endCodeLine();
       
   526 }
       
   527 
       
   528 static void nextCodeLine()
       
   529 {
       
   530   const char * fc = g_currentFontClass;
       
   531   endCodeLine();
       
   532   if (g_yyLineNr<g_inputLines) 
       
   533   {
       
   534     g_currentFontClass = fc;
       
   535     startCodeLine();
       
   536   }
       
   537 }
       
   538 
       
   539 /*! write a code fragment `text' that may span multiple lines, inserting
       
   540  * line numbers for each line.
       
   541  */
       
   542 static void codifyLines(char *text)
       
   543 {
       
   544   //printf("codifyLines(%d,\"%s\")\n",g_yyLineNr,text);
       
   545   char *p=text,*sp=p;
       
   546   char c;
       
   547   bool done=FALSE;
       
   548   while (!done)
       
   549   {
       
   550     sp=p;
       
   551     while ((c=*p++) && c!='\n') { }
       
   552     if (c=='\n')
       
   553     {
       
   554       g_yyLineNr++;
       
   555       *(p-1)='\0';
       
   556       g_code->codify(sp);
       
   557       nextCodeLine();
       
   558     }
       
   559     else
       
   560     {
       
   561       g_code->codify(sp);
       
   562       done=TRUE;
       
   563     }
       
   564   }
       
   565 }
       
   566 
       
   567 /*! writes a link to a fragment \a text that may span multiple lines, inserting
       
   568  * line numbers for each line. If \a text contains newlines, the link will be 
       
   569  * split into multiple links with the same destination, one for each line.
       
   570  */
       
   571 static void writeMultiLineCodeLink(CodeOutputInterface &ol,
       
   572                   const char *ref,const char *file,
       
   573                   const char *anchor,const char *text,
       
   574 		  const char *tooltip)
       
   575 {
       
   576   bool done=FALSE;
       
   577   char *p=(char *)text;
       
   578   while (!done)
       
   579   {
       
   580     char *sp=p;
       
   581     char c;
       
   582     while ((c=*p++) && c!='\n') { }
       
   583     if (c=='\n')
       
   584     {
       
   585       g_yyLineNr++;
       
   586       *(p-1)='\0';
       
   587       //printf("writeCodeLink(%s,%s,%s,%s)\n",ref,file,anchor,sp);
       
   588       ol.writeCodeLink(ref,file,anchor,sp,tooltip);
       
   589       nextCodeLine();
       
   590     }
       
   591     else
       
   592     {
       
   593       //printf("writeCodeLink(%s,%s,%s,%s)\n",ref,file,anchor,sp);
       
   594       ol.writeCodeLink(ref,file,anchor,sp,tooltip);
       
   595       done=TRUE;
       
   596     }
       
   597   }
       
   598 }
       
   599 
       
   600 static void addType()
       
   601 {
       
   602   if (g_name=="const") { g_name.resize(0); return; }
       
   603   if (!g_type.isEmpty()) g_type += ' ' ;
       
   604   g_type += g_name ;
       
   605   g_name.resize(0) ;
       
   606   if (!g_type.isEmpty()) g_type += ' ' ;
       
   607   g_type += g_args ;
       
   608   g_args.resize(0) ;
       
   609 }
       
   610 
       
   611 static void addParmType()
       
   612 {
       
   613   if (g_parmName=="const") { g_parmName.resize(0); return; }
       
   614   if (!g_parmType.isEmpty()) g_parmType += ' ' ;
       
   615   g_parmType += g_parmName ;
       
   616   g_parmName.resize(0) ;
       
   617 }
       
   618 
       
   619 static void addUsingDirective(const char *name)
       
   620 {
       
   621   if (g_exampleBlock && g_sourceFileDef && name)
       
   622   {
       
   623     NamespaceDef *nd = Doxygen::namespaceSDict->find(name);
       
   624     if (nd)
       
   625     {
       
   626       g_sourceFileDef->addUsingDirective(nd);
       
   627     }
       
   628   }
       
   629 }
       
   630 
       
   631 static void setParameterList(MemberDef *md)
       
   632 {
       
   633   g_classScope = md->getClassDef() ? md->getClassDef()->name().data() : "";
       
   634   LockingPtr<ArgumentList> al = md->argumentList();
       
   635   if (al==0) return; 
       
   636   Argument *a = al->first();
       
   637   while (a)
       
   638   {
       
   639     g_parmName = a->name.copy();
       
   640     g_parmType = a->type.copy();
       
   641     int i = g_parmType.find('*');
       
   642     if (i!=-1) g_parmType = g_parmType.left(i);
       
   643     i = g_parmType.find('&');
       
   644     if (i!=-1) g_parmType = g_parmType.left(i);
       
   645     g_parmType.stripPrefix("const ");
       
   646     g_parmType=g_parmType.stripWhiteSpace();
       
   647     g_theVarContext.addVariable(g_parmType,g_parmName);
       
   648     a = al->next();
       
   649   }
       
   650 }
       
   651 
       
   652 static ClassDef *stripClassName(const char *s)
       
   653 {
       
   654   int pos=0;
       
   655   QCString type = s;
       
   656   QCString className;
       
   657   QCString templSpec;
       
   658   while (extractClassNameFromType(type,pos,className,templSpec)!=-1)
       
   659   {
       
   660     QCString clName=className+templSpec;
       
   661     ClassDef *cd=0;
       
   662     if (!g_classScope.isEmpty())
       
   663     {
       
   664       cd=getResolvedClass(g_currentDefinition,g_sourceFileDef,g_classScope+"::"+clName);
       
   665     }
       
   666     if (cd==0)
       
   667     {
       
   668       cd=getResolvedClass(g_currentDefinition,g_sourceFileDef,clName);
       
   669     }
       
   670     //printf("stripClass trying `%s' = %p\n",clName.data(),cd);
       
   671     if (cd)
       
   672     {
       
   673       return cd;
       
   674     }
       
   675   }
       
   676 
       
   677   return 0;
       
   678 }
       
   679 
       
   680 static MemberDef *setCallContextForVar(const QCString &name)
       
   681 {
       
   682   if (name.isEmpty()) return 0;
       
   683   //fprintf(stderr,"setCallContextForVar(%s) g_classScope=%s\n",name.data(),g_classScope.data());
       
   684 
       
   685   int scopeEnd = name.findRev("::");
       
   686   if (scopeEnd!=-1) // name with explicit scope
       
   687   {
       
   688     QCString scope   = name.left(scopeEnd);
       
   689     QCString locName = name.right(name.length()-scopeEnd-2);
       
   690     //printf("explicit scope: name=%s scope=%s\n",locName.data(),scope.data());
       
   691     ClassDef *mcd = getClass(scope); 
       
   692     if (mcd && !locName.isEmpty())
       
   693     {
       
   694       MemberDef *md=mcd->getMemberByName(locName);
       
   695       if (md)
       
   696       {
       
   697         //printf("name=%s scope=%s\n",locName.data(),scope.data());
       
   698         g_theCallContext.setClass(stripClassName(md->typeString()));
       
   699         return md;
       
   700       }
       
   701     }
       
   702     else // check namespace as well
       
   703     {
       
   704       NamespaceDef *mnd = getResolvedNamespace(scope);
       
   705       if (mnd && !locName.isEmpty())
       
   706       {
       
   707 	MemberDef *md=mnd->getMemberByName(locName);
       
   708 	if (md)
       
   709 	{
       
   710 	  //printf("name=%s scope=%s\n",locName.data(),scope.data());
       
   711 	  g_theCallContext.setClass(stripClassName(md->typeString()));
       
   712 	  return md;
       
   713 	}
       
   714       }
       
   715     }
       
   716   }
       
   717   
       
   718   MemberName *mn;
       
   719   ClassDef *mcd = g_theVarContext.findVariable(name);
       
   720   if (mcd) // local variable
       
   721   {
       
   722     //fprintf(stderr,"local variable\n");
       
   723     if (mcd!=VariableContext::dummyContext)
       
   724     {
       
   725       //fprintf(stderr,"local var `%s' mcd=%s\n",name.data(),mcd->name().data());
       
   726       g_theCallContext.setClass(mcd);
       
   727     }
       
   728   }
       
   729   else
       
   730   {
       
   731     // look for a class member 
       
   732     mcd = getClass(g_classScope);
       
   733     if (mcd)
       
   734     {
       
   735       //fprintf(stderr,"Inside class %s\n",mcd->name().data());
       
   736       MemberDef *md=mcd->getMemberByName(name);
       
   737       if (md) 
       
   738       {
       
   739         //fprintf(stderr,"Found member %s\n",md->name().data());
       
   740 	if (g_scopeStack.top()!=CLASSBLOCK)
       
   741 	{
       
   742           //fprintf(stderr,"class member `%s' mcd=%s\n",name.data(),mcd->name().data());
       
   743 	  g_theCallContext.setClass(stripClassName(md->typeString()));
       
   744 	}
       
   745 	return md;
       
   746       }
       
   747     }
       
   748   }
       
   749 
       
   750   // look for a global member
       
   751   if ((mn=Doxygen::functionNameSDict->find(name)))
       
   752   {
       
   753     //printf("global var `%s'\n",name.data());
       
   754     if (mn->count()==1) // global defined only once
       
   755     {
       
   756       MemberDef *md=mn->getFirst();
       
   757       if (!md->isStatic() || md->getBodyDef()==g_sourceFileDef)
       
   758       {
       
   759         g_theCallContext.setClass(stripClassName(md->typeString()));
       
   760         return md;
       
   761       }
       
   762       return 0;
       
   763     }
       
   764     else if (mn->count()>1) // global defined more than once
       
   765     {
       
   766       MemberDef *md=mn->first();
       
   767       while (md)
       
   768       {
       
   769 	//printf("mn=%p md=%p md->getBodyDef()=%p g_sourceFileDef=%p\n",
       
   770 	//    mn,md,
       
   771 	//    md->getBodyDef(),g_sourceFileDef);
       
   772 	
       
   773 	// in case there are multiple members we could link to, we 
       
   774 	// only link to members if defined in the same file or 
       
   775 	// defined as external.
       
   776         if (!md->isStatic() || md->getBodyDef()==g_sourceFileDef)
       
   777         {
       
   778           g_theCallContext.setClass(stripClassName(md->typeString()));
       
   779 	  //printf("returning member %s in source file %s\n",md->name().data(),g_sourceFileDef->name().data());
       
   780           return md;
       
   781         }
       
   782 	md=mn->next();
       
   783       }
       
   784       return 0;
       
   785     }
       
   786   }
       
   787   return 0;
       
   788 }
       
   789 
       
   790 static void addDocCrossReference(MemberDef *src,MemberDef *dst)
       
   791 {
       
   792   static bool referencedByRelation = Config_getBool("REFERENCED_BY_RELATION");
       
   793   static bool referencesRelation   = Config_getBool("REFERENCES_RELATION");
       
   794   static bool callerGraph          = Config_getBool("CALLER_GRAPH");
       
   795   static bool callGraph            = Config_getBool("CALL_GRAPH");
       
   796 
       
   797   //printf("--> addDocCrossReference src=%s,dst=%s\n",src->name().data(),dst->name().data());
       
   798   if (dst->isTypedef() || dst->isEnumerate()) return; // don't add types
       
   799   if ((referencedByRelation || callerGraph || dst->hasCallerGraph()) && 
       
   800       (src->isFunction() || src->isSlot()) 
       
   801      )
       
   802   {
       
   803     dst->addSourceReferencedBy(src);
       
   804     MemberDef *mdDef = dst->memberDefinition();
       
   805     if (mdDef)
       
   806     {
       
   807       mdDef->addSourceReferencedBy(src);
       
   808     }
       
   809     MemberDef *mdDecl = dst->memberDeclaration();
       
   810     if (mdDecl)
       
   811     {
       
   812       mdDecl->addSourceReferencedBy(src);
       
   813     }
       
   814   }
       
   815   if ((referencesRelation || callGraph || src->hasCallGraph()) && 
       
   816       (src->isFunction() || src->isSlot())
       
   817      )
       
   818   {
       
   819     src->addSourceReferences(dst);
       
   820     MemberDef *mdDef = src->memberDefinition();
       
   821     if (mdDef)
       
   822     {
       
   823       mdDef->addSourceReferences(dst);
       
   824     }
       
   825     MemberDef *mdDecl = src->memberDeclaration();
       
   826     if (mdDecl)
       
   827     {
       
   828       mdDecl->addSourceReferences(dst);
       
   829     }
       
   830   }
       
   831 
       
   832 }
       
   833 
       
   834 static bool getLinkInScope(const QCString &c,  // scope
       
   835                            const QCString &m,  // member
       
   836 			   const char *memberText, // exact text
       
   837 			   CodeOutputInterface &ol,
       
   838 			   const char *text
       
   839 			  )
       
   840 {
       
   841   MemberDef    *md;
       
   842   ClassDef     *cd;
       
   843   FileDef      *fd;
       
   844   NamespaceDef *nd;
       
   845   GroupDef     *gd;
       
   846   //fprintf(stderr,"getLinkInScope: trying `%s'::`%s'\n",c.data(),m.data());
       
   847   if (getDefs(c,m,"()",md,cd,fd,nd,gd,FALSE,g_sourceFileDef) && 
       
   848       md->isLinkable())
       
   849   {
       
   850     if (g_exampleBlock)
       
   851     {
       
   852       QCString anchor;
       
   853       anchor.sprintf("a%d",g_anchorCount);
       
   854       //printf("addExampleFile(%s,%s,%s)\n",anchor.data(),g_exampleName.data(),
       
   855       //                                  g_exampleFile.data());
       
   856       if (md->addExample(anchor,g_exampleName,g_exampleFile))
       
   857       {
       
   858 	ol.writeCodeAnchor(anchor);
       
   859 	g_anchorCount++;
       
   860       }
       
   861     }
       
   862 
       
   863     Definition *d = md->getOuterScope()==Doxygen::globalScope ?
       
   864 	            md->getBodyDef() : md->getOuterScope();
       
   865     if (md->getGroupDef()) d = md->getGroupDef();
       
   866     //fprintf(stderr,"d=%p linkable=%d\n",d,d?d->isLinkable():0);
       
   867     if (d && d->isLinkable())
       
   868     {
       
   869       g_theCallContext.setClass(stripClassName(md->typeString()));
       
   870       //printf("g_currentDefinition=%p g_currentMemberDef=%p g_insideBody=%d\n",
       
   871       //        g_currentDefinition,g_currentMemberDef,g_insideBody);
       
   872 
       
   873       if (g_currentDefinition && g_currentMemberDef &&
       
   874 	  md!=g_currentMemberDef && g_insideBody)
       
   875       {
       
   876 	addDocCrossReference(g_currentMemberDef,md);
       
   877       }
       
   878       //printf("d->getReference()=`%s' d->getOutputBase()=`%s' name=`%s' member name=`%s'\n",d->getReference().data(),d->getOutputFileBase().data(),d->name().data(),md->name().data());
       
   879      
       
   880       ol.linkableSymbol(g_yyLineNr,md->name(),md,
       
   881 	                g_currentMemberDef ? g_currentMemberDef : g_currentDefinition);
       
   882       writeMultiLineCodeLink(ol,md->getReference(),
       
   883 	                        md->getOutputFileBase(),
       
   884 	                        md->anchor(),
       
   885 				text ? text : memberText,
       
   886 				md->briefDescriptionAsTooltip());
       
   887       addToSearchIndex(text ? text : memberText);
       
   888       return TRUE;
       
   889     } 
       
   890   }
       
   891   return FALSE;
       
   892 }
       
   893 
       
   894 static bool getLink(const char *className,
       
   895                     const char *memberName,
       
   896 		    CodeOutputInterface &ol,
       
   897 		    const char *text=0)
       
   898 {
       
   899   //printf("getLink(%s,%s) g_curClassName=%s\n",className,memberName,g_curClassName.data());
       
   900   QCString m=removeRedundantWhiteSpace(memberName);
       
   901   QCString c=className;
       
   902   if (!getLinkInScope(c,m,memberName,ol,text))
       
   903   {
       
   904     if (!g_curClassName.isEmpty())
       
   905     {
       
   906       if (!c.isEmpty()) c.prepend("::");
       
   907       c.prepend(g_curClassName);
       
   908       return getLinkInScope(c,m,memberName,ol,text);
       
   909     }
       
   910     return FALSE;
       
   911   }
       
   912   return TRUE;
       
   913 }
       
   914 
       
   915 static void generateClassOrGlobalLink(CodeOutputInterface &ol,char *clName,
       
   916                                       bool typeOnly=FALSE)
       
   917 {
       
   918   int i=0;
       
   919   if (*clName=='~') // correct for matching negated values i.s.o. destructors.
       
   920   {
       
   921     g_code->codify("~");
       
   922     clName++;
       
   923   }
       
   924   QCString className=clName;
       
   925   if (className.isEmpty()) return;
       
   926   if (g_insideProtocolList) // for Obj-C
       
   927   {
       
   928     className+="-p";
       
   929   }
       
   930   ClassDef *cd=0,*lcd=0;
       
   931   MemberDef *md=0;
       
   932   bool isLocal=FALSE;
       
   933 
       
   934   //printf("generateClassOrGlobalLink(className=%s)\n",className.data());
       
   935   if ((lcd=g_theVarContext.findVariable(className))==0) // not a local variable
       
   936   {
       
   937     Definition *d = g_currentDefinition;
       
   938     //printf("d=%p g_sourceFileDef=%p\n",d,g_currentDefinition);
       
   939     cd = getResolvedClass(d,g_sourceFileDef,className,&md);
       
   940     //fprintf(stderr,"non-local variable name=%s context=%d cd=%s md=%s!\n",
       
   941     //	className.data(),g_theVarContext.count(),cd?cd->name().data():"<none>",
       
   942     //	md?md->name().data():"<none>");
       
   943     if (cd==0 && md==0 && (i=className.find('<'))!=-1)
       
   944     {
       
   945       QCString bareName = className.left(i); //stripTemplateSpecifiersFromScope(className);
       
   946       //fprintf(stderr,"bareName=%s\n",bareName.data());
       
   947       if (bareName!=className)
       
   948       {
       
   949 	cd=getResolvedClass(d,g_sourceFileDef,bareName,&md); // try unspecialized version
       
   950       }
       
   951     }
       
   952     //printf("md=%s\n",md?md->name().data():"<none>");
       
   953     //fprintf(stderr,"is found as a type %s\n",cd?cd->name().data():"<null>");
       
   954     if (cd==0 && md==0) // also see if it is variable or enum or enum value
       
   955     {
       
   956       if (getLink(g_classScope,clName,ol,clName))
       
   957       {
       
   958 	return;
       
   959       }
       
   960     }
       
   961   }
       
   962   else
       
   963   {
       
   964     //printf("local variable!\n");
       
   965     if (lcd!=VariableContext::dummyContext) 
       
   966     {
       
   967       //printf("non-dummy context lcd=%s!\n",lcd->name().data());
       
   968       g_theCallContext.setClass(lcd);
       
   969 
       
   970       // to following is needed for links to a global variable, but is
       
   971       // no good for a link to a local variable that is also a global symbol.
       
   972        
       
   973       //if (getLink(g_classScope,clName,ol,clName))
       
   974       //{
       
   975 	//return;
       
   976       //}
       
   977     }
       
   978     isLocal=TRUE;
       
   979     //fprintf(stderr,"is a local variable cd=%p!\n",cd);
       
   980   }
       
   981   if (cd && cd->isLinkable()) // is it a linkable class
       
   982   {
       
   983     //fprintf(stderr,"is linkable class %s\n",clName);
       
   984     if (g_exampleBlock)
       
   985     {
       
   986       QCString anchor;
       
   987       anchor.sprintf("_a%d",g_anchorCount);
       
   988       //printf("addExampleClass(%s,%s,%s)\n",anchor.data(),g_exampleName.data(),
       
   989       //                                   g_exampleFile.data());
       
   990       if (cd->addExample(anchor,g_exampleName,g_exampleFile))
       
   991       {
       
   992 	ol.writeCodeAnchor(anchor);
       
   993 	g_anchorCount++;
       
   994       }
       
   995     }
       
   996     ol.linkableSymbol(g_yyLineNr,cd->name(),cd,
       
   997                       g_currentMemberDef ? g_currentMemberDef : g_currentDefinition);
       
   998     writeMultiLineCodeLink(ol,cd->getReference(),cd->getOutputFileBase(),0,clName,cd->briefDescriptionAsTooltip());
       
   999     addToSearchIndex(className);
       
  1000     if (md)
       
  1001     {
       
  1002       Definition *d = md->getOuterScope()==Doxygen::globalScope ?
       
  1003                       md->getBodyDef() : md->getOuterScope();
       
  1004       if (md->getGroupDef()) d = md->getGroupDef();
       
  1005       if (d && d->isLinkable() && md->isLinkable() && g_currentMemberDef)
       
  1006       {
       
  1007         addDocCrossReference(g_currentMemberDef,md);
       
  1008       }
       
  1009     }
       
  1010   }
       
  1011   else // not a class, maybe a global member
       
  1012   {
       
  1013     //fprintf(stderr,"class %s not linkable! cd=%p md=%p typeOnly=%d\n",clName,cd,md,typeOnly);
       
  1014     if (!isLocal && (md!=0 || (cd==0 && !typeOnly))) // not a class, see if it is a global enum/variable/typedef.
       
  1015     {
       
  1016       if (md==0) // not found as a typedef
       
  1017       {
       
  1018 	md = setCallContextForVar(clName);
       
  1019 	//printf("setCallContextForVar(%s) md=%p g_currentDefinition=%p\n",clName,md,g_currentDefinition);
       
  1020 	if (md && g_currentDefinition)
       
  1021 	{
       
  1022 	  //fprintf(stderr,"%s accessible from %s? %d md->getOuterScope=%s\n",
       
  1023 	  //    md->name().data(),g_currentDefinition->name().data(),
       
  1024 	  //    isAccessibleFrom(g_currentDefinition,g_sourceFileDef,md),
       
  1025 	  //    md->getOuterScope()->name().data());
       
  1026 	}
       
  1027 	     
       
  1028         if (md && g_currentDefinition && 
       
  1029 	    isAccessibleFrom(g_currentDefinition,g_sourceFileDef,md)==-1)
       
  1030 	{
       
  1031 	  md=0; // variable not accessible
       
  1032 	}
       
  1033       }
       
  1034       if (md)
       
  1035       {
       
  1036         //fprintf(stderr,"is a global md=%p g_currentDefinition=%s linkable=%d\n",md,g_currentDefinition?g_currentDefinition->name().data():"<none>",md->isLinkable());
       
  1037 	if (md->isLinkable())
       
  1038 	{
       
  1039           ol.linkableSymbol(g_yyLineNr,md->name(),md,
       
  1040 	                    g_currentMemberDef ? g_currentMemberDef : g_currentDefinition);
       
  1041 	  writeMultiLineCodeLink(ol,md->getReference(),md->getOutputFileBase(),md->anchor(),clName,md->briefDescriptionAsTooltip());
       
  1042           addToSearchIndex(clName);
       
  1043 	  if (g_currentMemberDef)
       
  1044 	  {
       
  1045 	    addDocCrossReference(g_currentMemberDef,md);
       
  1046 	  }
       
  1047 	  return;
       
  1048 	}
       
  1049       }
       
  1050     }
       
  1051     
       
  1052     // nothing found, just write out the word
       
  1053     //fprintf(stderr,"not found!\n");
       
  1054     ol.linkableSymbol(g_yyLineNr,clName,0,
       
  1055 	              g_currentMemberDef?g_currentMemberDef:g_currentDefinition);
       
  1056     codifyLines(clName);
       
  1057     addToSearchIndex(clName);
       
  1058   }
       
  1059 }
       
  1060 
       
  1061 static bool generateClassMemberLink(CodeOutputInterface &ol,MemberDef *xmd,const char *memName)
       
  1062 {
       
  1063   // extract class definition of the return type in order to resolve
       
  1064   // a->b()->c() like call chains
       
  1065 
       
  1066   //printf("type=`%s' args=`%s' class=%s\n",
       
  1067   //  xmd->typeString(),xmd->argsString(),
       
  1068   //  xmd->getClassDef()->name().data());
       
  1069 
       
  1070   if (g_exampleBlock)
       
  1071   {
       
  1072     QCString anchor;
       
  1073     anchor.sprintf("a%d",g_anchorCount);
       
  1074     //printf("addExampleFile(%s,%s,%s)\n",anchor.data(),g_exampleName.data(),
       
  1075     //                                  g_exampleFile.data());
       
  1076     if (xmd->addExample(anchor,g_exampleName,g_exampleFile))
       
  1077     {
       
  1078       ol.writeCodeAnchor(anchor);
       
  1079       g_anchorCount++;
       
  1080     }
       
  1081   }
       
  1082 
       
  1083   ClassDef *typeClass = stripClassName(removeAnonymousScopes(xmd->typeString()));
       
  1084   //fprintf(stderr,"%s -> typeName=%p\n",xmd->typeString(),typeClass);
       
  1085   g_theCallContext.setClass(typeClass);
       
  1086 
       
  1087   Definition *xd = xmd->getOuterScope()==Doxygen::globalScope ?
       
  1088     xmd->getBodyDef() : xmd->getOuterScope();
       
  1089   if (xmd->getGroupDef()) xd = xmd->getGroupDef();
       
  1090   if (xd && xd->isLinkable())
       
  1091   {
       
  1092 
       
  1093     //printf("g_currentDefiniton=%p g_currentMemberDef=%p xmd=%p g_insideBody=%d\n",g_currentDefinition,g_currentMemberDef,xmd,g_insideBody);
       
  1094 
       
  1095     if (xmd->templateMaster()) xmd = xmd->templateMaster();
       
  1096 
       
  1097     if (xmd->isLinkable())
       
  1098     {
       
  1099       // add usage reference
       
  1100       if (g_currentDefinition && g_currentMemberDef &&
       
  1101 	  /*xmd!=g_currentMemberDef &&*/ g_insideBody)
       
  1102       {
       
  1103 	addDocCrossReference(g_currentMemberDef,xmd);
       
  1104       }
       
  1105 
       
  1106       // write the actual link
       
  1107       ol.linkableSymbol(g_yyLineNr,xmd->name(),xmd,
       
  1108 	  g_currentMemberDef ? g_currentMemberDef : g_currentDefinition);
       
  1109       writeMultiLineCodeLink(ol,xmd->getReference(),
       
  1110 	  xmd->getOutputFileBase(),xmd->anchor(),memName,xmd->briefDescriptionAsTooltip());
       
  1111       addToSearchIndex(memName);
       
  1112       return TRUE;
       
  1113     }
       
  1114   }
       
  1115 
       
  1116   return FALSE;
       
  1117 }
       
  1118 
       
  1119 static bool generateClassMemberLink(CodeOutputInterface &ol,ClassDef *mcd,const char *memName)
       
  1120 {
       
  1121   if (mcd)
       
  1122   {
       
  1123     MemberDef *xmd = mcd->getMemberByName(memName);
       
  1124     //printf("generateClassMemberLink(class=%s,member=%s)=%p\n",mcd->name().data(),memName,xmd);
       
  1125     if (xmd)
       
  1126     {
       
  1127       return generateClassMemberLink(ol,xmd,memName);
       
  1128     }
       
  1129   }
       
  1130   
       
  1131   return FALSE;
       
  1132 }
       
  1133 
       
  1134 static void generateMemberLink(CodeOutputInterface &ol,const QCString &varName,
       
  1135             char *memName)
       
  1136 {
       
  1137   //printf("generateMemberLink(object=%s,mem=%s) classScope=%s\n",
       
  1138   //    varName.data(),memName,g_classScope.data());
       
  1139 
       
  1140   if (varName.isEmpty()) return;
       
  1141 
       
  1142   // look for the variable in the current context
       
  1143   ClassDef *vcd = g_theVarContext.findVariable(varName);
       
  1144   if (vcd) 
       
  1145   {
       
  1146     if (vcd!=VariableContext::dummyContext)
       
  1147     {
       
  1148       //printf("Class found!\n");
       
  1149       if (getLink(vcd->name(),memName,ol)) 
       
  1150       {
       
  1151 	//printf("Found result!\n");
       
  1152 	return;
       
  1153       }
       
  1154       if (vcd->baseClasses())
       
  1155       {
       
  1156 	BaseClassListIterator bcli(*vcd->baseClasses());
       
  1157 	for ( ; bcli.current() ; ++bcli)
       
  1158 	{
       
  1159 	  if (getLink(bcli.current()->classDef->name(),memName,ol)) 
       
  1160 	  {
       
  1161 	    //printf("Found result!\n");
       
  1162 	    return;
       
  1163 	  }
       
  1164 	}
       
  1165       }
       
  1166     }
       
  1167   }
       
  1168   else // variable not in current context, maybe it is in a parent context
       
  1169   {
       
  1170     vcd = getResolvedClass(g_currentDefinition,g_sourceFileDef,g_classScope);
       
  1171     if (vcd && vcd->isLinkable())
       
  1172     {
       
  1173       //printf("Found class %s for variable `%s'\n",g_classScope.data(),varName.data());
       
  1174       MemberName *vmn=Doxygen::memberNameSDict->find(varName);
       
  1175       if (vmn==0)
       
  1176       {
       
  1177 	int vi;
       
  1178 	QCString vn=varName;
       
  1179 	QCString scope;
       
  1180 	if ((vi=vn.findRev("::"))!=-1 || (vi=vn.findRev('.'))!=-1)  // explicit scope A::b(), probably static member
       
  1181 	{
       
  1182 	  ClassDef *jcd = getClass(vn.left(vi));
       
  1183 	  vn=vn.right(vn.length()-vi-2);
       
  1184 	  vmn=Doxygen::memberNameSDict->find(vn);
       
  1185 	  //printf("Trying name `%s' scope=%s\n",vn.data(),scope.data());
       
  1186 	  if (vmn)
       
  1187 	  {
       
  1188 	    MemberNameIterator vmni(*vmn);
       
  1189 	    MemberDef *vmd;
       
  1190 	    for (;(vmd=vmni.current());++vmni)
       
  1191 	    {
       
  1192 	      if (/*(vmd->isVariable() || vmd->isFunction()) && */
       
  1193 		  vmd->getClassDef()==jcd)
       
  1194 	      {
       
  1195 		//printf("Found variable type=%s\n",vmd->typeString());
       
  1196 		ClassDef *mcd=stripClassName(vmd->typeString());
       
  1197 		if (mcd && mcd->isLinkable())
       
  1198 		{
       
  1199 		  if (generateClassMemberLink(ol,mcd,memName)) return;
       
  1200 		}
       
  1201 	      }
       
  1202 	    }
       
  1203 	  }
       
  1204 	}
       
  1205       }
       
  1206       if (vmn)
       
  1207       {
       
  1208 	//printf("There is a variable with name `%s'\n",varName);
       
  1209 	MemberNameIterator vmni(*vmn);
       
  1210 	MemberDef *vmd;
       
  1211 	for (;(vmd=vmni.current());++vmni)
       
  1212 	{
       
  1213 	  if (/*(vmd->isVariable() || vmd->isFunction()) && */
       
  1214 	      vmd->getClassDef()==vcd)
       
  1215 	  {
       
  1216 	    //printf("Found variable type=%s\n",vmd->typeString());
       
  1217 	    ClassDef *mcd=stripClassName(vmd->typeString());
       
  1218 	    if (mcd && mcd->isLinkable())
       
  1219 	    {
       
  1220 	      if (generateClassMemberLink(ol,mcd,memName)) return;
       
  1221 	    }
       
  1222 	  }
       
  1223 	}
       
  1224       }
       
  1225     }
       
  1226   }
       
  1227   // nothing found -> write result as is
       
  1228   ol.linkableSymbol(g_yyLineNr,memName,0,
       
  1229 	            g_currentMemberDef?g_currentMemberDef:g_currentDefinition);
       
  1230   codifyLines(memName);
       
  1231   addToSearchIndex(memName);
       
  1232   return;
       
  1233 }
       
  1234 
       
  1235 static void generateFunctionLink(CodeOutputInterface &ol,char *funcName)
       
  1236 {
       
  1237   if (g_currentMemberDef && g_currentMemberDef->getClassDef() &&
       
  1238       funcName==g_currentMemberDef->localName() && 
       
  1239       g_currentMemberDef->getDefLine()==g_yyLineNr &&
       
  1240       generateClassMemberLink(ol,g_currentMemberDef,funcName)
       
  1241      )
       
  1242   {
       
  1243     // special case where funcName is the name of a method that is also
       
  1244     // defined on this line. In this case we can directly link to 
       
  1245     // g_currentMemberDef, which is not only faster, but
       
  1246     // in case of overloaded methods, this will make sure that we link to
       
  1247     // the correct method, and thereby get the correct reimplemented relations.
       
  1248     // See also bug 549022.
       
  1249     return;
       
  1250   }
       
  1251   //CodeClassDef *ccd=0;
       
  1252   ClassDef *ccd=0;
       
  1253   QCString locScope=g_classScope;
       
  1254   QCString locFunc=removeRedundantWhiteSpace(funcName);
       
  1255   //fprintf(stdout,"*** locScope=%s locFunc=%s\n",locScope.data(),locFunc.data());
       
  1256   int len=2;
       
  1257   int i=locFunc.findRev("::");
       
  1258   if (i==-1) i=locFunc.findRev("."),len=1;
       
  1259   if (i>0)
       
  1260   {
       
  1261     if (locScope.isEmpty())
       
  1262     {
       
  1263       locScope=locFunc.left(i);
       
  1264     }
       
  1265     else
       
  1266     {
       
  1267       locScope+="::"+locFunc.left(i);
       
  1268     }
       
  1269     locFunc=locFunc.right(locFunc.length()-i-len).stripWhiteSpace();
       
  1270     int ts=locScope.find('<'); // start of template
       
  1271     int te=locScope.findRev('>'); // end of template
       
  1272     //printf("ts=%d te=%d\n",ts,te);
       
  1273     if (ts!=-1 && te!=-1 && te>ts)
       
  1274     {
       
  1275       // remove template from scope
       
  1276       locScope=locScope.left(ts)+locScope.right(locScope.length()-te-1);
       
  1277     }
       
  1278   }
       
  1279   //printf("generateFunctionLink(%s) classScope=`%s'\n",locFunc.data(),locScope.data());
       
  1280   if (!locScope.isEmpty() && (ccd=g_codeClassSDict->find(locScope)))
       
  1281   {
       
  1282     //printf("using classScope %s\n",g_classScope.data());
       
  1283     if (ccd->baseClasses())
       
  1284     {
       
  1285       BaseClassListIterator bcli(*ccd->baseClasses());
       
  1286       for ( ; bcli.current() ; ++bcli)
       
  1287       {
       
  1288 	if (getLink(bcli.current()->classDef->name(),locFunc,ol,funcName)) 
       
  1289 	{
       
  1290 	  return;
       
  1291 	}
       
  1292       }
       
  1293     }
       
  1294   }
       
  1295   if (!getLink(locScope,locFunc,ol,funcName))
       
  1296   {
       
  1297     generateClassOrGlobalLink(ol,funcName);
       
  1298   }
       
  1299   return;
       
  1300 }
       
  1301 
       
  1302 /*! counts the number of lines in the input */
       
  1303 static int countLines()
       
  1304 {
       
  1305   const char *p=g_inputString;
       
  1306   char c;
       
  1307   int count=1;
       
  1308   while ((c=*p)) 
       
  1309   { 
       
  1310     p++ ; 
       
  1311     if (c=='\n') count++;  
       
  1312   }
       
  1313   if (p>g_inputString && *(p-1)!='\n') 
       
  1314   { // last line does not end with a \n, so we add an extra
       
  1315     // line and explicitly terminate the line after parsing.
       
  1316     count++, 
       
  1317     g_needsTermination=TRUE; 
       
  1318   } 
       
  1319   return count;
       
  1320 }
       
  1321 
       
  1322 static void endFontClass()
       
  1323 {
       
  1324   if (g_currentFontClass)
       
  1325   {
       
  1326     g_code->endFontClass();
       
  1327     g_currentFontClass=0;
       
  1328   }
       
  1329 }
       
  1330 
       
  1331 static void startFontClass(const char *s)
       
  1332 {
       
  1333   endFontClass();
       
  1334   g_code->startFontClass(s);
       
  1335   g_currentFontClass=s;
       
  1336 }
       
  1337 
       
  1338 //----------------------------------------------------------------------------
       
  1339 
       
  1340 // recursively writes a linkified Objective-C method call
       
  1341 static void writeObjCMethodCall(ObjCCallCtx *ctx)
       
  1342 {
       
  1343   if (ctx==0) return;
       
  1344   char c;
       
  1345   const char *p = ctx->format.data();
       
  1346   if (!ctx->methodName.isEmpty())
       
  1347   {
       
  1348     //printf("writeObjCMethodCall(%s) obj=%s method=%s\n",
       
  1349     //    ctx->format.data(),ctx->objectTypeOrName.data(),ctx->methodName.data());
       
  1350     if (!ctx->objectTypeOrName.isEmpty() && ctx->objectTypeOrName.at(0)!='$')
       
  1351     {
       
  1352       //printf("Looking for object=%s method=%s\n",ctx->objectTypeOrName.data(),
       
  1353       //	ctx->methodName.data());
       
  1354       ClassDef *cd = g_theVarContext.findVariable(ctx->objectTypeOrName);
       
  1355       if (cd==0) // not a local variable
       
  1356       {
       
  1357 	if (ctx->objectTypeOrName=="self")
       
  1358 	{
       
  1359 	  if (g_currentDefinition && 
       
  1360 	      g_currentDefinition->definitionType()==Definition::TypeClass)
       
  1361 	  {
       
  1362 	    ctx->objectType = (ClassDef *)g_currentDefinition;
       
  1363 	  }
       
  1364 	}
       
  1365 	else
       
  1366 	{
       
  1367 	  ctx->objectType = getResolvedClass(
       
  1368 	      g_currentDefinition,
       
  1369 	      g_sourceFileDef,
       
  1370 	      ctx->objectTypeOrName,
       
  1371 	      &ctx->method);
       
  1372 	}
       
  1373 	//printf("  object is class? %p\n",ctx->objectType);
       
  1374 	if (ctx->objectType) // found class
       
  1375 	{
       
  1376 	  ctx->method = ctx->objectType->getMemberByName(ctx->methodName);
       
  1377 	  //printf("    yes->method=%s\n",ctx->method?ctx->method->name().data():"<none>");
       
  1378 	}
       
  1379 	else if (ctx->method==0) // search for class variable with the same name
       
  1380 	{
       
  1381 	  //printf("    no\n");
       
  1382 	  //printf("g_currentDefinition=%p\n",g_currentDefinition);
       
  1383 	  if (g_currentDefinition && 
       
  1384 	      g_currentDefinition->definitionType()==Definition::TypeClass)
       
  1385 	  {
       
  1386 	    ctx->objectVar = ((ClassDef *)g_currentDefinition)->getMemberByName(ctx->objectTypeOrName);
       
  1387 	    //printf("      ctx->objectVar=%p\n",ctx->objectVar);
       
  1388 	    if (ctx->objectVar)
       
  1389 	    {
       
  1390 	      ctx->objectType = stripClassName(ctx->objectVar->typeString());
       
  1391 	      //printf("        ctx->objectType=%p\n",ctx->objectType);
       
  1392 	      if (ctx->objectType)
       
  1393 	      {
       
  1394 		ctx->method = ctx->objectType->getMemberByName(ctx->methodName);
       
  1395 		//printf("          ctx->method=%p\n",ctx->method);
       
  1396 	      }
       
  1397 	    }
       
  1398 	  }
       
  1399 	}
       
  1400       }
       
  1401       else // local variable
       
  1402       {
       
  1403 	//printf("  object is local variable\n");
       
  1404 	if (cd!=VariableContext::dummyContext)
       
  1405 	{
       
  1406 	  ctx->method = cd->getMemberByName(ctx->methodName);
       
  1407 	  //printf("   class=%p method=%p\n",cd,ctx->method);
       
  1408 	}
       
  1409       }
       
  1410     }
       
  1411   }
       
  1412 
       
  1413   //printf("[");
       
  1414   while ((c=*p++)) // for each character in ctx->format
       
  1415   {
       
  1416     if (c=='$')
       
  1417     {
       
  1418       char nc=*p++;
       
  1419       if (nc=='$') // escaped $
       
  1420       {
       
  1421 	g_code->codify("$");
       
  1422       }
       
  1423       else // name fragment or reference to a nested call 
       
  1424       {
       
  1425 	if (nc=='n') // name fragment
       
  1426 	{
       
  1427           nc=*p++;
       
  1428 	  QCString refIdStr;
       
  1429 	  while (nc!=0 && isdigit(nc)) { refIdStr+=nc; nc=*p++; }
       
  1430 	  p--;
       
  1431 	  int refId=refIdStr.toInt();
       
  1432 	  QCString *pName = g_nameDict.find(refId);
       
  1433 	  if (pName)
       
  1434 	  {
       
  1435 	    if (ctx->method && ctx->method->isLinkable())
       
  1436 	    {
       
  1437               g_code->linkableSymbol(g_yyLineNr,ctx->method->name(),ctx->method,
       
  1438                             g_currentMemberDef ? g_currentMemberDef : g_currentDefinition);
       
  1439               writeMultiLineCodeLink(*g_code,
       
  1440 		                     ctx->method->getReference(),
       
  1441 	                             ctx->method->getOutputFileBase(),
       
  1442 	                             ctx->method->anchor(),
       
  1443 				     pName->data(),
       
  1444 				     ctx->method->briefDescriptionAsTooltip());
       
  1445 	      if (g_currentMemberDef)
       
  1446 	      {
       
  1447 	        addDocCrossReference(g_currentMemberDef,ctx->method);
       
  1448 	      }
       
  1449 	    }
       
  1450 	    else
       
  1451 	    {
       
  1452               g_code->linkableSymbol(g_yyLineNr,pName->data(),0,
       
  1453                             g_currentMemberDef ? g_currentMemberDef : g_currentDefinition);
       
  1454    	      codifyLines(pName->data());
       
  1455 	    }
       
  1456 	  }
       
  1457 	  else
       
  1458 	  {
       
  1459 	    //printf("Invalid name: id=%d\n",refId);
       
  1460 	  }
       
  1461 	}
       
  1462 	else if (nc=='o') // reference to potential object name
       
  1463 	{
       
  1464           nc=*p++;
       
  1465 	  QCString refIdStr;
       
  1466 	  while (nc!=0 && isdigit(nc)) { refIdStr+=nc; nc=*p++; }
       
  1467 	  p--;
       
  1468 	  int refId=refIdStr.toInt();
       
  1469 	  QCString *pObject = g_objectDict.find(refId);
       
  1470 	  if (pObject)
       
  1471 	  {
       
  1472 	    if (*pObject=="self")
       
  1473 	    {
       
  1474 	      if (g_currentDefinition && 
       
  1475 		  g_currentDefinition->definitionType()==Definition::TypeClass)
       
  1476 	      {
       
  1477 	        ctx->objectType = (ClassDef *)g_currentDefinition;
       
  1478 	        if (ctx->objectType->categoryOf()) 
       
  1479 	        {
       
  1480 	          ctx->objectType = ctx->objectType->categoryOf();
       
  1481 	        }
       
  1482 	        if (ctx->objectType)
       
  1483 	        {
       
  1484 	          ctx->method = ctx->objectType->getMemberByName(ctx->methodName);
       
  1485 	        }
       
  1486 	      }
       
  1487  	      startFontClass("keyword");
       
  1488               codifyLines(pObject->data());
       
  1489 	      endFontClass();
       
  1490 	    }
       
  1491 	    else if (*pObject=="super")
       
  1492 	    {
       
  1493 	      if (g_currentDefinition &&
       
  1494 		  g_currentDefinition->definitionType()==Definition::TypeClass)
       
  1495 	      {
       
  1496 		ClassDef *cd = (ClassDef *)g_currentDefinition;
       
  1497 		if (cd->categoryOf()) 
       
  1498 		{
       
  1499 		  cd = cd->categoryOf();
       
  1500 		}
       
  1501 		BaseClassList *bcd = cd->baseClasses();
       
  1502 		if (bcd) // get direct base class (there should be only one)
       
  1503 		{
       
  1504 		  BaseClassListIterator bli(*bcd);
       
  1505 		  BaseClassDef *bclass;
       
  1506 		  for (bli.toFirst();(bclass=bli.current());++bli)
       
  1507 		  {
       
  1508 		    if (bclass->classDef->compoundType()!=ClassDef::Protocol)
       
  1509 		    {
       
  1510 		      ctx->objectType = bclass->classDef;
       
  1511 		      if (ctx->objectType)
       
  1512 		      {
       
  1513 			ctx->method = ctx->objectType->getMemberByName(ctx->methodName);
       
  1514 		      }
       
  1515 		    }
       
  1516 		  }
       
  1517 		}
       
  1518 	      }
       
  1519  	      startFontClass("keyword");
       
  1520               codifyLines(pObject->data());
       
  1521 	      endFontClass();
       
  1522 	    }
       
  1523 	    else if (ctx->objectVar && ctx->objectVar->isLinkable()) // object is class variable
       
  1524 	    {
       
  1525               g_code->linkableSymbol(g_yyLineNr,ctx->objectVar->name(),ctx->objectVar,
       
  1526                             g_currentMemberDef ? g_currentMemberDef : g_currentDefinition);
       
  1527 	      writeMultiLineCodeLink(*g_code,
       
  1528 		    ctx->objectVar->getReference(),
       
  1529 		    ctx->objectVar->getOutputFileBase(),
       
  1530 		    ctx->objectVar->anchor(),
       
  1531 		    pObject->data(),
       
  1532 		    ctx->objectVar->briefDescriptionAsTooltip());
       
  1533 	      if (g_currentMemberDef)
       
  1534 	      {
       
  1535 	        addDocCrossReference(g_currentMemberDef,ctx->objectVar);
       
  1536 	      }
       
  1537 	    }
       
  1538 	    else if (ctx->objectType && 
       
  1539 		     ctx->objectType!=VariableContext::dummyContext && 
       
  1540 		     ctx->objectType->isLinkable()
       
  1541 		    ) // object is class name
       
  1542 	    {
       
  1543 	      ClassDef *cd = ctx->objectType;
       
  1544               g_code->linkableSymbol(g_yyLineNr,cd->name(),cd,
       
  1545                             g_currentMemberDef ? g_currentMemberDef : g_currentDefinition);
       
  1546 	      writeMultiLineCodeLink(*g_code,
       
  1547 		    cd->getReference(),
       
  1548 		    cd->getOutputFileBase(),
       
  1549 		    0,
       
  1550 		    pObject->data(),
       
  1551 		    cd->briefDescriptionAsTooltip());
       
  1552 	    }
       
  1553 	    else // object still needs to be resolved
       
  1554 	    {
       
  1555 	      ClassDef *cd = getResolvedClass(g_currentDefinition, 
       
  1556 		  g_sourceFileDef, *pObject);
       
  1557 	      if (cd && cd->isLinkable())
       
  1558 	      {
       
  1559 		if (ctx->objectType==0) ctx->objectType=cd;
       
  1560                 g_code->linkableSymbol(g_yyLineNr,cd->name(),cd,
       
  1561                             g_currentMemberDef ? g_currentMemberDef : g_currentDefinition);
       
  1562 	   	writeMultiLineCodeLink(*g_code,
       
  1563 		    cd->getReference(),
       
  1564 		    cd->getOutputFileBase(),
       
  1565 		    0,
       
  1566 		    pObject->data(),
       
  1567 		    cd->briefDescriptionAsTooltip());
       
  1568 	      }
       
  1569 	      else
       
  1570 	      {
       
  1571                 g_code->linkableSymbol(g_yyLineNr,pObject->data(),0,
       
  1572                             g_currentMemberDef ? g_currentMemberDef : g_currentDefinition);
       
  1573 		codifyLines(pObject->data());
       
  1574 	      }
       
  1575 	    }
       
  1576 	  }
       
  1577 	  else
       
  1578 	  {
       
  1579 	    //printf("Invalid object: id=%d\n",refId);
       
  1580 	  }
       
  1581 	}
       
  1582 	else if (nc=='c') // reference to nested call
       
  1583 	{
       
  1584           nc=*p++;
       
  1585 	  QCString refIdStr;
       
  1586 	  while (nc!=0 && isdigit(nc)) { refIdStr+=nc; nc=*p++; }
       
  1587 	  p--;
       
  1588 	  int refId=refIdStr.toInt();
       
  1589 	  ObjCCallCtx *ictx = g_contextDict.find(refId);
       
  1590 	  if (ictx) // recurse into nested call
       
  1591 	  {
       
  1592 	    writeObjCMethodCall(ictx);
       
  1593 	    if (ictx->method) // link to nested call successfully
       
  1594 	    {
       
  1595 	      // get the ClassDef representing the method's return type
       
  1596 	      if (QCString(ictx->method->typeString())=="id")
       
  1597 	      {
       
  1598 		// see if the method name is unique, if so we link to it
       
  1599 		MemberName *mn=Doxygen::memberNameSDict->find(ctx->methodName);
       
  1600 		//printf("mn->count=%d ictx->method=%s ctx->methodName=%s\n",
       
  1601 		//    mn==0?-1:(int)mn->count(),
       
  1602 		//    ictx->method->name().data(),
       
  1603 		//    ctx->methodName.data());
       
  1604 		if (mn && mn->count()==1) // member name unique
       
  1605 		{
       
  1606 		  ctx->method = mn->getFirst();
       
  1607 		}
       
  1608 	      } 
       
  1609 	      else
       
  1610 	      {
       
  1611 		ctx->objectType = stripClassName(ictx->method->typeString());
       
  1612 		if (ctx->objectType)
       
  1613 		{
       
  1614 		  ctx->method = ctx->objectType->getMemberByName(ctx->methodName);
       
  1615 		}
       
  1616 	      }
       
  1617 	      //printf("  ***** method=%s -> object=%p\n",ictx->method->name().data(),ctx->objectType);
       
  1618 	    }
       
  1619 	  }
       
  1620 	  else
       
  1621 	  {
       
  1622 	    //printf("Invalid context: id=%d\n",refId);
       
  1623 	  }
       
  1624 	}
       
  1625 	else if (nc=='w') // some word
       
  1626 	{
       
  1627           nc=*p++;
       
  1628 	  QCString refIdStr;
       
  1629 	  while (nc!=0 && isdigit(nc)) { refIdStr+=nc; nc=*p++; }
       
  1630 	  p--;
       
  1631 	  int refId=refIdStr.toInt();
       
  1632 	  QCString *pWord = g_wordDict.find(refId);
       
  1633 	  if (pWord)
       
  1634 	  {
       
  1635             g_code->linkableSymbol(g_yyLineNr,pWord->data(),0,
       
  1636                          g_currentMemberDef ? g_currentMemberDef : g_currentDefinition);
       
  1637             codifyLines(pWord->data());
       
  1638 	  }
       
  1639 	}
       
  1640 	else // illegal marker
       
  1641 	{
       
  1642 	  ASSERT(!"invalid escape sequence");
       
  1643 	}
       
  1644       }
       
  1645     }
       
  1646     else // normal non-marker character
       
  1647     {
       
  1648       char s[2];
       
  1649       s[0]=c;s[1]=0;
       
  1650       codifyLines(s);
       
  1651     }
       
  1652   }  
       
  1653   //printf("%s %s]\n",ctx->objectTypeOrName.data(),ctx->methodName.data());
       
  1654   //printf("}=(type='%s',name='%s')",
       
  1655   //    ctx->objectTypeOrName.data(),
       
  1656   //    ctx->methodName.data());
       
  1657 }
       
  1658 
       
  1659 // Replaces an Objective-C method name fragment s by a marker of the form
       
  1660 // $n12, the number (12) can later be used as a key for obtaining the name 
       
  1661 // fragment, from g_nameDict
       
  1662 static QCString escapeName(const char *s)
       
  1663 {
       
  1664   QCString result;
       
  1665   result.sprintf("$n%d",g_currentNameId);
       
  1666   g_nameDict.insert(g_currentNameId,new QCString(s));
       
  1667   g_currentNameId++;
       
  1668   return result;
       
  1669 }
       
  1670 
       
  1671 static QCString escapeObject(const char *s)
       
  1672 {
       
  1673   QCString result;
       
  1674   result.sprintf("$o%d",g_currentObjId);
       
  1675   g_objectDict.insert(g_currentObjId,new QCString(s));
       
  1676   g_currentObjId++;
       
  1677   return result;
       
  1678 }
       
  1679 
       
  1680 static QCString escapeWord(const char *s)
       
  1681 {
       
  1682   QCString result;
       
  1683   result.sprintf("$w%d",g_currentWordId);
       
  1684   g_wordDict.insert(g_currentWordId,new QCString(s));
       
  1685   g_currentWordId++;
       
  1686   return result;
       
  1687 }
       
  1688 
       
  1689 /* -----------------------------------------------------------------
       
  1690  */
       
  1691 #undef	YY_INPUT
       
  1692 #define	YY_INPUT(buf,result,max_size) result=yyread(buf,max_size);
       
  1693 
       
  1694 static int yyread(char *buf,int max_size)
       
  1695 {
       
  1696     int c=0;
       
  1697     while( c < max_size && g_inputString[g_inputPosition] )
       
  1698     {
       
  1699 	*buf = g_inputString[g_inputPosition++] ;
       
  1700 	c++; buf++;
       
  1701     }
       
  1702     return c;
       
  1703 }
       
  1704 
       
  1705 %}
       
  1706 
       
  1707 B       [ \t]
       
  1708 BN      [ \t\n\r]
       
  1709 ID	"$"?[a-z_A-Z\x80-\xFF][a-z_A-Z0-9\x80-\xFF]*
       
  1710 SCOPENAME "$"?(({ID}?{BN}*"::"{BN}*)*)((~{BN}*)?{ID})
       
  1711 TEMPLIST "<"[^\"\}\{\(\)\/\n\>]*">"
       
  1712 SCOPETNAME ((({ID}{TEMPLIST}?){BN}*"::"{BN}*)*)((~{BN}*)?{ID})
       
  1713 SCOPEPREFIX ({ID}{TEMPLIST}?{BN}*"::"{BN}*)+
       
  1714 KEYWORD_OBJC ("@public"|"@private"|"@protected"|"@class"|"@implementation"|"@interface"|"@end"|"@selector"|"@protocol"|"@optional"|"@required"|"@throw"|"@synthesize")
       
  1715 KEYWORD ("asm"|"__assume"|"auto"|"class"|"const"|"delete"|"enum"|"explicit"|"extern"|"false"|"friend"|"gcnew"|"gcroot"|"get"|"inline"|"internal"|"mutable"|"namespace"|"new"|"nullptr"|"override"|"operator"|"pin_ptr"|"private"|"protected"|"public"|"raise"|"register"|"remove"|"self"|"set"|"sizeof"|"static"|"struct"|"__super"|"template"|"generic"|"this"|"true"|"typedef"|"typeid"|"typename"|"union"|"using"|"virtual"|"volatile"|"abstract"|"final"|"import"|"synchronized"|"transient"|{KEYWORD_OBJC})
       
  1716 FLOWKW  ("break"|"case"|"catch"|"continue"|"default"|"do"|"else"|"finally"|"for"|"foreach"|"for each"|"goto"|"if"|"return"|"switch"|"throw"|"throws"|"try"|"while"|"@try"|"@catch"|"@finally")
       
  1717 TYPEKW  ("bool"|"char"|"double"|"float"|"int"|"long"|"object"|"short"|"signed"|"unsigned"|"void"|"wchar_t"|"size_t"|"boolean"|"id"|"SEL"|"string")
       
  1718 CASTKW ("const_cast"|"dynamic_cast"|"reinterpret_cast"|"static_cast")
       
  1719 CHARLIT   (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^' \\\n]{1,4}"'"))
       
  1720 ARITHOP "+"|"-"|"/"|"*"|"%"|"--"|"++"
       
  1721 ASSIGNOP "="|"*="|"/="|"%="|"+="|"-="|"<<="|">>="|"&="|"^="|"|="
       
  1722 LOGICOP "=="|"!="|">"|"<"|">="|"<="|"&&"|"||"|"!"
       
  1723 BITOP   "&"|"|"|"^"|"<<"|">>"|"~"
       
  1724 OPERATOR {ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}
       
  1725 %option noyywrap
       
  1726 
       
  1727 %x      SkipString
       
  1728 %x      SkipStringS
       
  1729 %x      SkipVerbString
       
  1730 %x	SkipCPP
       
  1731 %x	SkipComment
       
  1732 %x	SkipCxxComment
       
  1733 %x	RemoveSpecialCComment
       
  1734 %x	StripSpecialCComment
       
  1735 %x	Body
       
  1736 %x      FuncCall
       
  1737 %x      MemberCall
       
  1738 %x      MemberCall2
       
  1739 %x      SkipInits
       
  1740 %x      ClassName
       
  1741 %x      PackageName
       
  1742 %x      ClassVar
       
  1743 %x	CppCliTypeModifierFollowup
       
  1744 %x      Bases
       
  1745 %x      SkipSharp
       
  1746 %x      ReadInclude
       
  1747 %x      TemplDecl
       
  1748 %x      TemplCast
       
  1749 %x	CallEnd
       
  1750 %x      ObjCMethod
       
  1751 %x	ObjCParams
       
  1752 %x	ObjCParamType
       
  1753 %x      ObjCCall
       
  1754 %x      ObjCMName
       
  1755 %x      ObjCSkipStr
       
  1756 %x      OldStyleArgs
       
  1757 %x	UsingName
       
  1758 
       
  1759 %%
       
  1760 
       
  1761 <*>\x0d
       
  1762 <Body>^([ \t]*"#"[ \t]*("include"|"import")[ \t]*)("<"|"\"") {
       
  1763   					  startFontClass("preprocessor");
       
  1764 					  g_code->codify(yytext);
       
  1765   					  BEGIN( ReadInclude ); 
       
  1766 					}
       
  1767 <Body>("@interface"|"@implementation"|"@protocol")[ \t\n]+ { 
       
  1768                                           g_insideObjC=TRUE;
       
  1769   					  startFontClass("keyword");
       
  1770   					  codifyLines(yytext);
       
  1771 					  endFontClass();
       
  1772   					  if (!g_insideTemplate) 
       
  1773 					    BEGIN( ClassName ); 
       
  1774 					}
       
  1775 <Body>(("public"|"private"){B}+)?("ref"|"value"|"interface"|"enum"){B}+("class"|"struct") {
       
  1776   					  if (g_insideTemplate) REJECT;
       
  1777   					  startFontClass("keyword");
       
  1778   					  codifyLines(yytext);
       
  1779 					  endFontClass();
       
  1780 					  BEGIN( ClassName ); 
       
  1781 					}
       
  1782 <Body>"property"|"event"/{BN}*			{ 
       
  1783   					  if (g_insideTemplate) REJECT;
       
  1784   					  startFontClass("keyword");
       
  1785   					  codifyLines(yytext);
       
  1786 					  endFontClass();
       
  1787 					}
       
  1788 <Body>(KEYWORD_CPPCLI_DATATYPE|("partial"{B}+)?"class"|"struct"|"union"|"namespace"){B}+ { 
       
  1789   					  startFontClass("keyword");
       
  1790   					  codifyLines(yytext);
       
  1791 					  endFontClass();
       
  1792   					  if (!g_insideTemplate) 
       
  1793 					    BEGIN( ClassName ); 
       
  1794 					}
       
  1795 <Body>("package")[ \t\n]+ 		{ 
       
  1796   					  startFontClass("keyword");
       
  1797   					  codifyLines(yytext);
       
  1798 					  endFontClass();
       
  1799 					  BEGIN( PackageName ); 
       
  1800 					}
       
  1801 <ClassVar>\n				{
       
  1802   					  if (!g_insideObjC) REJECT;
       
  1803   					  codifyLines(yytext);
       
  1804 					  BEGIN(Body);
       
  1805   					}
       
  1806 <Body,ClassVar,Bases>"-"|"+"		{
       
  1807 					  if (!g_insideObjC || g_insideBody)
       
  1808 					  { 
       
  1809   					    g_code->codify(yytext);
       
  1810 					  }
       
  1811 					  else // Start of Objective-C method
       
  1812 					  {
       
  1813 					    //printf("Method!\n");
       
  1814   					    g_code->codify(yytext);
       
  1815 					    BEGIN(ObjCMethod);
       
  1816 					  }
       
  1817   					}
       
  1818 <ObjCMethod>":"				{
       
  1819   					  g_code->codify(yytext);
       
  1820 					  BEGIN(ObjCParams);
       
  1821   					}
       
  1822 <ObjCParams>"("				{
       
  1823   					  g_code->codify(yytext);
       
  1824   					  BEGIN(ObjCParamType);
       
  1825 					}
       
  1826 <ObjCParams,ObjCMethod>";"|"{"		{
       
  1827   					  g_code->codify(yytext);
       
  1828 					  if (*yytext=='{')
       
  1829 					  {
       
  1830 					    g_curlyCount++;
       
  1831   					    if (g_searchingForBody)
       
  1832 					    {
       
  1833 					      g_searchingForBody=FALSE;
       
  1834 					      g_insideBody=TRUE;
       
  1835 					    }
       
  1836 					    if (g_insideBody) g_bodyCurlyCount++;
       
  1837 					    if (!g_curClassName.isEmpty()) // valid class name
       
  1838 					    {
       
  1839 					      pushScope(g_curClassName);
       
  1840                                               DBG_CTX((stderr,"** scope stack push SCOPEBLOCK\n"));
       
  1841   					      g_scopeStack.push(SCOPEBLOCK);
       
  1842 					    }
       
  1843 					  }
       
  1844                                           g_type.resize(0);
       
  1845                                           g_name.resize(0);
       
  1846 					  BEGIN(Body);
       
  1847   					}
       
  1848 <ObjCParams>{ID}{B}*":"			{
       
  1849   					  g_code->codify(yytext);
       
  1850   					}
       
  1851 <ObjCParamType>{TYPEKW} 		{
       
  1852   					  startFontClass("keywordtype");
       
  1853 					  g_code->codify(yytext);
       
  1854 					  endFontClass();
       
  1855   					  g_parmType=yytext;
       
  1856   					}
       
  1857 <ObjCParamType>{ID}			{
       
  1858 					  generateClassOrGlobalLink(*g_code,yytext);
       
  1859   					  g_parmType=yytext;
       
  1860   					}
       
  1861 <ObjCParamType>")"			{
       
  1862   					  g_code->codify(yytext);
       
  1863   					  BEGIN(ObjCParams);
       
  1864   					}
       
  1865 <ObjCParams>{ID}			{
       
  1866                                           g_code->linkableSymbol(g_yyLineNr,yytext,0,
       
  1867 	                                     g_currentMemberDef?g_currentMemberDef:g_currentDefinition);
       
  1868   					  g_code->codify(yytext);
       
  1869   					  g_parmName=yytext;
       
  1870 					  g_theVarContext.addVariable(g_parmType,g_parmName);
       
  1871 					  g_parmType.resize(0);g_parmName.resize(0);
       
  1872   					}
       
  1873 <ObjCMethod,ObjCParams,ObjCParamType>{ID} {
       
  1874 					  generateClassOrGlobalLink(*g_code,yytext);
       
  1875   					}
       
  1876 <ObjCMethod,ObjCParams,ObjCParamType>.	{
       
  1877   					  g_code->codify(yytext);
       
  1878   					}
       
  1879 <ObjCMethod,ObjCParams,ObjCParamType>\n	{
       
  1880   					  codifyLines(yytext);
       
  1881   					}
       
  1882 <ReadInclude>[^\n\"\>]+/(">"|"\"")  	{
       
  1883 					  //FileInfo *f;
       
  1884 					  bool ambig;
       
  1885 					  bool found=FALSE;
       
  1886                                           FileDef *fd=0;
       
  1887 					  //printf("looking for include %s\n",yytext);
       
  1888 					  if ((fd=findFileDef(Doxygen::inputNameDict,yytext,ambig)) &&
       
  1889 					      fd->isLinkable())
       
  1890 					  {
       
  1891 					    if (ambig) // multiple input files match the name
       
  1892 					    {
       
  1893 					      //printf("===== yes %s is ambigious\n",yytext);
       
  1894 					      QCString name = convertToQCString(QDir::cleanDirPath(yytext));
       
  1895 					      if (!name.isEmpty() && g_sourceFileDef)
       
  1896 					      {
       
  1897 					        FileName *fn = Doxygen::inputNameDict->find(name);
       
  1898 						if (fn)
       
  1899 						{
       
  1900 						  FileNameIterator fni(*fn);
       
  1901 						  // for each include name
       
  1902 						  for (fni.toFirst();!found && (fd=fni.current());++fni)
       
  1903 						  {
       
  1904 						    // see if this source file actually includes the file
       
  1905 						    found = g_sourceFileDef->isIncluded(fd->absFilePath());
       
  1906 						    //printf("      include file %s found=%d\n",fd->absFilePath().data(),found);
       
  1907 						  }
       
  1908 						}
       
  1909 					      }
       
  1910 					    }
       
  1911 					    else // not ambiguous
       
  1912 					    {
       
  1913 					      found = TRUE;
       
  1914 					    }
       
  1915 					  }
       
  1916 					  if (found)
       
  1917 					  {
       
  1918 					    //printf("      include file %s found=%d\n",fd->absFilePath().data(),found);
       
  1919 					    g_code->writeCodeLink(fd->getReference(),fd->getOutputFileBase(),0,yytext,fd->briefDescriptionAsTooltip());
       
  1920 					  }
       
  1921 					  else
       
  1922 					  {
       
  1923 					    g_code->codify(yytext);
       
  1924 					  }
       
  1925 					  char c=yyinput();
       
  1926 					  QCString text;
       
  1927 					  text+=c;
       
  1928 					  g_code->codify(text);
       
  1929 					  endFontClass();
       
  1930 					  BEGIN( Body );
       
  1931   					}
       
  1932 <Body,Bases>^[ \t]*"#"			{ 
       
  1933   					  startFontClass("preprocessor");
       
  1934 					  g_lastSkipCppContext = YY_START;
       
  1935   					  g_code->codify(yytext);
       
  1936   					  BEGIN( SkipCPP ) ; 
       
  1937 					}
       
  1938 <SkipCPP>.				{ 
       
  1939   					  g_code->codify(yytext);
       
  1940 					}
       
  1941 <SkipCPP>\\[\r]?\n			{ 
       
  1942   					  codifyLines(yytext);
       
  1943 					}
       
  1944 <SkipCPP>"//"				{ 
       
  1945   					  g_code->codify(yytext);
       
  1946 					}
       
  1947 <Body,FuncCall>"{"			{ 
       
  1948                                           g_theVarContext.pushScope();
       
  1949 
       
  1950                                           DBG_CTX((stderr,"** scope stack push INNERBLOCK\n"));
       
  1951   					  g_scopeStack.push(INNERBLOCK);
       
  1952 
       
  1953   					  if (g_searchingForBody)
       
  1954 					  {
       
  1955 					    g_searchingForBody=FALSE;
       
  1956 					    g_insideBody=TRUE;
       
  1957 					  }
       
  1958   					  g_code->codify(yytext);
       
  1959   					  g_curlyCount++;
       
  1960 					  if (g_insideBody) 
       
  1961 					  {
       
  1962 					    g_bodyCurlyCount++;
       
  1963 					  }
       
  1964   					  g_type.resize(0); 
       
  1965 					  g_name.resize(0);
       
  1966 					  BEGIN( Body );
       
  1967 					}
       
  1968 <Body,MemberCall,MemberCall2>"}"	{ 
       
  1969                                           g_theVarContext.popScope();
       
  1970   					  g_type.resize(0); 
       
  1971 					  g_name.resize(0);
       
  1972 
       
  1973 					  int *scope = g_scopeStack.pop();
       
  1974                                           DBG_CTX((stderr,"** scope stack pop SCOPEBLOCK=%d\n",scope==SCOPEBLOCK));
       
  1975   					  if (scope==SCOPEBLOCK || scope==CLASSBLOCK) 
       
  1976 					  {
       
  1977 					    popScope();
       
  1978 					  }
       
  1979 
       
  1980   					  g_code->codify(yytext);
       
  1981 
       
  1982 					  //fprintf(stderr,"g_bodyCurlyCount=%d\n",g_bodyCurlyCount);
       
  1983 					  if (--g_bodyCurlyCount<=0)
       
  1984 					  {
       
  1985 					    g_insideBody=FALSE;
       
  1986 					    g_currentMemberDef=0;
       
  1987 					    if (g_currentDefinition) 
       
  1988 					      g_currentDefinition=g_currentDefinition->getOuterScope();
       
  1989 					  }
       
  1990 					  BEGIN(Body);
       
  1991 					}
       
  1992 <Body,ClassVar>"@end"			{ 
       
  1993   					  //printf("End of objc scope fd=%s\n",g_sourceFileDef->name().data());
       
  1994                                           if (g_sourceFileDef)
       
  1995 					  {
       
  1996 					    FileDef *fd=g_sourceFileDef;
       
  1997                                             g_insideObjC = fd->name().lower().right(2)==".m" || 
       
  1998                                                            fd->name().lower().right(3)==".mm"; 
       
  1999 					    //printf("insideObjC=%d\n",g_insideObjC);
       
  2000 					  }
       
  2001 					  else
       
  2002 					  {
       
  2003 					    g_insideObjC = FALSE;
       
  2004 					  }
       
  2005 					  if (g_insideBody)
       
  2006 					  {
       
  2007                                             g_theVarContext.popScope();
       
  2008 
       
  2009 					    int *scope = g_scopeStack.pop();
       
  2010                                             DBG_CTX((stderr,"** scope stack pop SCOPEBLOCK=%d\n",scope==SCOPEBLOCK));
       
  2011   					    if (scope==SCOPEBLOCK || scope==CLASSBLOCK) 
       
  2012 					    {
       
  2013 					      popScope();
       
  2014 					    }
       
  2015 					    g_insideBody=FALSE;
       
  2016 					  }
       
  2017 
       
  2018 					  startFontClass("keyword");
       
  2019   					  g_code->codify(yytext);
       
  2020 					  endFontClass();
       
  2021 
       
  2022 					  g_currentMemberDef=0;
       
  2023 					  if (g_currentDefinition) 
       
  2024 					    g_currentDefinition=g_currentDefinition->getOuterScope();
       
  2025 					  BEGIN(Body);
       
  2026 					}
       
  2027 <ClassName,ClassVar>";"			{ 
       
  2028   					  g_code->codify(yytext);
       
  2029 					  g_searchingForBody=FALSE; 
       
  2030   					  BEGIN( Body ); 
       
  2031 					}
       
  2032 <ClassName,ClassVar>[*&^%]+       	{
       
  2033   					  g_type=g_curClassName.copy();
       
  2034   					  g_name.resize(0);
       
  2035 					  g_code->codify(yytext);
       
  2036 					  BEGIN( Body ); // variable of type struct *
       
  2037 					}
       
  2038 <ClassName>"__declspec"{B}*"("{B}*{ID}{B}*")"	{
       
  2039 					  startFontClass("keyword");
       
  2040   					  g_code->codify(yytext);
       
  2041 					  endFontClass();
       
  2042 					}
       
  2043 <ClassName>{ID}("::"{ID})*	        {
       
  2044                                           g_curClassName=yytext;
       
  2045 					  addType();
       
  2046 					  generateClassOrGlobalLink(*g_code,yytext);
       
  2047 					  BEGIN( ClassVar );
       
  2048 					}
       
  2049 <PackageName>{ID}("."{ID})*		{
       
  2050                                           g_curClassName=yytext;
       
  2051 					  g_curClassName=substitute(g_curClassName,".","::");
       
  2052 					  //printf("found package: %s\n",g_curClassName.data());
       
  2053 					  addType();
       
  2054 					  codifyLines(yytext);
       
  2055   					}
       
  2056 <ClassVar>"="				{
       
  2057 					  unput(*yytext);
       
  2058 					  BEGIN( Body );
       
  2059   					}
       
  2060 <ClassVar>("extends"|"implements")	{ // Java
       
  2061   					  startFontClass("keyword");
       
  2062   					  codifyLines(yytext);
       
  2063 					  endFontClass();
       
  2064 					  g_curClassBases.clear();
       
  2065   					  BEGIN( Bases ); 
       
  2066 					}
       
  2067 <ClassVar>("sealed"|"abstract")/{BN}*(":"|"{") {
       
  2068 					  //fprintf(stderr,"***** C++/CLI modifier %s on g_curClassName=%s\n",yytext,g_curClassName.data());
       
  2069   					  startFontClass("keyword");
       
  2070   					  codifyLines(yytext);
       
  2071 					  endFontClass();
       
  2072   					  BEGIN( CppCliTypeModifierFollowup ); 
       
  2073 					}
       
  2074 <ClassVar>{ID}				{
       
  2075   					  g_type = g_curClassName.copy();
       
  2076 					  g_name = yytext;
       
  2077 					  if (g_insideBody)
       
  2078 					  {
       
  2079 					    g_theVarContext.addVariable(g_type,g_name);
       
  2080 					  }
       
  2081 					  generateClassOrGlobalLink(*g_code,yytext);
       
  2082   					}
       
  2083 <ClassName,ClassVar,CppCliTypeModifierFollowup>{B}*":"{B}*	{
       
  2084   					  codifyLines(yytext);
       
  2085 					  g_curClassBases.clear();
       
  2086   					  BEGIN( Bases ); 
       
  2087 					}
       
  2088 <PackageName>[ \t]*";"				|
       
  2089 <Bases,ClassName,ClassVar,CppCliTypeModifierFollowup>{B}*"{"{B}* {
       
  2090                                           g_theVarContext.pushScope();
       
  2091   					  g_code->codify(yytext);
       
  2092 					  g_curlyCount++;
       
  2093 					  if (YY_START==ClassVar && g_curClassName.isEmpty())
       
  2094 					  {
       
  2095 					    g_curClassName = g_name.copy();
       
  2096 					  }
       
  2097   					  if (g_searchingForBody)
       
  2098 					  {
       
  2099 					    g_searchingForBody=FALSE;
       
  2100 					    g_insideBody=TRUE;
       
  2101 					  }
       
  2102 					  if (g_insideBody) g_bodyCurlyCount++;
       
  2103 					  if (!g_curClassName.isEmpty()) // valid class name
       
  2104 					  {
       
  2105                                             DBG_CTX((stderr,"** scope stack push CLASSBLOCK\n"));
       
  2106   					    g_scopeStack.push(CLASSBLOCK);
       
  2107 					    pushScope(g_curClassName);
       
  2108 					    //fprintf(stderr,"***** g_curClassName=%s\n",g_curClassName.data());
       
  2109 					    if (getResolvedClass(g_currentDefinition,g_sourceFileDef,g_curClassName)==0)
       
  2110 					    {
       
  2111 					      //printf("Adding new class %s\n",g_curClassName.data());
       
  2112 					      ClassDef *ncd=new ClassDef("<code>",1,
       
  2113 				 		  g_curClassName,ClassDef::Class,0,0,FALSE);
       
  2114 					      g_codeClassSDict->append(g_curClassName,ncd);
       
  2115 					      // insert base classes.
       
  2116 					      char *s=g_curClassBases.first();
       
  2117 					      while (s)
       
  2118 					      {
       
  2119 						ClassDef *bcd;
       
  2120 						bcd=g_codeClassSDict->find(s);
       
  2121 						if (bcd==0) bcd=getResolvedClass(g_currentDefinition,g_sourceFileDef,s);
       
  2122 						if (bcd && bcd!=ncd)
       
  2123 						{
       
  2124 						  ncd->insertBaseClass(bcd,s,Public,Normal);
       
  2125 						}
       
  2126 						s=g_curClassBases.next();
       
  2127 					      }
       
  2128 					    }
       
  2129 					    //printf("g_codeClassList.count()=%d\n",g_codeClassList.count());
       
  2130 					  }
       
  2131 					  else // not a class name -> assume inner block
       
  2132 					  {
       
  2133                                             DBG_CTX((stderr,"** scope stack push INNERBLOCK\n"));
       
  2134   					    g_scopeStack.push(INNERBLOCK);
       
  2135 					  }
       
  2136 					  g_curClassName.resize(0);
       
  2137 					  g_curClassBases.clear();
       
  2138 					  BEGIN( Body );
       
  2139  					}
       
  2140 <Bases>"virtual"|"public"|"protected"|"private"|"@public"|"@private"|"@protected" { 
       
  2141   					  startFontClass("keyword");
       
  2142   					  g_code->codify(yytext);
       
  2143 					  endFontClass();
       
  2144 					}
       
  2145 <Bases>{ID}	                        { 
       
  2146 					  //printf("%s:addBase(%s)\n",g_ccd.name.data(),yytext);
       
  2147   					  g_curClassBases.inSort(yytext); 
       
  2148 					  generateClassOrGlobalLink(*g_code,yytext);
       
  2149 					}
       
  2150 <Bases>"<"                              { 
       
  2151   					  g_code->codify(yytext);
       
  2152 					  if (!g_insideObjC)
       
  2153 					  {
       
  2154   					    g_sharpCount=1;
       
  2155 					    BEGIN ( SkipSharp );
       
  2156 					  }
       
  2157 					  else
       
  2158 					  {
       
  2159 					    g_insideProtocolList=TRUE;
       
  2160 					  }
       
  2161 					}
       
  2162 <Bases>">"				{
       
  2163   					  g_code->codify(yytext);
       
  2164 					  g_insideProtocolList=FALSE;
       
  2165   					}
       
  2166 <SkipSharp>"<"                          {
       
  2167   					  g_code->codify(yytext);
       
  2168   					  ++g_sharpCount; 
       
  2169 					}
       
  2170 <SkipSharp>">"                          { 
       
  2171   					  g_code->codify(yytext);
       
  2172   					  if (--g_sharpCount<=0)
       
  2173 					  BEGIN ( Bases );
       
  2174 					}
       
  2175 <Bases>"("                              {
       
  2176                                           g_code->codify(yytext);
       
  2177                                           g_sharpCount=1;
       
  2178                                           BEGIN ( SkipSharp );
       
  2179                                         }
       
  2180 <SkipSharp>"("                          {
       
  2181                                           g_code->codify(yytext);
       
  2182                                           ++g_sharpCount;
       
  2183                                         }
       
  2184 <SkipSharp>")"                          {
       
  2185                                           g_code->codify(yytext);
       
  2186                                           if (--g_sharpCount<=0)
       
  2187                                             BEGIN ( Bases );
       
  2188                                         }
       
  2189       
       
  2190       
       
  2191 <Bases>","                              { 
       
  2192   					  g_code->codify(yytext);
       
  2193 					}
       
  2194   					
       
  2195 
       
  2196 <Body>{SCOPEPREFIX}?"operator"{B}*"()"{B}*/"(" {
       
  2197   					  addType();
       
  2198 					  generateFunctionLink(*g_code,yytext);
       
  2199   					  g_bracketCount=0;
       
  2200 					  g_args.resize(0);
       
  2201   					  g_name+=yytext; 
       
  2202   					  BEGIN( FuncCall );
       
  2203 					}
       
  2204 <Body>{SCOPEPREFIX}?"operator"{B}*[^\(\n]+/"(" {
       
  2205   					  addType();
       
  2206 					  generateFunctionLink(*g_code,yytext);
       
  2207   					  g_bracketCount=0;
       
  2208 					  g_args.resize(0);
       
  2209   					  g_name+=yytext; 
       
  2210   					  BEGIN( FuncCall );
       
  2211 					}
       
  2212 <Body,TemplDecl>("template"|"generic")/([^a-zA-Z0-9])		{
       
  2213   					  startFontClass("keyword");
       
  2214   					  codifyLines(yytext);
       
  2215 					  endFontClass();
       
  2216 					  g_insideTemplate=TRUE;
       
  2217 					  g_sharpCount=0;
       
  2218 					}
       
  2219 <Body>"using"{BN}+"namespace"{BN}+	{
       
  2220   					  startFontClass("keyword");
       
  2221   					  codifyLines(yytext);
       
  2222 					  endFontClass();
       
  2223 					  BEGIN(UsingName);
       
  2224   					}
       
  2225 <UsingName>{ID}("::"{ID})*		{ addUsingDirective(yytext);
       
  2226  					  generateClassOrGlobalLink(*g_code,yytext);
       
  2227 					  BEGIN(Body);
       
  2228                                         }
       
  2229 <UsingName>\n				{ codifyLines(yytext); BEGIN(Body); }
       
  2230 <UsingName>.				{ codifyLines(yytext); BEGIN(Body); }
       
  2231 <Body,FuncCall>"$"?"this"("->"|".")	{ g_code->codify(yytext); // this-> for C++, this. for C#
       
  2232                                         }
       
  2233 <Body>{KEYWORD}/([^a-z_A-Z0-9]) 	{
       
  2234   					  startFontClass("keyword");
       
  2235   					  codifyLines(yytext);
       
  2236 					  if (QCString(yytext)=="typedef")
       
  2237 					  {
       
  2238 					    addType();
       
  2239   					    g_name+=yytext; 
       
  2240 					  }
       
  2241 					  endFontClass();
       
  2242   					}
       
  2243 <Body>{KEYWORD}/{B}* 			{
       
  2244   					  startFontClass("keyword");
       
  2245   					  codifyLines(yytext);
       
  2246 					  endFontClass();
       
  2247   					}
       
  2248 <Body>{KEYWORD}/{BN}*"(" 		{
       
  2249   					  startFontClass("keyword");
       
  2250   					  codifyLines(yytext);
       
  2251 					  endFontClass();
       
  2252   				          g_name.resize(0);g_type.resize(0);
       
  2253   					}
       
  2254 <FuncCall>"in"/{BN}*			{
       
  2255 					  if (!g_inForEachExpression) REJECT;
       
  2256   					  startFontClass("keywordflow");
       
  2257   					  codifyLines(yytext);
       
  2258 					  endFontClass();
       
  2259 					  // insert the variable in the parent scope, see bug 546158
       
  2260 					  g_theVarContext.popScope();
       
  2261 					  g_theVarContext.addVariable(g_parmType,g_parmName);
       
  2262 					  g_theVarContext.pushScope();
       
  2263   				          g_name.resize(0);g_type.resize(0);
       
  2264 					}
       
  2265 <Body>{FLOWKW}/{BN}*"(" 			{
       
  2266   					  startFontClass("keywordflow");
       
  2267   					  codifyLines(yytext);
       
  2268 					  endFontClass();
       
  2269   				          g_name.resize(0);g_type.resize(0);
       
  2270 					  g_inForEachExpression = (strcmp(yytext,"for each")==0 || strcmp(yytext, "foreach")==0);
       
  2271 					  BEGIN(FuncCall);
       
  2272   					}
       
  2273 <Body>{FLOWKW}/([^a-z_A-Z0-9]) 		{
       
  2274   					  startFontClass("keywordflow");
       
  2275   					  codifyLines(yytext);
       
  2276 					  endFontClass();
       
  2277 					  if (g_inFunctionTryBlock && (strcmp(yytext,"catch")==0 || strcmp(yytext,"finally")==0))
       
  2278 					  {
       
  2279 					    g_inFunctionTryBlock=FALSE;
       
  2280 					  }
       
  2281   					}
       
  2282 <Body>{FLOWKW}/{B}* 			{
       
  2283   					  startFontClass("keywordflow");
       
  2284   					  codifyLines(yytext);
       
  2285 					  endFontClass();
       
  2286   					}
       
  2287 <Body>[\\|\)\+\-\/\%\~\!]		{
       
  2288   					  g_code->codify(yytext);
       
  2289   				          g_name.resize(0);g_type.resize(0);
       
  2290 					  if (*yytext==')')
       
  2291 					  {
       
  2292 					    g_theCallContext.popScope();
       
  2293 					    g_bracketCount--;
       
  2294 					    BEGIN(FuncCall);
       
  2295 					  }
       
  2296   					}
       
  2297 <Body,TemplDecl,ObjCMethod>{TYPEKW}/{B}* {
       
  2298   					  startFontClass("keywordtype");
       
  2299 					  g_code->codify(yytext);
       
  2300 					  endFontClass();
       
  2301 					  addType();
       
  2302   					  g_name+=yytext; 
       
  2303   					}
       
  2304 <Body>"generic"/{B}*"<"[^\n\/\-\.\{\"\>]*">"{B}* {
       
  2305   					  startFontClass("keyword");
       
  2306 					  g_code->codify(yytext);
       
  2307 					  endFontClass();
       
  2308 					  g_sharpCount=0;
       
  2309 					  BEGIN(TemplDecl);
       
  2310 					}
       
  2311 <Body>"template"/{B}*"<"[^\n\/\-\.\{\"\>]*">"{B}* { // template<...>
       
  2312   					  startFontClass("keyword");
       
  2313 					  g_code->codify(yytext);
       
  2314 					  endFontClass();
       
  2315 					  g_sharpCount=0;
       
  2316 					  BEGIN(TemplDecl);
       
  2317                                         }
       
  2318 <TemplDecl>"class"|"typename"		{
       
  2319   					  startFontClass("keyword");
       
  2320   					  codifyLines(yytext);
       
  2321 					  endFontClass();
       
  2322   					}
       
  2323 <TemplDecl>"<"				{
       
  2324                                           g_code->codify(yytext);
       
  2325                                           g_sharpCount++;
       
  2326   					}
       
  2327 <TemplDecl>">"				{
       
  2328                                           g_code->codify(yytext);
       
  2329                                           g_sharpCount--;
       
  2330 					  if (g_sharpCount<=0)
       
  2331 					  {
       
  2332 					    BEGIN(Body);
       
  2333 					  }
       
  2334   					}
       
  2335 <TemplCast>">"				{
       
  2336   					  startFontClass("keyword");
       
  2337   					  codifyLines(yytext);
       
  2338 					  endFontClass();
       
  2339 					  BEGIN( g_lastTemplCastContext );
       
  2340   					}
       
  2341 <TemplCast>{ID}("::"{ID})*		{
       
  2342 					  generateClassOrGlobalLink(*g_code,yytext);
       
  2343 					}
       
  2344 <TemplCast>("const"|"volatile"){B}*	{
       
  2345   					  startFontClass("keyword");
       
  2346   					  codifyLines(yytext);
       
  2347 					  endFontClass();
       
  2348 					}
       
  2349 <TemplCast>[*^]*			{
       
  2350   					  codifyLines(yytext);
       
  2351 					}
       
  2352 <Body,FuncCall>{CASTKW}"<"                { // static_cast<T>(
       
  2353   					  startFontClass("keyword");
       
  2354   					  codifyLines(yytext);
       
  2355 					  endFontClass();
       
  2356                                           g_lastTemplCastContext = YY_START;
       
  2357 					  BEGIN(TemplCast);
       
  2358 					}
       
  2359 <Body,TemplCast>{SCOPENAME}{B}*"<"[^\n\/\-\.\{\"\>]*">"("::"{ID})*/{B}* { // A<T> *pt;
       
  2360 					  int i=QCString(yytext).find('<');
       
  2361 					  QCString kw = QCString(yytext).left(i).stripWhiteSpace();
       
  2362 					  if (kw.right(5)=="_cast" && YY_START==Body)
       
  2363 					  {
       
  2364 					    REJECT;
       
  2365 					  }
       
  2366 					  addType();
       
  2367 					  generateClassOrGlobalLink(*g_code,yytext);
       
  2368   					  g_name+=yytext; 
       
  2369 					}
       
  2370 <Body>{SCOPENAME}/{BN}*[;,)\]]		{ // "int var;" or "var, var2" or "debug(f) macro" 
       
  2371 					  addType();
       
  2372 					  generateClassOrGlobalLink(*g_code,yytext/*,TRUE*/);
       
  2373   					  g_name+=yytext; 
       
  2374 					}
       
  2375 <Body>{SCOPENAME}/{B}* 			{ // p->func()
       
  2376 					  addType();
       
  2377 					  generateClassOrGlobalLink(*g_code,yytext);
       
  2378   					  g_name+=yytext; 
       
  2379 					}
       
  2380 <Body>"("{B}*("*"{B}*)+{SCOPENAME}*{B}*")"/{B}*	{  // (*p)->func() but not "if (p) ..."
       
  2381 					  g_code->codify(yytext);
       
  2382 					  int s=0;while (s<yyleng && !isId(yytext[s])) s++;
       
  2383                                           int e=yyleng-1;while (e>=0 && !isId(yytext[e])) e--;
       
  2384 					  QCString varname = ((QCString)yytext).mid(s,e-s+1); 
       
  2385 					  addType();
       
  2386   					  g_name=varname; 
       
  2387 					}
       
  2388 <Body>{SCOPETNAME}/{BN}*"("		{ // a() or c::a() or t<A,B>::a()
       
  2389   					  addType();
       
  2390 					  generateFunctionLink(*g_code,yytext);
       
  2391 					  //printf("---> g_classScope=%s\n",g_classScope.data());
       
  2392 					  //g_theVarContext.addVariable(g_type,yytext);
       
  2393   					  g_bracketCount=0;
       
  2394 					  g_args.resize(0);
       
  2395   					  g_name+=yytext; 
       
  2396   					  BEGIN( FuncCall );
       
  2397 					}
       
  2398 <FuncCall,Body,MemberCall,MemberCall2,SkipInits>\"	{
       
  2399 					  startFontClass("stringliteral");
       
  2400   					  g_code->codify(yytext);
       
  2401   					  g_lastStringContext=YY_START;
       
  2402 					  g_inForEachExpression = FALSE;
       
  2403   					  BEGIN( SkipString );
       
  2404   					}
       
  2405 <FuncCall,Body,MemberCall,MemberCall2,SkipInits>\'	{
       
  2406 					  startFontClass("stringliteral");
       
  2407   					  g_code->codify(yytext);
       
  2408   					  g_lastStringContext=YY_START;
       
  2409 					  g_inForEachExpression = FALSE;
       
  2410   					  BEGIN( SkipStringS );
       
  2411   					}
       
  2412 <SkipString>[^\"\\\r\n]*		{ 
       
  2413   					  g_code->codify(yytext);
       
  2414 					}
       
  2415 <SkipStringS>[^\'\\\r\n]*		{
       
  2416   					  g_code->codify(yytext);
       
  2417   					}
       
  2418 <SkipString,SkipStringS>"//"|"/*"	{
       
  2419   					  g_code->codify(yytext);
       
  2420   					}
       
  2421 <SkipString>@?\"			{
       
  2422   					  g_code->codify(yytext);
       
  2423 					  endFontClass();
       
  2424   					  BEGIN( g_lastStringContext );
       
  2425   					}
       
  2426 <SkipStringS>\'				{
       
  2427   					  g_code->codify(yytext);
       
  2428 					  endFontClass();
       
  2429   					  BEGIN( g_lastStringContext );
       
  2430   					}
       
  2431 <SkipString,SkipStringS>\\.		{
       
  2432   					  g_code->codify(yytext);
       
  2433 					}
       
  2434 <SkipVerbString>[^"\n]+			{
       
  2435   					  g_code->codify(yytext);
       
  2436 					}
       
  2437 <SkipVerbString>\"\"			{ // escaped quote
       
  2438   					  g_code->codify(yytext);
       
  2439 					}
       
  2440 <SkipVerbString>\"			{ // end of string
       
  2441   					  g_code->codify(yytext);
       
  2442 					  endFontClass();
       
  2443 					  BEGIN( g_lastVerbStringContext );
       
  2444 					}
       
  2445 <SkipVerbString>.			{
       
  2446   					  g_code->codify(yytext);
       
  2447   					}
       
  2448 <SkipVerbString>\n			{
       
  2449   					  codifyLines(yytext);
       
  2450   					}
       
  2451 <Body>":"				{
       
  2452   					  g_code->codify(yytext);
       
  2453   					  g_name.resize(0);g_type.resize(0);
       
  2454   					}
       
  2455 <Body>"<"				{
       
  2456   					  if (g_insideTemplate)
       
  2457 					  {
       
  2458 					    g_sharpCount++;
       
  2459 					  }
       
  2460   					  g_code->codify(yytext);
       
  2461   					}
       
  2462 <Body>">"				{
       
  2463   					  if (g_insideTemplate)
       
  2464 					  {
       
  2465 					    if (--g_sharpCount<=0)
       
  2466 					    {
       
  2467 					      g_insideTemplate=FALSE;
       
  2468 					    }
       
  2469 					  }
       
  2470   					  g_code->codify(yytext);
       
  2471   					}
       
  2472 <Body,MemberCall,MemberCall2,FuncCall>"'"((\\0[Xx0-9]+)|(\\.)|(.))"'"	{
       
  2473   					  startFontClass("charliteral"); 
       
  2474   					  g_code->codify(yytext);
       
  2475 					  endFontClass();
       
  2476   					}
       
  2477 <Body>"."|"->"				{ 
       
  2478   					  g_code->codify(yytext);
       
  2479 					  g_memCallContext = YY_START;
       
  2480   					  BEGIN( MemberCall ); 
       
  2481 					}
       
  2482 <MemberCall>{SCOPETNAME}/{BN}*"(" 	{
       
  2483 					  if (g_theCallContext.getClass())
       
  2484 					  {
       
  2485 					    if (!generateClassMemberLink(*g_code,g_theCallContext.getClass(),yytext))
       
  2486 					    {
       
  2487                                               g_code->linkableSymbol(g_yyLineNr,yytext,0,
       
  2488 	                                                        g_currentMemberDef?g_currentMemberDef:g_currentDefinition);
       
  2489 					      g_code->codify(yytext);
       
  2490 					      addToSearchIndex(yytext);
       
  2491 					    }
       
  2492   					    g_name.resize(0);
       
  2493 					  }
       
  2494 					  else
       
  2495 					  {
       
  2496                                             g_code->linkableSymbol(g_yyLineNr,yytext,0,
       
  2497 	                                                        g_currentMemberDef?g_currentMemberDef:g_currentDefinition);
       
  2498   					    g_code->codify(yytext);
       
  2499 					    addToSearchIndex(yytext);
       
  2500   					    g_name.resize(0);
       
  2501 					  }
       
  2502 					  g_type.resize(0);
       
  2503 					  g_bracketCount=0;
       
  2504 					  if (g_memCallContext==Body)
       
  2505 					  {
       
  2506 					    BEGIN(FuncCall);
       
  2507 					  }
       
  2508 					  else
       
  2509 					  {
       
  2510 					    BEGIN(g_memCallContext);
       
  2511 					  }
       
  2512   					}
       
  2513 <MemberCall>{SCOPENAME}/{B}*		{
       
  2514 					  if (g_theCallContext.getClass())
       
  2515 					  {
       
  2516 					    //fprintf(stderr,"g_theCallContext.getClass()=%p\n",g_theCallContext.getClass());
       
  2517 					    if (!generateClassMemberLink(*g_code,g_theCallContext.getClass(),yytext))
       
  2518 					    {
       
  2519                                               g_code->linkableSymbol(g_yyLineNr,yytext,0,
       
  2520 	                                                        g_currentMemberDef?g_currentMemberDef:g_currentDefinition);
       
  2521 					      g_code->codify(yytext);
       
  2522 					      addToSearchIndex(yytext);
       
  2523 					    }
       
  2524   					    g_name.resize(0);
       
  2525 					  }
       
  2526 					  else
       
  2527 					  {
       
  2528 					    //fprintf(stderr,"no class context!\n");
       
  2529   					    g_code->codify(yytext);
       
  2530 					    addToSearchIndex(yytext);
       
  2531   					    g_name.resize(0);
       
  2532 					  }
       
  2533 					  g_type.resize(0);
       
  2534   					  BEGIN(g_memCallContext);
       
  2535   					}
       
  2536 <Body>[,=;\[]				{
       
  2537 					  if (g_insideObjC && *yytext=='[')
       
  2538 					  {
       
  2539 					    //printf("Found start of ObjC call!\n");
       
  2540 					    // start of a method call
       
  2541 					    g_contextDict.setAutoDelete(TRUE);
       
  2542 					    g_nameDict.setAutoDelete(TRUE);
       
  2543 					    g_objectDict.setAutoDelete(TRUE);
       
  2544 					    g_wordDict.setAutoDelete(TRUE);
       
  2545 					    g_contextDict.clear();
       
  2546 					    g_nameDict.clear();
       
  2547 					    g_objectDict.clear();
       
  2548 					    g_wordDict.clear();
       
  2549 					    g_currentCtxId  = 0;
       
  2550 					    g_currentNameId  = 0;
       
  2551 					    g_currentObjId  = 0;
       
  2552 					    g_currentCtx = 0;
       
  2553 					    g_braceCount = 0;
       
  2554 					    unput('[');
       
  2555 					    BEGIN(ObjCCall);
       
  2556 					  }
       
  2557 					  else
       
  2558 					  {
       
  2559 					    g_code->codify(yytext);
       
  2560 					    g_saveName = g_name.copy();
       
  2561 					    g_saveType = g_type.copy();
       
  2562 					    if (*yytext!='[' && !g_type.isEmpty()) 
       
  2563 					    {
       
  2564 					      //printf("g_scopeStack.bottom()=%p\n",g_scopeStack.bottom());
       
  2565 					      if (g_scopeStack.top()!=CLASSBLOCK)
       
  2566 					      {
       
  2567 						//printf("AddVariable: '%s' '%s' context=%d\n",
       
  2568 						//    g_type.data(),g_name.data(),g_theVarContext.count());
       
  2569 					        g_theVarContext.addVariable(g_type,g_name);
       
  2570 					      }
       
  2571 					      g_name.resize(0);
       
  2572 					    }
       
  2573 					    if (*yytext==';' || *yytext=='=') 
       
  2574 					    {
       
  2575 					      g_type.resize(0);
       
  2576 					      g_name.resize(0);
       
  2577 					    }
       
  2578 					    else if (*yytext=='[')
       
  2579 					    {
       
  2580 					      g_theCallContext.pushScope();
       
  2581 					    }
       
  2582 					    g_args.resize(0);
       
  2583                                             g_parmType.resize(0);
       
  2584                                             g_parmName.resize(0);
       
  2585 					  }
       
  2586   					}
       
  2587   /*
       
  2588 <ObjCMemberCall>{ID}			{
       
  2589   					  if (strcmp(yytext,"self")==0 || strcmp(yytext,"super")==0)
       
  2590 					  {
       
  2591 					    // TODO: get proper base class for "super"
       
  2592 					    g_theCallContext.setClass(getClass(g_curClassName));
       
  2593 					    startFontClass("keyword");
       
  2594 					    g_code->codify(yytext); 
       
  2595 					    endFontClass();
       
  2596 					  }
       
  2597 					  else
       
  2598 					  {
       
  2599 					    generateClassOrGlobalLink(*g_code,yytext);
       
  2600 					  }
       
  2601 					  g_name.resize(0);
       
  2602 					  BEGIN(ObjCMemberCall2);
       
  2603   					}
       
  2604 <ObjCMemberCall>"["			{
       
  2605 					    g_code->codify(yytext);
       
  2606 					    g_theCallContext.pushScope();
       
  2607   					}
       
  2608 <ObjCMemberCall2>{ID}":"?		{
       
  2609   					  g_name+=yytext;
       
  2610 					  if (g_theCallContext.getClass())
       
  2611 					  {
       
  2612 					    //printf("Calling method %s\n",g_name.data());
       
  2613 					    if (!generateClassMemberLink(*g_code,g_theCallContext.getClass(),g_name))
       
  2614 					    {
       
  2615   					      g_code->codify(yytext);
       
  2616 					      addToSearchIndex(g_name);
       
  2617 					    }
       
  2618 					  }
       
  2619 					  else
       
  2620 					  {
       
  2621   					    g_code->codify(yytext);
       
  2622 					    addToSearchIndex(g_name);
       
  2623 					  }
       
  2624   					  g_name.resize(0);
       
  2625 					  BEGIN(ObjCMemberCall3);
       
  2626   					}
       
  2627 <ObjCMemberCall2,ObjCMemberCall3>"]"	{
       
  2628 					  g_theCallContext.popScope();
       
  2629   					  g_code->codify(yytext);
       
  2630 					  BEGIN(Body);
       
  2631   					}
       
  2632   */
       
  2633 <ObjCCall,ObjCMName>"["         { 
       
  2634                                    saveObjCContext();
       
  2635 			           g_currentCtx->format+=*yytext;
       
  2636 			           BEGIN(ObjCCall);
       
  2637 		                   //printf("open\n");
       
  2638                                  }
       
  2639 <ObjCCall,ObjCMName>"]"         { 
       
  2640 			            g_currentCtx->format+=*yytext;
       
  2641                                     restoreObjCContext();
       
  2642 			            BEGIN(ObjCMName);
       
  2643 		             	    if (g_currentCtx==0)
       
  2644 				    {
       
  2645 				      // end of call
       
  2646 				      writeObjCMethodCall(g_contextDict.find(0));
       
  2647 				      BEGIN(Body);
       
  2648 				    }
       
  2649 			            //printf("close\n");
       
  2650                                   }
       
  2651 <ObjCCall>{ID}	                  {
       
  2652                                     g_currentCtx->format+=escapeObject(yytext);
       
  2653 			            if (g_braceCount==0)
       
  2654 			            {
       
  2655 			              g_currentCtx->objectTypeOrName=yytext;
       
  2656                                       //printf("new type=%s\n",g_currentCtx->objectTypeOrName.data());
       
  2657 			              BEGIN(ObjCMName);
       
  2658 			            }
       
  2659   		                  }
       
  2660 <ObjCMName>{ID}/{BN}*"]"          { 
       
  2661                                     if (g_braceCount==0 && 
       
  2662 					g_currentCtx->methodName.isEmpty())
       
  2663                                     {
       
  2664 			              g_currentCtx->methodName=yytext; 
       
  2665                                       g_currentCtx->format+=escapeName(yytext);
       
  2666 			            }
       
  2667 				    else
       
  2668 				    {
       
  2669                                       g_currentCtx->format+=escapeWord(yytext);
       
  2670 				    }
       
  2671                                   }
       
  2672 <ObjCMName>{ID}/{BN}*":"           { 
       
  2673                                      if (g_braceCount==0)
       
  2674                                      {
       
  2675 			               g_currentCtx->methodName+=yytext;
       
  2676                                        g_currentCtx->methodName+=":";
       
  2677 			             }
       
  2678                                      g_currentCtx->format+=escapeName(yytext);
       
  2679                                    }
       
  2680 <ObjCSkipStr>[^\n\"$\\]*           { g_currentCtx->format+=yytext; }
       
  2681 <ObjCSkipStr>\\.	           { g_currentCtx->format+=yytext; }
       
  2682 <ObjCSkipStr>"\""	           { g_currentCtx->format+=yytext; 
       
  2683                                       BEGIN(g_lastStringContext); 
       
  2684                                    }
       
  2685 <ObjCCall,ObjCMName>{CHARLIT}      { g_currentCtx->format+=yytext; }
       
  2686 <ObjCCall,ObjCMName>"@"?"\""       { g_currentCtx->format+=yytext; 
       
  2687                                       g_lastStringContext=YY_START;
       
  2688                                       BEGIN(ObjCSkipStr); 
       
  2689                                    }
       
  2690 <ObjCCall,ObjCMName,ObjCSkipStr>"$" { g_currentCtx->format+="$$"; }
       
  2691 <ObjCCall,ObjCMName>"("            { g_currentCtx->format+=*yytext; g_braceCount++; }
       
  2692 <ObjCCall,ObjCMName>")"            { g_currentCtx->format+=*yytext; g_braceCount--; }
       
  2693 <ObjCSkipStr>"@"/"\""		   { // needed to prevent matching the global rule (for C#)
       
  2694                                      g_currentCtx->format+=yytext;
       
  2695                                    }
       
  2696 <ObjCCall,ObjCMName,ObjCSkipStr>{ID} { g_currentCtx->format+=escapeWord(yytext); }
       
  2697 <ObjCCall,ObjCMName,ObjCSkipStr>.  { g_currentCtx->format+=*yytext; }
       
  2698 <ObjCCall,ObjCMName,ObjCSkipStr>\n { g_currentCtx->format+=*yytext; }
       
  2699 
       
  2700 <Body>"]"				{
       
  2701 					  g_theCallContext.popScope();
       
  2702   					  g_code->codify(yytext);
       
  2703 					  // TODO: nested arrays like: a[b[0]->func()]->func()
       
  2704 					  g_name = g_saveName.copy();
       
  2705 					  g_type = g_saveType.copy();
       
  2706 					}
       
  2707 <Body>[0-9]+				{
       
  2708 					  g_code->codify(yytext);
       
  2709 					}
       
  2710 <Body>[0-9]+[xX][0-9A-Fa-f]+		{
       
  2711 					  g_code->codify(yytext);
       
  2712 					}
       
  2713 <MemberCall2,FuncCall>{KEYWORD}/([^a-z_A-Z0-9]) {
       
  2714 					  //addParmType();
       
  2715 					  //g_parmName=yytext; 
       
  2716   					  startFontClass("keyword");
       
  2717   					  g_code->codify(yytext);
       
  2718 					  endFontClass();
       
  2719 					}
       
  2720 <MemberCall2,FuncCall,OldStyleArgs,TemplCast>{TYPEKW}/([^a-z_A-Z0-9]) {
       
  2721 					  addParmType();
       
  2722 					  g_parmName=yytext; 
       
  2723   					  startFontClass("keywordtype");
       
  2724   					  g_code->codify(yytext);
       
  2725 					  endFontClass();
       
  2726 					}
       
  2727 <MemberCall2,FuncCall>{FLOWKW}/([^a-z_A-Z0-9]) {
       
  2728 					  addParmType();
       
  2729 					  g_parmName=yytext; 
       
  2730   					  startFontClass("keywordflow");
       
  2731   					  g_code->codify(yytext);
       
  2732 					  endFontClass();
       
  2733 					}
       
  2734 <MemberCall2,FuncCall>{ID}(({B}*"<"[^\n\[\](){}<>]*">")?({B}*"::"{B}*{ID})?)* {
       
  2735 					  addParmType();
       
  2736 					  g_parmName=yytext; 
       
  2737 					  generateClassOrGlobalLink(*g_code,yytext,!g_insideBody);
       
  2738 					}
       
  2739 <FuncCall>";"				{ // probably a cast, not a function call
       
  2740   					  g_code->codify(yytext);
       
  2741 					  g_inForEachExpression = FALSE;
       
  2742 					  BEGIN( Body );
       
  2743   					}
       
  2744 <MemberCall2,FuncCall>,			{
       
  2745   					  g_code->codify(yytext);
       
  2746 					  g_theVarContext.addVariable(g_parmType,g_parmName);
       
  2747 					  g_parmType.resize(0);g_parmName.resize(0);
       
  2748 					}
       
  2749 <MemberCall2,FuncCall>"("		{
       
  2750 					  g_parmType.resize(0);g_parmName.resize(0);
       
  2751   					  g_code->codify(yytext);
       
  2752   					  g_bracketCount++; 
       
  2753 					  g_theCallContext.pushScope();
       
  2754 					  if (YY_START==FuncCall && !g_insideBody)
       
  2755 					  {
       
  2756 					    g_theVarContext.pushScope();
       
  2757 					  }
       
  2758 					}
       
  2759 <MemberCall2,FuncCall>{OPERATOR}        { // operator
       
  2760   					  if (strcmp(yytext,"*") && 
       
  2761 					      strcmp(yytext,"&") &&
       
  2762 					      strcmp(yytext,"^") &&
       
  2763 					      strcmp(yytext,"%")) // typically a pointer or reference
       
  2764 					  {
       
  2765 					    // not a * or &, or C++/CLI's ^ or %
       
  2766 					    g_parmType.resize(0);g_parmName.resize(0);
       
  2767 					  }
       
  2768   					  g_code->codify(yytext);
       
  2769   					}
       
  2770 <MemberCall,MemberCall2,FuncCall>")"	{ 
       
  2771 					  g_theVarContext.addVariable(g_parmType,g_parmName);
       
  2772 					  g_theCallContext.popScope();
       
  2773 					  g_inForEachExpression = FALSE;
       
  2774 					  //g_theCallContext.setClass(0); // commented out, otherwise a()->b() does not work for b().
       
  2775   					  g_code->codify(yytext);
       
  2776   					  if (--g_bracketCount<=0) 
       
  2777 					  {
       
  2778 					    if (g_name.isEmpty())
       
  2779 					    {
       
  2780 					      BEGIN( Body );
       
  2781 					    }
       
  2782 					    else
       
  2783 					    {
       
  2784 					      BEGIN( CallEnd ); 
       
  2785 					    }
       
  2786 					  }
       
  2787 					}
       
  2788 <CallEnd>[ \t\n]*			{ codifyLines(yytext); }
       
  2789   /*
       
  2790 <MemberCall2,FuncCall>")"[ \t\n]*[;:]	{
       
  2791   */
       
  2792 <CallEnd>[;:]				{
       
  2793   					  codifyLines(yytext);
       
  2794   					  g_bracketCount=0;
       
  2795 					  if (*yytext==';') g_searchingForBody=FALSE; 
       
  2796 					  if (!g_type.isEmpty())
       
  2797 					  {
       
  2798 					    //fprintf(stderr,"add variable g_type=%s g_name=%s)\n",g_type.data(),g_name.data());
       
  2799 					    g_theVarContext.addVariable(g_type,g_name);
       
  2800 					  }
       
  2801 					  g_parmType.resize(0);g_parmName.resize(0);
       
  2802 					  g_theCallContext.setClass(0);
       
  2803   					  if (*yytext==';' || g_insideBody)
       
  2804 					  {
       
  2805 					    if (!g_insideBody)
       
  2806 					    {
       
  2807                                               g_theVarContext.popScope();
       
  2808 					    }
       
  2809 					    g_name.resize(0);g_type.resize(0);
       
  2810 					    BEGIN( Body );
       
  2811 					  }
       
  2812 					  else
       
  2813 					  {
       
  2814 					    g_bracketCount=0;
       
  2815 					    BEGIN( SkipInits );
       
  2816 					  }
       
  2817   					}
       
  2818 <CallEnd>("const"|"volatile"|"sealed"|"override")({BN}+("const"|"volatile"|"sealed"|"override"))*/{BN}*(";"|"="|"throw"{BN}*"(") {
       
  2819 					  startFontClass("keyword");
       
  2820   					  codifyLines(yytext);
       
  2821 					  endFontClass();
       
  2822   					}
       
  2823 <CallEnd,OldStyleArgs>("const"|"volatile"|"sealed"|"override")*({BN}+("const"|"volatile"|"sealed"|"override"))*{BN}*"{" {
       
  2824                                           if (g_insideBody)
       
  2825 					  {
       
  2826 					    g_theVarContext.pushScope();
       
  2827 					  }
       
  2828 					  g_theVarContext.addVariable(g_parmType,g_parmName);
       
  2829 					  //g_theCallContext.popScope();
       
  2830 					  g_parmType.resize(0);g_parmName.resize(0);
       
  2831 					  int index = g_name.findRev("::");
       
  2832 					  if (index!=-1) 
       
  2833 					  {
       
  2834 					    QCString scope = g_name.left(index);
       
  2835 					    if (!g_classScope.isEmpty()) scope.prepend(g_classScope+"::");
       
  2836 					    ClassDef *cd=getResolvedClass(Doxygen::globalScope,g_sourceFileDef,scope);
       
  2837 					    if (cd)
       
  2838 					    {
       
  2839 					      setClassScope(cd->name());
       
  2840 					    }
       
  2841 					    else
       
  2842 					    {
       
  2843 					      setClassScope(g_realScope);
       
  2844 					    }
       
  2845                                             DBG_CTX((stderr,"** scope stack push SCOPEBLOCK\n"));
       
  2846   					    g_scopeStack.push(SCOPEBLOCK);
       
  2847 					  }
       
  2848 					  else
       
  2849 					  {
       
  2850                                             DBG_CTX((stderr,"** scope stack push INNERBLOCK\n"));
       
  2851   					    g_scopeStack.push(INNERBLOCK);
       
  2852 					  }
       
  2853 					  yytext[yyleng-1]='\0';
       
  2854 					  QCString cv(yytext);
       
  2855 					  if (!cv.stripWhiteSpace().isEmpty())
       
  2856 					  {
       
  2857 					    startFontClass("keyword");
       
  2858   					    codifyLines(yytext);
       
  2859 					    endFontClass();
       
  2860 					  }
       
  2861 					  else // just whitespace
       
  2862 					  {
       
  2863   					    codifyLines(yytext);
       
  2864 					  }
       
  2865 					  g_code->codify("{");
       
  2866   					  if (g_searchingForBody)
       
  2867 					  {
       
  2868 					    g_searchingForBody=FALSE;
       
  2869 					    g_insideBody=TRUE;
       
  2870 					  }
       
  2871 					  if (g_insideBody) g_bodyCurlyCount++;
       
  2872 					  g_curlyCount++;
       
  2873   					  g_type.resize(0); g_name.resize(0);
       
  2874 					  BEGIN( Body );
       
  2875   					}
       
  2876 <CallEnd>"try"				{ // function-try-block
       
  2877 					  startFontClass("keyword");
       
  2878   					  g_code->codify(yytext);
       
  2879 					  endFontClass();
       
  2880 					  g_inFunctionTryBlock=TRUE;
       
  2881                                         }
       
  2882 <CallEnd>{ID}				{
       
  2883   					  if (g_insideBody || !g_parmType.isEmpty()) 
       
  2884 					  {
       
  2885 					    REJECT;
       
  2886 					  }
       
  2887 					  // could be K&R style definition
       
  2888 					  addParmType();
       
  2889 					  g_parmName=yytext; 
       
  2890 					  generateClassOrGlobalLink(*g_code,yytext,!g_insideBody);
       
  2891 					  BEGIN(OldStyleArgs);
       
  2892   					}
       
  2893 <OldStyleArgs>{ID}			{
       
  2894 					  addParmType();
       
  2895 					  g_parmName=yytext; 
       
  2896 					  generateClassOrGlobalLink(*g_code,yytext,!g_insideBody);
       
  2897   					}
       
  2898 <OldStyleArgs>[,;]			{
       
  2899   					  g_code->codify(yytext);
       
  2900 					  g_theVarContext.addVariable(g_parmType,g_parmName);
       
  2901 					  if (*yytext==';') g_parmType.resize(0);
       
  2902 					  g_parmName.resize(0);
       
  2903   					}
       
  2904 <CallEnd,OldStyleArgs>"#"		{
       
  2905   					  startFontClass("preprocessor");
       
  2906 					  g_lastSkipCppContext = Body;
       
  2907   					  g_code->codify(yytext);
       
  2908 					  BEGIN( SkipCPP );
       
  2909   					}
       
  2910 <CallEnd>.				{
       
  2911   					  unput(*yytext);
       
  2912                                           if (!g_insideBody) 
       
  2913 					  {
       
  2914 					    g_theVarContext.popScope();
       
  2915 					  }
       
  2916 					  g_name.resize(0);g_args.resize(0);
       
  2917 					  g_parmType.resize(0);g_parmName.resize(0);
       
  2918 					  BEGIN( Body ); 
       
  2919   					}
       
  2920 <SkipInits>";"				{
       
  2921   					  g_code->codify(yytext);
       
  2922   					  g_type.resize(0); g_name.resize(0);
       
  2923   					  BEGIN( Body );
       
  2924   					}
       
  2925 <SkipInits>"{"				{ 
       
  2926   					  g_code->codify(yytext);
       
  2927 					  g_curlyCount++; 
       
  2928   					  if (g_searchingForBody)
       
  2929 					  {
       
  2930 					    g_searchingForBody=FALSE;
       
  2931 					    g_insideBody=TRUE;
       
  2932 					  }
       
  2933 					  if (g_insideBody) g_bodyCurlyCount++;
       
  2934 					  if (g_name.find("::")!=-1) 
       
  2935 					  {
       
  2936                                             DBG_CTX((stderr,"** scope stack push SCOPEBLOCK\n"));
       
  2937   					    g_scopeStack.push(SCOPEBLOCK);
       
  2938 					    setClassScope(g_realScope);
       
  2939 					  }
       
  2940 					  else
       
  2941 					  {
       
  2942                                             DBG_CTX((stderr,"** scope stack push INNERBLOCK\n"));
       
  2943   					    g_scopeStack.push(INNERBLOCK);
       
  2944 					  }
       
  2945   					  g_type.resize(0); g_name.resize(0);
       
  2946 					  BEGIN( Body ); 
       
  2947 					}
       
  2948 <SkipInits>{ID}				{
       
  2949 					  generateClassOrGlobalLink(*g_code,yytext);
       
  2950   					}
       
  2951 <FuncCall>{ID}/"("			{
       
  2952 					  generateFunctionLink(*g_code,yytext);
       
  2953 					}
       
  2954 <FuncCall>{ID}/("."|"->")               { 
       
  2955 					  g_name=yytext; 
       
  2956 					  generateClassOrGlobalLink(*g_code,yytext);
       
  2957 					  BEGIN( MemberCall2 ); 
       
  2958 					}
       
  2959 <FuncCall,MemberCall2>("("{B}*("*"{B}*)+{ID}*{B}*")"{B}*)/("."|"->") { 
       
  2960   					  g_code->codify(yytext);
       
  2961 					  int s=0;while (!isId(yytext[s])) s++;
       
  2962                                           int e=yyleng-1;while (!isId(yytext[e])) e--;
       
  2963 					  g_name=((QCString)yytext).mid(s,e-s+1); 
       
  2964 					  BEGIN( MemberCall2 ); 
       
  2965 					}
       
  2966 <MemberCall2>{ID}/([ \t\n]*"(")         { 
       
  2967   					  if (!g_args.isEmpty())
       
  2968 					    generateMemberLink(*g_code,g_args,yytext);
       
  2969 					  else
       
  2970 					    generateClassOrGlobalLink(*g_code,yytext);
       
  2971 					  g_args.resize(0);
       
  2972 					  BEGIN( FuncCall );
       
  2973 					}
       
  2974 <MemberCall2>{ID}/([ \t\n]*("."|"->"))  {
       
  2975   					  //g_code->codify(yytext);
       
  2976 					  g_name=yytext; 
       
  2977 					  generateClassOrGlobalLink(*g_code,yytext);
       
  2978 					  BEGIN( MemberCall2 ); 
       
  2979     					}
       
  2980 <MemberCall2>"->"|"."			{
       
  2981   					  g_code->codify(yytext);
       
  2982 					  g_memCallContext = YY_START;
       
  2983   					  BEGIN( MemberCall ); 
       
  2984   					}
       
  2985 <SkipComment>"/*"("!"?)"*/"		{ 
       
  2986   					  g_code->codify(yytext);
       
  2987 					  endFontClass();
       
  2988   					  BEGIN( g_lastCContext ) ; 
       
  2989 					}
       
  2990 <SkipComment>"//"|"/*"			{
       
  2991   					  g_code->codify(yytext);
       
  2992   					}
       
  2993 <SkipComment>[^*/\n]+			{
       
  2994   					  g_code->codify(yytext);
       
  2995   					}
       
  2996 <SkipComment>[ \t]*"*/"			{ 
       
  2997   					  g_code->codify(yytext);
       
  2998 					  endFontClass();
       
  2999   					  BEGIN( g_lastCContext ) ; 
       
  3000 					}
       
  3001 <SkipCxxComment>[^\r\n]*"\\"[\r]?\n	{ // line continuation
       
  3002   					  codifyLines(yytext);
       
  3003 					}
       
  3004 <SkipCxxComment>[^\r\n]+		{ 
       
  3005   					  g_code->codify(yytext);
       
  3006 					}
       
  3007 <SkipCxxComment>\r			
       
  3008 <SkipCxxComment>\n			{
       
  3009   					  unput('\n');
       
  3010 					  endFontClass();
       
  3011 					  BEGIN( g_lastCContext ) ;
       
  3012   					}
       
  3013 <SkipCxxComment>.			{
       
  3014   					  g_code->codify(yytext);
       
  3015   					}
       
  3016 <RemoveSpecialCComment>"*/"{B}*\n({B}*\n)*({B}*(("//@"[{}])|("/*@"[{}]"*/")){B}*\n)?{B}*"/*"[*!]/[^/*] {
       
  3017   					  g_yyLineNr+=QCString(yytext).contains('\n');
       
  3018 					}
       
  3019 <RemoveSpecialCComment>"*/"{B}*\n({B}*\n)*({B}*(("//@"[{}])|("/*@"[{}]"*/")){B}*\n)? {
       
  3020   					  g_yyLineNr+=QCString(yytext).contains('\n');
       
  3021 					  nextCodeLine();
       
  3022 					  if (g_lastSpecialCContext==SkipCxxComment)
       
  3023 					  { // force end of C++ comment here
       
  3024 					    endFontClass();
       
  3025 					    BEGIN( g_lastCContext ) ;
       
  3026 					  }
       
  3027 					  else
       
  3028 					  {
       
  3029   					    BEGIN(g_lastSpecialCContext);
       
  3030 					  }
       
  3031   					}
       
  3032 <RemoveSpecialCComment>"*/"		{
       
  3033   					  BEGIN(g_lastSpecialCContext);
       
  3034   					}
       
  3035 <RemoveSpecialCComment>[^*\n]+
       
  3036 <RemoveSpecialCComment>"//"|"/*"
       
  3037 <RemoveSpecialCComment>\n  { g_yyLineNr++; }
       
  3038 <RemoveSpecialCComment>.
       
  3039 <MemberCall>[^a-z_A-Z0-9(\n]		{ 
       
  3040   					  g_code->codify(yytext);
       
  3041     					  g_type.resize(0);
       
  3042 					  g_name.resize(0);
       
  3043 					  BEGIN(g_memCallContext); 
       
  3044 					}
       
  3045 <*>\n({B}*"//"[!/][^\n]*\n)+		{ // remove special one-line comment
       
  3046   					  if (Config_getBool("STRIP_CODE_COMMENTS"))
       
  3047 					  {
       
  3048 					    g_yyLineNr+=((QCString)yytext).contains('\n');
       
  3049 					    nextCodeLine();
       
  3050 					  }
       
  3051 					  else
       
  3052 					  {
       
  3053 					    startFontClass("comment");
       
  3054 					    codifyLines(yytext);
       
  3055 					    endFontClass();
       
  3056 					  }
       
  3057 					  if (YY_START==SkipCxxComment)
       
  3058 					  {
       
  3059 					    endFontClass();
       
  3060 					    BEGIN( g_lastCContext ) ;
       
  3061 					  }
       
  3062   					}
       
  3063 <SkipCPP>\n/.*\n			{ 
       
  3064   					  codifyLines(yytext);
       
  3065 					  endFontClass();
       
  3066 					  BEGIN( g_lastSkipCppContext ) ;
       
  3067 					}
       
  3068 <*>\n{B}*"//@"[{}].*\n			{ // remove one-line group marker
       
  3069   					  if (Config_getBool("STRIP_CODE_COMMENTS"))
       
  3070 					  {
       
  3071 					    g_yyLineNr+=2;
       
  3072 					    nextCodeLine();
       
  3073 					  }
       
  3074 					  else
       
  3075 					  {
       
  3076 					    startFontClass("comment");
       
  3077 					    codifyLines(yytext);
       
  3078 					    endFontClass();
       
  3079 					  }
       
  3080 					  if (YY_START==SkipCxxComment)
       
  3081 					  {
       
  3082 					    endFontClass();
       
  3083 					    BEGIN( g_lastCContext ) ;
       
  3084 					  }
       
  3085   					}
       
  3086 <*>\n{B}*"/*@"[{}]			{ // remove one-line group marker
       
  3087 					  if (Config_getBool("STRIP_CODE_COMMENTS"))
       
  3088   					  {
       
  3089 					    g_lastSpecialCContext = YY_START;
       
  3090 					    g_yyLineNr++;
       
  3091 					    BEGIN(RemoveSpecialCComment);
       
  3092 					  }
       
  3093 					  else
       
  3094 					  {
       
  3095 					    // check is to prevent getting stuck in skipping C++ comments
       
  3096 					    if (YY_START != SkipCxxComment)
       
  3097 					    {
       
  3098   					      g_lastCContext = YY_START ;
       
  3099 					    }
       
  3100 					    startFontClass("comment");
       
  3101 					    codifyLines(yytext);
       
  3102 					    BEGIN(SkipComment);
       
  3103   					  }
       
  3104   					}
       
  3105 <*>^{B}*"//@"[{}].*\n			{ // remove one-line group marker
       
  3106   					  if (Config_getBool("STRIP_CODE_COMMENTS"))
       
  3107 					  {
       
  3108 					    g_yyLineNr++;
       
  3109 					    nextCodeLine();
       
  3110 					  }
       
  3111 					  else
       
  3112 					  {
       
  3113 					    startFontClass("comment");
       
  3114 					    codifyLines(yytext);
       
  3115 					    endFontClass();
       
  3116 					  }
       
  3117   					}
       
  3118 <*>^{B}*"/*@"[{}]			{ // remove multi-line group marker
       
  3119 					  if (Config_getBool("STRIP_CODE_COMMENTS"))
       
  3120 					  {
       
  3121 					    g_lastSpecialCContext = YY_START;
       
  3122 					    BEGIN(RemoveSpecialCComment);
       
  3123 					  }
       
  3124 					  else
       
  3125 					  {
       
  3126 					    // check is to prevent getting stuck in skipping C++ comments
       
  3127 					    if (YY_START != SkipCxxComment)
       
  3128 					    {
       
  3129   					      g_lastCContext = YY_START ;
       
  3130 					    }
       
  3131 					    startFontClass("comment");
       
  3132 					    g_code->codify(yytext);
       
  3133 					    BEGIN(SkipComment);
       
  3134  					  }
       
  3135   					}
       
  3136 <*>^{B}*"//"[!/][^\n]*\n		{ // remove special one-line comment
       
  3137   					  if (Config_getBool("STRIP_CODE_COMMENTS"))
       
  3138 					  {
       
  3139 					    g_yyLineNr++;
       
  3140 					    nextCodeLine();
       
  3141 					  }
       
  3142 					  else
       
  3143 					  {
       
  3144 					    startFontClass("comment");
       
  3145 					    codifyLines(yytext);
       
  3146 					    endFontClass();
       
  3147 					  }
       
  3148   					}
       
  3149 <*>"//"[!/][^\n]*\n			{ // strip special one-line comment
       
  3150                                           if (YY_START==SkipComment || YY_START==SkipString) REJECT;
       
  3151   					  if (Config_getBool("STRIP_CODE_COMMENTS"))
       
  3152 					  {
       
  3153 					    char c[2]; c[0]='\n'; c[1]=0;
       
  3154 					    codifyLines(c);
       
  3155 					  }
       
  3156 					  else
       
  3157 					  {
       
  3158 					    startFontClass("comment");
       
  3159 					    codifyLines(yytext);
       
  3160 					    endFontClass();
       
  3161 					  }
       
  3162   					}
       
  3163 <*>\n{B}*"/*"[!*]/[^/*] 		{
       
  3164 					  if (Config_getBool("STRIP_CODE_COMMENTS"))
       
  3165   					  {
       
  3166 					    g_lastSpecialCContext = YY_START;
       
  3167 					    g_yyLineNr++;
       
  3168 					    BEGIN(RemoveSpecialCComment);
       
  3169 					  }
       
  3170 					  else
       
  3171 					  {
       
  3172 					    // check is to prevent getting stuck in skipping C++ comments
       
  3173 					    if (YY_START != SkipCxxComment)
       
  3174 					    {
       
  3175   					      g_lastCContext = YY_START ;
       
  3176 					    }
       
  3177 					    startFontClass("comment");
       
  3178 					    codifyLines(yytext);
       
  3179 					    BEGIN(SkipComment);
       
  3180   					  }
       
  3181 					}
       
  3182 <*>^{B}*"/*"[!*]/[^/*]			{ // special C comment block at a new line
       
  3183 					  if (Config_getBool("STRIP_CODE_COMMENTS"))
       
  3184 					  {
       
  3185 					    g_lastSpecialCContext = YY_START;
       
  3186 					    BEGIN(RemoveSpecialCComment);
       
  3187 					  }
       
  3188 					  else
       
  3189 					  {
       
  3190 					    // check is to prevent getting stuck in skipping C++ comments
       
  3191 					    if (YY_START != SkipCxxComment)
       
  3192 					    {
       
  3193   					      g_lastCContext = YY_START ;
       
  3194 					    }
       
  3195 					    startFontClass("comment");
       
  3196 					    g_code->codify(yytext);
       
  3197 					    BEGIN(SkipComment);
       
  3198  					  }
       
  3199 					}
       
  3200 <*>"/*"[!*]/[^/*]			{ // special C comment block half way a line
       
  3201                                           if (YY_START==SkipString) REJECT;
       
  3202 					  if (Config_getBool("STRIP_CODE_COMMENTS"))
       
  3203 					  {
       
  3204 					    g_lastSpecialCContext = YY_START;
       
  3205 					    BEGIN(RemoveSpecialCComment);
       
  3206 					  }
       
  3207 					  else
       
  3208 					  {
       
  3209 					    // check is to prevent getting stuck in skipping C++ comments
       
  3210 					    if (YY_START != SkipCxxComment)
       
  3211 					    {
       
  3212   					      g_lastCContext = YY_START ;
       
  3213 					    }
       
  3214 					    startFontClass("comment");
       
  3215 					    g_code->codify(yytext);
       
  3216 					    BEGIN(SkipComment);
       
  3217 					  }
       
  3218 					}
       
  3219 <*>"/*"("!"?)"*/"			{ 
       
  3220                                           if (YY_START==SkipString) REJECT;
       
  3221                                           if (!Config_getBool("STRIP_CODE_COMMENTS"))
       
  3222   					  {
       
  3223 					    startFontClass("comment");
       
  3224 					    g_code->codify(yytext);
       
  3225 					    endFontClass();
       
  3226 					  }
       
  3227 					}
       
  3228 <*>"/*"					{ 
       
  3229 					  startFontClass("comment");
       
  3230   					  g_code->codify(yytext);
       
  3231 					  // check is to prevent getting stuck in skipping C++ comments
       
  3232 					  if (YY_START != SkipCxxComment)
       
  3233 					  {
       
  3234   					    g_lastCContext = YY_START ;
       
  3235 					  }
       
  3236 					  BEGIN( SkipComment ) ;
       
  3237 					}
       
  3238 <*>@\"					{ // C# verbatim string
       
  3239 					  startFontClass("stringliteral");
       
  3240   					  g_code->codify(yytext);
       
  3241 					  g_lastVerbStringContext=YY_START;
       
  3242 					  BEGIN(SkipVerbString);
       
  3243 					}
       
  3244 <*>"//"					{ 
       
  3245   					  startFontClass("comment");
       
  3246   					  g_code->codify(yytext);
       
  3247   					  g_lastCContext = YY_START ;
       
  3248 					  BEGIN( SkipCxxComment ) ;
       
  3249 					}
       
  3250 <*>"("|"["					{
       
  3251   					  g_code->codify(yytext);
       
  3252 					  g_theCallContext.pushScope();
       
  3253   					}
       
  3254 <*>")"|"]"					{
       
  3255   					  g_code->codify(yytext);
       
  3256 					  g_theCallContext.popScope();
       
  3257   					}
       
  3258 <*>\n					{
       
  3259   					  codifyLines(yytext); 
       
  3260   					}
       
  3261 <*>.					{
       
  3262   					  g_code->codify(yytext);
       
  3263 					}
       
  3264   /*
       
  3265 <*>([ \t\n]*"\n"){2,}			{ // combine multiple blank lines
       
  3266   					  //QCString sepLine=yytext;
       
  3267   					  //g_code->codify("\n\n");
       
  3268   					  //g_yyLineNr+=sepLine.contains('\n'); 
       
  3269   					  //char sepLine[3]="\n\n";
       
  3270   					  codifyLines(yytext);
       
  3271 					}
       
  3272   */
       
  3273 
       
  3274 %%
       
  3275 
       
  3276 /*@ ----------------------------------------------------------------------------
       
  3277  */
       
  3278 
       
  3279 static void saveObjCContext()
       
  3280 {
       
  3281   if (g_currentCtx)
       
  3282   {
       
  3283     g_currentCtx->format+=QCString().sprintf("$c%d",g_currentCtxId);
       
  3284     if (g_braceCount==0 && YY_START==ObjCCall)
       
  3285     {
       
  3286       g_currentCtx->objectTypeOrName=g_currentCtx->format.mid(1);
       
  3287       //printf("new type=%s\n",g_currentCtx->objectTypeOrName.data());
       
  3288     }
       
  3289     g_contextStack.push(g_currentCtx);
       
  3290   }
       
  3291   else
       
  3292   {
       
  3293     //printf("Trying to save NULL context!\n");
       
  3294   }
       
  3295   ObjCCallCtx *newCtx = new ObjCCallCtx;
       
  3296   newCtx->id = g_currentCtxId;
       
  3297   newCtx->lexState = YY_START;
       
  3298   newCtx->braceCount = g_braceCount;
       
  3299   newCtx->objectType = 0;
       
  3300   newCtx->objectVar = 0;
       
  3301   newCtx->method = 0;
       
  3302   //printf("save state=%d\n",YY_START);
       
  3303   g_contextDict.insert(g_currentCtxId,newCtx);
       
  3304   g_currentCtx = newCtx;
       
  3305   g_braceCount = 0;
       
  3306   g_currentCtxId++;
       
  3307 }
       
  3308 
       
  3309 static void restoreObjCContext()
       
  3310 {
       
  3311   //printf("restore state=%d->%d\n",YY_START,g_currentCtx->lexState);
       
  3312   BEGIN(g_currentCtx->lexState);
       
  3313   g_braceCount = g_currentCtx->braceCount;
       
  3314   if (!g_contextStack.isEmpty())
       
  3315   {
       
  3316     g_currentCtx = g_contextStack.pop();
       
  3317   }
       
  3318   else
       
  3319   {
       
  3320     g_currentCtx = 0;
       
  3321     //printf("Trying to pop context while g_contextStack is empty!\n");
       
  3322   }
       
  3323 }
       
  3324 
       
  3325 void resetCCodeParserState()
       
  3326 {
       
  3327   //printf("***initParseCodeContext()\n");
       
  3328   g_theVarContext.clear();
       
  3329   g_classScopeLengthStack.setAutoDelete(TRUE);
       
  3330   g_classScopeLengthStack.clear();
       
  3331   delete g_codeClassSDict;
       
  3332   g_codeClassSDict = new ClassSDict(17);
       
  3333   g_codeClassSDict->setAutoDelete(TRUE);
       
  3334   g_codeClassSDict->clear();
       
  3335   g_curClassBases.clear();
       
  3336   g_anchorCount = 0;
       
  3337 }
       
  3338 
       
  3339 void parseCCode(CodeOutputInterface &od,const char *className,const QCString &s, 
       
  3340                   bool exBlock, const char *exName,FileDef *fd,
       
  3341 		  int startLine,int endLine,bool inlineFragment,
       
  3342 		  MemberDef *memberDef)
       
  3343 {
       
  3344   //printf("***parseCode() exBlock=%d exName=%s fd=%p\n",exBlock,exName,fd);
       
  3345   if (s.isEmpty()) return;
       
  3346   if (g_codeClassSDict==0)
       
  3347   {
       
  3348     resetCCodeParserState();
       
  3349   }
       
  3350   g_code = &od;
       
  3351   g_inputString   = s;
       
  3352   g_inputPosition = 0;
       
  3353   g_currentFontClass = 0;
       
  3354   g_needsTermination = FALSE;
       
  3355   g_inFunctionTryBlock = FALSE;
       
  3356   if (endLine!=-1)
       
  3357     g_inputLines  = endLine+1;
       
  3358   else
       
  3359     g_inputLines  = countLines();
       
  3360 
       
  3361   if (startLine!=-1)
       
  3362     g_yyLineNr    = startLine;
       
  3363   else
       
  3364     g_yyLineNr    = 1;
       
  3365 
       
  3366   g_curlyCount    = 0;
       
  3367   g_bodyCurlyCount    = 0;
       
  3368   g_bracketCount  = 0;
       
  3369   g_sharpCount    = 0;
       
  3370   g_insideTemplate = FALSE;
       
  3371   g_theCallContext.clear();
       
  3372   g_scopeStack.clear();
       
  3373   g_classScope    = className;
       
  3374   g_exampleBlock  = exBlock; 
       
  3375   g_exampleName   = exName;
       
  3376   g_sourceFileDef = fd;
       
  3377   g_lineNumbers   = fd!=0;
       
  3378   if (exBlock && fd==0)
       
  3379   {
       
  3380     // create a dummy filedef for the example
       
  3381     g_sourceFileDef = new FileDef("",exName);
       
  3382   }
       
  3383   if (g_sourceFileDef) 
       
  3384   {
       
  3385     setCurrentDoc(g_sourceFileDef->name(),g_sourceFileDef->getSourceFileBase());
       
  3386     g_insideObjC = g_sourceFileDef->name().lower().right(2)==".m" || 
       
  3387                    g_sourceFileDef->name().lower().right(3)==".mm"; 
       
  3388   }
       
  3389   g_currentDefinition = 0;
       
  3390   g_currentMemberDef = 0;
       
  3391   g_searchingForBody = exBlock;
       
  3392   g_insideBody = FALSE;
       
  3393   g_bracketCount = 0;
       
  3394   if (!g_exampleName.isEmpty())
       
  3395   {
       
  3396     g_exampleFile = convertNameToFile(g_exampleName+"-example");
       
  3397   }
       
  3398   g_includeCodeFragment = inlineFragment;
       
  3399   //printf("** exBlock=%d exName=%s include=%d\n",exBlock,exName,inlineFragment);
       
  3400   startCodeLine();
       
  3401   g_type.resize(0);
       
  3402   g_name.resize(0);
       
  3403   g_args.resize(0);
       
  3404   g_parmName.resize(0);
       
  3405   g_parmType.resize(0);
       
  3406   if (memberDef) setParameterList(memberDef);
       
  3407   codeYYrestart( codeYYin );
       
  3408   BEGIN( Body );
       
  3409   codeYYlex();
       
  3410   g_lexInit=TRUE;
       
  3411   if (g_needsTermination)
       
  3412   {
       
  3413     endFontClass();
       
  3414     g_code->endCodeLine();
       
  3415   }
       
  3416   if (exBlock && fd==0)
       
  3417   {
       
  3418     // delete the temporary file definition used for this example
       
  3419     delete g_sourceFileDef;
       
  3420     g_sourceFileDef=0;
       
  3421   }
       
  3422   return;
       
  3423 }
       
  3424 
       
  3425 void codeFreeScanner()
       
  3426 {
       
  3427 #if defined(YY_FLEX_SUBMINOR_VERSION) 
       
  3428   if (g_lexInit)
       
  3429   {
       
  3430     codeYYlex_destroy();
       
  3431   }
       
  3432 #endif
       
  3433 }
       
  3434 
       
  3435 
       
  3436 
       
  3437 #if !defined(YY_FLEX_SUBMINOR_VERSION) 
       
  3438 extern "C" { // some bogus code to keep the compiler happy
       
  3439   void codeYYdummy() { yy_flex_realloc(0,0); } 
       
  3440 }
       
  3441 #elif YY_FLEX_SUBMINOR_VERSION<33
       
  3442 #error "You seem to be using a version of flex newer than 2.5.4 but older than 2.5.33. These versions do NOT work with doxygen! Please use version <=2.5.4 or >=2.5.33 or expect things to be parsed wrongly!"
       
  3443 #endif
       
  3444