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