Fix for UBSan build
[platform/upstream/doxygen.git] / src / docparser.h
1 /******************************************************************************
2  *
3  * $Id: $
4  *
5  *
6  * Copyright (C) 1997-2012 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 #ifndef _DOCPARSER_H
20 #define _DOCPARSER_H
21
22 #include <stdio.h>
23
24 #include <qlist.h>
25 #include <qcstring.h>
26
27 #include "docvisitor.h"
28 #include "htmlattrib.h"
29
30 class DocNode;
31 class MemberDef;
32 class Definition;
33 class MemberGroup;
34 class SectionDict;
35
36 //---------------------------------------------------------------------------
37
38
39 /*! Main entry point for the documentation parser.
40  *  @param fileName  File in which the documentation block is found (or the
41  *                   name of the example file in case isExample is TRUE).
42  *  @param startLine Line at which the documentation block is found.
43  *  @param context   Class or namespace to which this block belongs.
44  *  @param md        Member definition to which the documentation belongs.
45  *                   Can be 0.
46  *  @param input     String representation of the documentation block.
47  *  @param indexWords Indicates whether or not words should be put in the 
48  *                   search index.
49  *  @param isExample TRUE if the documentation belongs to an example.
50  *  @param exampleName Base name of the example file (0 if isExample is FALSE).
51  *  @param singleLine Output should be presented on a single line, so without
52  *                   starting a new paragraph at the end.
53  *  @param linkFromIndex TRUE if the documentation is generated from an
54  *                   index page. In this case context is not used to determine
55  *                   the relative path when making a link.
56  *  @returns         Root node of the abstract syntax tree. Ownership of the
57  *                   pointer is handed over to the caller.
58  */
59 DocNode *validatingParseDoc(const char *fileName,int startLine,
60                             Definition *context, MemberDef *md,
61                             const char *input,bool indexWords,
62                             bool isExample,const char *exampleName=0,
63                             bool singleLine=FALSE,bool linkFromIndex=FALSE);
64
65 /*! Main entry point for parsing simple text fragments. These 
66  *  fragments are limited to words, whitespace and symbols.
67  */
68 DocNode *validatingParseText(const char *input);
69
70 /*! Searches for section and anchor commands in the input */
71 void docFindSections(const char *input,
72                      Definition *d,
73                      MemberGroup *m,
74                      const char *fileName);
75
76 //---------------------------------------------------------------------------
77
78 /** Abstract node interface with type information. */
79 class DocNode
80 {
81   public:
82     /*! Available node types. */
83     enum Kind { Kind_Root           = 0, 
84                 Kind_Word           = 1, 
85                 Kind_WhiteSpace     = 2, 
86                 Kind_Para           = 3, 
87                 Kind_AutoList       = 4, 
88                 Kind_AutoListItem   = 5,
89                 Kind_Symbol         = 6,
90                 Kind_URL            = 7,
91                 Kind_StyleChange    = 8,
92                 Kind_SimpleSect     = 9,
93                 Kind_Title          = 10,
94                 Kind_SimpleList     = 11,
95                 Kind_SimpleListItem = 12,
96                 Kind_Section        = 13,
97                 Kind_Verbatim       = 14,
98                 Kind_XRefItem       = 15,
99                 Kind_HtmlList       = 16,
100                 Kind_HtmlListItem   = 17,
101                 Kind_HtmlDescList   = 18,
102                 Kind_HtmlDescData   = 19,
103                 Kind_HtmlDescTitle  = 20,
104                 Kind_HtmlTable      = 21,
105                 Kind_HtmlRow        = 22,
106                 Kind_HtmlCell       = 23,
107                 Kind_HtmlCaption    = 24,
108                 Kind_LineBreak      = 25,
109                 Kind_HorRuler       = 26,
110                 Kind_Anchor         = 27,
111                 Kind_IndexEntry     = 28,
112                 Kind_Internal       = 29,
113                 Kind_HRef           = 30,
114                 Kind_Include        = 31,
115                 Kind_IncOperator    = 32,
116                 Kind_HtmlHeader     = 33,
117                 Kind_Image          = 34,
118                 Kind_DotFile        = 35,
119                 Kind_Link           = 36,
120                 Kind_Ref            = 37,
121                 Kind_Formula        = 38,
122                 Kind_SecRefItem     = 39,
123                 Kind_SecRefList     = 40,
124                 Kind_SimpleSectSep  = 41,
125                 Kind_LinkedWord     = 42,
126                 Kind_ParamSect      = 43,
127                 Kind_ParamList      = 44,
128                 Kind_InternalRef    = 45,
129                 Kind_Copy           = 46,
130                 Kind_Text           = 47,
131                 Kind_MscFile        = 48,
132                 Kind_HtmlBlockQuote = 49
133               };
134     /*! Creates a new node */
135     DocNode() : m_parent(0), m_insidePre(FALSE) {}
136
137     /*! Destroys a node. */
138     virtual ~DocNode() {}
139
140     /*! Returns the kind of node. Provides runtime type information */
141     virtual Kind kind() const = 0;
142
143     /*! Returns the parent of this node or 0 for the root node. */
144     DocNode *parent() const { return m_parent; }
145
146     /*! Sets a new parent for this node. */
147     void setParent(DocNode *parent) { m_parent = parent; }
148
149     /*! Acceptor function for node visitors. Part of the visitor pattern. 
150      *  @param v Abstract visitor.
151      */
152     virtual void accept(DocVisitor *v) = 0;
153
154     /*! Returns TRUE iff this node is inside a preformatted section */
155     bool isPreformatted() const { return m_insidePre; }
156
157   protected:
158     /*! Sets whether or not this item is inside a preformatted section */
159     void setInsidePreformatted(bool p) { m_insidePre = p; }
160     DocNode *m_parent;
161   private:
162
163     bool m_insidePre;
164 };
165
166 /** Default accept implementation for compound nodes in the abstract
167  *  syntax tree.
168  */
169 template<class T> class CompAccept
170 {
171   public:
172     CompAccept() { m_children.setAutoDelete(TRUE); }
173     virtual ~CompAccept() {}
174     void accept(T *obj, DocVisitor *v) 
175     { 
176       v->visitPre(obj); 
177       QListIterator<DocNode> cli(m_children);
178       DocNode *n;
179       for (cli.toFirst();(n=cli.current());++cli) n->accept(v);
180       v->visitPost(obj); 
181     }
182     const QList<DocNode> &children() const { return m_children; }
183     QList<DocNode> &children() { return m_children; }
184   
185   protected:
186     QList<DocNode> m_children;
187 };
188
189
190 /** Node representing a word 
191  */
192 class DocWord : public DocNode
193 {
194   public:
195     DocWord(DocNode *parent,const QCString &word);
196     QCString word() const { return m_word; }
197     Kind kind() const { return Kind_Word; }
198     void accept(DocVisitor *v) { v->visit(this); }
199
200   private:
201     QCString  m_word;
202 };
203
204 /** Node representing a word that can be linked to something
205  */
206 class DocLinkedWord : public DocNode
207 {
208   public:
209     DocLinkedWord(DocNode *parent,const QCString &word,
210                   const QCString &ref,const QCString &file,
211                   const QCString &anchor,const QCString &tooltip);
212     QCString word() const       { return m_word; }
213     Kind kind() const          { return Kind_LinkedWord; }
214     QCString file() const       { return m_file; }
215     QCString relPath() const    { return m_relPath; }
216     QCString ref() const        { return m_ref; }
217     QCString anchor() const     { return m_anchor; }
218     QCString tooltip() const    { return m_tooltip; }
219     void accept(DocVisitor *v) { v->visit(this); }
220
221   private:
222     QCString  m_word;
223     QCString  m_ref;
224     QCString  m_file;
225     QCString  m_relPath;
226     QCString  m_anchor;
227     QCString  m_tooltip;
228 };
229
230 /** Node representing an URL (or email address) */
231 class DocURL : public DocNode
232 {
233   public:
234     DocURL(DocNode *parent,const QCString &url,bool isEmail) : 
235       m_url(url), m_isEmail(isEmail) { m_parent=parent; }
236     QCString url() const        { return m_url; }
237     Kind kind() const          { return Kind_URL; }
238     void accept(DocVisitor *v) { v->visit(this); }
239     bool isEmail() const       { return m_isEmail; }
240
241   private:
242     QCString  m_url;
243     bool m_isEmail;
244 };
245
246 /** Node representing a line break */
247 class DocLineBreak : public DocNode
248 {
249   public:
250     DocLineBreak(DocNode *parent) { m_parent=parent; }
251     Kind kind() const          { return Kind_LineBreak; }
252     void accept(DocVisitor *v) { v->visit(this); }
253
254   private:
255 };
256
257 /** Node representing a horizonal ruler */
258 class DocHorRuler : public DocNode
259 {
260   public:
261     DocHorRuler(DocNode *parent) { m_parent = parent; }
262     Kind kind() const          { return Kind_HorRuler; }
263     void accept(DocVisitor *v) { v->visit(this); }
264
265   private:
266 };
267
268 /** Node representing an anchor */
269 class DocAnchor : public DocNode
270 {
271   public:
272     DocAnchor(DocNode *parent,const QCString &id,bool newAnchor);
273     Kind kind() const          { return Kind_Anchor; }
274     QCString anchor() const    { return m_anchor; }
275     QCString file() const      { return m_file; }
276     void accept(DocVisitor *v) { v->visit(this); }
277
278   private:
279     QCString  m_anchor;
280     QCString  m_file;
281 };
282
283 /** Node representing a citation of some bibliographic reference */
284 class DocCite : public DocNode
285 {
286   public:
287     DocCite(DocNode *parent,const QCString &target,const QCString &context);
288     Kind kind() const            { return Kind_Ref; }
289     QCString file() const        { return m_file; }
290     QCString relPath() const     { return m_relPath; }
291     QCString ref() const         { return m_ref; }
292     QCString anchor() const      { return m_anchor; }
293     QCString text() const        { return m_text; }
294     void accept(DocVisitor *v) { v->visit(this); }
295
296   private:
297     QCString   m_file;
298     QCString   m_relPath;
299     QCString   m_ref;
300     QCString   m_anchor;
301     QCString   m_text;
302 };
303
304
305 /** Node representing a style change */
306 class DocStyleChange : public DocNode
307 {
308   public:
309     enum Style { Bold, Italic, Code, Center, Small, 
310                  Subscript, Superscript, Preformatted,
311                  Span, Div
312                };
313     DocStyleChange(DocNode *parent,uint position,Style s,bool enable,
314                    const HtmlAttribList *attribs=0) : 
315       m_position(position), m_style(s), m_enable(enable)
316       { m_parent = parent; if (attribs) m_attribs=*attribs; }
317     Kind kind() const                     { return Kind_StyleChange; }
318     Style style() const                   { return m_style; }
319     const char *styleString() const;
320     bool enable() const                   { return m_enable; }
321     uint position() const                 { return m_position; }
322     void accept(DocVisitor *v)            { v->visit(this); }
323     const HtmlAttribList &attribs() const { return m_attribs; }
324
325   private:
326     uint     m_position;
327     Style    m_style;
328     bool     m_enable;
329     HtmlAttribList m_attribs;
330 };
331
332 /** Node representing a special symbol */
333 class DocSymbol : public DocNode
334 {
335   public:
336     enum SymType { Unknown=0, BSlash, At, Less, Greater, Amp, Dollar, Hash,
337                    DoubleColon, Percent, Copy, Tm, Reg, Apos, Quot, Uml, Acute, 
338                    Grave, Circ, Tilde, Szlig, Cedil, Ring, Nbsp, Slash, 
339                    Lsquo, Rsquo, Ldquo, Rdquo, Ndash, Mdash, Aelig, AElig,
340                    GrkGamma, GrkDelta, GrkTheta, GrkLambda, GrkXi, GrkPi,
341                    GrkSigma, GrkUpsilon, GrkPhi, GrkPsi, GrkOmega, Grkalpha,
342                    Grkbeta, Grkgamma, Grkdelta, Grkepsilon, Grkzeta, Grketa,
343                    Grktheta, Grkiota, Grkkappa, Grklambda, Grkmu, Grknu, Grkxi,
344                    Grkpi, Grkrho, Grksigma, Grktau, Grkupsilon, Grkphi, Grkchi,
345                    Grkpsi, Grkomega, Grkvarsigma, Section, Degree, Prime,
346                    DoublePrime, Infinity, EmptySet, PlusMinus, Times, Minus,
347                    CenterDot, Partial, Nabla, SquareRoot, Perpendicular, Sum,
348                    Integral, Product, Similar, Approx, NotEqual, Equivalent,
349                    Proportional, LessEqual, GreaterEqual, LeftArrow, RightArrow,
350                    SetIn, SetNotIn, LeftCeil, RightCeil, LeftFloor, RightFloor,
351                    Pipe
352                  };
353     DocSymbol(DocNode *parent,SymType s,char letter='\0') : 
354       m_symbol(s), m_letter(letter) { m_parent = parent; }
355     SymType symbol() const     { return m_symbol; }
356     char letter() const        { return m_letter; }
357     Kind kind() const          { return Kind_Symbol; }
358     void accept(DocVisitor *v) { v->visit(this); }
359     static SymType decodeSymbol(const QCString &symName,char *letter);
360
361   private:
362     SymType  m_symbol;
363     char     m_letter;
364 };
365
366 /** Node representing some amount of white space */
367 class DocWhiteSpace : public DocNode
368 {
369   public:
370     DocWhiteSpace(DocNode *parent,const QCString &chars) : 
371       m_chars(chars) { m_parent = parent; }
372     Kind kind() const          { return Kind_WhiteSpace; }
373     QCString chars() const      { return m_chars; }
374     void accept(DocVisitor *v) { v->visit(this); }
375   private:
376     QCString  m_chars;
377 };
378
379 /** Node representing a verbatim, unparsed text fragment */
380 class DocVerbatim : public DocNode
381 {
382   public:
383     enum Type { Code, HtmlOnly, ManOnly, LatexOnly, RtfOnly, XmlOnly, Verbatim, Dot, Msc };
384     DocVerbatim(DocNode *parent,const QCString &context,
385                 const QCString &text, Type t,bool isExample,
386                 const QCString &exampleFile,const QCString &lang=QCString());
387     Kind kind() const            { return Kind_Verbatim; }
388     Type type() const            { return m_type; }
389     QCString text() const        { return m_text; }
390     QCString context() const     { return m_context; }
391     void accept(DocVisitor *v)   { v->visit(this); }
392     bool isExample() const       { return m_isExample; }
393     QCString exampleFile() const { return m_exampleFile; }
394     QCString relPath() const     { return m_relPath; }
395     QCString language() const    { return m_lang; }
396
397   private:
398     QCString  m_context;
399     QCString  m_text;
400     Type      m_type;
401     bool      m_isExample;
402     QCString  m_exampleFile;
403     QCString  m_relPath;
404     QCString  m_lang;
405 };
406
407
408 /** Node representing an included text block from file */
409 class DocInclude : public DocNode
410 {
411   public:
412     enum Type { Include, DontInclude, VerbInclude, HtmlInclude, IncWithLines, Snippet };
413     DocInclude(DocNode *parent,const QCString &file,
414                const QCString context, Type t,
415                bool isExample,const QCString exampleFile,
416                const QCString blockId) : 
417       m_file(file), m_context(context), m_type(t),
418       m_isExample(isExample), m_exampleFile(exampleFile),
419       m_blockId(blockId) { m_parent = parent; }
420     Kind kind() const            { return Kind_Include; }
421     QCString file() const        { return m_file; }
422     QCString extension() const   { int i=m_file.findRev('.'); 
423                                    if (i!=-1) 
424                                      return m_file.right(m_file.length()-i); 
425                                    else 
426                                      return ""; 
427                                  }
428     Type type() const            { return m_type; }
429     QCString text() const        { return m_text; }
430     QCString context() const     { return m_context; }
431     QCString blockId() const     { return m_blockId; }
432     bool isExample() const       { return m_isExample; }
433     QCString exampleFile() const { return m_exampleFile; }
434     void accept(DocVisitor *v)   { v->visit(this); }
435     void parse();
436
437   private:
438     QCString  m_file;
439     QCString  m_context;
440     QCString  m_text;
441     Type      m_type;
442     bool      m_isExample;
443     QCString  m_exampleFile;
444     QCString  m_blockId;
445 };
446
447 /** Node representing a include/dontinclude operator block */
448 class DocIncOperator : public DocNode
449 {
450   public:
451     enum Type { Line, SkipLine, Skip, Until };
452     DocIncOperator(DocNode *parent,Type t,const QCString &pat,
453                    const QCString &context,bool isExample,const QCString &exampleFile) : 
454       m_type(t), m_pattern(pat), m_context(context), 
455       m_isFirst(FALSE), m_isLast(FALSE),
456       m_isExample(isExample), m_exampleFile(exampleFile) { m_parent = parent; }
457     Kind kind() const           { return Kind_IncOperator; }
458     Type type() const           { return m_type; }
459     QCString text() const        { return m_text; }
460     QCString pattern() const     { return m_pattern; }
461     QCString context() const     { return m_context; }
462     void accept(DocVisitor *v)  { v->visit(this); }
463     bool isFirst() const        { return m_isFirst; }
464     bool isLast() const         { return m_isLast; }
465     void markFirst(bool v=TRUE) { m_isFirst = v; }
466     void markLast(bool v=TRUE)  { m_isLast = v; }
467     bool isExample() const      { return m_isExample; }
468     QCString exampleFile() const { return m_exampleFile; }
469     void parse();
470
471   private:
472     Type     m_type;
473     QCString  m_text;
474     QCString  m_pattern;
475     QCString  m_context;
476     bool     m_isFirst;
477     bool     m_isLast;
478     bool     m_isExample;
479     QCString  m_exampleFile;
480 };
481
482 /** Node representing an item of a cross-referenced list */
483 class DocFormula : public DocNode
484 {
485   public:
486     DocFormula(DocNode *parent,int id);
487     Kind kind() const          { return Kind_Formula; }
488     QCString name() const       { return m_name; }
489     QCString text() const       { return m_text; }
490     QCString relPath() const    { return m_relPath; }
491     int id() const             { return m_id; }
492     void accept(DocVisitor *v) { v->visit(this); }
493     bool isInline()            { return m_text.length()>0 ? m_text.at(0)!='\\' : TRUE; }
494
495   private:
496     QCString  m_name;
497     QCString  m_text;
498     QCString  m_relPath;
499     int      m_id;
500 };
501
502 /** Node representing an entry in the index. */
503 class DocIndexEntry : public DocNode
504 {
505   public:
506     DocIndexEntry(DocNode *parent,Definition *scope,MemberDef *md) 
507       : m_scope(scope), m_member(md) { m_parent = parent; }
508     Kind kind() const { return Kind_IndexEntry; }
509     int parse();
510     Definition *scope() const    { return m_scope;  }
511     MemberDef *member() const    { return m_member; }
512     QCString entry() const        { return m_entry;  }
513     void accept(DocVisitor *v)   { v->visit(this);  }
514
515   private:
516     QCString     m_entry;
517     Definition *m_scope;
518     MemberDef  *m_member;
519 };
520
521 //-----------------------------------------------------------------------
522
523 /** Node representing a copy of documentation block. */
524 class DocCopy : public DocNode
525 {
526   public:
527     DocCopy(DocNode *parent,const QCString &link,bool copyBrief,bool copyDetails) 
528       : m_link(link), 
529         m_copyBrief(copyBrief), m_copyDetails(copyDetails) { m_parent = parent; }
530     Kind kind() const          { return Kind_Copy; }
531     QCString link() const       { return m_link; }
532     void accept(DocVisitor * /*v*/) { /*CompAccept<DocCopy>::accept(this,v);*/ }
533     void parse(QList<DocNode> &children);
534
535   private:
536     QCString  m_link;
537     bool     m_copyBrief;
538     bool     m_copyDetails;
539 };
540
541 /** Node representing an auto List */
542 class DocAutoList : public CompAccept<DocAutoList>, public DocNode
543 {
544   public:
545     DocAutoList(DocNode *parent,int indent,bool isEnumList,int depth);
546     Kind kind() const          { return Kind_AutoList; }
547     bool isEnumList() const    { return m_isEnumList; }
548     int  indent() const        { return m_indent; }
549     int depth() const          { return m_depth; }
550     void accept(DocVisitor *v) { CompAccept<DocAutoList>::accept(this,v); }
551     int parse();
552
553   private:
554     int      m_indent;
555     bool     m_isEnumList;
556     int      m_depth;
557 };
558
559 /** Node representing an item of a auto list */
560 class DocAutoListItem : public CompAccept<DocAutoListItem>, public DocNode
561 {
562   public:
563     DocAutoListItem(DocNode *parent,int indent,int num);
564     Kind kind() const          { return Kind_AutoListItem; }
565     int itemNumber() const     { return m_itemNum; }
566     void accept(DocVisitor *v) { CompAccept<DocAutoListItem>::accept(this,v); }
567     int parse();
568
569   private:
570     int m_indent;
571     int m_itemNum;
572 };
573
574
575
576 /** Node representing a simple section title */
577 class DocTitle : public CompAccept<DocTitle>, public DocNode
578 {
579   public:
580     DocTitle(DocNode *parent) { m_parent = parent; }
581     void parse();
582     void parseFromString(const QCString &title);
583     Kind kind() const          { return Kind_Title; }
584     void accept(DocVisitor *v) { CompAccept<DocTitle>::accept(this,v); }
585
586   private:
587 };
588
589 /** Node representing an item of a cross-referenced list */
590 class DocXRefItem : public CompAccept<DocXRefItem>, public DocNode
591 {
592   public:
593     DocXRefItem(DocNode *parent,int id,const char *key);
594     Kind kind() const          { return Kind_XRefItem; }
595     QCString file() const       { return m_file; }
596     QCString anchor() const     { return m_anchor; }
597     QCString title() const      { return m_title; }
598     QCString relPath() const    { return m_relPath; }
599     QCString key() const        { return m_key; }
600     void accept(DocVisitor *v) { CompAccept<DocXRefItem>::accept(this,v); }
601     bool parse();
602
603   private:
604     int      m_id;
605     QCString  m_key;
606     QCString  m_file;
607     QCString  m_anchor;
608     QCString  m_title;
609     QCString  m_relPath;
610 };
611
612 /** Node representing an image */
613 class DocImage : public CompAccept<DocImage>, public DocNode
614 {
615   public:
616     enum Type { Html, Latex, Rtf };
617     DocImage(DocNode *parent,const HtmlAttribList &attribs,
618              const QCString &name,Type t,const QCString &url=QCString());
619     Kind kind() const           { return Kind_Image; }
620     Type type() const           { return m_type; }
621     QCString name() const       { return m_name; }
622     bool hasCaption() const     { return !m_children.isEmpty(); }
623     QCString width() const      { return m_width; }
624     QCString height() const     { return m_height; }
625     QCString relPath() const    { return m_relPath; }
626     QCString url() const        { return m_url; }
627     const HtmlAttribList &attribs() const { return m_attribs; }
628     void accept(DocVisitor *v) { CompAccept<DocImage>::accept(this,v); }
629     void parse();
630
631   private:
632     HtmlAttribList m_attribs;
633     QCString  m_name;
634     Type     m_type;
635     QCString  m_width;
636     QCString  m_height;
637     QCString  m_relPath;
638     QCString  m_url;
639 };
640
641 /** Node representing a dot file */
642 class DocDotFile : public CompAccept<DocDotFile>, public DocNode
643 {
644   public:
645     DocDotFile(DocNode *parent,const QCString &name,const QCString &context);
646     void parse();
647     Kind kind() const          { return Kind_DotFile; }
648     QCString name() const       { return m_name; }
649     QCString file() const       { return m_file; }
650     QCString relPath() const    { return m_relPath; }
651     bool hasCaption() const    { return !m_children.isEmpty(); }
652     QCString width() const      { return m_width; }
653     QCString height() const     { return m_height; }
654     QCString context() const    { return m_context; }
655     void accept(DocVisitor *v) { CompAccept<DocDotFile>::accept(this,v); }
656   private:
657     QCString  m_name;
658     QCString  m_file;
659     QCString  m_relPath;
660     QCString  m_width;
661     QCString  m_height;
662     QCString  m_context;
663 };
664
665 /** Node representing a msc file */
666 class DocMscFile : public CompAccept<DocMscFile>, public DocNode
667 {
668   public:
669     DocMscFile(DocNode *parent,const QCString &name,const QCString &context);
670     void parse();
671     Kind kind() const          { return Kind_MscFile; }
672     QCString name() const      { return m_name; }
673     QCString file() const      { return m_file; }
674     QCString relPath() const   { return m_relPath; }
675     bool hasCaption() const    { return !m_children.isEmpty(); }
676     QCString width() const     { return m_width; }
677     QCString height() const    { return m_height; }
678     QCString context() const   { return m_context; }
679     void accept(DocVisitor *v) { CompAccept<DocMscFile>::accept(this,v); }
680   private:
681     QCString  m_name;
682     QCString  m_file;
683     QCString  m_relPath;
684     QCString  m_width;
685     QCString  m_height;
686     QCString  m_context;
687 };
688
689
690 /** Node representing a link to some item */
691 class DocLink : public CompAccept<DocLink>, public DocNode
692 {
693   public:
694     DocLink(DocNode *parent,const QCString &target);
695     QCString parse(bool,bool isXmlLink=FALSE);
696     Kind kind() const          { return Kind_Link; }
697     QCString file() const       { return m_file; }
698     QCString relPath() const    { return m_relPath; }
699     QCString ref() const        { return m_ref; }
700     QCString anchor() const     { return m_anchor; }
701     void accept(DocVisitor *v) { CompAccept<DocLink>::accept(this,v); }
702
703   private:
704     QCString  m_file;
705     QCString  m_relPath;
706     QCString  m_ref;
707     QCString  m_anchor;
708     QCString  m_refText;
709 };
710
711 /** Node representing a reference to some item */
712 class DocRef : public CompAccept<DocRef>, public DocNode
713 {
714   public:
715     DocRef(DocNode *parent,const QCString &target,const QCString &context);
716     void parse();
717     Kind kind() const            { return Kind_Ref; }
718     QCString file() const         { return m_file; }
719     QCString relPath() const      { return m_relPath; }
720     QCString ref() const          { return m_ref; }
721     QCString anchor() const       { return m_anchor; }
722     QCString targetTitle() const  { return m_text; }
723     bool hasLinkText() const     { return !m_children.isEmpty(); }
724     bool refToAnchor() const     { return m_refToAnchor; }
725     bool refToSection() const    { return m_refToSection; }
726     bool isSubPage() const       { return m_isSubPage; }
727     void accept(DocVisitor *v)   { CompAccept<DocRef>::accept(this,v); }
728
729   private:
730     bool      m_refToSection;
731     bool      m_refToAnchor;
732     bool      m_isSubPage;
733     QCString   m_file;
734     QCString   m_relPath;
735     QCString   m_ref;
736     QCString   m_anchor;
737     QCString   m_text;
738 };
739
740 /** Node representing an internal reference to some item */
741 class DocInternalRef : public CompAccept<DocInternalRef>, public DocNode
742 {
743   public:
744     DocInternalRef(DocNode *parent,const QCString &target);
745     void parse();
746     Kind kind() const            { return Kind_Ref; }
747     QCString file() const         { return m_file; }
748     QCString relPath() const      { return m_relPath; }
749     QCString anchor() const       { return m_anchor; }
750     void accept(DocVisitor *v)   { CompAccept<DocInternalRef>::accept(this,v); }
751
752   private:
753     QCString   m_file;
754     QCString   m_relPath;
755     QCString   m_anchor;
756 };
757
758 /** Node representing a Hypertext reference */
759 class DocHRef : public CompAccept<DocHRef>, public DocNode
760 {
761   public:
762     DocHRef(DocNode *parent,const HtmlAttribList &attribs,const QCString &url,
763            const QCString &relPath) : 
764       m_attribs(attribs), m_url(url), m_relPath(relPath) { m_parent = parent; }
765     int parse();
766     QCString url() const        { return m_url; }
767     QCString relPath() const    { return m_relPath; }
768     Kind kind() const           { return Kind_HRef; }
769     void accept(DocVisitor *v)  { CompAccept<DocHRef>::accept(this,v); }
770     const HtmlAttribList &attribs() const { return m_attribs; }
771
772   private:
773     HtmlAttribList m_attribs;
774     QCString   m_url;
775     QCString   m_relPath;
776 };
777
778 /** Node Html heading */
779 class DocHtmlHeader : public CompAccept<DocHtmlHeader>, public DocNode
780 {
781   public:
782     DocHtmlHeader(DocNode *parent,const HtmlAttribList &attribs,int level) : 
783        m_level(level), m_attribs(attribs) { m_parent = parent; }
784     int level() const                     { return m_level; }
785     Kind kind() const                     { return Kind_HtmlHeader; }
786     const HtmlAttribList &attribs() const { return m_attribs; }
787     void accept(DocVisitor *v) { CompAccept<DocHtmlHeader>::accept(this,v); }
788     int parse();
789
790   private:
791     int           m_level;
792     HtmlAttribList m_attribs;
793 };
794
795 /** Node representing a Html description item */
796 class DocHtmlDescTitle : public CompAccept<DocHtmlDescTitle>, public DocNode
797 {
798   public:
799     DocHtmlDescTitle(DocNode *parent,const HtmlAttribList &attribs) : 
800       m_attribs(attribs) { m_parent = parent; }
801     Kind kind() const                     { return Kind_HtmlDescTitle; }
802     const HtmlAttribList &attribs() const { return m_attribs; }
803     void accept(DocVisitor *v) { CompAccept<DocHtmlDescTitle>::accept(this,v); }
804     int parse();
805
806   private:
807     HtmlAttribList m_attribs;
808 };
809
810 /** Node representing a Html description list */
811 class DocHtmlDescList : public CompAccept<DocHtmlDescList>, public DocNode
812 {
813   public:
814     DocHtmlDescList(DocNode *parent,const HtmlAttribList &attribs) :
815       m_attribs(attribs) { m_parent = parent; }
816     Kind kind() const                     { return Kind_HtmlDescList; }
817     const HtmlAttribList &attribs() const { return m_attribs; }
818     void accept(DocVisitor *v) { CompAccept<DocHtmlDescList>::accept(this,v); }
819     int parse();
820
821   private:
822     HtmlAttribList m_attribs;
823 };
824
825 /** Node representing a normal section */
826 class DocSection : public CompAccept<DocSection>, public DocNode
827 {
828   public:
829     DocSection(DocNode *parent,int level,const QCString &id) :
830       m_level(level), m_id(id) { m_parent = parent; } 
831     Kind kind() const          { return Kind_Section; }
832     int level() const          { return m_level; }
833     QCString title() const      { return m_title; }
834     QCString anchor() const     { return m_anchor; }
835     QCString id() const         { return m_id; }
836     QCString file() const       { return m_file; }
837     void accept(DocVisitor *v) { CompAccept<DocSection>::accept(this,v); }
838     int parse();
839
840   private:
841     int      m_level;
842     QCString  m_id;
843     QCString  m_title;
844     QCString  m_anchor;
845     QCString  m_file;
846 };
847
848 /** Node representing a reference to a section */
849 class DocSecRefItem : public CompAccept<DocSecRefItem>, public DocNode
850 {
851   public:
852     DocSecRefItem(DocNode *parent,const QCString &target) : 
853       m_target(target) { m_parent = parent; }
854     Kind kind() const          { return Kind_SecRefItem; }
855     QCString target() const     { return m_target; }
856     QCString file() const       { return m_file; }
857     QCString anchor() const     { return m_anchor; }
858     void accept(DocVisitor *v) { CompAccept<DocSecRefItem>::accept(this,v); }
859     void parse();
860
861   private:
862     QCString  m_target;
863     QCString  m_file;
864     QCString  m_anchor;
865 };
866
867 /** Node representing a list of section references */
868 class DocSecRefList : public CompAccept<DocSecRefList>, public DocNode
869 {
870   public:
871     DocSecRefList(DocNode *parent) { m_parent = parent; }
872     void parse();
873     Kind kind() const          { return Kind_SecRefList; }
874     void accept(DocVisitor *v) { CompAccept<DocSecRefList>::accept(this,v); }
875
876   private:
877 };
878
879 /** Node representing an internal section of documentation */
880 class DocInternal : public CompAccept<DocInternal>, public DocNode
881 {
882   public:
883     DocInternal(DocNode *parent) { m_parent = parent; }
884     int parse(int);
885     Kind kind() const          { return Kind_Internal; }
886     void accept(DocVisitor *v) { CompAccept<DocInternal>::accept(this,v); }
887
888   private:
889 };
890
891 /** Node representing a simple list */
892 class DocSimpleList : public CompAccept<DocSimpleList>, public DocNode
893 {
894   public:
895     DocSimpleList(DocNode *parent) { m_parent = parent; }
896     Kind kind() const          { return Kind_SimpleList; }
897     void accept(DocVisitor *v) { CompAccept<DocSimpleList>::accept(this,v); }
898     int parse();
899
900   private:
901 };
902
903 /** Node representing a Html list */
904 class DocHtmlList : public CompAccept<DocHtmlList>, public DocNode
905 {
906   public:
907     enum Type { Unordered, Ordered };
908     DocHtmlList(DocNode *parent,const HtmlAttribList &attribs,Type t) : 
909       m_type(t), m_attribs(attribs) { m_parent = parent; }
910     Kind kind() const          { return Kind_HtmlList; }
911     Type type() const          { return m_type; }
912     void accept(DocVisitor *v) { CompAccept<DocHtmlList>::accept(this,v); }
913     const HtmlAttribList &attribs() const { return m_attribs; }
914     int parse();
915     int parseXml();
916
917   private:
918     Type          m_type;
919     HtmlAttribList m_attribs;
920 };
921
922 /** Node representing a simple section */
923 class DocSimpleSect : public CompAccept<DocSimpleSect>, public DocNode
924 {
925   public:
926     enum Type 
927     {  
928        Unknown, See, Return, Author, Authors, Version, Since, Date,
929        Note, Warning, Copyright, Pre, Post, Invar, Remark, Attention, User, Rcs
930     };
931     DocSimpleSect(DocNode *parent,Type t);
932     virtual ~DocSimpleSect();
933     Kind kind() const       { return Kind_SimpleSect; }
934     Type type() const       { return m_type; }
935     QCString typeString() const;
936     void accept(DocVisitor *v);
937     int parse(bool userTitle,bool needsSeparator);
938     int parseRcs();
939     int parseXml();
940     void appendLinkWord(const QCString &word);
941
942   private:
943     Type            m_type;
944     DocTitle *      m_title;
945 };
946
947 /** Node representing a separator between two simple sections of the
948  *  same type. 
949  */
950 class DocSimpleSectSep : public DocNode
951 {
952   public:
953     DocSimpleSectSep(DocNode *parent) { m_parent = parent; }
954     Kind kind() const { return Kind_SimpleSectSep; }
955     void accept(DocVisitor *v) { v->visit(this); }
956
957   private:
958 };
959
960 /** Node representing a parameter section */
961 class DocParamSect : public CompAccept<DocParamSect>, public DocNode
962 {
963     friend class DocParamList;
964   public:
965     enum Type 
966     {  
967        Unknown, Param, RetVal, Exception, TemplateParam
968     };
969     enum Direction
970     {
971        In=1, Out=2, InOut=3, Unspecified=0
972     };
973     DocParamSect(DocNode *parent,Type t) 
974       : m_type(t), m_dir(Unspecified), 
975         m_hasInOutSpecifier(FALSE), m_hasTypeSpecifier(FALSE) 
976     { m_parent = parent; }
977     int parse(const QCString &cmdName,bool xmlContext,Direction d);
978     Kind kind() const          { return Kind_ParamSect; }
979     Type type() const          { return m_type; }
980     void accept(DocVisitor *v) { CompAccept<DocParamSect>::accept(this,v); }
981     bool hasInOutSpecifier() const { return m_hasInOutSpecifier; }
982     bool hasTypeSpecifier() const  { return m_hasTypeSpecifier; }
983
984   private:
985     Type            m_type;
986     Direction       m_dir;
987     bool            m_hasInOutSpecifier;
988     bool            m_hasTypeSpecifier;
989 };
990
991 /** Node representing a paragraph in the documentation tree */
992 class DocPara : public CompAccept<DocPara>, public DocNode
993 {
994   public:
995     DocPara(DocNode *parent) : 
996              m_isFirst(FALSE), m_isLast(FALSE) { m_parent = parent; }
997     int parse();
998     Kind kind() const           { return Kind_Para; }
999     bool isEmpty() const        { return m_children.isEmpty(); }
1000     void accept(DocVisitor *v)  { CompAccept<DocPara>::accept(this,v); }
1001     void markFirst(bool v=TRUE) { m_isFirst=v; }
1002     void markLast(bool v=TRUE)  { m_isLast=v; }
1003     bool isFirst() const        { return m_isFirst; }
1004     bool isLast() const         { return m_isLast; }
1005
1006     int handleCommand(const QCString &cmdName);
1007     int handleHtmlStartTag(const QCString &tagName,const HtmlAttribList &tagHtmlAttribs);
1008     int handleHtmlEndTag(const QCString &tagName);
1009     int handleSimpleSection(DocSimpleSect::Type t,bool xmlContext=FALSE);
1010     int handleXRefItem();
1011     int handleParamSection(const QCString &cmdName,DocParamSect::Type t,
1012                            bool xmlContext,
1013                            int direction);
1014     void handleIncludeOperator(const QCString &cmdName,DocIncOperator::Type t);
1015     void handleImage(const QCString &cmdName);
1016     void handleDotFile(const QCString &cmdName);
1017     void handleMscFile(const QCString &cmdName);
1018     void handleInclude(const QCString &cmdName,DocInclude::Type t);
1019     void handleLink(const QCString &cmdName,bool isJavaLink);
1020     void handleCite();
1021     void handleRef(const QCString &cmdName);
1022     void handleSection(const QCString &cmdName);
1023     void handleInheritDoc();
1024     int handleStartCode();
1025     int handleHtmlHeader(const HtmlAttribList &tagHtmlAttribs,int level);
1026
1027     bool injectToken(int tok,const QCString &tokText);
1028
1029   private:
1030     QCString  m_sectionId;
1031     bool     m_isFirst;
1032     bool     m_isLast;
1033 };
1034
1035 /** Node representing a parameter list. */
1036 class DocParamList : public DocNode
1037 {
1038   public:
1039     DocParamList(DocNode *parent,DocParamSect::Type t,DocParamSect::Direction d) 
1040       : m_type(t), m_dir(d), m_isFirst(TRUE), m_isLast(TRUE)
1041     { m_paragraphs.setAutoDelete(TRUE); 
1042       m_params.setAutoDelete(TRUE); 
1043       m_paramTypes.setAutoDelete(TRUE);
1044       m_parent = parent; 
1045     }
1046     virtual ~DocParamList()         { }
1047     Kind kind() const               { return Kind_ParamList; }
1048     const QList<DocNode> &parameters()    { return m_params; }
1049     const QList<DocNode> &paramTypes()    { return m_paramTypes; }
1050     DocParamSect::Type type() const { return m_type; }
1051     DocParamSect::Direction direction() const { return m_dir; }
1052     void markFirst(bool b=TRUE)     { m_isFirst=b; }
1053     void markLast(bool b=TRUE)      { m_isLast=b; }
1054     bool isFirst() const            { return m_isFirst; }
1055     bool isLast() const             { return m_isLast; }
1056     void accept(DocVisitor *v)
1057     { 
1058       v->visitPre(this); 
1059       QListIterator<DocPara> cli(m_paragraphs);
1060       DocNode *n;
1061       for (cli.toFirst();(n=cli.current());++cli) n->accept(v);
1062       v->visitPost(this); 
1063     }
1064     int parse(const QCString &cmdName);
1065     int parseXml(const QCString &paramName);
1066
1067   private:
1068     QList<DocPara>          m_paragraphs;
1069     QList<DocNode>          m_params;
1070     QList<DocNode>          m_paramTypes;
1071     DocParamSect::Type      m_type;
1072     DocParamSect::Direction m_dir;
1073     bool                    m_isFirst;
1074     bool                    m_isLast;
1075 };
1076
1077 /** Node representing a simple list item */
1078 class DocSimpleListItem : public DocNode
1079 {
1080   public:
1081     DocSimpleListItem(DocNode *parent)
1082     { m_paragraph=new DocPara(this); m_parent = parent; }
1083     int parse();
1084     virtual ~DocSimpleListItem() { delete m_paragraph; }
1085     Kind kind() const            { return Kind_SimpleListItem; }
1086     void accept(DocVisitor *v)
1087     {
1088       v->visitPre(this); 
1089       m_paragraph->accept(v);
1090       v->visitPost(this); 
1091     }
1092
1093   private:
1094     DocPara *m_paragraph;
1095 };
1096
1097 /** Node representing a HTML list item */
1098 class DocHtmlListItem : public CompAccept<DocHtmlListItem>, public DocNode
1099 {
1100   public:
1101     DocHtmlListItem(DocNode *parent,const HtmlAttribList &attribs,int num) : 
1102       m_attribs(attribs), m_itemNum(num) { m_parent = parent; }
1103     Kind kind() const                     { return Kind_HtmlListItem; }
1104     int itemNumber() const                { return m_itemNum; }
1105     const HtmlAttribList &attribs() const { return m_attribs; }
1106     void accept(DocVisitor *v) { CompAccept<DocHtmlListItem>::accept(this,v); }
1107     int parse();
1108     int parseXml();
1109
1110   private:
1111     HtmlAttribList m_attribs;
1112     int            m_itemNum;
1113 };
1114
1115 /** Node representing a HTML description data */
1116 class DocHtmlDescData : public CompAccept<DocHtmlDescData>, public DocNode
1117 {
1118   public:
1119     DocHtmlDescData(DocNode *parent) { m_parent = parent; }
1120     Kind kind() const                     { return Kind_HtmlDescData; }
1121     const HtmlAttribList &attribs() const { return m_attribs; }
1122     void accept(DocVisitor *v) { CompAccept<DocHtmlDescData>::accept(this,v); }
1123     int parse();
1124
1125   private:
1126     HtmlAttribList m_attribs;
1127 };
1128
1129 /** Node representing a HTML table cell */
1130 class DocHtmlCell : public CompAccept<DocHtmlCell>, public DocNode
1131 {
1132     friend class DocHtmlTable;
1133   public:
1134     enum Alignment { Left, Right, Center };
1135     DocHtmlCell(DocNode *parent,const HtmlAttribList &attribs,bool isHeading) : 
1136        m_isHeading(isHeading), 
1137        m_isFirst(FALSE), m_isLast(FALSE), m_attribs(attribs),
1138        m_rowIdx(-1), m_colIdx(-1) { m_parent = parent; }
1139     bool isHeading() const      { return m_isHeading; }
1140     bool isFirst() const        { return m_isFirst; }
1141     bool isLast() const         { return m_isLast; }
1142     Kind kind() const           { return Kind_HtmlCell; }
1143     void accept(DocVisitor *v)  { CompAccept<DocHtmlCell>::accept(this,v); }
1144     void markFirst(bool v=TRUE) { m_isFirst=v; }
1145     void markLast(bool v=TRUE)  { m_isLast=v; }
1146     const HtmlAttribList &attribs() const { return m_attribs; }
1147     int parse();
1148     int parseXml();
1149     int rowIndex() const        { return m_rowIdx; }
1150     int columnIndex() const     { return m_colIdx; }
1151     int rowSpan() const;
1152     int colSpan() const;
1153     Alignment alignment() const;
1154
1155   private:
1156     void setRowIndex(int idx)    { m_rowIdx = idx; }
1157     void setColumnIndex(int idx) { m_colIdx = idx; }
1158     bool           m_isHeading;
1159     bool           m_isFirst;
1160     bool           m_isLast;
1161     HtmlAttribList m_attribs;
1162     int            m_rowIdx;
1163     int            m_colIdx;
1164 };
1165
1166 /** Node representing a HTML table caption */
1167 class DocHtmlCaption : public CompAccept<DocHtmlCaption>, public DocNode
1168 {
1169   public:
1170     DocHtmlCaption(DocNode *parent,const HtmlAttribList &attribs) : 
1171       m_attribs(attribs) { m_parent = parent; }
1172     Kind kind() const          { return Kind_HtmlCaption; }
1173     void accept(DocVisitor *v) { CompAccept<DocHtmlCaption>::accept(this,v); }
1174     const HtmlAttribList &attribs() const { return m_attribs; }
1175     int parse();
1176
1177   private:
1178     HtmlAttribList m_attribs;
1179     bool           m_atTop;
1180 };
1181
1182 /** Node representing a HTML table row */
1183 class DocHtmlRow : public CompAccept<DocHtmlRow>, public DocNode
1184 {
1185     friend class DocHtmlTable;
1186   public:
1187     DocHtmlRow(DocNode *parent,const HtmlAttribList &attribs) : 
1188       m_attribs(attribs), m_visibleCells(-1), m_rowIdx(-1) { m_parent = parent; }
1189     Kind kind() const          { return Kind_HtmlRow; }
1190     uint numCells() const      { return m_children.count(); }
1191     void accept(DocVisitor *v) { CompAccept<DocHtmlRow>::accept(this,v); }
1192     const HtmlAttribList &attribs() const { return m_attribs; }
1193     int parse();
1194     int parseXml(bool header);
1195     bool isHeading() const     { return m_children.count()>0 && 
1196                                  ((DocHtmlCell*)m_children.getFirst())->isHeading(); 
1197                                }
1198     void setVisibleCells(int n) { m_visibleCells = n; }
1199     int visibleCells() const    { return m_visibleCells; }
1200     int rowIndex() const        { return m_rowIdx; }
1201
1202   private:
1203     void setRowIndex(int idx)    { m_rowIdx = idx; }
1204     HtmlAttribList m_attribs;
1205     int m_visibleCells;
1206     int m_rowIdx;
1207 };
1208
1209 /** Node representing a HTML table */
1210 class DocHtmlTable : public CompAccept<DocHtmlTable>, public DocNode
1211 {
1212   public:
1213     DocHtmlTable(DocNode *parent,const HtmlAttribList &attribs) 
1214       : m_attribs(attribs) { m_caption=0; m_parent = parent; }
1215     ~DocHtmlTable()         { delete m_caption; }
1216     Kind kind() const       { return Kind_HtmlTable; }
1217     uint numRows() const    { return m_children.count(); }
1218     bool hasCaption()       { return m_caption!=0; }
1219     const HtmlAttribList &attribs() const { return m_attribs; }
1220     int parse();
1221     int parseXml();
1222     uint numColumns() const { return m_numCols; }
1223     void accept(DocVisitor *v);
1224
1225   private:
1226     void computeTableGrid();
1227     DocHtmlCaption    *m_caption;
1228     HtmlAttribList     m_attribs;
1229     int m_numCols;
1230 };
1231
1232 /** Node representing an HTML blockquote */
1233 class DocHtmlBlockQuote : public CompAccept<DocHtmlBlockQuote>, public DocNode
1234 {
1235   public:
1236     DocHtmlBlockQuote(DocNode *parent,const HtmlAttribList &attribs)
1237       : m_attribs(attribs) { m_parent = parent; }
1238     Kind kind() const       { return Kind_HtmlBlockQuote; }
1239     int parse();
1240     void accept(DocVisitor *v) { CompAccept<DocHtmlBlockQuote>::accept(this,v); }
1241     const HtmlAttribList &attribs() const { return m_attribs; }
1242
1243   private:
1244     HtmlAttribList m_attribs;
1245 };
1246
1247 /** Root node of a text fragment */
1248 class DocText : public CompAccept<DocText>, public DocNode
1249 {
1250   public:
1251     DocText() {}
1252     Kind kind() const       { return Kind_Text; }
1253     void accept(DocVisitor *v) { CompAccept<DocText>::accept(this,v); }
1254     void parse();
1255 };
1256
1257 /** Root node of documentation tree */
1258 class DocRoot : public CompAccept<DocRoot>, public DocNode
1259 {
1260   public:
1261     DocRoot(bool indent,bool sl) : m_indent(indent), m_singleLine(sl) {}
1262     Kind kind() const       { return Kind_Root; }
1263     void accept(DocVisitor *v) { CompAccept<DocRoot>::accept(this,v); }
1264     void parse();
1265     bool indent() const { return m_indent; }
1266     bool singleLine() const { return m_singleLine; }
1267
1268   private:
1269     bool m_indent;
1270     bool m_singleLine;
1271 };
1272
1273
1274 #endif