Root/
Source at commit 1322 created 12 years 8 months ago. By meklort, Add doxygen to utils folder | |
---|---|
1 | /******************************************************************************␊ |
2 | *␊ |
3 | * ␊ |
4 | *␊ |
5 | *␊ |
6 | * Copyright (C) 1997-2011 by Dimitri van Heesch.␊ |
7 | *␊ |
8 | * Permission to use, copy, modify, and distribute this software and its␊ |
9 | * documentation under the terms of the GNU General Public License is hereby ␊ |
10 | * granted. No representations are made about the suitability of this software ␊ |
11 | * for any purpose. It is provided "as is" without express or implied warranty.␊ |
12 | * See the GNU General Public License for more details.␊ |
13 | *␊ |
14 | * Documents produced by Doxygen are derivative works derived from the␊ |
15 | * input used in their production; they are not affected by this license.␊ |
16 | *␊ |
17 | */␊ |
18 | ␊ |
19 | #include <stdio.h>␊ |
20 | #include <stdlib.h>␊ |
21 | ␊ |
22 | #include <qfile.h>␊ |
23 | #include <qfileinfo.h>␊ |
24 | #include <qcstring.h>␊ |
25 | #include <qstack.h>␊ |
26 | #include <qdict.h>␊ |
27 | #include <qregexp.h>␊ |
28 | #include <ctype.h>␊ |
29 | ␊ |
30 | #include "doxygen.h"␊ |
31 | #include "debug.h"␊ |
32 | #include "util.h"␊ |
33 | #include "pagedef.h"␊ |
34 | ␊ |
35 | #include "docparser.h"␊ |
36 | #include "doctokenizer.h"␊ |
37 | #include "cmdmapper.h"␊ |
38 | #include "printdocvisitor.h"␊ |
39 | #include "message.h"␊ |
40 | #include "section.h"␊ |
41 | #include "searchindex.h"␊ |
42 | #include "language.h"␊ |
43 | #include "portable.h"␊ |
44 | ␊ |
45 | // debug off␊ |
46 | #define DBG(x) do {} while(0)␊ |
47 | ␊ |
48 | // debug to stdout␊ |
49 | //#define DBG(x) printf x␊ |
50 | ␊ |
51 | // debug to stderr␊ |
52 | //#define myprintf(x...) fprintf(stderr,x)␊ |
53 | //#define DBG(x) myprintf x␊ |
54 | ␊ |
55 | #define INTERNAL_ASSERT(x) do {} while(0)␊ |
56 | //#define INTERNAL_ASSERT(x) if (!(x)) DBG(("INTERNAL_ASSERT(%s) failed retval=0x%x: file=%s line=%d\n",#x,retval,__FILE__,__LINE__)); ␊ |
57 | ␊ |
58 | //---------------------------------------------------------------------------␊ |
59 | ␊ |
60 | static const char *sectionLevelToName[] = ␊ |
61 | {␊ |
62 | "page",␊ |
63 | "section",␊ |
64 | "subsection",␊ |
65 | "subsubsection",␊ |
66 | "paragraph"␊ |
67 | };␊ |
68 | ␊ |
69 | //---------------------------------------------------------------------------␊ |
70 | ␊ |
71 | // Parser state: global variables during a call to validatingParseDoc␊ |
72 | static Definition * g_scope;␊ |
73 | static QCString g_context;␊ |
74 | static bool g_inSeeBlock;␊ |
75 | static bool g_insideHtmlLink;␊ |
76 | static QStack<DocNode> g_nodeStack;␊ |
77 | static QStack<DocStyleChange> g_styleStack;␊ |
78 | static QStack<DocStyleChange> g_initialStyleStack;␊ |
79 | static QList<Definition> g_copyStack;␊ |
80 | static QCString g_fileName;␊ |
81 | static QCString g_relPath;␊ |
82 | ␊ |
83 | static bool g_hasParamCommand;␊ |
84 | static bool g_hasReturnCommand;␊ |
85 | static QDict<void> g_paramsFound;␊ |
86 | static MemberDef * g_memberDef;␊ |
87 | static bool g_isExample;␊ |
88 | static QCString g_exampleName;␊ |
89 | static SectionDict * g_sectionDict;␊ |
90 | static QCString g_searchUrl;␊ |
91 | ␊ |
92 | static QCString g_includeFileText;␊ |
93 | static uint g_includeFileOffset;␊ |
94 | static uint g_includeFileLength;␊ |
95 | ␊ |
96 | // parser's context to store all global variables␊ |
97 | struct DocParserContext␊ |
98 | {␊ |
99 | Definition *scope;␊ |
100 | QCString context;␊ |
101 | bool inSeeBlock;␊ |
102 | bool insideHtmlLink;␊ |
103 | QStack<DocNode> nodeStack;␊ |
104 | QStack<DocStyleChange> styleStack;␊ |
105 | QStack<DocStyleChange> initialStyleStack;␊ |
106 | QList<Definition> copyStack;␊ |
107 | QCString fileName;␊ |
108 | QCString relPath;␊ |
109 | ␊ |
110 | bool hasParamCommand;␊ |
111 | bool hasReturnCommand;␊ |
112 | MemberDef * memberDef;␊ |
113 | QDict<void> paramsFound;␊ |
114 | bool isExample;␊ |
115 | QCString exampleName;␊ |
116 | SectionDict *sectionDict;␊ |
117 | QCString searchUrl;␊ |
118 | ␊ |
119 | QCString includeFileText;␊ |
120 | uint includeFileOffset;␊ |
121 | uint includeFileLength;␊ |
122 | ␊ |
123 | TokenInfo *token;␊ |
124 | };␊ |
125 | ␊ |
126 | static QStack<DocParserContext> g_parserStack;␊ |
127 | ␊ |
128 | //---------------------------------------------------------------------------␊ |
129 | ␊ |
130 | static void docParserPushContext(bool saveParamInfo=TRUE)␊ |
131 | {␊ |
132 | //QCString indent;␊ |
133 | //indent.fill(' ',g_parserStack.count()*2+2);␊ |
134 | //printf("%sdocParserPushContext() count=%d\n",indent.data(),g_nodeStack.count());␊ |
135 | ␊ |
136 | doctokenizerYYpushContext();␊ |
137 | DocParserContext *ctx = new DocParserContext;␊ |
138 | ctx->scope = g_scope;␊ |
139 | ctx->context = g_context;␊ |
140 | ctx->inSeeBlock = g_inSeeBlock;␊ |
141 | ctx->insideHtmlLink = g_insideHtmlLink;␊ |
142 | ctx->nodeStack = g_nodeStack;␊ |
143 | ctx->styleStack = g_styleStack;␊ |
144 | ctx->initialStyleStack = g_initialStyleStack;␊ |
145 | ctx->copyStack = g_copyStack;␊ |
146 | ctx->fileName = g_fileName;␊ |
147 | ctx->relPath = g_relPath;␊ |
148 | ␊ |
149 | if (saveParamInfo)␊ |
150 | {␊ |
151 | ctx->hasParamCommand = g_hasParamCommand;␊ |
152 | ctx->hasReturnCommand = g_hasReturnCommand;␊ |
153 | ctx->paramsFound = g_paramsFound;␊ |
154 | }␊ |
155 | ␊ |
156 | ctx->memberDef = g_memberDef;␊ |
157 | ctx->isExample = g_isExample;␊ |
158 | ctx->exampleName = g_exampleName;␊ |
159 | ctx->sectionDict = g_sectionDict;␊ |
160 | ctx->searchUrl = g_searchUrl;␊ |
161 | ␊ |
162 | ctx->includeFileText = g_includeFileText;␊ |
163 | ctx->includeFileOffset = g_includeFileOffset;␊ |
164 | ctx->includeFileLength = g_includeFileLength;␊ |
165 | ␊ |
166 | ctx->token = g_token;␊ |
167 | g_token = new TokenInfo;␊ |
168 | ␊ |
169 | g_parserStack.push(ctx);␊ |
170 | }␊ |
171 | ␊ |
172 | static void docParserPopContext(bool keepParamInfo=FALSE)␊ |
173 | {␊ |
174 | DocParserContext *ctx = g_parserStack.pop();␊ |
175 | g_scope = ctx->scope;␊ |
176 | g_context = ctx->context;␊ |
177 | g_inSeeBlock = ctx->inSeeBlock;␊ |
178 | g_insideHtmlLink = ctx->insideHtmlLink;␊ |
179 | g_nodeStack = ctx->nodeStack;␊ |
180 | g_styleStack = ctx->styleStack;␊ |
181 | g_initialStyleStack = ctx->initialStyleStack;␊ |
182 | g_copyStack = ctx->copyStack;␊ |
183 | g_fileName = ctx->fileName;␊ |
184 | g_relPath = ctx->relPath;␊ |
185 | ␊ |
186 | if (!keepParamInfo)␊ |
187 | {␊ |
188 | g_hasParamCommand = ctx->hasParamCommand;␊ |
189 | g_hasReturnCommand = ctx->hasReturnCommand;␊ |
190 | g_paramsFound = ctx->paramsFound;␊ |
191 | }␊ |
192 | g_memberDef = ctx->memberDef;␊ |
193 | g_isExample = ctx->isExample;␊ |
194 | g_exampleName = ctx->exampleName;␊ |
195 | g_sectionDict = ctx->sectionDict;␊ |
196 | g_searchUrl = ctx->searchUrl;␊ |
197 | ␊ |
198 | g_includeFileText = ctx->includeFileText;␊ |
199 | g_includeFileOffset = ctx->includeFileOffset;␊ |
200 | g_includeFileLength = ctx->includeFileLength;␊ |
201 | ␊ |
202 | delete g_token;␊ |
203 | g_token = ctx->token;␊ |
204 | ␊ |
205 | delete ctx;␊ |
206 | doctokenizerYYpopContext();␊ |
207 | ␊ |
208 | //QCString indent;␊ |
209 | //indent.fill(' ',g_parserStack.count()*2+2);␊ |
210 | //printf("%sdocParserPopContext() count=%d\n",indent.data(),g_nodeStack.count());␊ |
211 | }␊ |
212 | ␊ |
213 | //---------------------------------------------------------------------------␊ |
214 | ␊ |
215 | /*! search for an image in the imageNameDict and if found␊ |
216 | * copies the image to the output directory (which depends on the \a type␊ |
217 | * parameter).␊ |
218 | */␊ |
219 | static QCString findAndCopyImage(const char *fileName,DocImage::Type type)␊ |
220 | {␊ |
221 | QCString result;␊ |
222 | bool ambig;␊ |
223 | FileDef *fd;␊ |
224 | //printf("Search for %s\n",fileName);␊ |
225 | if ((fd=findFileDef(Doxygen::imageNameDict,fileName,ambig)))␊ |
226 | {␊ |
227 | QCString inputFile = fd->absFilePath();␊ |
228 | QFile inImage(inputFile);␊ |
229 | if (inImage.open(IO_ReadOnly))␊ |
230 | {␊ |
231 | result = fileName;␊ |
232 | int i;␊ |
233 | if ((i=result.findRev('/'))!=-1 || (i=result.findRev('\\'))!=-1)␊ |
234 | {␊ |
235 | ␉result = result.right(result.length()-i-1);␊ |
236 | }␊ |
237 | //printf("fileName=%s result=%s\n",fileName,result.data());␊ |
238 | QCString outputDir;␊ |
239 | switch(type)␊ |
240 | {␊ |
241 | case DocImage::Html: ␊ |
242 | ␉ if (!Config_getBool("GENERATE_HTML")) return result;␊ |
243 | ␉ outputDir = Config_getString("HTML_OUTPUT");␊ |
244 | ␉ break;␊ |
245 | case DocImage::Latex: ␊ |
246 | ␉ if (!Config_getBool("GENERATE_LATEX")) return result;␊ |
247 | ␉ outputDir = Config_getString("LATEX_OUTPUT");␊ |
248 | ␉ break;␊ |
249 | case DocImage::Rtf:␊ |
250 | ␉ if (!Config_getBool("GENERATE_RTF")) return result;␊ |
251 | ␉ outputDir = Config_getString("RTF_OUTPUT");␊ |
252 | ␉ break;␊ |
253 | }␊ |
254 | QCString outputFile = outputDir+"/"+result;␊ |
255 | if (outputFile!=inputFile) // prevent copying to ourself␊ |
256 | {␊ |
257 | QFile outImage(outputFile.data());␊ |
258 | if (outImage.open(IO_WriteOnly)) // copy the image␊ |
259 | {␊ |
260 | char *buffer = new char[inImage.size()];␊ |
261 | inImage.readBlock(buffer,inImage.size());␊ |
262 | outImage.writeBlock(buffer,inImage.size());␊ |
263 | outImage.flush();␊ |
264 | delete[] buffer;␊ |
265 | if (type==DocImage::Html) Doxygen::indexList.addImageFile(result);␊ |
266 | }␊ |
267 | else␊ |
268 | {␊ |
269 | warn_doc_error(g_fileName,doctokenizerYYlineno,␊ |
270 | "warning: could not write output image %s",qPrint(outputFile));␊ |
271 | }␊ |
272 | }␊ |
273 | }␊ |
274 | else␊ |
275 | {␊ |
276 | warn_doc_error(g_fileName,doctokenizerYYlineno,␊ |
277 | ␉ "warning: could not open image %s",qPrint(fileName));␊ |
278 | }␊ |
279 | ␊ |
280 | if (type==DocImage::Latex && Config_getBool("USE_PDFLATEX") && ␊ |
281 | ␉fd->name().right(4)==".eps"␊ |
282 | )␊ |
283 | { // we have an .eps image in pdflatex mode => convert it to a pdf.␊ |
284 | QCString outputDir = Config_getString("LATEX_OUTPUT");␊ |
285 | QCString baseName = fd->name().left(fd->name().length()-4);␊ |
286 | QCString epstopdfArgs(4096);␊ |
287 | epstopdfArgs.sprintf("\"%s/%s.eps\" --outfile=\"%s/%s.pdf\"",␊ |
288 | outputDir.data(), baseName.data(),␊ |
289 | ␉␉␉ outputDir.data(), baseName.data());␊ |
290 | portable_sysTimerStart();␊ |
291 | if (portable_system("epstopdf",epstopdfArgs)!=0)␊ |
292 | {␊ |
293 | ␉err("error: Problems running epstopdf. Check your TeX installation!\n");␊ |
294 | }␊ |
295 | portable_sysTimerStop();␊ |
296 | return baseName;␊ |
297 | }␊ |
298 | }␊ |
299 | else if (ambig)␊ |
300 | {␊ |
301 | QCString text;␊ |
302 | text.sprintf("warning: image file name %s is ambiguous.\n",qPrint(fileName));␊ |
303 | text+="Possible candidates:\n";␊ |
304 | text+=showFileDefMatches(Doxygen::imageNameDict,fileName);␊ |
305 | warn_doc_error(g_fileName,doctokenizerYYlineno,text);␊ |
306 | }␊ |
307 | else␊ |
308 | {␊ |
309 | result=fileName;␊ |
310 | if (result.left(5)!="http:" && result.left(6)!="https:")␊ |
311 | {␊ |
312 | warn_doc_error(g_fileName,doctokenizerYYlineno,␊ |
313 | "warning: image file %s is not found in IMAGE_PATH: " ␊ |
314 | ␉ "assuming external image.",qPrint(fileName)␊ |
315 | );␊ |
316 | }␊ |
317 | }␊ |
318 | return result;␊ |
319 | }␊ |
320 | ␊ |
321 | /*! Collects the parameters found with \@param or \@retval commands␊ |
322 | * in a global list g_paramsFound. If \a isParam is set to TRUE␊ |
323 | * and the parameter is not an actual parameter of the current␊ |
324 | * member g_memberDef, then a warning is raised (unless warnings␊ |
325 | * are disabled altogether).␊ |
326 | */␊ |
327 | static void checkArgumentName(const QCString &name,bool isParam)␊ |
328 | { ␊ |
329 | if (!Config_getBool("WARN_IF_DOC_ERROR")) return;␊ |
330 | if (g_memberDef==0) return; // not a member␊ |
331 | LockingPtr<ArgumentList> al=g_memberDef->isDocsForDefinition() ? ␊ |
332 | ␉␉ g_memberDef->argumentList() :␊ |
333 | g_memberDef->declArgumentList();␊ |
334 | //printf("isDocsForDefinition()=%d\n",g_memberDef->isDocsForDefinition());␊ |
335 | if (al==0) return; // no argument list␊ |
336 | ␊ |
337 | static QRegExp re("[a-zA-Z0-9_\\x80-\\xFF]+\\.*");␊ |
338 | int p=0,i=0,l;␊ |
339 | while ((i=re.match(name,p,&l))!=-1) // to handle @param x,y␊ |
340 | {␊ |
341 | QCString aName=name.mid(i,l);␊ |
342 | //printf("aName=`%s'\n",aName.data());␊ |
343 | ArgumentListIterator ali(*al);␊ |
344 | Argument *a;␊ |
345 | bool found=FALSE;␊ |
346 | for (ali.toFirst();(a=ali.current());++ali)␊ |
347 | {␊ |
348 | QCString argName = g_memberDef->isDefine() ? a->type : a->name;␊ |
349 | argName=argName.stripWhiteSpace();␊ |
350 | //printf("argName=`%s'\n",argName.data());␊ |
351 | if (argName.right(3)=="...") argName=argName.left(argName.length()-3);␊ |
352 | if (aName==argName) ␊ |
353 | {␊ |
354 | ␉//printf("adding `%s'\n",aName.data());␊ |
355 | ␉g_paramsFound.insert(aName,(void *)(0x8));␊ |
356 | ␉found=TRUE;␊ |
357 | ␉break;␊ |
358 | }␊ |
359 | }␊ |
360 | if (!found && isParam)␊ |
361 | {␊ |
362 | //printf("member type=%d\n",memberDef->memberType());␊ |
363 | QCString scope=g_memberDef->getScopeString();␊ |
364 | if (!scope.isEmpty()) scope+="::"; else scope="";␊ |
365 | QCString inheritedFrom = "";␊ |
366 | QCString docFile = g_memberDef->docFile();␊ |
367 | int docLine = g_memberDef->docLine();␊ |
368 | MemberDef *inheritedMd = g_memberDef->inheritsDocsFrom();␊ |
369 | if (inheritedMd) // documentation was inherited␊ |
370 | {␊ |
371 | inheritedFrom.sprintf(" inherited from member %s at line "␊ |
372 | "%d in file %s",qPrint(inheritedMd->name()),␊ |
373 | inheritedMd->docLine(),qPrint(inheritedMd->docFile()));␊ |
374 | docFile = g_memberDef->getDefFileName();␊ |
375 | docLine = g_memberDef->getDefLine();␊ |
376 | ␊ |
377 | }␊ |
378 | QCString alStr = argListToString(al.pointer());␊ |
379 | warn_doc_error(docFile,docLine,␊ |
380 | ␉ "warning: argument '%s' of command @param "␊ |
381 | ␉ "is not found in the argument list of %s%s%s%s",␊ |
382 | ␉ qPrint(aName), qPrint(scope), qPrint(g_memberDef->name()),␊ |
383 | ␉ qPrint(alStr), qPrint(inheritedFrom));␊ |
384 | }␊ |
385 | p=i+l;␊ |
386 | }␊ |
387 | }␊ |
388 | ␊ |
389 | /*! Checks if the parameters that have been specified using \@param are␊ |
390 | * indeed all paramters.␊ |
391 | * Must be called after checkArgumentName() has been called for each␊ |
392 | * argument.␊ |
393 | */␊ |
394 | static void checkUndocumentedParams()␊ |
395 | {␊ |
396 | if (g_memberDef && g_hasParamCommand && Config_getBool("WARN_IF_DOC_ERROR"))␊ |
397 | {␊ |
398 | LockingPtr<ArgumentList> al=g_memberDef->isDocsForDefinition() ? ␊ |
399 | g_memberDef->argumentList() :␊ |
400 | g_memberDef->declArgumentList();␊ |
401 | if (al!=0)␊ |
402 | {␊ |
403 | ArgumentListIterator ali(*al);␊ |
404 | Argument *a;␊ |
405 | bool found=FALSE;␊ |
406 | for (ali.toFirst();(a=ali.current());++ali)␊ |
407 | {␊ |
408 | QCString argName = g_memberDef->isDefine() ? a->type : a->name;␊ |
409 | argName=argName.stripWhiteSpace();␊ |
410 | if (argName.right(3)=="...") argName=argName.left(argName.length()-3);␊ |
411 | if (getLanguageFromFileName(g_memberDef->getDefFileName())==SrcLangExt_Python && argName=="self")␊ |
412 | { ␊ |
413 | // allow undocumented self parameter for Python␊ |
414 | }␊ |
415 | else if (!argName.isEmpty() && g_paramsFound.find(argName)==0 && a->docs.isEmpty()) ␊ |
416 | {␊ |
417 | found = TRUE;␊ |
418 | break;␊ |
419 | }␊ |
420 | }␊ |
421 | if (found)␊ |
422 | {␊ |
423 | bool first=TRUE;␊ |
424 | QCString errMsg=␊ |
425 | "warning: The following parameters of "+␊ |
426 | QCString(g_memberDef->qualifiedName()) + ␊ |
427 | QCString(argListToString(al.pointer())) +␊ |
428 | " are not documented:\n";␊ |
429 | for (ali.toFirst();(a=ali.current());++ali)␊ |
430 | {␊ |
431 | QCString argName = g_memberDef->isDefine() ? a->type : a->name;␊ |
432 | argName=argName.stripWhiteSpace();␊ |
433 | if (getLanguageFromFileName(g_memberDef->getDefFileName())==SrcLangExt_Python && argName=="self")␊ |
434 | { ␊ |
435 | // allow undocumented self parameter for Python␊ |
436 | }␊ |
437 | else if (!argName.isEmpty() && g_paramsFound.find(argName)==0) ␊ |
438 | {␊ |
439 | if (!first)␊ |
440 | {␊ |
441 | errMsg+="\n";␊ |
442 | }␊ |
443 | else␊ |
444 | {␊ |
445 | first=FALSE;␊ |
446 | }␊ |
447 | errMsg+=" parameter '"+argName+"'";␊ |
448 | }␊ |
449 | }␊ |
450 | if (g_memberDef->inheritsDocsFrom())␊ |
451 | {␊ |
452 | warn_doc_error(g_memberDef->getDefFileName(),␊ |
453 | g_memberDef->getDefLine(),␊ |
454 | substitute(errMsg,"%","%%"));␊ |
455 | }␊ |
456 | else␊ |
457 | {␊ |
458 | warn_doc_error(g_memberDef->docFile(),␊ |
459 | g_memberDef->docLine(),␊ |
460 | substitute(errMsg,"%","%%"));␊ |
461 | }␊ |
462 | }␊ |
463 | }␊ |
464 | }␊ |
465 | }␊ |
466 | ␊ |
467 | /*! Check if a member has documentation for its parameter and or return␊ |
468 | * type, if applicable. If found this will be stored in the member, this␊ |
469 | * is needed as a member can have brief and detailed documentation, while␊ |
470 | * only one of these needs to document the parameters.␊ |
471 | */␊ |
472 | static void detectNoDocumentedParams()␊ |
473 | {␊ |
474 | if (g_memberDef && Config_getBool("WARN_NO_PARAMDOC"))␊ |
475 | {␊ |
476 | LockingPtr<ArgumentList> al = g_memberDef->argumentList();␊ |
477 | LockingPtr<ArgumentList> declAl = g_memberDef->declArgumentList();␊ |
478 | QCString returnType = g_memberDef->typeString();␊ |
479 | bool isPython = getLanguageFromFileName(g_memberDef->getDefFileName())==SrcLangExt_Python;␊ |
480 | ␊ |
481 | if (!g_memberDef->hasDocumentedParams() &&␊ |
482 | g_hasParamCommand)␊ |
483 | {␊ |
484 | //printf("%s->setHasDocumentedParams(TRUE);\n",g_memberDef->name().data());␊ |
485 | g_memberDef->setHasDocumentedParams(TRUE);␊ |
486 | }␊ |
487 | else if (!g_memberDef->hasDocumentedParams())␊ |
488 | {␊ |
489 | bool allDoc=TRUE; // no paramater => all parameters are documented␊ |
490 | if ( // member has parameters␊ |
491 | al!=0 && // but the member has a parameter list␊ |
492 | al->count()>0 // with at least one parameter (that is not void)␊ |
493 | )␊ |
494 | {␊ |
495 | ArgumentListIterator ali(*al);␊ |
496 | Argument *a;␊ |
497 | ␊ |
498 | // see if all parameters have documentation␊ |
499 | for (ali.toFirst();(a=ali.current()) && allDoc;++ali)␊ |
500 | {␊ |
501 | if (!a->name.isEmpty() && a->type!="void" &&␊ |
502 | !(isPython && a->name=="self")␊ |
503 | )␊ |
504 | {␊ |
505 | allDoc = !a->docs.isEmpty();␊ |
506 | }␊ |
507 | //printf("a->type=%s a->name=%s doc=%s\n",␊ |
508 | // a->type.data(),a->name.data(),a->docs.data());␊ |
509 | }␊ |
510 | if (!allDoc && declAl!=0) // try declaration arguments as well␊ |
511 | {␊ |
512 | allDoc=TRUE;␊ |
513 | ArgumentListIterator ali(*declAl);␊ |
514 | Argument *a;␊ |
515 | for (ali.toFirst();(a=ali.current()) && allDoc;++ali)␊ |
516 | {␊ |
517 | if (!a->name.isEmpty() && a->type!="void" &&␊ |
518 | !(isPython && a->name=="self")␊ |
519 | )␊ |
520 | {␊ |
521 | allDoc = !a->docs.isEmpty();␊ |
522 | }␊ |
523 | //printf("a->name=%s doc=%s\n",a->name.data(),a->docs.data());␊ |
524 | }␊ |
525 | }␊ |
526 | }␊ |
527 | if (allDoc) ␊ |
528 | {␊ |
529 | //printf("%s->setHasDocumentedParams(TRUE);\n",g_memberDef->name().data());␊ |
530 | g_memberDef->setHasDocumentedParams(TRUE);␊ |
531 | }␊ |
532 | }␊ |
533 | //printf("Member %s hasReturnCommand=%d\n",g_memberDef->name().data(),g_hasReturnCommand);␊ |
534 | if (!g_memberDef->hasDocumentedReturnType() && // docs not yet found␊ |
535 | g_hasReturnCommand)␊ |
536 | {␊ |
537 | g_memberDef->setHasDocumentedReturnType(TRUE);␊ |
538 | }␊ |
539 | else if ( // see if return needs to documented ␊ |
540 | g_memberDef->hasDocumentedReturnType() ||␊ |
541 | returnType.isEmpty() || // empty return type␊ |
542 | returnType.find("void")!=-1 || // void return type␊ |
543 | returnType.find("subroutine")!=-1 || // fortran subroutine␊ |
544 | g_memberDef->isConstructor() || // a constructor␊ |
545 | g_memberDef->isDestructor() // or destructor␊ |
546 | )␊ |
547 | {␊ |
548 | g_memberDef->setHasDocumentedReturnType(TRUE);␊ |
549 | }␊ |
550 | ␊ |
551 | }␊ |
552 | }␊ |
553 | ␊ |
554 | ␊ |
555 | //---------------------------------------------------------------------------␊ |
556 | ␊ |
557 | /*! Strips known html and tex extensions from \a text. */␊ |
558 | static QCString stripKnownExtensions(const char *text)␊ |
559 | {␊ |
560 | QCString result=text;␊ |
561 | if (result.right(4)==".tex")␊ |
562 | {␊ |
563 | result=result.left(result.length()-4);␊ |
564 | }␊ |
565 | else if (result.right(Doxygen::htmlFileExtension.length())==␊ |
566 | QCString(Doxygen::htmlFileExtension)) ␊ |
567 | {␊ |
568 | result=result.left(result.length()-Doxygen::htmlFileExtension.length());␊ |
569 | }␊ |
570 | return result;␊ |
571 | }␊ |
572 | ␊ |
573 | ␊ |
574 | //---------------------------------------------------------------------------␊ |
575 | ␊ |
576 | /*! Returns TRUE iff node n is a child of a preformatted node */␊ |
577 | static bool insidePRE(DocNode *n)␊ |
578 | {␊ |
579 | while (n)␊ |
580 | {␊ |
581 | if (n->isPreformatted()) return TRUE;␊ |
582 | n=n->parent();␊ |
583 | }␊ |
584 | return FALSE;␊ |
585 | }␊ |
586 | ␊ |
587 | //---------------------------------------------------------------------------␊ |
588 | ␊ |
589 | /*! Returns TRUE iff node n is a child of a html list item node */␊ |
590 | static bool insideLI(DocNode *n)␊ |
591 | {␊ |
592 | while (n)␊ |
593 | {␊ |
594 | if (n->kind()==DocNode::Kind_HtmlListItem) return TRUE;␊ |
595 | n=n->parent();␊ |
596 | }␊ |
597 | return FALSE;␊ |
598 | }␊ |
599 | ␊ |
600 | //---------------------------------------------------------------------------␊ |
601 | ␊ |
602 | /*! Returns TRUE iff node n is a child of a unordered html list node */␊ |
603 | static bool insideUL(DocNode *n)␊ |
604 | {␊ |
605 | while (n)␊ |
606 | {␊ |
607 | if (n->kind()==DocNode::Kind_HtmlList && ␊ |
608 | ((DocHtmlList *)n)->type()==DocHtmlList::Unordered) return TRUE;␊ |
609 | n=n->parent();␊ |
610 | }␊ |
611 | return FALSE;␊ |
612 | }␊ |
613 | ␊ |
614 | //---------------------------------------------------------------------------␊ |
615 | ␊ |
616 | /*! Returns TRUE iff node n is a child of a ordered html list node */␊ |
617 | static bool insideOL(DocNode *n)␊ |
618 | {␊ |
619 | while (n)␊ |
620 | {␊ |
621 | if (n->kind()==DocNode::Kind_HtmlList && ␊ |
622 | ((DocHtmlList *)n)->type()==DocHtmlList::Ordered) return TRUE;␊ |
623 | n=n->parent();␊ |
624 | }␊ |
625 | return FALSE;␊ |
626 | }␊ |
627 | ␊ |
628 | //---------------------------------------------------------------------------␊ |
629 | ␊ |
630 | static bool insideTable(DocNode *n)␊ |
631 | {␊ |
632 | while (n)␊ |
633 | {␊ |
634 | if (n->kind()==DocNode::Kind_HtmlTable) return TRUE;␊ |
635 | n=n->parent();␊ |
636 | }␊ |
637 | return FALSE;␊ |
638 | }␊ |
639 | ␊ |
640 | //---------------------------------------------------------------------------␊ |
641 | ␊ |
642 | ///*! Returns TRUE iff node n is a child of a language node */␊ |
643 | //static bool insideLang(DocNode *n)␊ |
644 | //{␊ |
645 | // while (n)␊ |
646 | // {␊ |
647 | // if (n->kind()==DocNode::Kind_Language) return TRUE;␊ |
648 | // n=n->parent();␊ |
649 | // }␊ |
650 | // return FALSE;␊ |
651 | //}␊ |
652 | ␊ |
653 | ␊ |
654 | //---------------------------------------------------------------------------␊ |
655 | ␊ |
656 | /*! Looks for a documentation block with name commandName in the current␊ |
657 | * context (g_context). The resulting documentation string is␊ |
658 | * put in pDoc, the definition in which the documentation was found is␊ |
659 | * put in pDef.␊ |
660 | * @retval TRUE if name was found.␊ |
661 | * @retval FALSE if name was not found.␊ |
662 | */␊ |
663 | static bool findDocsForMemberOrCompound(const char *commandName,␊ |
664 | QCString *pDoc,␊ |
665 | QCString *pBrief,␊ |
666 | Definition **pDef)␊ |
667 | {␊ |
668 | //printf("findDocsForMemberOrCompound(%s)\n",commandName);␊ |
669 | *pDoc="";␊ |
670 | *pBrief="";␊ |
671 | *pDef=0;␊ |
672 | QCString cmdArg=substitute(commandName,"#","::");␊ |
673 | int l=cmdArg.length();␊ |
674 | if (l==0) return FALSE;␊ |
675 | ␊ |
676 | int funcStart=cmdArg.find('(');␊ |
677 | if (funcStart==-1) ␊ |
678 | {␊ |
679 | funcStart=l;␊ |
680 | }␊ |
681 | else␊ |
682 | {␊ |
683 | // Check for the case of operator() and the like.␊ |
684 | // beware of scenarios like operator()((foo)bar)␊ |
685 | int secondParen = cmdArg.find('(', funcStart+1);␊ |
686 | int leftParen = cmdArg.find(')', funcStart+1);␊ |
687 | if (leftParen!=-1 && secondParen!=-1) ␊ |
688 | {␊ |
689 | if (leftParen<secondParen) ␊ |
690 | {␊ |
691 | funcStart=secondParen;␊ |
692 | }␊ |
693 | }␊ |
694 | }␊ |
695 | ␊ |
696 | QCString name=removeRedundantWhiteSpace(cmdArg.left(funcStart));␊ |
697 | QCString args=cmdArg.right(l-funcStart);␊ |
698 | ␊ |
699 | // try if the link is to a member␊ |
700 | MemberDef *md=0;␊ |
701 | ClassDef *cd=0;␊ |
702 | FileDef *fd=0;␊ |
703 | NamespaceDef *nd=0;␊ |
704 | GroupDef *gd=0;␊ |
705 | PageDef *pd=0;␊ |
706 | bool found = getDefs(␊ |
707 | g_context.find('.')==-1?g_context.data():"", // `find('.') is a hack to detect files␊ |
708 | name,␊ |
709 | args.isEmpty()?0:args.data(),␊ |
710 | md,cd,fd,nd,gd,FALSE,0,TRUE);␊ |
711 | //printf("found=%d context=%s name=%s\n",found,g_context.data(),name.data());␊ |
712 | if (found && md)␊ |
713 | {␊ |
714 | *pDoc=md->documentation();␊ |
715 | *pBrief=md->briefDescription();␊ |
716 | *pDef=md;␊ |
717 | return TRUE;␊ |
718 | }␊ |
719 | ␊ |
720 | ␊ |
721 | int scopeOffset=g_context.length();␊ |
722 | do // for each scope␊ |
723 | {␊ |
724 | QCString fullName=cmdArg;␊ |
725 | if (scopeOffset>0)␊ |
726 | {␊ |
727 | fullName.prepend(g_context.left(scopeOffset)+"::");␊ |
728 | }␊ |
729 | //printf("Trying fullName=`%s'\n",fullName.data());␊ |
730 | ␊ |
731 | // try class, namespace, group, page, file reference␊ |
732 | cd = Doxygen::classSDict->find(fullName);␊ |
733 | if (cd) // class ␊ |
734 | {␊ |
735 | *pDoc=cd->documentation();␊ |
736 | *pBrief=cd->briefDescription();␊ |
737 | *pDef=cd;␊ |
738 | return TRUE;␊ |
739 | }␊ |
740 | nd = Doxygen::namespaceSDict->find(fullName);␊ |
741 | if (nd) // namespace␊ |
742 | {␊ |
743 | *pDoc=nd->documentation();␊ |
744 | *pBrief=nd->briefDescription();␊ |
745 | *pDef=nd;␊ |
746 | return TRUE;␊ |
747 | }␊ |
748 | gd = Doxygen::groupSDict->find(cmdArg);␊ |
749 | if (gd) // group␊ |
750 | {␊ |
751 | *pDoc=gd->documentation();␊ |
752 | *pBrief=gd->briefDescription();␊ |
753 | *pDef=gd;␊ |
754 | return TRUE;␊ |
755 | }␊ |
756 | pd = Doxygen::pageSDict->find(cmdArg);␊ |
757 | if (pd) // page␊ |
758 | {␊ |
759 | *pDoc=pd->documentation();␊ |
760 | *pBrief=pd->briefDescription();␊ |
761 | *pDef=pd;␊ |
762 | return TRUE;␊ |
763 | }␊ |
764 | bool ambig;␊ |
765 | fd = findFileDef(Doxygen::inputNameDict,cmdArg,ambig);␊ |
766 | if (fd && !ambig) // file␊ |
767 | {␊ |
768 | *pDoc=fd->documentation();␊ |
769 | *pBrief=fd->briefDescription();␊ |
770 | *pDef=fd;␊ |
771 | return TRUE;␊ |
772 | }␊ |
773 | ␊ |
774 | if (scopeOffset==0)␊ |
775 | {␊ |
776 | scopeOffset=-1;␊ |
777 | }␊ |
778 | else␊ |
779 | {␊ |
780 | scopeOffset = g_context.findRev("::",scopeOffset-1);␊ |
781 | if (scopeOffset==-1) scopeOffset=0;␊ |
782 | }␊ |
783 | } while (scopeOffset>=0);␊ |
784 | ␊ |
785 | ␊ |
786 | return FALSE;␊ |
787 | }␊ |
788 | //---------------------------------------------------------------------------␊ |
789 | ␊ |
790 | // forward declaration␊ |
791 | static bool defaultHandleToken(DocNode *parent,int tok, ␊ |
792 | QList<DocNode> &children,bool␊ |
793 | handleWord=TRUE);␊ |
794 | ␊ |
795 | ␊ |
796 | static int handleStyleArgument(DocNode *parent,QList<DocNode> &children,␊ |
797 | const QCString &cmdName)␊ |
798 | {␊ |
799 | DBG(("handleStyleArgument(%s)\n",qPrint(cmdName)));␊ |
800 | QCString tokenName = g_token->name;␊ |
801 | int tok=doctokenizerYYlex();␊ |
802 | if (tok!=TK_WHITESPACE)␊ |
803 | {␊ |
804 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: expected whitespace after %s command",␊ |
805 | ␉qPrint(cmdName));␊ |
806 | return tok;␊ |
807 | }␊ |
808 | while ((tok=doctokenizerYYlex()) && ␊ |
809 | tok!=TK_WHITESPACE && ␊ |
810 | tok!=TK_NEWPARA &&␊ |
811 | tok!=TK_LISTITEM && ␊ |
812 | tok!=TK_ENDLIST␊ |
813 | )␊ |
814 | {␊ |
815 | static QRegExp specialChar("[.,|()\\[\\]:;\\?]");␊ |
816 | if (tok==TK_WORD && g_token->name.length()==1 && ␊ |
817 | g_token->name.find(specialChar)!=-1)␊ |
818 | {␊ |
819 | // special character that ends the markup command␊ |
820 | return tok;␊ |
821 | }␊ |
822 | if (!defaultHandleToken(parent,tok,children))␊ |
823 | {␊ |
824 | switch (tok)␊ |
825 | {␊ |
826 | case TK_COMMAND: ␊ |
827 | ␉ warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Illegal command \\%s as the argument of a \\%s command",␊ |
828 | ␉ qPrint(g_token->name),qPrint(cmdName));␊ |
829 | break;␊ |
830 | case TK_SYMBOL: ␊ |
831 | ␉ warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Unsupported symbol %s found while handling command %s",␊ |
832 | qPrint(g_token->name),qPrint(cmdName));␊ |
833 | break;␊ |
834 | case TK_HTMLTAG:␊ |
835 | if (insideLI(parent) && Mappers::htmlTagMapper->map(g_token->name) && g_token->endTag)␊ |
836 | { // ignore </li> as the end of a style command␊ |
837 | continue; ␊ |
838 | }␊ |
839 | return tok;␊ |
840 | break;␊ |
841 | default:␊ |
842 | ␉ warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Unexpected token %s while handling command %s",␊ |
843 | ␉ tokToString(tok),qPrint(cmdName));␊ |
844 | break;␊ |
845 | }␊ |
846 | break;␊ |
847 | }␊ |
848 | }␊ |
849 | DBG(("handleStyleArgument(%s) end tok=%x\n",qPrint(cmdName),tok));␊ |
850 | return (tok==TK_NEWPARA || tok==TK_LISTITEM || tok==TK_ENDLIST␊ |
851 | ) ? tok : RetVal_OK; ␊ |
852 | }␊ |
853 | ␊ |
854 | /*! Called when a style change starts. For instance a \<b\> command is␊ |
855 | * encountered.␊ |
856 | */␊ |
857 | static void handleStyleEnter(DocNode *parent,QList<DocNode> &children,␊ |
858 | DocStyleChange::Style s,const HtmlAttribList *attribs)␊ |
859 | {␊ |
860 | DBG(("HandleStyleEnter\n"));␊ |
861 | DocStyleChange *sc= new DocStyleChange(parent,g_nodeStack.count(),s,TRUE,attribs);␊ |
862 | children.append(sc);␊ |
863 | g_styleStack.push(sc);␊ |
864 | }␊ |
865 | ␊ |
866 | /*! Called when a style change ends. For instance a \</b\> command is␊ |
867 | * encountered.␊ |
868 | */␊ |
869 | static void handleStyleLeave(DocNode *parent,QList<DocNode> &children,␊ |
870 | DocStyleChange::Style s,const char *tagName)␊ |
871 | {␊ |
872 | DBG(("HandleStyleLeave\n"));␊ |
873 | if (g_styleStack.isEmpty() || // no style change␊ |
874 | g_styleStack.top()->style()!=s || // wrong style change␊ |
875 | g_styleStack.top()->position()!=g_nodeStack.count() // wrong position␊ |
876 | )␊ |
877 | {␊ |
878 | if (g_styleStack.isEmpty())␊ |
879 | {␊ |
880 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: found </%s> tag without matching <%s>",␊ |
881 | qPrint(tagName),qPrint(tagName));␊ |
882 | }␊ |
883 | else if (g_styleStack.top()->style()!=s)␊ |
884 | {␊ |
885 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: found </%s> tag while expecting </%s>",␊ |
886 | qPrint(tagName),qPrint(g_styleStack.top()->styleString()));␊ |
887 | }␊ |
888 | else␊ |
889 | {␊ |
890 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: found </%s> at different nesting level (%d) than expected (%d)",␊ |
891 | qPrint(tagName),g_nodeStack.count(),g_styleStack.top()->position());␊ |
892 | }␊ |
893 | }␊ |
894 | else // end the section␊ |
895 | {␊ |
896 | DocStyleChange *sc= new DocStyleChange(parent,g_nodeStack.count(),s,FALSE);␊ |
897 | children.append(sc);␊ |
898 | g_styleStack.pop();␊ |
899 | }␊ |
900 | }␊ |
901 | ␊ |
902 | /*! Called at the end of a paragraph to close all open style changes␊ |
903 | * (e.g. a <b> without a </b>). The closed styles are pushed onto a stack␊ |
904 | * and entered again at the start of a new paragraph.␊ |
905 | */␊ |
906 | static void handlePendingStyleCommands(DocNode *parent,QList<DocNode> &children)␊ |
907 | {␊ |
908 | if (!g_styleStack.isEmpty())␊ |
909 | {␊ |
910 | DocStyleChange *sc = g_styleStack.top();␊ |
911 | while (sc && sc->position()>=g_nodeStack.count()) ␊ |
912 | { // there are unclosed style modifiers in the paragraph␊ |
913 | children.append(new DocStyleChange(parent,g_nodeStack.count(),sc->style(),FALSE));␊ |
914 | g_initialStyleStack.push(sc);␊ |
915 | g_styleStack.pop();␊ |
916 | sc = g_styleStack.top();␊ |
917 | }␊ |
918 | }␊ |
919 | }␊ |
920 | ␊ |
921 | static void handleInitialStyleCommands(DocPara *parent,QList<DocNode> &children)␊ |
922 | {␊ |
923 | DocStyleChange *sc;␊ |
924 | while ((sc=g_initialStyleStack.pop()))␊ |
925 | {␊ |
926 | handleStyleEnter(parent,children,sc->style(),&sc->attribs());␊ |
927 | }␊ |
928 | }␊ |
929 | ␊ |
930 | static int handleAHref(DocNode *parent,QList<DocNode> &children,const HtmlAttribList &tagHtmlAttribs)␊ |
931 | {␊ |
932 | HtmlAttribListIterator li(tagHtmlAttribs);␊ |
933 | HtmlAttrib *opt;␊ |
934 | int index=0;␊ |
935 | int retval = RetVal_OK;␊ |
936 | for (li.toFirst();(opt=li.current());++li,++index)␊ |
937 | {␊ |
938 | if (opt->name=="name") // <a name=label> tag␊ |
939 | {␊ |
940 | if (!opt->value.isEmpty())␊ |
941 | {␊ |
942 | DocAnchor *anc = new DocAnchor(parent,opt->value,TRUE);␊ |
943 | children.append(anc);␊ |
944 | break; // stop looking for other tag attribs␊ |
945 | }␊ |
946 | else␊ |
947 | {␊ |
948 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: found <a> tag with name option but without value!");␊ |
949 | }␊ |
950 | }␊ |
951 | else if (opt->name=="href") // <a href=url>..</a> tag␊ |
952 | {␊ |
953 | // copy attributes␊ |
954 | HtmlAttribList attrList = tagHtmlAttribs;␊ |
955 | // and remove the href attribute␊ |
956 | bool result = attrList.remove(index);␊ |
957 | ASSERT(result);␊ |
958 | DocHRef *href = new DocHRef(parent,attrList,opt->value);␊ |
959 | children.append(href);␊ |
960 | g_insideHtmlLink=TRUE;␊ |
961 | retval = href->parse();␊ |
962 | g_insideHtmlLink=FALSE;␊ |
963 | break;␊ |
964 | }␊ |
965 | else // unsupported option for tag a␊ |
966 | {␊ |
967 | }␊ |
968 | }␊ |
969 | return retval;␊ |
970 | }␊ |
971 | ␊ |
972 | const char *DocStyleChange::styleString() const␊ |
973 | {␊ |
974 | switch (m_style)␊ |
975 | {␊ |
976 | case DocStyleChange::Bold: return "b"; ␊ |
977 | case DocStyleChange::Italic: return "em"; ␊ |
978 | case DocStyleChange::Code: return "code"; ␊ |
979 | case DocStyleChange::Center: return "center"; ␊ |
980 | case DocStyleChange::Small: return "small"; ␊ |
981 | case DocStyleChange::Subscript: return "subscript"; ␊ |
982 | case DocStyleChange::Superscript: return "superscript"; ␊ |
983 | case DocStyleChange::Preformatted: return "pre"; ␊ |
984 | case DocStyleChange::Div: return "div";␊ |
985 | case DocStyleChange::Span: return "span";␊ |
986 | }␊ |
987 | return "<invalid>";␊ |
988 | }␊ |
989 | ␊ |
990 | static void handleUnclosedStyleCommands()␊ |
991 | {␊ |
992 | if (!g_initialStyleStack.isEmpty())␊ |
993 | {␊ |
994 | DocStyleChange *sc = g_initialStyleStack.top();␊ |
995 | g_initialStyleStack.pop();␊ |
996 | handleUnclosedStyleCommands();␊ |
997 | warn_doc_error(g_fileName,doctokenizerYYlineno,␊ |
998 | "warning: end of comment block while expecting "␊ |
999 | "command </%s>",qPrint(sc->styleString()));␊ |
1000 | }␊ |
1001 | }␊ |
1002 | ␊ |
1003 | static void handleLinkedWord(DocNode *parent,QList<DocNode> &children)␊ |
1004 | {␊ |
1005 | Definition *compound=0;␊ |
1006 | MemberDef *member=0;␊ |
1007 | QCString name = linkToText(g_token->name,TRUE);␊ |
1008 | int len = g_token->name.length();␊ |
1009 | ClassDef *cd=0;␊ |
1010 | bool ambig;␊ |
1011 | FileDef *fd = findFileDef(Doxygen::inputNameDict,g_fileName,ambig);␊ |
1012 | //printf("handleLinkedWord(%s) g_context=%s\n",g_token->name.data(),g_context.data());␊ |
1013 | if (!g_insideHtmlLink && ␊ |
1014 | (resolveRef(g_context,g_token->name,g_inSeeBlock,&compound,&member,TRUE,fd,TRUE)␊ |
1015 | || (!g_context.isEmpty() && // also try with global scope␊ |
1016 | resolveRef("",g_token->name,g_inSeeBlock,&compound,&member,FALSE,0,TRUE))␊ |
1017 | )␊ |
1018 | )␊ |
1019 | {␊ |
1020 | //printf("resolveRef %s = %p (linkable?=%d)\n",qPrint(g_token->name),member,member ? member->isLinkable() : FALSE);␊ |
1021 | if (member && member->isLinkable()) // member link␊ |
1022 | {␊ |
1023 | if (member->isObjCMethod()) ␊ |
1024 | {␊ |
1025 | bool localLink = g_memberDef ? member->getClassDef()==g_memberDef->getClassDef() : FALSE;␊ |
1026 | name = member->objCMethodName(localLink,g_inSeeBlock);␊ |
1027 | }␊ |
1028 | children.append(new ␊ |
1029 | DocLinkedWord(parent,name,␊ |
1030 | member->getReference(),␊ |
1031 | member->getOutputFileBase(),␊ |
1032 | member->anchor(),␊ |
1033 | member->briefDescriptionAsTooltip()␊ |
1034 | )␊ |
1035 | );␊ |
1036 | }␊ |
1037 | else if (compound->isLinkable()) // compound link␊ |
1038 | {␊ |
1039 | QCString anchor;␊ |
1040 | if (compound->definitionType()==Definition::TypeFile)␊ |
1041 | {␊ |
1042 | name=g_token->name;␊ |
1043 | }␊ |
1044 | else if (compound->definitionType()==Definition::TypeGroup)␊ |
1045 | {␊ |
1046 | name=((GroupDef*)compound)->groupTitle();␊ |
1047 | }␊ |
1048 | else if (compound->definitionType()==Definition::TypeClass)␊ |
1049 | {␊ |
1050 | anchor=((ClassDef*)compound)->anchor();␊ |
1051 | }␊ |
1052 | children.append(new ␊ |
1053 | DocLinkedWord(parent,name,␊ |
1054 | compound->getReference(),␊ |
1055 | compound->getOutputFileBase(),␊ |
1056 | anchor,␊ |
1057 | compound->briefDescriptionAsTooltip()␊ |
1058 | )␊ |
1059 | );␊ |
1060 | }␊ |
1061 | else if (compound->definitionType()==Definition::TypeFile &&␊ |
1062 | ((FileDef*)compound)->generateSourceFile()␊ |
1063 | ) // undocumented file that has source code we can link to␊ |
1064 | {␊ |
1065 | children.append(new ␊ |
1066 | DocLinkedWord(parent,g_token->name,␊ |
1067 | compound->getReference(),␊ |
1068 | compound->getSourceFileBase(),␊ |
1069 | "",␊ |
1070 | compound->briefDescriptionAsTooltip()␊ |
1071 | )␊ |
1072 | );␊ |
1073 | }␊ |
1074 | else // not linkable␊ |
1075 | {␊ |
1076 | children.append(new DocWord(parent,name));␊ |
1077 | }␊ |
1078 | }␊ |
1079 | else if (!g_insideHtmlLink && len>1 && g_token->name.at(len-1)==':')␊ |
1080 | {␊ |
1081 | // special case, where matching Foo: fails to be an Obj-C reference, ␊ |
1082 | // but Foo itself might be linkable.␊ |
1083 | g_token->name=g_token->name.left(len-1);␊ |
1084 | handleLinkedWord(parent,children);␊ |
1085 | children.append(new DocWord(parent,":"));␊ |
1086 | }␊ |
1087 | else if (!g_insideHtmlLink && (cd=getClass(g_token->name+"-p")))␊ |
1088 | {␊ |
1089 | // special case 2, where the token name is not a class, but could␊ |
1090 | // be a Obj-C protocol␊ |
1091 | children.append(new ␊ |
1092 | DocLinkedWord(parent,name,␊ |
1093 | cd->getReference(),␊ |
1094 | cd->getOutputFileBase(),␊ |
1095 | cd->anchor(),␊ |
1096 | cd->briefDescriptionAsTooltip()␊ |
1097 | ));␊ |
1098 | }␊ |
1099 | else if (!g_insideHtmlLink && (cd=getClass(g_token->name+"-g")))␊ |
1100 | {␊ |
1101 | // special case 3, where the token name is not a class, but could␊ |
1102 | // be a C# generic␊ |
1103 | children.append(new ␊ |
1104 | DocLinkedWord(parent,name,␊ |
1105 | cd->getReference(),␊ |
1106 | cd->getOutputFileBase(),␊ |
1107 | cd->anchor(),␊ |
1108 | cd->briefDescriptionAsTooltip()␊ |
1109 | ));␊ |
1110 | }␊ |
1111 | else // normal non-linkable word␊ |
1112 | {␊ |
1113 | if (g_token->name.left(1)=="#" || g_token->name.left(2)=="::")␊ |
1114 | {␊ |
1115 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: explicit link request to '%s' could not be resolved",qPrint(name));␊ |
1116 | children.append(new DocWord(parent,g_token->name));␊ |
1117 | }␊ |
1118 | else␊ |
1119 | {␊ |
1120 | children.append(new DocWord(parent,name));␊ |
1121 | }␊ |
1122 | }␊ |
1123 | }␊ |
1124 | ␊ |
1125 | static void handleParameterType(DocNode *parent,QList<DocNode> &children,const QCString ¶mTypes)␊ |
1126 | {␊ |
1127 | QCString name = g_token->name;␊ |
1128 | int p=0,i;␊ |
1129 | QCString type;␊ |
1130 | while ((i=paramTypes.find('|',p))!=-1)␊ |
1131 | {␊ |
1132 | g_token->name = paramTypes.mid(p,i-p);␊ |
1133 | handleLinkedWord(parent,children);␊ |
1134 | p=i+1;␊ |
1135 | }␊ |
1136 | g_token->name = paramTypes.mid(p);␊ |
1137 | handleLinkedWord(parent,children);␊ |
1138 | g_token->name = name;␊ |
1139 | }␊ |
1140 | ␊ |
1141 | ␊ |
1142 | /* Helper function that deals with the most common tokens allowed in␊ |
1143 | * title like sections. ␊ |
1144 | * @param parent Parent node, owner of the children list passed as ␊ |
1145 | * the third argument. ␊ |
1146 | * @param tok The token to process.␊ |
1147 | * @param children The list of child nodes to which the node representing␊ |
1148 | * the token can be added.␊ |
1149 | * @param handleWord Indicates if word token should be processed␊ |
1150 | * @retval TRUE The token was handled.␊ |
1151 | * @retval FALSE The token was not handled.␊ |
1152 | */␊ |
1153 | static bool defaultHandleToken(DocNode *parent,int tok, QList<DocNode> &children,bool␊ |
1154 | handleWord)␊ |
1155 | {␊ |
1156 | DBG(("token %s at %d",tokToString(tok),doctokenizerYYlineno));␊ |
1157 | if (tok==TK_WORD || tok==TK_LNKWORD || tok==TK_SYMBOL || tok==TK_URL || ␊ |
1158 | tok==TK_COMMAND || tok==TK_HTMLTAG␊ |
1159 | )␊ |
1160 | {␊ |
1161 | DBG((" name=%s",qPrint(g_token->name)));␊ |
1162 | }␊ |
1163 | DBG(("\n"));␊ |
1164 | reparsetoken:␊ |
1165 | QCString tokenName = g_token->name;␊ |
1166 | switch (tok)␊ |
1167 | {␊ |
1168 | case TK_COMMAND: ␊ |
1169 | switch (Mappers::cmdMapper->map(tokenName))␊ |
1170 | {␊ |
1171 | case CMD_BSLASH:␊ |
1172 | children.append(new DocSymbol(parent,DocSymbol::BSlash));␊ |
1173 | break;␊ |
1174 | case CMD_AT:␊ |
1175 | children.append(new DocSymbol(parent,DocSymbol::At));␊ |
1176 | break;␊ |
1177 | case CMD_LESS:␊ |
1178 | children.append(new DocSymbol(parent,DocSymbol::Less));␊ |
1179 | break;␊ |
1180 | case CMD_GREATER:␊ |
1181 | children.append(new DocSymbol(parent,DocSymbol::Greater));␊ |
1182 | break;␊ |
1183 | case CMD_AMP:␊ |
1184 | children.append(new DocSymbol(parent,DocSymbol::Amp));␊ |
1185 | break;␊ |
1186 | case CMD_DOLLAR:␊ |
1187 | children.append(new DocSymbol(parent,DocSymbol::Dollar));␊ |
1188 | break;␊ |
1189 | case CMD_HASH:␊ |
1190 | children.append(new DocSymbol(parent,DocSymbol::Hash));␊ |
1191 | break;␊ |
1192 | case CMD_DCOLON:␊ |
1193 | children.append(new DocSymbol(parent,DocSymbol::DoubleColon));␊ |
1194 | break;␊ |
1195 | case CMD_PERCENT:␊ |
1196 | children.append(new DocSymbol(parent,DocSymbol::Percent));␊ |
1197 | break;␊ |
1198 | case CMD_QUOTE:␊ |
1199 | children.append(new DocSymbol(parent,DocSymbol::Quot));␊ |
1200 | break;␊ |
1201 | case CMD_EMPHASIS:␊ |
1202 | {␊ |
1203 | children.append(new DocStyleChange(parent,g_nodeStack.count(),DocStyleChange::Italic,TRUE));␊ |
1204 | tok=handleStyleArgument(parent,children,tokenName);␊ |
1205 | children.append(new DocStyleChange(parent,g_nodeStack.count(),DocStyleChange::Italic,FALSE));␊ |
1206 | if (tok!=TK_WORD) children.append(new DocWhiteSpace(parent," "));␊ |
1207 | if (tok==TK_NEWPARA) goto handlepara;␊ |
1208 | else if (tok==TK_WORD || tok==TK_HTMLTAG) ␊ |
1209 | {␊ |
1210 | ␉ DBG(("CMD_EMPHASIS: reparsing command %s\n",qPrint(g_token->name)));␊ |
1211 | goto reparsetoken;␊ |
1212 | }␊ |
1213 | }␊ |
1214 | break;␊ |
1215 | case CMD_BOLD:␊ |
1216 | {␊ |
1217 | children.append(new DocStyleChange(parent,g_nodeStack.count(),DocStyleChange::Bold,TRUE));␊ |
1218 | tok=handleStyleArgument(parent,children,tokenName);␊ |
1219 | children.append(new DocStyleChange(parent,g_nodeStack.count(),DocStyleChange::Bold,FALSE));␊ |
1220 | if (tok!=TK_WORD) children.append(new DocWhiteSpace(parent," "));␊ |
1221 | if (tok==TK_NEWPARA) goto handlepara;␊ |
1222 | else if (tok==TK_WORD || tok==TK_HTMLTAG) ␊ |
1223 | {␊ |
1224 | ␉ DBG(("CMD_BOLD: reparsing command %s\n",qPrint(g_token->name)));␊ |
1225 | goto reparsetoken;␊ |
1226 | }␊ |
1227 | }␊ |
1228 | break;␊ |
1229 | case CMD_CODE:␊ |
1230 | {␊ |
1231 | children.append(new DocStyleChange(parent,g_nodeStack.count(),DocStyleChange::Code,TRUE));␊ |
1232 | tok=handleStyleArgument(parent,children,tokenName);␊ |
1233 | children.append(new DocStyleChange(parent,g_nodeStack.count(),DocStyleChange::Code,FALSE));␊ |
1234 | if (tok!=TK_WORD) children.append(new DocWhiteSpace(parent," "));␊ |
1235 | if (tok==TK_NEWPARA) goto handlepara;␊ |
1236 | else if (tok==TK_WORD || tok==TK_HTMLTAG) ␊ |
1237 | {␊ |
1238 | ␉ DBG(("CMD_CODE: reparsing command %s\n",qPrint(g_token->name)));␊ |
1239 | goto reparsetoken;␊ |
1240 | }␊ |
1241 | }␊ |
1242 | break;␊ |
1243 | case CMD_HTMLONLY:␊ |
1244 | {␊ |
1245 | doctokenizerYYsetStateHtmlOnly();␊ |
1246 | tok = doctokenizerYYlex();␊ |
1247 | children.append(new DocVerbatim(parent,g_context,g_token->verb,DocVerbatim::HtmlOnly,g_isExample,g_exampleName));␊ |
1248 | if (tok==0) warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: htmlonly section ended without end marker");␊ |
1249 | doctokenizerYYsetStatePara();␊ |
1250 | }␊ |
1251 | break;␊ |
1252 | case CMD_MANONLY:␊ |
1253 | {␊ |
1254 | doctokenizerYYsetStateManOnly();␊ |
1255 | tok = doctokenizerYYlex();␊ |
1256 | children.append(new DocVerbatim(parent,g_context,g_token->verb,DocVerbatim::ManOnly,g_isExample,g_exampleName));␊ |
1257 | if (tok==0) warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: manonly section ended without end marker");␊ |
1258 | doctokenizerYYsetStatePara();␊ |
1259 | }␊ |
1260 | break;␊ |
1261 | case CMD_LATEXONLY:␊ |
1262 | {␊ |
1263 | doctokenizerYYsetStateLatexOnly();␊ |
1264 | tok = doctokenizerYYlex();␊ |
1265 | children.append(new DocVerbatim(parent,g_context,g_token->verb,DocVerbatim::LatexOnly,g_isExample,g_exampleName));␊ |
1266 | if (tok==0) warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: latexonly section ended without end marker",doctokenizerYYlineno);␊ |
1267 | doctokenizerYYsetStatePara();␊ |
1268 | }␊ |
1269 | break;␊ |
1270 | case CMD_XMLONLY:␊ |
1271 | {␊ |
1272 | doctokenizerYYsetStateXmlOnly();␊ |
1273 | tok = doctokenizerYYlex();␊ |
1274 | children.append(new DocVerbatim(parent,g_context,g_token->verb,DocVerbatim::XmlOnly,g_isExample,g_exampleName));␊ |
1275 | if (tok==0) warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: xmlonly section ended without end marker",doctokenizerYYlineno);␊ |
1276 | doctokenizerYYsetStatePara();␊ |
1277 | }␊ |
1278 | break;␊ |
1279 | case CMD_FORMULA:␊ |
1280 | {␊ |
1281 | DocFormula *form=new DocFormula(parent,g_token->id);␊ |
1282 | children.append(form);␊ |
1283 | }␊ |
1284 | break;␊ |
1285 | case CMD_ANCHOR:␊ |
1286 | {␊ |
1287 | tok=doctokenizerYYlex();␊ |
1288 | if (tok!=TK_WHITESPACE)␊ |
1289 | {␊ |
1290 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: expected whitespace after %s command",␊ |
1291 | qPrint(tokenName));␊ |
1292 | break;␊ |
1293 | }␊ |
1294 | tok=doctokenizerYYlex();␊ |
1295 | if (tok==0)␊ |
1296 | {␊ |
1297 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: unexpected end of comment block while parsing the "␊ |
1298 | "argument of command %s",qPrint(tokenName));␊ |
1299 | break;␊ |
1300 | }␊ |
1301 | else if (tok!=TK_WORD && tok!=TK_LNKWORD)␊ |
1302 | {␊ |
1303 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: unexpected token %s as the argument of %s",␊ |
1304 | tokToString(tok),qPrint(tokenName));␊ |
1305 | break;␊ |
1306 | }␊ |
1307 | DocAnchor *anchor = new DocAnchor(parent,g_token->name,FALSE);␊ |
1308 | children.append(anchor);␊ |
1309 | }␊ |
1310 | break;␊ |
1311 | case CMD_INTERNALREF:␊ |
1312 | {␊ |
1313 | tok=doctokenizerYYlex();␊ |
1314 | if (tok!=TK_WHITESPACE)␊ |
1315 | {␊ |
1316 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: expected whitespace after %s command",␊ |
1317 | qPrint(tokenName));␊ |
1318 | break;␊ |
1319 | }␊ |
1320 | doctokenizerYYsetStateInternalRef();␊ |
1321 | tok=doctokenizerYYlex(); // get the reference id␊ |
1322 | DocInternalRef *ref=0;␊ |
1323 | if (tok!=TK_WORD && tok!=TK_LNKWORD)␊ |
1324 | {␊ |
1325 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: unexpected token %s as the argument of %s",␊ |
1326 | tokToString(tok),qPrint(tokenName));␊ |
1327 | doctokenizerYYsetStatePara();␊ |
1328 | break;␊ |
1329 | }␊ |
1330 | ref = new DocInternalRef(parent,g_token->name);␊ |
1331 | children.append(ref);␊ |
1332 | ref->parse();␊ |
1333 | doctokenizerYYsetStatePara();␊ |
1334 | }␊ |
1335 | break;␊ |
1336 | default:␊ |
1337 | return FALSE;␊ |
1338 | }␊ |
1339 | break;␊ |
1340 | case TK_HTMLTAG:␊ |
1341 | {␊ |
1342 | switch (Mappers::htmlTagMapper->map(tokenName))␊ |
1343 | {␊ |
1344 | case HTML_DIV:␊ |
1345 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: found <div> tag in heading\n");␊ |
1346 | break;␊ |
1347 | case HTML_PRE:␊ |
1348 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: found <pre> tag in heading\n");␊ |
1349 | break;␊ |
1350 | case HTML_BOLD:␊ |
1351 | if (!g_token->endTag)␊ |
1352 | {␊ |
1353 | handleStyleEnter(parent,children,DocStyleChange::Bold,&g_token->attribs);␊ |
1354 | }␊ |
1355 | else␊ |
1356 | {␊ |
1357 | handleStyleLeave(parent,children,DocStyleChange::Bold,tokenName);␊ |
1358 | }␊ |
1359 | break;␊ |
1360 | case HTML_CODE:␊ |
1361 | case XML_C:␊ |
1362 | if (!g_token->endTag)␊ |
1363 | {␊ |
1364 | handleStyleEnter(parent,children,DocStyleChange::Code,&g_token->attribs);␊ |
1365 | }␊ |
1366 | else␊ |
1367 | {␊ |
1368 | handleStyleLeave(parent,children,DocStyleChange::Code,tokenName);␊ |
1369 | }␊ |
1370 | break;␊ |
1371 | case HTML_EMPHASIS:␊ |
1372 | if (!g_token->endTag)␊ |
1373 | {␊ |
1374 | handleStyleEnter(parent,children,DocStyleChange::Italic,&g_token->attribs);␊ |
1375 | }␊ |
1376 | else␊ |
1377 | {␊ |
1378 | handleStyleLeave(parent,children,DocStyleChange::Italic,tokenName);␊ |
1379 | }␊ |
1380 | break;␊ |
1381 | case HTML_SUB:␊ |
1382 | if (!g_token->endTag)␊ |
1383 | {␊ |
1384 | handleStyleEnter(parent,children,DocStyleChange::Subscript,&g_token->attribs);␊ |
1385 | }␊ |
1386 | else␊ |
1387 | {␊ |
1388 | handleStyleLeave(parent,children,DocStyleChange::Subscript,tokenName);␊ |
1389 | }␊ |
1390 | break;␊ |
1391 | case HTML_SUP:␊ |
1392 | if (!g_token->endTag)␊ |
1393 | {␊ |
1394 | handleStyleEnter(parent,children,DocStyleChange::Superscript,&g_token->attribs);␊ |
1395 | }␊ |
1396 | else␊ |
1397 | {␊ |
1398 | handleStyleLeave(parent,children,DocStyleChange::Superscript,tokenName);␊ |
1399 | }␊ |
1400 | break;␊ |
1401 | case HTML_CENTER:␊ |
1402 | if (!g_token->endTag)␊ |
1403 | {␊ |
1404 | handleStyleEnter(parent,children,DocStyleChange::Center,&g_token->attribs);␊ |
1405 | }␊ |
1406 | else␊ |
1407 | {␊ |
1408 | handleStyleLeave(parent,children,DocStyleChange::Center,tokenName);␊ |
1409 | }␊ |
1410 | break;␊ |
1411 | case HTML_SMALL:␊ |
1412 | if (!g_token->endTag)␊ |
1413 | {␊ |
1414 | handleStyleEnter(parent,children,DocStyleChange::Small,&g_token->attribs);␊ |
1415 | }␊ |
1416 | else␊ |
1417 | {␊ |
1418 | handleStyleLeave(parent,children,DocStyleChange::Small,tokenName);␊ |
1419 | }␊ |
1420 | break;␊ |
1421 | default:␊ |
1422 | return FALSE;␊ |
1423 | break;␊ |
1424 | }␊ |
1425 | }␊ |
1426 | break;␊ |
1427 | case TK_SYMBOL: ␊ |
1428 | {␊ |
1429 | char letter='\0';␊ |
1430 | DocSymbol::SymType s = DocSymbol::decodeSymbol(tokenName,&letter);␊ |
1431 | if (s!=DocSymbol::Unknown)␊ |
1432 | {␊ |
1433 | children.append(new DocSymbol(parent,s,letter));␊ |
1434 | }␊ |
1435 | else␊ |
1436 | {␊ |
1437 | return FALSE;␊ |
1438 | }␊ |
1439 | }␊ |
1440 | break;␊ |
1441 | case TK_WHITESPACE: ␊ |
1442 | case TK_NEWPARA: ␊ |
1443 | handlepara:␊ |
1444 | if (insidePRE(parent) || !children.isEmpty())␊ |
1445 | {␊ |
1446 | children.append(new DocWhiteSpace(parent,g_token->chars));␊ |
1447 | }␊ |
1448 | break;␊ |
1449 | case TK_LNKWORD: ␊ |
1450 | if (handleWord)␊ |
1451 | {␊ |
1452 | handleLinkedWord(parent,children);␊ |
1453 | }␊ |
1454 | else␊ |
1455 | return FALSE;␊ |
1456 | break;␊ |
1457 | case TK_WORD: ␊ |
1458 | if (handleWord)␊ |
1459 | {␊ |
1460 | children.append(new DocWord(parent,g_token->name));␊ |
1461 | }␊ |
1462 | else␊ |
1463 | return FALSE;␊ |
1464 | break;␊ |
1465 | case TK_URL:␊ |
1466 | if (g_insideHtmlLink)␊ |
1467 | {␊ |
1468 | children.append(new DocWord(parent,g_token->name));␊ |
1469 | }␊ |
1470 | else␊ |
1471 | {␊ |
1472 | children.append(new DocURL(parent,g_token->name,g_token->isEMailAddr));␊ |
1473 | }␊ |
1474 | break;␊ |
1475 | default:␊ |
1476 | return FALSE;␊ |
1477 | }␊ |
1478 | return TRUE;␊ |
1479 | }␊ |
1480 | ␊ |
1481 | ␊ |
1482 | //---------------------------------------------------------------------------␊ |
1483 | ␊ |
1484 | DocSymbol::SymType DocSymbol::decodeSymbol(const QCString &symName,char *letter)␊ |
1485 | {␊ |
1486 | int l=symName.length();␊ |
1487 | DBG(("decodeSymbol(%s) l=%d\n",qPrint(symName),l));␊ |
1488 | if (symName=="©") return DocSymbol::Copy;␊ |
1489 | else if (symName=="™") return DocSymbol::Tm;␊ |
1490 | else if (symName=="&tm;") return DocSymbol::Tm; // alias for ™␊ |
1491 | else if (symName=="®") return DocSymbol::Reg;␊ |
1492 | else if (symName=="<") return DocSymbol::Less;␊ |
1493 | else if (symName==">") return DocSymbol::Greater;␊ |
1494 | else if (symName=="&") return DocSymbol::Amp;␊ |
1495 | else if (symName=="'") return DocSymbol::Apos;␊ |
1496 | else if (symName==""") return DocSymbol::Quot;␊ |
1497 | else if (symName=="‘") return DocSymbol::Lsquo;␊ |
1498 | else if (symName=="’") return DocSymbol::Rsquo;␊ |
1499 | else if (symName=="“") return DocSymbol::Ldquo;␊ |
1500 | else if (symName=="”") return DocSymbol::Rdquo;␊ |
1501 | else if (symName=="–") return DocSymbol::Ndash;␊ |
1502 | else if (symName=="—") return DocSymbol::Mdash;␊ |
1503 | else if (symName=="ß") return DocSymbol::Szlig;␊ |
1504 | else if (symName==" ") return DocSymbol::Nbsp;␊ |
1505 | else if (symName=="Æ") return DocSymbol::AElig;␊ |
1506 | else if (symName=="æ") return DocSymbol::Aelig;␊ |
1507 | else if (l==6 && symName.right(4)=="uml;") ␊ |
1508 | {␊ |
1509 | *letter=symName.at(1);␊ |
1510 | return DocSymbol::Uml;␊ |
1511 | }␊ |
1512 | else if (l==8 && symName.right(6)=="acute;") ␊ |
1513 | {␊ |
1514 | *letter=symName.at(1);␊ |
1515 | return DocSymbol::Acute;␊ |
1516 | }␊ |
1517 | else if (l==8 && symName.right(6)=="grave;")␊ |
1518 | {␊ |
1519 | *letter=symName.at(1);␊ |
1520 | return DocSymbol::Grave;␊ |
1521 | }␊ |
1522 | else if (l==7 && symName.right(5)=="circ;")␊ |
1523 | {␊ |
1524 | *letter=symName.at(1);␊ |
1525 | return DocSymbol::Circ;␊ |
1526 | }␊ |
1527 | else if (l==8 && symName.right(6)=="tilde;")␊ |
1528 | {␊ |
1529 | *letter=symName.at(1);␊ |
1530 | return DocSymbol::Tilde;␊ |
1531 | }␊ |
1532 | else if (l==8 && symName.right(6)=="cedil;")␊ |
1533 | {␊ |
1534 | *letter=symName.at(1);␊ |
1535 | return DocSymbol::Cedil;␊ |
1536 | }␊ |
1537 | else if (l==7 && symName.right(5)=="ring;")␊ |
1538 | {␊ |
1539 | *letter=symName.at(1);␊ |
1540 | return DocSymbol::Ring;␊ |
1541 | }␊ |
1542 | else if (l==8 && symName.right(6)=="slash;")␊ |
1543 | {␊ |
1544 | *letter=symName.at(1);␊ |
1545 | return DocSymbol::Slash;␊ |
1546 | }␊ |
1547 | return DocSymbol::Unknown;␊ |
1548 | }␊ |
1549 | ␊ |
1550 | //---------------------------------------------------------------------------␊ |
1551 | ␊ |
1552 | static int internalValidatingParseDoc(DocNode *parent,QList<DocNode> &children,␊ |
1553 | const QCString &doc)␊ |
1554 | {␊ |
1555 | int retval = RetVal_OK;␊ |
1556 | ␊ |
1557 | if (doc.isEmpty()) return retval;␊ |
1558 | ␊ |
1559 | doctokenizerYYinit(doc,g_fileName);␊ |
1560 | ␊ |
1561 | // first parse any number of paragraphs␊ |
1562 | bool isFirst=TRUE;␊ |
1563 | DocPara *lastPar=0;␊ |
1564 | if (!children.isEmpty() && children.last()->kind()==DocNode::Kind_Para)␊ |
1565 | { // last child item was a paragraph␊ |
1566 | lastPar = (DocPara*)children.last();␊ |
1567 | isFirst=FALSE;␊ |
1568 | }␊ |
1569 | do␊ |
1570 | {␊ |
1571 | DocPara *par = new DocPara(parent);␊ |
1572 | if (isFirst) { par->markFirst(); isFirst=FALSE; }␊ |
1573 | retval=par->parse();␊ |
1574 | if (!par->isEmpty()) ␊ |
1575 | {␊ |
1576 | children.append(par);␊ |
1577 | if (lastPar) lastPar->markLast(FALSE);␊ |
1578 | lastPar=par;␊ |
1579 | }␊ |
1580 | else␊ |
1581 | {␊ |
1582 | delete par;␊ |
1583 | }␊ |
1584 | } while (retval==TK_NEWPARA);␊ |
1585 | if (lastPar) lastPar->markLast();␊ |
1586 | ␊ |
1587 | return retval;␊ |
1588 | }␊ |
1589 | ␊ |
1590 | //---------------------------------------------------------------------------␊ |
1591 | ␊ |
1592 | static void readTextFileByName(const QCString &file,QCString &text)␊ |
1593 | {␊ |
1594 | QStrList &examplePathList = Config_getList("EXAMPLE_PATH");␊ |
1595 | char *s=examplePathList.first();␊ |
1596 | while (s)␊ |
1597 | {␊ |
1598 | QCString absFileName = QCString(s)+portable_pathSeparator()+file;␊ |
1599 | QFileInfo fi(absFileName);␊ |
1600 | if (fi.exists())␊ |
1601 | {␊ |
1602 | text = fileToString(absFileName,Config_getBool("FILTER_SOURCE_FILES"));␊ |
1603 | return;␊ |
1604 | }␊ |
1605 | s=examplePathList.next(); ␊ |
1606 | }␊ |
1607 | ␊ |
1608 | // as a fallback we also look in the exampleNameDict␊ |
1609 | bool ambig;␊ |
1610 | FileDef *fd;␊ |
1611 | if ((fd=findFileDef(Doxygen::exampleNameDict,file,ambig)))␊ |
1612 | {␊ |
1613 | text = fileToString(fd->absFilePath(),Config_getBool("FILTER_SOURCE_FILES"));␊ |
1614 | }␊ |
1615 | else if (ambig)␊ |
1616 | {␊ |
1617 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: included file name %s is ambiguous"␊ |
1618 | "Possible candidates:\n%s",qPrint(file),␊ |
1619 | qPrint(showFileDefMatches(Doxygen::exampleNameDict,file))␊ |
1620 | );␊ |
1621 | }␊ |
1622 | else␊ |
1623 | {␊ |
1624 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: included file %s is not found. "␊ |
1625 | "Check your EXAMPLE_PATH",qPrint(file));␊ |
1626 | }␊ |
1627 | }␊ |
1628 | ␊ |
1629 | //---------------------------------------------------------------------------␊ |
1630 | ␊ |
1631 | DocWord::DocWord(DocNode *parent,const QCString &word) : ␊ |
1632 | m_word(word) ␊ |
1633 | {␊ |
1634 | m_parent = parent; ␊ |
1635 | //printf("new word %s url=%s\n",word.data(),g_searchUrl.data());␊ |
1636 | if (Doxygen::searchIndex && !g_searchUrl.isEmpty())␊ |
1637 | {␊ |
1638 | Doxygen::searchIndex->addWord(word,FALSE);␊ |
1639 | }␊ |
1640 | }␊ |
1641 | ␊ |
1642 | //---------------------------------------------------------------------------␊ |
1643 | ␊ |
1644 | DocLinkedWord::DocLinkedWord(DocNode *parent,const QCString &word,␊ |
1645 | const QCString &ref,const QCString &file,␊ |
1646 | const QCString &anchor,const QCString &tooltip) : ␊ |
1647 | m_word(word), m_ref(ref), ␊ |
1648 | m_file(file), m_relPath(g_relPath), m_anchor(anchor),␊ |
1649 | m_tooltip(tooltip)␊ |
1650 | {␊ |
1651 | m_parent = parent; ␊ |
1652 | //printf("DocLinkedWord: new word %s url=%s tooltip='%s'\n",␊ |
1653 | // word.data(),g_searchUrl.data(),tooltip.data());␊ |
1654 | if (Doxygen::searchIndex && !g_searchUrl.isEmpty())␊ |
1655 | {␊ |
1656 | Doxygen::searchIndex->addWord(word,FALSE);␊ |
1657 | }␊ |
1658 | }␊ |
1659 | ␊ |
1660 | //---------------------------------------------------------------------------␊ |
1661 | ␊ |
1662 | DocAnchor::DocAnchor(DocNode *parent,const QCString &id,bool newAnchor) ␊ |
1663 | {␊ |
1664 | m_parent = parent; ␊ |
1665 | if (id.isEmpty())␊ |
1666 | {␊ |
1667 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Empty anchor label");␊ |
1668 | }␊ |
1669 | if (newAnchor) // found <a name="label">␊ |
1670 | {␊ |
1671 | m_anchor = id;␊ |
1672 | }␊ |
1673 | else // found \anchor label␊ |
1674 | {␊ |
1675 | SectionInfo *sec = Doxygen::sectionDict[id];␊ |
1676 | if (sec)␊ |
1677 | {␊ |
1678 | //printf("Found anchor %s\n",id.data());␊ |
1679 | m_file = sec->fileName;␊ |
1680 | m_anchor = sec->label;␊ |
1681 | if (g_sectionDict && g_sectionDict->find(id)==0)␊ |
1682 | {␊ |
1683 | //printf("Inserting in dictionary!\n");␊ |
1684 | g_sectionDict->insert(id,sec);␊ |
1685 | }␊ |
1686 | }␊ |
1687 | else␊ |
1688 | {␊ |
1689 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Invalid anchor id `%s'",qPrint(id));␊ |
1690 | m_anchor = "invalid";␊ |
1691 | m_file = "invalid";␊ |
1692 | }␊ |
1693 | }␊ |
1694 | }␊ |
1695 | ␊ |
1696 | //---------------------------------------------------------------------------␊ |
1697 | ␊ |
1698 | DocVerbatim::DocVerbatim(DocNode *parent,const QCString &context,␊ |
1699 | const QCString &text, Type t,bool isExample,␊ |
1700 | const QCString &exampleFile) ␊ |
1701 | : m_context(context), m_text(text), m_type(t),␊ |
1702 | m_isExample(isExample), m_exampleFile(exampleFile), m_relPath(g_relPath) ␊ |
1703 | { ␊ |
1704 | m_parent = parent; ␊ |
1705 | }␊ |
1706 | ␊ |
1707 | ␊ |
1708 | //---------------------------------------------------------------------------␊ |
1709 | ␊ |
1710 | void DocInclude::parse()␊ |
1711 | {␊ |
1712 | DBG(("DocInclude::parse(file=%s,text=%s)\n",qPrint(m_file),qPrint(m_text)));␊ |
1713 | switch(m_type)␊ |
1714 | {␊ |
1715 | case IncWithLines:␊ |
1716 | // fall through␊ |
1717 | case Include:␊ |
1718 | // fall through␊ |
1719 | case DontInclude:␊ |
1720 | readTextFileByName(m_file,m_text);␊ |
1721 | g_includeFileText = m_text;␊ |
1722 | g_includeFileOffset = 0;␊ |
1723 | g_includeFileLength = m_text.length();␊ |
1724 | //printf("g_includeFile=<<%s>>\n",g_includeFileText.data());␊ |
1725 | break;␊ |
1726 | case VerbInclude: ␊ |
1727 | // fall through␊ |
1728 | case HtmlInclude:␊ |
1729 | readTextFileByName(m_file,m_text);␊ |
1730 | break;␊ |
1731 | }␊ |
1732 | }␊ |
1733 | ␊ |
1734 | //---------------------------------------------------------------------------␊ |
1735 | ␊ |
1736 | void DocIncOperator::parse()␊ |
1737 | {␊ |
1738 | const char *p = g_includeFileText;␊ |
1739 | uint l = g_includeFileLength;␊ |
1740 | uint o = g_includeFileOffset;␊ |
1741 | DBG(("DocIncOperator::parse() text=%s off=%d len=%d\n",qPrint(p),o,l));␊ |
1742 | uint so = o,bo;␊ |
1743 | bool nonEmpty = FALSE;␊ |
1744 | switch(type())␊ |
1745 | {␊ |
1746 | case Line:␊ |
1747 | while (o<l)␊ |
1748 | {␊ |
1749 | char c = p[o];␊ |
1750 | if (c=='\n') ␊ |
1751 | {␊ |
1752 | if (nonEmpty) break; // we have a pattern to match␊ |
1753 | so=o+1; // no pattern, skip empty line␊ |
1754 | }␊ |
1755 | else if (!isspace((uchar)c)) // no white space char␊ |
1756 | {␊ |
1757 | nonEmpty=TRUE;␊ |
1758 | }␊ |
1759 | o++;␊ |
1760 | }␊ |
1761 | if (g_includeFileText.mid(so,o-so).find(m_pattern)!=-1)␊ |
1762 | {␊ |
1763 | m_text = g_includeFileText.mid(so,o-so);␊ |
1764 | DBG(("DocIncOperator::parse() Line: %s\n",qPrint(m_text)));␊ |
1765 | }␊ |
1766 | g_includeFileOffset = QMIN(l,o+1); // set pointer to start of new line␊ |
1767 | break;␊ |
1768 | case SkipLine:␊ |
1769 | while (o<l)␊ |
1770 | {␊ |
1771 | so=o;␊ |
1772 | while (o<l)␊ |
1773 | {␊ |
1774 | char c = p[o];␊ |
1775 | if (c=='\n')␊ |
1776 | {␊ |
1777 | if (nonEmpty) break; // we have a pattern to match␊ |
1778 | so=o+1; // no pattern, skip empty line␊ |
1779 | }␊ |
1780 | else if (!isspace((uchar)c)) // no white space char␊ |
1781 | {␊ |
1782 | nonEmpty=TRUE;␊ |
1783 | }␊ |
1784 | o++;␊ |
1785 | }␊ |
1786 | if (g_includeFileText.mid(so,o-so).find(m_pattern)!=-1)␊ |
1787 | {␊ |
1788 | m_text = g_includeFileText.mid(so,o-so);␊ |
1789 | DBG(("DocIncOperator::parse() SkipLine: %s\n",qPrint(m_text)));␊ |
1790 | break;␊ |
1791 | }␊ |
1792 | o++; // skip new line␊ |
1793 | }␊ |
1794 | g_includeFileOffset = QMIN(l,o+1); // set pointer to start of new line␊ |
1795 | break;␊ |
1796 | case Skip:␊ |
1797 | while (o<l)␊ |
1798 | {␊ |
1799 | so=o;␊ |
1800 | while (o<l)␊ |
1801 | {␊ |
1802 | char c = p[o];␊ |
1803 | if (c=='\n')␊ |
1804 | {␊ |
1805 | if (nonEmpty) break; // we have a pattern to match␊ |
1806 | so=o+1; // no pattern, skip empty line␊ |
1807 | }␊ |
1808 | else if (!isspace((uchar)c)) // no white space char␊ |
1809 | {␊ |
1810 | nonEmpty=TRUE;␊ |
1811 | }␊ |
1812 | o++;␊ |
1813 | }␊ |
1814 | if (g_includeFileText.mid(so,o-so).find(m_pattern)!=-1)␊ |
1815 | {␊ |
1816 | break;␊ |
1817 | }␊ |
1818 | o++; // skip new line␊ |
1819 | }␊ |
1820 | g_includeFileOffset = so; // set pointer to start of new line␊ |
1821 | break;␊ |
1822 | case Until:␊ |
1823 | bo=o;␊ |
1824 | while (o<l)␊ |
1825 | {␊ |
1826 | so=o;␊ |
1827 | while (o<l)␊ |
1828 | {␊ |
1829 | char c = p[o];␊ |
1830 | if (c=='\n')␊ |
1831 | {␊ |
1832 | if (nonEmpty) break; // we have a pattern to match␊ |
1833 | so=o+1; // no pattern, skip empty line␊ |
1834 | }␊ |
1835 | else if (!isspace((uchar)c)) // no white space char␊ |
1836 | {␊ |
1837 | nonEmpty=TRUE;␊ |
1838 | }␊ |
1839 | o++;␊ |
1840 | }␊ |
1841 | if (g_includeFileText.mid(so,o-so).find(m_pattern)!=-1)␊ |
1842 | {␊ |
1843 | m_text = g_includeFileText.mid(bo,o-bo);␊ |
1844 | DBG(("DocIncOperator::parse() Until: %s\n",qPrint(m_text)));␊ |
1845 | break;␊ |
1846 | }␊ |
1847 | o++; // skip new line␊ |
1848 | }␊ |
1849 | g_includeFileOffset = QMIN(l,o+1); // set pointer to start of new line␊ |
1850 | break;␊ |
1851 | }␊ |
1852 | }␊ |
1853 | ␊ |
1854 | //---------------------------------------------------------------------------␊ |
1855 | ␊ |
1856 | void DocCopy::parse()␊ |
1857 | {␊ |
1858 | QCString doc,brief;␊ |
1859 | Definition *def;␊ |
1860 | if (findDocsForMemberOrCompound(m_link,&doc,&brief,&def))␊ |
1861 | {␊ |
1862 | if (g_copyStack.findRef(def)==-1) // definition not parsed earlier␊ |
1863 | {␊ |
1864 | bool hasParamCommand = g_hasParamCommand;␊ |
1865 | bool hasReturnCommand = g_hasReturnCommand;␊ |
1866 | QDict<void> paramsFound = g_paramsFound;␊ |
1867 | //printf("..1 hasParamCommand=%d hasReturnCommand=%d paramsFound=%d\n",␊ |
1868 | // g_hasParamCommand,g_hasReturnCommand,g_paramsFound.count());␊ |
1869 | ␊ |
1870 | docParserPushContext(FALSE);␊ |
1871 | g_scope = def;␊ |
1872 | if (def->definitionType()==Definition::TypeMember && def->getOuterScope())␊ |
1873 | {␊ |
1874 | if (def->getOuterScope()!=Doxygen::globalScope)␊ |
1875 | {␊ |
1876 | g_context=def->getOuterScope()->name();␊ |
1877 | }␊ |
1878 | }␊ |
1879 | else if (def!=Doxygen::globalScope)␊ |
1880 | {␊ |
1881 | g_context=def->name();␊ |
1882 | }␊ |
1883 | g_styleStack.clear();␊ |
1884 | g_nodeStack.clear();␊ |
1885 | g_paramsFound.clear();␊ |
1886 | g_copyStack.append(def);␊ |
1887 | // make sure the descriptions end with a newline, so the parser will correctly␊ |
1888 | // handle them in all cases.␊ |
1889 | //printf("doc='%s'\n",doc.data());␊ |
1890 | //printf("brief='%s'\n",brief.data());␊ |
1891 | if (m_copyBrief)␊ |
1892 | {␊ |
1893 | brief+='\n';␊ |
1894 | internalValidatingParseDoc(this,m_children,brief);␊ |
1895 | ␊ |
1896 | //printf("..2 hasParamCommand=%d hasReturnCommand=%d paramsFound=%d\n",␊ |
1897 | // g_hasParamCommand,g_hasReturnCommand,g_paramsFound.count());␊ |
1898 | hasParamCommand = hasParamCommand || g_hasParamCommand;␊ |
1899 | hasReturnCommand = hasReturnCommand || g_hasReturnCommand;␊ |
1900 | QDictIterator<void> it(g_paramsFound);␊ |
1901 | void *item;␊ |
1902 | for (;(item=it.current());++it)␊ |
1903 | {␊ |
1904 | paramsFound.insert(it.currentKey(),it.current());␊ |
1905 | }␊ |
1906 | }␊ |
1907 | if (m_copyDetails)␊ |
1908 | {␊ |
1909 | doc+='\n';␊ |
1910 | internalValidatingParseDoc(this,m_children,doc);␊ |
1911 | ␊ |
1912 | //printf("..3 hasParamCommand=%d hasReturnCommand=%d paramsFound=%d\n",␊ |
1913 | // g_hasParamCommand,g_hasReturnCommand,g_paramsFound.count());␊ |
1914 | hasParamCommand = hasParamCommand || g_hasParamCommand;␊ |
1915 | hasReturnCommand = hasReturnCommand || g_hasReturnCommand;␊ |
1916 | QDictIterator<void> it(g_paramsFound);␊ |
1917 | void *item;␊ |
1918 | for (;(item=it.current());++it)␊ |
1919 | {␊ |
1920 | paramsFound.insert(it.currentKey(),it.current());␊ |
1921 | }␊ |
1922 | }␊ |
1923 | g_copyStack.remove(def);␊ |
1924 | ASSERT(g_styleStack.isEmpty());␊ |
1925 | ASSERT(g_nodeStack.isEmpty());␊ |
1926 | docParserPopContext(TRUE);␊ |
1927 | ␊ |
1928 | g_hasParamCommand = hasParamCommand;␊ |
1929 | g_hasReturnCommand = hasReturnCommand;␊ |
1930 | g_paramsFound = paramsFound;␊ |
1931 | ␊ |
1932 | //printf("..4 hasParamCommand=%d hasReturnCommand=%d paramsFound=%d\n",␊ |
1933 | // g_hasParamCommand,g_hasReturnCommand,g_paramsFound.count());␊ |
1934 | }␊ |
1935 | else // oops, recursion␊ |
1936 | {␊ |
1937 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: recursive call chain of \\copydoc commands detected at %d\n",␊ |
1938 | doctokenizerYYlineno);␊ |
1939 | }␊ |
1940 | }␊ |
1941 | else␊ |
1942 | {␊ |
1943 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: target %s of \\copydoc command not found",␊ |
1944 | qPrint(m_link));␊ |
1945 | }␊ |
1946 | }␊ |
1947 | ␊ |
1948 | //---------------------------------------------------------------------------␊ |
1949 | ␊ |
1950 | DocXRefItem::DocXRefItem(DocNode *parent,int id,const char *key) : ␊ |
1951 | m_id(id), m_key(key), m_relPath(g_relPath)␊ |
1952 | {␊ |
1953 | m_parent = parent; ␊ |
1954 | }␊ |
1955 | ␊ |
1956 | bool DocXRefItem::parse()␊ |
1957 | {␊ |
1958 | QCString listName;␊ |
1959 | RefList *refList = Doxygen::xrefLists->find(m_key); ␊ |
1960 | if (refList && ␊ |
1961 | (␊ |
1962 | // either not a built-in list or the list is enabled␊ |
1963 | (m_key!="todo" || Config_getBool("GENERATE_TODOLIST")) && ␊ |
1964 | (m_key!="test" || Config_getBool("GENERATE_TESTLIST")) && ␊ |
1965 | (m_key!="bug" || Config_getBool("GENERATE_BUGLIST")) && ␊ |
1966 | (m_key!="deprecated" || Config_getBool("GENERATE_DEPRECATEDLIST"))␊ |
1967 | ) ␊ |
1968 | )␊ |
1969 | {␊ |
1970 | RefItem *item = refList->getRefItem(m_id);␊ |
1971 | ASSERT(item!=0);␊ |
1972 | if (item)␊ |
1973 | {␊ |
1974 | if (g_memberDef && g_memberDef->name().at(0)=='@')␊ |
1975 | {␊ |
1976 | m_file = "@"; // can't cross reference anonymous enum␊ |
1977 | m_anchor = "@";␊ |
1978 | }␊ |
1979 | else␊ |
1980 | {␊ |
1981 | m_file = convertNameToFile(refList->listName(),FALSE,TRUE);␊ |
1982 | m_anchor = item->listAnchor;␊ |
1983 | }␊ |
1984 | m_title = refList->sectionTitle();␊ |
1985 | //printf("DocXRefItem: file=%s anchor=%s title=%s\n",␊ |
1986 | // m_file.data(),m_anchor.data(),m_title.data());␊ |
1987 | ␊ |
1988 | if (!item->text.isEmpty())␊ |
1989 | {␊ |
1990 | docParserPushContext();␊ |
1991 | internalValidatingParseDoc(this,m_children,item->text);␊ |
1992 | docParserPopContext();␊ |
1993 | }␊ |
1994 | }␊ |
1995 | return TRUE;␊ |
1996 | }␊ |
1997 | return FALSE;␊ |
1998 | }␊ |
1999 | ␊ |
2000 | //---------------------------------------------------------------------------␊ |
2001 | ␊ |
2002 | DocFormula::DocFormula(DocNode *parent,int id) :␊ |
2003 | m_relPath(g_relPath)␊ |
2004 | {␊ |
2005 | m_parent = parent; ␊ |
2006 | QCString formCmd;␊ |
2007 | formCmd.sprintf("\\form#%d",id);␊ |
2008 | Formula *formula=Doxygen::formulaNameDict[formCmd];␊ |
2009 | if (formula)␊ |
2010 | {␊ |
2011 | m_id = formula->getId();␊ |
2012 | m_name.sprintf("form_%d",m_id);␊ |
2013 | m_text = formula->getFormulaText();␊ |
2014 | }␊ |
2015 | }␊ |
2016 | ␊ |
2017 | //---------------------------------------------------------------------------␊ |
2018 | ␊ |
2019 | //int DocLanguage::parse()␊ |
2020 | //{␊ |
2021 | // int retval;␊ |
2022 | // DBG(("DocLanguage::parse() start\n"));␊ |
2023 | // g_nodeStack.push(this);␊ |
2024 | //␊ |
2025 | // // parse one or more paragraphs␊ |
2026 | // bool isFirst=TRUE;␊ |
2027 | // DocPara *par=0;␊ |
2028 | // do␊ |
2029 | // {␊ |
2030 | // par = new DocPara(this);␊ |
2031 | // if (isFirst) { par->markFirst(); isFirst=FALSE; }␊ |
2032 | // m_children.append(par);␊ |
2033 | // retval=par->parse();␊ |
2034 | // }␊ |
2035 | // while (retval==TK_NEWPARA);␊ |
2036 | // if (par) par->markLast();␊ |
2037 | //␊ |
2038 | // DBG(("DocLanguage::parse() end\n"));␊ |
2039 | // DocNode *n = g_nodeStack.pop();␊ |
2040 | // ASSERT(n==this);␊ |
2041 | // return retval;␊ |
2042 | //}␊ |
2043 | ␊ |
2044 | //---------------------------------------------------------------------------␊ |
2045 | ␊ |
2046 | void DocSecRefItem::parse()␊ |
2047 | {␊ |
2048 | DBG(("DocSecRefItem::parse() start\n"));␊ |
2049 | g_nodeStack.push(this);␊ |
2050 | ␊ |
2051 | doctokenizerYYsetStateTitle();␊ |
2052 | int tok;␊ |
2053 | while ((tok=doctokenizerYYlex()))␊ |
2054 | {␊ |
2055 | if (!defaultHandleToken(this,tok,m_children))␊ |
2056 | {␊ |
2057 | switch (tok)␊ |
2058 | {␊ |
2059 | case TK_COMMAND: ␊ |
2060 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Illegal command %s as part of a \\refitem",␊ |
2061 | ␉ qPrint(g_token->name));␊ |
2062 | break;␊ |
2063 | case TK_SYMBOL: ␊ |
2064 | ␉ warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Unsupported symbol %s found",␊ |
2065 | qPrint(g_token->name));␊ |
2066 | break;␊ |
2067 | default:␊ |
2068 | ␉ warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Unexpected token %s",␊ |
2069 | ␉ tokToString(tok));␊ |
2070 | break;␊ |
2071 | }␊ |
2072 | }␊ |
2073 | }␊ |
2074 | doctokenizerYYsetStatePara();␊ |
2075 | handlePendingStyleCommands(this,m_children);␊ |
2076 | ␊ |
2077 | SectionInfo *sec=0;␊ |
2078 | if (!m_target.isEmpty())␊ |
2079 | {␊ |
2080 | sec=Doxygen::sectionDict[m_target];␊ |
2081 | if (sec)␊ |
2082 | {␊ |
2083 | m_file = sec->fileName;␊ |
2084 | m_anchor = sec->label;␊ |
2085 | if (g_sectionDict && g_sectionDict->find(m_target)==0)␊ |
2086 | {␊ |
2087 | g_sectionDict->insert(m_target,sec);␊ |
2088 | }␊ |
2089 | }␊ |
2090 | else␊ |
2091 | {␊ |
2092 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: reference to unknown section %s",␊ |
2093 | qPrint(m_target));␊ |
2094 | }␊ |
2095 | } ␊ |
2096 | else␊ |
2097 | {␊ |
2098 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: reference to empty target");␊ |
2099 | }␊ |
2100 | ␊ |
2101 | DBG(("DocSecRefItem::parse() end\n"));␊ |
2102 | DocNode *n = g_nodeStack.pop();␊ |
2103 | ASSERT(n==this);␊ |
2104 | }␊ |
2105 | ␊ |
2106 | //---------------------------------------------------------------------------␊ |
2107 | ␊ |
2108 | void DocSecRefList::parse()␊ |
2109 | {␊ |
2110 | DBG(("DocSecRefList::parse() start\n"));␊ |
2111 | g_nodeStack.push(this);␊ |
2112 | ␊ |
2113 | int tok=doctokenizerYYlex();␊ |
2114 | // skip white space␊ |
2115 | while (tok==TK_WHITESPACE || tok==TK_NEWPARA) tok=doctokenizerYYlex();␊ |
2116 | // handle items␊ |
2117 | while (tok)␊ |
2118 | {␊ |
2119 | if (tok==TK_COMMAND)␊ |
2120 | {␊ |
2121 | switch (Mappers::cmdMapper->map(g_token->name))␊ |
2122 | {␊ |
2123 | case CMD_SECREFITEM:␊ |
2124 | {␊ |
2125 | int tok=doctokenizerYYlex();␊ |
2126 | if (tok!=TK_WHITESPACE)␊ |
2127 | {␊ |
2128 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: expected whitespace after \\refitem command");␊ |
2129 | break;␊ |
2130 | }␊ |
2131 | tok=doctokenizerYYlex();␊ |
2132 | if (tok!=TK_WORD && tok!=TK_LNKWORD)␊ |
2133 | {␊ |
2134 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: unexpected token %s as the argument of \\refitem",␊ |
2135 | tokToString(tok));␊ |
2136 | break;␊ |
2137 | }␊ |
2138 | ␊ |
2139 | DocSecRefItem *item = new DocSecRefItem(this,g_token->name);␊ |
2140 | m_children.append(item);␊ |
2141 | item->parse();␊ |
2142 | }␊ |
2143 | break;␊ |
2144 | case CMD_ENDSECREFLIST:␊ |
2145 | goto endsecreflist;␊ |
2146 | default:␊ |
2147 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Illegal command %s as part of a \\secreflist",␊ |
2148 | qPrint(g_token->name));␊ |
2149 | goto endsecreflist;␊ |
2150 | }␊ |
2151 | }␊ |
2152 | else if (tok==TK_WHITESPACE)␊ |
2153 | {␊ |
2154 | // ignore whitespace␊ |
2155 | }␊ |
2156 | else␊ |
2157 | {␊ |
2158 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Unexpected token %s inside section reference list",␊ |
2159 | tokToString(tok));␊ |
2160 | goto endsecreflist;␊ |
2161 | }␊ |
2162 | tok=doctokenizerYYlex();␊ |
2163 | }␊ |
2164 | ␊ |
2165 | endsecreflist:␊ |
2166 | DBG(("DocSecRefList::parse() end\n"));␊ |
2167 | DocNode *n = g_nodeStack.pop();␊ |
2168 | ASSERT(n==this);␊ |
2169 | }␊ |
2170 | ␊ |
2171 | //---------------------------------------------------------------------------␊ |
2172 | ␊ |
2173 | DocInternalRef::DocInternalRef(DocNode *parent,const QCString &ref) ␊ |
2174 | : m_relPath(g_relPath)␊ |
2175 | {␊ |
2176 | m_parent = parent; ␊ |
2177 | int i=ref.find('#');␊ |
2178 | if (i!=-1)␊ |
2179 | {␊ |
2180 | m_anchor = ref.right(ref.length()-i-1);␊ |
2181 | m_file = ref.left(i);␊ |
2182 | }␊ |
2183 | else␊ |
2184 | {␊ |
2185 | m_file = ref;␊ |
2186 | }␊ |
2187 | }␊ |
2188 | ␊ |
2189 | void DocInternalRef::parse()␊ |
2190 | {␊ |
2191 | g_nodeStack.push(this);␊ |
2192 | DBG(("DocInternalRef::parse() start\n"));␊ |
2193 | ␊ |
2194 | int tok;␊ |
2195 | while ((tok=doctokenizerYYlex()))␊ |
2196 | {␊ |
2197 | if (!defaultHandleToken(this,tok,m_children))␊ |
2198 | {␊ |
2199 | switch (tok)␊ |
2200 | {␊ |
2201 | case TK_COMMAND: ␊ |
2202 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Illegal command %s as part of a \\ref",␊ |
2203 | ␉ qPrint(g_token->name));␊ |
2204 | break;␊ |
2205 | case TK_SYMBOL: ␊ |
2206 | ␉ warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Unsupported symbol %s found",␊ |
2207 | qPrint(g_token->name));␊ |
2208 | break;␊ |
2209 | default:␊ |
2210 | ␉ warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Unexpected token %s",␊ |
2211 | ␉␉tokToString(tok));␊ |
2212 | break;␊ |
2213 | }␊ |
2214 | }␊ |
2215 | }␊ |
2216 | ␊ |
2217 | handlePendingStyleCommands(this,m_children);␊ |
2218 | DBG(("DocInternalRef::parse() end\n"));␊ |
2219 | DocNode *n=g_nodeStack.pop();␊ |
2220 | ASSERT(n==this);␊ |
2221 | }␊ |
2222 | ␊ |
2223 | //---------------------------------------------------------------------------␊ |
2224 | ␊ |
2225 | DocRef::DocRef(DocNode *parent,const QCString &target,const QCString &context) : ␊ |
2226 | m_refToSection(FALSE), m_refToAnchor(FALSE)␊ |
2227 | {␊ |
2228 | m_parent = parent; ␊ |
2229 | Definition *compound = 0;␊ |
2230 | QCString anchor;␊ |
2231 | //printf("DocRef::DocRef(target=%s,context=%s\n",target.data(),context.data());␊ |
2232 | ASSERT(!target.isEmpty());␊ |
2233 | m_relPath = g_relPath;␊ |
2234 | SectionInfo *sec = Doxygen::sectionDict[target];␊ |
2235 | if (sec) // ref to section or anchor␊ |
2236 | {␊ |
2237 | m_text = sec->title;␊ |
2238 | if (m_text.isEmpty()) m_text = sec->label;␊ |
2239 | ␊ |
2240 | m_ref = sec->ref;␊ |
2241 | m_file = stripKnownExtensions(sec->fileName);␊ |
2242 | if (sec->type!=SectionInfo::Page) m_anchor = sec->label;␊ |
2243 | m_refToAnchor = sec->type==SectionInfo::Anchor;␊ |
2244 | m_refToSection = sec->type!=SectionInfo::Anchor;␊ |
2245 | //printf("m_text=%s,m_ref=%s,m_file=%s,m_refToAnchor=%d type=%d\n",␊ |
2246 | // m_text.data(),m_ref.data(),m_file.data(),m_refToAnchor,sec->type);␊ |
2247 | return;␊ |
2248 | }␊ |
2249 | else if (resolveLink(context,target,TRUE,&compound,anchor))␊ |
2250 | {␊ |
2251 | bool isFile = compound ? ␊ |
2252 | (compound->definitionType()==Definition::TypeFile ? TRUE : FALSE) : ␊ |
2253 | FALSE;␊ |
2254 | m_text = linkToText(target,isFile);␊ |
2255 | m_anchor = anchor;␊ |
2256 | if (compound && compound->isLinkable()) // ref to compound␊ |
2257 | {␊ |
2258 | if (anchor.isEmpty() && /* compound link */␊ |
2259 | compound->definitionType()==Definition::TypeGroup && /* is group */␊ |
2260 | ((GroupDef *)compound)->groupTitle() /* with title */␊ |
2261 | )␊ |
2262 | {␊ |
2263 | m_text=((GroupDef *)compound)->groupTitle(); // use group's title as link␊ |
2264 | }␊ |
2265 | else if (compound->definitionType()==Definition::TypeMember &&␊ |
2266 | ((MemberDef*)compound)->isObjCMethod())␊ |
2267 | {␊ |
2268 | // Objective C Method␊ |
2269 | MemberDef *member = (MemberDef*)compound;␊ |
2270 | bool localLink = g_memberDef ? member->getClassDef()==g_memberDef->getClassDef() : FALSE;␊ |
2271 | m_text = member->objCMethodName(localLink,g_inSeeBlock);␊ |
2272 | }␊ |
2273 | ␊ |
2274 | m_file = compound->getOutputFileBase();␊ |
2275 | m_ref = compound->getReference();␊ |
2276 | return;␊ |
2277 | }␊ |
2278 | else if (compound->definitionType()==Definition::TypeFile && ␊ |
2279 | ((FileDef*)compound)->generateSourceFile()␊ |
2280 | ) // undocumented file that has source code we can link to␊ |
2281 | {␊ |
2282 | m_file = compound->getSourceFileBase();␊ |
2283 | m_ref = compound->getReference();␊ |
2284 | return;␊ |
2285 | }␊ |
2286 | }␊ |
2287 | m_text = linkToText(target,FALSE);␊ |
2288 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: unable to resolve reference to `%s' for \\ref command",␊ |
2289 | qPrint(target)); ␊ |
2290 | }␊ |
2291 | ␊ |
2292 | static void flattenParagraphs(DocNode *root,QList<DocNode> &children)␊ |
2293 | {␊ |
2294 | QListIterator<DocNode> li(children);␊ |
2295 | QList<DocNode> newChildren;␊ |
2296 | DocNode *dn;␊ |
2297 | for (li.toFirst();(dn=li.current());++li)␊ |
2298 | {␊ |
2299 | if (dn->kind()==DocNode::Kind_Para)␊ |
2300 | {␊ |
2301 | DocPara *para = (DocPara*)dn;␊ |
2302 | QList<DocNode> ¶Children = para->children();␊ |
2303 | paraChildren.setAutoDelete(FALSE); // unlink children from paragraph node␊ |
2304 | QListIterator<DocNode> li2(paraChildren);␊ |
2305 | DocNode *dn2;␊ |
2306 | for (li2.toFirst();(dn2=li2.current());++li2)␊ |
2307 | {␊ |
2308 | newChildren.append(dn2); // add them to new node␊ |
2309 | }␊ |
2310 | }␊ |
2311 | }␊ |
2312 | children.clear();␊ |
2313 | QListIterator<DocNode> li3(newChildren);␊ |
2314 | for (li3.toFirst();(dn=li3.current());++li3)␊ |
2315 | {␊ |
2316 | children.append(dn);␊ |
2317 | dn->setParent(root);␊ |
2318 | }␊ |
2319 | }␊ |
2320 | ␊ |
2321 | void DocRef::parse()␊ |
2322 | {␊ |
2323 | g_nodeStack.push(this);␊ |
2324 | DBG(("DocRef::parse() start\n"));␊ |
2325 | ␊ |
2326 | int tok;␊ |
2327 | while ((tok=doctokenizerYYlex()))␊ |
2328 | {␊ |
2329 | if (!defaultHandleToken(this,tok,m_children))␊ |
2330 | {␊ |
2331 | switch (tok)␊ |
2332 | {␊ |
2333 | case TK_COMMAND: ␊ |
2334 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Illegal command %s as part of a \\ref",␊ |
2335 | ␉ qPrint(g_token->name));␊ |
2336 | break;␊ |
2337 | case TK_SYMBOL: ␊ |
2338 | ␉ warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Unsupported symbol %s found",␊ |
2339 | qPrint(g_token->name));␊ |
2340 | break;␊ |
2341 | case TK_HTMLTAG:␊ |
2342 | break;␊ |
2343 | default:␊ |
2344 | ␉ warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Unexpected token %s",␊ |
2345 | ␉␉tokToString(tok));␊ |
2346 | break;␊ |
2347 | }␊ |
2348 | }␊ |
2349 | }␊ |
2350 | ␊ |
2351 | if (m_children.isEmpty() && !m_text.isEmpty())␊ |
2352 | {␊ |
2353 | g_insideHtmlLink=TRUE;␊ |
2354 | docParserPushContext();␊ |
2355 | internalValidatingParseDoc(this,m_children,m_text);␊ |
2356 | docParserPopContext();␊ |
2357 | g_insideHtmlLink=FALSE;␊ |
2358 | flattenParagraphs(this,m_children);␊ |
2359 | }␊ |
2360 | ␊ |
2361 | handlePendingStyleCommands(this,m_children);␊ |
2362 | ␊ |
2363 | DocNode *n=g_nodeStack.pop();␊ |
2364 | ASSERT(n==this);␊ |
2365 | }␊ |
2366 | ␊ |
2367 | //---------------------------------------------------------------------------␊ |
2368 | ␊ |
2369 | DocLink::DocLink(DocNode *parent,const QCString &target) ␊ |
2370 | {␊ |
2371 | m_parent = parent; ␊ |
2372 | Definition *compound;␊ |
2373 | //PageInfo *page;␊ |
2374 | QCString anchor;␊ |
2375 | m_refText = target;␊ |
2376 | m_relPath = g_relPath;␊ |
2377 | if (!m_refText.isEmpty() && m_refText.at(0)=='#')␊ |
2378 | {␊ |
2379 | m_refText = m_refText.right(m_refText.length()-1);␊ |
2380 | }␊ |
2381 | if (resolveLink(g_context,stripKnownExtensions(target),g_inSeeBlock,␊ |
2382 | &compound,anchor))␊ |
2383 | {␊ |
2384 | m_anchor = anchor;␊ |
2385 | if (compound && compound->isLinkable())␊ |
2386 | {␊ |
2387 | m_file = compound->getOutputFileBase();␊ |
2388 | m_ref = compound->getReference();␊ |
2389 | }␊ |
2390 | else if (compound->definitionType()==Definition::TypeFile && ␊ |
2391 | ((FileDef*)compound)->generateSourceFile()␊ |
2392 | ) // undocumented file that has source code we can link to␊ |
2393 | {␊ |
2394 | m_file = compound->getSourceFileBase();␊ |
2395 | m_ref = compound->getReference();␊ |
2396 | }␊ |
2397 | return;␊ |
2398 | }␊ |
2399 | ␊ |
2400 | // bogus link target␊ |
2401 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: unable to resolve link to `%s' for \\link command",␊ |
2402 | qPrint(target)); ␊ |
2403 | }␊ |
2404 | ␊ |
2405 | ␊ |
2406 | QCString DocLink::parse(bool isJavaLink,bool isXmlLink)␊ |
2407 | {␊ |
2408 | QCString result;␊ |
2409 | g_nodeStack.push(this);␊ |
2410 | DBG(("DocLink::parse() start\n"));␊ |
2411 | ␊ |
2412 | int tok;␊ |
2413 | while ((tok=doctokenizerYYlex()))␊ |
2414 | {␊ |
2415 | if (!defaultHandleToken(this,tok,m_children,FALSE))␊ |
2416 | {␊ |
2417 | switch (tok)␊ |
2418 | {␊ |
2419 | case TK_COMMAND: ␊ |
2420 | switch (Mappers::cmdMapper->map(g_token->name))␊ |
2421 | {␊ |
2422 | case CMD_ENDLINK:␊ |
2423 | if (isJavaLink)␊ |
2424 | {␊ |
2425 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: {@link.. ended with @endlink command");␊ |
2426 | }␊ |
2427 | goto endlink;␊ |
2428 | default:␊ |
2429 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Illegal command %s as part of a \\link",␊ |
2430 | qPrint(g_token->name));␊ |
2431 | break;␊ |
2432 | }␊ |
2433 | break;␊ |
2434 | case TK_SYMBOL: ␊ |
2435 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Unsupported symbol %s found",␊ |
2436 | qPrint(g_token->name));␊ |
2437 | break;␊ |
2438 | case TK_HTMLTAG:␊ |
2439 | if (g_token->name!="see" || !isXmlLink)␊ |
2440 | {␊ |
2441 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Unexpected xml/html command %s found",␊ |
2442 | qPrint(g_token->name));␊ |
2443 | }␊ |
2444 | goto endlink;␊ |
2445 | case TK_LNKWORD: ␊ |
2446 | case TK_WORD: ␊ |
2447 | if (isJavaLink) // special case to detect closing }␊ |
2448 | {␊ |
2449 | QCString w = g_token->name;␊ |
2450 | int p;␊ |
2451 | if (w=="}")␊ |
2452 | {␊ |
2453 | goto endlink;␊ |
2454 | }␊ |
2455 | else if ((p=w.find('}'))!=-1)␊ |
2456 | {␊ |
2457 | uint l=w.length();␊ |
2458 | m_children.append(new DocWord(this,w.left(p)));␊ |
2459 | if ((uint)p<l-1) // something left after the } (for instance a .)␊ |
2460 | {␊ |
2461 | result=w.right(l-p-1);␊ |
2462 | }␊ |
2463 | goto endlink;␊ |
2464 | }␊ |
2465 | }␊ |
2466 | m_children.append(new DocWord(this,g_token->name));␊ |
2467 | break;␊ |
2468 | default:␊ |
2469 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Unexpected token %s",␊ |
2470 | tokToString(tok));␊ |
2471 | break;␊ |
2472 | }␊ |
2473 | }␊ |
2474 | }␊ |
2475 | if (tok==0)␊ |
2476 | {␊ |
2477 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Unexpected end of comment while inside"␊ |
2478 | " link command\n"); ␊ |
2479 | }␊ |
2480 | endlink:␊ |
2481 | ␊ |
2482 | if (m_children.isEmpty()) // no link text␊ |
2483 | {␊ |
2484 | m_children.append(new DocWord(this,m_refText));␊ |
2485 | }␊ |
2486 | ␊ |
2487 | handlePendingStyleCommands(this,m_children);␊ |
2488 | DBG(("DocLink::parse() end\n"));␊ |
2489 | DocNode *n=g_nodeStack.pop();␊ |
2490 | ASSERT(n==this);␊ |
2491 | return result;␊ |
2492 | }␊ |
2493 | ␊ |
2494 | ␊ |
2495 | //---------------------------------------------------------------------------␊ |
2496 | ␊ |
2497 | DocDotFile::DocDotFile(DocNode *parent,const QCString &name,const QCString &context) : ␊ |
2498 | m_name(name), m_relPath(g_relPath), m_context(context)␊ |
2499 | {␊ |
2500 | m_parent = parent; ␊ |
2501 | }␊ |
2502 | ␊ |
2503 | void DocDotFile::parse()␊ |
2504 | {␊ |
2505 | g_nodeStack.push(this);␊ |
2506 | DBG(("DocDotFile::parse() start\n"));␊ |
2507 | ␊ |
2508 | doctokenizerYYsetStateTitle();␊ |
2509 | int tok;␊ |
2510 | while ((tok=doctokenizerYYlex()))␊ |
2511 | {␊ |
2512 | if (!defaultHandleToken(this,tok,m_children))␊ |
2513 | {␊ |
2514 | switch (tok)␊ |
2515 | {␊ |
2516 | case TK_COMMAND: ␊ |
2517 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Illegal command %s as part of a \\dotfile",␊ |
2518 | ␉ qPrint(g_token->name));␊ |
2519 | break;␊ |
2520 | case TK_SYMBOL: ␊ |
2521 | ␉ warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Unsupported symbol %s found",␊ |
2522 | qPrint(g_token->name));␊ |
2523 | break;␊ |
2524 | default:␊ |
2525 | ␉ warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Unexpected token %s",␊ |
2526 | ␉␉tokToString(tok));␊ |
2527 | break;␊ |
2528 | }␊ |
2529 | }␊ |
2530 | }␊ |
2531 | tok=doctokenizerYYlex();␊ |
2532 | while (tok==TK_WORD) // there are values following the title␊ |
2533 | {␊ |
2534 | if (g_token->name=="width") ␊ |
2535 | {␊ |
2536 | m_width=g_token->chars;␊ |
2537 | }␊ |
2538 | else if (g_token->name=="height") ␊ |
2539 | {␊ |
2540 | m_height=g_token->chars;␊ |
2541 | }␊ |
2542 | else ␊ |
2543 | {␊ |
2544 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Unknown option %s after image title",␊ |
2545 | qPrint(g_token->name));␊ |
2546 | }␊ |
2547 | tok=doctokenizerYYlex();␊ |
2548 | }␊ |
2549 | ASSERT(tok==0);␊ |
2550 | doctokenizerYYsetStatePara();␊ |
2551 | handlePendingStyleCommands(this,m_children);␊ |
2552 | ␊ |
2553 | bool ambig;␊ |
2554 | FileDef *fd = findFileDef(Doxygen::dotFileNameDict,m_name,ambig);␊ |
2555 | if (fd==0 && m_name.right(4)!=".dot") // try with .dot extension as well␊ |
2556 | {␊ |
2557 | fd = findFileDef(Doxygen::dotFileNameDict,m_name+".dot",ambig);␊ |
2558 | }␊ |
2559 | if (fd)␊ |
2560 | {␊ |
2561 | m_file = fd->absFilePath();␊ |
2562 | }␊ |
2563 | else if (ambig)␊ |
2564 | {␊ |
2565 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: included dot file name %s is ambiguous.\n"␊ |
2566 | "Possible candidates:\n%s",qPrint(m_name),␊ |
2567 | qPrint(showFileDefMatches(Doxygen::exampleNameDict,m_name))␊ |
2568 | );␊ |
2569 | }␊ |
2570 | else␊ |
2571 | {␊ |
2572 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: included dot file %s is not found "␊ |
2573 | "in any of the paths specified via DOTFILE_DIRS!",qPrint(m_name));␊ |
2574 | }␊ |
2575 | ␊ |
2576 | DBG(("DocDotFile::parse() end\n"));␊ |
2577 | DocNode *n=g_nodeStack.pop();␊ |
2578 | ASSERT(n==this);␊ |
2579 | }␊ |
2580 | ␊ |
2581 | DocMscFile::DocMscFile(DocNode *parent,const QCString &name,const QCString &context) : ␊ |
2582 | m_name(name), m_relPath(g_relPath), m_context(context)␊ |
2583 | {␊ |
2584 | m_parent = parent; ␊ |
2585 | }␊ |
2586 | ␊ |
2587 | void DocMscFile::parse()␊ |
2588 | {␊ |
2589 | g_nodeStack.push(this);␊ |
2590 | DBG(("DocMscFile::parse() start\n"));␊ |
2591 | ␊ |
2592 | doctokenizerYYsetStateTitle();␊ |
2593 | int tok;␊ |
2594 | while ((tok=doctokenizerYYlex()))␊ |
2595 | {␊ |
2596 | if (!defaultHandleToken(this,tok,m_children))␊ |
2597 | {␊ |
2598 | switch (tok)␊ |
2599 | {␊ |
2600 | case TK_COMMAND: ␊ |
2601 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Illegal command %s as part of a \\mscfile",␊ |
2602 | ␉ qPrint(g_token->name));␊ |
2603 | break;␊ |
2604 | case TK_SYMBOL: ␊ |
2605 | ␉ warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Unsupported symbol %s found",␊ |
2606 | qPrint(g_token->name));␊ |
2607 | break;␊ |
2608 | default:␊ |
2609 | ␉ warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Unexpected token %s",␊ |
2610 | ␉␉tokToString(tok));␊ |
2611 | break;␊ |
2612 | }␊ |
2613 | }␊ |
2614 | }␊ |
2615 | tok=doctokenizerYYlex();␊ |
2616 | while (tok==TK_WORD) // there are values following the title␊ |
2617 | {␊ |
2618 | if (g_token->name=="width") ␊ |
2619 | {␊ |
2620 | m_width=g_token->chars;␊ |
2621 | }␊ |
2622 | else if (g_token->name=="height") ␊ |
2623 | {␊ |
2624 | m_height=g_token->chars;␊ |
2625 | }␊ |
2626 | else ␊ |
2627 | {␊ |
2628 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Unknown option %s after image title",␊ |
2629 | qPrint(g_token->name));␊ |
2630 | }␊ |
2631 | tok=doctokenizerYYlex();␊ |
2632 | }␊ |
2633 | ASSERT(tok==0);␊ |
2634 | doctokenizerYYsetStatePara();␊ |
2635 | handlePendingStyleCommands(this,m_children);␊ |
2636 | ␊ |
2637 | bool ambig;␊ |
2638 | FileDef *fd = findFileDef(Doxygen::mscFileNameDict,m_name,ambig);␊ |
2639 | if (fd==0 && m_name.right(4)!=".msc") // try with .msc extension as well␊ |
2640 | {␊ |
2641 | fd = findFileDef(Doxygen::mscFileNameDict,m_name+".msc",ambig);␊ |
2642 | }␊ |
2643 | if (fd)␊ |
2644 | {␊ |
2645 | m_file = fd->absFilePath();␊ |
2646 | }␊ |
2647 | else if (ambig)␊ |
2648 | {␊ |
2649 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: included msc file name %s is ambiguous.\n"␊ |
2650 | "Possible candidates:\n%s",qPrint(m_name),␊ |
2651 | qPrint(showFileDefMatches(Doxygen::exampleNameDict,m_name))␊ |
2652 | );␊ |
2653 | }␊ |
2654 | else␊ |
2655 | {␊ |
2656 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: included msc file %s is not found "␊ |
2657 | "in any of the paths specified via MSCFILE_DIRS!",qPrint(m_name));␊ |
2658 | }␊ |
2659 | ␊ |
2660 | DBG(("DocMscFile::parse() end\n"));␊ |
2661 | DocNode *n=g_nodeStack.pop();␊ |
2662 | ASSERT(n==this);␊ |
2663 | }␊ |
2664 | ␊ |
2665 | ␊ |
2666 | ␊ |
2667 | //---------------------------------------------------------------------------␊ |
2668 | ␊ |
2669 | DocImage::DocImage(DocNode *parent,const HtmlAttribList &attribs,const QCString &name,Type t) : ␊ |
2670 | m_attribs(attribs), m_name(name), ␊ |
2671 | m_type(t), m_relPath(g_relPath)␊ |
2672 | {␊ |
2673 | m_parent = parent;␊ |
2674 | }␊ |
2675 | ␊ |
2676 | void DocImage::parse()␊ |
2677 | {␊ |
2678 | g_nodeStack.push(this);␊ |
2679 | DBG(("DocImage::parse() start\n"));␊ |
2680 | ␊ |
2681 | // parse title␊ |
2682 | doctokenizerYYsetStateTitle();␊ |
2683 | int tok;␊ |
2684 | while ((tok=doctokenizerYYlex()))␊ |
2685 | {␊ |
2686 | if (tok==TK_WORD && (g_token->name=="width=" || g_token->name=="height="))␊ |
2687 | {␊ |
2688 | // special case: no title, but we do have a size indicator␊ |
2689 | doctokenizerYYsetStateTitleAttrValue();␊ |
2690 | // strip =␊ |
2691 | g_token->name=g_token->name.left(g_token->name.length()-1);␊ |
2692 | break;␊ |
2693 | } ␊ |
2694 | if (!defaultHandleToken(this,tok,m_children))␊ |
2695 | {␊ |
2696 | switch (tok)␊ |
2697 | {␊ |
2698 | case TK_COMMAND: ␊ |
2699 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Illegal command %s as part of a \\image",␊ |
2700 | qPrint(g_token->name));␊ |
2701 | break;␊ |
2702 | case TK_SYMBOL: ␊ |
2703 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Unsupported symbol %s found",␊ |
2704 | qPrint(g_token->name));␊ |
2705 | break;␊ |
2706 | default:␊ |
2707 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Unexpected token %s",␊ |
2708 | tokToString(tok));␊ |
2709 | break;␊ |
2710 | }␊ |
2711 | }␊ |
2712 | }␊ |
2713 | // parse size attributes␊ |
2714 | tok=doctokenizerYYlex();␊ |
2715 | while (tok==TK_WORD) // there are values following the title␊ |
2716 | {␊ |
2717 | if (g_token->name=="width") ␊ |
2718 | {␊ |
2719 | m_width=g_token->chars;␊ |
2720 | }␊ |
2721 | else if (g_token->name=="height") ␊ |
2722 | {␊ |
2723 | m_height=g_token->chars;␊ |
2724 | }␊ |
2725 | else ␊ |
2726 | {␊ |
2727 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Unknown option %s after image title",␊ |
2728 | qPrint(g_token->name));␊ |
2729 | }␊ |
2730 | tok=doctokenizerYYlex();␊ |
2731 | }␊ |
2732 | doctokenizerYYsetStatePara();␊ |
2733 | ␊ |
2734 | handlePendingStyleCommands(this,m_children);␊ |
2735 | DBG(("DocImage::parse() end\n"));␊ |
2736 | DocNode *n=g_nodeStack.pop();␊ |
2737 | ASSERT(n==this);␊ |
2738 | }␊ |
2739 | ␊ |
2740 | ␊ |
2741 | //---------------------------------------------------------------------------␊ |
2742 | ␊ |
2743 | int DocHtmlHeader::parse()␊ |
2744 | {␊ |
2745 | int retval=RetVal_OK;␊ |
2746 | g_nodeStack.push(this);␊ |
2747 | DBG(("DocHtmlHeader::parse() start\n"));␊ |
2748 | ␊ |
2749 | int tok;␊ |
2750 | while ((tok=doctokenizerYYlex()))␊ |
2751 | {␊ |
2752 | if (!defaultHandleToken(this,tok,m_children))␊ |
2753 | {␊ |
2754 | switch (tok)␊ |
2755 | {␊ |
2756 | case TK_COMMAND: ␊ |
2757 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Illegal command %s as part of a <h%d> tag",␊ |
2758 | ␉ qPrint(g_token->name),m_level);␊ |
2759 | break;␊ |
2760 | case TK_HTMLTAG:␊ |
2761 | {␊ |
2762 | int tagId=Mappers::htmlTagMapper->map(g_token->name);␊ |
2763 | if (tagId==HTML_H1 && g_token->endTag) // found </h1> tag␊ |
2764 | {␊ |
2765 | if (m_level!=1)␊ |
2766 | {␊ |
2767 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: <h%d> ended with </h1>",␊ |
2768 | m_level); ␊ |
2769 | }␊ |
2770 | goto endheader;␊ |
2771 | }␊ |
2772 | else if (tagId==HTML_H2 && g_token->endTag) // found </h2> tag␊ |
2773 | {␊ |
2774 | if (m_level!=2)␊ |
2775 | {␊ |
2776 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: <h%d> ended with </h2>",␊ |
2777 | m_level); ␊ |
2778 | }␊ |
2779 | goto endheader;␊ |
2780 | }␊ |
2781 | else if (tagId==HTML_H3 && g_token->endTag) // found </h3> tag␊ |
2782 | {␊ |
2783 | if (m_level!=3)␊ |
2784 | {␊ |
2785 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: <h%d> ended with </h3>",␊ |
2786 | m_level); ␊ |
2787 | }␊ |
2788 | goto endheader;␊ |
2789 | }␊ |
2790 | else if (tagId==HTML_H4 && g_token->endTag) // found </h4> tag␊ |
2791 | {␊ |
2792 | if (m_level!=4)␊ |
2793 | {␊ |
2794 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: <h%d> ended with </h4>",␊ |
2795 | m_level); ␊ |
2796 | }␊ |
2797 | goto endheader;␊ |
2798 | }␊ |
2799 | else if (tagId==HTML_H5 && g_token->endTag) // found </h5> tag␊ |
2800 | {␊ |
2801 | if (m_level!=5)␊ |
2802 | {␊ |
2803 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: <h%d> ended with </h5>",␊ |
2804 | m_level); ␊ |
2805 | }␊ |
2806 | goto endheader;␊ |
2807 | }␊ |
2808 | else if (tagId==HTML_H6 && g_token->endTag) // found </h6> tag␊ |
2809 | {␊ |
2810 | if (m_level!=6)␊ |
2811 | {␊ |
2812 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: <h%d> ended with </h6>",␊ |
2813 | m_level); ␊ |
2814 | }␊ |
2815 | goto endheader;␊ |
2816 | }␊ |
2817 | else if (tagId==HTML_A)␊ |
2818 | {␊ |
2819 | if (!g_token->endTag)␊ |
2820 | {␊ |
2821 | handleAHref(this,m_children,g_token->attribs);␊ |
2822 | }␊ |
2823 | }␊ |
2824 | else if (tagId==HTML_BR)␊ |
2825 | {␊ |
2826 | DocLineBreak *lb = new DocLineBreak(this);␊ |
2827 | m_children.append(lb);␊ |
2828 | }␊ |
2829 | else␊ |
2830 | {␊ |
2831 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Unexpected html tag <%s%s> found within <h%d> context",␊ |
2832 | g_token->endTag?"/":"",qPrint(g_token->name),m_level);␊ |
2833 | }␊ |
2834 | ␊ |
2835 | }␊ |
2836 | break;␊ |
2837 | case TK_SYMBOL: ␊ |
2838 | ␉ warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Unsupported symbol %s found",␊ |
2839 | qPrint(g_token->name));␊ |
2840 | break;␊ |
2841 | default:␊ |
2842 | ␉ warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Unexpected token %s",␊ |
2843 | ␉␉tokToString(tok));␊ |
2844 | break;␊ |
2845 | }␊ |
2846 | }␊ |
2847 | }␊ |
2848 | if (tok==0)␊ |
2849 | {␊ |
2850 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Unexpected end of comment while inside"␊ |
2851 | " <h%d> tag\n",m_level); ␊ |
2852 | }␊ |
2853 | endheader:␊ |
2854 | handlePendingStyleCommands(this,m_children);␊ |
2855 | DBG(("DocHtmlHeader::parse() end\n"));␊ |
2856 | DocNode *n=g_nodeStack.pop();␊ |
2857 | ASSERT(n==this);␊ |
2858 | return retval;␊ |
2859 | }␊ |
2860 | ␊ |
2861 | //---------------------------------------------------------------------------␊ |
2862 | ␊ |
2863 | int DocHRef::parse()␊ |
2864 | {␊ |
2865 | int retval=RetVal_OK;␊ |
2866 | g_nodeStack.push(this);␊ |
2867 | DBG(("DocHRef::parse() start\n"));␊ |
2868 | ␊ |
2869 | int tok;␊ |
2870 | while ((tok=doctokenizerYYlex()))␊ |
2871 | {␊ |
2872 | if (!defaultHandleToken(this,tok,m_children))␊ |
2873 | {␊ |
2874 | switch (tok)␊ |
2875 | {␊ |
2876 | case TK_COMMAND: ␊ |
2877 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Illegal command %s as part of a <a>..</a> block",␊ |
2878 | ␉ qPrint(g_token->name));␊ |
2879 | break;␊ |
2880 | case TK_SYMBOL: ␊ |
2881 | ␉ warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Unsupported symbol %s found",␊ |
2882 | qPrint(g_token->name));␊ |
2883 | break;␊ |
2884 | case TK_HTMLTAG:␊ |
2885 | {␊ |
2886 | int tagId=Mappers::htmlTagMapper->map(g_token->name);␊ |
2887 | if (tagId==HTML_A && g_token->endTag) // found </a> tag␊ |
2888 | {␊ |
2889 | goto endhref;␊ |
2890 | }␊ |
2891 | else␊ |
2892 | {␊ |
2893 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Unexpected html tag <%s%s> found within <a href=...> context",␊ |
2894 | g_token->endTag?"/":"",qPrint(g_token->name),doctokenizerYYlineno);␊ |
2895 | }␊ |
2896 | }␊ |
2897 | break;␊ |
2898 | default:␊ |
2899 | ␉ warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Unexpected token %s",␊ |
2900 | ␉␉tokToString(tok),doctokenizerYYlineno);␊ |
2901 | break;␊ |
2902 | }␊ |
2903 | }␊ |
2904 | }␊ |
2905 | if (tok==0)␊ |
2906 | {␊ |
2907 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Unexpected end of comment while inside"␊ |
2908 | " <a href=...> tag",doctokenizerYYlineno); ␊ |
2909 | }␊ |
2910 | endhref:␊ |
2911 | handlePendingStyleCommands(this,m_children);␊ |
2912 | DBG(("DocHRef::parse() end\n"));␊ |
2913 | DocNode *n=g_nodeStack.pop();␊ |
2914 | ASSERT(n==this);␊ |
2915 | return retval;␊ |
2916 | }␊ |
2917 | ␊ |
2918 | //---------------------------------------------------------------------------␊ |
2919 | ␊ |
2920 | int DocInternal::parse(int level)␊ |
2921 | {␊ |
2922 | int retval=RetVal_OK;␊ |
2923 | g_nodeStack.push(this);␊ |
2924 | DBG(("DocInternal::parse() start\n"));␊ |
2925 | ␊ |
2926 | // first parse any number of paragraphs␊ |
2927 | bool isFirst=TRUE;␊ |
2928 | DocPara *lastPar=0;␊ |
2929 | do␊ |
2930 | {␊ |
2931 | DocPara *par = new DocPara(this);␊ |
2932 | if (isFirst) { par->markFirst(); isFirst=FALSE; }␊ |
2933 | retval=par->parse();␊ |
2934 | if (!par->isEmpty()) ␊ |
2935 | {␊ |
2936 | m_children.append(par);␊ |
2937 | lastPar=par;␊ |
2938 | }␊ |
2939 | else␊ |
2940 | {␊ |
2941 | delete par;␊ |
2942 | }␊ |
2943 | if (retval==TK_LISTITEM)␊ |
2944 | {␊ |
2945 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Invalid list item found",doctokenizerYYlineno);␊ |
2946 | }␊ |
2947 | } while (retval!=0 && ␊ |
2948 | retval!=RetVal_Section &&␊ |
2949 | retval!=RetVal_Subsection &&␊ |
2950 | retval!=RetVal_Subsubsection &&␊ |
2951 | retval!=RetVal_Paragraph␊ |
2952 | );␊ |
2953 | if (lastPar) lastPar->markLast();␊ |
2954 | ␊ |
2955 | // then parse any number of level-n sections␊ |
2956 | while ((level==1 && retval==RetVal_Section) || ␊ |
2957 | (level==2 && retval==RetVal_Subsection) ||␊ |
2958 | (level==3 && retval==RetVal_Subsubsection) ||␊ |
2959 | (level==4 && retval==RetVal_Paragraph)␊ |
2960 | )␊ |
2961 | {␊ |
2962 | DocSection *s=new DocSection(this,␊ |
2963 | QMIN(level+Doxygen::subpageNestingLevel,5),g_token->sectionId);␊ |
2964 | m_children.append(s);␊ |
2965 | retval = s->parse();␊ |
2966 | }␊ |
2967 | ␊ |
2968 | if (retval==RetVal_Internal)␊ |
2969 | {␊ |
2970 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: \\internal command found inside internal section");␊ |
2971 | }␊ |
2972 | ␊ |
2973 | DBG(("DocInternal::parse() end\n"));␊ |
2974 | DocNode *n=g_nodeStack.pop();␊ |
2975 | ASSERT(n==this);␊ |
2976 | return retval;␊ |
2977 | }␊ |
2978 | ␊ |
2979 | //---------------------------------------------------------------------------␊ |
2980 | ␊ |
2981 | int DocIndexEntry::parse()␊ |
2982 | {␊ |
2983 | int retval=RetVal_OK;␊ |
2984 | g_nodeStack.push(this);␊ |
2985 | DBG(("DocIndexEntry::parse() start\n"));␊ |
2986 | int tok=doctokenizerYYlex();␊ |
2987 | if (tok!=TK_WHITESPACE)␊ |
2988 | {␊ |
2989 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: expected whitespace after \\addindex command");␊ |
2990 | goto endindexentry;␊ |
2991 | }␊ |
2992 | doctokenizerYYsetStateTitle();␊ |
2993 | m_entry="";␊ |
2994 | while ((tok=doctokenizerYYlex()))␊ |
2995 | {␊ |
2996 | switch (tok)␊ |
2997 | {␊ |
2998 | case TK_WHITESPACE:␊ |
2999 | m_entry+=" ";␊ |
3000 | break;␊ |
3001 | case TK_WORD: ␊ |
3002 | case TK_LNKWORD: ␊ |
3003 | m_entry+=g_token->name;␊ |
3004 | break;␊ |
3005 | case TK_SYMBOL:␊ |
3006 | {␊ |
3007 | char letter='\0';␊ |
3008 | DocSymbol::SymType s = DocSymbol::decodeSymbol(g_token->name,&letter);␊ |
3009 | switch (s)␊ |
3010 | {␊ |
3011 | case DocSymbol::BSlash: m_entry+='\\'; break;␊ |
3012 | case DocSymbol::At: m_entry+='@'; break;␊ |
3013 | case DocSymbol::Less: m_entry+='<'; break;␊ |
3014 | case DocSymbol::Greater: m_entry+='>'; break;␊ |
3015 | case DocSymbol::Amp: m_entry+='&'; break;␊ |
3016 | case DocSymbol::Dollar: m_entry+='$'; break;␊ |
3017 | case DocSymbol::Hash: m_entry+='#'; break;␊ |
3018 | case DocSymbol::Percent: m_entry+='%'; break;␊ |
3019 | case DocSymbol::Apos: m_entry+='\''; break;␊ |
3020 | case DocSymbol::Quot: m_entry+='"'; break;␊ |
3021 | case DocSymbol::Lsquo: m_entry+='`'; break;␊ |
3022 | case DocSymbol::Rsquo: m_entry+='\''; break;␊ |
3023 | case DocSymbol::Ldquo: m_entry+="``"; break;␊ |
3024 | case DocSymbol::Rdquo: m_entry+="''"; break;␊ |
3025 | case DocSymbol::Ndash: m_entry+="--"; break;␊ |
3026 | case DocSymbol::Mdash: m_entry+="---"; break;␊ |
3027 | default:␊ |
3028 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Unexpected symbol found as argument of \\addindex");␊ |
3029 | break;␊ |
3030 | }␊ |
3031 | }␊ |
3032 | break;␊ |
3033 | case TK_COMMAND: ␊ |
3034 | switch (Mappers::cmdMapper->map(g_token->name))␊ |
3035 | {␊ |
3036 | case CMD_BSLASH: m_entry+='\\'; break;␊ |
3037 | case CMD_AT: m_entry+='@'; break;␊ |
3038 | case CMD_LESS: m_entry+='<'; break;␊ |
3039 | case CMD_GREATER: m_entry+='>'; break;␊ |
3040 | case CMD_AMP: m_entry+='&'; break;␊ |
3041 | case CMD_DOLLAR: m_entry+='$'; break;␊ |
3042 | case CMD_HASH: m_entry+='#'; break;␊ |
3043 | case CMD_DCOLON: m_entry+="::"; break;␊ |
3044 | case CMD_PERCENT: m_entry+='%'; break;␊ |
3045 | case CMD_QUOTE: m_entry+='"'; break;␊ |
3046 | default:␊ |
3047 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Unexpected command %s found as argument of \\addindex",␊ |
3048 | qPrint(g_token->name));␊ |
3049 | break;␊ |
3050 | }␊ |
3051 | break;␊ |
3052 | default:␊ |
3053 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Unexpected token %s",␊ |
3054 | tokToString(tok));␊ |
3055 | break;␊ |
3056 | }␊ |
3057 | }␊ |
3058 | if (tok!=0) retval=tok;␊ |
3059 | doctokenizerYYsetStatePara();␊ |
3060 | m_entry = m_entry.stripWhiteSpace();␊ |
3061 | endindexentry:␊ |
3062 | DBG(("DocIndexEntry::parse() end retval=%x\n",retval));␊ |
3063 | DocNode *n=g_nodeStack.pop();␊ |
3064 | ASSERT(n==this);␊ |
3065 | return retval;␊ |
3066 | }␊ |
3067 | ␊ |
3068 | //---------------------------------------------------------------------------␊ |
3069 | ␊ |
3070 | int DocHtmlCaption::parse()␊ |
3071 | {␊ |
3072 | int retval=0;␊ |
3073 | g_nodeStack.push(this);␊ |
3074 | DBG(("DocHtmlCaption::parse() start\n"));␊ |
3075 | int tok;␊ |
3076 | while ((tok=doctokenizerYYlex()))␊ |
3077 | {␊ |
3078 | if (!defaultHandleToken(this,tok,m_children))␊ |
3079 | {␊ |
3080 | switch (tok)␊ |
3081 | {␊ |
3082 | case TK_COMMAND: ␊ |
3083 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Illegal command %s as part of a <caption> tag",␊ |
3084 | qPrint(g_token->name));␊ |
3085 | break;␊ |
3086 | case TK_SYMBOL: ␊ |
3087 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Unsupported symbol %s found",␊ |
3088 | qPrint(g_token->name));␊ |
3089 | break;␊ |
3090 | case TK_HTMLTAG:␊ |
3091 | {␊ |
3092 | int tagId=Mappers::htmlTagMapper->map(g_token->name);␊ |
3093 | if (tagId==HTML_CAPTION && g_token->endTag) // found </caption> tag␊ |
3094 | {␊ |
3095 | retval = RetVal_OK;␊ |
3096 | goto endcaption;␊ |
3097 | }␊ |
3098 | else␊ |
3099 | {␊ |
3100 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Unexpected html tag <%s%s> found within <caption> context",␊ |
3101 | g_token->endTag?"/":"",qPrint(g_token->name));␊ |
3102 | }␊ |
3103 | }␊ |
3104 | break;␊ |
3105 | default:␊ |
3106 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Unexpected token %s",␊ |
3107 | tokToString(tok));␊ |
3108 | break;␊ |
3109 | }␊ |
3110 | }␊ |
3111 | }␊ |
3112 | if (tok==0)␊ |
3113 | {␊ |
3114 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Unexpected end of comment while inside"␊ |
3115 | " <caption> tag",doctokenizerYYlineno); ␊ |
3116 | }␊ |
3117 | endcaption:␊ |
3118 | handlePendingStyleCommands(this,m_children);␊ |
3119 | DBG(("DocHtmlCaption::parse() end\n"));␊ |
3120 | DocNode *n=g_nodeStack.pop();␊ |
3121 | ASSERT(n==this);␊ |
3122 | return retval;␊ |
3123 | }␊ |
3124 | ␊ |
3125 | //---------------------------------------------------------------------------␊ |
3126 | ␊ |
3127 | int DocHtmlCell::parse()␊ |
3128 | {␊ |
3129 | int retval=RetVal_OK;␊ |
3130 | g_nodeStack.push(this);␊ |
3131 | DBG(("DocHtmlCell::parse() start\n"));␊ |
3132 | ␊ |
3133 | // parse one or more paragraphs␊ |
3134 | bool isFirst=TRUE;␊ |
3135 | DocPara *par=0;␊ |
3136 | do␊ |
3137 | {␊ |
3138 | par = new DocPara(this);␊ |
3139 | if (isFirst) { par->markFirst(); isFirst=FALSE; }␊ |
3140 | m_children.append(par);␊ |
3141 | retval=par->parse();␊ |
3142 | if (retval==TK_HTMLTAG)␊ |
3143 | {␊ |
3144 | int tagId=Mappers::htmlTagMapper->map(g_token->name);␊ |
3145 | if (tagId==HTML_TD && g_token->endTag) // found </dt> tag␊ |
3146 | {␊ |
3147 | retval=TK_NEWPARA; // ignore the tag␊ |
3148 | }␊ |
3149 | else if (tagId==HTML_TH && g_token->endTag) // found </th> tag␊ |
3150 | {␊ |
3151 | retval=TK_NEWPARA; // ignore the tag␊ |
3152 | }␊ |
3153 | }␊ |
3154 | }␊ |
3155 | while (retval==TK_NEWPARA);␊ |
3156 | if (par) par->markLast();␊ |
3157 | ␊ |
3158 | DBG(("DocHtmlCell::parse() end\n"));␊ |
3159 | DocNode *n=g_nodeStack.pop();␊ |
3160 | ASSERT(n==this);␊ |
3161 | return retval;␊ |
3162 | }␊ |
3163 | ␊ |
3164 | int DocHtmlCell::parseXml()␊ |
3165 | {␊ |
3166 | int retval=RetVal_OK;␊ |
3167 | g_nodeStack.push(this);␊ |
3168 | DBG(("DocHtmlCell::parseXml() start\n"));␊ |
3169 | ␊ |
3170 | // parse one or more paragraphs␊ |
3171 | bool isFirst=TRUE;␊ |
3172 | DocPara *par=0;␊ |
3173 | do␊ |
3174 | {␊ |
3175 | par = new DocPara(this);␊ |
3176 | if (isFirst) { par->markFirst(); isFirst=FALSE; }␊ |
3177 | m_children.append(par);␊ |
3178 | retval=par->parse();␊ |
3179 | if (retval==TK_HTMLTAG)␊ |
3180 | {␊ |
3181 | int tagId=Mappers::htmlTagMapper->map(g_token->name);␊ |
3182 | if (tagId==XML_ITEM && g_token->endTag) // found </item> tag␊ |
3183 | {␊ |
3184 | retval=TK_NEWPARA; // ignore the tag␊ |
3185 | }␊ |
3186 | else if (tagId==XML_DESCRIPTION && g_token->endTag) // found </description> tag␊ |
3187 | {␊ |
3188 | retval=TK_NEWPARA; // ignore the tag␊ |
3189 | }␊ |
3190 | }␊ |
3191 | }␊ |
3192 | while (retval==TK_NEWPARA);␊ |
3193 | if (par) par->markLast();␊ |
3194 | ␊ |
3195 | DBG(("DocHtmlCell::parseXml() end\n"));␊ |
3196 | DocNode *n=g_nodeStack.pop();␊ |
3197 | ASSERT(n==this);␊ |
3198 | return retval;␊ |
3199 | }␊ |
3200 | ␊ |
3201 | //---------------------------------------------------------------------------␊ |
3202 | ␊ |
3203 | int DocHtmlRow::parse()␊ |
3204 | {␊ |
3205 | int retval=RetVal_OK;␊ |
3206 | g_nodeStack.push(this);␊ |
3207 | DBG(("DocHtmlRow::parse() start\n"));␊ |
3208 | ␊ |
3209 | bool isHeading=FALSE;␊ |
3210 | bool isFirst=TRUE;␊ |
3211 | DocHtmlCell *cell=0;␊ |
3212 | ␊ |
3213 | // get next token␊ |
3214 | int tok=doctokenizerYYlex();␊ |
3215 | // skip whitespace␊ |
3216 | while (tok==TK_WHITESPACE || tok==TK_NEWPARA) tok=doctokenizerYYlex();␊ |
3217 | // should find a html tag now␊ |
3218 | if (tok==TK_HTMLTAG)␊ |
3219 | {␊ |
3220 | int tagId=Mappers::htmlTagMapper->map(g_token->name);␊ |
3221 | if (tagId==HTML_TD && !g_token->endTag) // found <td> tag␊ |
3222 | {␊ |
3223 | }␊ |
3224 | else if (tagId==HTML_TH && !g_token->endTag) // found <th> tag␊ |
3225 | {␊ |
3226 | isHeading=TRUE;␊ |
3227 | }␊ |
3228 | else // found some other tag␊ |
3229 | {␊ |
3230 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: expected <td> or <th> tag but "␊ |
3231 | "found <%s> instead!",qPrint(g_token->name));␊ |
3232 | doctokenizerYYpushBackHtmlTag(g_token->name);␊ |
3233 | goto endrow;␊ |
3234 | }␊ |
3235 | }␊ |
3236 | else if (tok==0) // premature end of comment␊ |
3237 | {␊ |
3238 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: unexpected end of comment while looking"␊ |
3239 | " for a html description title");␊ |
3240 | goto endrow;␊ |
3241 | }␊ |
3242 | else // token other than html token␊ |
3243 | {␊ |
3244 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: expected <td> or <th> tag but found %s token instead!",␊ |
3245 | tokToString(tok));␊ |
3246 | goto endrow;␊ |
3247 | }␊ |
3248 | ␊ |
3249 | // parse one or more cells␊ |
3250 | do␊ |
3251 | {␊ |
3252 | cell=new DocHtmlCell(this,g_token->attribs,isHeading);␊ |
3253 | cell->markFirst(isFirst);␊ |
3254 | isFirst=FALSE;␊ |
3255 | m_children.append(cell);␊ |
3256 | retval=cell->parse();␊ |
3257 | isHeading = retval==RetVal_TableHCell;␊ |
3258 | }␊ |
3259 | while (retval==RetVal_TableCell || retval==RetVal_TableHCell);␊ |
3260 | if (cell) cell->markLast(TRUE);␊ |
3261 | ␊ |
3262 | endrow:␊ |
3263 | DBG(("DocHtmlRow::parse() end\n"));␊ |
3264 | DocNode *n=g_nodeStack.pop();␊ |
3265 | ASSERT(n==this);␊ |
3266 | return retval;␊ |
3267 | }␊ |
3268 | ␊ |
3269 | int DocHtmlRow::parseXml(bool isHeading)␊ |
3270 | {␊ |
3271 | int retval=RetVal_OK;␊ |
3272 | g_nodeStack.push(this);␊ |
3273 | DBG(("DocHtmlRow::parseXml() start\n"));␊ |
3274 | ␊ |
3275 | bool isFirst=TRUE;␊ |
3276 | DocHtmlCell *cell=0;␊ |
3277 | ␊ |
3278 | // get next token␊ |
3279 | int tok=doctokenizerYYlex();␊ |
3280 | // skip whitespace␊ |
3281 | while (tok==TK_WHITESPACE || tok==TK_NEWPARA) tok=doctokenizerYYlex();␊ |
3282 | // should find a html tag now␊ |
3283 | if (tok==TK_HTMLTAG)␊ |
3284 | {␊ |
3285 | int tagId=Mappers::htmlTagMapper->map(g_token->name);␊ |
3286 | if (tagId==XML_TERM && !g_token->endTag) // found <term> tag␊ |
3287 | {␊ |
3288 | }␊ |
3289 | else if (tagId==XML_DESCRIPTION && !g_token->endTag) // found <description> tag␊ |
3290 | {␊ |
3291 | }␊ |
3292 | else // found some other tag␊ |
3293 | {␊ |
3294 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: expected <term> or <description> tag but "␊ |
3295 | "found <%s> instead!",qPrint(g_token->name));␊ |
3296 | doctokenizerYYpushBackHtmlTag(g_token->name);␊ |
3297 | goto endrow;␊ |
3298 | }␊ |
3299 | }␊ |
3300 | else if (tok==0) // premature end of comment␊ |
3301 | {␊ |
3302 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: unexpected end of comment while looking"␊ |
3303 | " for a html description title");␊ |
3304 | goto endrow;␊ |
3305 | }␊ |
3306 | else // token other than html token␊ |
3307 | {␊ |
3308 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: expected <td> or <th> tag but found %s token instead!",␊ |
3309 | tokToString(tok));␊ |
3310 | goto endrow;␊ |
3311 | }␊ |
3312 | ␊ |
3313 | do␊ |
3314 | {␊ |
3315 | cell=new DocHtmlCell(this,g_token->attribs,isHeading);␊ |
3316 | cell->markFirst(isFirst);␊ |
3317 | isFirst=FALSE;␊ |
3318 | m_children.append(cell);␊ |
3319 | retval=cell->parseXml();␊ |
3320 | }␊ |
3321 | while (retval==RetVal_TableCell || retval==RetVal_TableHCell);␊ |
3322 | if (cell) cell->markLast(TRUE);␊ |
3323 | ␊ |
3324 | endrow:␊ |
3325 | DBG(("DocHtmlRow::parseXml() end\n"));␊ |
3326 | DocNode *n=g_nodeStack.pop();␊ |
3327 | ASSERT(n==this);␊ |
3328 | return retval;␊ |
3329 | }␊ |
3330 | ␊ |
3331 | //---------------------------------------------------------------------------␊ |
3332 | ␊ |
3333 | int DocHtmlTable::parse()␊ |
3334 | {␊ |
3335 | int retval=RetVal_OK;␊ |
3336 | g_nodeStack.push(this);␊ |
3337 | DBG(("DocHtmlTable::parse() start\n"));␊ |
3338 | ␊ |
3339 | getrow:␊ |
3340 | // get next token␊ |
3341 | int tok=doctokenizerYYlex();␊ |
3342 | // skip whitespace␊ |
3343 | while (tok==TK_WHITESPACE || tok==TK_NEWPARA) tok=doctokenizerYYlex();␊ |
3344 | // should find a html tag now␊ |
3345 | if (tok==TK_HTMLTAG)␊ |
3346 | {␊ |
3347 | int tagId=Mappers::htmlTagMapper->map(g_token->name);␊ |
3348 | if (tagId==HTML_TR && !g_token->endTag) // found <tr> tag␊ |
3349 | {␊ |
3350 | // no caption, just rows␊ |
3351 | retval=RetVal_TableRow;␊ |
3352 | }␊ |
3353 | else if (tagId==HTML_CAPTION && !g_token->endTag) // found <caption> tag␊ |
3354 | {␊ |
3355 | if (m_caption)␊ |
3356 | {␊ |
3357 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: table already has a caption, found another one");␊ |
3358 | }␊ |
3359 | else␊ |
3360 | {␊ |
3361 | m_caption = new DocHtmlCaption(this,g_token->attribs);␊ |
3362 | retval=m_caption->parse();␊ |
3363 | ␊ |
3364 | if (retval==RetVal_OK) // caption was parsed ok␊ |
3365 | {␊ |
3366 | goto getrow;␊ |
3367 | }␊ |
3368 | }␊ |
3369 | }␊ |
3370 | else // found wrong token␊ |
3371 | {␊ |
3372 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: expected <tr> or <caption> tag but "␊ |
3373 | "found <%s%s> instead!", g_token->endTag ? "/" : "", qPrint(g_token->name));␊ |
3374 | }␊ |
3375 | }␊ |
3376 | else if (tok==0) // premature end of comment␊ |
3377 | {␊ |
3378 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: unexpected end of comment while looking"␊ |
3379 | " for a <tr> or <caption> tag");␊ |
3380 | }␊ |
3381 | else // token other than html token␊ |
3382 | {␊ |
3383 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: expected <tr> tag but found %s token instead!",␊ |
3384 | tokToString(tok));␊ |
3385 | }␊ |
3386 | ␊ |
3387 | // parse one or more rows␊ |
3388 | while (retval==RetVal_TableRow)␊ |
3389 | {␊ |
3390 | DocHtmlRow *tr=new DocHtmlRow(this,g_token->attribs);␊ |
3391 | m_children.append(tr);␊ |
3392 | retval=tr->parse();␊ |
3393 | } ␊ |
3394 | ␊ |
3395 | DBG(("DocHtmlTable::parse() end\n"));␊ |
3396 | DocNode *n=g_nodeStack.pop();␊ |
3397 | ASSERT(n==this);␊ |
3398 | return retval==RetVal_EndTable ? RetVal_OK : retval;␊ |
3399 | }␊ |
3400 | ␊ |
3401 | int DocHtmlTable::parseXml()␊ |
3402 | {␊ |
3403 | int retval=RetVal_OK;␊ |
3404 | g_nodeStack.push(this);␊ |
3405 | DBG(("DocHtmlTable::parseXml() start\n"));␊ |
3406 | ␊ |
3407 | // get next token␊ |
3408 | int tok=doctokenizerYYlex();␊ |
3409 | // skip whitespace␊ |
3410 | while (tok==TK_WHITESPACE || tok==TK_NEWPARA) tok=doctokenizerYYlex();␊ |
3411 | // should find a html tag now␊ |
3412 | int tagId=0;␊ |
3413 | bool isHeader=FALSE;␊ |
3414 | if (tok==TK_HTMLTAG)␊ |
3415 | {␊ |
3416 | tagId=Mappers::htmlTagMapper->map(g_token->name);␊ |
3417 | if (tagId==XML_ITEM && !g_token->endTag) // found <item> tag␊ |
3418 | {␊ |
3419 | retval=RetVal_TableRow;␊ |
3420 | }␊ |
3421 | if (tagId==XML_LISTHEADER && !g_token->endTag) // found <listheader> tag␊ |
3422 | {␊ |
3423 | retval=RetVal_TableRow;␊ |
3424 | isHeader=TRUE;␊ |
3425 | }␊ |
3426 | }␊ |
3427 | ␊ |
3428 | // parse one or more rows␊ |
3429 | while (retval==RetVal_TableRow)␊ |
3430 | {␊ |
3431 | DocHtmlRow *tr=new DocHtmlRow(this,g_token->attribs);␊ |
3432 | m_children.append(tr);␊ |
3433 | retval=tr->parseXml(isHeader);␊ |
3434 | isHeader=FALSE;␊ |
3435 | } ␊ |
3436 | ␊ |
3437 | DBG(("DocHtmlTable::parseXml() end\n"));␊ |
3438 | DocNode *n=g_nodeStack.pop();␊ |
3439 | ASSERT(n==this);␊ |
3440 | return retval==RetVal_EndTable ? RetVal_OK : retval;␊ |
3441 | }␊ |
3442 | ␊ |
3443 | uint DocHtmlTable::numCols() const␊ |
3444 | {␊ |
3445 | uint cols=0;␊ |
3446 | QListIterator<DocNode> cli(m_children);␊ |
3447 | DocNode *n;␊ |
3448 | for (cli.toFirst();(n=cli.current());++cli)␊ |
3449 | {␊ |
3450 | ASSERT(n->kind()==DocNode::Kind_HtmlRow);␊ |
3451 | cols=QMAX(cols,((DocHtmlRow *)n)->numCells());␊ |
3452 | }␊ |
3453 | return cols;␊ |
3454 | }␊ |
3455 | ␊ |
3456 | void DocHtmlTable::accept(DocVisitor *v) ␊ |
3457 | { ␊ |
3458 | v->visitPre(this); ␊ |
3459 | // for HTML output we put the caption first␊ |
3460 | if (m_caption && v->id()==DocVisitor_Html) m_caption->accept(v);␊ |
3461 | QListIterator<DocNode> cli(m_children);␊ |
3462 | DocNode *n;␊ |
3463 | for (cli.toFirst();(n=cli.current());++cli) n->accept(v);␊ |
3464 | // for other output formats we put the caption last␊ |
3465 | if (m_caption && v->id()!=DocVisitor_Html) m_caption->accept(v);␊ |
3466 | v->visitPost(this); ␊ |
3467 | }␊ |
3468 | ␊ |
3469 | //---------------------------------------------------------------------------␊ |
3470 | ␊ |
3471 | int DocHtmlDescTitle::parse()␊ |
3472 | {␊ |
3473 | int retval=0;␊ |
3474 | g_nodeStack.push(this);␊ |
3475 | DBG(("DocHtmlDescTitle::parse() start\n"));␊ |
3476 | ␊ |
3477 | int tok;␊ |
3478 | while ((tok=doctokenizerYYlex()))␊ |
3479 | {␊ |
3480 | if (!defaultHandleToken(this,tok,m_children))␊ |
3481 | {␊ |
3482 | switch (tok)␊ |
3483 | {␊ |
3484 | case TK_COMMAND: ␊ |
3485 | {␊ |
3486 | QCString cmdName=g_token->name;␊ |
3487 | bool isJavaLink=FALSE;␊ |
3488 | switch (Mappers::cmdMapper->map(cmdName))␊ |
3489 | {␊ |
3490 | case CMD_REF:␊ |
3491 | {␊ |
3492 | int tok=doctokenizerYYlex();␊ |
3493 | if (tok!=TK_WHITESPACE)␊ |
3494 | {␊ |
3495 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: expected whitespace after %s command",␊ |
3496 | qPrint(g_token->name));␊ |
3497 | }␊ |
3498 | else␊ |
3499 | {␊ |
3500 | doctokenizerYYsetStateRef();␊ |
3501 | tok=doctokenizerYYlex(); // get the reference id␊ |
3502 | if (tok!=TK_WORD)␊ |
3503 | {␊ |
3504 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: unexpected token %s as the argument of %s",␊ |
3505 | tokToString(tok),qPrint(cmdName));␊ |
3506 | }␊ |
3507 | else␊ |
3508 | {␊ |
3509 | DocRef *ref = new DocRef(this,g_token->name,g_context);␊ |
3510 | m_children.append(ref);␊ |
3511 | ref->parse();␊ |
3512 | }␊ |
3513 | doctokenizerYYsetStatePara();␊ |
3514 | }␊ |
3515 | }␊ |
3516 | break;␊ |
3517 | case CMD_JAVALINK:␊ |
3518 | isJavaLink=TRUE;␊ |
3519 | // fall through␊ |
3520 | case CMD_LINK:␊ |
3521 | {␊ |
3522 | int tok=doctokenizerYYlex();␊ |
3523 | if (tok!=TK_WHITESPACE)␊ |
3524 | {␊ |
3525 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: expected whitespace after %s command",␊ |
3526 | qPrint(cmdName));␊ |
3527 | }␊ |
3528 | else␊ |
3529 | {␊ |
3530 | doctokenizerYYsetStateLink();␊ |
3531 | tok=doctokenizerYYlex();␊ |
3532 | if (tok!=TK_WORD)␊ |
3533 | {␊ |
3534 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: unexpected token %s as the argument of %s",␊ |
3535 | tokToString(tok),qPrint(cmdName));␊ |
3536 | }␊ |
3537 | else␊ |
3538 | {␊ |
3539 | doctokenizerYYsetStatePara();␊ |
3540 | DocLink *lnk = new DocLink(this,g_token->name);␊ |
3541 | m_children.append(lnk);␊ |
3542 | QCString leftOver = lnk->parse(isJavaLink);␊ |
3543 | if (!leftOver.isEmpty())␊ |
3544 | {␊ |
3545 | m_children.append(new DocWord(this,leftOver));␊ |
3546 | }␊ |
3547 | }␊ |
3548 | }␊ |
3549 | }␊ |
3550 | ␊ |
3551 | break;␊ |
3552 | default:␊ |
3553 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Illegal command %s as part of a <dt> tag",␊ |
3554 | qPrint(g_token->name));␊ |
3555 | }␊ |
3556 | }␊ |
3557 | break;␊ |
3558 | case TK_SYMBOL: ␊ |
3559 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Unsupported symbol %s found",␊ |
3560 | qPrint(g_token->name));␊ |
3561 | break;␊ |
3562 | case TK_HTMLTAG:␊ |
3563 | {␊ |
3564 | int tagId=Mappers::htmlTagMapper->map(g_token->name);␊ |
3565 | if (tagId==HTML_DD && !g_token->endTag) // found <dd> tag␊ |
3566 | {␊ |
3567 | retval = RetVal_DescData;␊ |
3568 | goto endtitle;␊ |
3569 | }␊ |
3570 | else if (tagId==HTML_DT && g_token->endTag)␊ |
3571 | {␊ |
3572 | // ignore </dt> tag.␊ |
3573 | }␊ |
3574 | else if (tagId==HTML_DT)␊ |
3575 | {␊ |
3576 | // missing <dt> tag.␊ |
3577 | retval = RetVal_DescTitle;␊ |
3578 | goto endtitle;␊ |
3579 | }␊ |
3580 | else if (tagId==HTML_DL && g_token->endTag)␊ |
3581 | {␊ |
3582 | retval=RetVal_EndDesc;␊ |
3583 | goto endtitle;␊ |
3584 | }␊ |
3585 | else␊ |
3586 | {␊ |
3587 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Unexpected html tag <%s%s> found within <dt> context",␊ |
3588 | g_token->endTag?"/":"",qPrint(g_token->name));␊ |
3589 | }␊ |
3590 | }␊ |
3591 | break;␊ |
3592 | default:␊ |
3593 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Unexpected token %s",␊ |
3594 | tokToString(tok));␊ |
3595 | break;␊ |
3596 | }␊ |
3597 | }␊ |
3598 | }␊ |
3599 | if (tok==0)␊ |
3600 | {␊ |
3601 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Unexpected end of comment while inside"␊ |
3602 | " <dt> tag"); ␊ |
3603 | }␊ |
3604 | endtitle:␊ |
3605 | handlePendingStyleCommands(this,m_children);␊ |
3606 | DBG(("DocHtmlDescTitle::parse() end\n"));␊ |
3607 | DocNode *n=g_nodeStack.pop();␊ |
3608 | ASSERT(n==this);␊ |
3609 | return retval;␊ |
3610 | }␊ |
3611 | ␊ |
3612 | //---------------------------------------------------------------------------␊ |
3613 | ␊ |
3614 | int DocHtmlDescData::parse()␊ |
3615 | {␊ |
3616 | m_attribs = g_token->attribs;␊ |
3617 | int retval=0;␊ |
3618 | g_nodeStack.push(this);␊ |
3619 | DBG(("DocHtmlDescData::parse() start\n"));␊ |
3620 | ␊ |
3621 | bool isFirst=TRUE;␊ |
3622 | DocPara *par=0;␊ |
3623 | do␊ |
3624 | {␊ |
3625 | par = new DocPara(this);␊ |
3626 | if (isFirst) { par->markFirst(); isFirst=FALSE; }␊ |
3627 | m_children.append(par);␊ |
3628 | retval=par->parse();␊ |
3629 | }␊ |
3630 | while (retval==TK_NEWPARA);␊ |
3631 | if (par) par->markLast();␊ |
3632 | ␊ |
3633 | DBG(("DocHtmlDescData::parse() end\n"));␊ |
3634 | DocNode *n=g_nodeStack.pop();␊ |
3635 | ASSERT(n==this);␊ |
3636 | return retval;␊ |
3637 | }␊ |
3638 | ␊ |
3639 | //---------------------------------------------------------------------------␊ |
3640 | ␊ |
3641 | int DocHtmlDescList::parse()␊ |
3642 | {␊ |
3643 | int retval=RetVal_OK;␊ |
3644 | g_nodeStack.push(this);␊ |
3645 | DBG(("DocHtmlDescList::parse() start\n"));␊ |
3646 | ␊ |
3647 | // get next token␊ |
3648 | int tok=doctokenizerYYlex();␊ |
3649 | // skip whitespace␊ |
3650 | while (tok==TK_WHITESPACE || tok==TK_NEWPARA) tok=doctokenizerYYlex();␊ |
3651 | // should find a html tag now␊ |
3652 | if (tok==TK_HTMLTAG)␊ |
3653 | {␊ |
3654 | int tagId=Mappers::htmlTagMapper->map(g_token->name);␊ |
3655 | if (tagId==HTML_DT && !g_token->endTag) // found <dt> tag␊ |
3656 | {␊ |
3657 | // continue␊ |
3658 | }␊ |
3659 | else // found some other tag␊ |
3660 | {␊ |
3661 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: expected <dt> tag but "␊ |
3662 | "found <%s> instead!",qPrint(g_token->name));␊ |
3663 | doctokenizerYYpushBackHtmlTag(g_token->name);␊ |
3664 | goto enddesclist;␊ |
3665 | }␊ |
3666 | }␊ |
3667 | else if (tok==0) // premature end of comment␊ |
3668 | {␊ |
3669 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: unexpected end of comment while looking"␊ |
3670 | " for a html description title");␊ |
3671 | goto enddesclist;␊ |
3672 | }␊ |
3673 | else // token other than html token␊ |
3674 | {␊ |
3675 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: expected <dt> tag but found %s token instead!",␊ |
3676 | tokToString(tok));␊ |
3677 | goto enddesclist;␊ |
3678 | }␊ |
3679 | ␊ |
3680 | do␊ |
3681 | {␊ |
3682 | DocHtmlDescTitle *dt=new DocHtmlDescTitle(this,g_token->attribs);␊ |
3683 | m_children.append(dt);␊ |
3684 | DocHtmlDescData *dd=new DocHtmlDescData(this);␊ |
3685 | m_children.append(dd);␊ |
3686 | retval=dt->parse();␊ |
3687 | if (retval==RetVal_DescData)␊ |
3688 | {␊ |
3689 | retval=dd->parse();␊ |
3690 | }␊ |
3691 | else if (retval!=RetVal_DescTitle)␊ |
3692 | {␊ |
3693 | // error␊ |
3694 | break;␊ |
3695 | }␊ |
3696 | } while (retval==RetVal_DescTitle);␊ |
3697 | ␊ |
3698 | if (retval==0)␊ |
3699 | {␊ |
3700 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: unexpected end of comment while inside <dl> block");␊ |
3701 | }␊ |
3702 | ␊ |
3703 | enddesclist:␊ |
3704 | ␊ |
3705 | DocNode *n=g_nodeStack.pop();␊ |
3706 | ASSERT(n==this);␊ |
3707 | DBG(("DocHtmlDescList::parse() end\n"));␊ |
3708 | return retval==RetVal_EndDesc ? RetVal_OK : retval;␊ |
3709 | }␊ |
3710 | ␊ |
3711 | //---------------------------------------------------------------------------␊ |
3712 | ␊ |
3713 | int DocHtmlListItem::parse()␊ |
3714 | {␊ |
3715 | DBG(("DocHtmlListItem::parse() start\n"));␊ |
3716 | int retval=0;␊ |
3717 | g_nodeStack.push(this);␊ |
3718 | ␊ |
3719 | // parse one or more paragraphs␊ |
3720 | bool isFirst=TRUE;␊ |
3721 | DocPara *par=0;␊ |
3722 | do␊ |
3723 | {␊ |
3724 | par = new DocPara(this);␊ |
3725 | if (isFirst) { par->markFirst(); isFirst=FALSE; }␊ |
3726 | m_children.append(par);␊ |
3727 | retval=par->parse();␊ |
3728 | }␊ |
3729 | while (retval==TK_NEWPARA);␊ |
3730 | if (par) par->markLast();␊ |
3731 | ␊ |
3732 | DocNode *n=g_nodeStack.pop();␊ |
3733 | ASSERT(n==this);␊ |
3734 | DBG(("DocHtmlListItem::parse() end retval=%x\n",retval));␊ |
3735 | return retval;␊ |
3736 | }␊ |
3737 | ␊ |
3738 | int DocHtmlListItem::parseXml()␊ |
3739 | {␊ |
3740 | DBG(("DocHtmlListItem::parseXml() start\n"));␊ |
3741 | int retval=0;␊ |
3742 | g_nodeStack.push(this);␊ |
3743 | ␊ |
3744 | // parse one or more paragraphs␊ |
3745 | bool isFirst=TRUE;␊ |
3746 | DocPara *par=0;␊ |
3747 | do␊ |
3748 | {␊ |
3749 | par = new DocPara(this);␊ |
3750 | if (isFirst) { par->markFirst(); isFirst=FALSE; }␊ |
3751 | m_children.append(par);␊ |
3752 | retval=par->parse();␊ |
3753 | if (retval==0) break;␊ |
3754 | ␊ |
3755 | //printf("new item: retval=%x g_token->name=%s g_token->endTag=%d\n",␊ |
3756 | // retval,qPrint(g_token->name),g_token->endTag);␊ |
3757 | if (retval==RetVal_ListItem)␊ |
3758 | {␊ |
3759 | break;␊ |
3760 | }␊ |
3761 | }␊ |
3762 | while (retval!=RetVal_CloseXml);␊ |
3763 | ␊ |
3764 | if (par) par->markLast();␊ |
3765 | ␊ |
3766 | DocNode *n=g_nodeStack.pop();␊ |
3767 | ASSERT(n==this);␊ |
3768 | DBG(("DocHtmlListItem::parseXml() end retval=%x\n",retval));␊ |
3769 | return retval;␊ |
3770 | }␊ |
3771 | ␊ |
3772 | //---------------------------------------------------------------------------␊ |
3773 | ␊ |
3774 | int DocHtmlList::parse()␊ |
3775 | {␊ |
3776 | DBG(("DocHtmlList::parse() start\n"));␊ |
3777 | int retval=RetVal_OK;␊ |
3778 | int num=1;␊ |
3779 | g_nodeStack.push(this);␊ |
3780 | ␊ |
3781 | // get next token␊ |
3782 | int tok=doctokenizerYYlex();␊ |
3783 | // skip whitespace and paragraph breaks␊ |
3784 | while (tok==TK_WHITESPACE || tok==TK_NEWPARA) tok=doctokenizerYYlex();␊ |
3785 | // should find a html tag now␊ |
3786 | if (tok==TK_HTMLTAG)␊ |
3787 | {␊ |
3788 | int tagId=Mappers::htmlTagMapper->map(g_token->name);␊ |
3789 | if (tagId==HTML_LI && !g_token->endTag) // found <li> tag␊ |
3790 | {␊ |
3791 | // ok, we can go on.␊ |
3792 | }␊ |
3793 | else // found some other tag␊ |
3794 | {␊ |
3795 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: expected <li> tag but "␊ |
3796 | "found <%s> instead!",qPrint(g_token->name));␊ |
3797 | doctokenizerYYpushBackHtmlTag(g_token->name);␊ |
3798 | goto endlist;␊ |
3799 | }␊ |
3800 | }␊ |
3801 | else if (tok==0) // premature end of comment␊ |
3802 | {␊ |
3803 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: unexpected end of comment while looking"␊ |
3804 | " for a html list item");␊ |
3805 | goto endlist;␊ |
3806 | }␊ |
3807 | else // token other than html token␊ |
3808 | {␊ |
3809 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: expected <li> tag but found %s token instead!",␊ |
3810 | tokToString(tok));␊ |
3811 | goto endlist;␊ |
3812 | }␊ |
3813 | ␊ |
3814 | do␊ |
3815 | {␊ |
3816 | DocHtmlListItem *li=new DocHtmlListItem(this,g_token->attribs,num++);␊ |
3817 | m_children.append(li);␊ |
3818 | retval=li->parse();␊ |
3819 | } while (retval==RetVal_ListItem);␊ |
3820 | ␊ |
3821 | if (retval==0)␊ |
3822 | {␊ |
3823 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: unexpected end of comment while inside <%cl> block",␊ |
3824 | m_type==Unordered ? 'u' : 'o');␊ |
3825 | }␊ |
3826 | ␊ |
3827 | endlist:␊ |
3828 | DBG(("DocHtmlList::parse() end retval=%x\n",retval));␊ |
3829 | DocNode *n=g_nodeStack.pop();␊ |
3830 | ASSERT(n==this);␊ |
3831 | return retval==RetVal_EndList ? RetVal_OK : retval;␊ |
3832 | }␊ |
3833 | ␊ |
3834 | int DocHtmlList::parseXml()␊ |
3835 | {␊ |
3836 | DBG(("DocHtmlList::parseXml() start\n"));␊ |
3837 | int retval=RetVal_OK;␊ |
3838 | int num=1;␊ |
3839 | g_nodeStack.push(this);␊ |
3840 | ␊ |
3841 | // get next token␊ |
3842 | int tok=doctokenizerYYlex();␊ |
3843 | // skip whitespace and paragraph breaks␊ |
3844 | while (tok==TK_WHITESPACE || tok==TK_NEWPARA) tok=doctokenizerYYlex();␊ |
3845 | // should find a html tag now␊ |
3846 | if (tok==TK_HTMLTAG)␊ |
3847 | {␊ |
3848 | int tagId=Mappers::htmlTagMapper->map(g_token->name);␊ |
3849 | //printf("g_token->name=%s g_token->endTag=%d\n",qPrint(g_token->name),g_token->endTag);␊ |
3850 | if (tagId==XML_ITEM && !g_token->endTag) // found <item> tag␊ |
3851 | {␊ |
3852 | // ok, we can go on.␊ |
3853 | }␊ |
3854 | else // found some other tag␊ |
3855 | {␊ |
3856 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: expected <item> tag but "␊ |
3857 | "found <%s> instead!",qPrint(g_token->name));␊ |
3858 | doctokenizerYYpushBackHtmlTag(g_token->name);␊ |
3859 | goto endlist;␊ |
3860 | }␊ |
3861 | }␊ |
3862 | else if (tok==0) // premature end of comment␊ |
3863 | {␊ |
3864 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: unexpected end of comment while looking"␊ |
3865 | " for a html list item");␊ |
3866 | goto endlist;␊ |
3867 | }␊ |
3868 | else // token other than html token␊ |
3869 | {␊ |
3870 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: expected <item> tag but found %s token instead!",␊ |
3871 | tokToString(tok));␊ |
3872 | goto endlist;␊ |
3873 | }␊ |
3874 | ␊ |
3875 | do␊ |
3876 | {␊ |
3877 | DocHtmlListItem *li=new DocHtmlListItem(this,g_token->attribs,num++);␊ |
3878 | m_children.append(li);␊ |
3879 | retval=li->parseXml();␊ |
3880 | if (retval==0) break;␊ |
3881 | //printf("retval=%x g_token->name=%s\n",retval,qPrint(g_token->name));␊ |
3882 | } while (retval==RetVal_ListItem);␊ |
3883 | ␊ |
3884 | if (retval==0)␊ |
3885 | {␊ |
3886 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: unexpected end of comment while inside <list type=\"%s\"> block",␊ |
3887 | m_type==Unordered ? "bullet" : "number");␊ |
3888 | }␊ |
3889 | ␊ |
3890 | endlist:␊ |
3891 | DBG(("DocHtmlList::parseXml() end retval=%x\n",retval));␊ |
3892 | DocNode *n=g_nodeStack.pop();␊ |
3893 | ASSERT(n==this);␊ |
3894 | return retval==RetVal_EndList || ␊ |
3895 | (retval==RetVal_CloseXml || g_token->name=="list") ? ␊ |
3896 | RetVal_OK : retval;␊ |
3897 | }␊ |
3898 | ␊ |
3899 | //---------------------------------------------------------------------------␊ |
3900 | ␊ |
3901 | int DocSimpleListItem::parse()␊ |
3902 | {␊ |
3903 | g_nodeStack.push(this);␊ |
3904 | int rv=m_paragraph->parse();␊ |
3905 | m_paragraph->markFirst();␊ |
3906 | m_paragraph->markLast();␊ |
3907 | DocNode *n=g_nodeStack.pop();␊ |
3908 | ASSERT(n==this);␊ |
3909 | return rv;␊ |
3910 | }␊ |
3911 | ␊ |
3912 | //--------------------------------------------------------------------------␊ |
3913 | ␊ |
3914 | int DocSimpleList::parse()␊ |
3915 | {␊ |
3916 | g_nodeStack.push(this);␊ |
3917 | int rv;␊ |
3918 | do␊ |
3919 | {␊ |
3920 | DocSimpleListItem *li=new DocSimpleListItem(this);␊ |
3921 | m_children.append(li);␊ |
3922 | rv=li->parse();␊ |
3923 | } while (rv==RetVal_ListItem);␊ |
3924 | DocNode *n=g_nodeStack.pop();␊ |
3925 | ASSERT(n==this);␊ |
3926 | return (rv!=TK_NEWPARA) ? rv : RetVal_OK;␊ |
3927 | }␊ |
3928 | ␊ |
3929 | //--------------------------------------------------------------------------␊ |
3930 | ␊ |
3931 | int DocAutoListItem::parse()␊ |
3932 | {␊ |
3933 | int retval = RetVal_OK;␊ |
3934 | g_nodeStack.push(this);␊ |
3935 | retval=m_paragraph->parse();␊ |
3936 | m_paragraph->markFirst();␊ |
3937 | m_paragraph->markLast();␊ |
3938 | DocNode *n=g_nodeStack.pop();␊ |
3939 | ASSERT(n==this);␊ |
3940 | return retval;␊ |
3941 | }␊ |
3942 | ␊ |
3943 | //--------------------------------------------------------------------------␊ |
3944 | ␊ |
3945 | int DocAutoList::parse()␊ |
3946 | {␊ |
3947 | int retval = RetVal_OK;␊ |
3948 | int num=1;␊ |
3949 | g_nodeStack.push(this);␊ |
3950 | ␉ // first item or sub list => create new list␊ |
3951 | do␊ |
3952 | {␊ |
3953 | DocAutoListItem *li = new DocAutoListItem(this,num++);␊ |
3954 | m_children.append(li);␊ |
3955 | retval=li->parse();␊ |
3956 | } ␊ |
3957 | while (retval==TK_LISTITEM && // new list item␊ |
3958 | m_indent==g_token->indent && // at same indent level␊ |
3959 | ␉ m_isEnumList==g_token->isEnumList // of the same kind␊ |
3960 | );␊ |
3961 | ␊ |
3962 | DocNode *n=g_nodeStack.pop();␊ |
3963 | ASSERT(n==this);␊ |
3964 | return retval;␊ |
3965 | }␊ |
3966 | ␊ |
3967 | //--------------------------------------------------------------------------␊ |
3968 | ␊ |
3969 | void DocTitle::parse()␊ |
3970 | {␊ |
3971 | DBG(("DocTitle::parse() start\n"));␊ |
3972 | g_nodeStack.push(this);␊ |
3973 | doctokenizerYYsetStateTitle();␊ |
3974 | int tok;␊ |
3975 | while ((tok=doctokenizerYYlex()))␊ |
3976 | {␊ |
3977 | if (!defaultHandleToken(this,tok,m_children))␊ |
3978 | {␊ |
3979 | switch (tok)␊ |
3980 | {␊ |
3981 | case TK_COMMAND: ␊ |
3982 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Illegal command %s as part of a title section",␊ |
3983 | ␉ qPrint(g_token->name));␊ |
3984 | break;␊ |
3985 | case TK_SYMBOL: ␊ |
3986 | ␉ warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Unsupported symbol %s found",␊ |
3987 | qPrint(g_token->name));␊ |
3988 | break;␊ |
3989 | default:␊ |
3990 | ␉ warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Unexpected token %s",␊ |
3991 | ␉␉tokToString(tok));␊ |
3992 | break;␊ |
3993 | }␊ |
3994 | }␊ |
3995 | }␊ |
3996 | doctokenizerYYsetStatePara();␊ |
3997 | handlePendingStyleCommands(this,m_children);␊ |
3998 | DBG(("DocTitle::parse() end\n"));␊ |
3999 | DocNode *n = g_nodeStack.pop();␊ |
4000 | ASSERT(n==this);␊ |
4001 | }␊ |
4002 | ␊ |
4003 | void DocTitle::parseFromString(const QCString &text)␊ |
4004 | {␊ |
4005 | m_children.append(new DocWord(this,text));␊ |
4006 | }␊ |
4007 | ␊ |
4008 | //--------------------------------------------------------------------------␊ |
4009 | ␊ |
4010 | DocSimpleSect::DocSimpleSect(DocNode *parent,Type t) : ␊ |
4011 | m_type(t)␊ |
4012 | { ␊ |
4013 | m_parent = parent; ␊ |
4014 | m_title=0; ␊ |
4015 | }␊ |
4016 | ␊ |
4017 | DocSimpleSect::~DocSimpleSect()␊ |
4018 | { ␊ |
4019 | delete m_title; ␊ |
4020 | }␊ |
4021 | ␊ |
4022 | void DocSimpleSect::accept(DocVisitor *v)␊ |
4023 | {␊ |
4024 | v->visitPre(this);␊ |
4025 | if (m_title) m_title->accept(v);␊ |
4026 | QListIterator<DocNode> cli(m_children);␊ |
4027 | DocNode *n;␊ |
4028 | for (cli.toFirst();(n=cli.current());++cli) n->accept(v);␊ |
4029 | v->visitPost(this);␊ |
4030 | }␊ |
4031 | ␊ |
4032 | int DocSimpleSect::parse(bool userTitle,bool needsSeparator)␊ |
4033 | {␊ |
4034 | DBG(("DocSimpleSect::parse() start\n"));␊ |
4035 | g_nodeStack.push(this);␊ |
4036 | ␊ |
4037 | // handle case for user defined title␊ |
4038 | if (userTitle)␊ |
4039 | {␊ |
4040 | m_title = new DocTitle(this);␊ |
4041 | m_title->parse();␊ |
4042 | }␊ |
4043 | ␊ |
4044 | // add new paragraph as child␊ |
4045 | DocPara *par = new DocPara(this);␊ |
4046 | if (m_children.isEmpty()) ␊ |
4047 | {␊ |
4048 | par->markFirst();␊ |
4049 | }␊ |
4050 | else␊ |
4051 | {␊ |
4052 | ASSERT(m_children.last()->kind()==DocNode::Kind_Para);␊ |
4053 | ((DocPara *)m_children.last())->markLast(FALSE);␊ |
4054 | }␊ |
4055 | par->markLast();␊ |
4056 | if (needsSeparator) m_children.append(new DocSimpleSectSep(this));␊ |
4057 | m_children.append(par);␊ |
4058 | ␊ |
4059 | // parse the contents of the paragraph␊ |
4060 | int retval = par->parse();␊ |
4061 | ␊ |
4062 | DBG(("DocSimpleSect::parse() end retval=%d\n",retval));␊ |
4063 | DocNode *n=g_nodeStack.pop();␊ |
4064 | ASSERT(n==this);␊ |
4065 | return retval; // 0==EOF, TK_NEWPARA, TK_LISTITEM, TK_ENDLIST, RetVal_SimpleSec␊ |
4066 | }␊ |
4067 | ␊ |
4068 | int DocSimpleSect::parseRcs()␊ |
4069 | {␊ |
4070 | DBG(("DocSimpleSect::parseRcs() start\n"));␊ |
4071 | g_nodeStack.push(this);␊ |
4072 | ␊ |
4073 | m_title = new DocTitle(this);␊ |
4074 | m_title->parseFromString(g_token->name);␊ |
4075 | ␊ |
4076 | QCString text = g_token->text;␊ |
4077 | docParserPushContext(); // this will create a new g_token␊ |
4078 | internalValidatingParseDoc(this,m_children,text);␊ |
4079 | docParserPopContext(); // this will restore the old g_token␊ |
4080 | ␊ |
4081 | DBG(("DocSimpleSect::parseRcs()\n"));␊ |
4082 | DocNode *n=g_nodeStack.pop();␊ |
4083 | ASSERT(n==this);␊ |
4084 | return RetVal_OK; ␊ |
4085 | }␊ |
4086 | ␊ |
4087 | int DocSimpleSect::parseXml()␊ |
4088 | {␊ |
4089 | DBG(("DocSimpleSect::parse() start\n"));␊ |
4090 | g_nodeStack.push(this);␊ |
4091 | ␊ |
4092 | int retval = RetVal_OK;␊ |
4093 | for (;;) ␊ |
4094 | {␊ |
4095 | // add new paragraph as child␊ |
4096 | DocPara *par = new DocPara(this);␊ |
4097 | if (m_children.isEmpty()) ␊ |
4098 | {␊ |
4099 | par->markFirst();␊ |
4100 | }␊ |
4101 | else␊ |
4102 | {␊ |
4103 | ASSERT(m_children.last()->kind()==DocNode::Kind_Para);␊ |
4104 | ((DocPara *)m_children.last())->markLast(FALSE);␊ |
4105 | }␊ |
4106 | par->markLast();␊ |
4107 | m_children.append(par);␊ |
4108 | ␊ |
4109 | // parse the contents of the paragraph␊ |
4110 | retval = par->parse();␊ |
4111 | if (retval == 0) break;␊ |
4112 | if (retval == RetVal_CloseXml) ␊ |
4113 | {␊ |
4114 | retval = RetVal_OK;␊ |
4115 | break;␊ |
4116 | }␊ |
4117 | }␊ |
4118 | ␊ |
4119 | DBG(("DocSimpleSect::parseXml() end retval=%d\n",retval));␊ |
4120 | DocNode *n=g_nodeStack.pop();␊ |
4121 | ASSERT(n==this);␊ |
4122 | return retval; ␊ |
4123 | }␊ |
4124 | ␊ |
4125 | void DocSimpleSect::appendLinkWord(const QCString &word)␊ |
4126 | {␊ |
4127 | DocPara *p;␊ |
4128 | if (m_children.isEmpty() || m_children.last()->kind()!=DocNode::Kind_Para)␊ |
4129 | {␊ |
4130 | p = new DocPara(this);␊ |
4131 | m_children.append(p);␊ |
4132 | }␊ |
4133 | else␊ |
4134 | {␊ |
4135 | p = (DocPara *)m_children.last();␊ |
4136 | ␊ |
4137 | // Comma-seperate <seealso> links.␊ |
4138 | p->injectToken(TK_WORD,",");␊ |
4139 | p->injectToken(TK_WHITESPACE," ");␊ |
4140 | }␊ |
4141 | ␊ |
4142 | g_inSeeBlock=TRUE;␊ |
4143 | p->injectToken(TK_LNKWORD,word);␊ |
4144 | g_inSeeBlock=FALSE;␊ |
4145 | }␊ |
4146 | ␊ |
4147 | QCString DocSimpleSect::typeString() const␊ |
4148 | {␊ |
4149 | switch (m_type)␊ |
4150 | {␊ |
4151 | case Unknown: break;␊ |
4152 | case See: return "see";␊ |
4153 | case Return: return "return";␊ |
4154 | case Author: // fall through␊ |
4155 | case Authors: return "author";␊ |
4156 | case Version: return "version";␊ |
4157 | case Since: return "since";␊ |
4158 | case Date: return "date";␊ |
4159 | case Note: return "note";␊ |
4160 | case Warning: return "warning";␊ |
4161 | case Pre: return "pre";␊ |
4162 | case Post: return "post";␊ |
4163 | case Invar: return "invariant";␊ |
4164 | case Remark: return "remark";␊ |
4165 | case Attention: return "attention";␊ |
4166 | case User: return "user";␊ |
4167 | case Rcs: return "rcs";␊ |
4168 | }␊ |
4169 | return "unknown";␊ |
4170 | }␊ |
4171 | ␊ |
4172 | //--------------------------------------------------------------------------␊ |
4173 | ␊ |
4174 | int DocParamList::parse(const QCString &cmdName)␊ |
4175 | {␊ |
4176 | int retval=RetVal_OK;␊ |
4177 | DBG(("DocParamList::parse() start\n"));␊ |
4178 | g_nodeStack.push(this);␊ |
4179 | DocPara *par=0;␊ |
4180 | ␊ |
4181 | int tok=doctokenizerYYlex();␊ |
4182 | if (tok!=TK_WHITESPACE)␊ |
4183 | {␊ |
4184 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: expected whitespace after %s command",␊ |
4185 | qPrint(cmdName));␊ |
4186 | }␊ |
4187 | doctokenizerYYsetStateParam();␊ |
4188 | tok=doctokenizerYYlex();␊ |
4189 | while (tok==TK_WORD) /* there is a parameter name */␊ |
4190 | {␊ |
4191 | if (m_type==DocParamSect::Param)␊ |
4192 | {␊ |
4193 | int typeSeparator = g_token->name.find('#'); // explicit type position␊ |
4194 | if (typeSeparator!=-1)␊ |
4195 | {␊ |
4196 | handleParameterType(this,m_paramTypes,g_token->name.left(typeSeparator));␊ |
4197 | g_token->name = g_token->name.mid(typeSeparator+1);␊ |
4198 | g_hasParamCommand=TRUE;␊ |
4199 | checkArgumentName(g_token->name,TRUE);␊ |
4200 | ((DocParamSect*)parent())->m_hasTypeSpecifier=TRUE;␊ |
4201 | }␊ |
4202 | else␊ |
4203 | {␊ |
4204 | g_hasParamCommand=TRUE;␊ |
4205 | checkArgumentName(g_token->name,TRUE);␊ |
4206 | }␊ |
4207 | }␊ |
4208 | else if (m_type==DocParamSect::RetVal)␊ |
4209 | {␊ |
4210 | g_hasReturnCommand=TRUE;␊ |
4211 | checkArgumentName(g_token->name,FALSE);␊ |
4212 | }␊ |
4213 | //m_params.append(g_token->name);␊ |
4214 | handleLinkedWord(this,m_params);␊ |
4215 | tok=doctokenizerYYlex();␊ |
4216 | }␊ |
4217 | doctokenizerYYsetStatePara();␊ |
4218 | if (tok==0) /* premature end of comment block */␊ |
4219 | {␊ |
4220 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: unexpected end of comment block while parsing the "␊ |
4221 | "argument of command %s",qPrint(cmdName));␊ |
4222 | retval=0;␊ |
4223 | goto endparamlist;␊ |
4224 | }␊ |
4225 | ASSERT(tok==TK_WHITESPACE);␊ |
4226 | ␊ |
4227 | par = new DocPara(this);␊ |
4228 | m_paragraphs.append(par);␊ |
4229 | retval = par->parse();␊ |
4230 | par->markFirst();␊ |
4231 | par->markLast();␊ |
4232 | ␊ |
4233 | endparamlist:␊ |
4234 | DBG(("DocParamList::parse() end retval=%d\n",retval));␊ |
4235 | DocNode *n=g_nodeStack.pop();␊ |
4236 | ASSERT(n==this);␊ |
4237 | return retval;␊ |
4238 | }␊ |
4239 | ␊ |
4240 | int DocParamList::parseXml(const QCString ¶mName)␊ |
4241 | {␊ |
4242 | int retval=RetVal_OK;␊ |
4243 | DBG(("DocParamList::parseXml() start\n"));␊ |
4244 | g_nodeStack.push(this);␊ |
4245 | ␊ |
4246 | g_token->name = paramName;␊ |
4247 | if (m_type==DocParamSect::Param)␊ |
4248 | {␊ |
4249 | g_hasParamCommand=TRUE;␊ |
4250 | checkArgumentName(g_token->name,TRUE);␊ |
4251 | }␊ |
4252 | else if (m_type==DocParamSect::RetVal)␊ |
4253 | {␊ |
4254 | g_hasReturnCommand=TRUE;␊ |
4255 | checkArgumentName(g_token->name,FALSE);␊ |
4256 | }␊ |
4257 | ␊ |
4258 | handleLinkedWord(this,m_params);␊ |
4259 | ␊ |
4260 | do␊ |
4261 | {␊ |
4262 | DocPara *par = new DocPara(this);␊ |
4263 | retval = par->parse();␊ |
4264 | if (par->isEmpty()) // avoid adding an empty paragraph for the whitespace␊ |
4265 | // after </para> and before </param>␊ |
4266 | {␊ |
4267 | delete par;␊ |
4268 | break;␊ |
4269 | }␊ |
4270 | else // append the paragraph to the list␊ |
4271 | {␊ |
4272 | if (m_paragraphs.isEmpty())␊ |
4273 | {␊ |
4274 | par->markFirst();␊ |
4275 | }␊ |
4276 | else␊ |
4277 | {␊ |
4278 | m_paragraphs.last()->markLast(FALSE);␊ |
4279 | }␊ |
4280 | par->markLast();␊ |
4281 | m_paragraphs.append(par);␊ |
4282 | }␊ |
4283 | ␊ |
4284 | if (retval == 0) break;␊ |
4285 | ␊ |
4286 | } while (retval==RetVal_CloseXml && ␊ |
4287 | Mappers::htmlTagMapper->map(g_token->name)!=XML_PARAM &&␊ |
4288 | Mappers::htmlTagMapper->map(g_token->name)!=XML_TYPEPARAM &&␊ |
4289 | Mappers::htmlTagMapper->map(g_token->name)!=XML_EXCEPTION);␊ |
4290 | ␊ |
4291 | ␊ |
4292 | if (retval==0) /* premature end of comment block */␊ |
4293 | {␊ |
4294 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: unterminated param or exception tag");␊ |
4295 | }␊ |
4296 | else␊ |
4297 | {␊ |
4298 | retval=RetVal_OK;␊ |
4299 | }␊ |
4300 | ␊ |
4301 | ␊ |
4302 | DBG(("DocParamList::parse() end retval=%d\n",retval));␊ |
4303 | DocNode *n=g_nodeStack.pop();␊ |
4304 | ASSERT(n==this);␊ |
4305 | return retval;␊ |
4306 | }␊ |
4307 | ␊ |
4308 | //--------------------------------------------------------------------------␊ |
4309 | ␊ |
4310 | int DocParamSect::parse(const QCString &cmdName,bool xmlContext, Direction d)␊ |
4311 | {␊ |
4312 | int retval=RetVal_OK;␊ |
4313 | DBG(("DocParamSect::parse() start\n"));␊ |
4314 | g_nodeStack.push(this);␊ |
4315 | ␊ |
4316 | if (d!=Unspecified)␊ |
4317 | {␊ |
4318 | m_hasInOutSpecifier=TRUE;␊ |
4319 | }␊ |
4320 | ␊ |
4321 | DocParamList *pl = new DocParamList(this,m_type,d);␊ |
4322 | if (m_children.isEmpty())␊ |
4323 | {␊ |
4324 | pl->markFirst();␊ |
4325 | pl->markLast();␊ |
4326 | }␊ |
4327 | else␊ |
4328 | {␊ |
4329 | ASSERT(m_children.last()->kind()==DocNode::Kind_ParamList);␊ |
4330 | ((DocParamList *)m_children.last())->markLast(FALSE);␊ |
4331 | pl->markLast();␊ |
4332 | }␊ |
4333 | m_children.append(pl);␊ |
4334 | if (xmlContext)␊ |
4335 | {␊ |
4336 | retval = pl->parseXml(cmdName);␊ |
4337 | }␊ |
4338 | else␊ |
4339 | {␊ |
4340 | retval = pl->parse(cmdName);␊ |
4341 | }␊ |
4342 | ␊ |
4343 | DBG(("DocParamSect::parse() end retval=%d\n",retval));␊ |
4344 | DocNode *n=g_nodeStack.pop();␊ |
4345 | ASSERT(n==this);␊ |
4346 | return retval;␊ |
4347 | }␊ |
4348 | ␊ |
4349 | //--------------------------------------------------------------------------␊ |
4350 | ␊ |
4351 | int DocPara::handleSimpleSection(DocSimpleSect::Type t, bool xmlContext)␊ |
4352 | {␊ |
4353 | DocSimpleSect *ss=0;␊ |
4354 | bool needsSeparator = FALSE;␊ |
4355 | if (!m_children.isEmpty() && // previous element␊ |
4356 | m_children.last()->kind()==Kind_SimpleSect && // was a simple sect␊ |
4357 | ((DocSimpleSect *)m_children.last())->type()==t && // of same type␊ |
4358 | t!=DocSimpleSect::User) // but not user defined␊ |
4359 | {␊ |
4360 | // append to previous section␊ |
4361 | ss=(DocSimpleSect *)m_children.last();␊ |
4362 | needsSeparator = TRUE;␊ |
4363 | }␊ |
4364 | else // start new section␊ |
4365 | {␊ |
4366 | ss=new DocSimpleSect(this,t);␊ |
4367 | m_children.append(ss);␊ |
4368 | }␊ |
4369 | int rv = RetVal_OK;␊ |
4370 | if (xmlContext)␊ |
4371 | {␊ |
4372 | return ss->parseXml();␊ |
4373 | }␊ |
4374 | else␊ |
4375 | {␊ |
4376 | rv = ss->parse(t==DocSimpleSect::User,needsSeparator);␊ |
4377 | }␊ |
4378 | return (rv!=TK_NEWPARA) ? rv : RetVal_OK;␊ |
4379 | }␊ |
4380 | ␊ |
4381 | int DocPara::handleParamSection(const QCString &cmdName,␊ |
4382 | DocParamSect::Type t,␊ |
4383 | bool xmlContext=FALSE,␊ |
4384 | int direction=DocParamSect::Unspecified)␊ |
4385 | {␊ |
4386 | DocParamSect *ps=0;␊ |
4387 | if (!m_children.isEmpty() && // previous element␊ |
4388 | m_children.last()->kind()==Kind_ParamSect && // was a param sect␊ |
4389 | ((DocParamSect *)m_children.last())->type()==t) // of same type␊ |
4390 | {␊ |
4391 | // append to previous section␊ |
4392 | ps=(DocParamSect *)m_children.last();␊ |
4393 | }␊ |
4394 | else // start new section␊ |
4395 | {␊ |
4396 | ps=new DocParamSect(this,t);␊ |
4397 | m_children.append(ps);␊ |
4398 | }␊ |
4399 | int rv=ps->parse(cmdName,xmlContext,(DocParamSect::Direction)direction);␊ |
4400 | return (rv!=TK_NEWPARA) ? rv : RetVal_OK;␊ |
4401 | }␊ |
4402 | ␊ |
4403 | int DocPara::handleXRefItem()␊ |
4404 | {␊ |
4405 | int retval=doctokenizerYYlex();␊ |
4406 | ASSERT(retval==TK_WHITESPACE);␊ |
4407 | doctokenizerYYsetStateXRefItem();␊ |
4408 | retval=doctokenizerYYlex();␊ |
4409 | if (retval==RetVal_OK)␊ |
4410 | {␊ |
4411 | DocXRefItem *ref = new DocXRefItem(this,g_token->id,g_token->name);␊ |
4412 | if (ref->parse())␊ |
4413 | {␊ |
4414 | m_children.append(ref);␊ |
4415 | }␊ |
4416 | else ␊ |
4417 | {␊ |
4418 | delete ref;␊ |
4419 | }␊ |
4420 | }␊ |
4421 | doctokenizerYYsetStatePara();␊ |
4422 | return retval;␊ |
4423 | }␊ |
4424 | ␊ |
4425 | void DocPara::handleIncludeOperator(const QCString &cmdName,DocIncOperator::Type t)␊ |
4426 | {␊ |
4427 | DBG(("handleIncludeOperator(%s)\n",qPrint(cmdName)));␊ |
4428 | int tok=doctokenizerYYlex();␊ |
4429 | if (tok!=TK_WHITESPACE)␊ |
4430 | {␊ |
4431 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: expected whitespace after %s command",␊ |
4432 | qPrint(cmdName));␊ |
4433 | return;␊ |
4434 | }␊ |
4435 | doctokenizerYYsetStatePattern();␊ |
4436 | tok=doctokenizerYYlex();␊ |
4437 | doctokenizerYYsetStatePara();␊ |
4438 | if (tok==0)␊ |
4439 | {␊ |
4440 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: unexpected end of comment block while parsing the "␊ |
4441 | "argument of command %s", qPrint(cmdName));␊ |
4442 | return;␊ |
4443 | }␊ |
4444 | else if (tok!=TK_WORD)␊ |
4445 | {␊ |
4446 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: unexpected token %s as the argument of %s",␊ |
4447 | tokToString(tok),qPrint(cmdName));␊ |
4448 | return;␊ |
4449 | }␊ |
4450 | DocIncOperator *op = new DocIncOperator(this,t,g_token->name,g_context,g_isExample,g_exampleName);␊ |
4451 | DocNode *n1 = m_children.last();␊ |
4452 | DocNode *n2 = n1!=0 ? m_children.prev() : 0;␊ |
4453 | bool isFirst = n1==0 || // no last node␊ |
4454 | (n1->kind()!=DocNode::Kind_IncOperator && ␊ |
4455 | n1->kind()!=DocNode::Kind_WhiteSpace␊ |
4456 | ) || // last node is not operator or whitespace␊ |
4457 | (n1->kind()==DocNode::Kind_WhiteSpace && ␊ |
4458 | n2!=0 && n2->kind()!=DocNode::Kind_IncOperator␊ |
4459 | ); // previous not is not operator␊ |
4460 | op->markFirst(isFirst);␊ |
4461 | op->markLast(TRUE);␊ |
4462 | if (n1!=0 && n1->kind()==DocNode::Kind_IncOperator)␊ |
4463 | {␊ |
4464 | ((DocIncOperator *)n1)->markLast(FALSE);␊ |
4465 | }␊ |
4466 | else if (n1!=0 && n1->kind()==DocNode::Kind_WhiteSpace &&␊ |
4467 | n2!=0 && n2->kind()==DocNode::Kind_IncOperator␊ |
4468 | )␊ |
4469 | {␊ |
4470 | ((DocIncOperator *)n2)->markLast(FALSE);␊ |
4471 | }␊ |
4472 | m_children.append(op);␊ |
4473 | op->parse();␊ |
4474 | }␊ |
4475 | ␊ |
4476 | void DocPara::handleImage(const QCString &cmdName)␊ |
4477 | {␊ |
4478 | int tok=doctokenizerYYlex();␊ |
4479 | if (tok!=TK_WHITESPACE)␊ |
4480 | {␊ |
4481 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: expected whitespace after %s command",␊ |
4482 | qPrint(cmdName));␊ |
4483 | return;␊ |
4484 | }␊ |
4485 | tok=doctokenizerYYlex();␊ |
4486 | if (tok!=TK_WORD && tok!=TK_LNKWORD)␊ |
4487 | {␊ |
4488 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: unexpected token %s as the argument of %s",␊ |
4489 | tokToString(tok),qPrint(cmdName));␊ |
4490 | return;␊ |
4491 | }␊ |
4492 | tok=doctokenizerYYlex();␊ |
4493 | if (tok!=TK_WHITESPACE)␊ |
4494 | {␊ |
4495 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: expected whitespace after %s command",␊ |
4496 | qPrint(cmdName));␊ |
4497 | return;␊ |
4498 | }␊ |
4499 | DocImage::Type t;␊ |
4500 | QCString imgType = g_token->name.lower();␊ |
4501 | if (imgType=="html") t=DocImage::Html;␊ |
4502 | else if (imgType=="latex") t=DocImage::Latex;␊ |
4503 | else if (imgType=="rtf") t=DocImage::Rtf;␊ |
4504 | else␊ |
4505 | {␊ |
4506 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: image type %s specified as the first argument of "␊ |
4507 | "%s is not valid",␊ |
4508 | qPrint(imgType),qPrint(cmdName));␊ |
4509 | return;␊ |
4510 | } ␊ |
4511 | doctokenizerYYsetStateFile();␊ |
4512 | tok=doctokenizerYYlex();␊ |
4513 | doctokenizerYYsetStatePara();␊ |
4514 | if (tok!=TK_WORD)␊ |
4515 | {␊ |
4516 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: unexpected token %s as the argument of %s",␊ |
4517 | tokToString(tok),qPrint(cmdName));␊ |
4518 | return;␊ |
4519 | }␊ |
4520 | HtmlAttribList attrList;␊ |
4521 | DocImage *img = new DocImage(this,attrList,findAndCopyImage(g_token->name,t),t);␊ |
4522 | m_children.append(img);␊ |
4523 | img->parse();␊ |
4524 | }␊ |
4525 | ␊ |
4526 | void DocPara::handleDotFile(const QCString &cmdName)␊ |
4527 | {␊ |
4528 | int tok=doctokenizerYYlex();␊ |
4529 | if (tok!=TK_WHITESPACE)␊ |
4530 | {␊ |
4531 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: expected whitespace after %s command",␊ |
4532 | qPrint(cmdName));␊ |
4533 | return;␊ |
4534 | }␊ |
4535 | doctokenizerYYsetStateFile();␊ |
4536 | tok=doctokenizerYYlex();␊ |
4537 | doctokenizerYYsetStatePara();␊ |
4538 | if (tok!=TK_WORD)␊ |
4539 | {␊ |
4540 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: unexpected token %s as the argument of %s",␊ |
4541 | tokToString(tok),qPrint(cmdName));␊ |
4542 | return;␊ |
4543 | }␊ |
4544 | QCString name = g_token->name;␊ |
4545 | DocDotFile *df = new DocDotFile(this,name,g_context);␊ |
4546 | m_children.append(df);␊ |
4547 | df->parse();␊ |
4548 | }␊ |
4549 | ␊ |
4550 | void DocPara::handleMscFile(const QCString &cmdName)␊ |
4551 | {␊ |
4552 | int tok=doctokenizerYYlex();␊ |
4553 | if (tok!=TK_WHITESPACE)␊ |
4554 | {␊ |
4555 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: expected whitespace after %s command",␊ |
4556 | qPrint(cmdName));␊ |
4557 | return;␊ |
4558 | }␊ |
4559 | doctokenizerYYsetStateFile();␊ |
4560 | tok=doctokenizerYYlex();␊ |
4561 | doctokenizerYYsetStatePara();␊ |
4562 | if (tok!=TK_WORD)␊ |
4563 | {␊ |
4564 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: unexpected token %s as the argument of %s",␊ |
4565 | tokToString(tok),qPrint(cmdName));␊ |
4566 | return;␊ |
4567 | }␊ |
4568 | QCString name = g_token->name;␊ |
4569 | DocMscFile *df = new DocMscFile(this,name,g_context);␊ |
4570 | m_children.append(df);␊ |
4571 | df->parse();␊ |
4572 | }␊ |
4573 | ␊ |
4574 | void DocPara::handleLink(const QCString &cmdName,bool isJavaLink)␊ |
4575 | {␊ |
4576 | int tok=doctokenizerYYlex();␊ |
4577 | if (tok!=TK_WHITESPACE)␊ |
4578 | {␊ |
4579 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: expected whitespace after %s command",␊ |
4580 | qPrint(cmdName));␊ |
4581 | return;␊ |
4582 | }␊ |
4583 | doctokenizerYYsetStateLink();␊ |
4584 | tok=doctokenizerYYlex();␊ |
4585 | if (tok!=TK_WORD)␊ |
4586 | {␊ |
4587 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: unexpected token %s as the argument of %s",␊ |
4588 | tokToString(tok),qPrint(cmdName));␊ |
4589 | return;␊ |
4590 | }␊ |
4591 | doctokenizerYYsetStatePara();␊ |
4592 | DocLink *lnk = new DocLink(this,g_token->name);␊ |
4593 | m_children.append(lnk);␊ |
4594 | QCString leftOver = lnk->parse(isJavaLink);␊ |
4595 | if (!leftOver.isEmpty())␊ |
4596 | {␊ |
4597 | m_children.append(new DocWord(this,leftOver));␊ |
4598 | }␊ |
4599 | }␊ |
4600 | ␊ |
4601 | void DocPara::handleRef(const QCString &cmdName)␊ |
4602 | {␊ |
4603 | DBG(("handleRef(%s)\n",qPrint(cmdName)));␊ |
4604 | int tok=doctokenizerYYlex();␊ |
4605 | if (tok!=TK_WHITESPACE)␊ |
4606 | {␊ |
4607 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: expected whitespace after %s command",␊ |
4608 | qPrint(cmdName));␊ |
4609 | return;␊ |
4610 | }␊ |
4611 | doctokenizerYYsetStateRef();␊ |
4612 | tok=doctokenizerYYlex(); // get the reference id␊ |
4613 | DocRef *ref=0;␊ |
4614 | if (tok!=TK_WORD)␊ |
4615 | {␊ |
4616 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: unexpected token %s as the argument of %s",␊ |
4617 | tokToString(tok),qPrint(cmdName));␊ |
4618 | goto endref;␊ |
4619 | }␊ |
4620 | ref = new DocRef(this,g_token->name,g_context);␊ |
4621 | m_children.append(ref);␊ |
4622 | ref->parse();␊ |
4623 | endref:␊ |
4624 | doctokenizerYYsetStatePara();␊ |
4625 | }␊ |
4626 | ␊ |
4627 | ␊ |
4628 | void DocPara::handleInclude(const QCString &cmdName,DocInclude::Type t)␊ |
4629 | {␊ |
4630 | DBG(("handleInclude(%s)\n",qPrint(cmdName)));␊ |
4631 | int tok=doctokenizerYYlex();␊ |
4632 | if (tok!=TK_WHITESPACE)␊ |
4633 | {␊ |
4634 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: expected whitespace after %s command",␊ |
4635 | qPrint(cmdName));␊ |
4636 | return;␊ |
4637 | }␊ |
4638 | doctokenizerYYsetStateFile();␊ |
4639 | tok=doctokenizerYYlex();␊ |
4640 | doctokenizerYYsetStatePara();␊ |
4641 | if (tok==0)␊ |
4642 | {␊ |
4643 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: unexpected end of comment block while parsing the "␊ |
4644 | "argument of command %s",qPrint(cmdName));␊ |
4645 | return;␊ |
4646 | }␊ |
4647 | else if (tok!=TK_WORD)␊ |
4648 | {␊ |
4649 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: unexpected token %s as the argument of %s",␊ |
4650 | tokToString(tok),qPrint(cmdName));␊ |
4651 | return;␊ |
4652 | }␊ |
4653 | DocInclude *inc = new DocInclude(this,g_token->name,g_context,t,g_isExample,g_exampleName);␊ |
4654 | m_children.append(inc);␊ |
4655 | inc->parse();␊ |
4656 | }␊ |
4657 | ␊ |
4658 | void DocPara::handleSection(const QCString &cmdName)␊ |
4659 | {␊ |
4660 | // get the argument of the section command.␊ |
4661 | int tok=doctokenizerYYlex();␊ |
4662 | if (tok!=TK_WHITESPACE)␊ |
4663 | {␊ |
4664 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: expected whitespace after %s command",␊ |
4665 | qPrint(cmdName));␊ |
4666 | return;␊ |
4667 | }␊ |
4668 | tok=doctokenizerYYlex();␊ |
4669 | if (tok==0)␊ |
4670 | {␊ |
4671 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: unexpected end of comment block while parsing the "␊ |
4672 | "argument of command %s\n", qPrint(cmdName));␊ |
4673 | return;␊ |
4674 | }␊ |
4675 | else if (tok!=TK_WORD && tok!=TK_LNKWORD)␊ |
4676 | {␊ |
4677 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: unexpected token %s as the argument of %s",␊ |
4678 | tokToString(tok),qPrint(cmdName));␊ |
4679 | return;␊ |
4680 | }␊ |
4681 | g_token->sectionId = g_token->name;␊ |
4682 | doctokenizerYYsetStateSkipTitle();␊ |
4683 | doctokenizerYYlex();␊ |
4684 | doctokenizerYYsetStatePara();␊ |
4685 | }␊ |
4686 | ␊ |
4687 | int DocPara::handleHtmlHeader(const HtmlAttribList &tagHtmlAttribs,int level)␊ |
4688 | {␊ |
4689 | DocHtmlHeader *header = new DocHtmlHeader(this,tagHtmlAttribs,level);␊ |
4690 | m_children.append(header);␊ |
4691 | int retval = header->parse();␊ |
4692 | return (retval==RetVal_OK) ? TK_NEWPARA : retval;␊ |
4693 | }␊ |
4694 | ␊ |
4695 | // For XML tags whose content is stored in attributes rather than␊ |
4696 | // contained within the element, we need a way to inject the attribute␊ |
4697 | // text into the current paragraph.␊ |
4698 | bool DocPara::injectToken(int tok,const QCString &tokText) ␊ |
4699 | {␊ |
4700 | g_token->name = tokText;␊ |
4701 | return defaultHandleToken(this,tok,m_children);␊ |
4702 | }␊ |
4703 | ␊ |
4704 | int DocPara::handleStartCode()␊ |
4705 | {␊ |
4706 | int retval = doctokenizerYYlex();␊ |
4707 | // search for the first non-whitespace line, index is stored in li␊ |
4708 | int i=0,li=0,l=g_token->verb.length();␊ |
4709 | while (i<l && (g_token->verb.at(i)==' ' || g_token->verb.at(i)=='\n'))␊ |
4710 | {␊ |
4711 | if (g_token->verb.at(i)=='\n') li=i+1;␊ |
4712 | i++;␊ |
4713 | }␊ |
4714 | m_children.append(new DocVerbatim(this,g_context,g_token->verb.mid(li),DocVerbatim::Code,g_isExample,g_exampleName));␊ |
4715 | if (retval==0) warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: code section ended without end marker");␊ |
4716 | doctokenizerYYsetStatePara();␊ |
4717 | return retval;␊ |
4718 | }␊ |
4719 | ␊ |
4720 | void DocPara::handleInheritDoc()␊ |
4721 | {␊ |
4722 | if (g_memberDef) // inheriting docs from a member␊ |
4723 | {␊ |
4724 | MemberDef *reMd = g_memberDef->reimplements();␊ |
4725 | if (reMd) // member from which was inherited.␊ |
4726 | {␊ |
4727 | MemberDef *thisMd = g_memberDef;␊ |
4728 | //printf("{InheritDocs:%s=>%s}\n",g_memberDef->qualifiedName().data(),reMd->qualifiedName().data());␊ |
4729 | docParserPushContext();␊ |
4730 | g_scope=reMd->getOuterScope();␊ |
4731 | if (g_scope!=Doxygen::globalScope)␊ |
4732 | {␊ |
4733 | g_context=g_scope->name();␊ |
4734 | }␊ |
4735 | g_memberDef=reMd;␊ |
4736 | g_styleStack.clear();␊ |
4737 | g_nodeStack.clear();␊ |
4738 | g_copyStack.append(reMd);␊ |
4739 | internalValidatingParseDoc(this,m_children,reMd->briefDescription());␊ |
4740 | internalValidatingParseDoc(this,m_children,reMd->documentation());␊ |
4741 | g_copyStack.remove(reMd);␊ |
4742 | docParserPopContext(TRUE);␊ |
4743 | g_memberDef = thisMd;␊ |
4744 | }␊ |
4745 | }␊ |
4746 | }␊ |
4747 | ␊ |
4748 | ␊ |
4749 | int DocPara::handleCommand(const QCString &cmdName)␊ |
4750 | {␊ |
4751 | DBG(("handleCommand(%s)\n",qPrint(cmdName)));␊ |
4752 | int retval = RetVal_OK;␊ |
4753 | int cmdId = Mappers::cmdMapper->map(cmdName);␊ |
4754 | switch (cmdId)␊ |
4755 | {␊ |
4756 | case CMD_UNKNOWN:␊ |
4757 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Found unknown command `\\%s'",qPrint(cmdName));␊ |
4758 | break;␊ |
4759 | case CMD_EMPHASIS:␊ |
4760 | m_children.append(new DocStyleChange(this,g_nodeStack.count(),DocStyleChange::Italic,TRUE));␊ |
4761 | retval=handleStyleArgument(this,m_children,cmdName); ␊ |
4762 | m_children.append(new DocStyleChange(this,g_nodeStack.count(),DocStyleChange::Italic,FALSE));␊ |
4763 | if (retval!=TK_WORD) m_children.append(new DocWhiteSpace(this," "));␊ |
4764 | break;␊ |
4765 | case CMD_BOLD:␊ |
4766 | m_children.append(new DocStyleChange(this,g_nodeStack.count(),DocStyleChange::Bold,TRUE));␊ |
4767 | retval=handleStyleArgument(this,m_children,cmdName); ␊ |
4768 | m_children.append(new DocStyleChange(this,g_nodeStack.count(),DocStyleChange::Bold,FALSE));␊ |
4769 | if (retval!=TK_WORD) m_children.append(new DocWhiteSpace(this," "));␊ |
4770 | break;␊ |
4771 | case CMD_CODE:␊ |
4772 | m_children.append(new DocStyleChange(this,g_nodeStack.count(),DocStyleChange::Code,TRUE));␊ |
4773 | retval=handleStyleArgument(this,m_children,cmdName); ␊ |
4774 | m_children.append(new DocStyleChange(this,g_nodeStack.count(),DocStyleChange::Code,FALSE));␊ |
4775 | if (retval!=TK_WORD) m_children.append(new DocWhiteSpace(this," "));␊ |
4776 | break;␊ |
4777 | case CMD_BSLASH:␊ |
4778 | m_children.append(new DocSymbol(this,DocSymbol::BSlash));␊ |
4779 | break;␊ |
4780 | case CMD_AT:␊ |
4781 | m_children.append(new DocSymbol(this,DocSymbol::At));␊ |
4782 | break;␊ |
4783 | case CMD_LESS:␊ |
4784 | m_children.append(new DocSymbol(this,DocSymbol::Less));␊ |
4785 | break;␊ |
4786 | case CMD_GREATER:␊ |
4787 | m_children.append(new DocSymbol(this,DocSymbol::Greater));␊ |
4788 | break;␊ |
4789 | case CMD_AMP:␊ |
4790 | m_children.append(new DocSymbol(this,DocSymbol::Amp));␊ |
4791 | break;␊ |
4792 | case CMD_DOLLAR:␊ |
4793 | m_children.append(new DocSymbol(this,DocSymbol::Dollar));␊ |
4794 | break;␊ |
4795 | case CMD_HASH:␊ |
4796 | m_children.append(new DocSymbol(this,DocSymbol::Hash));␊ |
4797 | break;␊ |
4798 | case CMD_DCOLON:␊ |
4799 | m_children.append(new DocSymbol(this,DocSymbol::DoubleColon));␊ |
4800 | break;␊ |
4801 | case CMD_PERCENT:␊ |
4802 | m_children.append(new DocSymbol(this,DocSymbol::Percent));␊ |
4803 | break;␊ |
4804 | case CMD_QUOTE:␊ |
4805 | m_children.append(new DocSymbol(this,DocSymbol::Quot));␊ |
4806 | break;␊ |
4807 | case CMD_SA:␊ |
4808 | g_inSeeBlock=TRUE;␊ |
4809 | retval = handleSimpleSection(DocSimpleSect::See);␊ |
4810 | g_inSeeBlock=FALSE;␊ |
4811 | break;␊ |
4812 | case CMD_RETURN:␊ |
4813 | retval = handleSimpleSection(DocSimpleSect::Return);␊ |
4814 | g_hasReturnCommand=TRUE;␊ |
4815 | break;␊ |
4816 | case CMD_AUTHOR:␊ |
4817 | retval = handleSimpleSection(DocSimpleSect::Author);␊ |
4818 | break;␊ |
4819 | case CMD_AUTHORS:␊ |
4820 | retval = handleSimpleSection(DocSimpleSect::Authors);␊ |
4821 | break;␊ |
4822 | case CMD_VERSION:␊ |
4823 | retval = handleSimpleSection(DocSimpleSect::Version);␊ |
4824 | break;␊ |
4825 | case CMD_SINCE:␊ |
4826 | retval = handleSimpleSection(DocSimpleSect::Since);␊ |
4827 | break;␊ |
4828 | case CMD_DATE:␊ |
4829 | retval = handleSimpleSection(DocSimpleSect::Date);␊ |
4830 | break;␊ |
4831 | case CMD_NOTE:␊ |
4832 | retval = handleSimpleSection(DocSimpleSect::Note);␊ |
4833 | break;␊ |
4834 | case CMD_WARNING:␊ |
4835 | retval = handleSimpleSection(DocSimpleSect::Warning);␊ |
4836 | break;␊ |
4837 | case CMD_PRE:␊ |
4838 | retval = handleSimpleSection(DocSimpleSect::Pre);␊ |
4839 | break;␊ |
4840 | case CMD_POST:␊ |
4841 | retval = handleSimpleSection(DocSimpleSect::Post);␊ |
4842 | break;␊ |
4843 | case CMD_INVARIANT:␊ |
4844 | retval = handleSimpleSection(DocSimpleSect::Invar);␊ |
4845 | break;␊ |
4846 | case CMD_REMARK:␊ |
4847 | retval = handleSimpleSection(DocSimpleSect::Remark);␊ |
4848 | break;␊ |
4849 | case CMD_ATTENTION:␊ |
4850 | retval = handleSimpleSection(DocSimpleSect::Attention);␊ |
4851 | break;␊ |
4852 | case CMD_PAR:␊ |
4853 | retval = handleSimpleSection(DocSimpleSect::User);␊ |
4854 | break;␊ |
4855 | case CMD_LI:␊ |
4856 | {␊ |
4857 | ␉DocSimpleList *sl=new DocSimpleList(this);␊ |
4858 | ␉m_children.append(sl);␊ |
4859 | retval = sl->parse();␊ |
4860 | }␊ |
4861 | break;␊ |
4862 | case CMD_SECTION:␊ |
4863 | {␊ |
4864 | handleSection(cmdName);␊ |
4865 | ␉retval = RetVal_Section;␊ |
4866 | }␊ |
4867 | break;␊ |
4868 | case CMD_SUBSECTION:␊ |
4869 | {␊ |
4870 | handleSection(cmdName);␊ |
4871 | retval = RetVal_Subsection;␊ |
4872 | }␊ |
4873 | break;␊ |
4874 | case CMD_SUBSUBSECTION:␊ |
4875 | {␊ |
4876 | handleSection(cmdName);␊ |
4877 | retval = RetVal_Subsubsection;␊ |
4878 | }␊ |
4879 | break;␊ |
4880 | case CMD_PARAGRAPH:␊ |
4881 | {␊ |
4882 | handleSection(cmdName);␊ |
4883 | retval = RetVal_Paragraph;␊ |
4884 | }␊ |
4885 | break;␊ |
4886 | case CMD_STARTCODE:␊ |
4887 | {␊ |
4888 | doctokenizerYYsetStateCode();␊ |
4889 | retval = handleStartCode();␊ |
4890 | }␊ |
4891 | break;␊ |
4892 | case CMD_HTMLONLY:␊ |
4893 | {␊ |
4894 | doctokenizerYYsetStateHtmlOnly();␊ |
4895 | retval = doctokenizerYYlex();␊ |
4896 | m_children.append(new DocVerbatim(this,g_context,g_token->verb,DocVerbatim::HtmlOnly,g_isExample,g_exampleName));␊ |
4897 | if (retval==0) warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: htmlonly section ended without end marker");␊ |
4898 | doctokenizerYYsetStatePara();␊ |
4899 | }␊ |
4900 | break;␊ |
4901 | case CMD_MANONLY:␊ |
4902 | {␊ |
4903 | doctokenizerYYsetStateManOnly();␊ |
4904 | retval = doctokenizerYYlex();␊ |
4905 | m_children.append(new DocVerbatim(this,g_context,g_token->verb,DocVerbatim::ManOnly,g_isExample,g_exampleName));␊ |
4906 | if (retval==0) warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: manonly section ended without end marker");␊ |
4907 | doctokenizerYYsetStatePara();␊ |
4908 | }␊ |
4909 | break;␊ |
4910 | case CMD_LATEXONLY:␊ |
4911 | {␊ |
4912 | doctokenizerYYsetStateLatexOnly();␊ |
4913 | retval = doctokenizerYYlex();␊ |
4914 | m_children.append(new DocVerbatim(this,g_context,g_token->verb,DocVerbatim::LatexOnly,g_isExample,g_exampleName));␊ |
4915 | if (retval==0) warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: latexonly section ended without end marker");␊ |
4916 | doctokenizerYYsetStatePara();␊ |
4917 | }␊ |
4918 | break;␊ |
4919 | case CMD_XMLONLY:␊ |
4920 | {␊ |
4921 | doctokenizerYYsetStateXmlOnly();␊ |
4922 | retval = doctokenizerYYlex();␊ |
4923 | m_children.append(new DocVerbatim(this,g_context,g_token->verb,DocVerbatim::XmlOnly,g_isExample,g_exampleName));␊ |
4924 | if (retval==0) warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: xmlonly section ended without end marker");␊ |
4925 | doctokenizerYYsetStatePara();␊ |
4926 | }␊ |
4927 | break;␊ |
4928 | case CMD_VERBATIM:␊ |
4929 | {␊ |
4930 | doctokenizerYYsetStateVerbatim();␊ |
4931 | retval = doctokenizerYYlex();␊ |
4932 | m_children.append(new DocVerbatim(this,g_context,g_token->verb,DocVerbatim::Verbatim,g_isExample,g_exampleName));␊ |
4933 | if (retval==0) warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: verbatim section ended without end marker");␊ |
4934 | doctokenizerYYsetStatePara();␊ |
4935 | }␊ |
4936 | break;␊ |
4937 | case CMD_DOT:␊ |
4938 | {␊ |
4939 | doctokenizerYYsetStateDot();␊ |
4940 | retval = doctokenizerYYlex();␊ |
4941 | m_children.append(new DocVerbatim(this,g_context,g_token->verb,DocVerbatim::Dot,g_isExample,g_exampleName));␊ |
4942 | if (retval==0) warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: dot section ended without end marker");␊ |
4943 | doctokenizerYYsetStatePara();␊ |
4944 | }␊ |
4945 | break;␊ |
4946 | case CMD_MSC:␊ |
4947 | {␊ |
4948 | doctokenizerYYsetStateMsc();␊ |
4949 | retval = doctokenizerYYlex();␊ |
4950 | m_children.append(new DocVerbatim(this,g_context,g_token->verb,DocVerbatim::Msc,g_isExample,g_exampleName));␊ |
4951 | if (retval==0) warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: msc section ended without end marker");␊ |
4952 | doctokenizerYYsetStatePara();␊ |
4953 | }␊ |
4954 | break;␊ |
4955 | case CMD_ENDCODE:␊ |
4956 | case CMD_ENDHTMLONLY:␊ |
4957 | case CMD_ENDMANONLY:␊ |
4958 | case CMD_ENDLATEXONLY:␊ |
4959 | case CMD_ENDXMLONLY:␊ |
4960 | case CMD_ENDLINK:␊ |
4961 | case CMD_ENDVERBATIM:␊ |
4962 | case CMD_ENDDOT:␊ |
4963 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: unexpected command %s",qPrint(g_token->name));␊ |
4964 | break; ␊ |
4965 | case CMD_ENDMSC:␊ |
4966 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: unexpected command %s",qPrint(g_token->name));␊ |
4967 | break; ␊ |
4968 | case CMD_PARAM:␊ |
4969 | retval = handleParamSection(cmdName,DocParamSect::Param,FALSE,g_token->paramDir);␊ |
4970 | break;␊ |
4971 | case CMD_TPARAM:␊ |
4972 | retval = handleParamSection(cmdName,DocParamSect::TemplateParam,FALSE,g_token->paramDir);␊ |
4973 | break;␊ |
4974 | case CMD_RETVAL:␊ |
4975 | retval = handleParamSection(cmdName,DocParamSect::RetVal);␊ |
4976 | break;␊ |
4977 | case CMD_EXCEPTION:␊ |
4978 | retval = handleParamSection(cmdName,DocParamSect::Exception);␊ |
4979 | break;␊ |
4980 | case CMD_XREFITEM:␊ |
4981 | retval = handleXRefItem();␊ |
4982 | break;␊ |
4983 | case CMD_LINEBREAK:␊ |
4984 | {␊ |
4985 | DocLineBreak *lb = new DocLineBreak(this);␊ |
4986 | m_children.append(lb);␊ |
4987 | }␊ |
4988 | break;␊ |
4989 | case CMD_ANCHOR:␊ |
4990 | {␊ |
4991 | int tok=doctokenizerYYlex();␊ |
4992 | if (tok!=TK_WHITESPACE)␊ |
4993 | {␊ |
4994 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: expected whitespace after %s command",␊ |
4995 | qPrint(cmdName));␊ |
4996 | break;␊ |
4997 | }␊ |
4998 | tok=doctokenizerYYlex();␊ |
4999 | if (tok==0)␊ |
5000 | {␊ |
5001 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: unexpected end of comment block while parsing the "␊ |
5002 | "argument of command %s",qPrint(cmdName));␊ |
5003 | break;␊ |
5004 | }␊ |
5005 | else if (tok!=TK_WORD && tok!=TK_LNKWORD)␊ |
5006 | {␊ |
5007 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: unexpected token %s as the argument of %s",␊ |
5008 | tokToString(tok),qPrint(cmdName));␊ |
5009 | break;␊ |
5010 | }␊ |
5011 | DocAnchor *anchor = new DocAnchor(this,g_token->name,FALSE);␊ |
5012 | m_children.append(anchor);␊ |
5013 | }␊ |
5014 | break;␊ |
5015 | case CMD_ADDINDEX:␊ |
5016 | {␊ |
5017 | DocIndexEntry *ie = new DocIndexEntry(this,␊ |
5018 | g_scope!=Doxygen::globalScope?g_scope:0,␊ |
5019 | g_memberDef);␊ |
5020 | m_children.append(ie);␊ |
5021 | retval = ie->parse();␊ |
5022 | }␊ |
5023 | break;␊ |
5024 | case CMD_INTERNAL:␊ |
5025 | retval = RetVal_Internal;␊ |
5026 | break;␊ |
5027 | case CMD_COPYDOC: // fall through␊ |
5028 | case CMD_COPYBRIEF: // fall through␊ |
5029 | case CMD_COPYDETAILS:␊ |
5030 | {␊ |
5031 | int tok=doctokenizerYYlex();␊ |
5032 | if (tok!=TK_WHITESPACE)␊ |
5033 | {␊ |
5034 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: expected whitespace after %s command",␊ |
5035 | qPrint(cmdName));␊ |
5036 | break;␊ |
5037 | }␊ |
5038 | tok=doctokenizerYYlex();␊ |
5039 | if (tok==0)␊ |
5040 | {␊ |
5041 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: unexpected end of comment block while parsing the "␊ |
5042 | "argument of command %s\n", qPrint(cmdName));␊ |
5043 | break;␊ |
5044 | }␊ |
5045 | else if (tok!=TK_WORD && tok!=TK_LNKWORD)␊ |
5046 | {␊ |
5047 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: unexpected token %s as the argument of %s",␊ |
5048 | tokToString(tok),qPrint(cmdName));␊ |
5049 | break;␊ |
5050 | }␊ |
5051 | DocCopy *cpy = new DocCopy(this,g_token->name,␊ |
5052 | cmdId==CMD_COPYDOC || cmdId==CMD_COPYBRIEF,␊ |
5053 | cmdId==CMD_COPYDOC || cmdId==CMD_COPYDETAILS);␊ |
5054 | m_children.append(cpy);␊ |
5055 | cpy->parse();␊ |
5056 | }␊ |
5057 | break;␊ |
5058 | case CMD_INCLUDE:␊ |
5059 | handleInclude(cmdName,DocInclude::Include);␊ |
5060 | break;␊ |
5061 | case CMD_INCWITHLINES:␊ |
5062 | handleInclude(cmdName,DocInclude::IncWithLines);␊ |
5063 | break;␊ |
5064 | case CMD_DONTINCLUDE:␊ |
5065 | handleInclude(cmdName,DocInclude::DontInclude);␊ |
5066 | break;␊ |
5067 | case CMD_HTMLINCLUDE:␊ |
5068 | handleInclude(cmdName,DocInclude::HtmlInclude);␊ |
5069 | break;␊ |
5070 | case CMD_VERBINCLUDE:␊ |
5071 | handleInclude(cmdName,DocInclude::VerbInclude);␊ |
5072 | break;␊ |
5073 | case CMD_SKIP:␊ |
5074 | handleIncludeOperator(cmdName,DocIncOperator::Skip);␊ |
5075 | break;␊ |
5076 | case CMD_UNTIL:␊ |
5077 | handleIncludeOperator(cmdName,DocIncOperator::Until);␊ |
5078 | break;␊ |
5079 | case CMD_SKIPLINE:␊ |
5080 | handleIncludeOperator(cmdName,DocIncOperator::SkipLine);␊ |
5081 | break;␊ |
5082 | case CMD_LINE:␊ |
5083 | handleIncludeOperator(cmdName,DocIncOperator::Line);␊ |
5084 | break;␊ |
5085 | case CMD_IMAGE:␊ |
5086 | handleImage(cmdName);␊ |
5087 | break;␊ |
5088 | case CMD_DOTFILE:␊ |
5089 | handleDotFile(cmdName);␊ |
5090 | break;␊ |
5091 | case CMD_MSCFILE:␊ |
5092 | handleMscFile(cmdName);␊ |
5093 | break;␊ |
5094 | case CMD_LINK:␊ |
5095 | handleLink(cmdName,FALSE);␊ |
5096 | break;␊ |
5097 | case CMD_JAVALINK:␊ |
5098 | handleLink(cmdName,TRUE);␊ |
5099 | break;␊ |
5100 | case CMD_REF: // fall through␊ |
5101 | case CMD_SUBPAGE:␊ |
5102 | handleRef(cmdName);␊ |
5103 | break;␊ |
5104 | case CMD_SECREFLIST:␊ |
5105 | {␊ |
5106 | DocSecRefList *list = new DocSecRefList(this);␊ |
5107 | m_children.append(list);␊ |
5108 | list->parse();␊ |
5109 | }␊ |
5110 | break;␊ |
5111 | case CMD_SECREFITEM:␊ |
5112 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: unexpected command %s",qPrint(g_token->name));␊ |
5113 | break;␊ |
5114 | case CMD_ENDSECREFLIST:␊ |
5115 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: unexpected command %s",qPrint(g_token->name));␊ |
5116 | break;␊ |
5117 | case CMD_FORMULA:␊ |
5118 | {␊ |
5119 | DocFormula *form=new DocFormula(this,g_token->id);␊ |
5120 | m_children.append(form);␊ |
5121 | }␊ |
5122 | break;␊ |
5123 | //case CMD_LANGSWITCH:␊ |
5124 | // retval = handleLanguageSwitch();␊ |
5125 | // break;␊ |
5126 | case CMD_INTERNALREF:␊ |
5127 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: unexpected command %s",qPrint(g_token->name));␊ |
5128 | break;␊ |
5129 | case CMD_INHERITDOC:␊ |
5130 | handleInheritDoc();␊ |
5131 | break;␊ |
5132 | default:␊ |
5133 | // we should not get here!␊ |
5134 | ASSERT(0);␊ |
5135 | break;␊ |
5136 | }␊ |
5137 | INTERNAL_ASSERT(retval==0 || retval==RetVal_OK || retval==RetVal_SimpleSec || ␊ |
5138 | retval==TK_LISTITEM || retval==TK_ENDLIST || retval==TK_NEWPARA ||␊ |
5139 | retval==RetVal_Section || retval==RetVal_EndList || ␊ |
5140 | retval==RetVal_Internal || retval==RetVal_SwitchLang␊ |
5141 | );␊ |
5142 | DBG(("handleCommand(%s) end retval=%x\n",qPrint(cmdName),retval));␊ |
5143 | return retval;␊ |
5144 | }␊ |
5145 | ␊ |
5146 | static bool findAttribute(const HtmlAttribList &tagHtmlAttribs, ␊ |
5147 | const char *attrName, ␊ |
5148 | QCString *result) ␊ |
5149 | {␊ |
5150 | ␊ |
5151 | HtmlAttribListIterator li(tagHtmlAttribs);␊ |
5152 | HtmlAttrib *opt;␊ |
5153 | for (li.toFirst();(opt=li.current());++li)␊ |
5154 | {␊ |
5155 | if (opt->name==attrName) ␊ |
5156 | {␊ |
5157 | *result = opt->value;␊ |
5158 | return TRUE;␊ |
5159 | }␊ |
5160 | }␊ |
5161 | return FALSE;␊ |
5162 | }␊ |
5163 | ␊ |
5164 | int DocPara::handleHtmlStartTag(const QCString &tagName,const HtmlAttribList &tagHtmlAttribs)␊ |
5165 | {␊ |
5166 | DBG(("handleHtmlStartTag(%s,%d)\n",qPrint(tagName),tagHtmlAttribs.count()));␊ |
5167 | int retval=RetVal_OK;␊ |
5168 | int tagId = Mappers::htmlTagMapper->map(tagName);␊ |
5169 | if (g_token->emptyTag && !(tagId&XML_CmdMask) && ␊ |
5170 | tagId!=HTML_UNKNOWN && tagId!=HTML_IMG && tagId!=HTML_BR)␊ |
5171 | {␊ |
5172 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: HTML tags may not use the 'empty tag' XHTML syntax.");␊ |
5173 | }␊ |
5174 | switch (tagId)␊ |
5175 | {␊ |
5176 | case HTML_UL: ␊ |
5177 | {␊ |
5178 | DocHtmlList *list = new DocHtmlList(this,tagHtmlAttribs,DocHtmlList::Unordered);␊ |
5179 | m_children.append(list);␊ |
5180 | retval=list->parse();␊ |
5181 | }␊ |
5182 | break;␊ |
5183 | case HTML_OL: ␊ |
5184 | {␊ |
5185 | DocHtmlList *list = new DocHtmlList(this,tagHtmlAttribs,DocHtmlList::Ordered);␊ |
5186 | m_children.append(list);␊ |
5187 | retval=list->parse();␊ |
5188 | }␊ |
5189 | break;␊ |
5190 | case HTML_LI:␊ |
5191 | if (!insideUL(this) && !insideOL(this))␊ |
5192 | {␊ |
5193 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: lonely <li> tag found");␊ |
5194 | }␊ |
5195 | else␊ |
5196 | {␊ |
5197 | retval=RetVal_ListItem;␊ |
5198 | }␊ |
5199 | break;␊ |
5200 | case HTML_BOLD:␊ |
5201 | handleStyleEnter(this,m_children,DocStyleChange::Bold,&g_token->attribs);␊ |
5202 | break;␊ |
5203 | case HTML_CODE:␊ |
5204 | if (getLanguageFromFileName(g_fileName)==SrcLangExt_CSharp) ␊ |
5205 | // for C# code we treat <code> as an XML tag␊ |
5206 | {␊ |
5207 | doctokenizerYYsetStateXmlCode();␊ |
5208 | retval = handleStartCode();␊ |
5209 | }␊ |
5210 | else // normal HTML markup␊ |
5211 | {␊ |
5212 | handleStyleEnter(this,m_children,DocStyleChange::Code,&g_token->attribs);␊ |
5213 | }␊ |
5214 | break;␊ |
5215 | case HTML_EMPHASIS:␊ |
5216 | handleStyleEnter(this,m_children,DocStyleChange::Italic,&g_token->attribs);␊ |
5217 | break;␊ |
5218 | case HTML_DIV:␊ |
5219 | handleStyleEnter(this,m_children,DocStyleChange::Div,&g_token->attribs);␊ |
5220 | break;␊ |
5221 | case HTML_SPAN:␊ |
5222 | handleStyleEnter(this,m_children,DocStyleChange::Span,&g_token->attribs);␊ |
5223 | break;␊ |
5224 | case HTML_SUB:␊ |
5225 | handleStyleEnter(this,m_children,DocStyleChange::Subscript,&g_token->attribs);␊ |
5226 | break;␊ |
5227 | case HTML_SUP:␊ |
5228 | handleStyleEnter(this,m_children,DocStyleChange::Superscript,&g_token->attribs);␊ |
5229 | break;␊ |
5230 | case HTML_CENTER:␊ |
5231 | handleStyleEnter(this,m_children,DocStyleChange::Center,&g_token->attribs);␊ |
5232 | break;␊ |
5233 | case HTML_SMALL:␊ |
5234 | handleStyleEnter(this,m_children,DocStyleChange::Small,&g_token->attribs);␊ |
5235 | break;␊ |
5236 | case HTML_PRE:␊ |
5237 | handleStyleEnter(this,m_children,DocStyleChange::Preformatted,&g_token->attribs);␊ |
5238 | setInsidePreformatted(TRUE);␊ |
5239 | //doctokenizerYYsetInsidePre(TRUE);␊ |
5240 | break;␊ |
5241 | case HTML_P:␊ |
5242 | retval=TK_NEWPARA;␊ |
5243 | break;␊ |
5244 | case HTML_DL:␊ |
5245 | {␊ |
5246 | DocHtmlDescList *list = new DocHtmlDescList(this,tagHtmlAttribs);␊ |
5247 | m_children.append(list);␊ |
5248 | retval=list->parse();␊ |
5249 | }␊ |
5250 | break;␊ |
5251 | case HTML_DT:␊ |
5252 | retval = RetVal_DescTitle;␊ |
5253 | break;␊ |
5254 | case HTML_DD:␊ |
5255 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Unexpected tag <dd> found");␊ |
5256 | break;␊ |
5257 | case HTML_TABLE:␊ |
5258 | {␊ |
5259 | DocHtmlTable *table = new DocHtmlTable(this,tagHtmlAttribs);␊ |
5260 | m_children.append(table);␊ |
5261 | retval=table->parse();␊ |
5262 | }␊ |
5263 | break;␊ |
5264 | case HTML_TR:␊ |
5265 | retval = RetVal_TableRow;␊ |
5266 | break;␊ |
5267 | case HTML_TD:␊ |
5268 | retval = RetVal_TableCell;␊ |
5269 | break;␊ |
5270 | case HTML_TH:␊ |
5271 | retval = RetVal_TableHCell;␊ |
5272 | break;␊ |
5273 | case HTML_CAPTION:␊ |
5274 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Unexpected tag <caption> found");␊ |
5275 | break;␊ |
5276 | case HTML_BR:␊ |
5277 | {␊ |
5278 | DocLineBreak *lb = new DocLineBreak(this);␊ |
5279 | m_children.append(lb);␊ |
5280 | }␊ |
5281 | break;␊ |
5282 | case HTML_HR:␊ |
5283 | {␊ |
5284 | DocHorRuler *hr = new DocHorRuler(this);␊ |
5285 | m_children.append(hr);␊ |
5286 | }␊ |
5287 | break;␊ |
5288 | case HTML_A:␊ |
5289 | retval=handleAHref(this,m_children,tagHtmlAttribs);␊ |
5290 | break;␊ |
5291 | case HTML_H1:␊ |
5292 | retval=handleHtmlHeader(tagHtmlAttribs,1);␊ |
5293 | break;␊ |
5294 | case HTML_H2:␊ |
5295 | retval=handleHtmlHeader(tagHtmlAttribs,2);␊ |
5296 | break;␊ |
5297 | case HTML_H3:␊ |
5298 | retval=handleHtmlHeader(tagHtmlAttribs,3);␊ |
5299 | break;␊ |
5300 | case HTML_H4:␊ |
5301 | retval=handleHtmlHeader(tagHtmlAttribs,4);␊ |
5302 | break;␊ |
5303 | case HTML_H5:␊ |
5304 | retval=handleHtmlHeader(tagHtmlAttribs,5);␊ |
5305 | break;␊ |
5306 | case HTML_H6:␊ |
5307 | retval=handleHtmlHeader(tagHtmlAttribs,6);␊ |
5308 | break;␊ |
5309 | case HTML_IMG:␊ |
5310 | {␊ |
5311 | HtmlAttribListIterator li(tagHtmlAttribs);␊ |
5312 | HtmlAttrib *opt;␊ |
5313 | bool found=FALSE;␊ |
5314 | int index=0;␊ |
5315 | for (li.toFirst();(opt=li.current());++li,++index)␊ |
5316 | {␊ |
5317 | //printf("option name=%s value=%s\n",opt->name.data(),opt->value.data());␊ |
5318 | if (opt->name=="src" && !opt->value.isEmpty())␊ |
5319 | {␊ |
5320 | // copy attributes␊ |
5321 | HtmlAttribList attrList = tagHtmlAttribs;␊ |
5322 | // and remove the src attribute␊ |
5323 | bool result = attrList.remove(index);␊ |
5324 | ASSERT(result);␊ |
5325 | DocImage *img = new DocImage(this,attrList,opt->value,DocImage::Html);␊ |
5326 | m_children.append(img);␊ |
5327 | found = TRUE;␊ |
5328 | }␊ |
5329 | }␊ |
5330 | if (!found)␊ |
5331 | {␊ |
5332 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: IMG tag does not have a SRC attribute!\n");␊ |
5333 | }␊ |
5334 | }␊ |
5335 | break;␊ |
5336 | ␊ |
5337 | case XML_SUMMARY:␊ |
5338 | case XML_REMARKS:␊ |
5339 | case XML_VALUE:␊ |
5340 | case XML_PARA:␊ |
5341 | if (!m_children.isEmpty())␊ |
5342 | {␊ |
5343 | retval = TK_NEWPARA;␊ |
5344 | }␊ |
5345 | break;␊ |
5346 | case XML_EXAMPLE:␊ |
5347 | case XML_DESCRIPTION:␊ |
5348 | if (insideTable(this))␊ |
5349 | {␊ |
5350 | retval=RetVal_TableCell;␊ |
5351 | }␊ |
5352 | break;␊ |
5353 | case XML_C:␊ |
5354 | handleStyleEnter(this,m_children,DocStyleChange::Code,&g_token->attribs);␊ |
5355 | break;␊ |
5356 | case XML_PARAM:␊ |
5357 | case XML_TYPEPARAM:␊ |
5358 | {␊ |
5359 | QCString paramName;␊ |
5360 | if (findAttribute(tagHtmlAttribs,"name",¶mName))␊ |
5361 | {␊ |
5362 | if (paramName.isEmpty())␊ |
5363 | {␊ |
5364 | if (Config_getBool("WARN_NO_PARAMDOC"))␊ |
5365 | {␊ |
5366 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: empty 'name' attribute for <param> tag.");␊ |
5367 | }␊ |
5368 | }␊ |
5369 | else␊ |
5370 | {␊ |
5371 | retval = handleParamSection(paramName,␊ |
5372 | tagId==XML_PARAM ? DocParamSect::Param : DocParamSect::TemplateParam,␊ |
5373 | TRUE);␊ |
5374 | }␊ |
5375 | }␊ |
5376 | else␊ |
5377 | {␊ |
5378 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Missing 'name' attribute from <param> tag.");␊ |
5379 | }␊ |
5380 | }␊ |
5381 | break;␊ |
5382 | case XML_PARAMREF:␊ |
5383 | case XML_TYPEPARAMREF:␊ |
5384 | {␊ |
5385 | QCString paramName;␊ |
5386 | if (findAttribute(tagHtmlAttribs,"name",¶mName))␊ |
5387 | {␊ |
5388 | //printf("paramName=%s\n",paramName.data());␊ |
5389 | m_children.append(new DocStyleChange(this,g_nodeStack.count(),DocStyleChange::Italic,TRUE));␊ |
5390 | m_children.append(new DocWord(this,paramName)); ␊ |
5391 | m_children.append(new DocStyleChange(this,g_nodeStack.count(),DocStyleChange::Italic,FALSE));␊ |
5392 | if (retval!=TK_WORD) m_children.append(new DocWhiteSpace(this," "));␊ |
5393 | }␊ |
5394 | else␊ |
5395 | {␊ |
5396 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Missing 'name' attribute from <param%sref> tag.",tagId==XML_PARAMREF?"":"type");␊ |
5397 | }␊ |
5398 | }␊ |
5399 | break;␊ |
5400 | case XML_EXCEPTION:␊ |
5401 | {␊ |
5402 | QCString exceptName;␊ |
5403 | if (findAttribute(tagHtmlAttribs,"cref",&exceptName))␊ |
5404 | {␊ |
5405 | retval = handleParamSection(exceptName,DocParamSect::Exception,TRUE);␊ |
5406 | }␊ |
5407 | else␊ |
5408 | {␊ |
5409 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Missing 'name' attribute from <exception> tag.");␊ |
5410 | }␊ |
5411 | }␊ |
5412 | break;␊ |
5413 | case XML_ITEM:␊ |
5414 | case XML_LISTHEADER:␊ |
5415 | if (insideTable(this))␊ |
5416 | {␊ |
5417 | retval=RetVal_TableRow;␊ |
5418 | }␊ |
5419 | else if (insideUL(this) || insideOL(this))␊ |
5420 | {␊ |
5421 | retval=RetVal_ListItem;␊ |
5422 | }␊ |
5423 | else␊ |
5424 | {␊ |
5425 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: lonely <item> tag found");␊ |
5426 | }␊ |
5427 | break;␊ |
5428 | case XML_RETURNS:␊ |
5429 | retval = handleSimpleSection(DocSimpleSect::Return,TRUE);␊ |
5430 | g_hasReturnCommand=TRUE;␊ |
5431 | break;␊ |
5432 | case XML_TERM:␊ |
5433 | //m_children.append(new DocStyleChange(this,g_nodeStack.count(),DocStyleChange::Bold,TRUE));␊ |
5434 | if (insideTable(this))␊ |
5435 | {␊ |
5436 | retval=RetVal_TableCell;␊ |
5437 | }␊ |
5438 | break;␊ |
5439 | case XML_SEE:␊ |
5440 | // I'm not sure if <see> is the same as <seealso> or if it␊ |
5441 | // should you link a member without producing a section. The␊ |
5442 | // C# specification is extremely vague about this (but what else ␊ |
5443 | // can we expect from Microsoft...)␊ |
5444 | {␊ |
5445 | QCString cref;␊ |
5446 | //printf("XML_SEE: empty tag=%d\n",g_token->emptyTag);␊ |
5447 | if (findAttribute(tagHtmlAttribs,"cref",&cref))␊ |
5448 | {␊ |
5449 | if (g_token->emptyTag) // <see cref="..."/> style␊ |
5450 | {␊ |
5451 | bool inSeeBlock = g_inSeeBlock;␊ |
5452 | g_token->name = cref;␊ |
5453 | g_inSeeBlock = TRUE;␊ |
5454 | handleLinkedWord(this,m_children);␊ |
5455 | g_inSeeBlock = inSeeBlock;␊ |
5456 | }␊ |
5457 | else // <see cref="...">...</see> style␊ |
5458 | {␊ |
5459 | //DocRef *ref = new DocRef(this,cref);␊ |
5460 | //m_children.append(ref);␊ |
5461 | //ref->parse();␊ |
5462 | doctokenizerYYsetStatePara();␊ |
5463 | DocLink *lnk = new DocLink(this,cref);␊ |
5464 | m_children.append(lnk);␊ |
5465 | QCString leftOver = lnk->parse(FALSE,TRUE);␊ |
5466 | if (!leftOver.isEmpty())␊ |
5467 | {␊ |
5468 | m_children.append(new DocWord(this,leftOver));␊ |
5469 | }␊ |
5470 | }␊ |
5471 | }␊ |
5472 | else␊ |
5473 | {␊ |
5474 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Missing 'cref' attribute from <see> tag.");␊ |
5475 | }␊ |
5476 | }␊ |
5477 | break;␊ |
5478 | case XML_SEEALSO:␊ |
5479 | {␊ |
5480 | QCString cref;␊ |
5481 | if (findAttribute(tagHtmlAttribs,"cref",&cref))␊ |
5482 | {␊ |
5483 | // Look for an existing "see" section␊ |
5484 | DocSimpleSect *ss=0;␊ |
5485 | QListIterator<DocNode> cli(m_children);␊ |
5486 | DocNode *n;␊ |
5487 | for (cli.toFirst();(n=cli.current());++cli)␊ |
5488 | {␊ |
5489 | if (n->kind()==Kind_SimpleSect && ((DocSimpleSect *)n)->type()==DocSimpleSect::See)␊ |
5490 | {␊ |
5491 | ss = (DocSimpleSect *)n;␊ |
5492 | }␊ |
5493 | }␊ |
5494 | ␊ |
5495 | if (!ss) // start new section␊ |
5496 | {␊ |
5497 | ss=new DocSimpleSect(this,DocSimpleSect::See);␊ |
5498 | m_children.append(ss);␊ |
5499 | }␊ |
5500 | ␊ |
5501 | ss->appendLinkWord(cref);␊ |
5502 | retval = RetVal_OK;␊ |
5503 | }␊ |
5504 | else␊ |
5505 | {␊ |
5506 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Missing 'cref' attribute from <seealso> tag.");␊ |
5507 | }␊ |
5508 | }␊ |
5509 | break;␊ |
5510 | case XML_LIST:␊ |
5511 | {␊ |
5512 | QCString type;␊ |
5513 | findAttribute(tagHtmlAttribs,"type",&type);␊ |
5514 | DocHtmlList::Type listType = DocHtmlList::Unordered;␊ |
5515 | HtmlAttribList emptyList;␊ |
5516 | if (type=="number")␊ |
5517 | {␊ |
5518 | listType=DocHtmlList::Ordered;␊ |
5519 | }␊ |
5520 | if (type=="table")␊ |
5521 | {␊ |
5522 | DocHtmlTable *table = new DocHtmlTable(this,emptyList);␊ |
5523 | m_children.append(table);␊ |
5524 | retval=table->parseXml();␊ |
5525 | }␊ |
5526 | else␊ |
5527 | {␊ |
5528 | DocHtmlList *list = new DocHtmlList(this,emptyList,listType);␊ |
5529 | m_children.append(list);␊ |
5530 | retval=list->parseXml();␊ |
5531 | }␊ |
5532 | }␊ |
5533 | break;␊ |
5534 | case XML_INCLUDE:␊ |
5535 | case XML_PERMISSION:␊ |
5536 | // These tags are defined in .Net but are currently unsupported␊ |
5537 | break;␊ |
5538 | case HTML_UNKNOWN:␊ |
5539 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Unsupported xml/html tag <%s> found", qPrint(tagName));␊ |
5540 | m_children.append(new DocWord(this, "<"+tagName+tagHtmlAttribs.toString()+">"));␊ |
5541 | break;␊ |
5542 | default:␊ |
5543 | // we should not get here!␊ |
5544 | ASSERT(0);␊ |
5545 | break;␊ |
5546 | }␊ |
5547 | return retval;␊ |
5548 | }␊ |
5549 | ␊ |
5550 | int DocPara::handleHtmlEndTag(const QCString &tagName)␊ |
5551 | {␊ |
5552 | DBG(("handleHtmlEndTag(%s)\n",qPrint(tagName)));␊ |
5553 | int tagId = Mappers::htmlTagMapper->map(tagName);␊ |
5554 | int retval=RetVal_OK;␊ |
5555 | switch (tagId)␊ |
5556 | {␊ |
5557 | case HTML_UL: ␊ |
5558 | if (!insideUL(this))␊ |
5559 | {␊ |
5560 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: found </ul> tag without matching <ul>");␊ |
5561 | }␊ |
5562 | else␊ |
5563 | {␊ |
5564 | retval=RetVal_EndList;␊ |
5565 | }␊ |
5566 | break;␊ |
5567 | case HTML_OL: ␊ |
5568 | if (!insideOL(this))␊ |
5569 | {␊ |
5570 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: found </ol> tag without matching <ol>");␊ |
5571 | }␊ |
5572 | else␊ |
5573 | {␊ |
5574 | retval=RetVal_EndList;␊ |
5575 | }␊ |
5576 | break;␊ |
5577 | case HTML_LI:␊ |
5578 | if (!insideLI(this))␊ |
5579 | {␊ |
5580 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: found </li> tag without matching <li>");␊ |
5581 | }␊ |
5582 | else␊ |
5583 | {␊ |
5584 | // ignore </li> tags␊ |
5585 | }␊ |
5586 | break;␊ |
5587 | //case HTML_PRE:␊ |
5588 | // if (!insidePRE(this))␊ |
5589 | // {␊ |
5590 | // warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: found </pre> tag without matching <pre>");␊ |
5591 | // }␊ |
5592 | // else␊ |
5593 | // {␊ |
5594 | // retval=RetVal_EndPre;␊ |
5595 | // }␊ |
5596 | // break;␊ |
5597 | case HTML_BOLD:␊ |
5598 | handleStyleLeave(this,m_children,DocStyleChange::Bold,"b");␊ |
5599 | break;␊ |
5600 | case HTML_CODE:␊ |
5601 | handleStyleLeave(this,m_children,DocStyleChange::Code,"code");␊ |
5602 | break;␊ |
5603 | case HTML_EMPHASIS:␊ |
5604 | handleStyleLeave(this,m_children,DocStyleChange::Italic,"em");␊ |
5605 | break;␊ |
5606 | case HTML_DIV:␊ |
5607 | handleStyleLeave(this,m_children,DocStyleChange::Div,"div");␊ |
5608 | break;␊ |
5609 | case HTML_SPAN:␊ |
5610 | handleStyleLeave(this,m_children,DocStyleChange::Span,"span");␊ |
5611 | break;␊ |
5612 | case HTML_SUB:␊ |
5613 | handleStyleLeave(this,m_children,DocStyleChange::Subscript,"sub");␊ |
5614 | break;␊ |
5615 | case HTML_SUP:␊ |
5616 | handleStyleLeave(this,m_children,DocStyleChange::Superscript,"sup");␊ |
5617 | break;␊ |
5618 | case HTML_CENTER:␊ |
5619 | handleStyleLeave(this,m_children,DocStyleChange::Center,"center");␊ |
5620 | break;␊ |
5621 | case HTML_SMALL:␊ |
5622 | handleStyleLeave(this,m_children,DocStyleChange::Small,"small");␊ |
5623 | break;␊ |
5624 | case HTML_PRE:␊ |
5625 | handleStyleLeave(this,m_children,DocStyleChange::Preformatted,"pre");␊ |
5626 | setInsidePreformatted(FALSE);␊ |
5627 | //doctokenizerYYsetInsidePre(FALSE);␊ |
5628 | break;␊ |
5629 | case HTML_P:␊ |
5630 | // ignore </p> tag␊ |
5631 | break;␊ |
5632 | case HTML_DL:␊ |
5633 | retval=RetVal_EndDesc;␊ |
5634 | break;␊ |
5635 | case HTML_DT:␊ |
5636 | // ignore </dt> tag␊ |
5637 | break;␊ |
5638 | case HTML_DD:␊ |
5639 | // ignore </dd> tag␊ |
5640 | break;␊ |
5641 | case HTML_TABLE:␊ |
5642 | retval=RetVal_EndTable;␊ |
5643 | break;␊ |
5644 | case HTML_TR:␊ |
5645 | // ignore </tr> tag␊ |
5646 | break;␊ |
5647 | case HTML_TD:␊ |
5648 | // ignore </td> tag␊ |
5649 | break;␊ |
5650 | case HTML_TH:␊ |
5651 | // ignore </th> tag␊ |
5652 | break;␊ |
5653 | case HTML_CAPTION:␊ |
5654 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Unexpected tag </caption> found");␊ |
5655 | break;␊ |
5656 | case HTML_BR:␊ |
5657 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Illegal </br> tag found\n");␊ |
5658 | break;␊ |
5659 | case HTML_H1:␊ |
5660 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Unexpected tag </h1> found");␊ |
5661 | break;␊ |
5662 | case HTML_H2:␊ |
5663 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Unexpected tag </h2> found");␊ |
5664 | break;␊ |
5665 | case HTML_H3:␊ |
5666 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Unexpected tag </h3> found");␊ |
5667 | break;␊ |
5668 | case HTML_IMG:␊ |
5669 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Unexpected tag </img> found");␊ |
5670 | break;␊ |
5671 | case HTML_HR:␊ |
5672 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Unexpected tag </hr> found");␊ |
5673 | break;␊ |
5674 | case HTML_A:␊ |
5675 | //warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Unexpected tag </a> found");␊ |
5676 | // ignore </a> tag (can be part of <a name=...></a>␊ |
5677 | break;␊ |
5678 | ␊ |
5679 | case XML_TERM:␊ |
5680 | //m_children.append(new DocStyleChange(this,g_nodeStack.count(),DocStyleChange::Bold,FALSE));␊ |
5681 | break;␊ |
5682 | case XML_SUMMARY:␊ |
5683 | case XML_REMARKS:␊ |
5684 | case XML_PARA:␊ |
5685 | case XML_VALUE:␊ |
5686 | case XML_LIST:␊ |
5687 | case XML_EXAMPLE:␊ |
5688 | case XML_PARAM:␊ |
5689 | case XML_TYPEPARAM:␊ |
5690 | case XML_RETURNS:␊ |
5691 | case XML_SEE:␊ |
5692 | case XML_SEEALSO:␊ |
5693 | case XML_EXCEPTION:␊ |
5694 | retval = RetVal_CloseXml;␊ |
5695 | break;␊ |
5696 | case XML_C:␊ |
5697 | handleStyleLeave(this,m_children,DocStyleChange::Code,"c");␊ |
5698 | break;␊ |
5699 | case XML_ITEM:␊ |
5700 | case XML_LISTHEADER:␊ |
5701 | case XML_INCLUDE:␊ |
5702 | case XML_PERMISSION:␊ |
5703 | case XML_DESCRIPTION:␊ |
5704 | case XML_PARAMREF:␊ |
5705 | case XML_TYPEPARAMREF:␊ |
5706 | // These tags are defined in .Net but are currently unsupported␊ |
5707 | break;␊ |
5708 | case HTML_UNKNOWN:␊ |
5709 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Unsupported xml/html tag </%s> found", qPrint(tagName));␊ |
5710 | m_children.append(new DocWord(this,"</"+tagName+">"));␊ |
5711 | break;␊ |
5712 | default:␊ |
5713 | // we should not get here!␊ |
5714 | warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected end tag %s\n",qPrint(tagName));␊ |
5715 | ASSERT(0);␊ |
5716 | break;␊ |
5717 | }␊ |
5718 | return retval;␊ |
5719 | }␊ |
5720 | ␊ |
5721 | int DocPara::parse()␊ |
5722 | {␊ |
5723 | DBG(("DocPara::parse() start\n"));␊ |
5724 | g_nodeStack.push(this);␊ |
5725 | // handle style commands "inherited" from the previous paragraph␊ |
5726 | handleInitialStyleCommands(this,m_children);␊ |
5727 | int tok;␊ |
5728 | int retval=0;␊ |
5729 | while ((tok=doctokenizerYYlex())) // get the next token␊ |
5730 | {␊ |
5731 | reparsetoken:␊ |
5732 | DBG(("token %s at %d",tokToString(tok),doctokenizerYYlineno));␊ |
5733 | if (tok==TK_WORD || tok==TK_LNKWORD || tok==TK_SYMBOL || tok==TK_URL || ␊ |
5734 | tok==TK_COMMAND || tok==TK_HTMLTAG␊ |
5735 | )␊ |
5736 | {␊ |
5737 | DBG((" name=%s",qPrint(g_token->name)));␊ |
5738 | }␊ |
5739 | DBG(("\n"));␊ |
5740 | switch(tok)␊ |
5741 | {␊ |
5742 | case TK_WORD:␊ |
5743 | m_children.append(new DocWord(this,g_token->name));␊ |
5744 | break;␊ |
5745 | case TK_LNKWORD:␊ |
5746 | handleLinkedWord(this,m_children);␊ |
5747 | break;␊ |
5748 | case TK_URL:␊ |
5749 | m_children.append(new DocURL(this,g_token->name,g_token->isEMailAddr));␊ |
5750 | break;␊ |
5751 | case TK_WHITESPACE:␊ |
5752 | {␊ |
5753 | // prevent leading whitespace and collapse multiple whitespace areas␊ |
5754 | DocNode::Kind k;␊ |
5755 | if (insidePRE(this) || // all whitespace is relevant␊ |
5756 | (␊ |
5757 | // remove leading whitespace ␊ |
5758 | !m_children.isEmpty() && ␊ |
5759 | // and whitespace after certain constructs␊ |
5760 | (k=m_children.last()->kind())!=DocNode::Kind_HtmlDescList &&␊ |
5761 | k!=DocNode::Kind_HtmlTable &&␊ |
5762 | k!=DocNode::Kind_HtmlList &&␊ |
5763 | k!=DocNode::Kind_SimpleSect &&␊ |
5764 | k!=DocNode::Kind_AutoList &&␊ |
5765 | k!=DocNode::Kind_SimpleList &&␊ |
5766 | /*k!=DocNode::Kind_Verbatim &&*/␊ |
5767 | k!=DocNode::Kind_HtmlHeader &&␊ |
5768 | k!=DocNode::Kind_ParamSect &&␊ |
5769 | k!=DocNode::Kind_XRefItem␊ |
5770 | )␊ |
5771 | )␊ |
5772 | {␊ |
5773 | m_children.append(new DocWhiteSpace(this,g_token->chars));␊ |
5774 | }␊ |
5775 | }␊ |
5776 | break;␊ |
5777 | case TK_LISTITEM:␊ |
5778 | {␊ |
5779 | DBG(("found list item at %d parent=%d\n",g_token->indent,parent()->kind()));␊ |
5780 | DocNode *n=parent();␊ |
5781 | while (n && n->kind()!=DocNode::Kind_AutoList) n=n->parent();␊ |
5782 | if (n) // we found an auto list up in the hierarchy␊ |
5783 | {␊ |
5784 | DocAutoList *al = (DocAutoList *)n;␊ |
5785 | DBG(("previous list item at %d\n",al->indent()));␊ |
5786 | if (al->indent()>=g_token->indent) ␊ |
5787 | // new item at the same or lower indent level␊ |
5788 | {␊ |
5789 | retval=TK_LISTITEM;␊ |
5790 | goto endparagraph;␊ |
5791 | }␊ |
5792 | }␊ |
5793 | ␊ |
5794 | // determine list depth␊ |
5795 | int depth = 0;␊ |
5796 | n=parent();␊ |
5797 | while(n) ␊ |
5798 | {␊ |
5799 | if(n->kind() == DocNode::Kind_AutoList) ++depth;␊ |
5800 | n=n->parent();␊ |
5801 | }␊ |
5802 | ␊ |
5803 | // first item or sub list => create new list␊ |
5804 | DocAutoList *al=0;␊ |
5805 | do␊ |
5806 | {␊ |
5807 | al = new DocAutoList(this,g_token->indent,g_token->isEnumList,␊ |
5808 | depth);␊ |
5809 | m_children.append(al);␊ |
5810 | retval = al->parse();␊ |
5811 | } while (retval==TK_LISTITEM && // new list␊ |
5812 | al->indent()==g_token->indent // at same indent level␊ |
5813 | );␊ |
5814 | ␊ |
5815 | // check the return value␊ |
5816 | if (retval==RetVal_SimpleSec) // auto list ended due to simple section command␊ |
5817 | {␊ |
5818 | // Reparse the token that ended the section at this level,␊ |
5819 | // so a new simple section will be started at this level.␊ |
5820 | // This is the same as unputting the last read token and continuing.␊ |
5821 | g_token->name = g_token->simpleSectName;␊ |
5822 | if (g_token->name.left(4)=="rcs:") // RCS section␊ |
5823 | {␊ |
5824 | g_token->name = g_token->name.mid(4);␊ |
5825 | g_token->text = g_token->simpleSectText;␊ |
5826 | tok = TK_RCSTAG;␊ |
5827 | }␊ |
5828 | else // other section␊ |
5829 | {␊ |
5830 | tok = TK_COMMAND;␊ |
5831 | }␊ |
5832 | DBG(("reparsing command %s\n",qPrint(g_token->name)));␊ |
5833 | goto reparsetoken;␊ |
5834 | }␊ |
5835 | else if (retval==TK_ENDLIST)␊ |
5836 | {␊ |
5837 | if (al->indent()>g_token->indent) // end list␊ |
5838 | {␊ |
5839 | goto endparagraph;␊ |
5840 | }␊ |
5841 | else // continue with current paragraph␊ |
5842 | {␊ |
5843 | }␊ |
5844 | }␊ |
5845 | else // paragraph ended due to TK_NEWPARA, TK_LISTITEM, or EOF␊ |
5846 | {␊ |
5847 | goto endparagraph;␊ |
5848 | }␊ |
5849 | }␊ |
5850 | break;␊ |
5851 | case TK_ENDLIST: ␊ |
5852 | DBG(("Found end of list inside of paragraph at line %d\n",doctokenizerYYlineno));␊ |
5853 | if (parent()->kind()==DocNode::Kind_AutoListItem)␊ |
5854 | {␊ |
5855 | ASSERT(parent()->parent()->kind()==DocNode::Kind_AutoList);␊ |
5856 | DocAutoList *al = (DocAutoList *)parent()->parent();␊ |
5857 | if (al->indent()>=g_token->indent)␊ |
5858 | {␊ |
5859 | // end of list marker ends this paragraph␊ |
5860 | retval=TK_ENDLIST;␊ |
5861 | goto endparagraph;␊ |
5862 | }␊ |
5863 | else␊ |
5864 | {␊ |
5865 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: End of list marker found "␊ |
5866 | "has invalid indent level");␊ |
5867 | }␊ |
5868 | }␊ |
5869 | else␊ |
5870 | {␊ |
5871 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: End of list marker found without any preceding "␊ |
5872 | "list items");␊ |
5873 | }␊ |
5874 | break;␊ |
5875 | case TK_COMMAND: ␊ |
5876 | {␊ |
5877 | // see if we have to start a simple section␊ |
5878 | int cmd = Mappers::cmdMapper->map(g_token->name);␊ |
5879 | DocNode *n=parent();␊ |
5880 | while (n && ␊ |
5881 | n->kind()!=DocNode::Kind_SimpleSect && ␊ |
5882 | n->kind()!=DocNode::Kind_ParamSect␊ |
5883 | ) ␊ |
5884 | {␊ |
5885 | n=n->parent();␊ |
5886 | }␊ |
5887 | if (cmd&SIMPLESECT_BIT)␊ |
5888 | {␊ |
5889 | if (n) // already in a simple section␊ |
5890 | {␊ |
5891 | // simple section cannot start in this paragraph, need␊ |
5892 | // to unwind the stack and remember the command.␊ |
5893 | g_token->simpleSectName = g_token->name.copy();␊ |
5894 | retval=RetVal_SimpleSec;␊ |
5895 | goto endparagraph;␊ |
5896 | }␊ |
5897 | }␊ |
5898 | // see if we are in a simple list␊ |
5899 | n=parent();␊ |
5900 | while (n && n->kind()!=DocNode::Kind_SimpleListItem) n=n->parent();␊ |
5901 | if (n)␊ |
5902 | {␊ |
5903 | if (cmd==CMD_LI)␊ |
5904 | {␊ |
5905 | retval=RetVal_ListItem;␊ |
5906 | goto endparagraph;␊ |
5907 | }␊ |
5908 | }␊ |
5909 | ␊ |
5910 | // handle the command␊ |
5911 | retval=handleCommand(g_token->name.copy());␊ |
5912 | DBG(("handleCommand returns %x\n",retval));␊ |
5913 | ␊ |
5914 | // check the return value␊ |
5915 | if (retval==RetVal_SimpleSec)␊ |
5916 | {␊ |
5917 | // Reparse the token that ended the section at this level,␊ |
5918 | // so a new simple section will be started at this level.␊ |
5919 | // This is the same as unputting the last read token and continuing.␊ |
5920 | g_token->name = g_token->simpleSectName;␊ |
5921 | if (g_token->name.left(4)=="rcs:") // RCS section␊ |
5922 | {␊ |
5923 | g_token->name = g_token->name.mid(4);␊ |
5924 | g_token->text = g_token->simpleSectText;␊ |
5925 | tok = TK_RCSTAG;␊ |
5926 | }␊ |
5927 | else // other section␊ |
5928 | {␊ |
5929 | tok = TK_COMMAND;␊ |
5930 | }␊ |
5931 | DBG(("reparsing command %s\n",qPrint(g_token->name)));␊ |
5932 | goto reparsetoken;␊ |
5933 | }␊ |
5934 | else if (retval==RetVal_OK) ␊ |
5935 | {␊ |
5936 | // the command ended normally, keep scanning for new tokens.␊ |
5937 | retval = 0;␊ |
5938 | }␊ |
5939 | else if (retval>0 && retval<RetVal_OK)␊ |
5940 | { ␊ |
5941 | // the command ended with a new command, reparse this token␊ |
5942 | tok = retval;␊ |
5943 | goto reparsetoken;␊ |
5944 | }␊ |
5945 | else // end of file, end of paragraph, start or end of section ␊ |
5946 | // or some auto list marker␊ |
5947 | {␊ |
5948 | goto endparagraph;␊ |
5949 | }␊ |
5950 | }␊ |
5951 | break;␊ |
5952 | case TK_HTMLTAG: ␊ |
5953 | {␊ |
5954 | if (!g_token->endTag) // found a start tag␊ |
5955 | {␊ |
5956 | retval = handleHtmlStartTag(g_token->name,g_token->attribs);␊ |
5957 | }␊ |
5958 | else // found an end tag␊ |
5959 | {␊ |
5960 | retval = handleHtmlEndTag(g_token->name);␊ |
5961 | }␊ |
5962 | if (retval==RetVal_OK) ␊ |
5963 | {␊ |
5964 | // the command ended normally, keep scanner for new tokens.␊ |
5965 | retval = 0;␊ |
5966 | }␊ |
5967 | else␊ |
5968 | {␊ |
5969 | goto endparagraph;␊ |
5970 | }␊ |
5971 | }␊ |
5972 | break;␊ |
5973 | case TK_SYMBOL: ␊ |
5974 | {␊ |
5975 | char letter='\0';␊ |
5976 | DocSymbol::SymType s = DocSymbol::decodeSymbol(g_token->name,&letter);␊ |
5977 | if (s!=DocSymbol::Unknown)␊ |
5978 | {␊ |
5979 | m_children.append(new DocSymbol(this,s,letter));␊ |
5980 | }␊ |
5981 | else␊ |
5982 | {␊ |
5983 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Unsupported symbol %s found",␊ |
5984 | qPrint(g_token->name));␊ |
5985 | }␊ |
5986 | break;␊ |
5987 | }␊ |
5988 | case TK_NEWPARA: ␊ |
5989 | retval=TK_NEWPARA;␊ |
5990 | goto endparagraph;␊ |
5991 | case TK_RCSTAG:␊ |
5992 | {␊ |
5993 | DocNode *n=parent();␊ |
5994 | while (n && ␊ |
5995 | n->kind()!=DocNode::Kind_SimpleSect && ␊ |
5996 | n->kind()!=DocNode::Kind_ParamSect␊ |
5997 | ) ␊ |
5998 | {␊ |
5999 | n=n->parent();␊ |
6000 | }␊ |
6001 | if (n) // already in a simple section␊ |
6002 | {␊ |
6003 | // simple section cannot start in this paragraph, need␊ |
6004 | // to unwind the stack and remember the command.␊ |
6005 | g_token->simpleSectName = "rcs:"+g_token->name;␊ |
6006 | g_token->simpleSectText = g_token->text;␊ |
6007 | retval=RetVal_SimpleSec;␊ |
6008 | goto endparagraph;␊ |
6009 | }␊ |
6010 | ␊ |
6011 | // see if we are in a simple list␊ |
6012 | DocSimpleSect *ss=new DocSimpleSect(this,DocSimpleSect::Rcs);␊ |
6013 | m_children.append(ss);␊ |
6014 | ss->parseRcs();␊ |
6015 | }␊ |
6016 | break;␊ |
6017 | default:␊ |
6018 | warn_doc_error(g_fileName,doctokenizerYYlineno,␊ |
6019 | "warning: Found unexpected token (id=%x)\n",tok);␊ |
6020 | break;␊ |
6021 | }␊ |
6022 | }␊ |
6023 | retval=0;␊ |
6024 | endparagraph:␊ |
6025 | handlePendingStyleCommands(this,m_children);␊ |
6026 | DocNode *n = g_nodeStack.pop();␊ |
6027 | ASSERT(n==this);␊ |
6028 | DBG(("DocPara::parse() end retval=%x\n",retval));␊ |
6029 | INTERNAL_ASSERT(retval==0 || retval==TK_NEWPARA || retval==TK_LISTITEM || ␊ |
6030 | retval==TK_ENDLIST || retval>RetVal_OK ␊ |
6031 | ␉);␊ |
6032 | ␊ |
6033 | return retval; ␊ |
6034 | }␊ |
6035 | ␊ |
6036 | //--------------------------------------------------------------------------␊ |
6037 | ␊ |
6038 | int DocSection::parse()␊ |
6039 | {␊ |
6040 | DBG(("DocSection::parse() start %s level=%d\n",qPrint(g_token->sectionId),m_level));␊ |
6041 | int retval=RetVal_OK;␊ |
6042 | g_nodeStack.push(this);␊ |
6043 | ␊ |
6044 | SectionInfo *sec;␊ |
6045 | if (!m_id.isEmpty())␊ |
6046 | {␊ |
6047 | sec=Doxygen::sectionDict[m_id];␊ |
6048 | if (sec)␊ |
6049 | {␊ |
6050 | m_file = sec->fileName;␊ |
6051 | m_anchor = sec->label;␊ |
6052 | m_title = sec->title;␊ |
6053 | if (m_title.isEmpty()) m_title = sec->label;␊ |
6054 | if (g_sectionDict && g_sectionDict->find(m_id)==0)␊ |
6055 | {␊ |
6056 | g_sectionDict->insert(m_id,sec);␊ |
6057 | }␊ |
6058 | }␊ |
6059 | }␊ |
6060 | ␊ |
6061 | // first parse any number of paragraphs␊ |
6062 | bool isFirst=TRUE;␊ |
6063 | DocPara *lastPar=0;␊ |
6064 | do␊ |
6065 | {␊ |
6066 | DocPara *par = new DocPara(this);␊ |
6067 | if (isFirst) { par->markFirst(); isFirst=FALSE; }␊ |
6068 | retval=par->parse();␊ |
6069 | if (!par->isEmpty()) ␊ |
6070 | {␊ |
6071 | m_children.append(par);␊ |
6072 | lastPar=par;␊ |
6073 | }␊ |
6074 | else␊ |
6075 | {␊ |
6076 | delete par;␊ |
6077 | }␊ |
6078 | if (retval==TK_LISTITEM)␊ |
6079 | {␊ |
6080 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Invalid list item found");␊ |
6081 | }␊ |
6082 | } while (retval!=0 && ␊ |
6083 | retval!=RetVal_Internal &&␊ |
6084 | retval!=RetVal_Section &&␊ |
6085 | retval!=RetVal_Subsection &&␊ |
6086 | retval!=RetVal_Subsubsection &&␊ |
6087 | retval!=RetVal_Paragraph ␊ |
6088 | );␊ |
6089 | ␊ |
6090 | if (lastPar) lastPar->markLast();␊ |
6091 | ␊ |
6092 | //printf("m_level=%d <-> %d\n",m_level,Doxygen::subpageNestingLevel);␊ |
6093 | ␊ |
6094 | if (retval==RetVal_Subsection && m_level==Doxygen::subpageNestingLevel+1)␊ |
6095 | {␊ |
6096 | // then parse any number of nested sections␊ |
6097 | while (retval==RetVal_Subsection) // more sections follow␊ |
6098 | {␊ |
6099 | //SectionInfo *sec=Doxygen::sectionDict[g_token->sectionId];␊ |
6100 | DocSection *s=new DocSection(this,␊ |
6101 | QMIN(2+Doxygen::subpageNestingLevel,5),g_token->sectionId);␊ |
6102 | m_children.append(s);␊ |
6103 | retval = s->parse();␊ |
6104 | }␊ |
6105 | }␊ |
6106 | else if (retval==RetVal_Subsubsection && m_level==Doxygen::subpageNestingLevel+2)␊ |
6107 | {␊ |
6108 | // then parse any number of nested sections␊ |
6109 | while (retval==RetVal_Subsubsection) // more sections follow␊ |
6110 | {␊ |
6111 | //SectionInfo *sec=Doxygen::sectionDict[g_token->sectionId];␊ |
6112 | DocSection *s=new DocSection(this,␊ |
6113 | QMIN(3+Doxygen::subpageNestingLevel,5),g_token->sectionId);␊ |
6114 | m_children.append(s);␊ |
6115 | retval = s->parse();␊ |
6116 | }␊ |
6117 | }␊ |
6118 | else if (retval==RetVal_Paragraph && m_level==QMIN(5,Doxygen::subpageNestingLevel+3))␊ |
6119 | {␊ |
6120 | // then parse any number of nested sections␊ |
6121 | while (retval==RetVal_Paragraph) // more sections follow␊ |
6122 | {␊ |
6123 | //SectionInfo *sec=Doxygen::sectionDict[g_token->sectionId];␊ |
6124 | DocSection *s=new DocSection(this,␊ |
6125 | QMIN(4+Doxygen::subpageNestingLevel,5),g_token->sectionId);␊ |
6126 | m_children.append(s);␊ |
6127 | retval = s->parse();␊ |
6128 | }␊ |
6129 | }␊ |
6130 | else if ((m_level<=1+Doxygen::subpageNestingLevel && retval==RetVal_Subsubsection) ||␊ |
6131 | (m_level<=2+Doxygen::subpageNestingLevel && retval==RetVal_Paragraph)␊ |
6132 | ) ␊ |
6133 | {␊ |
6134 | int level; ␊ |
6135 | if (retval==RetVal_Subsection) level=2; ␊ |
6136 | else if (retval==RetVal_Subsubsection) level=3;␊ |
6137 | else level=4;␊ |
6138 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Unexpected %s "␊ |
6139 | "command found inside %s!",␊ |
6140 | sectionLevelToName[level],sectionLevelToName[m_level]);␊ |
6141 | retval=0; // stop parsing␊ |
6142 | ␊ |
6143 | }␊ |
6144 | else if (retval==RetVal_Internal)␊ |
6145 | {␊ |
6146 | DocInternal *in = new DocInternal(this);␊ |
6147 | m_children.append(in);␊ |
6148 | retval = in->parse(m_level+1);␊ |
6149 | }␊ |
6150 | else␊ |
6151 | {␊ |
6152 | }␊ |
6153 | ␊ |
6154 | INTERNAL_ASSERT(retval==0 || ␊ |
6155 | retval==RetVal_Section || ␊ |
6156 | retval==RetVal_Subsection || ␊ |
6157 | retval==RetVal_Subsubsection || ␊ |
6158 | retval==RetVal_Paragraph || ␊ |
6159 | retval==RetVal_Internal␊ |
6160 | );␊ |
6161 | ␊ |
6162 | DBG(("DocSection::parse() end\n"));␊ |
6163 | DocNode *n = g_nodeStack.pop();␊ |
6164 | ASSERT(n==this);␊ |
6165 | return retval;␊ |
6166 | }␊ |
6167 | ␊ |
6168 | //--------------------------------------------------------------------------␊ |
6169 | ␊ |
6170 | void DocText::parse()␊ |
6171 | {␊ |
6172 | DBG(("DocText::parse() start\n"));␊ |
6173 | g_nodeStack.push(this);␊ |
6174 | doctokenizerYYsetStateText();␊ |
6175 | ␊ |
6176 | int tok;␊ |
6177 | while ((tok=doctokenizerYYlex())) // get the next token␊ |
6178 | {␊ |
6179 | switch(tok)␊ |
6180 | {␊ |
6181 | case TK_WORD: ␊ |
6182 | ␉m_children.append(new DocWord(this,g_token->name));␊ |
6183 | ␉break;␊ |
6184 | case TK_WHITESPACE: ␊ |
6185 | m_children.append(new DocWhiteSpace(this,g_token->chars));␊ |
6186 | ␉break;␊ |
6187 | case TK_SYMBOL: ␊ |
6188 | {␊ |
6189 | char letter='\0';␊ |
6190 | DocSymbol::SymType s = DocSymbol::decodeSymbol(g_token->name,&letter);␊ |
6191 | if (s!=DocSymbol::Unknown)␊ |
6192 | {␊ |
6193 | m_children.append(new DocSymbol(this,s,letter));␊ |
6194 | }␊ |
6195 | else␊ |
6196 | {␊ |
6197 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Unsupported symbol %s found",␊ |
6198 | qPrint(g_token->name));␊ |
6199 | }␊ |
6200 | }␊ |
6201 | break;␊ |
6202 | case TK_COMMAND: ␊ |
6203 | switch (Mappers::cmdMapper->map(g_token->name))␊ |
6204 | {␊ |
6205 | case CMD_BSLASH:␊ |
6206 | m_children.append(new DocSymbol(this,DocSymbol::BSlash));␊ |
6207 | break;␊ |
6208 | case CMD_AT:␊ |
6209 | m_children.append(new DocSymbol(this,DocSymbol::At));␊ |
6210 | break;␊ |
6211 | case CMD_LESS:␊ |
6212 | m_children.append(new DocSymbol(this,DocSymbol::Less));␊ |
6213 | break;␊ |
6214 | case CMD_GREATER:␊ |
6215 | m_children.append(new DocSymbol(this,DocSymbol::Greater));␊ |
6216 | break;␊ |
6217 | case CMD_AMP:␊ |
6218 | m_children.append(new DocSymbol(this,DocSymbol::Amp));␊ |
6219 | break;␊ |
6220 | case CMD_DOLLAR:␊ |
6221 | m_children.append(new DocSymbol(this,DocSymbol::Dollar));␊ |
6222 | break;␊ |
6223 | case CMD_HASH:␊ |
6224 | m_children.append(new DocSymbol(this,DocSymbol::Hash));␊ |
6225 | break;␊ |
6226 | case CMD_DCOLON:␊ |
6227 | m_children.append(new DocSymbol(this,DocSymbol::DoubleColon));␊ |
6228 | break;␊ |
6229 | case CMD_PERCENT:␊ |
6230 | m_children.append(new DocSymbol(this,DocSymbol::Percent));␊ |
6231 | break;␊ |
6232 | case CMD_QUOTE:␊ |
6233 | m_children.append(new DocSymbol(this,DocSymbol::Quot));␊ |
6234 | break;␊ |
6235 | default:␊ |
6236 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Unexpected command `%s' found",␊ |
6237 | qPrint(g_token->name));␊ |
6238 | break;␊ |
6239 | }␊ |
6240 | break;␊ |
6241 | default:␊ |
6242 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Unexpected token %s",␊ |
6243 | tokToString(tok));␊ |
6244 | break;␊ |
6245 | }␊ |
6246 | }␊ |
6247 | ␊ |
6248 | handleUnclosedStyleCommands();␊ |
6249 | ␊ |
6250 | DocNode *n = g_nodeStack.pop();␊ |
6251 | ASSERT(n==this);␊ |
6252 | DBG(("DocText::parse() end\n"));␊ |
6253 | }␊ |
6254 | ␊ |
6255 | ␊ |
6256 | //--------------------------------------------------------------------------␊ |
6257 | ␊ |
6258 | void DocRoot::parse()␊ |
6259 | {␊ |
6260 | DBG(("DocRoot::parse() start\n"));␊ |
6261 | g_nodeStack.push(this);␊ |
6262 | doctokenizerYYsetStatePara();␊ |
6263 | int retval=0;␊ |
6264 | ␊ |
6265 | // first parse any number of paragraphs␊ |
6266 | bool isFirst=TRUE;␊ |
6267 | DocPara *lastPar=0;␊ |
6268 | do␊ |
6269 | {␊ |
6270 | DocPara *par = new DocPara(this);␊ |
6271 | if (isFirst) { par->markFirst(); isFirst=FALSE; }␊ |
6272 | retval=par->parse();␊ |
6273 | if (!par->isEmpty()) ␊ |
6274 | {␊ |
6275 | m_children.append(par);␊ |
6276 | lastPar=par;␊ |
6277 | }␊ |
6278 | else␊ |
6279 | {␊ |
6280 | delete par;␊ |
6281 | }␊ |
6282 | if (retval==TK_LISTITEM)␊ |
6283 | {␊ |
6284 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Invalid list item found");␊ |
6285 | }␊ |
6286 | else if (retval==RetVal_Subsection)␊ |
6287 | {␊ |
6288 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: found subsection command outside of section context!");␊ |
6289 | }␊ |
6290 | else if (retval==RetVal_Subsubsection)␊ |
6291 | {␊ |
6292 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: found subsubsection command outside of subsection context!");␊ |
6293 | }␊ |
6294 | else if (retval==RetVal_Paragraph)␊ |
6295 | {␊ |
6296 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: found paragraph command outside of subsubsection context!");␊ |
6297 | }␊ |
6298 | } while (retval!=0 && retval!=RetVal_Section && retval!=RetVal_Internal);␊ |
6299 | if (lastPar) lastPar->markLast();␊ |
6300 | ␊ |
6301 | //printf("DocRoot::parse() retval=%d %d\n",retval,RetVal_Section);␊ |
6302 | // then parse any number of level1 sections␊ |
6303 | while (retval==RetVal_Section)␊ |
6304 | {␊ |
6305 | SectionInfo *sec=Doxygen::sectionDict[g_token->sectionId];␊ |
6306 | if (sec)␊ |
6307 | {␊ |
6308 | DocSection *s=new DocSection(this,␊ |
6309 | QMIN(1+Doxygen::subpageNestingLevel,5),g_token->sectionId);␊ |
6310 | m_children.append(s);␊ |
6311 | retval = s->parse();␊ |
6312 | }␊ |
6313 | else␊ |
6314 | {␊ |
6315 | warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Invalid section id `%s'; ignoring section",qPrint(g_token->sectionId));␊ |
6316 | retval = 0;␊ |
6317 | }␊ |
6318 | }␊ |
6319 | ␊ |
6320 | if (retval==RetVal_Internal)␊ |
6321 | {␊ |
6322 | DocInternal *in = new DocInternal(this);␊ |
6323 | m_children.append(in);␊ |
6324 | retval = in->parse(1);␊ |
6325 | }␊ |
6326 | ␊ |
6327 | ␊ |
6328 | handleUnclosedStyleCommands();␊ |
6329 | ␊ |
6330 | DocNode *n = g_nodeStack.pop();␊ |
6331 | ASSERT(n==this);␊ |
6332 | DBG(("DocRoot::parse() end\n"));␊ |
6333 | }␊ |
6334 | ␊ |
6335 | //--------------------------------------------------------------------------␊ |
6336 | ␊ |
6337 | DocNode *validatingParseDoc(const char *fileName,int startLine,␊ |
6338 | Definition *ctx,MemberDef *md,␊ |
6339 | const char *input,bool indexWords,␊ |
6340 | bool isExample, const char *exampleName,␊ |
6341 | bool singleLine, bool linkFromIndex)␊ |
6342 | {␊ |
6343 | //printf("validatingParseDoc(%s,%s)=[%s]\n",ctx?ctx->name().data():"<none>",␊ |
6344 | // md?md->name().data():"<none>",␊ |
6345 | // input);␊ |
6346 | //printf("========== validating %s at line %d\n",fileName,startLine);␊ |
6347 | //printf("---------------- input --------------------\n%s\n----------- end input -------------------\n",input);␊ |
6348 | //g_token = new TokenInfo;␊ |
6349 | ␊ |
6350 | // store parser state so we can re-enter this function if needed␊ |
6351 | bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");␊ |
6352 | docParserPushContext();␊ |
6353 | ␊ |
6354 | if (ctx && ctx!=Doxygen::globalScope &&␊ |
6355 | (ctx->definitionType()==Definition::TypeClass || ␊ |
6356 | ctx->definitionType()==Definition::TypeNamespace␊ |
6357 | ) ␊ |
6358 | ) ␊ |
6359 | {␊ |
6360 | g_context = ctx->name();␊ |
6361 | }␊ |
6362 | else if (ctx && ctx->definitionType()==Definition::TypePage)␊ |
6363 | {␊ |
6364 | Definition *scope = ((PageDef*)ctx)->getPageScope();␊ |
6365 | if (scope && scope!=Doxygen::globalScope) g_context = scope->name();␊ |
6366 | }␊ |
6367 | else if (ctx && ctx->definitionType()==Definition::TypeGroup)␊ |
6368 | {␊ |
6369 | Definition *scope = ((GroupDef*)ctx)->getGroupScope();␊ |
6370 | if (scope && scope!=Doxygen::globalScope) g_context = scope->name();␊ |
6371 | }␊ |
6372 | else␊ |
6373 | {␊ |
6374 | g_context = "";␊ |
6375 | }␊ |
6376 | g_scope = ctx;␊ |
6377 | ␊ |
6378 | if (indexWords && md && Doxygen::searchIndex)␊ |
6379 | {␊ |
6380 | g_searchUrl=md->getOutputFileBase();␊ |
6381 | Doxygen::searchIndex->setCurrentDoc(␊ |
6382 | (fortranOpt?theTranslator->trSubprogram(TRUE,TRUE):theTranslator->trMember(TRUE,TRUE))+" "+md->qualifiedName(),␊ |
6383 | g_searchUrl,␊ |
6384 | md->anchor());␊ |
6385 | }␊ |
6386 | else if (indexWords && ctx && Doxygen::searchIndex)␊ |
6387 | {␊ |
6388 | g_searchUrl=ctx->getOutputFileBase();␊ |
6389 | QCString name = ctx->qualifiedName();␊ |
6390 | if (Config_getBool("OPTIMIZE_OUTPUT_JAVA"))␊ |
6391 | {␊ |
6392 | name = substitute(name,"::",".");␊ |
6393 | }␊ |
6394 | switch (ctx->definitionType())␊ |
6395 | {␊ |
6396 | case Definition::TypePage:␊ |
6397 | {␊ |
6398 | PageDef *pd = (PageDef *)ctx;␊ |
6399 | if (!pd->title().isEmpty())␊ |
6400 | {␊ |
6401 | name = theTranslator->trPage(TRUE,TRUE)+" "+pd->title();␊ |
6402 | }␊ |
6403 | else␊ |
6404 | {␊ |
6405 | name = theTranslator->trPage(TRUE,TRUE)+" "+pd->name();␊ |
6406 | }␊ |
6407 | }␊ |
6408 | break;␊ |
6409 | case Definition::TypeClass:␊ |
6410 | {␊ |
6411 | ClassDef *cd = (ClassDef *)ctx;␊ |
6412 | name.prepend(cd->compoundTypeString()+" ");␊ |
6413 | }␊ |
6414 | break;␊ |
6415 | case Definition::TypeNamespace:␊ |
6416 | {␊ |
6417 | if (Config_getBool("OPTIMIZE_OUTPUT_JAVA"))␊ |
6418 | {␊ |
6419 | name = theTranslator->trPackage(name);␊ |
6420 | }␊ |
6421 | else if(fortranOpt)␊ |
6422 | {␊ |
6423 | name.prepend(theTranslator->trModule(TRUE,TRUE)+" ");␊ |
6424 | }␊ |
6425 | else␊ |
6426 | {␊ |
6427 | name.prepend(theTranslator->trNamespace(TRUE,TRUE)+" ");␊ |
6428 | }␊ |
6429 | }␊ |
6430 | break;␊ |
6431 | case Definition::TypeGroup:␊ |
6432 | {␊ |
6433 | GroupDef *gd = (GroupDef *)ctx;␊ |
6434 | if (gd->groupTitle())␊ |
6435 | {␊ |
6436 | name = theTranslator->trGroup(TRUE,TRUE)+" "+gd->groupTitle();␊ |
6437 | }␊ |
6438 | else␊ |
6439 | {␊ |
6440 | name.prepend(theTranslator->trGroup(TRUE,TRUE)+" ");␊ |
6441 | }␊ |
6442 | }␊ |
6443 | break;␊ |
6444 | default:␊ |
6445 | break;␊ |
6446 | }␊ |
6447 | Doxygen::searchIndex->setCurrentDoc(name,g_searchUrl);␊ |
6448 | }␊ |
6449 | else␊ |
6450 | {␊ |
6451 | g_searchUrl="";␊ |
6452 | }␊ |
6453 | ␊ |
6454 | g_fileName = fileName;␊ |
6455 | g_relPath = (!linkFromIndex && ctx) ? ␊ |
6456 | QCString(relativePathToRoot(ctx->getOutputFileBase())) : ␊ |
6457 | QCString("");␊ |
6458 | //printf("ctx->name=%s relPath=%s\n",ctx->name().data(),g_relPath.data());␊ |
6459 | g_memberDef = md;␊ |
6460 | g_nodeStack.clear();␊ |
6461 | g_styleStack.clear();␊ |
6462 | g_initialStyleStack.clear();␊ |
6463 | g_inSeeBlock = FALSE;␊ |
6464 | g_insideHtmlLink = FALSE;␊ |
6465 | g_includeFileText = "";␊ |
6466 | g_includeFileOffset = 0;␊ |
6467 | g_includeFileLength = 0;␊ |
6468 | g_isExample = isExample;␊ |
6469 | g_exampleName = exampleName;␊ |
6470 | g_hasParamCommand = FALSE;␊ |
6471 | g_hasReturnCommand = FALSE;␊ |
6472 | g_paramsFound.setAutoDelete(FALSE);␊ |
6473 | g_paramsFound.clear();␊ |
6474 | g_sectionDict = 0; //sections;␊ |
6475 | ␊ |
6476 | //printf("Starting comment block at %s:%d\n",g_fileName.data(),startLine);␊ |
6477 | doctokenizerYYlineno=startLine;␊ |
6478 | doctokenizerYYinit(input,g_fileName);␊ |
6479 | ␊ |
6480 | ␊ |
6481 | // build abstract syntax tree␊ |
6482 | DocRoot *root = new DocRoot(md!=0,singleLine);␊ |
6483 | root->parse();␊ |
6484 | ␊ |
6485 | ␊ |
6486 | if (Debug::isFlagSet(Debug::PrintTree))␊ |
6487 | {␊ |
6488 | // pretty print the result␊ |
6489 | PrintDocVisitor *v = new PrintDocVisitor;␊ |
6490 | root->accept(v);␊ |
6491 | delete v;␊ |
6492 | }␊ |
6493 | ␊ |
6494 | ␊ |
6495 | checkUndocumentedParams();␊ |
6496 | detectNoDocumentedParams();␊ |
6497 | ␊ |
6498 | // TODO: These should be called at the end of the program.␊ |
6499 | //doctokenizerYYcleanup();␊ |
6500 | //Mappers::cmdMapper->freeInstance();␊ |
6501 | //Mappers::htmlTagMapper->freeInstance();␊ |
6502 | ␊ |
6503 | // restore original parser state␊ |
6504 | docParserPopContext();␊ |
6505 | ␊ |
6506 | //printf(">>>>>> end validatingParseDoc(%s,%s)\n",ctx?ctx->name().data():"<none>",␊ |
6507 | // md?md->name().data():"<none>");␊ |
6508 | ␊ |
6509 | return root;␊ |
6510 | }␊ |
6511 | ␊ |
6512 | DocNode *validatingParseText(const char *input)␊ |
6513 | {␊ |
6514 | // store parser state so we can re-enter this function if needed␊ |
6515 | docParserPushContext();␊ |
6516 | ␊ |
6517 | //printf("------------ input ---------\n%s\n"␊ |
6518 | // "------------ end input -----\n",input);␊ |
6519 | //g_token = new TokenInfo;␊ |
6520 | g_context = "";␊ |
6521 | g_fileName = "<parseText>";␊ |
6522 | g_relPath = "";␊ |
6523 | g_memberDef = 0;␊ |
6524 | g_nodeStack.clear();␊ |
6525 | g_styleStack.clear();␊ |
6526 | g_initialStyleStack.clear();␊ |
6527 | g_inSeeBlock = FALSE;␊ |
6528 | g_insideHtmlLink = FALSE;␊ |
6529 | g_includeFileText = "";␊ |
6530 | g_includeFileOffset = 0;␊ |
6531 | g_includeFileLength = 0;␊ |
6532 | g_isExample = FALSE;␊ |
6533 | g_exampleName = "";␊ |
6534 | g_hasParamCommand = FALSE;␊ |
6535 | g_hasReturnCommand = FALSE;␊ |
6536 | g_paramsFound.setAutoDelete(FALSE);␊ |
6537 | g_paramsFound.clear();␊ |
6538 | g_searchUrl="";␊ |
6539 | ␊ |
6540 | DocText *txt = new DocText;␊ |
6541 | ␊ |
6542 | if (input)␊ |
6543 | {␊ |
6544 | doctokenizerYYlineno=1;␊ |
6545 | doctokenizerYYinit(input,g_fileName);␊ |
6546 | ␊ |
6547 | // build abstract syntax tree␊ |
6548 | txt->parse();␊ |
6549 | ␊ |
6550 | if (Debug::isFlagSet(Debug::PrintTree))␊ |
6551 | {␊ |
6552 | // pretty print the result␊ |
6553 | PrintDocVisitor *v = new PrintDocVisitor;␊ |
6554 | txt->accept(v);␊ |
6555 | delete v;␊ |
6556 | }␊ |
6557 | }␊ |
6558 | ␊ |
6559 | // restore original parser state␊ |
6560 | docParserPopContext();␊ |
6561 | return txt;␊ |
6562 | }␊ |
6563 | ␊ |
6564 | void docFindSections(const char *input,␊ |
6565 | Definition *d,␊ |
6566 | MemberGroup *mg,␊ |
6567 | const char *fileName)␊ |
6568 | {␊ |
6569 | doctokenizerYYFindSections(input,d,mg,fileName);␊ |
6570 | }␊ |
6571 | ␊ |
6572 | void initDocParser()␊ |
6573 | {␊ |
6574 | static bool searchEngine = Config_getBool("SEARCHENGINE");␊ |
6575 | static bool serverBasedSearch = Config_getBool("SERVER_BASED_SEARCH");␊ |
6576 | if (searchEngine && serverBasedSearch)␊ |
6577 | {␊ |
6578 | Doxygen::searchIndex = new SearchIndex;␊ |
6579 | }␊ |
6580 | else // no search engine or pure javascript based search function␊ |
6581 | {␊ |
6582 | Doxygen::searchIndex = 0;␊ |
6583 | }␊ |
6584 | }␊ |
6585 | ␊ |
6586 | void finializeDocParser()␊ |
6587 | {␊ |
6588 | delete Doxygen::searchIndex;␊ |
6589 | }␊ |
6590 | ␊ |
6591 |