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