Fix for UBSan build
[platform/upstream/doxygen.git] / src / printdocvisitor.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 _PRINTDOCVISITOR_H
20 #define _PRINTDOCVISITOR_H
21
22 #include "docvisitor.h"
23
24 /*! Concrete visitor implementation for pretty printing */
25 class PrintDocVisitor : public DocVisitor
26 {
27   public:
28     PrintDocVisitor() : DocVisitor(DocVisitor_Other), m_indent(0), 
29                         m_needsEnter(FALSE), m_insidePre(FALSE) {}
30     
31     //--------------------------------------
32     
33     void visit(DocWord *w)
34     {
35       indent_leaf();
36       printf("%s",w->word().data());
37     }
38     void visit(DocLinkedWord *w)
39     {
40       indent_leaf();
41       printf("%s",w->word().data());
42     }
43     void visit(DocWhiteSpace *w)
44     {
45       indent_leaf();
46       if (m_insidePre)
47       {
48         printf("%s",w->chars().data());
49       }
50       else
51       {
52         printf(" ");
53       }
54     }
55     void visit(DocSymbol *s)
56     {
57       indent_leaf();
58       switch(s->symbol())
59       {
60         case DocSymbol::BSlash:  printf("\\"); break;
61         case DocSymbol::At:      printf("@"); break;
62         case DocSymbol::Less:    printf("<"); break;
63         case DocSymbol::Greater: printf(">"); break;
64         case DocSymbol::Amp:     printf("&"); break;
65         case DocSymbol::Dollar:  printf("$"); break;
66         case DocSymbol::Hash:    printf("#"); break;
67         case DocSymbol::Percent: printf("%%"); break;
68         case DocSymbol::Pipe:    printf("|"); break;
69         case DocSymbol::Copy:    printf("&copy;"); break;
70         case DocSymbol::Apos:    printf("'"); break;
71         case DocSymbol::Quot:    printf("\""); break;
72         case DocSymbol::Lsquo:   printf("&lsquo;"); break;
73         case DocSymbol::Rsquo:   printf("&rsquo;"); break;
74         case DocSymbol::Ldquo:   printf("&ldquo;"); break;
75         case DocSymbol::Rdquo:   printf("&rdquo;"); break;
76         case DocSymbol::Ndash:   printf("&ndash;"); break;
77         case DocSymbol::Mdash:   printf("&mdash;"); break;
78         case DocSymbol::Uml:     printf("&%cuml;",s->letter()); break;
79         case DocSymbol::Acute:   printf("&%cacute;",s->letter()); break;
80         case DocSymbol::Grave:   printf("&%cgrave;",s->letter()); break;
81         case DocSymbol::Circ:    printf("&%ccirc;",s->letter()); break;
82         case DocSymbol::Tilde:   printf("&%ctilde;",s->letter()); break;
83         case DocSymbol::Szlig:   printf("&szlig;"); break;
84         case DocSymbol::Cedil:   printf("&%ccedul;",s->letter()); break;
85         case DocSymbol::Ring:    printf("&%cring;",s->letter()); break;
86         case DocSymbol::Nbsp:    printf("&nbsp;"); break;
87         case DocSymbol::Aelig:   printf("&aelig;"); break;
88         case DocSymbol::AElig:   printf("&AElig;"); break;
89     case DocSymbol::GrkGamma:      printf("&Gamma;"); break;
90     case DocSymbol::GrkDelta:      printf("&Delta;"); break;
91     case DocSymbol::GrkTheta:      printf("&Theta;"); break;
92     case DocSymbol::GrkLambda:     printf("&Lambda;"); break;
93     case DocSymbol::GrkXi:         printf("&Xi;"); break;
94     case DocSymbol::GrkPi:         printf("&Pi;"); break;
95     case DocSymbol::GrkSigma:      printf("&Sigma;"); break;
96     case DocSymbol::GrkUpsilon:    printf("&Upsilon;"); break;
97     case DocSymbol::GrkPhi:        printf("&Phi;"); break;
98     case DocSymbol::GrkPsi:        printf("&Psi;"); break;
99     case DocSymbol::GrkOmega:      printf("&Omega;"); break;
100     case DocSymbol::Grkalpha:      printf("&alpha;"); break;
101     case DocSymbol::Grkbeta:       printf("&beta;"); break;
102     case DocSymbol::Grkgamma:      printf("&gamma;"); break;
103     case DocSymbol::Grkdelta:      printf("&delta;"); break;
104     case DocSymbol::Grkepsilon:    printf("&epsilon;"); break;
105     case DocSymbol::Grkzeta:       printf("&zeta;"); break;
106     case DocSymbol::Grketa:        printf("&eta;"); break;
107     case DocSymbol::Grktheta:      printf("&theta;"); break;
108     case DocSymbol::Grkiota:       printf("&iota;"); break;
109     case DocSymbol::Grkkappa:      printf("&kappa;"); break;
110     case DocSymbol::Grklambda:     printf("&lambda;"); break;
111     case DocSymbol::Grkmu:         printf("&mu;"); break;
112     case DocSymbol::Grknu:         printf("&nu;"); break;
113     case DocSymbol::Grkxi:         printf("&xi;"); break;
114     case DocSymbol::Grkpi:         printf("&pi;"); break;
115     case DocSymbol::Grkrho:        printf("&rho;"); break;
116     case DocSymbol::Grksigma:      printf("&sigma;"); break;
117     case DocSymbol::Grktau:        printf("&tau;"); break;
118     case DocSymbol::Grkupsilon:    printf("&upsilon;"); break;
119     case DocSymbol::Grkphi:        printf("&phi;"); break;
120     case DocSymbol::Grkchi:        printf("&chi;"); break;
121     case DocSymbol::Grkpsi:        printf("&psi;"); break;
122     case DocSymbol::Grkomega:      printf("&omega;"); break;
123     case DocSymbol::Grkvarsigma:   printf("&sigmaf;"); break;
124     case DocSymbol::Section:       printf("&sect;"); break;
125     case DocSymbol::Degree:        printf("&deg;"); break;
126     case DocSymbol::Prime:         printf("&prime;"); break;
127     case DocSymbol::DoublePrime:   printf("&Prime;"); break;
128     case DocSymbol::Infinity:      printf("&infin;"); break;
129     case DocSymbol::EmptySet:      printf("&empty;"); break;
130     case DocSymbol::PlusMinus:     printf("&plusmn;"); break;
131     case DocSymbol::Times:         printf("&times;"); break;
132     case DocSymbol::Minus:         printf("&minus;"); break;
133     case DocSymbol::CenterDot:     printf("&sdot;"); break;
134     case DocSymbol::Partial:       printf("&part;"); break;
135     case DocSymbol::Nabla:         printf("&nabla;"); break;
136     case DocSymbol::SquareRoot:    printf("&radic;"); break;
137     case DocSymbol::Perpendicular: printf("&perp;"); break;
138     case DocSymbol::Sum:           printf("&sum;"); break;
139     case DocSymbol::Integral:      printf("&int;"); break;
140     case DocSymbol::Product:       printf("&prod;"); break;
141     case DocSymbol::Similar:       printf("&sim;"); break;
142     case DocSymbol::Approx:        printf("&asymp;"); break;
143     case DocSymbol::NotEqual:      printf("&ne;"); break;
144     case DocSymbol::Equivalent:    printf("&equiv;"); break;
145     case DocSymbol::Proportional:  printf("&prop;"); break;
146     case DocSymbol::LessEqual:     printf("&le;"); break;
147     case DocSymbol::GreaterEqual:  printf("&ge;"); break;
148     case DocSymbol::LeftArrow:     printf("&larr;"); break;
149     case DocSymbol::RightArrow:    printf("&rarr;"); break;
150     case DocSymbol::SetIn:         printf("&isin;"); break;
151     case DocSymbol::SetNotIn:      printf("&notin;"); break;
152     case DocSymbol::LeftCeil:      printf("&lceil;"); break;
153     case DocSymbol::RightCeil:     printf("&rceil;"); break;
154     case DocSymbol::LeftFloor:     printf("&lfloor;"); break;
155     case DocSymbol::RightFloor:    printf("&rfloor;"); break;
156         default:
157           printf("Error: unknown symbol found\n");
158       }
159     }
160     void visit(DocURL *u)
161     {
162       indent_leaf();
163       printf("%s",u->url().data());
164     }
165     void visit(DocLineBreak *)
166     {
167       indent_leaf();
168       printf("<br/>");
169     }
170     void visit(DocHorRuler *)
171     {
172       indent_leaf();
173       printf("<hr>");
174     }
175     void visit(DocStyleChange *s)
176     {
177       indent_leaf();
178       switch (s->style())
179       {
180         case DocStyleChange::Bold:
181          if (s->enable()) printf("<bold>"); else printf("</bold>");
182          break;
183         case DocStyleChange::Italic:
184          if (s->enable()) printf("<italic>"); else printf("</italic>");
185          break;
186         case DocStyleChange::Code:
187          if (s->enable()) printf("<code>"); else printf("</code>");
188          break;
189         case DocStyleChange::Subscript:
190          if (s->enable()) printf("<sub>"); else printf("</sub>");
191          break;
192         case DocStyleChange::Superscript:
193          if (s->enable()) printf("<sup>"); else printf("</sup>");
194          break;
195         case DocStyleChange::Center:
196          if (s->enable()) printf("<center>"); else printf("</center>");
197          break;
198         case DocStyleChange::Small:
199          if (s->enable()) printf("<small>"); else printf("</small>");
200          break;
201         case DocStyleChange::Preformatted:
202          if (s->enable()) printf("<pre>"); else printf("</pre>");
203          break;
204         case DocStyleChange::Div:
205          if (s->enable()) printf("<div>"); else printf("</div>");
206          break;
207         case DocStyleChange::Span:
208          if (s->enable()) printf("<span>"); else printf("</span>");
209          break;
210       }
211     }
212     void visit(DocVerbatim *s)
213     {
214       indent_leaf();
215       switch(s->type())
216       {
217         case DocVerbatim::Code: printf("<code>"); break;
218         case DocVerbatim::Verbatim: printf("<verbatim>"); break;
219         case DocVerbatim::HtmlOnly: printf("<htmlonly>"); break;
220         case DocVerbatim::RtfOnly: printf("<rtfonly>"); break;
221         case DocVerbatim::ManOnly: printf("<manonly>"); break;
222         case DocVerbatim::LatexOnly: printf("<latexonly>"); break;
223         case DocVerbatim::XmlOnly: printf("<xmlonly>"); break;
224         case DocVerbatim::Dot: printf("<dot>"); break;
225         case DocVerbatim::Msc: printf("<msc>"); break;
226       }
227       printf("%s",s->text().data());
228       switch(s->type())
229       {
230         case DocVerbatim::Code: printf("</code>"); break;
231         case DocVerbatim::Verbatim: printf("</verbatim>"); break;
232         case DocVerbatim::HtmlOnly: printf("</htmlonly>"); break;
233         case DocVerbatim::RtfOnly: printf("</rtfonly>"); break;
234         case DocVerbatim::ManOnly: printf("</manonly>"); break;
235         case DocVerbatim::LatexOnly: printf("</latexonly>"); break;
236         case DocVerbatim::XmlOnly: printf("</xmlonly>"); break;
237         case DocVerbatim::Dot: printf("</dot>"); break;
238         case DocVerbatim::Msc: printf("</msc>"); break;
239       }
240     }
241     void visit(DocAnchor *a)
242     {
243       indent_leaf();
244       printf("<anchor name=\"%s\"/>",a->anchor().data());
245     }
246     void visit(DocInclude *inc)
247     {
248       indent_leaf();
249       printf("<include file=\"%s\" type=\"",inc->file().data());
250       switch(inc->type())
251       {
252         case DocInclude::Include: printf("include"); break;
253         case DocInclude::IncWithLines: printf("incwithlines"); break;
254         case DocInclude::DontInclude: printf("dontinclude"); break;
255         case DocInclude::HtmlInclude: printf("htmlinclude"); break;
256         case DocInclude::VerbInclude: printf("verbinclude"); break;
257         case DocInclude::Snippet: printf("snippet"); break;
258       }
259       printf("\"/>");
260     }
261     void visit(DocIncOperator *op)
262     {
263       indent_leaf();
264       printf("<incoperator pattern=\"%s\" type=\"",op->pattern().data());
265       switch(op->type())
266       {
267         case DocIncOperator::Line:     printf("line");     break;
268         case DocIncOperator::Skip:     printf("skip");     break;
269         case DocIncOperator::SkipLine: printf("skipline"); break;
270         case DocIncOperator::Until:    printf("until");    break;
271       }
272       printf("\"/>");
273     }
274     void visit(DocFormula *f)
275     {
276       indent_leaf();
277       printf("<formula name=%s test=%s/>",f->name().data(),f->text().data());
278     }
279     void visit(DocIndexEntry *i)
280     {
281       indent_leaf();
282       printf("<indexentry>%s</indexentry\n",i->entry().data());
283     }
284     void visit(DocSimpleSectSep *)
285     {
286       indent_leaf();
287       printf("<simplesectsep/>");
288     }
289     void visit(DocCite *cite)
290     {
291       indent_leaf();
292       printf("<cite ref=\"%s\" file=\"%s\" "
293              "anchor=\"%s\" text=\"%s\""
294              "/>\n",
295              cite->ref().data(),cite->file().data(),cite->anchor().data(),
296              cite->text().data());
297     }
298
299     //--------------------------------------
300     
301     void visitPre(DocAutoList *l)
302     {
303       indent_pre();
304       if (l->isEnumList())
305       {
306         printf("<ol>\n");
307       }
308       else
309       {
310         printf("<ul>\n");
311       }
312     }
313     void visitPost(DocAutoList *l)
314     {
315       indent_post();
316       if (l->isEnumList())
317       {
318         printf("</ol>\n");
319       }
320       else
321       {
322         printf("</ul>\n");
323       }
324     }
325     void visitPre(DocAutoListItem *)
326     {
327       indent_pre();
328       printf("<li>\n");
329     }
330     void visitPost(DocAutoListItem *) 
331     {
332       indent_post();
333       printf("</li>\n");
334     }
335     void visitPre(DocPara *) 
336     {
337       indent_pre();
338       printf("<para>\n");
339     }
340     void visitPost(DocPara *)
341     {
342       indent_post();
343       printf("</para>\n");
344     }
345     void visitPre(DocRoot *)
346     {
347       indent_pre();
348       printf("<root>\n");
349     }
350     void visitPost(DocRoot *)
351     {
352       indent_post();
353       printf("</root>\n");
354     }
355     void visitPre(DocSimpleSect *s)
356     {
357       indent_pre();
358       printf("<simplesect type=");
359       switch(s->type())
360       {
361         case DocSimpleSect::See: printf("see"); break;
362         case DocSimpleSect::Return: printf("return"); break;
363         case DocSimpleSect::Author: printf("author"); break;
364         case DocSimpleSect::Authors: printf("authors"); break;
365         case DocSimpleSect::Version: printf("version"); break;
366         case DocSimpleSect::Since: printf("since"); break;
367         case DocSimpleSect::Date: printf("date"); break;
368         case DocSimpleSect::Note: printf("note"); break;
369         case DocSimpleSect::Warning: printf("warning"); break;
370         case DocSimpleSect::Pre: printf("pre"); break;
371         case DocSimpleSect::Post: printf("post"); break;
372         case DocSimpleSect::Copyright: printf("copyright"); break;
373         case DocSimpleSect::Invar: printf("invar"); break;
374         case DocSimpleSect::Remark: printf("remark"); break;
375         case DocSimpleSect::Attention: printf("attention"); break;
376         case DocSimpleSect::User: printf("user"); break;
377         case DocSimpleSect::Rcs: printf("rcs"); break;
378         case DocSimpleSect::Unknown: printf("unknown"); break;
379       }
380       printf(">\n");
381     }
382     void visitPost(DocSimpleSect *)
383     {
384       indent_post();
385       printf("</simplesect>\n");
386     }
387     void visitPre(DocTitle *)
388     {
389       indent_pre();
390       printf("<title>\n");
391     }
392     void visitPost(DocTitle *)
393     {
394       indent_post();
395       printf("</title>\n");
396     }
397     void visitPre(DocSimpleList *)
398     {
399       indent_pre();
400       printf("<ul>\n");
401     }
402     void visitPost(DocSimpleList *)
403     {
404       indent_post();
405       printf("</ul>\n");
406     }
407     void visitPre(DocSimpleListItem *)
408     {
409       indent_pre();
410       printf("<li>\n");
411     }
412     void visitPost(DocSimpleListItem *) 
413     {
414       indent_post();
415       printf("</li>\n");
416     }
417     void visitPre(DocSection *s)
418     {
419       indent_pre();
420       printf("<sect%d>\n",s->level());
421     }
422     void visitPost(DocSection *s) 
423     {
424       indent_post();
425       printf("</sect%d>\n",s->level());
426     }
427     void visitPre(DocHtmlList *s)
428     {
429       indent_pre();
430       if (s->type()==DocHtmlList::Ordered) printf("<ol>\n"); else printf("<ul>\n");
431     }
432     void visitPost(DocHtmlList *s) 
433     {
434       indent_post();
435       if (s->type()==DocHtmlList::Ordered) printf("</ol>\n"); else printf("</ul>\n");
436     }
437     void visitPre(DocHtmlListItem *)
438     {
439       indent_pre();
440       printf("<li>\n");
441     }
442     void visitPost(DocHtmlListItem *) 
443     {
444       indent_post();
445       printf("</li>\n");
446     }
447     //void visitPre(DocHtmlPre *)
448     //{
449     //  indent_pre();
450     //  printf("<pre>\n");
451     //  m_insidePre=TRUE;
452     //}
453     //void visitPost(DocHtmlPre *) 
454     //{
455     //  m_insidePre=FALSE;
456     //  indent_post();
457     //  printf("</pre>\n");
458     //}
459     void visitPre(DocHtmlDescList *)
460     {
461       indent_pre();
462       printf("<dl>\n");
463     }
464     void visitPost(DocHtmlDescList *) 
465     {
466       indent_post();
467       printf("</dl>\n");
468     }
469     void visitPre(DocHtmlDescTitle *)
470     {
471       indent_pre();
472       printf("<dt>\n");
473     }
474     void visitPost(DocHtmlDescTitle *) 
475     {
476       indent_post();
477       printf("</dt>\n");
478     }
479     void visitPre(DocHtmlDescData *)
480     {
481       indent_pre();
482       printf("<dd>\n");
483     }
484     void visitPost(DocHtmlDescData *) 
485     {
486       indent_post();
487       printf("</dd>\n");
488     }
489     void visitPre(DocHtmlTable *t)
490     {
491       indent_pre();
492       printf("<table rows=\"%d\" cols=\"%d\">\n",
493           t->numRows(),t->numColumns());
494     }
495     void visitPost(DocHtmlTable *) 
496     {
497       indent_post();
498       printf("</table>\n");
499     }
500     void visitPre(DocHtmlRow *)
501     {
502       indent_pre();
503       printf("<tr>\n");
504     }
505     void visitPost(DocHtmlRow *) 
506     {
507       indent_post();
508       printf("</tr>\n");
509     }
510     void visitPre(DocHtmlCell *c)
511     {
512       indent_pre();
513       printf("<t%c>\n",c->isHeading()?'h':'d');
514     }
515     void visitPost(DocHtmlCell *c) 
516     {
517       indent_post();
518       printf("</t%c>\n",c->isHeading()?'h':'d');
519     }
520     void visitPre(DocHtmlCaption *)
521     {
522       indent_pre();
523       printf("<caption>\n");
524     }
525     void visitPost(DocHtmlCaption *) 
526     {
527       indent_post();
528       printf("</caption>\n");
529     }
530     void visitPre(DocInternal *)
531     {
532       indent_pre();
533       printf("<internal>\n");
534     }
535     void visitPost(DocInternal *) 
536     {
537       indent_post();
538       printf("</internal>\n");
539     }
540     void visitPre(DocHRef *href)
541     {
542       indent_pre();
543       printf("<a url=\"%s\">\n",href->url().data());
544     }
545     void visitPost(DocHRef *) 
546     {
547       indent_post();
548       printf("</a>\n");
549     }
550     void visitPre(DocHtmlHeader *header)
551     {
552       indent_pre();
553       printf("<h%d>\n",header->level());
554     }
555     void visitPost(DocHtmlHeader *header) 
556     {
557       indent_post();
558       printf("</h%d>\n",header->level());
559     }
560     void visitPre(DocImage *img)
561     {
562       indent_pre();
563       printf("<image src=\"%s\" type=\"",img->name().data());
564       switch(img->type())
565       {
566         case DocImage::Html: printf("html"); break;
567         case DocImage::Latex: printf("latex"); break;
568         case DocImage::Rtf: printf("rtf"); break;
569       }
570       printf("\" width=%s height=%s>\n",img->width().data(),img->height().data());
571     }
572     void visitPost(DocImage *) 
573     {
574       indent_post();
575       printf("</image>\n");
576     }
577     void visitPre(DocDotFile *df)
578     {
579       indent_pre();
580       printf("<dotfile src=\"%s\">\n",df->name().data());
581     }
582     void visitPost(DocDotFile *) 
583     {
584       indent_post();
585       printf("</dotfile>\n");
586     }
587     void visitPre(DocMscFile *df)
588     {
589       indent_pre();
590       printf("<mscfile src=\"%s\">\n",df->name().data());
591     }
592     void visitPost(DocMscFile *) 
593     {
594       indent_post();
595       printf("</mscfile>\n");
596     }
597     void visitPre(DocLink *lnk)
598     {
599       indent_pre();
600       printf("<link ref=\"%s\" file=\"%s\" anchor=\"%s\">\n",
601           lnk->ref().data(),lnk->file().data(),lnk->anchor().data());
602     }
603     void visitPost(DocLink *) 
604     {
605       indent_post();
606       printf("</link>\n");
607     }
608     void visitPre(DocRef *ref)
609     {
610       indent_pre();
611       printf("<ref ref=\"%s\" file=\"%s\" "
612              "anchor=\"%s\" targetTitle=\"%s\""
613              " hasLinkText=\"%s\" refToAnchor=\"%s\" refToSection=\"%s\">\n",
614              ref->ref().data(),ref->file().data(),ref->anchor().data(),
615              ref->targetTitle().data(),ref->hasLinkText()?"yes":"no",
616              ref->refToAnchor()?"yes":"no", ref->refToSection()?"yes":"no");
617     }
618     void visitPost(DocRef *) 
619     {
620       indent_post();
621       printf("</ref>\n");
622     }
623     void visitPre(DocSecRefItem *ref)
624     {
625       indent_pre();
626       printf("<secrefitem target=\"%s\">\n",ref->target().data());
627     }
628     void visitPost(DocSecRefItem *) 
629     {
630       indent_post();
631       printf("</secrefitem>\n");
632     }
633     void visitPre(DocSecRefList *)
634     {
635       indent_pre();
636       printf("<secreflist>\n");
637     }
638     void visitPost(DocSecRefList *) 
639     {
640       indent_post();
641       printf("</secreflist>\n");
642     }
643     //void visitPre(DocLanguage *l)
644     //{
645     //  indent_pre();
646     //  printf("<language id=%s>\n",l->id().data());
647     //}
648     //void visitPost(DocLanguage *) 
649     //{
650     //  indent_post();
651     //  printf("</language>\n");
652     //}
653     void visitPre(DocParamList *pl)
654     {
655       indent_pre();
656       //QStrListIterator sli(pl->parameters());
657       QListIterator<DocNode> sli(pl->parameters());
658       //const char *s;
659       DocNode *param;
660       printf("<parameters>");
661       for (sli.toFirst();(param=sli.current());++sli)
662       {
663         printf("<param>");
664         if (param->kind()==DocNode::Kind_Word)
665         {
666           visit((DocWord*)param); 
667         }
668         else if (param->kind()==DocNode::Kind_LinkedWord)
669         {
670           visit((DocLinkedWord*)param); 
671         }
672         printf("</param>");
673       }
674       printf("\n");
675     }
676     void visitPost(DocParamList *)
677     {
678       indent_post();
679       printf("</parameters>\n");
680     }
681     void visitPre(DocParamSect *ps)
682     {
683       indent_pre();
684       printf("<paramsect type=");
685       switch (ps->type())
686       {
687         case DocParamSect::Param: printf("param"); break;
688         case DocParamSect::RetVal: printf("retval"); break;
689         case DocParamSect::Exception: printf("exception"); break;
690         case DocParamSect::TemplateParam: printf("templateparam"); break;
691         case DocParamSect::Unknown: printf("unknown"); break;
692       }
693       printf(">\n");
694     }
695     void visitPost(DocParamSect *)
696     {
697       indent_post();
698       printf("</paramsect>\n");
699     }
700     void visitPre(DocXRefItem *x)
701     {
702       indent_pre();
703       printf("<xrefitem file=\"%s\" anchor=\"%s\" title=\"%s\"/>\n",
704           x->file().data(),x->anchor().data(),x->title().data());
705     }
706     void visitPost(DocXRefItem *)
707     {
708       indent_post();
709       printf("<xrefitem/>\n");
710     }
711     void visitPre(DocInternalRef *r)
712     {
713       indent_pre();
714       printf("<internalref file=%s anchor=%s>\n",r->file().data(),r->anchor().data());
715     }
716     void visitPost(DocInternalRef *)
717     {
718       indent_post();
719       printf("</internalref>\n");
720     }
721     void visitPre(DocCopy *c)
722     {
723       indent_pre();
724       printf("<copy link=\"%s\">\n",c->link().data());
725     }
726     void visitPost(DocCopy *)
727     {
728       indent_post();
729       printf("</copy>\n");
730     }
731     void visitPre(DocText *)
732     {
733       indent_pre();
734       printf("<text>\n");
735     }
736     void visitPost(DocText *)
737     {
738       indent_post();
739       printf("</text>\n");
740     }
741     void visitPre(DocHtmlBlockQuote *)
742     {
743       indent_pre();
744       printf("<blockquote>\n");
745     }
746     void visitPost(DocHtmlBlockQuote *)
747     {
748       indent_post();
749       printf("</blockquote>\n");
750     }
751
752   private:
753     // helper functions
754     void indent() 
755     { 
756       if (m_needsEnter) printf("\n");
757       for (int i=0;i<m_indent;i++) printf("."); 
758       m_needsEnter=FALSE;
759     } 
760     void indent_leaf()
761     {
762       if (!m_needsEnter) indent();
763       m_needsEnter=TRUE;
764     }
765     void indent_pre()
766     {
767       indent();
768       m_indent++;
769     }
770     void indent_post()
771     {
772       m_indent--;
773       indent();
774     }
775     
776     // member variables
777     int m_indent;
778     bool m_needsEnter;
779     bool m_insidePre;
780 };
781
782 #endif