1 /******************************************************************************
6 * Copyright (C) 1997-2012 by Dimitri van Heesch.
7 * Authors: Dimitri van Heesch, Miguel Lobo.
9 * Permission to use, copy, modify, and distribute this software and its
10 * documentation under the terms of the GNU General Public License is hereby
11 * granted. No representations are made about the suitability of this software
12 * for any purpose. It is provided "as is" without express or implied warranty.
13 * See the GNU General Public License for more details.
15 * Documents produced by Doxygen are derivative works derived from the
16 * input used in their production; they are not affected by this license.
22 #include "perlmodgen.h"
23 #include "docparser.h"
32 #include "ftextstream.h"
33 #include "arguments.h"
35 #define PERLOUTPUT_MAX_INDENTATION 40
37 class PerlModOutputStream
44 PerlModOutputStream(FTextStream *t = 0) : m_t(t) { }
47 void add(const char *s);
48 void add(QCString &s);
50 void add(unsigned int n);
53 void PerlModOutputStream::add(char c)
61 void PerlModOutputStream::add(const char *s)
69 void PerlModOutputStream::add(QCString &s)
77 void PerlModOutputStream::add(int n)
85 void PerlModOutputStream::add(unsigned int n)
99 inline PerlModOutput(bool pretty)
100 : m_pretty(pretty), m_stream(0), m_indentation(false), m_blockstart(true)
105 virtual ~PerlModOutput() { }
107 inline void setPerlModOutputStream(PerlModOutputStream *os) { m_stream = os; }
109 inline PerlModOutput &openSave() { iopenSave(); return *this; }
110 inline PerlModOutput &closeSave(QCString &s) { icloseSave(s); return *this; }
112 inline PerlModOutput &continueBlock()
115 m_blockstart = false;
122 inline PerlModOutput &add(char c) { m_stream->add(c); return *this; }
123 inline PerlModOutput &add(const char *s) { m_stream->add(s); return *this; }
124 inline PerlModOutput &add(QCString &s) { m_stream->add(s); return *this; }
125 inline PerlModOutput &add(int n) { m_stream->add(n); return *this; }
126 inline PerlModOutput &add(unsigned int n) { m_stream->add(n); return *this; }
128 PerlModOutput &addQuoted(const char *s) { iaddQuoted(s); return *this; }
130 inline PerlModOutput &indent()
134 m_stream->add(m_spaces);
139 inline PerlModOutput &open(char c, const char *s = 0) { iopen(c, s); return *this; }
140 inline PerlModOutput &close(char c = 0) { iclose(c); return *this; }
142 inline PerlModOutput &addField(const char *s) { iaddField(s); return *this; }
143 inline PerlModOutput &addFieldQuotedChar(const char *field, char content)
145 iaddFieldQuotedChar(field, content); return *this;
147 inline PerlModOutput &addFieldQuotedString(const char *field, const char *content)
149 iaddFieldQuotedString(field, content); return *this;
151 inline PerlModOutput &addFieldBoolean(const char *field, bool content)
153 return addFieldQuotedString(field, content ? "yes" : "no");
155 inline PerlModOutput &openList(const char *s = 0) { open('[', s); return *this; }
156 inline PerlModOutput &closeList() { close(']'); return *this; }
157 inline PerlModOutput &openHash(const char *s = 0 ) { open('{', s); return *this; }
158 inline PerlModOutput &closeHash() { close('}'); return *this; }
163 void icloseSave(QCString &);
168 void iaddQuoted(const char *);
169 void iaddFieldQuotedChar(const char *, char);
170 void iaddFieldQuotedString(const char *, const char *);
171 void iaddField(const char *);
173 void iopen(char, const char *);
178 PerlModOutputStream *m_stream;
182 QStack<PerlModOutputStream> m_saved;
183 char m_spaces[PERLOUTPUT_MAX_INDENTATION * 2 + 2];
186 void PerlModOutput::iopenSave()
188 m_saved.push(m_stream);
189 m_stream = new PerlModOutputStream();
192 void PerlModOutput::icloseSave(QCString &s)
196 m_stream = m_saved.pop();
199 void PerlModOutput::incIndent()
201 if (m_indentation < PERLOUTPUT_MAX_INDENTATION)
203 char *s = &m_spaces[m_indentation * 2];
204 *s++ = ' '; *s++ = ' '; *s = 0;
209 void PerlModOutput::decIndent()
212 if (m_indentation < PERLOUTPUT_MAX_INDENTATION)
213 m_spaces[m_indentation * 2] = 0;
216 void PerlModOutput::iaddQuoted(const char *s)
219 while ((c = *s++) != 0) {
220 if ((c == '\'') || (c == '\\'))
226 void PerlModOutput::iaddField(const char *s)
230 m_stream->add(m_pretty ? " => " : "=>");
233 void PerlModOutput::iaddFieldQuotedChar(const char *field, char content)
237 if ((content == '\'') || (content == '\\'))
239 m_stream->add(content);
243 void PerlModOutput::iaddFieldQuotedString(const char *field, const char *content)
253 void PerlModOutput::iopen(char c, const char *s)
264 void PerlModOutput::iclose(char c)
270 m_blockstart = false;
273 /*! @brief Concrete visitor implementation for PerlMod output. */
274 class PerlModDocVisitor : public DocVisitor
277 PerlModDocVisitor(PerlModOutput &);
278 virtual ~PerlModDocVisitor() { }
282 //--------------------------------------
283 // visitor functions for leaf nodes
284 //--------------------------------------
286 void visit(DocWord *);
287 void visit(DocLinkedWord *);
288 void visit(DocWhiteSpace *);
289 void visit(DocSymbol *);
290 void visit(DocURL *);
291 void visit(DocLineBreak *);
292 void visit(DocHorRuler *);
293 void visit(DocStyleChange *);
294 void visit(DocVerbatim *);
295 void visit(DocAnchor *);
296 void visit(DocInclude *);
297 void visit(DocIncOperator *);
298 void visit(DocFormula *);
299 void visit(DocIndexEntry *);
300 void visit(DocSimpleSectSep *);
301 void visit(DocCite *);
303 //--------------------------------------
304 // visitor functions for compound nodes
305 //--------------------------------------
307 void visitPre(DocAutoList *);
308 void visitPost(DocAutoList *);
309 void visitPre(DocAutoListItem *);
310 void visitPost(DocAutoListItem *);
311 void visitPre(DocPara *) ;
312 void visitPost(DocPara *);
313 void visitPre(DocRoot *);
314 void visitPost(DocRoot *);
315 void visitPre(DocSimpleSect *);
316 void visitPost(DocSimpleSect *);
317 void visitPre(DocTitle *);
318 void visitPost(DocTitle *);
319 void visitPre(DocSimpleList *);
320 void visitPost(DocSimpleList *);
321 void visitPre(DocSimpleListItem *);
322 void visitPost(DocSimpleListItem *);
323 void visitPre(DocSection *);
324 void visitPost(DocSection *);
325 void visitPre(DocHtmlList *);
326 void visitPost(DocHtmlList *) ;
327 void visitPre(DocHtmlListItem *);
328 void visitPost(DocHtmlListItem *);
329 //void visitPre(DocHtmlPre *);
330 //void visitPost(DocHtmlPre *);
331 void visitPre(DocHtmlDescList *);
332 void visitPost(DocHtmlDescList *);
333 void visitPre(DocHtmlDescTitle *);
334 void visitPost(DocHtmlDescTitle *);
335 void visitPre(DocHtmlDescData *);
336 void visitPost(DocHtmlDescData *);
337 void visitPre(DocHtmlTable *);
338 void visitPost(DocHtmlTable *);
339 void visitPre(DocHtmlRow *);
340 void visitPost(DocHtmlRow *) ;
341 void visitPre(DocHtmlCell *);
342 void visitPost(DocHtmlCell *);
343 void visitPre(DocHtmlCaption *);
344 void visitPost(DocHtmlCaption *);
345 void visitPre(DocInternal *);
346 void visitPost(DocInternal *);
347 void visitPre(DocHRef *);
348 void visitPost(DocHRef *);
349 void visitPre(DocHtmlHeader *);
350 void visitPost(DocHtmlHeader *);
351 void visitPre(DocImage *);
352 void visitPost(DocImage *);
353 void visitPre(DocDotFile *);
354 void visitPost(DocDotFile *);
355 void visitPre(DocMscFile *);
356 void visitPost(DocMscFile *);
357 void visitPre(DocLink *);
358 void visitPost(DocLink *);
359 void visitPre(DocRef *);
360 void visitPost(DocRef *);
361 void visitPre(DocSecRefItem *);
362 void visitPost(DocSecRefItem *);
363 void visitPre(DocSecRefList *);
364 void visitPost(DocSecRefList *);
365 //void visitPre(DocLanguage *);
366 //void visitPost(DocLanguage *);
367 void visitPre(DocParamSect *);
368 void visitPost(DocParamSect *);
369 void visitPre(DocParamList *);
370 void visitPost(DocParamList *);
371 void visitPre(DocXRefItem *);
372 void visitPost(DocXRefItem *);
373 void visitPre(DocInternalRef *);
374 void visitPost(DocInternalRef *);
375 void visitPre(DocCopy *);
376 void visitPost(DocCopy *);
377 void visitPre(DocText *);
378 void visitPost(DocText *);
379 void visitPre(DocHtmlBlockQuote *);
380 void visitPost(DocHtmlBlockQuote *);
384 //--------------------------------------
386 //--------------------------------------
388 void addLink(const QCString &ref, const QCString &file,
389 const QCString &anchor);
394 void openItem(const char *);
396 void singleItem(const char *);
397 void openSubBlock(const char * = 0);
398 void closeSubBlock();
402 //--------------------------------------
404 //--------------------------------------
406 PerlModOutput &m_output;
408 bool m_textblockstart;
412 PerlModDocVisitor::PerlModDocVisitor(PerlModOutput &output)
413 : DocVisitor(DocVisitor_Other), m_output(output), m_textmode(false)
415 m_output.openList("doc");
418 void PerlModDocVisitor::finish()
425 void PerlModDocVisitor::addLink(const QCString &,const QCString &file,const QCString &anchor)
427 QCString link = file;
428 if (!anchor.isEmpty())
429 (link += "_1") += anchor;
430 m_output.addFieldQuotedString("link", link);
433 void PerlModDocVisitor::openItem(const char *name)
436 m_output.openHash().addFieldQuotedString("type", name);
439 void PerlModDocVisitor::closeItem()
442 m_output.closeHash();
445 void PerlModDocVisitor::enterText()
450 m_output.addField("content").add('\'');
454 void PerlModDocVisitor::leaveText()
464 void PerlModDocVisitor::singleItem(const char *name)
470 void PerlModDocVisitor::openSubBlock(const char *s)
473 m_output.openList(s);
474 m_textblockstart = true;
477 void PerlModDocVisitor::closeSubBlock()
480 m_output.closeList();
483 void PerlModDocVisitor::openOther()
485 // Using a secondary text stream will corrupt the perl file. Instead of
486 // printing doc => [ data => [] ], it will print doc => [] data => [].
493 void PerlModDocVisitor::closeOther()
495 // Using a secondary text stream will corrupt the perl file. Instead of
496 // printing doc => [ data => [] ], it will print doc => [] data => [].
500 m_output.closeSave(other);
505 void PerlModDocVisitor::visit(DocWord *w)
508 m_output.addQuoted(w->word());
511 void PerlModDocVisitor::visit(DocLinkedWord *w)
514 addLink(w->ref(), w->file(), w->anchor());
515 m_output.addFieldQuotedString("content", w->word());
519 void PerlModDocVisitor::visit(DocWhiteSpace *)
525 void PerlModDocVisitor::visit(DocSymbol *sy)
529 const char *accent = 0;
530 const char *symbol = 0;
533 case DocSymbol::At: c = '@'; break;
534 case DocSymbol::Less: c = '<'; break;
535 case DocSymbol::Greater: c = '>'; break;
536 case DocSymbol::Amp: c = '&'; break;
537 case DocSymbol::Dollar: c = '$'; break;
538 case DocSymbol::Hash: c = '#'; break;
539 case DocSymbol::DoubleColon: s = "::"; break;
540 case DocSymbol::Percent: c = '%'; break;
541 case DocSymbol::Pipe: c = '|'; break;
542 case DocSymbol::Quot: c = '"'; break;
543 case DocSymbol::Lsquo: s = "\\\'"; break;
544 case DocSymbol::Rsquo: s = "\\\'"; break;
545 case DocSymbol::Ldquo: c = '"'; break;
546 case DocSymbol::Rdquo: c = '"'; break;
547 case DocSymbol::Ndash: c = '-'; break;
548 case DocSymbol::Mdash: s = "--"; break;
549 case DocSymbol::Nbsp: c = ' '; break;
550 case DocSymbol::Uml: accent = "umlaut"; break;
551 case DocSymbol::Acute: accent = "acute"; break;
552 case DocSymbol::Grave: accent = "grave"; break;
553 case DocSymbol::Circ: accent = "circ"; break;
554 case DocSymbol::Slash: accent = "slash"; break;
555 case DocSymbol::Tilde: accent = "tilde"; break;
556 case DocSymbol::Cedil: accent = "cedilla"; break;
557 case DocSymbol::Ring: accent = "ring"; break;
558 case DocSymbol::BSlash: s = "\\\\"; break;
559 case DocSymbol::Copy: symbol = "copyright"; break;
560 case DocSymbol::Tm: symbol = "trademark"; break;
561 case DocSymbol::Reg: symbol = "registered"; break;
562 case DocSymbol::Szlig: symbol = "szlig"; break;
563 case DocSymbol::Apos: s = "\\\'"; break;
564 case DocSymbol::Aelig: symbol = "aelig"; break;
565 case DocSymbol::AElig: symbol = "AElig"; break;
566 case DocSymbol::GrkGamma: symbol = "Gamma"; break;
567 case DocSymbol::GrkDelta: symbol = "Delta"; break;
568 case DocSymbol::GrkTheta: symbol = "Theta"; break;
569 case DocSymbol::GrkLambda: symbol = "Lambda"; break;
570 case DocSymbol::GrkXi: symbol = "Xi"; break;
571 case DocSymbol::GrkPi: symbol = "Pi"; break;
572 case DocSymbol::GrkSigma: symbol = "Sigma"; break;
573 case DocSymbol::GrkUpsilon: symbol = "Upsilon"; break;
574 case DocSymbol::GrkPhi: symbol = "Phi"; break;
575 case DocSymbol::GrkPsi: symbol = "Psi"; break;
576 case DocSymbol::GrkOmega: symbol = "Omega"; break;
577 case DocSymbol::Grkalpha: symbol = "alpha"; break;
578 case DocSymbol::Grkbeta: symbol = "beta"; break;
579 case DocSymbol::Grkgamma: symbol = "gamma"; break;
580 case DocSymbol::Grkdelta: symbol = "delta"; break;
581 case DocSymbol::Grkepsilon: symbol = "epsilon"; break;
582 case DocSymbol::Grkzeta: symbol = "zeta"; break;
583 case DocSymbol::Grketa: symbol = "eta"; break;
584 case DocSymbol::Grktheta: symbol = "theta"; break;
585 case DocSymbol::Grkiota: symbol = "iota"; break;
586 case DocSymbol::Grkkappa: symbol = "kappa"; break;
587 case DocSymbol::Grklambda: symbol = "lambda"; break;
588 case DocSymbol::Grkmu: symbol = "mu"; break;
589 case DocSymbol::Grknu: symbol = "nu"; break;
590 case DocSymbol::Grkxi: symbol = "xi"; break;
591 case DocSymbol::Grkpi: symbol = "pi"; break;
592 case DocSymbol::Grkrho: symbol = "rho"; break;
593 case DocSymbol::Grksigma: symbol = "sigma"; break;
594 case DocSymbol::Grktau: symbol = "tau"; break;
595 case DocSymbol::Grkupsilon: symbol = "upsilon"; break;
596 case DocSymbol::Grkphi: symbol = "phi"; break;
597 case DocSymbol::Grkchi: symbol = "chi"; break;
598 case DocSymbol::Grkpsi: symbol = "psi"; break;
599 case DocSymbol::Grkomega: symbol = "omega"; break;
600 case DocSymbol::Grkvarsigma: symbol = "sigma"; break;
601 case DocSymbol::Section: symbol = "sect"; break;
602 case DocSymbol::Degree: symbol = "deg"; break;
603 case DocSymbol::Prime: s = "\\\'"; break;
604 case DocSymbol::DoublePrime: c = '"'; break;
605 case DocSymbol::Infinity: symbol = "inf"; break;
606 case DocSymbol::EmptySet: symbol = "empty"; break;
607 case DocSymbol::PlusMinus: s = "+/-"; break;
608 case DocSymbol::Times: c = '*'; break;
609 case DocSymbol::Minus: c = '-'; break;
610 case DocSymbol::CenterDot: c = '.'; break;
611 case DocSymbol::Partial: symbol = "partial"; break;
612 case DocSymbol::Nabla: symbol = "nabla"; break;
613 case DocSymbol::SquareRoot: symbol = "sqrt"; break;
614 case DocSymbol::Perpendicular: symbol = "perp"; break;
615 case DocSymbol::Sum: symbol = "sum"; break;
616 case DocSymbol::Integral: symbol = "int"; break;
617 case DocSymbol::Product: symbol = "prod"; break;
618 case DocSymbol::Similar: c = '~'; break;
619 case DocSymbol::Approx: symbol = "approx"; break;
620 case DocSymbol::NotEqual: s = "!="; break;
621 case DocSymbol::Equivalent: symbol = "equiv"; break;
622 case DocSymbol::Proportional: symbol = "propto"; break;
623 case DocSymbol::LessEqual: s = "<="; break;
624 case DocSymbol::GreaterEqual: s = ">="; break;
625 case DocSymbol::LeftArrow: s = "<-"; break;
626 case DocSymbol::RightArrow: s = "->"; break;
627 case DocSymbol::SetIn: symbol = "in"; break;
628 case DocSymbol::SetNotIn: symbol = "notin"; break;
629 case DocSymbol::LeftCeil: symbol = "lceil"; break;
630 case DocSymbol::RightCeil: symbol = "rceil"; break;
631 case DocSymbol::LeftFloor: symbol = "lfloor"; break;
632 case DocSymbol::RightFloor: symbol = "rfloor"; break;
633 case DocSymbol::Unknown: err("error: unknown symbol found\n");
646 else if (symbol != 0)
650 m_output.addFieldQuotedString("symbol", symbol);
653 else if (accent != 0)
658 .addFieldQuotedString("accent", accent)
659 .addFieldQuotedChar("letter", sy->letter());
664 void PerlModDocVisitor::visit(DocURL *u)
667 m_output.addFieldQuotedString("content", u->url());
671 void PerlModDocVisitor::visit(DocLineBreak *) { singleItem("linebreak"); }
672 void PerlModDocVisitor::visit(DocHorRuler *) { singleItem("hruler"); }
674 void PerlModDocVisitor::visit(DocStyleChange *s)
676 const char *style = 0;
679 case DocStyleChange::Bold: style = "bold"; break;
680 case DocStyleChange::Italic: style = "italic"; break;
681 case DocStyleChange::Code: style = "code"; break;
682 case DocStyleChange::Subscript: style = "subscript"; break;
683 case DocStyleChange::Superscript: style = "superscript"; break;
684 case DocStyleChange::Center: style = "center"; break;
685 case DocStyleChange::Small: style = "small"; break;
686 case DocStyleChange::Preformatted: style = "preformatted"; break;
687 case DocStyleChange::Div: style = "div"; break;
688 case DocStyleChange::Span: style = "span"; break;
692 m_output.addFieldQuotedString("style", style)
693 .addFieldBoolean("enable", s->enable());
697 void PerlModDocVisitor::visit(DocVerbatim *s)
699 const char *type = 0;
702 case DocVerbatim::Code:
704 m_output.add("<programlisting>");
705 parseCode(m_ci,s->context(),s->text(),FALSE,0);
706 m_output.add("</programlisting>");
709 case DocVerbatim::Verbatim: type = "preformatted"; break;
710 case DocVerbatim::HtmlOnly: type = "htmlonly"; break;
711 case DocVerbatim::RtfOnly: type = "rtfonly"; break;
712 case DocVerbatim::ManOnly: type = "manonly"; break;
713 case DocVerbatim::LatexOnly: type = "latexonly"; break;
714 case DocVerbatim::XmlOnly: type = "xmlonly"; break;
715 case DocVerbatim::Dot: type = "dot"; break;
716 case DocVerbatim::Msc: type = "msc"; break;
719 m_output.addFieldQuotedString("content", s->text());
723 void PerlModDocVisitor::visit(DocAnchor *anc)
725 QCString anchor = anc->file() + "_1" + anc->anchor();
727 m_output.addFieldQuotedString("id", anchor);
731 void PerlModDocVisitor::visit(DocInclude *inc)
733 const char *type = 0;
736 case DocInclude::IncWithLines:
739 m_t << "<div class=\"fragment\"><pre>";
740 QFileInfo cfi( inc->file() );
741 FileDef fd( cfi.dirPath(), cfi.fileName() );
742 parseCode(m_ci,inc->context(),inc->text().latin1(),inc->isExample(),inc->exampleFile(), &fd);
743 m_t << "</pre></div>";
748 case DocInclude::Include:
750 m_output.add("<programlisting>");
751 parseCode(m_ci,inc->context(),inc->text(),FALSE,0);
752 m_output.add("</programlisting>");
755 case DocInclude::DontInclude: return;
756 case DocInclude::HtmlInclude: type = "htmlonly"; break;
757 case DocInclude::VerbInclude: type = "preformatted"; break;
758 case DocInclude::Snippet: return;
761 m_output.addFieldQuotedString("content", inc->text());
765 void PerlModDocVisitor::visit(DocIncOperator *)
768 //printf("DocIncOperator: type=%d first=%d, last=%d text=`%s'\n",
769 // op->type(),op->isFirst(),op->isLast(),op->text().data());
772 m_output.add("<programlisting>");
774 if (op->type()!=DocIncOperator::Skip)
776 parseCode(m_ci,op->context(),op->text(),FALSE,0);
780 m_output.add("</programlisting>");
789 void PerlModDocVisitor::visit(DocFormula *f)
794 m_output.addFieldQuotedString("id", id).addFieldQuotedString("content", f->text());
798 void PerlModDocVisitor::visit(DocIndexEntry *)
801 m_output.add("<indexentry>"
803 m_output.addQuoted(ie->entry());
804 m_output.add("</primaryie>"
805 "<secondaryie></secondaryie>"
810 void PerlModDocVisitor::visit(DocSimpleSectSep *)
814 void PerlModDocVisitor::visit(DocCite *cite)
817 m_output.addFieldQuotedString("text", cite->text());
822 //--------------------------------------
823 // visitor functions for compound nodes
824 //--------------------------------------
826 void PerlModDocVisitor::visitPre(DocAutoList *l)
829 m_output.addFieldQuotedString("style", l->isEnumList() ? "ordered" : "itemized");
830 openSubBlock("content");
833 void PerlModDocVisitor::visitPost(DocAutoList *)
839 void PerlModDocVisitor::visitPre(DocAutoListItem *)
844 void PerlModDocVisitor::visitPost(DocAutoListItem *)
849 void PerlModDocVisitor::visitPre(DocPara *)
851 if (m_textblockstart)
852 m_textblockstart = false;
854 singleItem("parbreak");
857 openSubBlock("content");
861 void PerlModDocVisitor::visitPost(DocPara *)
869 void PerlModDocVisitor::visitPre(DocRoot *)
873 void PerlModDocVisitor::visitPost(DocRoot *)
877 void PerlModDocVisitor::visitPre(DocSimpleSect *s)
879 const char *type = 0;
882 case DocSimpleSect::See: type = "see"; break;
883 case DocSimpleSect::Return: type = "return"; break;
884 case DocSimpleSect::Author: type = "author"; break;
885 case DocSimpleSect::Authors: type = "authors"; break;
886 case DocSimpleSect::Version: type = "version"; break;
887 case DocSimpleSect::Since: type = "since"; break;
888 case DocSimpleSect::Date: type = "date"; break;
889 case DocSimpleSect::Note: type = "note"; break;
890 case DocSimpleSect::Warning: type = "warning"; break;
891 case DocSimpleSect::Pre: type = "pre"; break;
892 case DocSimpleSect::Post: type = "post"; break;
893 case DocSimpleSect::Copyright: type = "copyright"; break;
894 case DocSimpleSect::Invar: type = "invariant"; break;
895 case DocSimpleSect::Remark: type = "remark"; break;
896 case DocSimpleSect::Attention: type = "attention"; break;
897 case DocSimpleSect::User: type = "par"; break;
898 case DocSimpleSect::Rcs: type = "rcs"; break;
899 case DocSimpleSect::Unknown:
900 err("error: unknown simple section found\n");
909 void PerlModDocVisitor::visitPost(DocSimpleSect *)
913 m_output.closeHash();
916 void PerlModDocVisitor::visitPre(DocTitle *)
919 openSubBlock("content");
922 void PerlModDocVisitor::visitPost(DocTitle *)
928 void PerlModDocVisitor::visitPre(DocSimpleList *)
931 m_output.addFieldQuotedString("style", "itemized");
932 openSubBlock("content");
935 void PerlModDocVisitor::visitPost(DocSimpleList *)
941 void PerlModDocVisitor::visitPre(DocSimpleListItem *) { openSubBlock(); }
942 void PerlModDocVisitor::visitPost(DocSimpleListItem *) { closeSubBlock(); }
944 void PerlModDocVisitor::visitPre(DocSection *s)
946 QCString sect = QCString().sprintf("sect%d",s->level());
948 openSubBlock("content");
951 void PerlModDocVisitor::visitPost(DocSection *)
957 void PerlModDocVisitor::visitPre(DocHtmlList *l)
960 m_output.addFieldQuotedString("style", (l->type() == DocHtmlList::Ordered) ? "ordered" : "itemized");
961 openSubBlock("content");
964 void PerlModDocVisitor::visitPost(DocHtmlList *)
970 void PerlModDocVisitor::visitPre(DocHtmlListItem *) { openSubBlock(); }
971 void PerlModDocVisitor::visitPost(DocHtmlListItem *) { closeSubBlock(); }
973 //void PerlModDocVisitor::visitPre(DocHtmlPre *)
975 // openItem("preformatted");
976 // openSubBlock("content");
977 // //m_insidePre=TRUE;
980 //void PerlModDocVisitor::visitPost(DocHtmlPre *)
982 // //m_insidePre=FALSE;
987 void PerlModDocVisitor::visitPre(DocHtmlDescList *)
990 m_output.add("<variablelist>\n");
994 void PerlModDocVisitor::visitPost(DocHtmlDescList *)
997 m_output.add("</variablelist>\n");
1001 void PerlModDocVisitor::visitPre(DocHtmlDescTitle *)
1004 m_output.add("<varlistentry><term>");
1008 void PerlModDocVisitor::visitPost(DocHtmlDescTitle *)
1011 m_output.add("</term></varlistentry>\n");
1015 void PerlModDocVisitor::visitPre(DocHtmlDescData *)
1018 m_output.add("<listitem>");
1022 void PerlModDocVisitor::visitPost(DocHtmlDescData *)
1025 m_output.add("</listitem>\n");
1029 void PerlModDocVisitor::visitPre(DocHtmlTable *)
1032 m_output.add("<table rows=\""); m_output.add(t->numRows());
1033 m_output.add("\" cols=\""); m_output.add(t->numCols()); m_output.add("\">");
1037 void PerlModDocVisitor::visitPost(DocHtmlTable *)
1040 m_output.add("</table>\n");
1044 void PerlModDocVisitor::visitPre(DocHtmlRow *)
1047 m_output.add("<row>\n");
1051 void PerlModDocVisitor::visitPost(DocHtmlRow *)
1054 m_output.add("</row>\n");
1058 void PerlModDocVisitor::visitPre(DocHtmlCell *)
1061 if (c->isHeading()) m_output.add("<entry thead=\"yes\">"); else m_output.add("<entry thead=\"no\">");
1065 void PerlModDocVisitor::visitPost(DocHtmlCell *)
1068 m_output.add("</entry>");
1072 void PerlModDocVisitor::visitPre(DocHtmlCaption *)
1075 m_output.add("<caption>");
1079 void PerlModDocVisitor::visitPost(DocHtmlCaption *)
1082 m_output.add("</caption>\n");
1086 void PerlModDocVisitor::visitPre(DocInternal *)
1089 m_output.add("<internal>");
1093 void PerlModDocVisitor::visitPost(DocInternal *)
1096 m_output.add("</internal>");
1100 void PerlModDocVisitor::visitPre(DocHRef *)
1103 m_output.add("<ulink url=\""); m_output.add(href->url()); m_output.add("\">");
1107 void PerlModDocVisitor::visitPost(DocHRef *)
1110 m_output.add("</ulink>");
1114 void PerlModDocVisitor::visitPre(DocHtmlHeader *)
1117 m_output.add("<sect"); m_output.add(header->level()); m_output.add(">");
1121 void PerlModDocVisitor::visitPost(DocHtmlHeader *)
1124 m_output.add("</sect"); m_output.add(header->level()); m_output.add(">\n");
1128 void PerlModDocVisitor::visitPre(DocImage *)
1131 m_output.add("<image type=\"");
1134 case DocImage::Html: m_output.add("html"); break;
1135 case DocImage::Latex: m_output.add("latex"); break;
1136 case DocImage::Rtf: m_output.add("rtf"); break;
1140 QCString baseName=img->name();
1142 if ((i=baseName.findRev('/'))!=-1 || (i=baseName.findRev('\\'))!=-1)
1144 baseName=baseName.right(baseName.length()-i-1);
1146 m_output.add(" name=\""); m_output.add(baseName); m_output.add("\"");
1147 if (!img->width().isEmpty())
1149 m_output.add(" width=\"");
1150 m_output.addQuoted(img->width());
1153 else if (!img->height().isEmpty())
1155 m_output.add(" height=\"");
1156 m_output.addQuoted(img->height());
1163 void PerlModDocVisitor::visitPost(DocImage *)
1166 m_output.add("</image>");
1170 void PerlModDocVisitor::visitPre(DocDotFile *)
1173 m_output.add("<dotfile name=\""); m_output.add(df->file()); m_output.add("\">");
1177 void PerlModDocVisitor::visitPost(DocDotFile *)
1180 m_output.add("</dotfile>");
1183 void PerlModDocVisitor::visitPre(DocMscFile *)
1186 m_output.add("<mscfile name=\""); m_output.add(df->file()); m_output.add("\">");
1190 void PerlModDocVisitor::visitPost(DocMscFile *)
1193 m_output.add("<mscfile>");
1198 void PerlModDocVisitor::visitPre(DocLink *lnk)
1201 addLink(lnk->ref(), lnk->file(), lnk->anchor());
1204 void PerlModDocVisitor::visitPost(DocLink *)
1209 void PerlModDocVisitor::visitPre(DocRef *ref)
1212 if (!ref->hasLinkText())
1213 m_output.addFieldQuotedString("text", ref->targetTitle());
1214 openSubBlock("content");
1217 void PerlModDocVisitor::visitPost(DocRef *)
1223 void PerlModDocVisitor::visitPre(DocSecRefItem *)
1226 m_output.add("<tocitem id=\""); m_output.add(ref->file()); m_output.add("_1"); m_output.add(ref->anchor()); m_output.add("\">");
1230 void PerlModDocVisitor::visitPost(DocSecRefItem *)
1233 m_output.add("</tocitem>");
1237 void PerlModDocVisitor::visitPre(DocSecRefList *)
1240 m_output.add("<toclist>");
1244 void PerlModDocVisitor::visitPost(DocSecRefList *)
1247 m_output.add("</toclist>");
1251 //void PerlModDocVisitor::visitPre(DocLanguage *l)
1253 // openItem("language");
1254 // m_output.addFieldQuotedString("id", l->id());
1257 //void PerlModDocVisitor::visitPost(DocLanguage *)
1262 void PerlModDocVisitor::visitPre(DocParamSect *s)
1265 const char *type = 0;
1268 case DocParamSect::Param: type = "params"; break;
1269 case DocParamSect::RetVal: type = "retvals"; break;
1270 case DocParamSect::Exception: type = "exceptions"; break;
1271 case DocParamSect::TemplateParam: type = "templateparam"; break;
1272 case DocParamSect::Unknown:
1273 err("error: unknown parameter section found\n");
1280 void PerlModDocVisitor::visitPost(DocParamSect *)
1286 void PerlModDocVisitor::visitPre(DocParamList *pl)
1290 .openList("parameters");
1291 //QStrListIterator li(pl->parameters());
1293 QListIterator<DocNode> li(pl->parameters());
1295 for (li.toFirst();(param=li.current());++li)
1298 if (param->kind()==DocNode::Kind_Word)
1300 s = ((DocWord*)param)->word();
1302 else if (param->kind()==DocNode::Kind_LinkedWord)
1304 s = ((DocLinkedWord*)param)->word();
1307 .addFieldQuotedString("name", s)
1310 m_output.closeList()
1314 void PerlModDocVisitor::visitPost(DocParamList *)
1317 m_output.closeList()
1321 void PerlModDocVisitor::visitPre(DocXRefItem *)
1324 m_output.add("<xrefsect id=\"");
1325 m_output.add(x->file()); m_output.add("_1"); m_output.add(x->anchor());
1326 m_output.add("\">");
1327 m_output.add("<xreftitle>");
1328 m_output.addQuoted(x->title());
1329 m_output.add("</xreftitle>");
1330 m_output.add("<xrefdescription>");
1332 openItem("xrefitem");
1333 openSubBlock("content");
1336 void PerlModDocVisitor::visitPost(DocXRefItem *)
1341 m_output.add("</xrefdescription>");
1342 m_output.add("</xrefsect>");
1346 void PerlModDocVisitor::visitPre(DocInternalRef *ref)
1349 addLink(0,ref->file(),ref->anchor());
1350 openSubBlock("content");
1353 void PerlModDocVisitor::visitPost(DocInternalRef *)
1359 void PerlModDocVisitor::visitPre(DocCopy *)
1363 void PerlModDocVisitor::visitPost(DocCopy *)
1367 void PerlModDocVisitor::visitPre(DocText *)
1371 void PerlModDocVisitor::visitPost(DocText *)
1375 void PerlModDocVisitor::visitPre(DocHtmlBlockQuote *)
1377 openItem("blockquote");
1378 openSubBlock("content");
1381 void PerlModDocVisitor::visitPost(DocHtmlBlockQuote *)
1387 static void addTemplateArgumentList(ArgumentList *al,PerlModOutput &output,const char *)
1392 output.openList("template_parameters");
1393 ArgumentListIterator ali(*al);
1395 for (ali.toFirst();(a=ali.current());++ali)
1398 if (!a->type.isEmpty())
1399 output.addFieldQuotedString("type", a->type);
1400 if (!a->name.isEmpty())
1401 output.addFieldQuotedString("declaration_name", a->name)
1402 .addFieldQuotedString("definition_name", a->name);
1403 if (!a->defval.isEmpty())
1404 output.addFieldQuotedString("default", a->defval);
1411 static void addMemberTemplateLists(MemberDef *md,PerlModOutput &output)
1413 ClassDef *cd = md->getClassDef();
1414 const char *cname = cd ? cd->name().data() : 0;
1415 if (md->templateArguments()) // function template prefix
1416 addTemplateArgumentList(md->templateArguments(),output,cname);
1420 static void addTemplateList(ClassDef *cd,PerlModOutput &output)
1422 addTemplateArgumentList(cd->templateArguments(),output,cd->name());
1425 static void addPerlModDocBlock(PerlModOutput &output,
1427 const QCString &fileName,
1431 const QCString &text)
1433 QCString stext = text.stripWhiteSpace();
1434 if (stext.isEmpty())
1435 output.addField(name).add("{}");
1437 DocNode *root = validatingParseDoc(fileName,lineNr,scope,md,stext,FALSE,0);
1438 output.openHash(name);
1439 PerlModDocVisitor *visitor = new PerlModDocVisitor(output);
1440 root->accept(visitor);
1448 static const char *getProtectionName(Protection prot)
1452 case Public: return "public";
1453 case Protected: return "protected";
1454 case Private: return "private";
1455 case Package: return "package";
1460 static const char *getVirtualnessName(Specifier virt)
1464 case Normal: return "non_virtual";
1465 case Virtual: return "virtual";
1466 case Pure: return "pure_virtual";
1471 static QCString pathDoxyfile;
1472 static QCString pathDoxyExec;
1474 void setPerlModDoxyfile(const QCString &qs)
1477 pathDoxyExec = QDir::currentDirPath().utf8();
1480 class PerlModGenerator
1484 PerlModOutput m_output;
1486 QCString pathDoxyStructurePM;
1487 QCString pathDoxyDocsTex;
1488 QCString pathDoxyFormatTex;
1489 QCString pathDoxyLatexTex;
1490 QCString pathDoxyLatexDVI;
1491 QCString pathDoxyLatexPDF;
1492 QCString pathDoxyStructureTex;
1493 QCString pathDoxyDocsPM;
1494 QCString pathDoxyLatexPL;
1495 QCString pathDoxyLatexStructurePL;
1496 QCString pathDoxyRules;
1497 QCString pathMakefile;
1499 inline PerlModGenerator(bool pretty) : m_output(pretty) { }
1501 void generatePerlModForMember(MemberDef *md, Definition *);
1502 void generatePerlModSection(Definition *d, MemberList *ml,
1503 const char *name, const char *header=0);
1504 void addListOfAllMembers(ClassDef *cd);
1505 void generatePerlModForClass(ClassDef *cd);
1506 void generatePerlModForNamespace(NamespaceDef *nd);
1507 void generatePerlModForFile(FileDef *fd);
1508 void generatePerlModForGroup(GroupDef *gd);
1509 void generatePerlModForPage(PageDef *pi);
1511 bool createOutputFile(QFile &f, const char *s);
1512 bool createOutputDir(QDir &perlModDir);
1513 bool generateDoxyLatexTex();
1514 bool generateDoxyFormatTex();
1515 bool generateDoxyStructurePM();
1516 bool generateDoxyLatexPL();
1517 bool generateDoxyLatexStructurePL();
1518 bool generateDoxyRules();
1519 bool generateMakefile();
1520 bool generatePerlModOutput();
1525 void PerlModGenerator::generatePerlModForMember(MemberDef *md,Definition *)
1527 // + declaration/definition arg lists
1529 // + reimplementedBy
1531 // + const/volatile specifiers
1533 // - source definition
1534 // - source references
1535 // - source referenced by
1537 // - template arguments
1538 // (templateArguments(), definitionTemplateParameterLists())
1542 switch (md->memberType())
1544 case MemberDef::Define: memType="define"; break;
1545 case MemberDef::EnumValue: memType="enumvalue"; break;
1546 case MemberDef::Property: memType="property"; break;
1547 case MemberDef::Variable: memType="variable"; break;
1548 case MemberDef::Typedef: memType="typedef"; break;
1549 case MemberDef::Enumeration: memType="enum"; break;
1550 case MemberDef::Function: memType="function"; isFunc=TRUE; break;
1551 case MemberDef::Signal: memType="signal"; isFunc=TRUE; break;
1552 //case MemberDef::Prototype: memType="prototype"; isFunc=TRUE; break;
1553 case MemberDef::Friend: memType="friend"; isFunc=TRUE; break;
1554 case MemberDef::DCOP: memType="dcop"; isFunc=TRUE; break;
1555 case MemberDef::Slot: memType="slot"; isFunc=TRUE; break;
1556 case MemberDef::Event: memType="event"; break;
1560 .addFieldQuotedString("kind", memType)
1561 .addFieldQuotedString("name", md->name())
1562 .addFieldQuotedString("virtualness", getVirtualnessName(md->virtualness()))
1563 .addFieldQuotedString("protection", getProtectionName(md->protection()))
1564 .addFieldBoolean("static", md->isStatic());
1566 addPerlModDocBlock(m_output,"brief",md->getDefFileName(),md->getDefLine(),md->getOuterScope(),md,md->briefDescription());
1567 addPerlModDocBlock(m_output,"detailed",md->getDefFileName(),md->getDefLine(),md->getOuterScope(),md,md->documentation());
1568 if (md->memberType()!=MemberDef::Define &&
1569 md->memberType()!=MemberDef::Enumeration)
1570 m_output.addFieldQuotedString("type", md->typeString());
1572 LockingPtr<ArgumentList> al = md->argumentList();
1573 if (isFunc) //function
1575 m_output.addFieldBoolean("const", al!=0 && al->constSpecifier)
1576 .addFieldBoolean("volatile", al!=0 && al->volatileSpecifier);
1578 m_output.openList("parameters");
1579 LockingPtr<ArgumentList> declAl = md->declArgumentList();
1580 LockingPtr<ArgumentList> defAl = md->argumentList();
1581 if (declAl!=0 && declAl->count()>0)
1583 ArgumentListIterator declAli(*declAl);
1584 ArgumentListIterator defAli(*defAl);
1586 for (declAli.toFirst();(a=declAli.current());++declAli)
1588 Argument *defArg = defAli.current();
1589 m_output.openHash();
1591 if (!a->name.isEmpty())
1592 m_output.addFieldQuotedString("declaration_name", a->name);
1594 if (defArg && !defArg->name.isEmpty() && defArg->name!=a->name)
1595 m_output.addFieldQuotedString("definition_name", defArg->name);
1597 if (!a->type.isEmpty())
1598 m_output.addFieldQuotedString("type", a->type);
1600 if (!a->array.isEmpty())
1601 m_output.addFieldQuotedString("array", a->array);
1603 if (!a->defval.isEmpty())
1604 m_output.addFieldQuotedString("default_value", a->defval);
1606 if (!a->attrib.isEmpty())
1607 m_output.addFieldQuotedString("attributes", a->attrib);
1609 m_output.closeHash();
1610 if (defArg) ++defAli;
1613 m_output.closeList();
1615 else if (md->memberType()==MemberDef::Define &&
1616 md->argsString()!=0) // define
1618 m_output.openList("parameters");
1619 ArgumentListIterator ali(*al);
1621 for (ali.toFirst();(a=ali.current());++ali)
1624 .addFieldQuotedString("name", a->type)
1627 m_output.closeList();
1629 else if (md->argsString()!=0)
1631 m_output.addFieldQuotedString("arguments", md->argsString());
1634 if (!md->initializer().isEmpty())
1635 m_output.addFieldQuotedString("initializer", md->initializer());
1637 if (md->excpString())
1638 m_output.addFieldQuotedString("exceptions", md->excpString());
1640 if (md->memberType()==MemberDef::Enumeration) // enum
1642 LockingPtr<MemberList> enumFields = md->enumFieldList();
1645 m_output.openList("values");
1646 MemberListIterator emli(*enumFields);
1648 for (emli.toFirst();(emd=emli.current());++emli)
1651 .addFieldQuotedString("name", emd->name());
1653 if (!emd->initializer().isEmpty())
1654 m_output.addFieldQuotedString("initializer", emd->initializer());
1656 addPerlModDocBlock(m_output,"brief",emd->getDefFileName(),emd->getDefLine(),emd->getOuterScope(),emd,emd->briefDescription());
1658 addPerlModDocBlock(m_output,"detailed",emd->getDefFileName(),emd->getDefLine(),emd->getOuterScope(),emd,emd->documentation());
1660 m_output.closeHash();
1662 m_output.closeList();
1666 MemberDef *rmd = md->reimplements();
1668 m_output.openHash("reimplements")
1669 .addFieldQuotedString("name", rmd->name())
1672 LockingPtr<MemberList> rbml = md->reimplementedBy();
1675 MemberListIterator mli(*rbml);
1676 m_output.openList("reimplemented_by");
1677 for (mli.toFirst();(rmd=mli.current());++mli)
1679 .addFieldQuotedString("name", rmd->name())
1681 m_output.closeList();
1684 m_output.closeHash();
1687 void PerlModGenerator::generatePerlModSection(Definition *d,
1688 MemberList *ml,const char *name,const char *header)
1690 if (ml==0) return; // empty list
1692 m_output.openHash(name);
1695 m_output.addFieldQuotedString("header", header);
1697 m_output.openList("members");
1698 MemberListIterator mli(*ml);
1700 for (mli.toFirst();(md=mli.current());++mli)
1702 generatePerlModForMember(md,d);
1704 m_output.closeList()
1708 void PerlModGenerator::addListOfAllMembers(ClassDef *cd)
1710 m_output.openList("all_members");
1711 if (cd->memberNameInfoSDict())
1713 MemberNameInfoSDict::Iterator mnii(*cd->memberNameInfoSDict());
1714 MemberNameInfo *mni;
1715 for (mnii.toFirst();(mni=mnii.current());++mnii)
1717 MemberNameInfoIterator mii(*mni);
1719 for (mii.toFirst();(mi=mii.current());++mii)
1721 MemberDef *md=mi->memberDef;
1722 ClassDef *cd=md->getClassDef();
1723 Definition *d=md->getGroupDef();
1727 .addFieldQuotedString("name", md->name())
1728 .addFieldQuotedString("virtualness", getVirtualnessName(md->virtualness()))
1729 .addFieldQuotedString("protection", getProtectionName(mi->prot));
1731 if (!mi->ambiguityResolutionScope.isEmpty())
1732 m_output.addFieldQuotedString("ambiguity_scope", mi->ambiguityResolutionScope);
1734 m_output.addFieldQuotedString("scope", cd->name())
1739 m_output.closeList();
1742 void PerlModGenerator::generatePerlModForClass(ClassDef *cd)
1744 // + brief description
1745 // + detailed description
1746 // + template argument list(s)
1749 // + inheritance diagram
1750 // + list of direct super classes
1751 // + list of direct sub classes
1752 // + list of inner classes
1753 // + collaboration diagram
1754 // + list of all members
1755 // + user defined member sections
1756 // + standard member sections
1757 // + detailed member documentation
1758 // - examples using the class
1760 if (cd->isReference()) return; // skip external references.
1761 if (cd->name().find('@')!=-1) return; // skip anonymous compounds.
1762 if (cd->templateMaster()!=0) return; // skip generated template instances.
1765 .addFieldQuotedString("name", cd->name());
1767 if (cd->baseClasses())
1769 m_output.openList("base");
1770 BaseClassListIterator bcli(*cd->baseClasses());
1772 for (bcli.toFirst();(bcd=bcli.current());++bcli)
1774 .addFieldQuotedString("name", bcd->classDef->displayName())
1775 .addFieldQuotedString("virtualness", getVirtualnessName(bcd->virt))
1776 .addFieldQuotedString("protection", getProtectionName(bcd->prot))
1778 m_output.closeList();
1781 if (cd->subClasses())
1783 m_output.openList("derived");
1784 BaseClassListIterator bcli(*cd->subClasses());
1786 for (bcli.toFirst();(bcd=bcli.current());++bcli)
1788 .addFieldQuotedString("name", bcd->classDef->displayName())
1789 .addFieldQuotedString("virtualness", getVirtualnessName(bcd->virt))
1790 .addFieldQuotedString("protection", getProtectionName(bcd->prot))
1792 m_output.closeList();
1795 ClassSDict *cl = cd->getClassSDict();
1798 m_output.openList("inner");
1799 ClassSDict::Iterator cli(*cl);
1801 for (cli.toFirst();(cd=cli.current());++cli)
1803 .addFieldQuotedString("name", cd->name())
1805 m_output.closeList();
1808 IncludeInfo *ii=cd->includeInfo();
1811 QCString nm = ii->includeName;
1812 if (nm.isEmpty() && ii->fileDef) nm = ii->fileDef->docName();
1815 m_output.openHash("includes");
1817 if (ii->fileDef && !ii->fileDef->isReference()) // TODO: support external references
1818 t << " id=\"" << ii->fileDef->getOutputFileBase() << "\"";
1820 m_output.addFieldBoolean("local", ii->local)
1821 .addFieldQuotedString("name", nm)
1826 addTemplateList(cd,m_output);
1827 addListOfAllMembers(cd);
1828 if (cd->getMemberGroupSDict())
1830 MemberGroupSDict::Iterator mgli(*cd->getMemberGroupSDict());
1832 for (;(mg=mgli.current());++mgli)
1833 generatePerlModSection(cd,mg->members(),"user_defined",mg->header());
1836 generatePerlModSection(cd,cd->getMemberList(MemberList::pubTypes),"public_typedefs");
1837 generatePerlModSection(cd,cd->getMemberList(MemberList::pubMethods),"public_methods");
1838 generatePerlModSection(cd,cd->getMemberList(MemberList::pubAttribs),"public_members");
1839 generatePerlModSection(cd,cd->getMemberList(MemberList::pubSlots),"public_slots");
1840 generatePerlModSection(cd,cd->getMemberList(MemberList::signals),"signals");
1841 generatePerlModSection(cd,cd->getMemberList(MemberList::dcopMethods),"dcop_methods");
1842 generatePerlModSection(cd,cd->getMemberList(MemberList::properties),"properties");
1843 generatePerlModSection(cd,cd->getMemberList(MemberList::pubStaticMethods),"public_static_methods");
1844 generatePerlModSection(cd,cd->getMemberList(MemberList::pubStaticAttribs),"public_static_members");
1845 generatePerlModSection(cd,cd->getMemberList(MemberList::proTypes),"protected_typedefs");
1846 generatePerlModSection(cd,cd->getMemberList(MemberList::proMethods),"protected_methods");
1847 generatePerlModSection(cd,cd->getMemberList(MemberList::proAttribs),"protected_members");
1848 generatePerlModSection(cd,cd->getMemberList(MemberList::proSlots),"protected_slots");
1849 generatePerlModSection(cd,cd->getMemberList(MemberList::proStaticMethods),"protected_static_methods");
1850 generatePerlModSection(cd,cd->getMemberList(MemberList::proStaticAttribs),"protected_static_members");
1851 generatePerlModSection(cd,cd->getMemberList(MemberList::priTypes),"private_typedefs");
1852 generatePerlModSection(cd,cd->getMemberList(MemberList::priMethods),"private_methods");
1853 generatePerlModSection(cd,cd->getMemberList(MemberList::priAttribs),"private_members");
1854 generatePerlModSection(cd,cd->getMemberList(MemberList::priSlots),"private_slots");
1855 generatePerlModSection(cd,cd->getMemberList(MemberList::priStaticMethods),"private_static_methods");
1856 generatePerlModSection(cd,cd->getMemberList(MemberList::priStaticAttribs),"private_static_members");
1857 generatePerlModSection(cd,cd->getMemberList(MemberList::friends),"friend_methods");
1858 generatePerlModSection(cd,cd->getMemberList(MemberList::related),"related_methods");
1860 addPerlModDocBlock(m_output,"brief",cd->getDefFileName(),cd->getDefLine(),cd,0,cd->briefDescription());
1861 addPerlModDocBlock(m_output,"detailed",cd->getDefFileName(),cd->getDefLine(),cd,0,cd->documentation());
1864 DotClassGraph inheritanceGraph(cd,DotClassGraph::Inheritance);
1865 if (!inheritanceGraph.isTrivial())
1867 t << " <inheritancegraph>" << endl;
1868 inheritanceGraph.writePerlMod(t);
1869 t << " </inheritancegraph>" << endl;
1871 DotClassGraph collaborationGraph(cd,DotClassGraph::Implementation);
1872 if (!collaborationGraph.isTrivial())
1874 t << " <collaborationgraph>" << endl;
1875 collaborationGraph.writePerlMod(t);
1876 t << " </collaborationgraph>" << endl;
1878 t << " <location file=\""
1879 << cd->getDefFileName() << "\" line=\""
1880 << cd->getDefLine() << "\"";
1881 if (cd->getStartBodyLine()!=-1)
1883 t << " bodystart=\"" << cd->getStartBodyLine() << "\" bodyend=\""
1884 << cd->getEndBodyLine() << "\"";
1889 m_output.closeHash();
1892 void PerlModGenerator::generatePerlModForNamespace(NamespaceDef *nd)
1894 // + contained class definitions
1895 // + contained namespace definitions
1901 // - files containing (parts of) the namespace definition
1903 if (nd->isReference()) return; // skip external references
1906 .addFieldQuotedString("name", nd->name());
1908 ClassSDict *cl = nd->getClassSDict();
1911 m_output.openList("classes");
1912 ClassSDict::Iterator cli(*cl);
1914 for (cli.toFirst();(cd=cli.current());++cli)
1916 .addFieldQuotedString("name", cd->name())
1918 m_output.closeList();
1921 NamespaceSDict *nl = nd->getNamespaceSDict();
1924 m_output.openList("namespaces");
1925 NamespaceSDict::Iterator nli(*nl);
1927 for (nli.toFirst();(nd=nli.current());++nli)
1929 .addFieldQuotedString("name", nd->name())
1931 m_output.closeList();
1934 if (nd->getMemberGroupSDict())
1936 MemberGroupSDict::Iterator mgli(*nd->getMemberGroupSDict());
1938 for (;(mg=mgli.current());++mgli)
1939 generatePerlModSection(nd,mg->members(),"user-defined",mg->header());
1942 generatePerlModSection(nd,nd->getMemberList(MemberList::decDefineMembers),"defines");
1943 generatePerlModSection(nd,nd->getMemberList(MemberList::decProtoMembers),"prototypes");
1944 generatePerlModSection(nd,nd->getMemberList(MemberList::decTypedefMembers),"typedefs");
1945 generatePerlModSection(nd,nd->getMemberList(MemberList::decEnumMembers),"enums");
1946 generatePerlModSection(nd,nd->getMemberList(MemberList::decFuncMembers),"functions");
1947 generatePerlModSection(nd,nd->getMemberList(MemberList::decVarMembers),"variables");
1949 addPerlModDocBlock(m_output,"brief",nd->getDefFileName(),nd->getDefLine(),0,0,nd->briefDescription());
1950 addPerlModDocBlock(m_output,"detailed",nd->getDefFileName(),nd->getDefLine(),0,0,nd->documentation());
1952 m_output.closeHash();
1955 void PerlModGenerator::generatePerlModForFile(FileDef *fd)
1958 // + includedby files
1960 // - included by graph
1961 // - contained class definitions
1962 // - contained namespace definitions
1969 // - number of lines
1971 if (fd->isReference()) return;
1974 .addFieldQuotedString("name", fd->name());
1977 m_output.openList("includes");
1978 if (fd->includeFileList())
1980 QListIterator<IncludeInfo> ili1(*fd->includeFileList());
1981 for (ili1.toFirst();(inc=ili1.current());++ili1)
1984 .addFieldQuotedString("name", inc->includeName);
1985 if (inc->fileDef && !inc->fileDef->isReference())
1987 m_output.addFieldQuotedString("ref", inc->fileDef->getOutputFileBase());
1989 m_output.closeHash();
1992 m_output.closeList();
1994 m_output.openList("included_by");
1995 if (fd->includedByFileList())
1997 QListIterator<IncludeInfo> ili2(*fd->includedByFileList());
1998 for (ili2.toFirst();(inc=ili2.current());++ili2)
2001 .addFieldQuotedString("name", inc->includeName);
2002 if (inc->fileDef && !inc->fileDef->isReference())
2004 m_output.addFieldQuotedString("ref", inc->fileDef->getOutputFileBase());
2006 m_output.closeHash();
2009 m_output.closeList();
2011 generatePerlModSection(fd,fd->getMemberList(MemberList::decDefineMembers),"defines");
2012 generatePerlModSection(fd,fd->getMemberList(MemberList::decProtoMembers),"prototypes");
2013 generatePerlModSection(fd,fd->getMemberList(MemberList::decTypedefMembers),"typedefs");
2014 generatePerlModSection(fd,fd->getMemberList(MemberList::decEnumMembers),"enums");
2015 generatePerlModSection(fd,fd->getMemberList(MemberList::decFuncMembers),"functions");
2016 generatePerlModSection(fd,fd->getMemberList(MemberList::decVarMembers),"variables");
2018 addPerlModDocBlock(m_output,"brief",fd->getDefFileName(),fd->getDefLine(),0,0,fd->briefDescription());
2019 addPerlModDocBlock(m_output,"detailed",fd->getDefFileName(),fd->getDefLine(),0,0,fd->documentation());
2021 m_output.closeHash();
2024 void PerlModGenerator::generatePerlModForGroup(GroupDef *gd)
2035 // + brief description
2036 // + detailed description
2038 if (gd->isReference()) return; // skip external references
2041 .addFieldQuotedString("name", gd->name())
2042 .addFieldQuotedString("title", gd->groupTitle());
2044 FileList *fl = gd->getFiles();
2047 m_output.openList("files");
2048 QListIterator<FileDef> fli(*fl);
2049 FileDef *fd = fl->first();
2050 for (fli.toFirst();(fd=fli.current());++fli)
2052 .addFieldQuotedString("name", fd->name())
2054 m_output.closeList();
2057 ClassSDict *cl = gd->getClasses();
2060 m_output.openList("classes");
2061 ClassSDict::Iterator cli(*cl);
2063 for (cli.toFirst();(cd=cli.current());++cli)
2065 .addFieldQuotedString("name", cd->name())
2067 m_output.closeList();
2070 NamespaceSDict *nl = gd->getNamespaces();
2073 m_output.openList("namespaces");
2074 NamespaceSDict::Iterator nli(*nl);
2076 for (nli.toFirst();(nd=nli.current());++nli)
2078 .addFieldQuotedString("name", nd->name())
2080 m_output.closeList();
2083 PageSDict *pl = gd->getPages();
2086 m_output.openList("pages");
2087 PageSDict::Iterator pli(*pl);
2089 for (pli.toFirst();(pd=pli.current());++pli)
2091 .addFieldQuotedString("title", pd->title())
2093 m_output.closeList();
2096 GroupList *gl = gd->getSubGroups();
2099 m_output.openList("groups");
2100 GroupListIterator gli(*gl);
2102 for (gli.toFirst();(sgd=gli.current());++gli)
2104 .addFieldQuotedString("title", sgd->groupTitle())
2106 m_output.closeList();
2109 if (gd->getMemberGroupSDict())
2111 MemberGroupSDict::Iterator mgli(*gd->getMemberGroupSDict());
2113 for (;(mg=mgli.current());++mgli)
2114 generatePerlModSection(gd,mg->members(),"user-defined",mg->header());
2117 generatePerlModSection(gd,gd->getMemberList(MemberList::decDefineMembers),"defines");
2118 generatePerlModSection(gd,gd->getMemberList(MemberList::decProtoMembers),"prototypes");
2119 generatePerlModSection(gd,gd->getMemberList(MemberList::decTypedefMembers),"typedefs");
2120 generatePerlModSection(gd,gd->getMemberList(MemberList::decEnumMembers),"enums");
2121 generatePerlModSection(gd,gd->getMemberList(MemberList::decFuncMembers),"functions");
2122 generatePerlModSection(gd,gd->getMemberList(MemberList::decVarMembers),"variables");
2124 addPerlModDocBlock(m_output,"brief",gd->getDefFileName(),gd->getDefLine(),0,0,gd->briefDescription());
2125 addPerlModDocBlock(m_output,"detailed",gd->getDefFileName(),gd->getDefLine(),0,0,gd->documentation());
2127 m_output.closeHash();
2130 void PerlModGenerator::generatePerlModForPage(PageDef *pd)
2136 if (pd->isReference()) return;
2139 .addFieldQuotedString("name", pd->name());
2141 SectionInfo *si = Doxygen::sectionDict.find(pd->name());
2143 m_output.addFieldQuotedString("title", si->title);
2145 addPerlModDocBlock(m_output,"detailed",pd->docFile(),pd->docLine(),0,0,pd->documentation());
2146 m_output.closeHash();
2149 bool PerlModGenerator::generatePerlModOutput()
2152 if (!createOutputFile(outputFile, pathDoxyDocsPM))
2155 FTextStream outputTextStream(&outputFile);
2156 PerlModOutputStream outputStream(&outputTextStream);
2157 m_output.setPerlModOutputStream(&outputStream);
2158 m_output.add("$doxydocs=").openHash();
2160 m_output.openList("classes");
2161 ClassSDict::Iterator cli(*Doxygen::classSDict);
2163 for (cli.toFirst();(cd=cli.current());++cli)
2164 generatePerlModForClass(cd);
2165 m_output.closeList();
2167 m_output.openList("namespaces");
2168 NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict);
2170 for (nli.toFirst();(nd=nli.current());++nli)
2171 generatePerlModForNamespace(nd);
2172 m_output.closeList();
2174 m_output.openList("files");
2175 FileNameListIterator fnli(*Doxygen::inputNameList);
2177 for (;(fn=fnli.current());++fnli)
2179 FileNameIterator fni(*fn);
2181 for (;(fd=fni.current());++fni)
2182 generatePerlModForFile(fd);
2184 m_output.closeList();
2186 m_output.openList("groups");
2187 GroupSDict::Iterator gli(*Doxygen::groupSDict);
2189 for (;(gd=gli.current());++gli)
2191 generatePerlModForGroup(gd);
2193 m_output.closeList();
2195 m_output.openList("pages");
2196 PageSDict::Iterator pdi(*Doxygen::pageSDict);
2198 for (pdi.toFirst();(pd=pdi.current());++pdi)
2200 generatePerlModForPage(pd);
2202 if (Doxygen::mainPage)
2204 generatePerlModForPage(Doxygen::mainPage);
2206 m_output.closeList();
2208 m_output.closeHash().add(";\n1;\n");
2212 bool PerlModGenerator::createOutputFile(QFile &f, const char *s)
2215 if (!f.open(IO_WriteOnly))
2217 err("Cannot open file %s for writing!\n", s);
2223 bool PerlModGenerator::createOutputDir(QDir &perlModDir)
2225 QCString outputDirectory = Config_getString("OUTPUT_DIRECTORY");
2226 if (outputDirectory.isEmpty())
2228 outputDirectory=QDir::currentDirPath().utf8();
2232 QDir dir(outputDirectory);
2235 dir.setPath(QDir::currentDirPath());
2236 if (!dir.mkdir(outputDirectory))
2238 err("error: tag OUTPUT_DIRECTORY: Output directory `%s' does not "
2239 "exist and cannot be created\n",outputDirectory.data());
2242 else if (!Config_getBool("QUIET"))
2244 err("notice: Output directory `%s' does not exist. "
2245 "I have created it for you.\n", outputDirectory.data());
2247 dir.cd(outputDirectory);
2249 outputDirectory=dir.absPath().utf8();
2252 QDir dir(outputDirectory);
2255 dir.setPath(QDir::currentDirPath());
2256 if (!dir.mkdir(outputDirectory))
2258 err("Cannot create directory %s\n",outputDirectory.data());
2263 perlModDir.setPath(outputDirectory+"/perlmod");
2264 if (!perlModDir.exists() && !perlModDir.mkdir(outputDirectory+"/perlmod"))
2266 err("Could not create perlmod directory in %s\n",outputDirectory.data());
2272 bool PerlModGenerator::generateDoxyStructurePM()
2275 if (!createOutputFile(doxyModelPM, pathDoxyStructurePM))
2278 FTextStream doxyModelPMStream(&doxyModelPM);
2279 doxyModelPMStream <<
2280 "sub memberlist($) {\n"
2281 " my $prefix = $_[0];\n"
2283 "\t[ \"hash\", $prefix . \"s\",\n"
2286 "\t [ \"list\", $prefix . \"List\",\n"
2287 "\t\t[ \"hash\", $prefix,\n"
2289 "\t\t kind => [ \"string\", $prefix . \"Kind\" ],\n"
2290 "\t\t name => [ \"string\", $prefix . \"Name\" ],\n"
2291 "\t\t static => [ \"string\", $prefix . \"Static\" ],\n"
2292 "\t\t virtualness => [ \"string\", $prefix . \"Virtualness\" ],\n"
2293 "\t\t protection => [ \"string\", $prefix . \"Protection\" ],\n"
2294 "\t\t type => [ \"string\", $prefix . \"Type\" ],\n"
2295 "\t\t parameters =>\n"
2296 "\t\t [ \"list\", $prefix . \"Params\",\n"
2297 "\t\t\t[ \"hash\", $prefix . \"Param\",\n"
2299 "\t\t\t declaration_name => [ \"string\", $prefix . \"ParamName\" ],\n"
2300 "\t\t\t type => [ \"string\", $prefix . \"ParamType\" ],\n"
2304 "\t\t detailed =>\n"
2305 "\t\t [ \"hash\", $prefix . \"Detailed\",\n"
2307 "\t\t\t doc => [ \"doc\", $prefix . \"DetailedDoc\" ],\n"
2308 "\t\t\t return => [ \"doc\", $prefix . \"Return\" ],\n"
2309 "\t\t\t see => [ \"doc\", $prefix . \"See\" ],\n"
2310 "\t\t\t params =>\n"
2311 "\t\t\t [ \"list\", $prefix . \"PDBlocks\",\n"
2312 "\t\t\t [ \"hash\", $prefix . \"PDBlock\",\n"
2314 "\t\t\t\t parameters =>\n"
2315 "\t\t\t\t [ \"list\", $prefix . \"PDParams\",\n"
2316 "\t\t\t\t [ \"hash\", $prefix . \"PDParam\",\n"
2318 "\t\t\t\t\t name => [ \"string\", $prefix . \"PDParamName\" ],\n"
2322 "\t\t\t\t doc => [ \"doc\", $prefix . \"PDDoc\" ],\n"
2335 "$doxystructure =\n"
2336 " [ \"hash\", \"Root\",\n"
2339 "\t [ \"list\", \"Files\",\n"
2340 "\t [ \"hash\", \"File\",\n"
2342 "\t\tname => [ \"string\", \"FileName\" ],\n"
2343 "\t\ttypedefs => memberlist(\"FileTypedef\"),\n"
2344 "\t\tvariables => memberlist(\"FileVariable\"),\n"
2345 "\t\tfunctions => memberlist(\"FileFunction\"),\n"
2347 "\t\t [ \"hash\", \"FileDetailed\",\n"
2349 "\t\t doc => [ \"doc\", \"FileDetailedDoc\" ],\n"
2356 "\t [ \"list\", \"Pages\",\n"
2357 "\t [ \"hash\", \"Page\",\n"
2359 "\t\tname => [ \"string\", \"PageName\" ],\n"
2361 "\t\t [ \"hash\", \"PageDetailed\",\n"
2363 "\t\t doc => [ \"doc\", \"PageDetailedDoc\" ],\n"
2370 "\t [ \"list\", \"Classes\",\n"
2371 "\t [ \"hash\", \"Class\",\n"
2373 "\t\tname => [ \"string\", \"ClassName\" ],\n"
2374 "\t\tpublic_typedefs => memberlist(\"ClassPublicTypedef\"),\n"
2375 "\t\tpublic_methods => memberlist(\"ClassPublicMethod\"),\n"
2376 "\t\tpublic_members => memberlist(\"ClassPublicMember\"),\n"
2377 "\t\tprotected_typedefs => memberlist(\"ClassProtectedTypedef\"),\n"
2378 "\t\tprotected_methods => memberlist(\"ClassProtectedMethod\"),\n"
2379 "\t\tprotected_members => memberlist(\"ClassProtectedMember\"),\n"
2380 "\t\tprivate_typedefs => memberlist(\"ClassPrivateTypedef\"),\n"
2381 "\t\tprivate_methods => memberlist(\"ClassPrivateMethod\"),\n"
2382 "\t\tprivate_members => memberlist(\"ClassPrivateMember\"),\n"
2384 "\t\t [ \"hash\", \"ClassDetailed\",\n"
2386 "\t\t doc => [ \"doc\", \"ClassDetailedDoc\" ],\n"
2393 "\t [ \"list\", \"Groups\",\n"
2394 "\t [ \"hash\", \"Group\",\n"
2396 "\t\tname => [ \"string\", \"GroupName\" ],\n"
2397 "\t\ttitle => [ \"string\", \"GroupTitle\" ],\n"
2399 "\t\t [ \"list\", \"Files\",\n"
2400 "\t\t [ \"hash\", \"File\",\n"
2402 "\t\t name => [ \"string\", \"Filename\" ]\n"
2407 "\t\t [ \"list\", \"Classes\",\n"
2408 "\t\t [ \"hash\", \"Class\",\n"
2410 "\t\t name => [ \"string\", \"Classname\" ]\n"
2414 "\t\tnamespaces =>\n"
2415 "\t\t [ \"list\", \"Namespaces\",\n"
2416 "\t\t [ \"hash\", \"Namespace\",\n"
2418 "\t\t name => [ \"string\", \"NamespaceName\" ]\n"
2423 "\t\t [ \"list\", \"Pages\",\n"
2424 "\t\t [ \"hash\", \"Page\","
2426 "\t\t title => [ \"string\", \"PageName\" ]\n"
2431 "\t\t [ \"list\", \"Groups\",\n"
2432 "\t\t [ \"hash\", \"Group\",\n"
2434 "\t\t title => [ \"string\", \"GroupName\" ]\n"
2438 "\t\tfunctions => memberlist(\"GroupFunction\"),\n"
2440 "\t\t [ \"hash\", \"GroupDetailed\",\n"
2442 "\t\t doc => [ \"doc\", \"GroupDetailedDoc\" ],\n"
2456 bool PerlModGenerator::generateDoxyRules()
2459 if (!createOutputFile(doxyRules, pathDoxyRules))
2462 bool perlmodLatex = Config_getBool("PERLMOD_LATEX");
2463 QCString prefix = Config_getString("PERLMOD_MAKEVAR_PREFIX");
2465 FTextStream doxyRulesStream(&doxyRules);
2467 prefix << "DOXY_EXEC_PATH = " << pathDoxyExec << "\n" <<
2468 prefix << "DOXYFILE = " << pathDoxyfile << "\n" <<
2469 prefix << "DOXYDOCS_PM = " << pathDoxyDocsPM << "\n" <<
2470 prefix << "DOXYSTRUCTURE_PM = " << pathDoxyStructurePM << "\n" <<
2471 prefix << "DOXYRULES = " << pathDoxyRules << "\n";
2474 prefix << "DOXYLATEX_PL = " << pathDoxyLatexPL << "\n" <<
2475 prefix << "DOXYLATEXSTRUCTURE_PL = " << pathDoxyLatexStructurePL << "\n" <<
2476 prefix << "DOXYSTRUCTURE_TEX = " << pathDoxyStructureTex << "\n" <<
2477 prefix << "DOXYDOCS_TEX = " << pathDoxyDocsTex << "\n" <<
2478 prefix << "DOXYFORMAT_TEX = " << pathDoxyFormatTex << "\n" <<
2479 prefix << "DOXYLATEX_TEX = " << pathDoxyLatexTex << "\n" <<
2480 prefix << "DOXYLATEX_DVI = " << pathDoxyLatexDVI << "\n" <<
2481 prefix << "DOXYLATEX_PDF = " << pathDoxyLatexPDF << "\n";
2485 ".PHONY: clean-perlmod\n"
2487 "\trm -f $(" << prefix << "DOXYSTRUCTURE_PM) \\\n"
2488 "\t$(" << prefix << "DOXYDOCS_PM)";
2492 "\t$(" << prefix << "DOXYLATEX_PL) \\\n"
2493 "\t$(" << prefix << "DOXYLATEXSTRUCTURE_PL) \\\n"
2494 "\t$(" << prefix << "DOXYDOCS_TEX) \\\n"
2495 "\t$(" << prefix << "DOXYSTRUCTURE_TEX) \\\n"
2496 "\t$(" << prefix << "DOXYFORMAT_TEX) \\\n"
2497 "\t$(" << prefix << "DOXYLATEX_TEX) \\\n"
2498 "\t$(" << prefix << "DOXYLATEX_PDF) \\\n"
2499 "\t$(" << prefix << "DOXYLATEX_DVI) \\\n"
2500 "\t$(addprefix $(" << prefix << "DOXYLATEX_TEX:tex=),out aux log)";
2501 doxyRulesStream << "\n\n";
2504 "$(" << prefix << "DOXYRULES) \\\n"
2505 "$(" << prefix << "DOXYMAKEFILE) \\\n"
2506 "$(" << prefix << "DOXYSTRUCTURE_PM) \\\n"
2507 "$(" << prefix << "DOXYDOCS_PM)";
2511 "$(" << prefix << "DOXYLATEX_PL) \\\n"
2512 "$(" << prefix << "DOXYLATEXSTRUCTURE_PL) \\\n"
2513 "$(" << prefix << "DOXYFORMAT_TEX) \\\n"
2514 "$(" << prefix << "DOXYLATEX_TEX)";
2518 "\t$(" << prefix << "DOXYFILE)\n"
2519 "\tcd $(" << prefix << "DOXY_EXEC_PATH) ; doxygen \"$<\"\n";
2524 "$(" << prefix << "DOXYDOCS_TEX): \\\n"
2525 "$(" << prefix << "DOXYLATEX_PL) \\\n"
2526 "$(" << prefix << "DOXYDOCS_PM)\n"
2527 "\tperl -I\"$(<D)\" \"$<\" >\"$@\"\n"
2529 "$(" << prefix << "DOXYSTRUCTURE_TEX): \\\n"
2530 "$(" << prefix << "DOXYLATEXSTRUCTURE_PL) \\\n"
2531 "$(" << prefix << "DOXYSTRUCTURE_PM)\n"
2532 "\tperl -I\"$(<D)\" \"$<\" >\"$@\"\n"
2534 "$(" << prefix << "DOXYLATEX_PDF) \\\n"
2535 "$(" << prefix << "DOXYLATEX_DVI): \\\n"
2536 "$(" << prefix << "DOXYLATEX_TEX) \\\n"
2537 "$(" << prefix << "DOXYFORMAT_TEX) \\\n"
2538 "$(" << prefix << "DOXYSTRUCTURE_TEX) \\\n"
2539 "$(" << prefix << "DOXYDOCS_TEX)\n"
2541 "$(" << prefix << "DOXYLATEX_PDF): \\\n"
2542 "$(" << prefix << "DOXYLATEX_TEX)\n"
2543 "\tpdflatex -interaction=nonstopmode \"$<\"\n"
2545 "$(" << prefix << "DOXYLATEX_DVI): \\\n"
2546 "$(" << prefix << "DOXYLATEX_TEX)\n"
2547 "\tlatex -interaction=nonstopmode \"$<\"\n";
2553 bool PerlModGenerator::generateMakefile()
2556 if (!createOutputFile(makefile, pathMakefile))
2559 bool perlmodLatex = Config_getBool("PERLMOD_LATEX");
2560 QCString prefix = Config_getString("PERLMOD_MAKEVAR_PREFIX");
2562 FTextStream makefileStream(&makefile);
2564 ".PHONY: default clean" << (perlmodLatex ? " pdf" : "") << "\n"
2565 "default: " << (perlmodLatex ? "pdf" : "clean") << "\n"
2567 "include " << pathDoxyRules << "\n"
2569 "clean: clean-perlmod\n";
2573 "pdf: $(" << prefix << "DOXYLATEX_PDF)\n"
2574 "dvi: $(" << prefix << "DOXYLATEX_DVI)\n";
2580 bool PerlModGenerator::generateDoxyLatexStructurePL()
2582 QFile doxyLatexStructurePL;
2583 if (!createOutputFile(doxyLatexStructurePL, pathDoxyLatexStructurePL))
2586 FTextStream doxyLatexStructurePLStream(&doxyLatexStructurePL);
2587 doxyLatexStructurePLStream <<
2588 "use DoxyStructure;\n"
2590 "sub process($) {\n"
2591 "\tmy $node = $_[0];\n"
2592 "\tmy ($type, $name) = @$node[0, 1];\n"
2594 "\tif ($type eq \"string\") { $command = \"String\" }\n"
2595 "\telsif ($type eq \"doc\") { $command = \"Doc\" }\n"
2596 "\telsif ($type eq \"hash\") {\n"
2597 "\t\t$command = \"Hash\";\n"
2598 "\t\tfor my $subnode (values %{$$node[2]}) {\n"
2599 "\t\t\tprocess($subnode);\n"
2602 "\telsif ($type eq \"list\") {\n"
2603 "\t\t$command = \"List\";\n"
2604 "\t\tprocess($$node[2]);\n"
2606 "\tprint \"\\\\\" . $command . \"Node{\" . $name . \"}%\\n\";\n"
2609 "process($doxystructure);\n";
2614 bool PerlModGenerator::generateDoxyLatexPL()
2617 if (!createOutputFile(doxyLatexPL, pathDoxyLatexPL))
2620 FTextStream doxyLatexPLStream(&doxyLatexPL);
2621 doxyLatexPLStream <<
2622 "use DoxyStructure;\n"
2625 "sub latex_quote($) {\n"
2626 "\tmy $text = $_[0];\n"
2627 "\t$text =~ s/\\\\/\\\\textbackslash /g;\n"
2628 "\t$text =~ s/\\|/\\\\textbar /g;\n"
2629 "\t$text =~ s/</\\\\textless /g;\n"
2630 "\t$text =~ s/>/\\\\textgreater /g;\n"
2631 "\t$text =~ s/~/\\\\textasciitilde /g;\n"
2632 "\t$text =~ s/\\^/\\\\textasciicircum /g;\n"
2633 "\t$text =~ s/[\\$&%#_{}]/\\\\$&/g;\n"
2637 "sub generate_doc($) {\n"
2638 "\tmy $doc = $_[0];\n"
2639 "\tfor my $item (@$doc) {\n"
2640 "\t\tmy $type = $$item{type};\n"
2641 "\t\tif ($type eq \"text\") {\n"
2642 "\t\t\tlatex_quote($$item{content});\n"
2643 "\t\t} elsif ($type eq \"parbreak\") {\n"
2644 "\t\t\tprint \"\\n\\n\";\n"
2645 "\t\t} elsif ($type eq \"style\") {\n"
2646 "\t\t\tmy $style = $$item{style};\n"
2647 "\t\t\tif ($$item{enable} eq \"yes\") {\n"
2648 "\t\t\t\tif ($style eq \"bold\") { print '\\bfseries'; }\n"
2649 "\t\t\t\tif ($style eq \"italic\") { print '\\itshape'; }\n"
2650 "\t\t\t\tif ($style eq \"code\") { print '\\ttfamily'; }\n"
2652 "\t\t\t\tif ($style eq \"bold\") { print '\\mdseries'; }\n"
2653 "\t\t\t\tif ($style eq \"italic\") { print '\\upshape'; }\n"
2654 "\t\t\t\tif ($style eq \"code\") { print '\\rmfamily'; }\n"
2656 "\t\t\tprint '{}';\n"
2657 "\t\t} elsif ($type eq \"symbol\") {\n"
2658 "\t\t\tmy $symbol = $$item{symbol};\n"
2659 "\t\t\tif ($symbol eq \"copyright\") { print '\\copyright'; }\n"
2660 "\t\t\telsif ($symbol eq \"szlig\") { print '\\ss'; }\n"
2661 "\t\t\tprint '{}';\n"
2662 "\t\t} elsif ($type eq \"accent\") {\n"
2663 "\t\t\tmy ($accent) = $$item{accent};\n"
2664 "\t\t\tif ($accent eq \"umlaut\") { print '\\\"'; }\n"
2665 "\t\t\telsif ($accent eq \"acute\") { print '\\\\\\''; }\n"
2666 "\t\t\telsif ($accent eq \"grave\") { print '\\`'; }\n"
2667 "\t\t\telsif ($accent eq \"circ\") { print '\\^'; }\n"
2668 "\t\t\telsif ($accent eq \"tilde\") { print '\\~'; }\n"
2669 "\t\t\telsif ($accent eq \"cedilla\") { print '\\c'; }\n"
2670 "\t\t\telsif ($accent eq \"ring\") { print '\\r'; }\n"
2671 "\t\t\tprint \"{\" . $$item{letter} . \"}\"; \n"
2672 "\t\t} elsif ($type eq \"list\") {\n"
2673 "\t\t\tmy $env = ($$item{style} eq \"ordered\") ? \"enumerate\" : \"itemize\";\n"
2674 "\t\t\tprint \"\\n\\\\begin{\" . $env .\"}\";\n"
2675 "\t\t \tfor my $subitem (@{$$item{content}}) {\n"
2676 "\t\t\t\tprint \"\\n\\\\item \";\n"
2677 "\t\t\t\tgenerate_doc($subitem);\n"
2679 "\t\t\tprint \"\\n\\\\end{\" . $env .\"}\";\n"
2680 "\t\t} elsif ($type eq \"url\") {\n"
2681 "\t\t\tlatex_quote($$item{content});\n"
2686 "sub generate($$) {\n"
2687 "\tmy ($item, $node) = @_;\n"
2688 "\tmy ($type, $name) = @$node[0, 1];\n"
2689 "\tif ($type eq \"string\") {\n"
2690 "\t\tprint \"\\\\\" . $name . \"{\";\n"
2691 "\t\tlatex_quote($item);\n"
2692 "\t\tprint \"}\";\n"
2693 "\t} elsif ($type eq \"doc\") {\n"
2694 "\t\tif (@$item) {\n"
2695 "\t\t\tprint \"\\\\\" . $name . \"{\";\n"
2696 "\t\t\tgenerate_doc($item);\n"
2697 "\t\t\tprint \"}%\\n\";\n"
2699 "#\t\t\tprint \"\\\\\" . $name . \"Empty%\\n\";\n"
2701 "\t} elsif ($type eq \"hash\") {\n"
2702 "\t\tmy ($key, $value);\n"
2703 "\t\twhile (($key, $subnode) = each %{$$node[2]}) {\n"
2704 "\t\t\tmy $subname = $$subnode[1];\n"
2705 "\t\t\tprint \"\\\\Defcs{field\" . $subname . \"}{\";\n"
2706 "\t\t\tif ($$item{$key}) {\n"
2707 "\t\t\t\tgenerate($$item{$key}, $subnode);\n"
2709 "#\t\t\t\t\tprint \"\\\\\" . $subname . \"Empty%\\n\";\n"
2711 "\t\t\tprint \"}%\\n\";\n"
2713 "\t\tprint \"\\\\\" . $name . \"%\\n\";\n"
2714 "\t} elsif ($type eq \"list\") {\n"
2715 "\t\tmy $index = 0;\n"
2716 "\t\tif (@$item) {\n"
2717 "\t\t\tprint \"\\\\\" . $name . \"{%\\n\";\n"
2718 "\t\t\tfor my $subitem (@$item) {\n"
2719 "\t\t\t\tif ($index) {\n"
2720 "\t\t\t\t\tprint \"\\\\\" . $name . \"Sep%\\n\";\n"
2722 "\t\t\t\tgenerate($subitem, $$node[2]);\n"
2723 "\t\t\t\t$index++;\n"
2725 "\t\t\tprint \"}%\\n\";\n"
2727 "#\t\t\tprint \"\\\\\" . $name . \"Empty%\\n\";\n"
2732 "generate($doxydocs, $doxystructure);\n";
2737 bool PerlModGenerator::generateDoxyFormatTex()
2739 QFile doxyFormatTex;
2740 if (!createOutputFile(doxyFormatTex, pathDoxyFormatTex))
2743 FTextStream doxyFormatTexStream(&doxyFormatTex);
2744 doxyFormatTexStream <<
2745 "\\def\\Defcs#1{\\long\\expandafter\\def\\csname#1\\endcsname}\n"
2746 "\\Defcs{Empty}{}\n"
2747 "\\def\\IfEmpty#1{\\expandafter\\ifx\\csname#1\\endcsname\\Empty}\n"
2749 "\\def\\StringNode#1{\\Defcs{#1}##1{##1}}\n"
2750 "\\def\\DocNode#1{\\Defcs{#1}##1{##1}}\n"
2751 "\\def\\ListNode#1{\\Defcs{#1}##1{##1}\\Defcs{#1Sep}{}}\n"
2752 "\\def\\HashNode#1{\\Defcs{#1}{}}\n"
2754 "\\input{" << pathDoxyStructureTex << "}\n"
2757 "\\dimendef\\DimenA=151\\relax\n"
2758 "\\dimendef\\DimenB=152\\relax\n"
2759 "\\countdef\\ZoneDepth=151\\relax\n"
2761 "\\def\\Cs#1{\\csname#1\\endcsname}\n"
2762 "\\def\\Letcs#1{\\expandafter\\let\\csname#1\\endcsname}\n"
2763 "\\def\\Heading#1{\\vskip 4mm\\relax\\textbf{#1}}\n"
2764 "\\def\\See#1{\\begin{flushleft}\\Heading{See also: }#1\\end{flushleft}}\n"
2766 "\\def\\Frame#1{\\vskip 3mm\\relax\\fbox{ \\vbox{\\hsize0.95\\hsize\\vskip 1mm\\relax\n"
2767 "\\raggedright#1\\vskip 0.5mm\\relax} }}\n"
2769 "\\def\\Zone#1#2#3{%\n"
2770 "\\Defcs{Test#1}{#2}%\n"
2771 "\\Defcs{Emit#1}{#3}%\n"
2773 "\\advance\\ZoneDepth1\\relax\n"
2774 "\\Letcs{Mode\\number\\ZoneDepth}0\\relax\n"
2775 "\\Letcs{Present\\number\\ZoneDepth}0\\relax\n"
2777 "\\expandafter\\if\\Cs{Present\\number\\ZoneDepth}1%\n"
2778 "\\advance\\ZoneDepth-1\\relax\n"
2779 "\\Letcs{Present\\number\\ZoneDepth}1\\relax\n"
2780 "\\expandafter\\if\\Cs{Mode\\number\\ZoneDepth}1%\n"
2781 "\\advance\\ZoneDepth1\\relax\n"
2782 "\\Letcs{Mode\\number\\ZoneDepth}1\\relax\n"
2784 "\\advance\\ZoneDepth-1\\relax\\fi\n"
2785 "\\advance\\ZoneDepth1\\relax\\fi\n"
2786 "\\advance\\ZoneDepth-1\\relax}}\n"
2788 "\\def\\Member#1#2{%\n"
2789 "\\Defcs{Test#1}{\\Cs{field#1Detailed}\n"
2790 "\\IfEmpty{field#1DetailedDoc}\\else\\Letcs{Present#1}1\\fi}\n"
2791 "\\Defcs{#1}{\\Letcs{Present#1}0\\relax\n"
2792 "\\Cs{Test#1}\\if1\\Cs{Present#1}\\Letcs{Present\\number\\ZoneDepth}1\\relax\n"
2793 "\\if1\\Cs{Mode\\number\\ZoneDepth}#2\\fi\\fi}}\n"
2795 "\\def\\TypedefMemberList#1#2{%\n"
2796 "\\Defcs{#1DetailedDoc}##1{\\vskip 5.5mm\\relax##1}%\n"
2797 "\\Defcs{#1Name}##1{\\textbf{##1}}%\n"
2798 "\\Defcs{#1See}##1{\\See{##1}}%\n"
2800 "\\Zone{#1s}{\\Cs{field#1List}}{\\subsubsection{#2}\\Cs{field#1List}}%\n"
2801 "\\Member{#1}{\\Frame{typedef \\Cs{field#1Type} \\Cs{field#1Name}}%\n"
2802 "\\Cs{field#1DetailedDoc}\\Cs{field#1See}\\vskip 5mm\\relax}}%\n"
2804 "\\def\\VariableMemberList#1#2{%\n"
2805 "\\Defcs{#1DetailedDoc}##1{\\vskip 5.5mm\\relax##1}%\n"
2806 "\\Defcs{#1Name}##1{\\textbf{##1}}%\n"
2807 "\\Defcs{#1See}##1{\\See{##1}}%\n"
2809 "\\Zone{#1s}{\\Cs{field#1List}}{\\subsubsection{#2}\\Cs{field#1List}}%\n"
2810 "\\Member{#1}{\\Frame{\\Cs{field#1Type}{} \\Cs{field#1Name}}%\n"
2811 "\\Cs{field#1DetailedDoc}\\Cs{field#1See}\\vskip 5mm\\relax}}%\n"
2813 "\\def\\FunctionMemberList#1#2{%\n"
2814 "\\Defcs{#1PDParamName}##1{\\textit{##1}}%\n"
2815 "\\Defcs{#1PDParam}{\\Cs{field#1PDParamName}}%\n"
2816 "\\Defcs{#1PDParamsSep}{, }%\n"
2817 "\\Defcs{#1PDBlocksSep}{\\vskip 2mm\\relax}%\n"
2819 "\\Defcs{#1PDBlocks}##1{%\n"
2820 "\\Heading{Parameters:}\\vskip 1.5mm\\relax\n"
2821 "\\DimenA0pt\\relax\n"
2822 "\\Defcs{#1PDBlock}{\\setbox\\BoxA\\hbox{\\Cs{field#1PDParams}}%\n"
2823 "\\ifdim\\DimenA<\\wd\\BoxA\\DimenA\\wd\\BoxA\\fi}%\n"
2825 "\\advance\\DimenA3mm\\relax\n"
2826 "\\DimenB\\hsize\\advance\\DimenB-\\DimenA\\relax\n"
2827 "\\Defcs{#1PDBlock}{\\hbox to\\hsize{\\vtop{\\hsize\\DimenA\\relax\n"
2828 "\\Cs{field#1PDParams}}\\hfill\n"
2829 "\\vtop{\\hsize\\DimenB\\relax\\Cs{field#1PDDoc}}}}%\n"
2832 "\\Defcs{#1ParamName}##1{\\textit{##1}}\n"
2833 "\\Defcs{#1Param}{\\Cs{field#1ParamType}{} \\Cs{field#1ParamName}}\n"
2834 "\\Defcs{#1ParamsSep}{, }\n"
2836 "\\Defcs{#1Name}##1{\\textbf{##1}}\n"
2837 "\\Defcs{#1See}##1{\\See{##1}}\n"
2838 "\\Defcs{#1Return}##1{\\Heading{Returns: }##1}\n"
2839 "\\Defcs{field#1Title}{\\Frame{\\Cs{field#1Type}{} \\Cs{field#1Name}(\\Cs{field#1Params})}}%\n"
2841 "\\Zone{#1s}{\\Cs{field#1List}}{\\subsubsection{#2}\\Cs{field#1List}}%\n"
2843 "\\Cs{field#1Title}\\vskip 6mm\\relax\\Cs{field#1DetailedDoc}\n"
2844 "\\Cs{field#1Return}\\Cs{field#1PDBlocks}\\Cs{field#1See}\\vskip 5mm\\relax}}\n"
2846 "\\def\\FileDetailed{\\fieldFileDetailedDoc\\par}\n"
2847 "\\def\\ClassDetailed{\\fieldClassDetailedDoc\\par}\n"
2849 "\\def\\FileSubzones{\\fieldFileTypedefs\\fieldFileVariables\\fieldFileFunctions}\n"
2851 "\\def\\ClassSubzones{%\n"
2852 "\\fieldClassPublicTypedefs\\fieldClassPublicMembers\\fieldClassPublicMethods\n"
2853 "\\fieldClassProtectedTypedefs\\fieldClassProtectedMembers\\fieldClassProtectedMethods\n"
2854 "\\fieldClassPrivateTypedefs\\fieldClassPrivateMembers\\fieldClassPrivateMethods}\n"
2856 "\\Member{Page}{\\subsection{\\fieldPageName}\\fieldPageDetailedDoc}\n"
2858 "\\TypedefMemberList{FileTypedef}{Typedefs}\n"
2859 "\\VariableMemberList{FileVariable}{Variables}\n"
2860 "\\FunctionMemberList{FileFunction}{Functions}\n"
2861 "\\Zone{File}{\\FileSubzones}{\\subsection{\\fieldFileName}\\fieldFileDetailed\\FileSubzones}\n"
2863 "\\TypedefMemberList{ClassPublicTypedef}{Public Typedefs}\n"
2864 "\\TypedefMemberList{ClassProtectedTypedef}{Protected Typedefs}\n"
2865 "\\TypedefMemberList{ClassPrivateTypedef}{Private Typedefs}\n"
2866 "\\VariableMemberList{ClassPublicMember}{Public Members}\n"
2867 "\\VariableMemberList{ClassProtectedMember}{Protected Members}\n"
2868 "\\VariableMemberList{ClassPrivateMember}{Private Members}\n"
2869 "\\FunctionMemberList{ClassPublicMethod}{Public Methods}\n"
2870 "\\FunctionMemberList{ClassProtectedMethod}{Protected Methods}\n"
2871 "\\FunctionMemberList{ClassPrivateMethod}{Private Methods}\n"
2872 "\\Zone{Class}{\\ClassSubzones}{\\subsection{\\fieldClassName}\\fieldClassDetailed\\ClassSubzones}\n"
2874 "\\Zone{AllPages}{\\fieldPages}{\\section{Pages}\\fieldPages}\n"
2875 "\\Zone{AllFiles}{\\fieldFiles}{\\section{Files}\\fieldFiles}\n"
2876 "\\Zone{AllClasses}{\\fieldClasses}{\\section{Classes}\\fieldClasses}\n"
2878 "\\newlength{\\oldparskip}\n"
2879 "\\newlength{\\oldparindent}\n"
2880 "\\newlength{\\oldfboxrule}\n"
2882 "\\ZoneDepth0\\relax\n"
2883 "\\Letcs{Mode0}1\\relax\n"
2885 "\\def\\EmitDoxyDocs{%\n"
2886 "\\setlength{\\oldparskip}{\\parskip}\n"
2887 "\\setlength{\\oldparindent}{\\parindent}\n"
2888 "\\setlength{\\oldfboxrule}{\\fboxrule}\n"
2889 "\\setlength{\\parskip}{0cm}\n"
2890 "\\setlength{\\parindent}{0cm}\n"
2891 "\\setlength{\\fboxrule}{1pt}\n"
2892 "\\AllPages\\AllFiles\\AllClasses\n"
2893 "\\setlength{\\parskip}{\\oldparskip}\n"
2894 "\\setlength{\\parindent}{\\oldparindent}\n"
2895 "\\setlength{\\fboxrule}{\\oldfboxrule}}\n";
2900 bool PerlModGenerator::generateDoxyLatexTex()
2903 if (!createOutputFile(doxyLatexTex, pathDoxyLatexTex))
2906 FTextStream doxyLatexTexStream(&doxyLatexTex);
2907 doxyLatexTexStream <<
2908 "\\documentclass[a4paper,12pt]{article}\n"
2909 "\\usepackage[latin1]{inputenc}\n"
2910 "\\usepackage[none]{hyphenat}\n"
2911 "\\usepackage[T1]{fontenc}\n"
2912 "\\usepackage{hyperref}\n"
2913 "\\usepackage{times}\n"
2915 "\\input{doxyformat}\n"
2917 "\\begin{document}\n"
2918 "\\input{" << pathDoxyDocsTex << "}\n"
2921 "\\end{document}\n";
2926 void PerlModGenerator::generate()
2937 if (!createOutputDir(perlModDir))
2940 bool perlmodLatex = Config_getBool("PERLMOD_LATEX");
2942 QCString perlModAbsPath = perlModDir.absPath().utf8();
2943 pathDoxyDocsPM = perlModAbsPath + "/DoxyDocs.pm";
2944 pathDoxyStructurePM = perlModAbsPath + "/DoxyStructure.pm";
2945 pathMakefile = perlModAbsPath + "/Makefile";
2946 pathDoxyRules = perlModAbsPath + "/doxyrules.make";
2949 pathDoxyStructureTex = perlModAbsPath + "/doxystructure.tex";
2950 pathDoxyFormatTex = perlModAbsPath + "/doxyformat.tex";
2951 pathDoxyLatexTex = perlModAbsPath + "/doxylatex.tex";
2952 pathDoxyLatexDVI = perlModAbsPath + "/doxylatex.dvi";
2953 pathDoxyLatexPDF = perlModAbsPath + "/doxylatex.pdf";
2954 pathDoxyDocsTex = perlModAbsPath + "/doxydocs.tex";
2955 pathDoxyLatexPL = perlModAbsPath + "/doxylatex.pl";
2956 pathDoxyLatexStructurePL = perlModAbsPath + "/doxylatex-structure.pl";
2959 if (!(generatePerlModOutput()
2960 && generateDoxyStructurePM()
2961 && generateMakefile()
2962 && generateDoxyRules()))
2966 if (!(generateDoxyLatexStructurePL()
2967 && generateDoxyLatexPL()
2968 && generateDoxyLatexTex()
2969 && generateDoxyFormatTex()))
2974 void generatePerlMod()
2976 PerlModGenerator pmg(Config_getBool("PERLMOD_PRETTY"));
2981 // c-basic-offset: 2
2984 /* This elisp function for XEmacs makes Control-Z transform
2985 the text in the region into a valid C string.
2987 (global-set-key '(control z) (lambda () (interactive)
2989 (if (< (mark) (point)) (exchange-point-and-mark))
2990 (let ((start (point)) (replacers
2991 '(("\\\\" "\\\\\\\\")
2994 ("^.*$" "\"\\&\\\\n\""))))
2996 (while (re-search-forward (caar replacers) (mark) t)
2997 (replace-match (cadar replacers) t))
2999 (setq replacers (cdr replacers)))))))