00001 /****************************************************************************** 00002 * 00003 * 00004 * 00005 * 00006 * Copyright (C) 1997-2008 by Dimitri van Heesch. 00007 * Authors: Dimitri van Heesch, Miguel Lobo. 00008 * 00009 * Permission to use, copy, modify, and distribute this software and its 00010 * documentation under the terms of the GNU General Public License is hereby 00011 * granted. No representations are made about the suitability of this software 00012 * for any purpose. It is provided "as is" without express or implied warranty. 00013 * See the GNU General Public License for more details. 00014 * 00015 * Documents produced by Doxygen are derivative works derived from the 00016 * input used in their production; they are not affected by this license. 00017 * 00018 */ 00019 00020 #include <stdlib.h> 00021 00022 #include "perlmodgen.h" 00023 #include "docparser.h" 00024 #include "message.h" 00025 #include "doxygen.h" 00026 #include "pagedef.h" 00027 00028 #include <qdir.h> 00029 #include <qstack.h> 00030 #include <qdict.h> 00031 #include <qfile.h> 00032 #include <qtextstream.h> 00033 00034 #define PERLOUTPUT_MAX_INDENTATION 40 00035 00036 class PerlModOutputStream 00037 { 00038 public: 00039 00040 QString m_s; 00041 QTextStream *m_t; 00042 00043 PerlModOutputStream(QTextStream *t = 0) : m_t(t) { } 00044 00045 void add(char c); 00046 void add(const char *s); 00047 void add(QCString &s); 00048 void add(QString &s); 00049 void add(int n); 00050 void add(unsigned int n); 00051 }; 00052 00053 void PerlModOutputStream::add(char c) 00054 { 00055 if (m_t != 0) 00056 (*m_t) << c; 00057 else 00058 m_s += c; 00059 } 00060 00061 void PerlModOutputStream::add(const char *s) 00062 { 00063 if (m_t != 0) 00064 (*m_t) << s; 00065 else 00066 m_s += s; 00067 } 00068 00069 void PerlModOutputStream::add(QCString &s) 00070 { 00071 if (m_t != 0) 00072 (*m_t) << s; 00073 else 00074 m_s += s; 00075 } 00076 00077 void PerlModOutputStream::add(QString &s) 00078 { 00079 if (m_t != 0) 00080 (*m_t) << s; 00081 else 00082 m_s += s; 00083 } 00084 00085 void PerlModOutputStream::add(int n) 00086 { 00087 if (m_t != 0) 00088 (*m_t) << n; 00089 else 00090 m_s += n; 00091 } 00092 00093 void PerlModOutputStream::add(unsigned int n) 00094 { 00095 if (m_t != 0) 00096 (*m_t) << n; 00097 else 00098 m_s += n; 00099 } 00100 00101 class PerlModOutput 00102 { 00103 public: 00104 00105 bool m_pretty; 00106 00107 inline PerlModOutput(bool pretty) 00108 : m_pretty(pretty), m_stream(0), m_indentation(false), m_blockstart(true) 00109 { 00110 m_spaces[0] = 0; 00111 } 00112 00113 virtual ~PerlModOutput() { } 00114 00115 inline void setPerlModOutputStream(PerlModOutputStream *os) { m_stream = os; } 00116 00117 inline PerlModOutput &openSave() { iopenSave(); return *this; } 00118 inline PerlModOutput &closeSave(QString &s) { icloseSave(s); return *this; } 00119 00120 inline PerlModOutput &continueBlock() 00121 { 00122 if (m_blockstart) 00123 m_blockstart = false; 00124 else 00125 m_stream->add(','); 00126 indent(); 00127 return *this; 00128 } 00129 00130 inline PerlModOutput &add(char c) { m_stream->add(c); return *this; } 00131 inline PerlModOutput &add(const char *s) { m_stream->add(s); return *this; } 00132 inline PerlModOutput &add(QCString &s) { m_stream->add(s); return *this; } 00133 inline PerlModOutput &add(QString &s) { m_stream->add(s); return *this; } 00134 inline PerlModOutput &add(int n) { m_stream->add(n); return *this; } 00135 inline PerlModOutput &add(unsigned int n) { m_stream->add(n); return *this; } 00136 00137 PerlModOutput &addQuoted(const char *s) { iaddQuoted(s); return *this; } 00138 00139 inline PerlModOutput &indent() 00140 { 00141 if (m_pretty) { 00142 m_stream->add('\n'); 00143 m_stream->add(m_spaces); 00144 } 00145 return *this; 00146 } 00147 00148 inline PerlModOutput &open(char c, const char *s = 0) { iopen(c, s); return *this; } 00149 inline PerlModOutput &close(char c = 0) { iclose(c); return *this; } 00150 00151 inline PerlModOutput &addField(const char *s) { iaddField(s); return *this; } 00152 inline PerlModOutput &addFieldQuotedChar(const char *field, char content) 00153 { 00154 iaddFieldQuotedChar(field, content); return *this; 00155 } 00156 inline PerlModOutput &addFieldQuotedString(const char *field, const char *content) 00157 { 00158 iaddFieldQuotedString(field, content); return *this; 00159 } 00160 inline PerlModOutput &addFieldBoolean(const char *field, bool content) 00161 { 00162 return addFieldQuotedString(field, content ? "yes" : "no"); 00163 } 00164 inline PerlModOutput &openList(const char *s = 0) { open('[', s); return *this; } 00165 inline PerlModOutput &closeList() { close(']'); return *this; } 00166 inline PerlModOutput &openHash(const char *s = 0 ) { open('{', s); return *this; } 00167 inline PerlModOutput &closeHash() { close('}'); return *this; } 00168 00169 protected: 00170 00171 void iopenSave(); 00172 void icloseSave(QString &); 00173 00174 void incIndent(); 00175 void decIndent(); 00176 00177 void iaddQuoted(const char *); 00178 void iaddFieldQuotedChar(const char *, char); 00179 void iaddFieldQuotedString(const char *, const char *); 00180 void iaddField(const char *); 00181 00182 void iopen(char, const char *); 00183 void iclose(char); 00184 00185 private: 00186 00187 PerlModOutputStream *m_stream; 00188 int m_indentation; 00189 bool m_blockstart; 00190 00191 QStack<PerlModOutputStream> m_saved; 00192 char m_spaces[PERLOUTPUT_MAX_INDENTATION * 2 + 2]; 00193 }; 00194 00195 void PerlModOutput::iopenSave() 00196 { 00197 m_saved.push(m_stream); 00198 m_stream = new PerlModOutputStream(); 00199 } 00200 00201 void PerlModOutput::icloseSave(QString &s) 00202 { 00203 s = m_stream->m_s; 00204 delete m_stream; 00205 m_stream = m_saved.pop(); 00206 } 00207 00208 void PerlModOutput::incIndent() 00209 { 00210 if (m_indentation < PERLOUTPUT_MAX_INDENTATION) 00211 { 00212 char *s = &m_spaces[m_indentation * 2]; 00213 *s++ = ' '; *s++ = ' '; *s = 0; 00214 } 00215 m_indentation++; 00216 } 00217 00218 void PerlModOutput::decIndent() 00219 { 00220 m_indentation--; 00221 if (m_indentation < PERLOUTPUT_MAX_INDENTATION) 00222 m_spaces[m_indentation * 2] = 0; 00223 } 00224 00225 void PerlModOutput::iaddQuoted(const char *s) 00226 { 00227 char c; 00228 while ((c = *s++) != 0) { 00229 if ((c == '\'') || (c == '\\')) 00230 m_stream->add('\\'); 00231 m_stream->add(c); 00232 } 00233 } 00234 00235 void PerlModOutput::iaddField(const char *s) 00236 { 00237 continueBlock(); 00238 m_stream->add(s); 00239 m_stream->add(m_pretty ? " => " : "=>"); 00240 } 00241 00242 void PerlModOutput::iaddFieldQuotedChar(const char *field, char content) 00243 { 00244 iaddField(field); 00245 m_stream->add('\''); 00246 if ((content == '\'') || (content == '\\')) 00247 m_stream->add('\\'); 00248 m_stream->add(content); 00249 m_stream->add('\''); 00250 } 00251 00252 void PerlModOutput::iaddFieldQuotedString(const char *field, const char *content) 00253 { 00254 if (content == 0) 00255 return; 00256 iaddField(field); 00257 m_stream->add('\''); 00258 iaddQuoted(content); 00259 m_stream->add('\''); 00260 } 00261 00262 void PerlModOutput::iopen(char c, const char *s) 00263 { 00264 if (s != 0) 00265 iaddField(s); 00266 else 00267 continueBlock(); 00268 m_stream->add(c); 00269 incIndent(); 00270 m_blockstart = true; 00271 } 00272 00273 void PerlModOutput::iclose(char c) 00274 { 00275 decIndent(); 00276 indent(); 00277 if (c != 0) 00278 m_stream->add(c); 00279 m_blockstart = false; 00280 } 00281 00283 class PerlModDocVisitor : public DocVisitor 00284 { 00285 public: 00286 PerlModDocVisitor(PerlModOutput &); 00287 virtual ~PerlModDocVisitor() { } 00288 00289 void finish(); 00290 00291 //-------------------------------------- 00292 // visitor functions for leaf nodes 00293 //-------------------------------------- 00294 00295 void visit(DocWord *); 00296 void visit(DocLinkedWord *); 00297 void visit(DocWhiteSpace *); 00298 void visit(DocSymbol *); 00299 void visit(DocURL *); 00300 void visit(DocLineBreak *); 00301 void visit(DocHorRuler *); 00302 void visit(DocStyleChange *); 00303 void visit(DocVerbatim *); 00304 void visit(DocAnchor *); 00305 void visit(DocInclude *); 00306 void visit(DocIncOperator *); 00307 void visit(DocFormula *); 00308 void visit(DocIndexEntry *); 00309 00310 //-------------------------------------- 00311 // visitor functions for compound nodes 00312 //-------------------------------------- 00313 00314 void visitPre(DocAutoList *); 00315 void visitPost(DocAutoList *); 00316 void visitPre(DocAutoListItem *); 00317 void visitPost(DocAutoListItem *); 00318 void visitPre(DocPara *) ; 00319 void visitPost(DocPara *); 00320 void visitPre(DocRoot *); 00321 void visitPost(DocRoot *); 00322 void visitPre(DocSimpleSect *); 00323 void visitPost(DocSimpleSect *); 00324 void visitPre(DocTitle *); 00325 void visitPost(DocTitle *); 00326 void visitPre(DocSimpleList *); 00327 void visitPost(DocSimpleList *); 00328 void visitPre(DocSimpleListItem *); 00329 void visitPost(DocSimpleListItem *); 00330 void visitPre(DocSection *); 00331 void visitPost(DocSection *); 00332 void visitPre(DocHtmlList *); 00333 void visitPost(DocHtmlList *) ; 00334 void visitPre(DocHtmlListItem *); 00335 void visitPost(DocHtmlListItem *); 00336 //void visitPre(DocHtmlPre *); 00337 //void visitPost(DocHtmlPre *); 00338 void visitPre(DocHtmlDescList *); 00339 void visitPost(DocHtmlDescList *); 00340 void visitPre(DocHtmlDescTitle *); 00341 void visitPost(DocHtmlDescTitle *); 00342 void visitPre(DocHtmlDescData *); 00343 void visitPost(DocHtmlDescData *); 00344 void visitPre(DocHtmlTable *); 00345 void visitPost(DocHtmlTable *); 00346 void visitPre(DocHtmlRow *); 00347 void visitPost(DocHtmlRow *) ; 00348 void visitPre(DocHtmlCell *); 00349 void visitPost(DocHtmlCell *); 00350 void visitPre(DocHtmlCaption *); 00351 void visitPost(DocHtmlCaption *); 00352 void visitPre(DocInternal *); 00353 void visitPost(DocInternal *); 00354 void visitPre(DocHRef *); 00355 void visitPost(DocHRef *); 00356 void visitPre(DocHtmlHeader *); 00357 void visitPost(DocHtmlHeader *); 00358 void visitPre(DocImage *); 00359 void visitPost(DocImage *); 00360 void visitPre(DocDotFile *); 00361 void visitPost(DocDotFile *); 00362 void visitPre(DocLink *); 00363 void visitPost(DocLink *); 00364 void visitPre(DocRef *); 00365 void visitPost(DocRef *); 00366 void visitPre(DocSecRefItem *); 00367 void visitPost(DocSecRefItem *); 00368 void visitPre(DocSecRefList *); 00369 void visitPost(DocSecRefList *); 00370 //void visitPre(DocLanguage *); 00371 //void visitPost(DocLanguage *); 00372 void visitPre(DocParamSect *); 00373 void visitPost(DocParamSect *); 00374 void visitPre(DocParamList *); 00375 void visitPost(DocParamList *); 00376 void visitPre(DocXRefItem *); 00377 void visitPost(DocXRefItem *); 00378 void visitPre(DocInternalRef *); 00379 void visitPost(DocInternalRef *); 00380 void visitPre(DocCopy *); 00381 void visitPost(DocCopy *); 00382 void visitPre(DocText *); 00383 void visitPost(DocText *); 00384 00385 private: 00386 00387 //-------------------------------------- 00388 // helper functions 00389 //-------------------------------------- 00390 00391 void addLink(const QString &ref, const QString &file, 00392 const QString &anchor); 00393 00394 void enterText(); 00395 void leaveText(); 00396 00397 void openItem(const char *); 00398 void closeItem(); 00399 void singleItem(const char *); 00400 void openSubBlock(const char * = 0); 00401 void closeSubBlock(); 00402 void openOther(); 00403 void closeOther(); 00404 00405 //-------------------------------------- 00406 // state variables 00407 //-------------------------------------- 00408 00409 PerlModOutput &m_output; 00410 bool m_textmode; 00411 bool m_textblockstart; 00412 QString m_other; 00413 }; 00414 00415 PerlModDocVisitor::PerlModDocVisitor(PerlModOutput &output) 00416 : DocVisitor(DocVisitor_Other), m_output(output), m_textmode(false) 00417 { 00418 m_output.openList("doc"); 00419 } 00420 00421 void PerlModDocVisitor::finish() 00422 { 00423 leaveText(); 00424 m_output.closeList() 00425 .add(m_other); 00426 } 00427 00428 void PerlModDocVisitor::addLink(const QString &,const QString &file,const QString &anchor) 00429 { 00430 QString link = file; 00431 if (!anchor.isEmpty()) 00432 (link += "_1") += anchor; 00433 m_output.addFieldQuotedString("link", link); 00434 } 00435 00436 void PerlModDocVisitor::openItem(const char *name) 00437 { 00438 leaveText(); 00439 m_output.openHash().addFieldQuotedString("type", name); 00440 } 00441 00442 void PerlModDocVisitor::closeItem() 00443 { 00444 leaveText(); 00445 m_output.closeHash(); 00446 } 00447 00448 void PerlModDocVisitor::enterText() 00449 { 00450 if (m_textmode) 00451 return; 00452 openItem("text"); 00453 m_output.addField("content").add('\''); 00454 m_textmode = true; 00455 } 00456 00457 void PerlModDocVisitor::leaveText() 00458 { 00459 if (!m_textmode) 00460 return; 00461 m_textmode = false; 00462 m_output 00463 .add('\'') 00464 .closeHash(); 00465 } 00466 00467 void PerlModDocVisitor::singleItem(const char *name) 00468 { 00469 openItem(name); 00470 closeItem(); 00471 } 00472 00473 void PerlModDocVisitor::openSubBlock(const char *s) 00474 { 00475 m_output.openList(s); 00476 m_textblockstart = true; 00477 } 00478 00479 void PerlModDocVisitor::closeSubBlock() 00480 { 00481 leaveText(); 00482 m_output.closeList(); 00483 } 00484 00485 void PerlModDocVisitor::openOther() 00486 { 00487 // Using a secondary text stream will corrupt the perl file. Instead of 00488 // printing doc => [ data => [] ], it will print doc => [] data => []. 00489 /* 00490 leaveText(); 00491 m_output.openSave(); 00492 */ 00493 } 00494 00495 void PerlModDocVisitor::closeOther() 00496 { 00497 // Using a secondary text stream will corrupt the perl file. Instead of 00498 // printing doc => [ data => [] ], it will print doc => [] data => []. 00499 /* 00500 QString other; 00501 leaveText(); 00502 m_output.closeSave(other); 00503 m_other += other; 00504 */ 00505 } 00506 00507 void PerlModDocVisitor::visit(DocWord *w) 00508 { 00509 enterText(); 00510 m_output.addQuoted(w->word()); 00511 } 00512 00513 void PerlModDocVisitor::visit(DocLinkedWord *w) 00514 { 00515 openItem("url"); 00516 addLink(w->ref(), w->file(), w->anchor()); 00517 m_output.addFieldQuotedString("content", w->word()); 00518 closeItem(); 00519 } 00520 00521 void PerlModDocVisitor::visit(DocWhiteSpace *) 00522 { 00523 enterText(); 00524 m_output.add(' '); 00525 } 00526 00527 void PerlModDocVisitor::visit(DocSymbol *sy) 00528 { 00529 char c = 0; 00530 const char *s = 0; 00531 const char *accent = 0; 00532 const char *symbol = 0; 00533 switch(sy->symbol()) 00534 { 00535 case DocSymbol::At: c = '@'; break; 00536 case DocSymbol::Less: c = '<'; break; 00537 case DocSymbol::Greater: c = '>'; break; 00538 case DocSymbol::Amp: c = '&'; break; 00539 case DocSymbol::Dollar: c = '$'; break; 00540 case DocSymbol::Hash: c = '#'; break; 00541 case DocSymbol::Percent: c = '%'; break; 00542 case DocSymbol::Quot: c = '"'; break; 00543 case DocSymbol::Lsquo: s = "\\\'"; break; 00544 case DocSymbol::Rsquo: s = "\\\'"; break; 00545 case DocSymbol::Ldquo: c = '"'; break; 00546 case DocSymbol::Rdquo: c = '"'; break; 00547 case DocSymbol::Ndash: c = '-'; break; 00548 case DocSymbol::Mdash: s = "--"; break; 00549 case DocSymbol::Nbsp: c = ' '; break; 00550 case DocSymbol::Uml: accent = "umlaut"; break; 00551 case DocSymbol::Acute: accent = "acute"; break; 00552 case DocSymbol::Grave: accent = "grave"; break; 00553 case DocSymbol::Circ: accent = "circ"; break; 00554 case DocSymbol::Slash: accent = "slash"; break; 00555 case DocSymbol::Tilde: accent = "tilde"; break; 00556 case DocSymbol::Cedil: accent = "cedilla"; break; 00557 case DocSymbol::Ring: accent = "ring"; break; 00558 case DocSymbol::BSlash: s = "\\\\"; break; 00559 case DocSymbol::Copy: symbol = "copyright"; break; 00560 case DocSymbol::Tm: symbol = "trademark"; break; 00561 case DocSymbol::Reg: symbol = "registered"; break; 00562 case DocSymbol::Szlig: symbol = "szlig"; break; 00563 case DocSymbol::Apos: s = "\\\'"; break; 00564 case DocSymbol::Unknown: 00565 err("Error: unknown symbol found\n"); 00566 break; 00567 } 00568 if (c != 0) { 00569 enterText(); 00570 m_output.add(c); 00571 } else if (s != 0) { 00572 enterText(); 00573 m_output.add(s); 00574 } else if (symbol != 0) { 00575 leaveText(); 00576 openItem("symbol"); 00577 m_output.addFieldQuotedString("symbol", symbol); 00578 closeItem(); 00579 } else if (accent != 0) { 00580 leaveText(); 00581 openItem("accent"); 00582 m_output 00583 .addFieldQuotedString("accent", accent) 00584 .addFieldQuotedChar("letter", sy->letter()); 00585 closeItem(); 00586 } 00587 } 00588 00589 void PerlModDocVisitor::visit(DocURL *u) 00590 { 00591 openItem("url"); 00592 m_output.addFieldQuotedString("content", u->url()); 00593 closeItem(); 00594 } 00595 00596 void PerlModDocVisitor::visit(DocLineBreak *) { singleItem("linebreak"); } 00597 void PerlModDocVisitor::visit(DocHorRuler *) { singleItem("hruler"); } 00598 00599 void PerlModDocVisitor::visit(DocStyleChange *s) 00600 { 00601 const char *style = 0; 00602 switch (s->style()) 00603 { 00604 case DocStyleChange::Bold: style = "bold"; break; 00605 case DocStyleChange::Italic: style = "italic"; break; 00606 case DocStyleChange::Code: style = "code"; break; 00607 case DocStyleChange::Subscript: style = "subscript"; break; 00608 case DocStyleChange::Superscript: style = "superscript"; break; 00609 case DocStyleChange::Center: style = "center"; break; 00610 case DocStyleChange::Small: style = "small"; break; 00611 case DocStyleChange::Preformatted: style = "preformatted"; break; 00612 case DocStyleChange::Div: style = "div"; break; 00613 case DocStyleChange::Span: style = "span"; break; 00614 00615 } 00616 openItem("style"); 00617 m_output.addFieldQuotedString("style", style) 00618 .addFieldBoolean("enable", s->enable()); 00619 closeItem(); 00620 } 00621 00622 void PerlModDocVisitor::visit(DocVerbatim *s) 00623 { 00624 const char *type = 0; 00625 switch(s->type()) 00626 { 00627 case DocVerbatim::Code: 00628 #if 0 00629 m_output.add("<programlisting>"); 00630 parseCode(m_ci,s->context(),s->text(),FALSE,0); 00631 m_output.add("</programlisting>"); 00632 #endif 00633 return; 00634 case DocVerbatim::Verbatim: type = "preformatted"; break; 00635 case DocVerbatim::HtmlOnly: type = "htmlonly"; break; 00636 case DocVerbatim::ManOnly: type = "manonly"; break; 00637 case DocVerbatim::LatexOnly: type = "latexonly"; break; 00638 case DocVerbatim::XmlOnly: type = "xmlonly"; break; 00639 case DocVerbatim::Dot: type = "dot"; break; 00640 case DocVerbatim::Msc: type = "msc"; break; 00641 } 00642 openItem(type); 00643 m_output.addFieldQuotedString("content", s->text()); 00644 closeItem(); 00645 } 00646 00647 void PerlModDocVisitor::visit(DocAnchor *anc) 00648 { 00649 QString anchor = anc->file() + "_1" + anc->anchor(); 00650 openItem("anchor"); 00651 m_output.addFieldQuotedString("id", anchor); 00652 closeItem(); 00653 } 00654 00655 void PerlModDocVisitor::visit(DocInclude *inc) 00656 { 00657 const char *type = 0; 00658 switch(inc->type()) 00659 { 00660 case DocInclude::IncWithLines: 00661 #if 0 00662 { 00663 m_t << "<div class=\"fragment\"><pre>"; 00664 QFileInfo cfi( inc->file() ); 00665 FileDef fd( cfi.dirPath(), cfi.fileName() ); 00666 parseCode(m_ci,inc->context(),inc->text().latin1(),inc->isExample(),inc->exampleFile(), &fd); 00667 m_t << "</pre></div>"; 00668 } 00669 break; 00670 #endif 00671 return; 00672 case DocInclude::Include: 00673 #if 0 00674 m_output.add("<programlisting>"); 00675 parseCode(m_ci,inc->context(),inc->text(),FALSE,0); 00676 m_output.add("</programlisting>"); 00677 #endif 00678 return; 00679 case DocInclude::DontInclude: return; 00680 case DocInclude::HtmlInclude: type = "htmlonly"; break; 00681 case DocInclude::VerbInclude: type = "preformatted"; break; 00682 } 00683 openItem(type); 00684 m_output.addFieldQuotedString("content", inc->text()); 00685 closeItem(); 00686 } 00687 00688 void PerlModDocVisitor::visit(DocIncOperator *) 00689 { 00690 #if 0 00691 //printf("DocIncOperator: type=%d first=%d, last=%d text=`%s'\n", 00692 // op->type(),op->isFirst(),op->isLast(),op->text().data()); 00693 if (op->isFirst()) 00694 { 00695 m_output.add("<programlisting>"); 00696 } 00697 if (op->type()!=DocIncOperator::Skip) 00698 { 00699 parseCode(m_ci,op->context(),op->text(),FALSE,0); 00700 } 00701 if (op->isLast()) 00702 { 00703 m_output.add("</programlisting>"); 00704 } 00705 else 00706 { 00707 m_output.add('\n'); 00708 } 00709 #endif 00710 } 00711 00712 void PerlModDocVisitor::visit(DocFormula *f) 00713 { 00714 openItem("formula"); 00715 QString id; 00716 id += f->id(); 00717 m_output.addFieldQuotedString("id", id).addFieldQuotedString("content", f->text()); 00718 closeItem(); 00719 } 00720 00721 void PerlModDocVisitor::visit(DocIndexEntry *) 00722 { 00723 #if 0 00724 m_output.add("<indexentry>" 00725 "<primaryie>"); 00726 m_output.addQuoted(ie->entry()); 00727 m_output.add("</primaryie>" 00728 "<secondaryie></secondaryie>" 00729 "</indexentry>"); 00730 #endif 00731 } 00732 00733 //-------------------------------------- 00734 // visitor functions for compound nodes 00735 //-------------------------------------- 00736 00737 void PerlModDocVisitor::visitPre(DocAutoList *l) 00738 { 00739 openItem("list"); 00740 m_output.addFieldQuotedString("style", l->isEnumList() ? "ordered" : "itemized"); 00741 openSubBlock("content"); 00742 } 00743 00744 void PerlModDocVisitor::visitPost(DocAutoList *) 00745 { 00746 closeSubBlock(); 00747 closeItem(); 00748 } 00749 00750 void PerlModDocVisitor::visitPre(DocAutoListItem *) 00751 { 00752 openSubBlock(); 00753 } 00754 00755 void PerlModDocVisitor::visitPost(DocAutoListItem *) 00756 { 00757 closeSubBlock(); 00758 } 00759 00760 void PerlModDocVisitor::visitPre(DocPara *) 00761 { 00762 if (m_textblockstart) 00763 m_textblockstart = false; 00764 else 00765 singleItem("parbreak"); 00766 /* 00767 openItem("para"); 00768 openSubBlock("content"); 00769 */ 00770 } 00771 00772 void PerlModDocVisitor::visitPost(DocPara *) 00773 { 00774 /* 00775 closeSubBlock(); 00776 closeItem(); 00777 */ 00778 } 00779 00780 void PerlModDocVisitor::visitPre(DocRoot *) 00781 { 00782 } 00783 00784 void PerlModDocVisitor::visitPost(DocRoot *) 00785 { 00786 } 00787 00788 void PerlModDocVisitor::visitPre(DocSimpleSect *s) 00789 { 00790 const char *type = 0; 00791 switch (s->type()) 00792 { 00793 case DocSimpleSect::See: type = "see"; break; 00794 case DocSimpleSect::Return: type = "return"; break; 00795 case DocSimpleSect::Author: type = "author"; break; 00796 case DocSimpleSect::Authors: type = "authors"; break; 00797 case DocSimpleSect::Version: type = "version"; break; 00798 case DocSimpleSect::Since: type = "since"; break; 00799 case DocSimpleSect::Date: type = "date"; break; 00800 case DocSimpleSect::Note: type = "bug"; break; 00801 case DocSimpleSect::Warning: type = "warning"; break; 00802 case DocSimpleSect::Pre: type = "pre"; break; 00803 case DocSimpleSect::Post: type = "post"; break; 00804 case DocSimpleSect::Invar: type = "invariant"; break; 00805 case DocSimpleSect::Remark: type = "remark"; break; 00806 case DocSimpleSect::Attention: type = "attention"; break; 00807 case DocSimpleSect::User: type = "par"; break; 00808 case DocSimpleSect::Rcs: type = "rcs"; break; 00809 case DocSimpleSect::Unknown: 00810 err("Error: unknown simple section found\n"); 00811 break; 00812 } 00813 openOther(); 00814 openSubBlock(type); 00815 } 00816 00817 void PerlModDocVisitor::visitPost(DocSimpleSect *) 00818 { 00819 closeSubBlock(); 00820 closeOther(); 00821 } 00822 00823 void PerlModDocVisitor::visitPre(DocTitle *) 00824 { 00825 openItem("title"); 00826 openSubBlock("content"); 00827 } 00828 00829 void PerlModDocVisitor::visitPost(DocTitle *) 00830 { 00831 closeSubBlock(); 00832 closeItem(); 00833 } 00834 00835 void PerlModDocVisitor::visitPre(DocSimpleList *) 00836 { 00837 openItem("list"); 00838 m_output.addFieldQuotedString("style", "itemized"); 00839 openSubBlock("content"); 00840 } 00841 00842 void PerlModDocVisitor::visitPost(DocSimpleList *) 00843 { 00844 closeSubBlock(); 00845 closeItem(); 00846 } 00847 00848 void PerlModDocVisitor::visitPre(DocSimpleListItem *) { openSubBlock(); } 00849 void PerlModDocVisitor::visitPost(DocSimpleListItem *) { closeSubBlock(); } 00850 00851 void PerlModDocVisitor::visitPre(DocSection *s) 00852 { 00853 QString sect = QString("sect%1").arg(s->level()); 00854 openItem(sect); 00855 openSubBlock("content"); 00856 } 00857 00858 void PerlModDocVisitor::visitPost(DocSection *) 00859 { 00860 closeSubBlock(); 00861 closeItem(); 00862 } 00863 00864 void PerlModDocVisitor::visitPre(DocHtmlList *l) 00865 { 00866 openItem("list"); 00867 m_output.addFieldQuotedString("style", (l->type() == DocHtmlList::Ordered) ? "ordered" : "itemized"); 00868 openSubBlock("content"); 00869 } 00870 00871 void PerlModDocVisitor::visitPost(DocHtmlList *) 00872 { 00873 closeSubBlock(); 00874 closeItem(); 00875 } 00876 00877 void PerlModDocVisitor::visitPre(DocHtmlListItem *) { openSubBlock(); } 00878 void PerlModDocVisitor::visitPost(DocHtmlListItem *) { closeSubBlock(); } 00879 00880 //void PerlModDocVisitor::visitPre(DocHtmlPre *) 00881 //{ 00882 // openItem("preformatted"); 00883 // openSubBlock("content"); 00884 // //m_insidePre=TRUE; 00885 //} 00886 00887 //void PerlModDocVisitor::visitPost(DocHtmlPre *) 00888 //{ 00889 // //m_insidePre=FALSE; 00890 // closeSubBlock(); 00891 // closeItem(); 00892 //} 00893 00894 void PerlModDocVisitor::visitPre(DocHtmlDescList *) 00895 { 00896 #if 0 00897 m_output.add("<variablelist>\n"); 00898 #endif 00899 } 00900 00901 void PerlModDocVisitor::visitPost(DocHtmlDescList *) 00902 { 00903 #if 0 00904 m_output.add("</variablelist>\n"); 00905 #endif 00906 } 00907 00908 void PerlModDocVisitor::visitPre(DocHtmlDescTitle *) 00909 { 00910 #if 0 00911 m_output.add("<varlistentry><term>"); 00912 #endif 00913 } 00914 00915 void PerlModDocVisitor::visitPost(DocHtmlDescTitle *) 00916 { 00917 #if 0 00918 m_output.add("</term></varlistentry>\n"); 00919 #endif 00920 } 00921 00922 void PerlModDocVisitor::visitPre(DocHtmlDescData *) 00923 { 00924 #if 0 00925 m_output.add("<listitem>"); 00926 #endif 00927 } 00928 00929 void PerlModDocVisitor::visitPost(DocHtmlDescData *) 00930 { 00931 #if 0 00932 m_output.add("</listitem>\n"); 00933 #endif 00934 } 00935 00936 void PerlModDocVisitor::visitPre(DocHtmlTable *) 00937 { 00938 #if 0 00939 m_output.add("<table rows=\""); m_output.add(t->numRows()); 00940 m_output.add("\" cols=\""); m_output.add(t->numCols()); m_output.add("\">"); 00941 #endif 00942 } 00943 00944 void PerlModDocVisitor::visitPost(DocHtmlTable *) 00945 { 00946 #if 0 00947 m_output.add("</table>\n"); 00948 #endif 00949 } 00950 00951 void PerlModDocVisitor::visitPre(DocHtmlRow *) 00952 { 00953 #if 0 00954 m_output.add("<row>\n"); 00955 #endif 00956 } 00957 00958 void PerlModDocVisitor::visitPost(DocHtmlRow *) 00959 { 00960 #if 0 00961 m_output.add("</row>\n"); 00962 #endif 00963 } 00964 00965 void PerlModDocVisitor::visitPre(DocHtmlCell *) 00966 { 00967 #if 0 00968 if (c->isHeading()) m_output.add("<entry thead=\"yes\">"); else m_output.add("<entry thead=\"no\">"); 00969 #endif 00970 } 00971 00972 void PerlModDocVisitor::visitPost(DocHtmlCell *) 00973 { 00974 #if 0 00975 m_output.add("</entry>"); 00976 #endif 00977 } 00978 00979 void PerlModDocVisitor::visitPre(DocHtmlCaption *) 00980 { 00981 #if 0 00982 m_output.add("<caption>"); 00983 #endif 00984 } 00985 00986 void PerlModDocVisitor::visitPost(DocHtmlCaption *) 00987 { 00988 #if 0 00989 m_output.add("</caption>\n"); 00990 #endif 00991 } 00992 00993 void PerlModDocVisitor::visitPre(DocInternal *) 00994 { 00995 #if 0 00996 m_output.add("<internal>"); 00997 #endif 00998 } 00999 01000 void PerlModDocVisitor::visitPost(DocInternal *) 01001 { 01002 #if 0 01003 m_output.add("</internal>"); 01004 #endif 01005 } 01006 01007 void PerlModDocVisitor::visitPre(DocHRef *) 01008 { 01009 #if 0 01010 m_output.add("<ulink url=\""); m_output.add(href->url()); m_output.add("\">"); 01011 #endif 01012 } 01013 01014 void PerlModDocVisitor::visitPost(DocHRef *) 01015 { 01016 #if 0 01017 m_output.add("</ulink>"); 01018 #endif 01019 } 01020 01021 void PerlModDocVisitor::visitPre(DocHtmlHeader *) 01022 { 01023 #if 0 01024 m_output.add("<sect"); m_output.add(header->level()); m_output.add(">"); 01025 #endif 01026 } 01027 01028 void PerlModDocVisitor::visitPost(DocHtmlHeader *) 01029 { 01030 #if 0 01031 m_output.add("</sect"); m_output.add(header->level()); m_output.add(">\n"); 01032 #endif 01033 } 01034 01035 void PerlModDocVisitor::visitPre(DocImage *) 01036 { 01037 #if 0 01038 m_output.add("<image type=\""); 01039 switch(img->type()) 01040 { 01041 case DocImage::Html: m_output.add("html"); break; 01042 case DocImage::Latex: m_output.add("latex"); break; 01043 case DocImage::Rtf: m_output.add("rtf"); break; 01044 } 01045 m_output.add("\""); 01046 01047 QCString baseName=img->name(); 01048 int i; 01049 if ((i=baseName.findRev('/'))!=-1 || (i=baseName.findRev('\\'))!=-1) 01050 { 01051 baseName=baseName.right(baseName.length()-i-1); 01052 } 01053 m_output.add(" name=\""); m_output.add(baseName); m_output.add("\""); 01054 if (!img->width().isEmpty()) 01055 { 01056 m_output.add(" width=\""); 01057 m_output.addQuoted(img->width()); 01058 m_output.add("\""); 01059 } 01060 else if (!img->height().isEmpty()) 01061 { 01062 m_output.add(" height=\""); 01063 m_output.addQuoted(img->height()); 01064 m_output.add("\""); 01065 } 01066 m_output.add(">"); 01067 #endif 01068 } 01069 01070 void PerlModDocVisitor::visitPost(DocImage *) 01071 { 01072 #if 0 01073 m_output.add("</image>"); 01074 #endif 01075 } 01076 01077 void PerlModDocVisitor::visitPre(DocDotFile *) 01078 { 01079 #if 0 01080 m_output.add("<dotfile name=\""); m_output.add(df->file()); m_output.add("\">"); 01081 #endif 01082 } 01083 01084 void PerlModDocVisitor::visitPost(DocDotFile *) 01085 { 01086 #if 0 01087 m_output.add("</dotfile>"); 01088 #endif 01089 } 01090 01091 void PerlModDocVisitor::visitPre(DocLink *lnk) 01092 { 01093 openItem("link"); 01094 addLink(lnk->ref(), lnk->file(), lnk->anchor()); 01095 } 01096 01097 void PerlModDocVisitor::visitPost(DocLink *) 01098 { 01099 closeItem(); 01100 } 01101 01102 void PerlModDocVisitor::visitPre(DocRef *ref) 01103 { 01104 openItem("ref"); 01105 if (!ref->hasLinkText()) 01106 m_output.addFieldQuotedString("text", ref->targetTitle()); 01107 openSubBlock("content"); 01108 } 01109 01110 void PerlModDocVisitor::visitPost(DocRef *) 01111 { 01112 closeSubBlock(); 01113 closeItem(); 01114 } 01115 01116 void PerlModDocVisitor::visitPre(DocSecRefItem *) 01117 { 01118 #if 0 01119 m_output.add("<tocitem id=\""); m_output.add(ref->file()); m_output.add("_1"); m_output.add(ref->anchor()); m_output.add("\">"); 01120 #endif 01121 } 01122 01123 void PerlModDocVisitor::visitPost(DocSecRefItem *) 01124 { 01125 #if 0 01126 m_output.add("</tocitem>"); 01127 #endif 01128 } 01129 01130 void PerlModDocVisitor::visitPre(DocSecRefList *) 01131 { 01132 #if 0 01133 m_output.add("<toclist>"); 01134 #endif 01135 } 01136 01137 void PerlModDocVisitor::visitPost(DocSecRefList *) 01138 { 01139 #if 0 01140 m_output.add("</toclist>"); 01141 #endif 01142 } 01143 01144 //void PerlModDocVisitor::visitPre(DocLanguage *l) 01145 //{ 01146 // openItem("language"); 01147 // m_output.addFieldQuotedString("id", l->id()); 01148 //} 01149 // 01150 //void PerlModDocVisitor::visitPost(DocLanguage *) 01151 //{ 01152 // closeItem(); 01153 //} 01154 01155 void PerlModDocVisitor::visitPre(DocParamSect *s) 01156 { 01157 leaveText(); 01158 const char *type = 0; 01159 switch(s->type()) 01160 { 01161 case DocParamSect::Param: type = "params"; break; 01162 case DocParamSect::RetVal: type = "retvals"; break; 01163 case DocParamSect::Exception: type = "exceptions"; break; 01164 case DocParamSect::TemplateParam: type = "templateparam"; break; 01165 case DocParamSect::Unknown: 01166 err("Error: unknown parameter section found\n"); 01167 break; 01168 } 01169 openOther(); 01170 openSubBlock(type); 01171 } 01172 01173 void PerlModDocVisitor::visitPost(DocParamSect *) 01174 { 01175 closeSubBlock(); 01176 closeOther(); 01177 } 01178 01179 void PerlModDocVisitor::visitPre(DocParamList *pl) 01180 { 01181 leaveText(); 01182 m_output.openHash() 01183 .openList("parameters"); 01184 //QStrListIterator li(pl->parameters()); 01185 //const char *s; 01186 QListIterator<DocNode> li(pl->parameters()); 01187 DocNode *param; 01188 for (li.toFirst();(param=li.current());++li) 01189 { 01190 QCString s; 01191 if (param->kind()==DocNode::Kind_Word) 01192 { 01193 s = ((DocWord*)param)->word(); 01194 } 01195 else if (param->kind()==DocNode::Kind_LinkedWord) 01196 { 01197 s = ((DocLinkedWord*)param)->word(); 01198 } 01199 m_output.openHash() 01200 .addFieldQuotedString("name", s) 01201 .closeHash(); 01202 } 01203 m_output.closeList() 01204 .openList("doc"); 01205 } 01206 01207 void PerlModDocVisitor::visitPost(DocParamList *) 01208 { 01209 leaveText(); 01210 m_output.closeList() 01211 .closeHash(); 01212 } 01213 01214 void PerlModDocVisitor::visitPre(DocXRefItem *) 01215 { 01216 #if 0 01217 m_output.add("<xrefsect id=\""); 01218 m_output.add(x->file()); m_output.add("_1"); m_output.add(x->anchor()); 01219 m_output.add("\">"); 01220 m_output.add("<xreftitle>"); 01221 m_output.addQuoted(x->title()); 01222 m_output.add("</xreftitle>"); 01223 m_output.add("<xrefdescription>"); 01224 #endif 01225 openItem("xrefitem"); 01226 openSubBlock("content"); 01227 } 01228 01229 void PerlModDocVisitor::visitPost(DocXRefItem *) 01230 { 01231 closeSubBlock(); 01232 closeItem(); 01233 #if 0 01234 m_output.add("</xrefdescription>"); 01235 m_output.add("</xrefsect>"); 01236 #endif 01237 } 01238 01239 void PerlModDocVisitor::visitPre(DocInternalRef *ref) 01240 { 01241 openItem("ref"); 01242 addLink(0,ref->file(),ref->anchor()); 01243 openSubBlock("content"); 01244 } 01245 01246 void PerlModDocVisitor::visitPost(DocInternalRef *) 01247 { 01248 closeSubBlock(); 01249 closeItem(); 01250 } 01251 01252 void PerlModDocVisitor::visitPre(DocCopy *) 01253 { 01254 } 01255 01256 void PerlModDocVisitor::visitPost(DocCopy *) 01257 { 01258 } 01259 01260 void PerlModDocVisitor::visitPre(DocText *) 01261 { 01262 } 01263 01264 void PerlModDocVisitor::visitPost(DocText *) 01265 { 01266 } 01267 01268 static void addTemplateArgumentList(ArgumentList *al,PerlModOutput &output,const char *) 01269 { 01270 QCString indentStr; 01271 if (!al) 01272 return; 01273 output.openList("template_parameters"); 01274 ArgumentListIterator ali(*al); 01275 Argument *a; 01276 for (ali.toFirst();(a=ali.current());++ali) 01277 { 01278 output.openHash(); 01279 if (!a->type.isEmpty()) 01280 output.addFieldQuotedString("type", a->type); 01281 if (!a->name.isEmpty()) 01282 output.addFieldQuotedString("declaration_name", a->name) 01283 .addFieldQuotedString("definition_name", a->name); 01284 if (!a->defval.isEmpty()) 01285 output.addFieldQuotedString("default", a->defval); 01286 output.closeHash(); 01287 } 01288 output.closeList(); 01289 } 01290 01291 #if 0 01292 static void addMemberTemplateLists(MemberDef *md,PerlModOutput &output) 01293 { 01294 ClassDef *cd = md->getClassDef(); 01295 const char *cname = cd ? cd->name().data() : 0; 01296 if (md->templateArguments()) // function template prefix 01297 addTemplateArgumentList(md->templateArguments(),output,cname); 01298 } 01299 #endif 01300 01301 static void addTemplateList(ClassDef *cd,PerlModOutput &output) 01302 { 01303 addTemplateArgumentList(cd->templateArguments(),output,cd->name()); 01304 } 01305 01306 static void addPerlModDocBlock(PerlModOutput &output, 01307 const char *name, 01308 const QCString &fileName, 01309 int lineNr, 01310 Definition *scope, 01311 MemberDef *md, 01312 const QCString &text) 01313 { 01314 QCString stext = text.stripWhiteSpace(); 01315 if (stext.isEmpty()) 01316 output.addField(name).add("{}"); 01317 else { 01318 DocNode *root = validatingParseDoc(fileName,lineNr,scope,md,stext,FALSE,0); 01319 output.openHash(name); 01320 PerlModDocVisitor *visitor = new PerlModDocVisitor(output); 01321 root->accept(visitor); 01322 visitor->finish(); 01323 output.closeHash(); 01324 delete visitor; 01325 delete root; 01326 } 01327 } 01328 01329 static const char *getProtectionName(Protection prot) 01330 { 01331 switch (prot) 01332 { 01333 case Public: return "public"; 01334 case Protected: return "protected"; 01335 case Private: return "private"; 01336 case Package: return "package"; 01337 } 01338 return 0; 01339 } 01340 01341 static const char *getVirtualnessName(Specifier virt) 01342 { 01343 switch(virt) 01344 { 01345 case Normal: return "non_virtual"; 01346 case Virtual: return "virtual"; 01347 case Pure: return "pure_virtual"; 01348 } 01349 return 0; 01350 } 01351 01352 static QString pathDoxyfile; 01353 static QString pathDoxyExec; 01354 01355 void setPerlModDoxyfile(const QString &qs) 01356 { 01357 pathDoxyfile = qs; 01358 pathDoxyExec = QDir::currentDirPath(); 01359 } 01360 01361 class PerlModGenerator 01362 { 01363 public: 01364 01365 PerlModOutput m_output; 01366 01367 QString pathDoxyStructurePM; 01368 QString pathDoxyDocsTex; 01369 QString pathDoxyFormatTex; 01370 QString pathDoxyLatexTex; 01371 QString pathDoxyLatexDVI; 01372 QString pathDoxyLatexPDF; 01373 QString pathDoxyStructureTex; 01374 QString pathDoxyDocsPM; 01375 QString pathDoxyLatexPL; 01376 QString pathDoxyLatexStructurePL; 01377 QString pathDoxyRules; 01378 QString pathMakefile; 01379 01380 inline PerlModGenerator(bool pretty) : m_output(pretty) { } 01381 01382 void generatePerlModForMember(MemberDef *md, Definition *); 01383 void generatePerlModSection(Definition *d, MemberList *ml, 01384 const char *name, const char *header=0); 01385 void addListOfAllMembers(ClassDef *cd); 01386 void generatePerlModForClass(ClassDef *cd); 01387 void generatePerlModForNamespace(NamespaceDef *nd); 01388 void generatePerlModForFile(FileDef *fd); 01389 void generatePerlModForGroup(GroupDef *gd); 01390 void generatePerlModForPage(PageDef *pi); 01391 01392 bool createOutputFile(QFile &f, const char *s); 01393 bool createOutputDir(QDir &perlModDir); 01394 bool generateDoxyLatexTex(); 01395 bool generateDoxyFormatTex(); 01396 bool generateDoxyStructurePM(); 01397 bool generateDoxyLatexPL(); 01398 bool generateDoxyLatexStructurePL(); 01399 bool generateDoxyRules(); 01400 bool generateMakefile(); 01401 bool generatePerlModOutput(); 01402 01403 void generate(); 01404 }; 01405 01406 void PerlModGenerator::generatePerlModForMember(MemberDef *md,Definition *) 01407 { 01408 // + declaration/definition arg lists 01409 // + reimplements 01410 // + reimplementedBy 01411 // + exceptions 01412 // + const/volatile specifiers 01413 // - examples 01414 // - source definition 01415 // - source references 01416 // - source referenced by 01417 // - body code 01418 // - template arguments 01419 // (templateArguments(), definitionTemplateParameterLists()) 01420 01421 QCString memType; 01422 bool isFunc=FALSE; 01423 switch (md->memberType()) 01424 { 01425 case MemberDef::Define: memType="define"; break; 01426 case MemberDef::EnumValue: memType="enumvalue"; break; 01427 case MemberDef::Property: memType="property"; break; 01428 case MemberDef::Variable: memType="variable"; break; 01429 case MemberDef::Typedef: memType="typedef"; break; 01430 case MemberDef::Enumeration: memType="enum"; break; 01431 case MemberDef::Function: memType="function"; isFunc=TRUE; break; 01432 case MemberDef::Signal: memType="signal"; isFunc=TRUE; break; 01433 case MemberDef::Prototype: memType="prototype"; isFunc=TRUE; break; 01434 case MemberDef::Friend: memType="friend"; isFunc=TRUE; break; 01435 case MemberDef::DCOP: memType="dcop"; isFunc=TRUE; break; 01436 case MemberDef::Slot: memType="slot"; isFunc=TRUE; break; 01437 case MemberDef::Event: memType="event"; break; 01438 } 01439 01440 m_output.openHash() 01441 .addFieldQuotedString("kind", memType) 01442 .addFieldQuotedString("name", md->name()) 01443 .addFieldQuotedString("virtualness", getVirtualnessName(md->virtualness())) 01444 .addFieldQuotedString("protection", getProtectionName(md->protection())) 01445 .addFieldBoolean("static", md->isStatic()); 01446 01447 addPerlModDocBlock(m_output,"brief",md->getDefFileName(),md->getDefLine(),md->getOuterScope(),md,md->briefDescription()); 01448 addPerlModDocBlock(m_output,"detailed",md->getDefFileName(),md->getDefLine(),md->getOuterScope(),md,md->documentation()); 01449 if (md->memberType()!=MemberDef::Define && 01450 md->memberType()!=MemberDef::Enumeration) 01451 m_output.addFieldQuotedString("type", md->typeString()); 01452 01453 LockingPtr<ArgumentList> al = md->argumentList(); 01454 if (isFunc) //function 01455 { 01456 m_output.addFieldBoolean("const", al!=0 && al->constSpecifier) 01457 .addFieldBoolean("volatile", al!=0 && al->volatileSpecifier); 01458 01459 m_output.openList("parameters"); 01460 LockingPtr<ArgumentList> declAl = md->declArgumentList(); 01461 LockingPtr<ArgumentList> defAl = md->argumentList(); 01462 if (declAl!=0 && declAl->count()>0) 01463 { 01464 ArgumentListIterator declAli(*declAl); 01465 ArgumentListIterator defAli(*defAl); 01466 Argument *a; 01467 for (declAli.toFirst();(a=declAli.current());++declAli) 01468 { 01469 Argument *defArg = defAli.current(); 01470 m_output.openHash(); 01471 01472 if (!a->name.isEmpty()) 01473 m_output.addFieldQuotedString("declaration_name", a->name); 01474 01475 if (defArg && !defArg->name.isEmpty() && defArg->name!=a->name) 01476 m_output.addFieldQuotedString("definition_name", defArg->name); 01477 01478 if (!a->type.isEmpty()) 01479 m_output.addFieldQuotedString("type", a->type); 01480 01481 if (!a->array.isEmpty()) 01482 m_output.addFieldQuotedString("array", a->array); 01483 01484 if (!a->defval.isEmpty()) 01485 m_output.addFieldQuotedString("default_value", a->defval); 01486 01487 if (!a->attrib.isEmpty()) 01488 m_output.addFieldQuotedString("attributes", a->attrib); 01489 01490 m_output.closeHash(); 01491 if (defArg) ++defAli; 01492 } 01493 } 01494 m_output.closeList(); 01495 } 01496 else if (md->memberType()==MemberDef::Define && 01497 md->argsString()!=0) // define 01498 { 01499 m_output.openList("parameters"); 01500 ArgumentListIterator ali(*al); 01501 Argument *a; 01502 for (ali.toFirst();(a=ali.current());++ali) 01503 { 01504 m_output.openHash() 01505 .addFieldQuotedString("name", a->type) 01506 .closeHash(); 01507 } 01508 m_output.closeList(); 01509 } 01510 if (!md->initializer().isEmpty()) 01511 m_output.addFieldQuotedString("initializer", md->initializer()); 01512 01513 if (md->excpString()) 01514 m_output.addFieldQuotedString("exceptions", md->excpString()); 01515 01516 if (md->memberType()==MemberDef::Enumeration) // enum 01517 { 01518 LockingPtr<MemberList> enumFields = md->enumFieldList(); 01519 if (enumFields!=0) 01520 { 01521 m_output.openList("values"); 01522 MemberListIterator emli(*enumFields); 01523 MemberDef *emd; 01524 for (emli.toFirst();(emd=emli.current());++emli) 01525 { 01526 m_output.openHash() 01527 .addFieldQuotedString("name", emd->name()); 01528 01529 if (!emd->initializer().isEmpty()) 01530 m_output.addFieldQuotedString("initializer", emd->initializer()); 01531 01532 addPerlModDocBlock(m_output,"brief",emd->getDefFileName(),emd->getDefLine(),emd->getOuterScope(),emd,emd->briefDescription()); 01533 01534 addPerlModDocBlock(m_output,"detailed",emd->getDefFileName(),emd->getDefLine(),emd->getOuterScope(),emd,emd->documentation()); 01535 01536 m_output.closeHash(); 01537 } 01538 m_output.closeList(); 01539 } 01540 } 01541 01542 MemberDef *rmd = md->reimplements(); 01543 if (rmd) 01544 m_output.openHash("reimplements") 01545 .addFieldQuotedString("name", rmd->name()) 01546 .closeHash(); 01547 01548 LockingPtr<MemberList> rbml = md->reimplementedBy(); 01549 if (rbml!=0) 01550 { 01551 MemberListIterator mli(*rbml); 01552 m_output.openList("reimplemented_by"); 01553 for (mli.toFirst();(rmd=mli.current());++mli) 01554 m_output.openHash() 01555 .addFieldQuotedString("name", rmd->name()) 01556 .closeHash(); 01557 m_output.closeList(); 01558 } 01559 01560 m_output.closeHash(); 01561 } 01562 01563 void PerlModGenerator::generatePerlModSection(Definition *d, 01564 MemberList *ml,const char *name,const char *header) 01565 { 01566 if (ml==0) return; // empty list 01567 01568 m_output.openHash(name); 01569 01570 if (header) 01571 m_output.addFieldQuotedString("header", header); 01572 01573 m_output.openList("members"); 01574 MemberListIterator mli(*ml); 01575 MemberDef *md; 01576 for (mli.toFirst();(md=mli.current());++mli) 01577 { 01578 generatePerlModForMember(md,d); 01579 } 01580 m_output.closeList() 01581 .closeHash(); 01582 } 01583 01584 void PerlModGenerator::addListOfAllMembers(ClassDef *cd) 01585 { 01586 m_output.openList("all_members"); 01587 if (cd->memberNameInfoSDict()) 01588 { 01589 MemberNameInfoSDict::Iterator mnii(*cd->memberNameInfoSDict()); 01590 MemberNameInfo *mni; 01591 for (mnii.toFirst();(mni=mnii.current());++mnii) 01592 { 01593 MemberNameInfoIterator mii(*mni); 01594 MemberInfo *mi; 01595 for (mii.toFirst();(mi=mii.current());++mii) 01596 { 01597 MemberDef *md=mi->memberDef; 01598 ClassDef *cd=md->getClassDef(); 01599 Definition *d=md->getGroupDef(); 01600 if (d==0) d = cd; 01601 01602 m_output.openHash() 01603 .addFieldQuotedString("name", md->name()) 01604 .addFieldQuotedString("virtualness", getVirtualnessName(md->virtualness())) 01605 .addFieldQuotedString("protection", getProtectionName(mi->prot)); 01606 01607 if (!mi->ambiguityResolutionScope.isEmpty()) 01608 m_output.addFieldQuotedString("ambiguity_scope", mi->ambiguityResolutionScope); 01609 01610 m_output.addFieldQuotedString("scope", cd->name()) 01611 .closeHash(); 01612 } 01613 } 01614 } 01615 m_output.closeList(); 01616 } 01617 01618 void PerlModGenerator::generatePerlModForClass(ClassDef *cd) 01619 { 01620 // + brief description 01621 // + detailed description 01622 // + template argument list(s) 01623 // - include file 01624 // + member groups 01625 // + inheritance diagram 01626 // + list of direct super classes 01627 // + list of direct sub classes 01628 // + list of inner classes 01629 // + collaboration diagram 01630 // + list of all members 01631 // + user defined member sections 01632 // + standard member sections 01633 // + detailed member documentation 01634 // - examples using the class 01635 01636 if (cd->isReference()) return; // skip external references. 01637 if (cd->name().find('@')!=-1) return; // skip anonymous compounds. 01638 if (cd->templateMaster()!=0) return; // skip generated template instances. 01639 01640 m_output.openHash() 01641 .addFieldQuotedString("name", cd->name()); 01642 01643 if (cd->baseClasses()) 01644 { 01645 m_output.openList("base"); 01646 BaseClassListIterator bcli(*cd->baseClasses()); 01647 BaseClassDef *bcd; 01648 for (bcli.toFirst();(bcd=bcli.current());++bcli) 01649 m_output.openHash() 01650 .addFieldQuotedString("name", bcd->classDef->displayName()) 01651 .addFieldQuotedString("virtualness", getVirtualnessName(bcd->virt)) 01652 .addFieldQuotedString("protection", getProtectionName(bcd->prot)) 01653 .closeHash(); 01654 m_output.closeList(); 01655 } 01656 01657 if (cd->subClasses()) 01658 { 01659 m_output.openList("derived"); 01660 BaseClassListIterator bcli(*cd->subClasses()); 01661 BaseClassDef *bcd; 01662 for (bcli.toFirst();(bcd=bcli.current());++bcli) 01663 m_output.openHash() 01664 .addFieldQuotedString("name", bcd->classDef->displayName()) 01665 .addFieldQuotedString("virtualness", getVirtualnessName(bcd->virt)) 01666 .addFieldQuotedString("protection", getProtectionName(bcd->prot)) 01667 .closeHash(); 01668 m_output.closeList(); 01669 } 01670 01671 ClassSDict *cl = cd->getInnerClasses(); 01672 if (cl) 01673 { 01674 m_output.openList("inner"); 01675 ClassSDict::Iterator cli(*cl); 01676 ClassDef *cd; 01677 for (cli.toFirst();(cd=cli.current());++cli) 01678 m_output.openHash() 01679 .addFieldQuotedString("name", cd->name()) 01680 .closeHash(); 01681 m_output.closeList(); 01682 } 01683 01684 IncludeInfo *ii=cd->includeInfo(); 01685 if (ii) 01686 { 01687 QCString nm = ii->includeName; 01688 if (nm.isEmpty() && ii->fileDef) nm = ii->fileDef->docName(); 01689 if (!nm.isEmpty()) 01690 { 01691 m_output.openHash("includes"); 01692 #if 0 01693 if (ii->fileDef && !ii->fileDef->isReference()) // TODO: support external references 01694 t << " id=\"" << ii->fileDef->getOutputFileBase() << "\""; 01695 #endif 01696 m_output.addFieldBoolean("local", ii->local) 01697 .addFieldQuotedString("name", nm) 01698 .closeHash(); 01699 } 01700 } 01701 01702 addTemplateList(cd,m_output); 01703 addListOfAllMembers(cd); 01704 if (cd->getMemberGroupSDict()) 01705 { 01706 MemberGroupSDict::Iterator mgli(*cd->getMemberGroupSDict()); 01707 MemberGroup *mg; 01708 for (;(mg=mgli.current());++mgli) 01709 generatePerlModSection(cd,mg->members(),"user_defined",mg->header()); 01710 } 01711 01712 generatePerlModSection(cd,cd->getMemberList(MemberList::pubTypes),"public_typedefs"); 01713 generatePerlModSection(cd,cd->getMemberList(MemberList::pubMethods),"public_methods"); 01714 generatePerlModSection(cd,cd->getMemberList(MemberList::pubAttribs),"public_members"); 01715 generatePerlModSection(cd,cd->getMemberList(MemberList::pubSlots),"public_slots"); 01716 generatePerlModSection(cd,cd->getMemberList(MemberList::signals),"signals"); 01717 generatePerlModSection(cd,cd->getMemberList(MemberList::dcopMethods),"dcop_methods"); 01718 generatePerlModSection(cd,cd->getMemberList(MemberList::properties),"properties"); 01719 generatePerlModSection(cd,cd->getMemberList(MemberList::pubStaticMethods),"public_static_methods"); 01720 generatePerlModSection(cd,cd->getMemberList(MemberList::pubStaticAttribs),"public_static_members"); 01721 generatePerlModSection(cd,cd->getMemberList(MemberList::proTypes),"protected_typedefs"); 01722 generatePerlModSection(cd,cd->getMemberList(MemberList::proMethods),"protected_methods"); 01723 generatePerlModSection(cd,cd->getMemberList(MemberList::proAttribs),"protected_members"); 01724 generatePerlModSection(cd,cd->getMemberList(MemberList::proSlots),"protected_slots"); 01725 generatePerlModSection(cd,cd->getMemberList(MemberList::proStaticMethods),"protected_static_methods"); 01726 generatePerlModSection(cd,cd->getMemberList(MemberList::proStaticAttribs),"protected_static_members"); 01727 generatePerlModSection(cd,cd->getMemberList(MemberList::priTypes),"private_typedefs"); 01728 generatePerlModSection(cd,cd->getMemberList(MemberList::priMethods),"private_methods"); 01729 generatePerlModSection(cd,cd->getMemberList(MemberList::priAttribs),"private_members"); 01730 generatePerlModSection(cd,cd->getMemberList(MemberList::priSlots),"private_slots"); 01731 generatePerlModSection(cd,cd->getMemberList(MemberList::priStaticMethods),"private_static_methods"); 01732 generatePerlModSection(cd,cd->getMemberList(MemberList::priStaticAttribs),"private_static_members"); 01733 generatePerlModSection(cd,cd->getMemberList(MemberList::friends),"friend_methods"); 01734 generatePerlModSection(cd,cd->getMemberList(MemberList::related),"related_methods"); 01735 01736 addPerlModDocBlock(m_output,"brief",cd->getDefFileName(),cd->getDefLine(),cd,0,cd->briefDescription()); 01737 addPerlModDocBlock(m_output,"detailed",cd->getDefFileName(),cd->getDefLine(),cd,0,cd->documentation()); 01738 01739 #if 0 01740 DotClassGraph inheritanceGraph(cd,DotClassGraph::Inheritance); 01741 if (!inheritanceGraph.isTrivial()) 01742 { 01743 t << " <inheritancegraph>" << endl; 01744 inheritanceGraph.writePerlMod(t); 01745 t << " </inheritancegraph>" << endl; 01746 } 01747 DotClassGraph collaborationGraph(cd,DotClassGraph::Implementation); 01748 if (!collaborationGraph.isTrivial()) 01749 { 01750 t << " <collaborationgraph>" << endl; 01751 collaborationGraph.writePerlMod(t); 01752 t << " </collaborationgraph>" << endl; 01753 } 01754 t << " <location file=\"" 01755 << cd->getDefFileName() << "\" line=\"" 01756 << cd->getDefLine() << "\""; 01757 if (cd->getStartBodyLine()!=-1) 01758 { 01759 t << " bodystart=\"" << cd->getStartBodyLine() << "\" bodyend=\"" 01760 << cd->getEndBodyLine() << "\""; 01761 } 01762 t << "/>" << endl; 01763 #endif 01764 01765 m_output.closeHash(); 01766 } 01767 01768 void PerlModGenerator::generatePerlModForNamespace(NamespaceDef *nd) 01769 { 01770 // + contained class definitions 01771 // + contained namespace definitions 01772 // + member groups 01773 // + normal members 01774 // + brief desc 01775 // + detailed desc 01776 // + location 01777 // - files containing (parts of) the namespace definition 01778 01779 if (nd->isReference()) return; // skip external references 01780 01781 m_output.openHash() 01782 .addFieldQuotedString("name", nd->name()); 01783 01784 ClassSDict *cl = nd->getClassSDict(); 01785 if (cl) 01786 { 01787 m_output.openList("classes"); 01788 ClassSDict::Iterator cli(*cl); 01789 ClassDef *cd; 01790 for (cli.toFirst();(cd=cli.current());++cli) 01791 m_output.openHash() 01792 .addFieldQuotedString("name", cd->name()) 01793 .closeHash(); 01794 m_output.closeList(); 01795 } 01796 01797 NamespaceSDict *nl = nd->getNamespaceSDict(); 01798 if (nl) 01799 { 01800 m_output.openList("namespaces"); 01801 NamespaceSDict::Iterator nli(*nl); 01802 NamespaceDef *nd; 01803 for (nli.toFirst();(nd=nli.current());++nli) 01804 m_output.openHash() 01805 .addFieldQuotedString("name", nd->name()) 01806 .closeHash(); 01807 m_output.closeList(); 01808 } 01809 01810 if (nd->getMemberGroupSDict()) 01811 { 01812 MemberGroupSDict::Iterator mgli(*nd->getMemberGroupSDict()); 01813 MemberGroup *mg; 01814 for (;(mg=mgli.current());++mgli) 01815 generatePerlModSection(nd,mg->members(),"user-defined",mg->header()); 01816 } 01817 01818 generatePerlModSection(nd,nd->getMemberList(MemberList::decDefineMembers),"defines"); 01819 generatePerlModSection(nd,nd->getMemberList(MemberList::decProtoMembers),"prototypes"); 01820 generatePerlModSection(nd,nd->getMemberList(MemberList::decTypedefMembers),"typedefs"); 01821 generatePerlModSection(nd,nd->getMemberList(MemberList::decEnumMembers),"enums"); 01822 generatePerlModSection(nd,nd->getMemberList(MemberList::decFuncMembers),"functions"); 01823 generatePerlModSection(nd,nd->getMemberList(MemberList::decVarMembers),"variables"); 01824 01825 addPerlModDocBlock(m_output,"brief",nd->getDefFileName(),nd->getDefLine(),0,0,nd->briefDescription()); 01826 addPerlModDocBlock(m_output,"detailed",nd->getDefFileName(),nd->getDefLine(),0,0,nd->documentation()); 01827 01828 m_output.closeHash(); 01829 } 01830 01831 void PerlModGenerator::generatePerlModForFile(FileDef *fd) 01832 { 01833 // + includes files 01834 // + includedby files 01835 // - include graph 01836 // - included by graph 01837 // - contained class definitions 01838 // - contained namespace definitions 01839 // - member groups 01840 // + normal members 01841 // + brief desc 01842 // + detailed desc 01843 // - source code 01844 // - location 01845 // - number of lines 01846 01847 if (fd->isReference()) return; 01848 01849 m_output.openHash() 01850 .addFieldQuotedString("name", fd->name()); 01851 01852 IncludeInfo *inc; 01853 m_output.openList("includes"); 01854 if (fd->includeFileList()) 01855 { 01856 QListIterator<IncludeInfo> ili1(*fd->includeFileList()); 01857 for (ili1.toFirst();(inc=ili1.current());++ili1) 01858 { 01859 m_output.openHash() 01860 .addFieldQuotedString("name", inc->includeName); 01861 if (inc->fileDef && !inc->fileDef->isReference()) 01862 { 01863 m_output.addFieldQuotedString("ref", inc->fileDef->getOutputFileBase()); 01864 } 01865 m_output.closeHash(); 01866 } 01867 } 01868 m_output.closeList(); 01869 01870 m_output.openList("included_by"); 01871 if (fd->includedByFileList()) 01872 { 01873 QListIterator<IncludeInfo> ili2(*fd->includedByFileList()); 01874 for (ili2.toFirst();(inc=ili2.current());++ili2) 01875 { 01876 m_output.openHash() 01877 .addFieldQuotedString("name", inc->includeName); 01878 if (inc->fileDef && !inc->fileDef->isReference()) 01879 { 01880 m_output.addFieldQuotedString("ref", inc->fileDef->getOutputFileBase()); 01881 } 01882 m_output.closeHash(); 01883 } 01884 } 01885 m_output.closeList(); 01886 01887 generatePerlModSection(fd,fd->getMemberList(MemberList::decDefineMembers),"defines"); 01888 generatePerlModSection(fd,fd->getMemberList(MemberList::decProtoMembers),"prototypes"); 01889 generatePerlModSection(fd,fd->getMemberList(MemberList::decTypedefMembers),"typedefs"); 01890 generatePerlModSection(fd,fd->getMemberList(MemberList::decEnumMembers),"enums"); 01891 generatePerlModSection(fd,fd->getMemberList(MemberList::decFuncMembers),"functions"); 01892 generatePerlModSection(fd,fd->getMemberList(MemberList::decVarMembers),"variables"); 01893 01894 addPerlModDocBlock(m_output,"brief",fd->getDefFileName(),fd->getDefLine(),0,0,fd->briefDescription()); 01895 addPerlModDocBlock(m_output,"detailed",fd->getDefFileName(),fd->getDefLine(),0,0,fd->documentation()); 01896 01897 m_output.closeHash(); 01898 } 01899 01900 void PerlModGenerator::generatePerlModForGroup(GroupDef *gd) 01901 { 01902 // + members 01903 // + member groups 01904 // + files 01905 // + classes 01906 // + namespaces 01907 // - packages 01908 // + pages 01909 // + child groups 01910 // - examples 01911 // + brief description 01912 // + detailed description 01913 01914 if (gd->isReference()) return; // skip external references 01915 01916 m_output.openHash() 01917 .addFieldQuotedString("name", gd->name()) 01918 .addFieldQuotedString("title", gd->groupTitle()); 01919 01920 FileList *fl = gd->getFiles(); 01921 if (fl) 01922 { 01923 m_output.openList("files"); 01924 QListIterator<FileDef> fli(*fl); 01925 FileDef *fd = fl->first(); 01926 for (fli.toFirst();(fd=fli.current());++fli) 01927 m_output.openHash() 01928 .addFieldQuotedString("name", fd->name()) 01929 .closeHash(); 01930 m_output.closeList(); 01931 } 01932 01933 ClassSDict *cl = gd->getClasses(); 01934 if (cl) 01935 { 01936 m_output.openList("classes"); 01937 ClassSDict::Iterator cli(*cl); 01938 ClassDef *cd; 01939 for (cli.toFirst();(cd=cli.current());++cli) 01940 m_output.openHash() 01941 .addFieldQuotedString("name", cd->name()) 01942 .closeHash(); 01943 m_output.closeList(); 01944 } 01945 01946 NamespaceSDict *nl = gd->getNamespaces(); 01947 if (nl) 01948 { 01949 m_output.openList("namespaces"); 01950 NamespaceSDict::Iterator nli(*nl); 01951 NamespaceDef *nd; 01952 for (nli.toFirst();(nd=nli.current());++nli) 01953 m_output.openHash() 01954 .addFieldQuotedString("name", nd->name()) 01955 .closeHash(); 01956 m_output.closeList(); 01957 } 01958 01959 PageSDict *pl = gd->getPages(); 01960 if (pl) 01961 { 01962 m_output.openList("pages"); 01963 PageSDict::Iterator pli(*pl); 01964 PageDef *pd; 01965 for (pli.toFirst();(pd=pli.current());++pli) 01966 m_output.openHash() 01967 .addFieldQuotedString("title", pd->title()) 01968 .closeHash(); 01969 m_output.closeList(); 01970 } 01971 01972 GroupList *gl = gd->getSubGroups(); 01973 if (gl) 01974 { 01975 m_output.openList("groups"); 01976 GroupListIterator gli(*gl); 01977 GroupDef *sgd; 01978 for (gli.toFirst();(sgd=gli.current());++gli) 01979 m_output.openHash() 01980 .addFieldQuotedString("title", sgd->groupTitle()) 01981 .closeHash(); 01982 m_output.closeList(); 01983 } 01984 01985 if (gd->getMemberGroupSDict()) 01986 { 01987 MemberGroupSDict::Iterator mgli(*gd->getMemberGroupSDict()); 01988 MemberGroup *mg; 01989 for (;(mg=mgli.current());++mgli) 01990 generatePerlModSection(gd,mg->members(),"user-defined",mg->header()); 01991 } 01992 01993 generatePerlModSection(gd,gd->getMemberList(MemberList::decDefineMembers),"defines"); 01994 generatePerlModSection(gd,gd->getMemberList(MemberList::decProtoMembers),"prototypes"); 01995 generatePerlModSection(gd,gd->getMemberList(MemberList::decTypedefMembers),"typedefs"); 01996 generatePerlModSection(gd,gd->getMemberList(MemberList::decEnumMembers),"enums"); 01997 generatePerlModSection(gd,gd->getMemberList(MemberList::decFuncMembers),"functions"); 01998 generatePerlModSection(gd,gd->getMemberList(MemberList::decVarMembers),"variables"); 01999 02000 addPerlModDocBlock(m_output,"brief",gd->getDefFileName(),gd->getDefLine(),0,0,gd->briefDescription()); 02001 addPerlModDocBlock(m_output,"detailed",gd->getDefFileName(),gd->getDefLine(),0,0,gd->documentation()); 02002 02003 m_output.closeHash(); 02004 } 02005 02006 void PerlModGenerator::generatePerlModForPage(PageDef *pd) 02007 { 02008 // + name 02009 // + title 02010 // + documentation 02011 02012 if (pd->isReference()) return; 02013 02014 m_output.openHash() 02015 .addFieldQuotedString("name", pd->name()); 02016 02017 SectionInfo *si = Doxygen::sectionDict.find(pd->name()); 02018 if (si) 02019 m_output.addFieldQuotedString("title", si->title); 02020 02021 addPerlModDocBlock(m_output,"detailed",pd->docFile(),pd->docLine(),0,0,pd->documentation()); 02022 m_output.closeHash(); 02023 } 02024 02025 bool PerlModGenerator::generatePerlModOutput() 02026 { 02027 QFile outputFile; 02028 if (!createOutputFile(outputFile, pathDoxyDocsPM)) 02029 return false; 02030 02031 QTextStream outputTextStream(&outputFile); 02032 PerlModOutputStream outputStream(&outputTextStream); 02033 m_output.setPerlModOutputStream(&outputStream); 02034 m_output.add("$doxydocs=").openHash(); 02035 02036 m_output.openList("classes"); 02037 ClassSDict::Iterator cli(*Doxygen::classSDict); 02038 ClassDef *cd; 02039 for (cli.toFirst();(cd=cli.current());++cli) 02040 generatePerlModForClass(cd); 02041 m_output.closeList(); 02042 02043 m_output.openList("namespaces"); 02044 NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict); 02045 NamespaceDef *nd; 02046 for (nli.toFirst();(nd=nli.current());++nli) 02047 generatePerlModForNamespace(nd); 02048 m_output.closeList(); 02049 02050 m_output.openList("files"); 02051 FileNameListIterator fnli(*Doxygen::inputNameList); 02052 FileName *fn; 02053 for (;(fn=fnli.current());++fnli) 02054 { 02055 FileNameIterator fni(*fn); 02056 FileDef *fd; 02057 for (;(fd=fni.current());++fni) 02058 generatePerlModForFile(fd); 02059 } 02060 m_output.closeList(); 02061 02062 m_output.openList("groups"); 02063 GroupSDict::Iterator gli(*Doxygen::groupSDict); 02064 GroupDef *gd; 02065 for (;(gd=gli.current());++gli) 02066 { 02067 generatePerlModForGroup(gd); 02068 } 02069 m_output.closeList(); 02070 02071 m_output.openList("pages"); 02072 PageSDict::Iterator pdi(*Doxygen::pageSDict); 02073 PageDef *pd=0; 02074 for (pdi.toFirst();(pd=pdi.current());++pdi) 02075 { 02076 generatePerlModForPage(pd); 02077 } 02078 if (Doxygen::mainPage) 02079 { 02080 generatePerlModForPage(Doxygen::mainPage); 02081 } 02082 m_output.closeList(); 02083 02084 m_output.closeHash().add(";\n1;\n"); 02085 return true; 02086 } 02087 02088 bool PerlModGenerator::createOutputFile(QFile &f, const char *s) 02089 { 02090 f.setName(s); 02091 if (!f.open(IO_WriteOnly)) 02092 { 02093 err("Cannot open file %s for writing!\n", s); 02094 return false; 02095 } 02096 return true; 02097 } 02098 02099 bool PerlModGenerator::createOutputDir(QDir &perlModDir) 02100 { 02101 QCString outputDirectory = Config_getString("OUTPUT_DIRECTORY"); 02102 if (outputDirectory.isEmpty()) 02103 { 02104 outputDirectory=QDir::currentDirPath(); 02105 } 02106 else 02107 { 02108 QDir dir(outputDirectory); 02109 if (!dir.exists()) 02110 { 02111 dir.setPath(QDir::currentDirPath()); 02112 if (!dir.mkdir(outputDirectory)) 02113 { 02114 err("Error: tag OUTPUT_DIRECTORY: Output directory `%s' does not " 02115 "exist and cannot be created\n",outputDirectory.data()); 02116 exit(1); 02117 } 02118 else if (!Config_getBool("QUIET")) 02119 { 02120 err("Notice: Output directory `%s' does not exist. " 02121 "I have created it for you.\n", outputDirectory.data()); 02122 } 02123 dir.cd(outputDirectory); 02124 } 02125 outputDirectory=dir.absPath(); 02126 } 02127 02128 QDir dir(outputDirectory); 02129 if (!dir.exists()) 02130 { 02131 dir.setPath(QDir::currentDirPath()); 02132 if (!dir.mkdir(outputDirectory)) 02133 { 02134 err("Cannot create directory %s\n",outputDirectory.data()); 02135 return false; 02136 } 02137 } 02138 02139 perlModDir.setPath(outputDirectory+"/perlmod"); 02140 if (!perlModDir.exists() && !perlModDir.mkdir(outputDirectory+"/perlmod")) 02141 { 02142 err("Could not create perlmod directory in %s\n",outputDirectory.data()); 02143 return false; 02144 } 02145 return true; 02146 } 02147 02148 bool PerlModGenerator::generateDoxyStructurePM() 02149 { 02150 QFile doxyModelPM; 02151 if (!createOutputFile(doxyModelPM, pathDoxyStructurePM)) 02152 return false; 02153 02154 QTextStream doxyModelPMStream(&doxyModelPM); 02155 doxyModelPMStream << 02156 "sub memberlist($) {\n" 02157 " my $prefix = $_[0];\n" 02158 " return\n" 02159 "\t[ \"hash\", $prefix . \"s\",\n" 02160 "\t {\n" 02161 "\t members =>\n" 02162 "\t [ \"list\", $prefix . \"List\",\n" 02163 "\t\t[ \"hash\", $prefix,\n" 02164 "\t\t {\n" 02165 "\t\t kind => [ \"string\", $prefix . \"Kind\" ],\n" 02166 "\t\t name => [ \"string\", $prefix . \"Name\" ],\n" 02167 "\t\t static => [ \"string\", $prefix . \"Static\" ],\n" 02168 "\t\t virtualness => [ \"string\", $prefix . \"Virtualness\" ],\n" 02169 "\t\t protection => [ \"string\", $prefix . \"Protection\" ],\n" 02170 "\t\t type => [ \"string\", $prefix . \"Type\" ],\n" 02171 "\t\t parameters =>\n" 02172 "\t\t [ \"list\", $prefix . \"Params\",\n" 02173 "\t\t\t[ \"hash\", $prefix . \"Param\",\n" 02174 "\t\t\t {\n" 02175 "\t\t\t declaration_name => [ \"string\", $prefix . \"ParamName\" ],\n" 02176 "\t\t\t type => [ \"string\", $prefix . \"ParamType\" ],\n" 02177 "\t\t\t },\n" 02178 "\t\t\t],\n" 02179 "\t\t ],\n" 02180 "\t\t detailed =>\n" 02181 "\t\t [ \"hash\", $prefix . \"Detailed\",\n" 02182 "\t\t\t{\n" 02183 "\t\t\t doc => [ \"doc\", $prefix . \"DetailedDoc\" ],\n" 02184 "\t\t\t return => [ \"doc\", $prefix . \"Return\" ],\n" 02185 "\t\t\t see => [ \"doc\", $prefix . \"See\" ],\n" 02186 "\t\t\t params =>\n" 02187 "\t\t\t [ \"list\", $prefix . \"PDBlocks\",\n" 02188 "\t\t\t [ \"hash\", $prefix . \"PDBlock\",\n" 02189 "\t\t\t\t{\n" 02190 "\t\t\t\t parameters =>\n" 02191 "\t\t\t\t [ \"list\", $prefix . \"PDParams\",\n" 02192 "\t\t\t\t [ \"hash\", $prefix . \"PDParam\",\n" 02193 "\t\t\t\t\t{\n" 02194 "\t\t\t\t\t name => [ \"string\", $prefix . \"PDParamName\" ],\n" 02195 "\t\t\t\t\t},\n" 02196 "\t\t\t\t ],\n" 02197 "\t\t\t\t ],\n" 02198 "\t\t\t\t doc => [ \"doc\", $prefix . \"PDDoc\" ],\n" 02199 "\t\t\t\t},\n" 02200 "\t\t\t ],\n" 02201 "\t\t\t ],\n" 02202 "\t\t\t},\n" 02203 "\t\t ],\n" 02204 "\t\t },\n" 02205 "\t\t],\n" 02206 "\t ],\n" 02207 "\t },\n" 02208 "\t];\n" 02209 "}\n" 02210 "\n" 02211 "$doxystructure =\n" 02212 " [ \"hash\", \"Root\",\n" 02213 " {\n" 02214 "\tfiles =>\n" 02215 "\t [ \"list\", \"Files\",\n" 02216 "\t [ \"hash\", \"File\",\n" 02217 "\t {\n" 02218 "\t\tname => [ \"string\", \"FileName\" ],\n" 02219 "\t\ttypedefs => memberlist(\"FileTypedef\"),\n" 02220 "\t\tvariables => memberlist(\"FileVariable\"),\n" 02221 "\t\tfunctions => memberlist(\"FileFunction\"),\n" 02222 "\t\tdetailed =>\n" 02223 "\t\t [ \"hash\", \"FileDetailed\",\n" 02224 "\t\t {\n" 02225 "\t\t doc => [ \"doc\", \"FileDetailedDoc\" ],\n" 02226 "\t\t },\n" 02227 "\t\t ],\n" 02228 "\t },\n" 02229 "\t ],\n" 02230 "\t ],\n" 02231 "\tpages =>\n" 02232 "\t [ \"list\", \"Pages\",\n" 02233 "\t [ \"hash\", \"Page\",\n" 02234 "\t {\n" 02235 "\t\tname => [ \"string\", \"PageName\" ],\n" 02236 "\t\tdetailed =>\n" 02237 "\t\t [ \"hash\", \"PageDetailed\",\n" 02238 "\t\t {\n" 02239 "\t\t doc => [ \"doc\", \"PageDetailedDoc\" ],\n" 02240 "\t\t },\n" 02241 "\t\t ],\n" 02242 "\t },\n" 02243 "\t ],\n" 02244 "\t ],\n" 02245 "\tclasses =>\n" 02246 "\t [ \"list\", \"Classes\",\n" 02247 "\t [ \"hash\", \"Class\",\n" 02248 "\t {\n" 02249 "\t\tname => [ \"string\", \"ClassName\" ],\n" 02250 "\t\tpublic_typedefs => memberlist(\"ClassPublicTypedef\"),\n" 02251 "\t\tpublic_methods => memberlist(\"ClassPublicMethod\"),\n" 02252 "\t\tpublic_members => memberlist(\"ClassPublicMember\"),\n" 02253 "\t\tprotected_typedefs => memberlist(\"ClassProtectedTypedef\"),\n" 02254 "\t\tprotected_methods => memberlist(\"ClassProtectedMethod\"),\n" 02255 "\t\tprotected_members => memberlist(\"ClassProtectedMember\"),\n" 02256 "\t\tprivate_typedefs => memberlist(\"ClassPrivateTypedef\"),\n" 02257 "\t\tprivate_methods => memberlist(\"ClassPrivateMethod\"),\n" 02258 "\t\tprivate_members => memberlist(\"ClassPrivateMember\"),\n" 02259 "\t\tdetailed =>\n" 02260 "\t\t [ \"hash\", \"ClassDetailed\",\n" 02261 "\t\t {\n" 02262 "\t\t doc => [ \"doc\", \"ClassDetailedDoc\" ],\n" 02263 "\t\t },\n" 02264 "\t\t ],\n" 02265 "\t },\n" 02266 "\t ],\n" 02267 "\t ],\n" 02268 "\tgroups =>\n" 02269 "\t [ \"list\", \"Groups\",\n" 02270 "\t [ \"hash\", \"Group\",\n" 02271 "\t {\n" 02272 "\t\tname => [ \"string\", \"GroupName\" ],\n" 02273 "\t\ttitle => [ \"string\", \"GroupTitle\" ],\n" 02274 "\t\tfiles =>\n" 02275 "\t\t [ \"list\", \"Files\",\n" 02276 "\t\t [ \"hash\", \"File\",\n" 02277 "\t\t {\n" 02278 "\t\t name => [ \"string\", \"Filename\" ]\n" 02279 "\t\t }\n" 02280 "\t\t ],\n" 02281 "\t\t ],\n" 02282 "\t\tclasses =>\n" 02283 "\t\t [ \"list\", \"Classes\",\n" 02284 "\t\t [ \"hash\", \"Class\",\n" 02285 "\t\t {\n" 02286 "\t\t name => [ \"string\", \"Classname\" ]\n" 02287 "\t\t }\n" 02288 "\t\t ],\n" 02289 "\t\t ],\n" 02290 "\t\tnamespaces =>\n" 02291 "\t\t [ \"list\", \"Namespaces\",\n" 02292 "\t\t [ \"hash\", \"Namespace\",\n" 02293 "\t\t {\n" 02294 "\t\t name => [ \"string\", \"NamespaceName\" ]\n" 02295 "\t\t }\n" 02296 "\t\t ],\n" 02297 "\t\t ],\n" 02298 "\t\tpages =>\n" 02299 "\t\t [ \"list\", \"Pages\",\n" 02300 "\t\t [ \"hash\", \"Page\"," 02301 "\t\t {\n" 02302 "\t\t title => [ \"string\", \"PageName\" ]\n" 02303 "\t\t }\n" 02304 "\t\t ],\n" 02305 "\t\t ],\n" 02306 "\t\tgroups =>\n" 02307 "\t\t [ \"list\", \"Groups\",\n" 02308 "\t\t [ \"hash\", \"Group\",\n" 02309 "\t\t {\n" 02310 "\t\t title => [ \"string\", \"GroupName\" ]\n" 02311 "\t\t }\n" 02312 "\t\t ],\n" 02313 "\t\t ],\n" 02314 "\t\tfunctions => memberlist(\"GroupFunction\"),\n" 02315 "\t\tdetailed =>\n" 02316 "\t\t [ \"hash\", \"GroupDetailed\",\n" 02317 "\t\t {\n" 02318 "\t\t doc => [ \"doc\", \"GroupDetailedDoc\" ],\n" 02319 "\t\t },\n" 02320 "\t\t ],\n" 02321 "\t }\n" 02322 "\t ],\n" 02323 "\t ],\n" 02324 " },\n" 02325 " ];\n" 02326 "\n" 02327 "1;\n"; 02328 02329 return true; 02330 } 02331 02332 bool PerlModGenerator::generateDoxyRules() 02333 { 02334 QFile doxyRules; 02335 if (!createOutputFile(doxyRules, pathDoxyRules)) 02336 return false; 02337 02338 bool perlmodLatex = Config_getBool("PERLMOD_LATEX"); 02339 QString prefix = Config_getString("PERLMOD_MAKEVAR_PREFIX"); 02340 02341 QTextStream doxyRulesStream(&doxyRules); 02342 doxyRulesStream << 02343 prefix << "DOXY_EXEC_PATH = " << pathDoxyExec << "\n" << 02344 prefix << "DOXYFILE = " << pathDoxyfile << "\n" << 02345 prefix << "DOXYDOCS_PM = " << pathDoxyDocsPM << "\n" << 02346 prefix << "DOXYSTRUCTURE_PM = " << pathDoxyStructurePM << "\n" << 02347 prefix << "DOXYRULES = " << pathDoxyRules << "\n"; 02348 if (perlmodLatex) 02349 doxyRulesStream << 02350 prefix << "DOXYLATEX_PL = " << pathDoxyLatexPL << "\n" << 02351 prefix << "DOXYLATEXSTRUCTURE_PL = " << pathDoxyLatexStructurePL << "\n" << 02352 prefix << "DOXYSTRUCTURE_TEX = " << pathDoxyStructureTex << "\n" << 02353 prefix << "DOXYDOCS_TEX = " << pathDoxyDocsTex << "\n" << 02354 prefix << "DOXYFORMAT_TEX = " << pathDoxyFormatTex << "\n" << 02355 prefix << "DOXYLATEX_TEX = " << pathDoxyLatexTex << "\n" << 02356 prefix << "DOXYLATEX_DVI = " << pathDoxyLatexDVI << "\n" << 02357 prefix << "DOXYLATEX_PDF = " << pathDoxyLatexPDF << "\n"; 02358 02359 doxyRulesStream << 02360 "\n" 02361 ".PHONY: clean-perlmod\n" 02362 "clean-perlmod::\n" 02363 "\trm -f $(" << prefix << "DOXYSTRUCTURE_PM) \\\n" 02364 "\t$(" << prefix << "DOXYDOCS_PM)"; 02365 if (perlmodLatex) 02366 doxyRulesStream << 02367 " \\\n" 02368 "\t$(" << prefix << "DOXYLATEX_PL) \\\n" 02369 "\t$(" << prefix << "DOXYLATEXSTRUCTURE_PL) \\\n" 02370 "\t$(" << prefix << "DOXYDOCS_TEX) \\\n" 02371 "\t$(" << prefix << "DOXYSTRUCTURE_TEX) \\\n" 02372 "\t$(" << prefix << "DOXYFORMAT_TEX) \\\n" 02373 "\t$(" << prefix << "DOXYLATEX_TEX) \\\n" 02374 "\t$(" << prefix << "DOXYLATEX_PDF) \\\n" 02375 "\t$(" << prefix << "DOXYLATEX_DVI) \\\n" 02376 "\t$(addprefix $(" << prefix << "DOXYLATEX_TEX:tex=),out aux log)"; 02377 doxyRulesStream << "\n\n"; 02378 02379 doxyRulesStream << 02380 "$(" << prefix << "DOXYRULES) \\\n" 02381 "$(" << prefix << "DOXYMAKEFILE) \\\n" 02382 "$(" << prefix << "DOXYSTRUCTURE_PM) \\\n" 02383 "$(" << prefix << "DOXYDOCS_PM)"; 02384 if (perlmodLatex) { 02385 doxyRulesStream << 02386 " \\\n" 02387 "$(" << prefix << "DOXYLATEX_PL) \\\n" 02388 "$(" << prefix << "DOXYLATEXSTRUCTURE_PL) \\\n" 02389 "$(" << prefix << "DOXYFORMAT_TEX) \\\n" 02390 "$(" << prefix << "DOXYLATEX_TEX)"; 02391 } 02392 doxyRulesStream << 02393 ": \\\n" 02394 "\t$(" << prefix << "DOXYFILE)\n" 02395 "\tcd $(" << prefix << "DOXY_EXEC_PATH) ; doxygen \"$<\"\n"; 02396 02397 if (perlmodLatex) { 02398 doxyRulesStream << 02399 "\n" 02400 "$(" << prefix << "DOXYDOCS_TEX): \\\n" 02401 "$(" << prefix << "DOXYLATEX_PL) \\\n" 02402 "$(" << prefix << "DOXYDOCS_PM)\n" 02403 "\tperl -I\"$(<D)\" \"$<\" >\"$@\"\n" 02404 "\n" 02405 "$(" << prefix << "DOXYSTRUCTURE_TEX): \\\n" 02406 "$(" << prefix << "DOXYLATEXSTRUCTURE_PL) \\\n" 02407 "$(" << prefix << "DOXYSTRUCTURE_PM)\n" 02408 "\tperl -I\"$(<D)\" \"$<\" >\"$@\"\n" 02409 "\n" 02410 "$(" << prefix << "DOXYLATEX_PDF) \\\n" 02411 "$(" << prefix << "DOXYLATEX_DVI): \\\n" 02412 "$(" << prefix << "DOXYLATEX_TEX) \\\n" 02413 "$(" << prefix << "DOXYFORMAT_TEX) \\\n" 02414 "$(" << prefix << "DOXYSTRUCTURE_TEX) \\\n" 02415 "$(" << prefix << "DOXYDOCS_TEX)\n" 02416 "\n" 02417 "$(" << prefix << "DOXYLATEX_PDF): \\\n" 02418 "$(" << prefix << "DOXYLATEX_TEX)\n" 02419 "\tpdflatex -interaction=nonstopmode \"$<\"\n" 02420 "\n" 02421 "$(" << prefix << "DOXYLATEX_DVI): \\\n" 02422 "$(" << prefix << "DOXYLATEX_TEX)\n" 02423 "\tlatex -interaction=nonstopmode \"$<\"\n"; 02424 } 02425 02426 return true; 02427 } 02428 02429 bool PerlModGenerator::generateMakefile() 02430 { 02431 QFile makefile; 02432 if (!createOutputFile(makefile, pathMakefile)) 02433 return false; 02434 02435 bool perlmodLatex = Config_getBool("PERLMOD_LATEX"); 02436 QString prefix = Config_getString("PERLMOD_MAKEVAR_PREFIX"); 02437 02438 QTextStream makefileStream(&makefile); 02439 makefileStream << 02440 ".PHONY: default clean" << (perlmodLatex ? " pdf" : "") << "\n" 02441 "default: " << (perlmodLatex ? "pdf" : "clean") << "\n" 02442 "\n" 02443 "include " << pathDoxyRules << "\n" 02444 "\n" 02445 "clean: clean-perlmod\n"; 02446 02447 if (perlmodLatex) { 02448 makefileStream << 02449 "pdf: $(" << prefix << "DOXYLATEX_PDF)\n" 02450 "dvi: $(" << prefix << "DOXYLATEX_DVI)\n"; 02451 } 02452 02453 return true; 02454 } 02455 02456 bool PerlModGenerator::generateDoxyLatexStructurePL() 02457 { 02458 QFile doxyLatexStructurePL; 02459 if (!createOutputFile(doxyLatexStructurePL, pathDoxyLatexStructurePL)) 02460 return false; 02461 02462 QTextStream doxyLatexStructurePLStream(&doxyLatexStructurePL); 02463 doxyLatexStructurePLStream << 02464 "use DoxyStructure;\n" 02465 "\n" 02466 "sub process($) {\n" 02467 "\tmy $node = $_[0];\n" 02468 "\tmy ($type, $name) = @$node[0, 1];\n" 02469 "\tmy $command;\n" 02470 "\tif ($type eq \"string\") { $command = \"String\" }\n" 02471 "\telsif ($type eq \"doc\") { $command = \"Doc\" }\n" 02472 "\telsif ($type eq \"hash\") {\n" 02473 "\t\t$command = \"Hash\";\n" 02474 "\t\tfor my $subnode (values %{$$node[2]}) {\n" 02475 "\t\t\tprocess($subnode);\n" 02476 "\t\t}\n" 02477 "\t}\n" 02478 "\telsif ($type eq \"list\") {\n" 02479 "\t\t$command = \"List\";\n" 02480 "\t\tprocess($$node[2]);\n" 02481 "\t}\n" 02482 "\tprint \"\\\\\" . $command . \"Node{\" . $name . \"}%\\n\";\n" 02483 "}\n" 02484 "\n" 02485 "process($doxystructure);\n"; 02486 02487 return true; 02488 } 02489 02490 bool PerlModGenerator::generateDoxyLatexPL() 02491 { 02492 QFile doxyLatexPL; 02493 if (!createOutputFile(doxyLatexPL, pathDoxyLatexPL)) 02494 return false; 02495 02496 QTextStream doxyLatexPLStream(&doxyLatexPL); 02497 doxyLatexPLStream << 02498 "use DoxyStructure;\n" 02499 "use DoxyDocs;\n" 02500 "\n" 02501 "sub latex_quote($) {\n" 02502 "\tmy $text = $_[0];\n" 02503 "\t$text =~ s/\\\\/\\\\textbackslash /g;\n" 02504 "\t$text =~ s/\\|/\\\\textbar /g;\n" 02505 "\t$text =~ s/</\\\\textless /g;\n" 02506 "\t$text =~ s/>/\\\\textgreater /g;\n" 02507 "\t$text =~ s/~/\\\\textasciitilde /g;\n" 02508 "\t$text =~ s/\\^/\\\\textasciicircum /g;\n" 02509 "\t$text =~ s/[\\$&%#_{}]/\\\\$&/g;\n" 02510 "\tprint $text;\n" 02511 "}\n" 02512 "\n" 02513 "sub generate_doc($) {\n" 02514 "\tmy $doc = $_[0];\n" 02515 "\tfor my $item (@$doc) {\n" 02516 "\t\tmy $type = $$item{type};\n" 02517 "\t\tif ($type eq \"text\") {\n" 02518 "\t\t\tlatex_quote($$item{content});\n" 02519 "\t\t} elsif ($type eq \"parbreak\") {\n" 02520 "\t\t\tprint \"\\n\\n\";\n" 02521 "\t\t} elsif ($type eq \"style\") {\n" 02522 "\t\t\tmy $style = $$item{style};\n" 02523 "\t\t\tif ($$item{enable} eq \"yes\") {\n" 02524 "\t\t\t\tif ($style eq \"bold\") { print '\\bfseries'; }\n" 02525 "\t\t\t\tif ($style eq \"italic\") { print '\\itshape'; }\n" 02526 "\t\t\t\tif ($style eq \"code\") { print '\\ttfamily'; }\n" 02527 "\t\t\t} else {\n" 02528 "\t\t\t\tif ($style eq \"bold\") { print '\\mdseries'; }\n" 02529 "\t\t\t\tif ($style eq \"italic\") { print '\\upshape'; }\n" 02530 "\t\t\t\tif ($style eq \"code\") { print '\\rmfamily'; }\n" 02531 "\t\t\t}\n" 02532 "\t\t\tprint '{}';\n" 02533 "\t\t} elsif ($type eq \"symbol\") {\n" 02534 "\t\t\tmy $symbol = $$item{symbol};\n" 02535 "\t\t\tif ($symbol eq \"copyright\") { print '\\copyright'; }\n" 02536 "\t\t\telsif ($symbol eq \"szlig\") { print '\\ss'; }\n" 02537 "\t\t\tprint '{}';\n" 02538 "\t\t} elsif ($type eq \"accent\") {\n" 02539 "\t\t\tmy ($accent) = $$item{accent};\n" 02540 "\t\t\tif ($accent eq \"umlaut\") { print '\\\"'; }\n" 02541 "\t\t\telsif ($accent eq \"acute\") { print '\\\\\\''; }\n" 02542 "\t\t\telsif ($accent eq \"grave\") { print '\\`'; }\n" 02543 "\t\t\telsif ($accent eq \"circ\") { print '\\^'; }\n" 02544 "\t\t\telsif ($accent eq \"tilde\") { print '\\~'; }\n" 02545 "\t\t\telsif ($accent eq \"cedilla\") { print '\\c'; }\n" 02546 "\t\t\telsif ($accent eq \"ring\") { print '\\r'; }\n" 02547 "\t\t\tprint \"{\" . $$item{letter} . \"}\"; \n" 02548 "\t\t} elsif ($type eq \"list\") {\n" 02549 "\t\t\tmy $env = ($$item{style} eq \"ordered\") ? \"enumerate\" : \"itemize\";\n" 02550 "\t\t\tprint \"\\n\\\\begin{\" . $env .\"}\";\n" 02551 "\t\t \tfor my $subitem (@{$$item{content}}) {\n" 02552 "\t\t\t\tprint \"\\n\\\\item \";\n" 02553 "\t\t\t\tgenerate_doc($subitem);\n" 02554 "\t\t \t}\n" 02555 "\t\t\tprint \"\\n\\\\end{\" . $env .\"}\";\n" 02556 "\t\t} elsif ($type eq \"url\") {\n" 02557 "\t\t\tlatex_quote($$item{content});\n" 02558 "\t\t}\n" 02559 "\t}\n" 02560 "}\n" 02561 "\n" 02562 "sub generate($$) {\n" 02563 "\tmy ($item, $node) = @_;\n" 02564 "\tmy ($type, $name) = @$node[0, 1];\n" 02565 "\tif ($type eq \"string\") {\n" 02566 "\t\tprint \"\\\\\" . $name . \"{\";\n" 02567 "\t\tlatex_quote($item);\n" 02568 "\t\tprint \"}\";\n" 02569 "\t} elsif ($type eq \"doc\") {\n" 02570 "\t\tif (@$item) {\n" 02571 "\t\t\tprint \"\\\\\" . $name . \"{\";\n" 02572 "\t\t\tgenerate_doc($item);\n" 02573 "\t\t\tprint \"}%\\n\";\n" 02574 "\t\t} else {\n" 02575 "#\t\t\tprint \"\\\\\" . $name . \"Empty%\\n\";\n" 02576 "\t\t}\n" 02577 "\t} elsif ($type eq \"hash\") {\n" 02578 "\t\tmy ($key, $value);\n" 02579 "\t\twhile (($key, $subnode) = each %{$$node[2]}) {\n" 02580 "\t\t\tmy $subname = $$subnode[1];\n" 02581 "\t\t\tprint \"\\\\Defcs{field\" . $subname . \"}{\";\n" 02582 "\t\t\tif ($$item{$key}) {\n" 02583 "\t\t\t\tgenerate($$item{$key}, $subnode);\n" 02584 "\t\t\t} else {\n" 02585 "#\t\t\t\t\tprint \"\\\\\" . $subname . \"Empty%\\n\";\n" 02586 "\t\t\t}\n" 02587 "\t\t\tprint \"}%\\n\";\n" 02588 "\t\t}\n" 02589 "\t\tprint \"\\\\\" . $name . \"%\\n\";\n" 02590 "\t} elsif ($type eq \"list\") {\n" 02591 "\t\tmy $index = 0;\n" 02592 "\t\tif (@$item) {\n" 02593 "\t\t\tprint \"\\\\\" . $name . \"{%\\n\";\n" 02594 "\t\t\tfor my $subitem (@$item) {\n" 02595 "\t\t\t\tif ($index) {\n" 02596 "\t\t\t\t\tprint \"\\\\\" . $name . \"Sep%\\n\";\n" 02597 "\t\t\t\t}\n" 02598 "\t\t\t\tgenerate($subitem, $$node[2]);\n" 02599 "\t\t\t\t$index++;\n" 02600 "\t\t\t}\n" 02601 "\t\t\tprint \"}%\\n\";\n" 02602 "\t\t} else {\n" 02603 "#\t\t\tprint \"\\\\\" . $name . \"Empty%\\n\";\n" 02604 "\t\t}\n" 02605 "\t}\n" 02606 "}\n" 02607 "\n" 02608 "generate($doxydocs, $doxystructure);\n"; 02609 02610 return true; 02611 } 02612 02613 bool PerlModGenerator::generateDoxyFormatTex() 02614 { 02615 QFile doxyFormatTex; 02616 if (!createOutputFile(doxyFormatTex, pathDoxyFormatTex)) 02617 return false; 02618 02619 QTextStream doxyFormatTexStream(&doxyFormatTex); 02620 doxyFormatTexStream << 02621 "\\def\\Defcs#1{\\long\\expandafter\\def\\csname#1\\endcsname}\n" 02622 "\\Defcs{Empty}{}\n" 02623 "\\def\\IfEmpty#1{\\expandafter\\ifx\\csname#1\\endcsname\\Empty}\n" 02624 "\n" 02625 "\\def\\StringNode#1{\\Defcs{#1}##1{##1}}\n" 02626 "\\def\\DocNode#1{\\Defcs{#1}##1{##1}}\n" 02627 "\\def\\ListNode#1{\\Defcs{#1}##1{##1}\\Defcs{#1Sep}{}}\n" 02628 "\\def\\HashNode#1{\\Defcs{#1}{}}\n" 02629 "\n" 02630 "\\input{" << pathDoxyStructureTex << "}\n" 02631 "\n" 02632 "\\newbox\\BoxA\n" 02633 "\\dimendef\\DimenA=151\\relax\n" 02634 "\\dimendef\\DimenB=152\\relax\n" 02635 "\\countdef\\ZoneDepth=151\\relax\n" 02636 "\n" 02637 "\\def\\Cs#1{\\csname#1\\endcsname}\n" 02638 "\\def\\Letcs#1{\\expandafter\\let\\csname#1\\endcsname}\n" 02639 "\\def\\Heading#1{\\vskip 4mm\\relax\\textbf{#1}}\n" 02640 "\\def\\See#1{\\begin{flushleft}\\Heading{See also: }#1\\end{flushleft}}\n" 02641 "\n" 02642 "\\def\\Frame#1{\\vskip 3mm\\relax\\fbox{ \\vbox{\\hsize0.95\\hsize\\vskip 1mm\\relax\n" 02643 "\\raggedright#1\\vskip 0.5mm\\relax} }}\n" 02644 "\n" 02645 "\\def\\Zone#1#2#3{%\n" 02646 "\\Defcs{Test#1}{#2}%\n" 02647 "\\Defcs{Emit#1}{#3}%\n" 02648 "\\Defcs{#1}{%\n" 02649 "\\advance\\ZoneDepth1\\relax\n" 02650 "\\Letcs{Mode\\number\\ZoneDepth}0\\relax\n" 02651 "\\Letcs{Present\\number\\ZoneDepth}0\\relax\n" 02652 "\\Cs{Test#1}\n" 02653 "\\expandafter\\if\\Cs{Present\\number\\ZoneDepth}1%\n" 02654 "\\advance\\ZoneDepth-1\\relax\n" 02655 "\\Letcs{Present\\number\\ZoneDepth}1\\relax\n" 02656 "\\expandafter\\if\\Cs{Mode\\number\\ZoneDepth}1%\n" 02657 "\\advance\\ZoneDepth1\\relax\n" 02658 "\\Letcs{Mode\\number\\ZoneDepth}1\\relax\n" 02659 "\\Cs{Emit#1}\n" 02660 "\\advance\\ZoneDepth-1\\relax\\fi\n" 02661 "\\advance\\ZoneDepth1\\relax\\fi\n" 02662 "\\advance\\ZoneDepth-1\\relax}}\n" 02663 "\n" 02664 "\\def\\Member#1#2{%\n" 02665 "\\Defcs{Test#1}{\\Cs{field#1Detailed}\n" 02666 "\\IfEmpty{field#1DetailedDoc}\\else\\Letcs{Present#1}1\\fi}\n" 02667 "\\Defcs{#1}{\\Letcs{Present#1}0\\relax\n" 02668 "\\Cs{Test#1}\\if1\\Cs{Present#1}\\Letcs{Present\\number\\ZoneDepth}1\\relax\n" 02669 "\\if1\\Cs{Mode\\number\\ZoneDepth}#2\\fi\\fi}}\n" 02670 "\n" 02671 "\\def\\TypedefMemberList#1#2{%\n" 02672 "\\Defcs{#1DetailedDoc}##1{\\vskip 5.5mm\\relax##1}%\n" 02673 "\\Defcs{#1Name}##1{\\textbf{##1}}%\n" 02674 "\\Defcs{#1See}##1{\\See{##1}}%\n" 02675 "%\n" 02676 "\\Zone{#1s}{\\Cs{field#1List}}{\\subsubsection{#2}\\Cs{field#1List}}%\n" 02677 "\\Member{#1}{\\Frame{typedef \\Cs{field#1Type} \\Cs{field#1Name}}%\n" 02678 "\\Cs{field#1DetailedDoc}\\Cs{field#1See}\\vskip 5mm\\relax}}%\n" 02679 "\n" 02680 "\\def\\VariableMemberList#1#2{%\n" 02681 "\\Defcs{#1DetailedDoc}##1{\\vskip 5.5mm\\relax##1}%\n" 02682 "\\Defcs{#1Name}##1{\\textbf{##1}}%\n" 02683 "\\Defcs{#1See}##1{\\See{##1}}%\n" 02684 "%\n" 02685 "\\Zone{#1s}{\\Cs{field#1List}}{\\subsubsection{#2}\\Cs{field#1List}}%\n" 02686 "\\Member{#1}{\\Frame{\\Cs{field#1Type}{} \\Cs{field#1Name}}%\n" 02687 "\\Cs{field#1DetailedDoc}\\Cs{field#1See}\\vskip 5mm\\relax}}%\n" 02688 "\n" 02689 "\\def\\FunctionMemberList#1#2{%\n" 02690 "\\Defcs{#1PDParamName}##1{\\textit{##1}}%\n" 02691 "\\Defcs{#1PDParam}{\\Cs{field#1PDParamName}}%\n" 02692 "\\Defcs{#1PDParamsSep}{, }%\n" 02693 "\\Defcs{#1PDBlocksSep}{\\vskip 2mm\\relax}%\n" 02694 "%\n" 02695 "\\Defcs{#1PDBlocks}##1{%\n" 02696 "\\Heading{Parameters:}\\vskip 1.5mm\\relax\n" 02697 "\\DimenA0pt\\relax\n" 02698 "\\Defcs{#1PDBlock}{\\setbox\\BoxA\\hbox{\\Cs{field#1PDParams}}%\n" 02699 "\\ifdim\\DimenA<\\wd\\BoxA\\DimenA\\wd\\BoxA\\fi}%\n" 02700 "##1%\n" 02701 "\\advance\\DimenA3mm\\relax\n" 02702 "\\DimenB\\hsize\\advance\\DimenB-\\DimenA\\relax\n" 02703 "\\Defcs{#1PDBlock}{\\hbox to\\hsize{\\vtop{\\hsize\\DimenA\\relax\n" 02704 "\\Cs{field#1PDParams}}\\hfill\n" 02705 "\\vtop{\\hsize\\DimenB\\relax\\Cs{field#1PDDoc}}}}%\n" 02706 "##1}\n" 02707 "\n" 02708 "\\Defcs{#1ParamName}##1{\\textit{##1}}\n" 02709 "\\Defcs{#1Param}{\\Cs{field#1ParamType}{} \\Cs{field#1ParamName}}\n" 02710 "\\Defcs{#1ParamsSep}{, }\n" 02711 "\n" 02712 "\\Defcs{#1Name}##1{\\textbf{##1}}\n" 02713 "\\Defcs{#1See}##1{\\See{##1}}\n" 02714 "\\Defcs{#1Return}##1{\\Heading{Returns: }##1}\n" 02715 "\\Defcs{field#1Title}{\\Frame{\\Cs{field#1Type}{} \\Cs{field#1Name}(\\Cs{field#1Params})}}%\n" 02716 "%\n" 02717 "\\Zone{#1s}{\\Cs{field#1List}}{\\subsubsection{#2}\\Cs{field#1List}}%\n" 02718 "\\Member{#1}{%\n" 02719 "\\Cs{field#1Title}\\vskip 6mm\\relax\\Cs{field#1DetailedDoc}\n" 02720 "\\Cs{field#1Return}\\Cs{field#1PDBlocks}\\Cs{field#1See}\\vskip 5mm\\relax}}\n" 02721 "\n" 02722 "\\def\\FileDetailed{\\fieldFileDetailedDoc\\par}\n" 02723 "\\def\\ClassDetailed{\\fieldClassDetailedDoc\\par}\n" 02724 "\n" 02725 "\\def\\FileSubzones{\\fieldFileTypedefs\\fieldFileVariables\\fieldFileFunctions}\n" 02726 "\n" 02727 "\\def\\ClassSubzones{%\n" 02728 "\\fieldClassPublicTypedefs\\fieldClassPublicMembers\\fieldClassPublicMethods\n" 02729 "\\fieldClassProtectedTypedefs\\fieldClassProtectedMembers\\fieldClassProtectedMethods\n" 02730 "\\fieldClassPrivateTypedefs\\fieldClassPrivateMembers\\fieldClassPrivateMethods}\n" 02731 "\n" 02732 "\\Member{Page}{\\subsection{\\fieldPageName}\\fieldPageDetailedDoc}\n" 02733 "\n" 02734 "\\TypedefMemberList{FileTypedef}{Typedefs}\n" 02735 "\\VariableMemberList{FileVariable}{Variables}\n" 02736 "\\FunctionMemberList{FileFunction}{Functions}\n" 02737 "\\Zone{File}{\\FileSubzones}{\\subsection{\\fieldFileName}\\fieldFileDetailed\\FileSubzones}\n" 02738 "\n" 02739 "\\TypedefMemberList{ClassPublicTypedef}{Public Typedefs}\n" 02740 "\\TypedefMemberList{ClassProtectedTypedef}{Protected Typedefs}\n" 02741 "\\TypedefMemberList{ClassPrivateTypedef}{Private Typedefs}\n" 02742 "\\VariableMemberList{ClassPublicMember}{Public Members}\n" 02743 "\\VariableMemberList{ClassProtectedMember}{Protected Members}\n" 02744 "\\VariableMemberList{ClassPrivateMember}{Private Members}\n" 02745 "\\FunctionMemberList{ClassPublicMethod}{Public Methods}\n" 02746 "\\FunctionMemberList{ClassProtectedMethod}{Protected Methods}\n" 02747 "\\FunctionMemberList{ClassPrivateMethod}{Private Methods}\n" 02748 "\\Zone{Class}{\\ClassSubzones}{\\subsection{\\fieldClassName}\\fieldClassDetailed\\ClassSubzones}\n" 02749 "\n" 02750 "\\Zone{AllPages}{\\fieldPages}{\\section{Pages}\\fieldPages}\n" 02751 "\\Zone{AllFiles}{\\fieldFiles}{\\section{Files}\\fieldFiles}\n" 02752 "\\Zone{AllClasses}{\\fieldClasses}{\\section{Classes}\\fieldClasses}\n" 02753 "\n" 02754 "\\newlength{\\oldparskip}\n" 02755 "\\newlength{\\oldparindent}\n" 02756 "\\newlength{\\oldfboxrule}\n" 02757 "\n" 02758 "\\ZoneDepth0\\relax\n" 02759 "\\Letcs{Mode0}1\\relax\n" 02760 "\n" 02761 "\\def\\EmitDoxyDocs{%\n" 02762 "\\setlength{\\oldparskip}{\\parskip}\n" 02763 "\\setlength{\\oldparindent}{\\parindent}\n" 02764 "\\setlength{\\oldfboxrule}{\\fboxrule}\n" 02765 "\\setlength{\\parskip}{0cm}\n" 02766 "\\setlength{\\parindent}{0cm}\n" 02767 "\\setlength{\\fboxrule}{1pt}\n" 02768 "\\AllPages\\AllFiles\\AllClasses\n" 02769 "\\setlength{\\parskip}{\\oldparskip}\n" 02770 "\\setlength{\\parindent}{\\oldparindent}\n" 02771 "\\setlength{\\fboxrule}{\\oldfboxrule}}\n"; 02772 02773 return true; 02774 } 02775 02776 bool PerlModGenerator::generateDoxyLatexTex() 02777 { 02778 QFile doxyLatexTex; 02779 if (!createOutputFile(doxyLatexTex, pathDoxyLatexTex)) 02780 return false; 02781 02782 QTextStream doxyLatexTexStream(&doxyLatexTex); 02783 doxyLatexTexStream << 02784 "\\documentclass[a4paper,12pt]{article}\n" 02785 "\\usepackage[latin1]{inputenc}\n" 02786 "\\usepackage[none]{hyphenat}\n" 02787 "\\usepackage[T1]{fontenc}\n" 02788 "\\usepackage{hyperref}\n" 02789 "\\usepackage{times}\n" 02790 "\n" 02791 "\\input{doxyformat}\n" 02792 "\n" 02793 "\\begin{document}\n" 02794 "\\input{" << pathDoxyDocsTex << "}\n" 02795 "\\sloppy\n" 02796 "\\EmitDoxyDocs\n" 02797 "\\end{document}\n"; 02798 02799 return true; 02800 } 02801 02802 void PerlModGenerator::generate() 02803 { 02804 // + classes 02805 // + namespaces 02806 // + files 02807 // - packages 02808 // + groups 02809 // + related pages 02810 // - examples 02811 02812 QDir perlModDir; 02813 if (!createOutputDir(perlModDir)) 02814 return; 02815 02816 bool perlmodLatex = Config_getBool("PERLMOD_LATEX"); 02817 02818 pathDoxyDocsPM = perlModDir.absPath() + "/DoxyDocs.pm"; 02819 pathDoxyStructurePM = perlModDir.absPath() + "/DoxyStructure.pm"; 02820 pathMakefile = perlModDir.absPath() + "/Makefile"; 02821 pathDoxyRules = perlModDir.absPath() + "/doxyrules.make"; 02822 02823 if (perlmodLatex) { 02824 pathDoxyStructureTex = perlModDir.absPath() + "/doxystructure.tex"; 02825 pathDoxyFormatTex = perlModDir.absPath() + "/doxyformat.tex"; 02826 pathDoxyLatexTex = perlModDir.absPath() + "/doxylatex.tex"; 02827 pathDoxyLatexDVI = perlModDir.absPath() + "/doxylatex.dvi"; 02828 pathDoxyLatexPDF = perlModDir.absPath() + "/doxylatex.pdf"; 02829 pathDoxyDocsTex = perlModDir.absPath() + "/doxydocs.tex"; 02830 pathDoxyLatexPL = perlModDir.absPath() + "/doxylatex.pl"; 02831 pathDoxyLatexStructurePL = perlModDir.absPath() + "/doxylatex-structure.pl"; 02832 } 02833 02834 if (!(generatePerlModOutput() 02835 && generateDoxyStructurePM() 02836 && generateMakefile() 02837 && generateDoxyRules())) 02838 return; 02839 02840 if (perlmodLatex) { 02841 if (!(generateDoxyLatexStructurePL() 02842 && generateDoxyLatexPL() 02843 && generateDoxyLatexTex() 02844 && generateDoxyFormatTex())) 02845 return; 02846 } 02847 } 02848 02849 void generatePerlMod() 02850 { 02851 PerlModGenerator pmg(Config_getBool("PERLMOD_PRETTY")); 02852 pmg.generate(); 02853 } 02854 02855 // Local Variables: 02856 // c-basic-offset: 2 02857 // End: 02858 02859 /* This elisp function for XEmacs makes Control-Z transform 02860 the text in the region into a valid C string. 02861 02862 (global-set-key '(control z) (lambda () (interactive) 02863 (save-excursion 02864 (if (< (mark) (point)) (exchange-point-and-mark)) 02865 (let ((start (point)) (replacers 02866 '(("\\\\" "\\\\\\\\") 02867 ("\"" "\\\\\"") 02868 ("\t" "\\\\t") 02869 ("^.*$" "\"\\&\\\\n\"")))) 02870 (while replacers 02871 (while (re-search-forward (caar replacers) (mark) t) 02872 (replace-match (cadar replacers) t)) 02873 (goto-char start) 02874 (setq replacers (cdr replacers))))))) 02875 */