Orb/Doxygen/src/perlmodgen.cpp
changeset 0 42188c7ea2d9
child 4 468f4c8d3d5b
equal deleted inserted replaced
-1:000000000000 0:42188c7ea2d9
       
     1 /******************************************************************************
       
     2  *
       
     3  *
       
     4  *
       
     5  *
       
     6  * Copyright (C) 1997-2008 by Dimitri van Heesch.
       
     7  * Authors: Dimitri van Heesch, Miguel Lobo.
       
     8  *
       
     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.
       
    14  *
       
    15  * Documents produced by Doxygen are derivative works derived from the
       
    16  * input used in their production; they are not affected by this license.
       
    17  *
       
    18  */
       
    19 
       
    20 #include <stdlib.h>
       
    21 
       
    22 #include "perlmodgen.h"
       
    23 #include "docparser.h"
       
    24 #include "message.h"
       
    25 #include "doxygen.h"
       
    26 #include "pagedef.h"
       
    27 
       
    28 #include <qdir.h>
       
    29 #include <qstack.h>
       
    30 #include <qdict.h>
       
    31 #include <qfile.h>
       
    32 #include <qtextstream.h>
       
    33 
       
    34 #define PERLOUTPUT_MAX_INDENTATION 40
       
    35 
       
    36 class PerlModOutputStream
       
    37 {
       
    38 public:
       
    39 
       
    40   QString m_s;
       
    41   QTextStream *m_t;
       
    42 
       
    43   PerlModOutputStream(QTextStream *t = 0) : m_t(t) { }
       
    44 
       
    45   void add(char c);
       
    46   void add(const char *s);
       
    47   void add(QCString &s);
       
    48   void add(QString &s);
       
    49   void add(int n);
       
    50   void add(unsigned int n);
       
    51 };
       
    52 
       
    53 void PerlModOutputStream::add(char c)
       
    54 {
       
    55   if (m_t != 0)
       
    56     (*m_t) << c;
       
    57   else
       
    58     m_s += c;
       
    59 }
       
    60 
       
    61 void PerlModOutputStream::add(const char *s)
       
    62 {
       
    63   if (m_t != 0)
       
    64     (*m_t) << s;
       
    65   else
       
    66     m_s += s;
       
    67 }
       
    68 
       
    69 void PerlModOutputStream::add(QCString &s)
       
    70 {
       
    71   if (m_t != 0)
       
    72     (*m_t) << s;
       
    73   else
       
    74     m_s += s;
       
    75 }
       
    76 
       
    77 void PerlModOutputStream::add(QString &s)
       
    78 {
       
    79   if (m_t != 0)
       
    80     (*m_t) << s;
       
    81   else
       
    82     m_s += s;
       
    83 }
       
    84 
       
    85 void PerlModOutputStream::add(int n)
       
    86 {
       
    87   if (m_t != 0)
       
    88     (*m_t) << n;
       
    89   else
       
    90     m_s += n;
       
    91 }
       
    92 
       
    93 void PerlModOutputStream::add(unsigned int n)
       
    94 {
       
    95   if (m_t != 0)
       
    96     (*m_t) << n;
       
    97   else
       
    98     m_s += n;
       
    99 }
       
   100 
       
   101 class PerlModOutput
       
   102 {
       
   103 public:
       
   104 
       
   105   bool m_pretty;
       
   106 
       
   107   inline PerlModOutput(bool pretty)
       
   108     : m_pretty(pretty), m_stream(0), m_indentation(false), m_blockstart(true)
       
   109   {
       
   110     m_spaces[0] = 0;
       
   111   }
       
   112 
       
   113   virtual ~PerlModOutput() { }
       
   114 
       
   115   inline void setPerlModOutputStream(PerlModOutputStream *os) { m_stream = os; }
       
   116 
       
   117   inline PerlModOutput &openSave() { iopenSave(); return *this; }
       
   118   inline PerlModOutput &closeSave(QString &s) { icloseSave(s); return *this; }
       
   119 
       
   120   inline PerlModOutput &continueBlock()
       
   121   {
       
   122     if (m_blockstart)
       
   123       m_blockstart = false;
       
   124     else
       
   125       m_stream->add(',');
       
   126     indent();
       
   127     return *this;
       
   128   }
       
   129 
       
   130   inline PerlModOutput &add(char c) { m_stream->add(c); return *this; }
       
   131   inline PerlModOutput &add(const char *s) { m_stream->add(s); return *this; }
       
   132   inline PerlModOutput &add(QCString &s) { m_stream->add(s); return *this; }
       
   133   inline PerlModOutput &add(QString &s) { m_stream->add(s); return *this; }
       
   134   inline PerlModOutput &add(int n) { m_stream->add(n); return *this; }
       
   135   inline PerlModOutput &add(unsigned int n) { m_stream->add(n); return *this; }
       
   136 
       
   137   PerlModOutput &addQuoted(const char *s) { iaddQuoted(s); return *this; }
       
   138 
       
   139   inline PerlModOutput &indent()
       
   140   {
       
   141     if (m_pretty) {
       
   142       m_stream->add('\n');
       
   143       m_stream->add(m_spaces);
       
   144     }
       
   145     return *this;
       
   146   }
       
   147 
       
   148   inline PerlModOutput &open(char c, const char *s = 0) { iopen(c, s); return *this; }
       
   149   inline PerlModOutput &close(char c = 0) { iclose(c); return *this; }
       
   150 
       
   151   inline PerlModOutput &addField(const char *s) { iaddField(s); return *this; }
       
   152   inline PerlModOutput &addFieldQuotedChar(const char *field, char content)
       
   153   {
       
   154     iaddFieldQuotedChar(field, content); return *this;
       
   155   }
       
   156   inline PerlModOutput &addFieldQuotedString(const char *field, const char *content)
       
   157   {
       
   158     iaddFieldQuotedString(field, content); return *this;
       
   159   }
       
   160   inline PerlModOutput &addFieldBoolean(const char *field, bool content)
       
   161   {
       
   162     return addFieldQuotedString(field, content ? "yes" : "no");
       
   163   }
       
   164   inline PerlModOutput &openList(const char *s = 0) { open('[', s); return *this; }
       
   165   inline PerlModOutput &closeList() { close(']'); return *this; }
       
   166   inline PerlModOutput &openHash(const char *s = 0 ) { open('{', s); return *this; }
       
   167   inline PerlModOutput &closeHash() { close('}'); return *this; }
       
   168 
       
   169 protected:
       
   170   
       
   171   void iopenSave();
       
   172   void icloseSave(QString &);
       
   173   
       
   174   void incIndent();
       
   175   void decIndent();
       
   176 
       
   177   void iaddQuoted(const char *);
       
   178   void iaddFieldQuotedChar(const char *, char);
       
   179   void iaddFieldQuotedString(const char *, const char *);
       
   180   void iaddField(const char *);
       
   181 
       
   182   void iopen(char, const char *);
       
   183   void iclose(char);
       
   184 
       
   185 private:
       
   186   
       
   187   PerlModOutputStream *m_stream;
       
   188   int m_indentation;
       
   189   bool m_blockstart;
       
   190 
       
   191   QStack<PerlModOutputStream> m_saved;
       
   192   char m_spaces[PERLOUTPUT_MAX_INDENTATION * 2 + 2];
       
   193 };
       
   194 
       
   195 void PerlModOutput::iopenSave()
       
   196 {
       
   197   m_saved.push(m_stream);
       
   198   m_stream = new PerlModOutputStream();
       
   199 }
       
   200 
       
   201 void PerlModOutput::icloseSave(QString &s)
       
   202 {
       
   203   s = m_stream->m_s;
       
   204   delete m_stream;
       
   205   m_stream = m_saved.pop();
       
   206 }
       
   207 
       
   208 void PerlModOutput::incIndent()
       
   209 {
       
   210   if (m_indentation < PERLOUTPUT_MAX_INDENTATION)
       
   211   {
       
   212     char *s = &m_spaces[m_indentation * 2];
       
   213     *s++ = ' '; *s++ = ' '; *s = 0;
       
   214   }
       
   215   m_indentation++;
       
   216 }
       
   217 
       
   218 void PerlModOutput::decIndent()
       
   219 {
       
   220   m_indentation--;
       
   221   if (m_indentation < PERLOUTPUT_MAX_INDENTATION)
       
   222     m_spaces[m_indentation * 2] = 0;
       
   223 }
       
   224 
       
   225 void PerlModOutput::iaddQuoted(const char *s) 
       
   226 {
       
   227   char c;
       
   228   while ((c = *s++) != 0) {
       
   229     if ((c == '\'') || (c == '\\'))
       
   230       m_stream->add('\\');
       
   231     m_stream->add(c);
       
   232   }
       
   233 }
       
   234   
       
   235 void PerlModOutput::iaddField(const char *s)
       
   236 {
       
   237   continueBlock();
       
   238   m_stream->add(s);
       
   239   m_stream->add(m_pretty ? " => " : "=>");
       
   240 }
       
   241 
       
   242 void PerlModOutput::iaddFieldQuotedChar(const char *field, char content)
       
   243 {
       
   244   iaddField(field);
       
   245   m_stream->add('\'');
       
   246   if ((content == '\'') || (content == '\\'))
       
   247     m_stream->add('\\');
       
   248   m_stream->add(content);
       
   249   m_stream->add('\'');
       
   250 }
       
   251 
       
   252 void PerlModOutput::iaddFieldQuotedString(const char *field, const char *content)
       
   253 {
       
   254   if (content == 0)
       
   255     return;
       
   256   iaddField(field);
       
   257   m_stream->add('\'');
       
   258   iaddQuoted(content);
       
   259   m_stream->add('\'');
       
   260 }
       
   261 
       
   262 void PerlModOutput::iopen(char c, const char *s)
       
   263 {
       
   264   if (s != 0)
       
   265     iaddField(s);
       
   266   else
       
   267     continueBlock();
       
   268   m_stream->add(c);
       
   269   incIndent();
       
   270   m_blockstart = true;
       
   271 }
       
   272 
       
   273 void PerlModOutput::iclose(char c)
       
   274 {
       
   275   decIndent(); 
       
   276   indent();
       
   277   if (c != 0)
       
   278     m_stream->add(c); 
       
   279   m_blockstart = false;
       
   280 }
       
   281 
       
   282 /*! @brief Concrete visitor implementation for PerlMod output. */
       
   283 class PerlModDocVisitor : public DocVisitor
       
   284 {
       
   285 public:
       
   286   PerlModDocVisitor(PerlModOutput &);
       
   287   virtual ~PerlModDocVisitor() { }
       
   288 
       
   289   void finish();
       
   290   
       
   291   //--------------------------------------
       
   292   // visitor functions for leaf nodes
       
   293   //--------------------------------------
       
   294    
       
   295   void visit(DocWord *);
       
   296   void visit(DocLinkedWord *);
       
   297   void visit(DocWhiteSpace *);
       
   298   void visit(DocSymbol *);
       
   299   void visit(DocURL *);
       
   300   void visit(DocLineBreak *);
       
   301   void visit(DocHorRuler *);
       
   302   void visit(DocStyleChange *);
       
   303   void visit(DocVerbatim *);
       
   304   void visit(DocAnchor *);
       
   305   void visit(DocInclude *);
       
   306   void visit(DocIncOperator *);
       
   307   void visit(DocFormula *);
       
   308   void visit(DocIndexEntry *);
       
   309   void visit(DocSimpleSectSep *);
       
   310 
       
   311   //--------------------------------------
       
   312   // visitor functions for compound nodes
       
   313   //--------------------------------------
       
   314    
       
   315   void visitPre(DocAutoList *);
       
   316   void visitPost(DocAutoList *);
       
   317   void visitPre(DocAutoListItem *);
       
   318   void visitPost(DocAutoListItem *);
       
   319   void visitPre(DocPara *) ;
       
   320   void visitPost(DocPara *);
       
   321   void visitPre(DocRoot *);
       
   322   void visitPost(DocRoot *);
       
   323   void visitPre(DocSimpleSect *);
       
   324   void visitPost(DocSimpleSect *);
       
   325   void visitPre(DocTitle *);
       
   326   void visitPost(DocTitle *);
       
   327   void visitPre(DocSimpleList *);
       
   328   void visitPost(DocSimpleList *);
       
   329   void visitPre(DocSimpleListItem *);
       
   330   void visitPost(DocSimpleListItem *);
       
   331   void visitPre(DocSection *);
       
   332   void visitPost(DocSection *);
       
   333   void visitPre(DocHtmlList *);
       
   334   void visitPost(DocHtmlList *) ;
       
   335   void visitPre(DocHtmlListItem *);
       
   336   void visitPost(DocHtmlListItem *);
       
   337   //void visitPre(DocHtmlPre *);
       
   338   //void visitPost(DocHtmlPre *);
       
   339   void visitPre(DocHtmlDescList *);
       
   340   void visitPost(DocHtmlDescList *);
       
   341   void visitPre(DocHtmlDescTitle *);
       
   342   void visitPost(DocHtmlDescTitle *);
       
   343   void visitPre(DocHtmlDescData *);
       
   344   void visitPost(DocHtmlDescData *);
       
   345   void visitPre(DocHtmlTable *);
       
   346   void visitPost(DocHtmlTable *);
       
   347   void visitPre(DocHtmlRow *);
       
   348   void visitPost(DocHtmlRow *) ;
       
   349   void visitPre(DocHtmlCell *);
       
   350   void visitPost(DocHtmlCell *);
       
   351   void visitPre(DocHtmlCaption *);
       
   352   void visitPost(DocHtmlCaption *);
       
   353   void visitPre(DocInternal *);
       
   354   void visitPost(DocInternal *);
       
   355   void visitPre(DocHRef *);
       
   356   void visitPost(DocHRef *);
       
   357   void visitPre(DocHtmlHeader *);
       
   358   void visitPost(DocHtmlHeader *);
       
   359   void visitPre(DocImage *);
       
   360   void visitPost(DocImage *);
       
   361   void visitPre(DocDotFile *);
       
   362   void visitPost(DocDotFile *);
       
   363   void visitPre(DocLink *);
       
   364   void visitPost(DocLink *);
       
   365   void visitPre(DocRef *);
       
   366   void visitPost(DocRef *);
       
   367   void visitPre(DocSecRefItem *);
       
   368   void visitPost(DocSecRefItem *);
       
   369   void visitPre(DocSecRefList *);
       
   370   void visitPost(DocSecRefList *);
       
   371   //void visitPre(DocLanguage *);
       
   372   //void visitPost(DocLanguage *);
       
   373   void visitPre(DocParamSect *);
       
   374   void visitPost(DocParamSect *);
       
   375   void visitPre(DocParamList *);
       
   376   void visitPost(DocParamList *);
       
   377   void visitPre(DocXRefItem *);
       
   378   void visitPost(DocXRefItem *);
       
   379   void visitPre(DocInternalRef *);
       
   380   void visitPost(DocInternalRef *);
       
   381   void visitPre(DocCopy *);
       
   382   void visitPost(DocCopy *);
       
   383   void visitPre(DocText *);
       
   384   void visitPost(DocText *);
       
   385 
       
   386 private:
       
   387 
       
   388   //--------------------------------------
       
   389   // helper functions
       
   390   //--------------------------------------
       
   391 
       
   392   void addLink(const QString &ref, const QString &file,
       
   393 	       const QString &anchor);
       
   394    
       
   395   void enterText();
       
   396   void leaveText();
       
   397 
       
   398   void openItem(const char *);
       
   399   void closeItem();
       
   400   void singleItem(const char *);
       
   401   void openSubBlock(const char * = 0);
       
   402   void closeSubBlock();
       
   403   void openOther();
       
   404   void closeOther();
       
   405 
       
   406   //--------------------------------------
       
   407   // state variables
       
   408   //--------------------------------------
       
   409 
       
   410   PerlModOutput &m_output;
       
   411   bool m_textmode;
       
   412   bool m_textblockstart;
       
   413   QString m_other;
       
   414 };
       
   415 
       
   416 PerlModDocVisitor::PerlModDocVisitor(PerlModOutput &output)
       
   417   : DocVisitor(DocVisitor_Other), m_output(output), m_textmode(false)
       
   418 {
       
   419   m_output.openList("doc");
       
   420 }
       
   421 
       
   422 void PerlModDocVisitor::finish()
       
   423 {
       
   424   leaveText();
       
   425   m_output.closeList()
       
   426     .add(m_other);
       
   427 }
       
   428 
       
   429 void PerlModDocVisitor::addLink(const QString &,const QString &file,const QString &anchor)
       
   430 {
       
   431   QString link = file;
       
   432   if (!anchor.isEmpty())
       
   433     (link += "_1") += anchor;
       
   434   m_output.addFieldQuotedString("link", link);
       
   435 }
       
   436 
       
   437 void PerlModDocVisitor::openItem(const char *name)
       
   438 {
       
   439   leaveText();
       
   440   m_output.openHash().addFieldQuotedString("type", name);
       
   441 }
       
   442 
       
   443 void PerlModDocVisitor::closeItem()
       
   444 {
       
   445   leaveText();
       
   446   m_output.closeHash();
       
   447 }
       
   448 
       
   449 void PerlModDocVisitor::enterText()
       
   450 {
       
   451   if (m_textmode)
       
   452     return;
       
   453   openItem("text");
       
   454   m_output.addField("content").add('\'');
       
   455   m_textmode = true;
       
   456 }
       
   457 
       
   458 void PerlModDocVisitor::leaveText()
       
   459 {
       
   460   if (!m_textmode)
       
   461     return;
       
   462   m_textmode = false;
       
   463   m_output
       
   464     .add('\'')
       
   465     .closeHash();
       
   466 }
       
   467 
       
   468 void PerlModDocVisitor::singleItem(const char *name)
       
   469 {
       
   470   openItem(name);
       
   471   closeItem();
       
   472 }
       
   473 
       
   474 void PerlModDocVisitor::openSubBlock(const char *s)
       
   475 {
       
   476   leaveText();
       
   477   m_output.openList(s);
       
   478   m_textblockstart = true;
       
   479 }
       
   480 
       
   481 void PerlModDocVisitor::closeSubBlock()
       
   482 {
       
   483   leaveText();
       
   484   m_output.closeList();
       
   485 }
       
   486 
       
   487 void PerlModDocVisitor::openOther()
       
   488 {
       
   489   // Using a secondary text stream will corrupt the perl file. Instead of
       
   490   // printing doc => [ data => [] ], it will print doc => [] data => [].
       
   491   /*
       
   492   leaveText();
       
   493   m_output.openSave();
       
   494   */
       
   495 }
       
   496 
       
   497 void PerlModDocVisitor::closeOther()
       
   498 {
       
   499   // Using a secondary text stream will corrupt the perl file. Instead of
       
   500   // printing doc => [ data => [] ], it will print doc => [] data => [].
       
   501   /*
       
   502   QString other;
       
   503   leaveText();
       
   504   m_output.closeSave(other);
       
   505   m_other += other;
       
   506   */
       
   507 }
       
   508 
       
   509 void PerlModDocVisitor::visit(DocWord *w)
       
   510 {
       
   511   enterText();
       
   512   m_output.addQuoted(w->word());
       
   513 }
       
   514 
       
   515 void PerlModDocVisitor::visit(DocLinkedWord *w)
       
   516 {
       
   517   openItem("url");
       
   518   addLink(w->ref(), w->file(), w->anchor());
       
   519   m_output.addFieldQuotedString("content", w->word());
       
   520   closeItem();
       
   521 }
       
   522 
       
   523 void PerlModDocVisitor::visit(DocWhiteSpace *)
       
   524 {
       
   525   enterText();
       
   526   m_output.add(' ');
       
   527 }
       
   528 
       
   529 void PerlModDocVisitor::visit(DocSymbol *sy)
       
   530 {
       
   531   char c = 0;
       
   532   const char *s = 0;
       
   533   const char *accent = 0;
       
   534   const char *symbol = 0;
       
   535   switch(sy->symbol())
       
   536   {
       
   537   case DocSymbol::At:      c = '@'; break;
       
   538   case DocSymbol::Less:    c = '<'; break;
       
   539   case DocSymbol::Greater: c = '>'; break;
       
   540   case DocSymbol::Amp:     c = '&'; break;
       
   541   case DocSymbol::Dollar:  c = '$'; break;
       
   542   case DocSymbol::Hash:    c = '#'; break;
       
   543   case DocSymbol::Percent: c = '%'; break;
       
   544   case DocSymbol::Quot:    c = '"'; break;
       
   545   case DocSymbol::Lsquo:   s = "\\\'"; break;
       
   546   case DocSymbol::Rsquo:   s = "\\\'"; break;
       
   547   case DocSymbol::Ldquo:   c = '"'; break;
       
   548   case DocSymbol::Rdquo:   c = '"'; break;
       
   549   case DocSymbol::Ndash:   c = '-'; break;
       
   550   case DocSymbol::Mdash:   s = "--"; break;
       
   551   case DocSymbol::Nbsp:    c = ' '; break;
       
   552   case DocSymbol::Uml:     accent = "umlaut"; break;
       
   553   case DocSymbol::Acute:   accent = "acute"; break;
       
   554   case DocSymbol::Grave:   accent = "grave"; break;
       
   555   case DocSymbol::Circ:    accent = "circ"; break;
       
   556   case DocSymbol::Slash:   accent = "slash"; break;
       
   557   case DocSymbol::Tilde:   accent = "tilde"; break;
       
   558   case DocSymbol::Cedil:   accent = "cedilla"; break;
       
   559   case DocSymbol::Ring:    accent = "ring"; break;
       
   560   case DocSymbol::BSlash:  s = "\\\\"; break;
       
   561   case DocSymbol::Copy:    symbol = "copyright"; break;
       
   562   case DocSymbol::Tm:      symbol = "trademark"; break;
       
   563   case DocSymbol::Reg:     symbol = "registered"; break;
       
   564   case DocSymbol::Szlig:   symbol = "szlig"; break;
       
   565   case DocSymbol::Apos:    s = "\\\'"; break;
       
   566   case DocSymbol::Aelig:   symbol = "aelig"; break;
       
   567   case DocSymbol::AElig:   symbol = "AElig"; break;
       
   568   case DocSymbol::Unknown:
       
   569     err("Error: unknown symbol found\n");
       
   570     break;
       
   571   }
       
   572   if (c != 0) {
       
   573     enterText();
       
   574     m_output.add(c);
       
   575   } else if (s != 0) {
       
   576     enterText();
       
   577     m_output.add(s);
       
   578   } else if (symbol != 0) {
       
   579     leaveText();
       
   580     openItem("symbol");
       
   581     m_output.addFieldQuotedString("symbol", symbol);
       
   582     closeItem();
       
   583   } else if (accent != 0) {
       
   584     leaveText();
       
   585     openItem("accent");
       
   586     m_output
       
   587       .addFieldQuotedString("accent", accent)
       
   588       .addFieldQuotedChar("letter", sy->letter());
       
   589     closeItem();
       
   590   }
       
   591 }
       
   592 
       
   593 void PerlModDocVisitor::visit(DocURL *u)
       
   594 {
       
   595   openItem("url");
       
   596   m_output.addFieldQuotedString("content", u->url());
       
   597   closeItem();
       
   598 }
       
   599 
       
   600 void PerlModDocVisitor::visit(DocLineBreak *) { singleItem("linebreak"); }
       
   601 void PerlModDocVisitor::visit(DocHorRuler *) { singleItem("hruler"); }
       
   602 
       
   603 void PerlModDocVisitor::visit(DocStyleChange *s)
       
   604 {
       
   605   const char *style = 0;
       
   606   switch (s->style())
       
   607   {
       
   608     case DocStyleChange::Bold:          style = "bold"; break;
       
   609     case DocStyleChange::Italic:        style = "italic"; break;
       
   610     case DocStyleChange::Code:          style = "code"; break;
       
   611     case DocStyleChange::Subscript:     style = "subscript"; break;
       
   612     case DocStyleChange::Superscript:   style = "superscript"; break;
       
   613     case DocStyleChange::Center:        style = "center"; break;
       
   614     case DocStyleChange::Small:         style = "small"; break;
       
   615     case DocStyleChange::Preformatted:  style = "preformatted"; break;
       
   616     case DocStyleChange::Div:           style = "div"; break;
       
   617     case DocStyleChange::Span:          style = "span"; break;
       
   618                                         
       
   619   }
       
   620   openItem("style");
       
   621   m_output.addFieldQuotedString("style", style)
       
   622     .addFieldBoolean("enable", s->enable());
       
   623   closeItem();
       
   624 }
       
   625 
       
   626 void PerlModDocVisitor::visit(DocVerbatim *s)
       
   627 {
       
   628   const char *type = 0;
       
   629   switch(s->type())
       
   630   {
       
   631   case DocVerbatim::Code:
       
   632 #if 0
       
   633     m_output.add("<programlisting>");
       
   634     parseCode(m_ci,s->context(),s->text(),FALSE,0);
       
   635     m_output.add("</programlisting>");
       
   636 #endif
       
   637     return;
       
   638   case DocVerbatim::Verbatim:	type = "preformatted"; break;
       
   639   case DocVerbatim::HtmlOnly:	type = "htmlonly"; break;
       
   640   case DocVerbatim::ManOnly:	type = "manonly"; break;
       
   641   case DocVerbatim::LatexOnly:	type = "latexonly"; break;
       
   642   case DocVerbatim::XmlOnly:	type = "xmlonly"; break;
       
   643   case DocVerbatim::Dot:	type = "dot"; break;
       
   644   case DocVerbatim::Msc:	type = "msc"; break;
       
   645   }
       
   646   openItem(type);
       
   647   m_output.addFieldQuotedString("content", s->text());
       
   648   closeItem();
       
   649 }
       
   650 
       
   651 void PerlModDocVisitor::visit(DocAnchor *anc)
       
   652 {
       
   653   QString anchor = anc->file() + "_1" + anc->anchor();
       
   654   openItem("anchor");
       
   655   m_output.addFieldQuotedString("id", anchor);
       
   656   closeItem();
       
   657 }
       
   658 
       
   659 void PerlModDocVisitor::visit(DocInclude *inc)
       
   660 {
       
   661   const char *type = 0;
       
   662   switch(inc->type())
       
   663   {
       
   664   case DocInclude::IncWithLines:
       
   665   #if 0
       
   666       { 
       
   667          m_t << "<div class=\"fragment\"><pre>";
       
   668          QFileInfo cfi( inc->file() );
       
   669          FileDef fd( cfi.dirPath(), cfi.fileName() );
       
   670          parseCode(m_ci,inc->context(),inc->text().latin1(),inc->isExample(),inc->exampleFile(), &fd);
       
   671          m_t << "</pre></div>"; 
       
   672       }
       
   673       break;
       
   674   #endif
       
   675     return;
       
   676   case DocInclude::Include:
       
   677 #if 0
       
   678     m_output.add("<programlisting>");
       
   679     parseCode(m_ci,inc->context(),inc->text(),FALSE,0);
       
   680     m_output.add("</programlisting>");
       
   681 #endif
       
   682     return;
       
   683   case DocInclude::DontInclude:	return;
       
   684   case DocInclude::HtmlInclude:	type = "htmlonly"; break;
       
   685   case DocInclude::VerbInclude:	type = "preformatted"; break;
       
   686   }
       
   687   openItem(type);
       
   688   m_output.addFieldQuotedString("content", inc->text());
       
   689   closeItem();
       
   690 }
       
   691 
       
   692 void PerlModDocVisitor::visit(DocIncOperator *)
       
   693 {
       
   694 #if 0
       
   695   //printf("DocIncOperator: type=%d first=%d, last=%d text=`%s'\n",
       
   696   //    op->type(),op->isFirst(),op->isLast(),op->text().data());
       
   697   if (op->isFirst())
       
   698   {
       
   699     m_output.add("<programlisting>");
       
   700   }
       
   701   if (op->type()!=DocIncOperator::Skip)
       
   702   {
       
   703     parseCode(m_ci,op->context(),op->text(),FALSE,0);
       
   704   }
       
   705   if (op->isLast()) 
       
   706   {
       
   707     m_output.add("</programlisting>");
       
   708   }
       
   709   else
       
   710   {
       
   711     m_output.add('\n');
       
   712   }
       
   713 #endif
       
   714 }
       
   715 
       
   716 void PerlModDocVisitor::visit(DocFormula *f)
       
   717 {
       
   718   openItem("formula");
       
   719   QString id;
       
   720   id += f->id();
       
   721   m_output.addFieldQuotedString("id", id).addFieldQuotedString("content", f->text());
       
   722   closeItem();
       
   723 }
       
   724 
       
   725 void PerlModDocVisitor::visit(DocIndexEntry *)
       
   726 {
       
   727 #if 0
       
   728   m_output.add("<indexentry>"
       
   729 	       "<primaryie>");
       
   730   m_output.addQuoted(ie->entry());
       
   731   m_output.add("</primaryie>"
       
   732 	       "<secondaryie></secondaryie>"
       
   733 	       "</indexentry>");
       
   734 #endif
       
   735 }
       
   736 
       
   737 void PerlModDocVisitor::visit(DocSimpleSectSep *)
       
   738 {
       
   739 }
       
   740 
       
   741 //--------------------------------------
       
   742 // visitor functions for compound nodes
       
   743 //--------------------------------------
       
   744 
       
   745 void PerlModDocVisitor::visitPre(DocAutoList *l)
       
   746 {
       
   747   openItem("list");
       
   748   m_output.addFieldQuotedString("style", l->isEnumList() ? "ordered" : "itemized");
       
   749   openSubBlock("content");
       
   750 }
       
   751 
       
   752 void PerlModDocVisitor::visitPost(DocAutoList *)
       
   753 {
       
   754   closeSubBlock();
       
   755   closeItem();
       
   756 }
       
   757 
       
   758 void PerlModDocVisitor::visitPre(DocAutoListItem *)
       
   759 {
       
   760   openSubBlock();
       
   761 }
       
   762 
       
   763 void PerlModDocVisitor::visitPost(DocAutoListItem *)
       
   764 {
       
   765   closeSubBlock();
       
   766 }
       
   767 
       
   768 void PerlModDocVisitor::visitPre(DocPara *)
       
   769 {
       
   770   if (m_textblockstart)
       
   771     m_textblockstart = false;
       
   772   else
       
   773     singleItem("parbreak");
       
   774   /*
       
   775   openItem("para");
       
   776   openSubBlock("content");
       
   777   */
       
   778 }
       
   779 
       
   780 void PerlModDocVisitor::visitPost(DocPara *)
       
   781 {
       
   782   /*
       
   783   closeSubBlock();
       
   784   closeItem();
       
   785   */
       
   786 }
       
   787 
       
   788 void PerlModDocVisitor::visitPre(DocRoot *)
       
   789 {
       
   790 }
       
   791 
       
   792 void PerlModDocVisitor::visitPost(DocRoot *)
       
   793 {
       
   794 }
       
   795 
       
   796 void PerlModDocVisitor::visitPre(DocSimpleSect *s)
       
   797 {
       
   798   const char *type = 0;
       
   799   switch (s->type())
       
   800   {
       
   801   case DocSimpleSect::See:		type = "see"; break;
       
   802   case DocSimpleSect::Return:		type = "return"; break;
       
   803   case DocSimpleSect::Author:		type = "author"; break;
       
   804   case DocSimpleSect::Authors:		type = "authors"; break;
       
   805   case DocSimpleSect::Version:		type = "version"; break;
       
   806   case DocSimpleSect::Since:		type = "since"; break;
       
   807   case DocSimpleSect::Date:		type = "date"; break;
       
   808   case DocSimpleSect::Note:		type = "bug"; break;
       
   809   case DocSimpleSect::Warning:		type = "warning"; break;
       
   810   case DocSimpleSect::Pre:		type = "pre"; break;
       
   811   case DocSimpleSect::Post:		type = "post"; break;
       
   812   case DocSimpleSect::Invar:		type = "invariant"; break;
       
   813   case DocSimpleSect::Remark:		type = "remark"; break;
       
   814   case DocSimpleSect::Attention:	type = "attention"; break;
       
   815   case DocSimpleSect::User:		type = "par"; break;
       
   816   case DocSimpleSect::Rcs:		type = "rcs"; break;
       
   817   case DocSimpleSect::Unknown:
       
   818     err("Error: unknown simple section found\n");
       
   819     break;
       
   820   }
       
   821   openOther();
       
   822   openSubBlock(type);
       
   823 }
       
   824 
       
   825 void PerlModDocVisitor::visitPost(DocSimpleSect *)
       
   826 {
       
   827   closeSubBlock();
       
   828   closeOther();
       
   829 }
       
   830 
       
   831 void PerlModDocVisitor::visitPre(DocTitle *)
       
   832 {
       
   833   openItem("title");
       
   834   openSubBlock("content");
       
   835 }
       
   836 
       
   837 void PerlModDocVisitor::visitPost(DocTitle *)
       
   838 {
       
   839   closeSubBlock();
       
   840   closeItem();
       
   841 }
       
   842 
       
   843 void PerlModDocVisitor::visitPre(DocSimpleList *) 
       
   844 {
       
   845   openItem("list");
       
   846   m_output.addFieldQuotedString("style", "itemized");
       
   847   openSubBlock("content");
       
   848 }
       
   849 
       
   850 void PerlModDocVisitor::visitPost(DocSimpleList *)
       
   851 {
       
   852   closeSubBlock();
       
   853   closeItem();
       
   854 }
       
   855 
       
   856 void PerlModDocVisitor::visitPre(DocSimpleListItem *) { openSubBlock(); }
       
   857 void PerlModDocVisitor::visitPost(DocSimpleListItem *) { closeSubBlock(); }
       
   858 
       
   859 void PerlModDocVisitor::visitPre(DocSection *s)
       
   860 {
       
   861   QString sect = QString("sect%1").arg(s->level());
       
   862   openItem(sect);
       
   863   openSubBlock("content");
       
   864 }
       
   865 
       
   866 void PerlModDocVisitor::visitPost(DocSection *)
       
   867 {
       
   868   closeSubBlock();
       
   869   closeItem();
       
   870 }
       
   871 
       
   872 void PerlModDocVisitor::visitPre(DocHtmlList *l)
       
   873 {
       
   874   openItem("list");
       
   875   m_output.addFieldQuotedString("style", (l->type() == DocHtmlList::Ordered) ? "ordered" : "itemized");
       
   876   openSubBlock("content");
       
   877 }
       
   878 
       
   879 void PerlModDocVisitor::visitPost(DocHtmlList *)
       
   880 {
       
   881   closeSubBlock();
       
   882   closeItem();
       
   883 }
       
   884 
       
   885 void PerlModDocVisitor::visitPre(DocHtmlListItem *) { openSubBlock(); }
       
   886 void PerlModDocVisitor::visitPost(DocHtmlListItem *) { closeSubBlock(); }
       
   887 
       
   888 //void PerlModDocVisitor::visitPre(DocHtmlPre *)
       
   889 //{
       
   890 //  openItem("preformatted");
       
   891 //  openSubBlock("content");
       
   892 //  //m_insidePre=TRUE;
       
   893 //}
       
   894 
       
   895 //void PerlModDocVisitor::visitPost(DocHtmlPre *)
       
   896 //{
       
   897 //  //m_insidePre=FALSE;
       
   898 //  closeSubBlock();
       
   899 //  closeItem();
       
   900 //}
       
   901 
       
   902 void PerlModDocVisitor::visitPre(DocHtmlDescList *)
       
   903 {
       
   904 #if 0
       
   905   m_output.add("<variablelist>\n");
       
   906 #endif
       
   907 }
       
   908 
       
   909 void PerlModDocVisitor::visitPost(DocHtmlDescList *)
       
   910 {
       
   911 #if 0
       
   912   m_output.add("</variablelist>\n");
       
   913 #endif
       
   914 }
       
   915 
       
   916 void PerlModDocVisitor::visitPre(DocHtmlDescTitle *)
       
   917 {
       
   918 #if 0
       
   919   m_output.add("<varlistentry><term>");
       
   920 #endif
       
   921 }
       
   922 
       
   923 void PerlModDocVisitor::visitPost(DocHtmlDescTitle *)
       
   924 {
       
   925 #if 0
       
   926   m_output.add("</term></varlistentry>\n");
       
   927 #endif
       
   928 }
       
   929 
       
   930 void PerlModDocVisitor::visitPre(DocHtmlDescData *)
       
   931 {
       
   932 #if 0
       
   933   m_output.add("<listitem>");
       
   934 #endif
       
   935 }
       
   936 
       
   937 void PerlModDocVisitor::visitPost(DocHtmlDescData *)
       
   938 {
       
   939 #if 0
       
   940   m_output.add("</listitem>\n");
       
   941 #endif
       
   942 }
       
   943 
       
   944 void PerlModDocVisitor::visitPre(DocHtmlTable *)
       
   945 {
       
   946 #if 0
       
   947   m_output.add("<table rows=\""); m_output.add(t->numRows());
       
   948   m_output.add("\" cols=\""); m_output.add(t->numCols()); m_output.add("\">");
       
   949 #endif
       
   950 }
       
   951 
       
   952 void PerlModDocVisitor::visitPost(DocHtmlTable *)
       
   953 {
       
   954 #if 0
       
   955   m_output.add("</table>\n");
       
   956 #endif
       
   957 }
       
   958 
       
   959 void PerlModDocVisitor::visitPre(DocHtmlRow *)
       
   960 {
       
   961 #if 0
       
   962   m_output.add("<row>\n");
       
   963 #endif
       
   964 }
       
   965 
       
   966 void PerlModDocVisitor::visitPost(DocHtmlRow *)
       
   967 {
       
   968 #if 0
       
   969   m_output.add("</row>\n");
       
   970 #endif
       
   971 }
       
   972 
       
   973 void PerlModDocVisitor::visitPre(DocHtmlCell *)
       
   974 {
       
   975 #if 0
       
   976   if (c->isHeading()) m_output.add("<entry thead=\"yes\">"); else m_output.add("<entry thead=\"no\">");
       
   977 #endif
       
   978 }
       
   979 
       
   980 void PerlModDocVisitor::visitPost(DocHtmlCell *)
       
   981 {
       
   982 #if 0
       
   983   m_output.add("</entry>");
       
   984 #endif
       
   985 }
       
   986 
       
   987 void PerlModDocVisitor::visitPre(DocHtmlCaption *)
       
   988 {
       
   989 #if 0
       
   990   m_output.add("<caption>");
       
   991 #endif
       
   992 }
       
   993 
       
   994 void PerlModDocVisitor::visitPost(DocHtmlCaption *)
       
   995 {
       
   996 #if 0
       
   997   m_output.add("</caption>\n");
       
   998 #endif
       
   999 }
       
  1000 
       
  1001 void PerlModDocVisitor::visitPre(DocInternal *)
       
  1002 {
       
  1003 #if 0
       
  1004   m_output.add("<internal>");
       
  1005 #endif
       
  1006 }
       
  1007 
       
  1008 void PerlModDocVisitor::visitPost(DocInternal *)
       
  1009 {
       
  1010 #if 0
       
  1011   m_output.add("</internal>");
       
  1012 #endif
       
  1013 }
       
  1014 
       
  1015 void PerlModDocVisitor::visitPre(DocHRef *)
       
  1016 {
       
  1017 #if 0
       
  1018   m_output.add("<ulink url=\""); m_output.add(href->url()); m_output.add("\">");
       
  1019 #endif
       
  1020 }
       
  1021 
       
  1022 void PerlModDocVisitor::visitPost(DocHRef *)
       
  1023 {
       
  1024 #if 0
       
  1025   m_output.add("</ulink>");
       
  1026 #endif
       
  1027 }
       
  1028 
       
  1029 void PerlModDocVisitor::visitPre(DocHtmlHeader *)
       
  1030 {
       
  1031 #if 0
       
  1032   m_output.add("<sect"); m_output.add(header->level()); m_output.add(">");
       
  1033 #endif
       
  1034 }
       
  1035 
       
  1036 void PerlModDocVisitor::visitPost(DocHtmlHeader *)
       
  1037 {
       
  1038 #if 0
       
  1039   m_output.add("</sect"); m_output.add(header->level()); m_output.add(">\n");
       
  1040 #endif
       
  1041 }
       
  1042 
       
  1043 void PerlModDocVisitor::visitPre(DocImage *)
       
  1044 {
       
  1045 #if 0
       
  1046   m_output.add("<image type=\"");
       
  1047   switch(img->type())
       
  1048   {
       
  1049   case DocImage::Html:  m_output.add("html"); break;
       
  1050   case DocImage::Latex: m_output.add("latex"); break;
       
  1051   case DocImage::Rtf:   m_output.add("rtf"); break;
       
  1052   }
       
  1053   m_output.add("\"");
       
  1054   
       
  1055   QCString baseName=img->name();
       
  1056   int i;
       
  1057   if ((i=baseName.findRev('/'))!=-1 || (i=baseName.findRev('\\'))!=-1)
       
  1058   {
       
  1059     baseName=baseName.right(baseName.length()-i-1);
       
  1060   }
       
  1061   m_output.add(" name=\""); m_output.add(baseName); m_output.add("\"");
       
  1062   if (!img->width().isEmpty())
       
  1063   {
       
  1064     m_output.add(" width=\"");
       
  1065     m_output.addQuoted(img->width());
       
  1066     m_output.add("\"");
       
  1067   }
       
  1068   else if (!img->height().isEmpty())
       
  1069   {
       
  1070     m_output.add(" height=\"");
       
  1071     m_output.addQuoted(img->height());
       
  1072     m_output.add("\"");
       
  1073   }
       
  1074   m_output.add(">");
       
  1075 #endif
       
  1076 }
       
  1077 
       
  1078 void PerlModDocVisitor::visitPost(DocImage *)
       
  1079 {
       
  1080 #if 0
       
  1081   m_output.add("</image>");
       
  1082 #endif
       
  1083 }
       
  1084 
       
  1085 void PerlModDocVisitor::visitPre(DocDotFile *)
       
  1086 {
       
  1087 #if 0
       
  1088   m_output.add("<dotfile name=\""); m_output.add(df->file()); m_output.add("\">");
       
  1089 #endif
       
  1090 }
       
  1091 
       
  1092 void PerlModDocVisitor::visitPost(DocDotFile *)
       
  1093 {
       
  1094 #if 0
       
  1095   m_output.add("</dotfile>");
       
  1096 #endif
       
  1097 }
       
  1098 
       
  1099 void PerlModDocVisitor::visitPre(DocLink *lnk)
       
  1100 {
       
  1101   openItem("link");
       
  1102   addLink(lnk->ref(), lnk->file(), lnk->anchor());
       
  1103 }
       
  1104 
       
  1105 void PerlModDocVisitor::visitPost(DocLink *)
       
  1106 {
       
  1107   closeItem();
       
  1108 }
       
  1109 
       
  1110 void PerlModDocVisitor::visitPre(DocRef *ref)
       
  1111 {
       
  1112   openItem("ref");
       
  1113   if (!ref->hasLinkText())
       
  1114     m_output.addFieldQuotedString("text", ref->targetTitle());
       
  1115   openSubBlock("content");
       
  1116 }
       
  1117 
       
  1118 void PerlModDocVisitor::visitPost(DocRef *)
       
  1119 {
       
  1120   closeSubBlock();
       
  1121   closeItem();
       
  1122 }
       
  1123 
       
  1124 void PerlModDocVisitor::visitPre(DocSecRefItem *)
       
  1125 {
       
  1126 #if 0
       
  1127   m_output.add("<tocitem id=\""); m_output.add(ref->file()); m_output.add("_1"); m_output.add(ref->anchor()); m_output.add("\">");
       
  1128 #endif
       
  1129 }
       
  1130 
       
  1131 void PerlModDocVisitor::visitPost(DocSecRefItem *)
       
  1132 {
       
  1133 #if 0
       
  1134   m_output.add("</tocitem>");
       
  1135 #endif
       
  1136 }
       
  1137 
       
  1138 void PerlModDocVisitor::visitPre(DocSecRefList *)
       
  1139 {
       
  1140 #if 0
       
  1141   m_output.add("<toclist>");
       
  1142 #endif
       
  1143 }
       
  1144 
       
  1145 void PerlModDocVisitor::visitPost(DocSecRefList *)
       
  1146 {
       
  1147 #if 0
       
  1148   m_output.add("</toclist>");
       
  1149 #endif
       
  1150 }
       
  1151 
       
  1152 //void PerlModDocVisitor::visitPre(DocLanguage *l)
       
  1153 //{
       
  1154 //  openItem("language");
       
  1155 //  m_output.addFieldQuotedString("id", l->id());
       
  1156 //}
       
  1157 //
       
  1158 //void PerlModDocVisitor::visitPost(DocLanguage *)
       
  1159 //{
       
  1160 //  closeItem();
       
  1161 //}
       
  1162 
       
  1163 void PerlModDocVisitor::visitPre(DocParamSect *s)
       
  1164 {
       
  1165   leaveText();
       
  1166   const char *type = 0;
       
  1167   switch(s->type())
       
  1168   {
       
  1169   case DocParamSect::Param:     type = "params"; break;
       
  1170   case DocParamSect::RetVal:    type = "retvals"; break;
       
  1171   case DocParamSect::Exception: type = "exceptions"; break;
       
  1172   case DocParamSect::TemplateParam: type = "templateparam"; break;
       
  1173   case DocParamSect::Unknown:
       
  1174     err("Error: unknown parameter section found\n");
       
  1175     break;
       
  1176   }
       
  1177   openOther();
       
  1178   openSubBlock(type);
       
  1179 }
       
  1180 
       
  1181 void PerlModDocVisitor::visitPost(DocParamSect *)
       
  1182 {
       
  1183   closeSubBlock();
       
  1184   closeOther();
       
  1185 }
       
  1186 
       
  1187 void PerlModDocVisitor::visitPre(DocParamList *pl)
       
  1188 {
       
  1189   leaveText();
       
  1190   m_output.openHash()
       
  1191     .openList("parameters");
       
  1192   //QStrListIterator li(pl->parameters());
       
  1193   //const char *s;
       
  1194   QListIterator<DocNode> li(pl->parameters());
       
  1195   DocNode *param;
       
  1196   for (li.toFirst();(param=li.current());++li)
       
  1197   {
       
  1198     QCString s;
       
  1199     if (param->kind()==DocNode::Kind_Word)
       
  1200     {
       
  1201       s = ((DocWord*)param)->word(); 
       
  1202     }
       
  1203     else if (param->kind()==DocNode::Kind_LinkedWord)
       
  1204     {
       
  1205       s = ((DocLinkedWord*)param)->word(); 
       
  1206     }
       
  1207     m_output.openHash()
       
  1208       .addFieldQuotedString("name", s)
       
  1209       .closeHash();
       
  1210   }
       
  1211   m_output.closeList()
       
  1212     .openList("doc");
       
  1213 }
       
  1214 
       
  1215 void PerlModDocVisitor::visitPost(DocParamList *)
       
  1216 {
       
  1217   leaveText();
       
  1218   m_output.closeList()
       
  1219     .closeHash();
       
  1220 }
       
  1221 
       
  1222 void PerlModDocVisitor::visitPre(DocXRefItem *)
       
  1223 {
       
  1224 #if 0
       
  1225   m_output.add("<xrefsect id=\"");
       
  1226   m_output.add(x->file()); m_output.add("_1"); m_output.add(x->anchor());
       
  1227   m_output.add("\">");
       
  1228   m_output.add("<xreftitle>");
       
  1229   m_output.addQuoted(x->title());
       
  1230   m_output.add("</xreftitle>");
       
  1231   m_output.add("<xrefdescription>");
       
  1232 #endif
       
  1233   openItem("xrefitem");
       
  1234   openSubBlock("content");
       
  1235 }
       
  1236 
       
  1237 void PerlModDocVisitor::visitPost(DocXRefItem *)
       
  1238 {
       
  1239   closeSubBlock();
       
  1240   closeItem();
       
  1241 #if 0
       
  1242   m_output.add("</xrefdescription>");
       
  1243   m_output.add("</xrefsect>");
       
  1244 #endif
       
  1245 }
       
  1246 
       
  1247 void PerlModDocVisitor::visitPre(DocInternalRef *ref)
       
  1248 {
       
  1249   openItem("ref");
       
  1250   addLink(0,ref->file(),ref->anchor());
       
  1251   openSubBlock("content");
       
  1252 }
       
  1253 
       
  1254 void PerlModDocVisitor::visitPost(DocInternalRef *)
       
  1255 {
       
  1256   closeSubBlock();
       
  1257   closeItem();
       
  1258 }
       
  1259 
       
  1260 void PerlModDocVisitor::visitPre(DocCopy *)
       
  1261 {
       
  1262 }
       
  1263 
       
  1264 void PerlModDocVisitor::visitPost(DocCopy *)
       
  1265 {
       
  1266 }
       
  1267 
       
  1268 void PerlModDocVisitor::visitPre(DocText *)
       
  1269 {
       
  1270 }
       
  1271 
       
  1272 void PerlModDocVisitor::visitPost(DocText *)
       
  1273 {
       
  1274 }
       
  1275 
       
  1276 static void addTemplateArgumentList(ArgumentList *al,PerlModOutput &output,const char *)
       
  1277 {
       
  1278   QCString indentStr;
       
  1279   if (!al)
       
  1280     return;
       
  1281   output.openList("template_parameters");
       
  1282   ArgumentListIterator ali(*al);
       
  1283   Argument *a;
       
  1284   for (ali.toFirst();(a=ali.current());++ali)
       
  1285   {
       
  1286     output.openHash();
       
  1287     if (!a->type.isEmpty())
       
  1288       output.addFieldQuotedString("type", a->type);
       
  1289     if (!a->name.isEmpty())
       
  1290       output.addFieldQuotedString("declaration_name", a->name)
       
  1291 	.addFieldQuotedString("definition_name", a->name);
       
  1292     if (!a->defval.isEmpty())
       
  1293       output.addFieldQuotedString("default", a->defval);
       
  1294     output.closeHash();
       
  1295   }
       
  1296   output.closeList();
       
  1297 }
       
  1298 
       
  1299 #if 0
       
  1300 static void addMemberTemplateLists(MemberDef *md,PerlModOutput &output)
       
  1301 {
       
  1302   ClassDef *cd = md->getClassDef();
       
  1303   const char *cname = cd ? cd->name().data() : 0;
       
  1304   if (md->templateArguments()) // function template prefix
       
  1305     addTemplateArgumentList(md->templateArguments(),output,cname);
       
  1306 }
       
  1307 #endif
       
  1308 
       
  1309 static void addTemplateList(ClassDef *cd,PerlModOutput &output)
       
  1310 {
       
  1311   addTemplateArgumentList(cd->templateArguments(),output,cd->name());
       
  1312 }
       
  1313 
       
  1314 static void addPerlModDocBlock(PerlModOutput &output,
       
  1315 			    const char *name,
       
  1316 			    const QCString &fileName,
       
  1317 			    int lineNr,
       
  1318 			    Definition *scope,
       
  1319 			    MemberDef *md,
       
  1320 			    const QCString &text)
       
  1321 {
       
  1322   QCString stext = text.stripWhiteSpace();
       
  1323   if (stext.isEmpty())
       
  1324     output.addField(name).add("{}");
       
  1325   else {
       
  1326     DocNode *root = validatingParseDoc(fileName,lineNr,scope,md,stext,FALSE,0);
       
  1327     output.openHash(name);
       
  1328     PerlModDocVisitor *visitor = new PerlModDocVisitor(output);
       
  1329     root->accept(visitor);
       
  1330     visitor->finish();
       
  1331     output.closeHash();
       
  1332     delete visitor;
       
  1333     delete root;
       
  1334   }
       
  1335 }
       
  1336 
       
  1337 static const char *getProtectionName(Protection prot) 
       
  1338 {
       
  1339   switch (prot)
       
  1340   {
       
  1341   case Public:    return "public";
       
  1342   case Protected: return "protected";
       
  1343   case Private:   return "private";
       
  1344   case Package:   return "package";
       
  1345   }
       
  1346   return 0;
       
  1347 }
       
  1348 
       
  1349 static const char *getVirtualnessName(Specifier virt)
       
  1350 {
       
  1351   switch(virt)
       
  1352   {
       
  1353   case Normal:  return "non_virtual";
       
  1354   case Virtual: return "virtual";
       
  1355   case Pure:    return "pure_virtual";
       
  1356   }
       
  1357   return 0;
       
  1358 }
       
  1359 
       
  1360 static QString pathDoxyfile;
       
  1361 static QString pathDoxyExec;
       
  1362 
       
  1363 void setPerlModDoxyfile(const QString &qs)
       
  1364 {
       
  1365   pathDoxyfile = qs;
       
  1366   pathDoxyExec = QDir::currentDirPath();
       
  1367 }
       
  1368 
       
  1369 class PerlModGenerator
       
  1370 {
       
  1371 public:
       
  1372 
       
  1373   PerlModOutput m_output;
       
  1374 
       
  1375   QString pathDoxyStructurePM;
       
  1376   QString pathDoxyDocsTex;
       
  1377   QString pathDoxyFormatTex;
       
  1378   QString pathDoxyLatexTex;
       
  1379   QString pathDoxyLatexDVI;
       
  1380   QString pathDoxyLatexPDF;
       
  1381   QString pathDoxyStructureTex;
       
  1382   QString pathDoxyDocsPM;
       
  1383   QString pathDoxyLatexPL;
       
  1384   QString pathDoxyLatexStructurePL;
       
  1385   QString pathDoxyRules;
       
  1386   QString pathMakefile;
       
  1387 
       
  1388   inline PerlModGenerator(bool pretty) : m_output(pretty) { }
       
  1389 
       
  1390   void generatePerlModForMember(MemberDef *md, Definition *);
       
  1391   void generatePerlModSection(Definition *d, MemberList *ml,
       
  1392 			      const char *name, const char *header=0);
       
  1393   void addListOfAllMembers(ClassDef *cd);
       
  1394   void generatePerlModForClass(ClassDef *cd);
       
  1395   void generatePerlModForNamespace(NamespaceDef *nd);
       
  1396   void generatePerlModForFile(FileDef *fd);
       
  1397   void generatePerlModForGroup(GroupDef *gd);
       
  1398   void generatePerlModForPage(PageDef *pi);
       
  1399   
       
  1400   bool createOutputFile(QFile &f, const char *s);
       
  1401   bool createOutputDir(QDir &perlModDir);
       
  1402   bool generateDoxyLatexTex();
       
  1403   bool generateDoxyFormatTex();
       
  1404   bool generateDoxyStructurePM();
       
  1405   bool generateDoxyLatexPL();
       
  1406   bool generateDoxyLatexStructurePL();
       
  1407   bool generateDoxyRules();
       
  1408   bool generateMakefile();
       
  1409   bool generatePerlModOutput();
       
  1410 
       
  1411   void generate();
       
  1412 };
       
  1413 
       
  1414 void PerlModGenerator::generatePerlModForMember(MemberDef *md,Definition *)
       
  1415 {
       
  1416   // + declaration/definition arg lists
       
  1417   // + reimplements
       
  1418   // + reimplementedBy
       
  1419   // + exceptions
       
  1420   // + const/volatile specifiers
       
  1421   // - examples
       
  1422   // - source definition
       
  1423   // - source references
       
  1424   // - source referenced by
       
  1425   // - body code
       
  1426   // - template arguments
       
  1427   //     (templateArguments(), definitionTemplateParameterLists())
       
  1428  
       
  1429   QCString memType;
       
  1430   bool isFunc=FALSE;
       
  1431   switch (md->memberType())
       
  1432   {
       
  1433   case MemberDef::Define:      memType="define";    break;
       
  1434   case MemberDef::EnumValue:   memType="enumvalue"; break;
       
  1435   case MemberDef::Property:    memType="property";  break;
       
  1436   case MemberDef::Variable:    memType="variable";  break;
       
  1437   case MemberDef::Typedef:     memType="typedef";   break;
       
  1438   case MemberDef::Enumeration: memType="enum";      break;
       
  1439   case MemberDef::Function:    memType="function";  isFunc=TRUE; break;
       
  1440   case MemberDef::Signal:      memType="signal";    isFunc=TRUE; break;
       
  1441   //case MemberDef::Prototype:   memType="prototype"; isFunc=TRUE; break;
       
  1442   case MemberDef::Friend:      memType="friend";    isFunc=TRUE; break;
       
  1443   case MemberDef::DCOP:        memType="dcop";      isFunc=TRUE; break;
       
  1444   case MemberDef::Slot:        memType="slot";      isFunc=TRUE; break;
       
  1445   case MemberDef::Event:       memType="event";     break;
       
  1446   }
       
  1447 
       
  1448   m_output.openHash()
       
  1449     .addFieldQuotedString("kind", memType)
       
  1450     .addFieldQuotedString("name", md->name())
       
  1451     .addFieldQuotedString("virtualness", getVirtualnessName(md->virtualness()))
       
  1452     .addFieldQuotedString("protection", getProtectionName(md->protection()))
       
  1453     .addFieldBoolean("static", md->isStatic());
       
  1454   
       
  1455   addPerlModDocBlock(m_output,"brief",md->getDefFileName(),md->getDefLine(),md->getOuterScope(),md,md->briefDescription());
       
  1456   addPerlModDocBlock(m_output,"detailed",md->getDefFileName(),md->getDefLine(),md->getOuterScope(),md,md->documentation());
       
  1457   if (md->memberType()!=MemberDef::Define &&
       
  1458       md->memberType()!=MemberDef::Enumeration)
       
  1459     m_output.addFieldQuotedString("type", md->typeString());
       
  1460   
       
  1461   LockingPtr<ArgumentList> al = md->argumentList();
       
  1462   if (isFunc) //function
       
  1463   {
       
  1464     m_output.addFieldBoolean("const", al!=0 && al->constSpecifier)
       
  1465       .addFieldBoolean("volatile", al!=0 && al->volatileSpecifier);
       
  1466 
       
  1467     m_output.openList("parameters");
       
  1468     LockingPtr<ArgumentList> declAl = md->declArgumentList();
       
  1469     LockingPtr<ArgumentList> defAl  = md->argumentList();
       
  1470     if (declAl!=0 && declAl->count()>0)
       
  1471     {
       
  1472       ArgumentListIterator declAli(*declAl);
       
  1473       ArgumentListIterator defAli(*defAl);
       
  1474       Argument *a;
       
  1475       for (declAli.toFirst();(a=declAli.current());++declAli)
       
  1476       {
       
  1477 	Argument *defArg = defAli.current();
       
  1478 	m_output.openHash();
       
  1479 
       
  1480 	if (!a->name.isEmpty())
       
  1481 	  m_output.addFieldQuotedString("declaration_name", a->name);
       
  1482 
       
  1483 	if (defArg && !defArg->name.isEmpty() && defArg->name!=a->name)
       
  1484 	  m_output.addFieldQuotedString("definition_name", defArg->name);
       
  1485 
       
  1486 	if (!a->type.isEmpty())
       
  1487 	  m_output.addFieldQuotedString("type", a->type);
       
  1488 
       
  1489 	if (!a->array.isEmpty())
       
  1490 	  m_output.addFieldQuotedString("array", a->array);
       
  1491 
       
  1492 	if (!a->defval.isEmpty())
       
  1493 	  m_output.addFieldQuotedString("default_value", a->defval);
       
  1494 
       
  1495 	if (!a->attrib.isEmpty())
       
  1496 	  m_output.addFieldQuotedString("attributes", a->attrib);
       
  1497 	
       
  1498 	m_output.closeHash();
       
  1499 	if (defArg) ++defAli;
       
  1500       }
       
  1501     }
       
  1502     m_output.closeList();
       
  1503   }
       
  1504   else if (md->memberType()==MemberDef::Define &&
       
  1505 	   md->argsString()!=0) // define
       
  1506   {
       
  1507     m_output.openList("parameters");
       
  1508     ArgumentListIterator ali(*al);
       
  1509     Argument *a;
       
  1510     for (ali.toFirst();(a=ali.current());++ali)
       
  1511     {
       
  1512       m_output.openHash()
       
  1513 	.addFieldQuotedString("name", a->type)
       
  1514 	.closeHash();
       
  1515     }
       
  1516     m_output.closeList();
       
  1517   }
       
  1518   if (!md->initializer().isEmpty())
       
  1519     m_output.addFieldQuotedString("initializer", md->initializer());
       
  1520   
       
  1521   if (md->excpString())
       
  1522     m_output.addFieldQuotedString("exceptions", md->excpString());
       
  1523   
       
  1524   if (md->memberType()==MemberDef::Enumeration) // enum
       
  1525   {
       
  1526     LockingPtr<MemberList> enumFields = md->enumFieldList();
       
  1527     if (enumFields!=0)
       
  1528     {
       
  1529       m_output.openList("values");
       
  1530       MemberListIterator emli(*enumFields);
       
  1531       MemberDef *emd;
       
  1532       for (emli.toFirst();(emd=emli.current());++emli)
       
  1533       {
       
  1534 	m_output.openHash()
       
  1535 	  .addFieldQuotedString("name", emd->name());
       
  1536 	 
       
  1537 	if (!emd->initializer().isEmpty())
       
  1538 	  m_output.addFieldQuotedString("initializer", emd->initializer());
       
  1539 
       
  1540 	addPerlModDocBlock(m_output,"brief",emd->getDefFileName(),emd->getDefLine(),emd->getOuterScope(),emd,emd->briefDescription());
       
  1541 
       
  1542 	addPerlModDocBlock(m_output,"detailed",emd->getDefFileName(),emd->getDefLine(),emd->getOuterScope(),emd,emd->documentation());
       
  1543 
       
  1544 	m_output.closeHash();
       
  1545       }
       
  1546       m_output.closeList();
       
  1547     }
       
  1548   }
       
  1549 
       
  1550   MemberDef *rmd = md->reimplements();
       
  1551   if (rmd)
       
  1552     m_output.openHash("reimplements")
       
  1553       .addFieldQuotedString("name", rmd->name())
       
  1554       .closeHash();
       
  1555 
       
  1556   LockingPtr<MemberList> rbml = md->reimplementedBy();
       
  1557   if (rbml!=0)
       
  1558   {
       
  1559     MemberListIterator mli(*rbml);
       
  1560     m_output.openList("reimplemented_by");
       
  1561     for (mli.toFirst();(rmd=mli.current());++mli)
       
  1562       m_output.openHash()
       
  1563 	.addFieldQuotedString("name", rmd->name())
       
  1564 	.closeHash();
       
  1565     m_output.closeList();
       
  1566   }
       
  1567   
       
  1568   m_output.closeHash();
       
  1569 }
       
  1570 
       
  1571 void PerlModGenerator::generatePerlModSection(Definition *d,
       
  1572 					      MemberList *ml,const char *name,const char *header)
       
  1573 {
       
  1574   if (ml==0) return; // empty list
       
  1575 
       
  1576   m_output.openHash(name);
       
  1577 
       
  1578   if (header)
       
  1579     m_output.addFieldQuotedString("header", header);
       
  1580   
       
  1581   m_output.openList("members");
       
  1582   MemberListIterator mli(*ml);
       
  1583   MemberDef *md;
       
  1584   for (mli.toFirst();(md=mli.current());++mli)
       
  1585   {
       
  1586     generatePerlModForMember(md,d);
       
  1587   }
       
  1588   m_output.closeList()
       
  1589     .closeHash();
       
  1590 }
       
  1591 
       
  1592 void PerlModGenerator::addListOfAllMembers(ClassDef *cd)
       
  1593 {
       
  1594   m_output.openList("all_members");
       
  1595   if (cd->memberNameInfoSDict())
       
  1596   {
       
  1597     MemberNameInfoSDict::Iterator mnii(*cd->memberNameInfoSDict());
       
  1598     MemberNameInfo *mni;
       
  1599     for (mnii.toFirst();(mni=mnii.current());++mnii)
       
  1600     {
       
  1601       MemberNameInfoIterator mii(*mni);
       
  1602       MemberInfo *mi;
       
  1603       for (mii.toFirst();(mi=mii.current());++mii)
       
  1604       {
       
  1605         MemberDef *md=mi->memberDef;
       
  1606         ClassDef  *cd=md->getClassDef();
       
  1607         Definition *d=md->getGroupDef();
       
  1608         if (d==0) d = cd;
       
  1609 
       
  1610         m_output.openHash()
       
  1611           .addFieldQuotedString("name", md->name())
       
  1612           .addFieldQuotedString("virtualness", getVirtualnessName(md->virtualness()))
       
  1613           .addFieldQuotedString("protection", getProtectionName(mi->prot));
       
  1614 
       
  1615         if (!mi->ambiguityResolutionScope.isEmpty())
       
  1616           m_output.addFieldQuotedString("ambiguity_scope", mi->ambiguityResolutionScope);
       
  1617 
       
  1618         m_output.addFieldQuotedString("scope", cd->name())
       
  1619           .closeHash();
       
  1620       }
       
  1621     }
       
  1622   }
       
  1623   m_output.closeList();
       
  1624 }
       
  1625 
       
  1626 void PerlModGenerator::generatePerlModForClass(ClassDef *cd)
       
  1627 {
       
  1628   // + brief description
       
  1629   // + detailed description
       
  1630   // + template argument list(s)
       
  1631   // - include file
       
  1632   // + member groups
       
  1633   // + inheritance diagram
       
  1634   // + list of direct super classes
       
  1635   // + list of direct sub classes
       
  1636   // + list of inner classes
       
  1637   // + collaboration diagram
       
  1638   // + list of all members
       
  1639   // + user defined member sections
       
  1640   // + standard member sections
       
  1641   // + detailed member documentation
       
  1642   // - examples using the class
       
  1643   
       
  1644   if (cd->isReference())        return; // skip external references.
       
  1645   if (cd->name().find('@')!=-1) return; // skip anonymous compounds.
       
  1646   if (cd->templateMaster()!=0)  return; // skip generated template instances.
       
  1647 
       
  1648   m_output.openHash()
       
  1649     .addFieldQuotedString("name", cd->name());
       
  1650   
       
  1651   if (cd->baseClasses())
       
  1652   {
       
  1653     m_output.openList("base");
       
  1654     BaseClassListIterator bcli(*cd->baseClasses());
       
  1655     BaseClassDef *bcd;
       
  1656     for (bcli.toFirst();(bcd=bcli.current());++bcli)
       
  1657       m_output.openHash()
       
  1658 	.addFieldQuotedString("name", bcd->classDef->displayName())
       
  1659 	.addFieldQuotedString("virtualness", getVirtualnessName(bcd->virt))
       
  1660 	.addFieldQuotedString("protection", getProtectionName(bcd->prot))
       
  1661 	.closeHash();
       
  1662     m_output.closeList();
       
  1663   }
       
  1664 
       
  1665   if (cd->subClasses())
       
  1666   {
       
  1667     m_output.openList("derived");
       
  1668     BaseClassListIterator bcli(*cd->subClasses());
       
  1669     BaseClassDef *bcd;
       
  1670     for (bcli.toFirst();(bcd=bcli.current());++bcli)
       
  1671       m_output.openHash()
       
  1672 	.addFieldQuotedString("name", bcd->classDef->displayName())
       
  1673 	.addFieldQuotedString("virtualness", getVirtualnessName(bcd->virt))
       
  1674 	.addFieldQuotedString("protection", getProtectionName(bcd->prot))
       
  1675 	.closeHash();
       
  1676     m_output.closeList();
       
  1677   }
       
  1678 
       
  1679   ClassSDict *cl = cd->getInnerClasses();
       
  1680   if (cl)
       
  1681   {
       
  1682     m_output.openList("inner");
       
  1683     ClassSDict::Iterator cli(*cl);
       
  1684     ClassDef *cd;
       
  1685     for (cli.toFirst();(cd=cli.current());++cli)
       
  1686       m_output.openHash()
       
  1687 	.addFieldQuotedString("name", cd->name())
       
  1688 	.closeHash();
       
  1689     m_output.closeList();
       
  1690   }
       
  1691 
       
  1692   IncludeInfo *ii=cd->includeInfo();
       
  1693   if (ii)
       
  1694   {
       
  1695     QCString nm = ii->includeName;
       
  1696     if (nm.isEmpty() && ii->fileDef) nm = ii->fileDef->docName();
       
  1697     if (!nm.isEmpty())
       
  1698     {
       
  1699       m_output.openHash("includes");
       
  1700 #if 0
       
  1701       if (ii->fileDef && !ii->fileDef->isReference()) // TODO: support external references
       
  1702         t << " id=\"" << ii->fileDef->getOutputFileBase() << "\"";
       
  1703 #endif
       
  1704       m_output.addFieldBoolean("local", ii->local)
       
  1705 	.addFieldQuotedString("name", nm)
       
  1706 	.closeHash();
       
  1707     }
       
  1708   }
       
  1709 
       
  1710   addTemplateList(cd,m_output);
       
  1711   addListOfAllMembers(cd);
       
  1712   if (cd->getMemberGroupSDict())
       
  1713   {
       
  1714     MemberGroupSDict::Iterator mgli(*cd->getMemberGroupSDict());
       
  1715     MemberGroup *mg;
       
  1716     for (;(mg=mgli.current());++mgli)
       
  1717       generatePerlModSection(cd,mg->members(),"user_defined",mg->header());
       
  1718   }
       
  1719 
       
  1720   generatePerlModSection(cd,cd->getMemberList(MemberList::pubTypes),"public_typedefs");
       
  1721   generatePerlModSection(cd,cd->getMemberList(MemberList::pubMethods),"public_methods");
       
  1722   generatePerlModSection(cd,cd->getMemberList(MemberList::pubAttribs),"public_members");
       
  1723   generatePerlModSection(cd,cd->getMemberList(MemberList::pubSlots),"public_slots");
       
  1724   generatePerlModSection(cd,cd->getMemberList(MemberList::signals),"signals");
       
  1725   generatePerlModSection(cd,cd->getMemberList(MemberList::dcopMethods),"dcop_methods");
       
  1726   generatePerlModSection(cd,cd->getMemberList(MemberList::properties),"properties");
       
  1727   generatePerlModSection(cd,cd->getMemberList(MemberList::pubStaticMethods),"public_static_methods");
       
  1728   generatePerlModSection(cd,cd->getMemberList(MemberList::pubStaticAttribs),"public_static_members");
       
  1729   generatePerlModSection(cd,cd->getMemberList(MemberList::proTypes),"protected_typedefs");
       
  1730   generatePerlModSection(cd,cd->getMemberList(MemberList::proMethods),"protected_methods");
       
  1731   generatePerlModSection(cd,cd->getMemberList(MemberList::proAttribs),"protected_members");
       
  1732   generatePerlModSection(cd,cd->getMemberList(MemberList::proSlots),"protected_slots");
       
  1733   generatePerlModSection(cd,cd->getMemberList(MemberList::proStaticMethods),"protected_static_methods");
       
  1734   generatePerlModSection(cd,cd->getMemberList(MemberList::proStaticAttribs),"protected_static_members");
       
  1735   generatePerlModSection(cd,cd->getMemberList(MemberList::priTypes),"private_typedefs");
       
  1736   generatePerlModSection(cd,cd->getMemberList(MemberList::priMethods),"private_methods");
       
  1737   generatePerlModSection(cd,cd->getMemberList(MemberList::priAttribs),"private_members");
       
  1738   generatePerlModSection(cd,cd->getMemberList(MemberList::priSlots),"private_slots");
       
  1739   generatePerlModSection(cd,cd->getMemberList(MemberList::priStaticMethods),"private_static_methods");
       
  1740   generatePerlModSection(cd,cd->getMemberList(MemberList::priStaticAttribs),"private_static_members");
       
  1741   generatePerlModSection(cd,cd->getMemberList(MemberList::friends),"friend_methods");
       
  1742   generatePerlModSection(cd,cd->getMemberList(MemberList::related),"related_methods");
       
  1743 
       
  1744   addPerlModDocBlock(m_output,"brief",cd->getDefFileName(),cd->getDefLine(),cd,0,cd->briefDescription());
       
  1745   addPerlModDocBlock(m_output,"detailed",cd->getDefFileName(),cd->getDefLine(),cd,0,cd->documentation());
       
  1746 
       
  1747 #if 0
       
  1748   DotClassGraph inheritanceGraph(cd,DotClassGraph::Inheritance);
       
  1749   if (!inheritanceGraph.isTrivial())
       
  1750   {
       
  1751     t << "    <inheritancegraph>" << endl;
       
  1752     inheritanceGraph.writePerlMod(t);
       
  1753     t << "    </inheritancegraph>" << endl;
       
  1754   }
       
  1755   DotClassGraph collaborationGraph(cd,DotClassGraph::Implementation);
       
  1756   if (!collaborationGraph.isTrivial())
       
  1757   {
       
  1758     t << "    <collaborationgraph>" << endl;
       
  1759     collaborationGraph.writePerlMod(t);
       
  1760     t << "    </collaborationgraph>" << endl;
       
  1761   }
       
  1762   t << "    <location file=\"" 
       
  1763     << cd->getDefFileName() << "\" line=\"" 
       
  1764     << cd->getDefLine() << "\"";
       
  1765     if (cd->getStartBodyLine()!=-1)
       
  1766     {
       
  1767       t << " bodystart=\"" << cd->getStartBodyLine() << "\" bodyend=\"" 
       
  1768         << cd->getEndBodyLine() << "\"";
       
  1769     }
       
  1770   t << "/>" << endl;
       
  1771 #endif
       
  1772 
       
  1773   m_output.closeHash();
       
  1774 }
       
  1775 
       
  1776 void PerlModGenerator::generatePerlModForNamespace(NamespaceDef *nd)
       
  1777 {
       
  1778   // + contained class definitions
       
  1779   // + contained namespace definitions
       
  1780   // + member groups
       
  1781   // + normal members
       
  1782   // + brief desc
       
  1783   // + detailed desc
       
  1784   // + location
       
  1785   // - files containing (parts of) the namespace definition
       
  1786 
       
  1787   if (nd->isReference()) return; // skip external references
       
  1788 
       
  1789   m_output.openHash()
       
  1790     .addFieldQuotedString("name", nd->name());
       
  1791   
       
  1792   ClassSDict *cl = nd->getClassSDict();
       
  1793   if (cl)
       
  1794   {
       
  1795     m_output.openList("classes");
       
  1796     ClassSDict::Iterator cli(*cl);
       
  1797     ClassDef *cd;
       
  1798     for (cli.toFirst();(cd=cli.current());++cli)
       
  1799       m_output.openHash()
       
  1800 	.addFieldQuotedString("name", cd->name())
       
  1801 	.closeHash();
       
  1802     m_output.closeList();
       
  1803   }
       
  1804 
       
  1805   NamespaceSDict *nl = nd->getNamespaceSDict();
       
  1806   if (nl)
       
  1807   {
       
  1808     m_output.openList("namespaces");
       
  1809     NamespaceSDict::Iterator nli(*nl);
       
  1810     NamespaceDef *nd;
       
  1811     for (nli.toFirst();(nd=nli.current());++nli)
       
  1812       m_output.openHash()
       
  1813 	.addFieldQuotedString("name", nd->name())
       
  1814 	.closeHash();
       
  1815     m_output.closeList();
       
  1816   }
       
  1817 
       
  1818   if (nd->getMemberGroupSDict())
       
  1819   {
       
  1820     MemberGroupSDict::Iterator mgli(*nd->getMemberGroupSDict());
       
  1821     MemberGroup *mg;
       
  1822     for (;(mg=mgli.current());++mgli)
       
  1823       generatePerlModSection(nd,mg->members(),"user-defined",mg->header());
       
  1824   }
       
  1825 
       
  1826   generatePerlModSection(nd,nd->getMemberList(MemberList::decDefineMembers),"defines");
       
  1827   generatePerlModSection(nd,nd->getMemberList(MemberList::decProtoMembers),"prototypes");
       
  1828   generatePerlModSection(nd,nd->getMemberList(MemberList::decTypedefMembers),"typedefs");
       
  1829   generatePerlModSection(nd,nd->getMemberList(MemberList::decEnumMembers),"enums");
       
  1830   generatePerlModSection(nd,nd->getMemberList(MemberList::decFuncMembers),"functions");
       
  1831   generatePerlModSection(nd,nd->getMemberList(MemberList::decVarMembers),"variables");
       
  1832 
       
  1833   addPerlModDocBlock(m_output,"brief",nd->getDefFileName(),nd->getDefLine(),0,0,nd->briefDescription());
       
  1834   addPerlModDocBlock(m_output,"detailed",nd->getDefFileName(),nd->getDefLine(),0,0,nd->documentation());
       
  1835 
       
  1836   m_output.closeHash();
       
  1837 }
       
  1838 
       
  1839 void PerlModGenerator::generatePerlModForFile(FileDef *fd)
       
  1840 {
       
  1841   // + includes files
       
  1842   // + includedby files
       
  1843   // - include graph
       
  1844   // - included by graph
       
  1845   // - contained class definitions
       
  1846   // - contained namespace definitions
       
  1847   // - member groups
       
  1848   // + normal members
       
  1849   // + brief desc
       
  1850   // + detailed desc
       
  1851   // - source code
       
  1852   // - location
       
  1853   // - number of lines
       
  1854  
       
  1855   if (fd->isReference()) return;
       
  1856 
       
  1857   m_output.openHash()
       
  1858     .addFieldQuotedString("name", fd->name());
       
  1859   
       
  1860   IncludeInfo *inc;
       
  1861   m_output.openList("includes");
       
  1862   if (fd->includeFileList())
       
  1863   {
       
  1864     QListIterator<IncludeInfo> ili1(*fd->includeFileList());
       
  1865     for (ili1.toFirst();(inc=ili1.current());++ili1)
       
  1866     {
       
  1867       m_output.openHash()
       
  1868         .addFieldQuotedString("name", inc->includeName);
       
  1869       if (inc->fileDef && !inc->fileDef->isReference())
       
  1870       {
       
  1871         m_output.addFieldQuotedString("ref", inc->fileDef->getOutputFileBase());
       
  1872       }
       
  1873       m_output.closeHash();
       
  1874     }
       
  1875   }
       
  1876   m_output.closeList();
       
  1877   
       
  1878   m_output.openList("included_by");
       
  1879   if (fd->includedByFileList())
       
  1880   {
       
  1881     QListIterator<IncludeInfo> ili2(*fd->includedByFileList());
       
  1882     for (ili2.toFirst();(inc=ili2.current());++ili2)
       
  1883     {
       
  1884       m_output.openHash()
       
  1885         .addFieldQuotedString("name", inc->includeName);
       
  1886       if (inc->fileDef && !inc->fileDef->isReference())
       
  1887       {
       
  1888         m_output.addFieldQuotedString("ref", inc->fileDef->getOutputFileBase());
       
  1889       }
       
  1890       m_output.closeHash();
       
  1891     }
       
  1892   }
       
  1893   m_output.closeList();
       
  1894   
       
  1895   generatePerlModSection(fd,fd->getMemberList(MemberList::decDefineMembers),"defines");
       
  1896   generatePerlModSection(fd,fd->getMemberList(MemberList::decProtoMembers),"prototypes");
       
  1897   generatePerlModSection(fd,fd->getMemberList(MemberList::decTypedefMembers),"typedefs");
       
  1898   generatePerlModSection(fd,fd->getMemberList(MemberList::decEnumMembers),"enums");
       
  1899   generatePerlModSection(fd,fd->getMemberList(MemberList::decFuncMembers),"functions");
       
  1900   generatePerlModSection(fd,fd->getMemberList(MemberList::decVarMembers),"variables");
       
  1901 
       
  1902   addPerlModDocBlock(m_output,"brief",fd->getDefFileName(),fd->getDefLine(),0,0,fd->briefDescription());
       
  1903   addPerlModDocBlock(m_output,"detailed",fd->getDefFileName(),fd->getDefLine(),0,0,fd->documentation());
       
  1904 
       
  1905   m_output.closeHash();
       
  1906 }
       
  1907 
       
  1908 void PerlModGenerator::generatePerlModForGroup(GroupDef *gd)
       
  1909 {
       
  1910   // + members
       
  1911   // + member groups
       
  1912   // + files
       
  1913   // + classes
       
  1914   // + namespaces
       
  1915   // - packages
       
  1916   // + pages
       
  1917   // + child groups
       
  1918   // - examples
       
  1919   // + brief description
       
  1920   // + detailed description
       
  1921 
       
  1922   if (gd->isReference()) return; // skip external references
       
  1923 
       
  1924   m_output.openHash()
       
  1925     .addFieldQuotedString("name", gd->name())
       
  1926     .addFieldQuotedString("title", gd->groupTitle());
       
  1927 
       
  1928   FileList *fl = gd->getFiles();
       
  1929   if (fl)
       
  1930   {
       
  1931     m_output.openList("files");
       
  1932     QListIterator<FileDef> fli(*fl);
       
  1933     FileDef *fd = fl->first();
       
  1934     for (fli.toFirst();(fd=fli.current());++fli)
       
  1935       m_output.openHash()
       
  1936 	.addFieldQuotedString("name", fd->name())
       
  1937 	.closeHash();
       
  1938     m_output.closeList();
       
  1939   }
       
  1940 
       
  1941   ClassSDict *cl = gd->getClasses();
       
  1942   if (cl)
       
  1943   {
       
  1944     m_output.openList("classes");
       
  1945     ClassSDict::Iterator cli(*cl);
       
  1946     ClassDef *cd;
       
  1947     for (cli.toFirst();(cd=cli.current());++cli)
       
  1948       m_output.openHash()
       
  1949 	.addFieldQuotedString("name", cd->name())
       
  1950 	.closeHash();
       
  1951     m_output.closeList();
       
  1952   }
       
  1953 
       
  1954   NamespaceSDict *nl = gd->getNamespaces();
       
  1955   if (nl)
       
  1956   {
       
  1957     m_output.openList("namespaces");
       
  1958     NamespaceSDict::Iterator nli(*nl);
       
  1959     NamespaceDef *nd;
       
  1960     for (nli.toFirst();(nd=nli.current());++nli)
       
  1961       m_output.openHash()
       
  1962 	.addFieldQuotedString("name", nd->name())
       
  1963 	.closeHash();
       
  1964     m_output.closeList();
       
  1965   }
       
  1966 
       
  1967   PageSDict *pl = gd->getPages();
       
  1968   if (pl)
       
  1969   {
       
  1970     m_output.openList("pages");
       
  1971     PageSDict::Iterator pli(*pl);
       
  1972     PageDef *pd;
       
  1973     for (pli.toFirst();(pd=pli.current());++pli)
       
  1974       m_output.openHash()
       
  1975 	.addFieldQuotedString("title", pd->title())
       
  1976 	.closeHash();
       
  1977     m_output.closeList();
       
  1978   }
       
  1979 
       
  1980   GroupList *gl = gd->getSubGroups();
       
  1981   if (gl)
       
  1982   {
       
  1983     m_output.openList("groups");
       
  1984     GroupListIterator gli(*gl);
       
  1985     GroupDef *sgd;
       
  1986     for (gli.toFirst();(sgd=gli.current());++gli)
       
  1987       m_output.openHash()
       
  1988 	.addFieldQuotedString("title", sgd->groupTitle())
       
  1989 	.closeHash();
       
  1990     m_output.closeList();
       
  1991   }
       
  1992 
       
  1993   if (gd->getMemberGroupSDict())
       
  1994   {
       
  1995     MemberGroupSDict::Iterator mgli(*gd->getMemberGroupSDict());
       
  1996     MemberGroup *mg;
       
  1997     for (;(mg=mgli.current());++mgli)
       
  1998       generatePerlModSection(gd,mg->members(),"user-defined",mg->header());
       
  1999   }
       
  2000 
       
  2001   generatePerlModSection(gd,gd->getMemberList(MemberList::decDefineMembers),"defines");
       
  2002   generatePerlModSection(gd,gd->getMemberList(MemberList::decProtoMembers),"prototypes");
       
  2003   generatePerlModSection(gd,gd->getMemberList(MemberList::decTypedefMembers),"typedefs");
       
  2004   generatePerlModSection(gd,gd->getMemberList(MemberList::decEnumMembers),"enums");
       
  2005   generatePerlModSection(gd,gd->getMemberList(MemberList::decFuncMembers),"functions");
       
  2006   generatePerlModSection(gd,gd->getMemberList(MemberList::decVarMembers),"variables");
       
  2007 
       
  2008   addPerlModDocBlock(m_output,"brief",gd->getDefFileName(),gd->getDefLine(),0,0,gd->briefDescription());
       
  2009   addPerlModDocBlock(m_output,"detailed",gd->getDefFileName(),gd->getDefLine(),0,0,gd->documentation());
       
  2010 
       
  2011   m_output.closeHash();
       
  2012 }
       
  2013 
       
  2014 void PerlModGenerator::generatePerlModForPage(PageDef *pd)
       
  2015 {
       
  2016   // + name
       
  2017   // + title
       
  2018   // + documentation
       
  2019 
       
  2020   if (pd->isReference()) return;
       
  2021 
       
  2022   m_output.openHash()
       
  2023     .addFieldQuotedString("name", pd->name());
       
  2024     
       
  2025   SectionInfo *si = Doxygen::sectionDict.find(pd->name());
       
  2026   if (si)
       
  2027     m_output.addFieldQuotedString("title", si->title);
       
  2028 
       
  2029   addPerlModDocBlock(m_output,"detailed",pd->docFile(),pd->docLine(),0,0,pd->documentation());
       
  2030   m_output.closeHash();
       
  2031 }
       
  2032 
       
  2033 bool PerlModGenerator::generatePerlModOutput()
       
  2034 {
       
  2035   QFile outputFile;
       
  2036   if (!createOutputFile(outputFile, pathDoxyDocsPM))
       
  2037     return false;
       
  2038   
       
  2039   QTextStream outputTextStream(&outputFile);
       
  2040   PerlModOutputStream outputStream(&outputTextStream);
       
  2041   m_output.setPerlModOutputStream(&outputStream);
       
  2042   m_output.add("$doxydocs=").openHash();
       
  2043   
       
  2044   m_output.openList("classes");
       
  2045   ClassSDict::Iterator cli(*Doxygen::classSDict);
       
  2046   ClassDef *cd;
       
  2047   for (cli.toFirst();(cd=cli.current());++cli)
       
  2048     generatePerlModForClass(cd);
       
  2049   m_output.closeList();
       
  2050 
       
  2051   m_output.openList("namespaces");
       
  2052   NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict);
       
  2053   NamespaceDef *nd;
       
  2054   for (nli.toFirst();(nd=nli.current());++nli)
       
  2055     generatePerlModForNamespace(nd);
       
  2056   m_output.closeList();
       
  2057 
       
  2058   m_output.openList("files");
       
  2059   FileNameListIterator fnli(*Doxygen::inputNameList);
       
  2060   FileName *fn;
       
  2061   for (;(fn=fnli.current());++fnli)
       
  2062   {
       
  2063     FileNameIterator fni(*fn);
       
  2064     FileDef *fd;
       
  2065     for (;(fd=fni.current());++fni)
       
  2066       generatePerlModForFile(fd);
       
  2067   }
       
  2068   m_output.closeList();
       
  2069 
       
  2070   m_output.openList("groups");
       
  2071   GroupSDict::Iterator gli(*Doxygen::groupSDict);
       
  2072   GroupDef *gd;
       
  2073   for (;(gd=gli.current());++gli)
       
  2074   {
       
  2075     generatePerlModForGroup(gd);
       
  2076   }
       
  2077   m_output.closeList();
       
  2078 
       
  2079   m_output.openList("pages");
       
  2080   PageSDict::Iterator pdi(*Doxygen::pageSDict);
       
  2081   PageDef *pd=0;
       
  2082   for (pdi.toFirst();(pd=pdi.current());++pdi)
       
  2083   {
       
  2084     generatePerlModForPage(pd);
       
  2085   }
       
  2086   if (Doxygen::mainPage)
       
  2087   {
       
  2088     generatePerlModForPage(Doxygen::mainPage);
       
  2089   }
       
  2090   m_output.closeList();
       
  2091 
       
  2092   m_output.closeHash().add(";\n1;\n");
       
  2093   return true;
       
  2094 }
       
  2095 
       
  2096 bool PerlModGenerator::createOutputFile(QFile &f, const char *s)
       
  2097 {
       
  2098   f.setName(s);
       
  2099   if (!f.open(IO_WriteOnly))
       
  2100   {
       
  2101     err("Cannot open file %s for writing!\n", s);
       
  2102     return false;
       
  2103   }
       
  2104   return true;
       
  2105 }
       
  2106 
       
  2107 bool PerlModGenerator::createOutputDir(QDir &perlModDir)
       
  2108 {
       
  2109   QCString outputDirectory = Config_getString("OUTPUT_DIRECTORY");
       
  2110   if (outputDirectory.isEmpty())
       
  2111   {
       
  2112     outputDirectory=QDir::currentDirPath();
       
  2113   }
       
  2114   else
       
  2115   {
       
  2116     QDir dir(outputDirectory);
       
  2117     if (!dir.exists())
       
  2118     {
       
  2119       dir.setPath(QDir::currentDirPath());
       
  2120       if (!dir.mkdir(outputDirectory))
       
  2121       {
       
  2122 	err("Error: tag OUTPUT_DIRECTORY: Output directory `%s' does not "
       
  2123 	    "exist and cannot be created\n",outputDirectory.data());
       
  2124 	exit(1);
       
  2125       }
       
  2126       else if (!Config_getBool("QUIET"))
       
  2127       {
       
  2128 	err("Notice: Output directory `%s' does not exist. "
       
  2129 	    "I have created it for you.\n", outputDirectory.data());
       
  2130       }
       
  2131       dir.cd(outputDirectory);
       
  2132     }
       
  2133     outputDirectory=dir.absPath();
       
  2134   }
       
  2135 
       
  2136   QDir dir(outputDirectory);
       
  2137   if (!dir.exists())
       
  2138   {
       
  2139     dir.setPath(QDir::currentDirPath());
       
  2140     if (!dir.mkdir(outputDirectory))
       
  2141     {
       
  2142       err("Cannot create directory %s\n",outputDirectory.data());
       
  2143       return false;
       
  2144     }
       
  2145   }
       
  2146  
       
  2147   perlModDir.setPath(outputDirectory+"/perlmod");
       
  2148   if (!perlModDir.exists() && !perlModDir.mkdir(outputDirectory+"/perlmod"))
       
  2149   {
       
  2150     err("Could not create perlmod directory in %s\n",outputDirectory.data());
       
  2151     return false;
       
  2152   }
       
  2153   return true;
       
  2154 }
       
  2155 
       
  2156 bool PerlModGenerator::generateDoxyStructurePM()
       
  2157 {
       
  2158   QFile doxyModelPM;
       
  2159   if (!createOutputFile(doxyModelPM, pathDoxyStructurePM))
       
  2160     return false;
       
  2161 
       
  2162   QTextStream doxyModelPMStream(&doxyModelPM);
       
  2163   doxyModelPMStream << 
       
  2164     "sub memberlist($) {\n"
       
  2165     "    my $prefix = $_[0];\n"
       
  2166     "    return\n"
       
  2167     "\t[ \"hash\", $prefix . \"s\",\n"
       
  2168     "\t  {\n"
       
  2169     "\t    members =>\n"
       
  2170     "\t      [ \"list\", $prefix . \"List\",\n"
       
  2171     "\t\t[ \"hash\", $prefix,\n"
       
  2172     "\t\t  {\n"
       
  2173     "\t\t    kind => [ \"string\", $prefix . \"Kind\" ],\n"
       
  2174     "\t\t    name => [ \"string\", $prefix . \"Name\" ],\n"
       
  2175     "\t\t    static => [ \"string\", $prefix . \"Static\" ],\n"
       
  2176     "\t\t    virtualness => [ \"string\", $prefix . \"Virtualness\" ],\n"
       
  2177     "\t\t    protection => [ \"string\", $prefix . \"Protection\" ],\n"
       
  2178     "\t\t    type => [ \"string\", $prefix . \"Type\" ],\n"
       
  2179     "\t\t    parameters =>\n"
       
  2180     "\t\t      [ \"list\", $prefix . \"Params\",\n"
       
  2181     "\t\t\t[ \"hash\", $prefix . \"Param\",\n"
       
  2182     "\t\t\t  {\n"
       
  2183     "\t\t\t    declaration_name => [ \"string\", $prefix . \"ParamName\" ],\n"
       
  2184     "\t\t\t    type => [ \"string\", $prefix . \"ParamType\" ],\n"
       
  2185     "\t\t\t  },\n"
       
  2186     "\t\t\t],\n"
       
  2187     "\t\t      ],\n"
       
  2188     "\t\t    detailed =>\n"
       
  2189     "\t\t      [ \"hash\", $prefix . \"Detailed\",\n"
       
  2190     "\t\t\t{\n"
       
  2191     "\t\t\t  doc => [ \"doc\", $prefix . \"DetailedDoc\" ],\n"
       
  2192     "\t\t\t  return => [ \"doc\", $prefix . \"Return\" ],\n"
       
  2193     "\t\t\t  see => [ \"doc\", $prefix . \"See\" ],\n"
       
  2194     "\t\t\t  params =>\n"
       
  2195     "\t\t\t    [ \"list\", $prefix . \"PDBlocks\",\n"
       
  2196     "\t\t\t      [ \"hash\", $prefix . \"PDBlock\",\n"
       
  2197     "\t\t\t\t{\n"
       
  2198     "\t\t\t\t  parameters =>\n"
       
  2199     "\t\t\t\t    [ \"list\", $prefix . \"PDParams\",\n"
       
  2200     "\t\t\t\t      [ \"hash\", $prefix . \"PDParam\",\n"
       
  2201     "\t\t\t\t\t{\n"
       
  2202     "\t\t\t\t\t  name => [ \"string\", $prefix . \"PDParamName\" ],\n"
       
  2203     "\t\t\t\t\t},\n"
       
  2204     "\t\t\t\t      ],\n"
       
  2205     "\t\t\t\t    ],\n"
       
  2206     "\t\t\t\t  doc => [ \"doc\", $prefix . \"PDDoc\" ],\n"
       
  2207     "\t\t\t\t},\n"
       
  2208     "\t\t\t      ],\n"
       
  2209     "\t\t\t    ],\n"
       
  2210     "\t\t\t},\n"
       
  2211     "\t\t      ],\n"
       
  2212     "\t\t  },\n"
       
  2213     "\t\t],\n"
       
  2214     "\t      ],\n"
       
  2215     "\t  },\n"
       
  2216     "\t];\n"
       
  2217     "}\n"
       
  2218     "\n"
       
  2219     "$doxystructure =\n"
       
  2220     "    [ \"hash\", \"Root\",\n"
       
  2221     "      {\n"
       
  2222     "\tfiles =>\n"
       
  2223     "\t  [ \"list\", \"Files\",\n"
       
  2224     "\t    [ \"hash\", \"File\",\n"
       
  2225     "\t      {\n"
       
  2226     "\t\tname => [ \"string\", \"FileName\" ],\n"
       
  2227     "\t\ttypedefs => memberlist(\"FileTypedef\"),\n"
       
  2228     "\t\tvariables => memberlist(\"FileVariable\"),\n"
       
  2229     "\t\tfunctions => memberlist(\"FileFunction\"),\n"
       
  2230     "\t\tdetailed =>\n"
       
  2231     "\t\t  [ \"hash\", \"FileDetailed\",\n"
       
  2232     "\t\t    {\n"
       
  2233     "\t\t      doc => [ \"doc\", \"FileDetailedDoc\" ],\n"
       
  2234     "\t\t    },\n"
       
  2235     "\t\t  ],\n"
       
  2236     "\t      },\n"
       
  2237     "\t    ],\n"
       
  2238     "\t  ],\n"
       
  2239     "\tpages =>\n"
       
  2240     "\t  [ \"list\", \"Pages\",\n"
       
  2241     "\t    [ \"hash\", \"Page\",\n"
       
  2242     "\t      {\n"
       
  2243     "\t\tname => [ \"string\", \"PageName\" ],\n"
       
  2244     "\t\tdetailed =>\n"
       
  2245     "\t\t  [ \"hash\", \"PageDetailed\",\n"
       
  2246     "\t\t    {\n"
       
  2247     "\t\t      doc => [ \"doc\", \"PageDetailedDoc\" ],\n"
       
  2248     "\t\t    },\n"
       
  2249     "\t\t  ],\n"
       
  2250     "\t      },\n"
       
  2251     "\t    ],\n"
       
  2252     "\t  ],\n"
       
  2253     "\tclasses =>\n"
       
  2254     "\t  [ \"list\", \"Classes\",\n"
       
  2255     "\t    [ \"hash\", \"Class\",\n"
       
  2256     "\t      {\n"
       
  2257     "\t\tname => [ \"string\", \"ClassName\" ],\n"
       
  2258     "\t\tpublic_typedefs => memberlist(\"ClassPublicTypedef\"),\n"
       
  2259     "\t\tpublic_methods => memberlist(\"ClassPublicMethod\"),\n"
       
  2260     "\t\tpublic_members => memberlist(\"ClassPublicMember\"),\n"
       
  2261     "\t\tprotected_typedefs => memberlist(\"ClassProtectedTypedef\"),\n"
       
  2262     "\t\tprotected_methods => memberlist(\"ClassProtectedMethod\"),\n"
       
  2263     "\t\tprotected_members => memberlist(\"ClassProtectedMember\"),\n"
       
  2264     "\t\tprivate_typedefs => memberlist(\"ClassPrivateTypedef\"),\n"
       
  2265     "\t\tprivate_methods => memberlist(\"ClassPrivateMethod\"),\n"
       
  2266     "\t\tprivate_members => memberlist(\"ClassPrivateMember\"),\n"
       
  2267     "\t\tdetailed =>\n"
       
  2268     "\t\t  [ \"hash\", \"ClassDetailed\",\n"
       
  2269     "\t\t    {\n"
       
  2270     "\t\t      doc => [ \"doc\", \"ClassDetailedDoc\" ],\n"
       
  2271     "\t\t    },\n"
       
  2272     "\t\t  ],\n"
       
  2273     "\t      },\n"
       
  2274     "\t    ],\n"
       
  2275     "\t  ],\n"
       
  2276     "\tgroups =>\n"
       
  2277     "\t  [ \"list\", \"Groups\",\n"
       
  2278     "\t    [ \"hash\", \"Group\",\n"
       
  2279     "\t      {\n"
       
  2280     "\t\tname => [ \"string\", \"GroupName\" ],\n"
       
  2281     "\t\ttitle => [ \"string\", \"GroupTitle\" ],\n"
       
  2282     "\t\tfiles =>\n"
       
  2283     "\t\t  [ \"list\", \"Files\",\n"
       
  2284     "\t\t    [ \"hash\", \"File\",\n"
       
  2285     "\t\t      {\n"
       
  2286     "\t\t        name => [ \"string\", \"Filename\" ]\n"
       
  2287     "\t\t      }\n"
       
  2288     "\t\t    ],\n"
       
  2289     "\t\t  ],\n"
       
  2290     "\t\tclasses  =>\n"
       
  2291     "\t\t  [ \"list\", \"Classes\",\n"
       
  2292     "\t\t    [ \"hash\", \"Class\",\n"
       
  2293     "\t\t      {\n" 
       
  2294     "\t\t        name => [ \"string\", \"Classname\" ]\n"
       
  2295     "\t\t      }\n"
       
  2296     "\t\t    ],\n"
       
  2297     "\t\t  ],\n"
       
  2298     "\t\tnamespaces =>\n"
       
  2299     "\t\t  [ \"list\", \"Namespaces\",\n"
       
  2300     "\t\t    [ \"hash\", \"Namespace\",\n"
       
  2301     "\t\t      {\n" 
       
  2302     "\t\t        name => [ \"string\", \"NamespaceName\" ]\n"
       
  2303     "\t\t      }\n"
       
  2304     "\t\t    ],\n"
       
  2305     "\t\t  ],\n"
       
  2306     "\t\tpages =>\n"
       
  2307     "\t\t  [ \"list\", \"Pages\",\n"
       
  2308     "\t\t    [ \"hash\", \"Page\","
       
  2309     "\t\t      {\n"
       
  2310     "\t\t        title => [ \"string\", \"PageName\" ]\n"
       
  2311     "\t\t      }\n"
       
  2312     "\t\t    ],\n"
       
  2313     "\t\t  ],\n"
       
  2314     "\t\tgroups =>\n"
       
  2315     "\t\t  [ \"list\", \"Groups\",\n"
       
  2316     "\t\t    [ \"hash\", \"Group\",\n"
       
  2317     "\t\t      {\n"
       
  2318     "\t\t        title => [ \"string\", \"GroupName\" ]\n"
       
  2319     "\t\t      }\n"
       
  2320     "\t\t    ],\n"
       
  2321     "\t\t  ],\n"
       
  2322     "\t\tfunctions => memberlist(\"GroupFunction\"),\n"
       
  2323     "\t\tdetailed =>\n"
       
  2324     "\t\t  [ \"hash\", \"GroupDetailed\",\n"
       
  2325     "\t\t    {\n"
       
  2326     "\t\t      doc => [ \"doc\", \"GroupDetailedDoc\" ],\n"
       
  2327     "\t\t    },\n"
       
  2328     "\t\t  ],\n"
       
  2329     "\t      }\n"
       
  2330     "\t    ],\n"
       
  2331     "\t  ],\n"
       
  2332     "      },\n"
       
  2333     "    ];\n"
       
  2334     "\n"
       
  2335     "1;\n";
       
  2336 
       
  2337   return true;
       
  2338 }
       
  2339 
       
  2340 bool PerlModGenerator::generateDoxyRules()
       
  2341 {
       
  2342   QFile doxyRules;
       
  2343   if (!createOutputFile(doxyRules, pathDoxyRules))
       
  2344     return false;
       
  2345 
       
  2346   bool perlmodLatex = Config_getBool("PERLMOD_LATEX");
       
  2347   QString prefix = Config_getString("PERLMOD_MAKEVAR_PREFIX");
       
  2348 
       
  2349   QTextStream doxyRulesStream(&doxyRules);
       
  2350   doxyRulesStream <<
       
  2351     prefix << "DOXY_EXEC_PATH = " << pathDoxyExec << "\n" <<
       
  2352     prefix << "DOXYFILE = " << pathDoxyfile << "\n" <<
       
  2353     prefix << "DOXYDOCS_PM = " << pathDoxyDocsPM << "\n" <<
       
  2354     prefix << "DOXYSTRUCTURE_PM = " << pathDoxyStructurePM << "\n" <<
       
  2355     prefix << "DOXYRULES = " << pathDoxyRules << "\n";
       
  2356   if (perlmodLatex)
       
  2357     doxyRulesStream <<
       
  2358       prefix << "DOXYLATEX_PL = " << pathDoxyLatexPL << "\n" <<
       
  2359       prefix << "DOXYLATEXSTRUCTURE_PL = " << pathDoxyLatexStructurePL << "\n" <<
       
  2360       prefix << "DOXYSTRUCTURE_TEX = " << pathDoxyStructureTex << "\n" <<
       
  2361       prefix << "DOXYDOCS_TEX = " << pathDoxyDocsTex << "\n" <<
       
  2362       prefix << "DOXYFORMAT_TEX = " << pathDoxyFormatTex << "\n" <<
       
  2363       prefix << "DOXYLATEX_TEX = " << pathDoxyLatexTex << "\n" <<
       
  2364       prefix << "DOXYLATEX_DVI = " << pathDoxyLatexDVI << "\n" <<
       
  2365       prefix << "DOXYLATEX_PDF = " << pathDoxyLatexPDF << "\n";
       
  2366 
       
  2367   doxyRulesStream <<
       
  2368     "\n"
       
  2369     ".PHONY: clean-perlmod\n"
       
  2370     "clean-perlmod::\n"
       
  2371     "\trm -f $(" << prefix << "DOXYSTRUCTURE_PM) \\\n"
       
  2372     "\t$(" << prefix << "DOXYDOCS_PM)";
       
  2373   if (perlmodLatex)
       
  2374     doxyRulesStream <<
       
  2375       " \\\n"
       
  2376       "\t$(" << prefix << "DOXYLATEX_PL) \\\n"
       
  2377       "\t$(" << prefix << "DOXYLATEXSTRUCTURE_PL) \\\n"
       
  2378       "\t$(" << prefix << "DOXYDOCS_TEX) \\\n"
       
  2379       "\t$(" << prefix << "DOXYSTRUCTURE_TEX) \\\n"
       
  2380       "\t$(" << prefix << "DOXYFORMAT_TEX) \\\n"
       
  2381       "\t$(" << prefix << "DOXYLATEX_TEX) \\\n"
       
  2382       "\t$(" << prefix << "DOXYLATEX_PDF) \\\n"
       
  2383       "\t$(" << prefix << "DOXYLATEX_DVI) \\\n"
       
  2384       "\t$(addprefix $(" << prefix << "DOXYLATEX_TEX:tex=),out aux log)";
       
  2385   doxyRulesStream << "\n\n";
       
  2386 
       
  2387   doxyRulesStream <<
       
  2388     "$(" << prefix << "DOXYRULES) \\\n"
       
  2389     "$(" << prefix << "DOXYMAKEFILE) \\\n"
       
  2390     "$(" << prefix << "DOXYSTRUCTURE_PM) \\\n"
       
  2391     "$(" << prefix << "DOXYDOCS_PM)";
       
  2392   if (perlmodLatex) {
       
  2393     doxyRulesStream <<
       
  2394       " \\\n"
       
  2395       "$(" << prefix << "DOXYLATEX_PL) \\\n"
       
  2396       "$(" << prefix << "DOXYLATEXSTRUCTURE_PL) \\\n"
       
  2397       "$(" << prefix << "DOXYFORMAT_TEX) \\\n"
       
  2398       "$(" << prefix << "DOXYLATEX_TEX)";
       
  2399   }
       
  2400   doxyRulesStream <<
       
  2401     ": \\\n"
       
  2402     "\t$(" << prefix << "DOXYFILE)\n"
       
  2403     "\tcd $(" << prefix << "DOXY_EXEC_PATH) ; doxygen \"$<\"\n";
       
  2404 
       
  2405   if (perlmodLatex) {
       
  2406     doxyRulesStream <<
       
  2407       "\n"
       
  2408       "$(" << prefix << "DOXYDOCS_TEX): \\\n"
       
  2409       "$(" << prefix << "DOXYLATEX_PL) \\\n"
       
  2410       "$(" << prefix << "DOXYDOCS_PM)\n"
       
  2411       "\tperl -I\"$(<D)\" \"$<\" >\"$@\"\n"
       
  2412       "\n"
       
  2413       "$(" << prefix << "DOXYSTRUCTURE_TEX): \\\n"
       
  2414       "$(" << prefix << "DOXYLATEXSTRUCTURE_PL) \\\n"
       
  2415       "$(" << prefix << "DOXYSTRUCTURE_PM)\n"
       
  2416       "\tperl -I\"$(<D)\" \"$<\" >\"$@\"\n"
       
  2417       "\n"
       
  2418       "$(" << prefix << "DOXYLATEX_PDF) \\\n"
       
  2419       "$(" << prefix << "DOXYLATEX_DVI): \\\n"
       
  2420       "$(" << prefix << "DOXYLATEX_TEX) \\\n"
       
  2421       "$(" << prefix << "DOXYFORMAT_TEX) \\\n"
       
  2422       "$(" << prefix << "DOXYSTRUCTURE_TEX) \\\n"
       
  2423       "$(" << prefix << "DOXYDOCS_TEX)\n"
       
  2424       "\n"
       
  2425       "$(" << prefix << "DOXYLATEX_PDF): \\\n"
       
  2426       "$(" << prefix << "DOXYLATEX_TEX)\n"
       
  2427       "\tpdflatex -interaction=nonstopmode \"$<\"\n"
       
  2428       "\n"
       
  2429       "$(" << prefix << "DOXYLATEX_DVI): \\\n"
       
  2430       "$(" << prefix << "DOXYLATEX_TEX)\n"
       
  2431       "\tlatex -interaction=nonstopmode \"$<\"\n";
       
  2432   }
       
  2433 
       
  2434   return true;
       
  2435 }
       
  2436 
       
  2437 bool PerlModGenerator::generateMakefile()
       
  2438 {
       
  2439   QFile makefile;
       
  2440   if (!createOutputFile(makefile, pathMakefile))
       
  2441     return false;
       
  2442 
       
  2443   bool perlmodLatex = Config_getBool("PERLMOD_LATEX");
       
  2444   QString prefix = Config_getString("PERLMOD_MAKEVAR_PREFIX");
       
  2445 
       
  2446   QTextStream makefileStream(&makefile);
       
  2447   makefileStream <<
       
  2448     ".PHONY: default clean" << (perlmodLatex ? " pdf" : "") << "\n"
       
  2449     "default: " << (perlmodLatex ? "pdf" : "clean") << "\n"
       
  2450     "\n"
       
  2451     "include " << pathDoxyRules << "\n"
       
  2452     "\n"
       
  2453     "clean: clean-perlmod\n";
       
  2454 
       
  2455   if (perlmodLatex) {
       
  2456     makefileStream <<
       
  2457       "pdf: $(" << prefix << "DOXYLATEX_PDF)\n"
       
  2458       "dvi: $(" << prefix << "DOXYLATEX_DVI)\n";
       
  2459   }
       
  2460 
       
  2461   return true;
       
  2462 }
       
  2463 
       
  2464 bool PerlModGenerator::generateDoxyLatexStructurePL()
       
  2465 {
       
  2466   QFile doxyLatexStructurePL;
       
  2467   if (!createOutputFile(doxyLatexStructurePL, pathDoxyLatexStructurePL))
       
  2468     return false;
       
  2469 
       
  2470   QTextStream doxyLatexStructurePLStream(&doxyLatexStructurePL);
       
  2471   doxyLatexStructurePLStream << 
       
  2472     "use DoxyStructure;\n"
       
  2473     "\n"
       
  2474     "sub process($) {\n"
       
  2475     "\tmy $node = $_[0];\n"
       
  2476     "\tmy ($type, $name) = @$node[0, 1];\n"
       
  2477     "\tmy $command;\n"
       
  2478     "\tif ($type eq \"string\") { $command = \"String\" }\n"
       
  2479     "\telsif ($type eq \"doc\") { $command = \"Doc\" }\n"
       
  2480     "\telsif ($type eq \"hash\") {\n"
       
  2481     "\t\t$command = \"Hash\";\n"
       
  2482     "\t\tfor my $subnode (values %{$$node[2]}) {\n"
       
  2483     "\t\t\tprocess($subnode);\n"
       
  2484     "\t\t}\n"
       
  2485     "\t}\n"
       
  2486     "\telsif ($type eq \"list\") {\n"
       
  2487     "\t\t$command = \"List\";\n"
       
  2488     "\t\tprocess($$node[2]);\n"
       
  2489     "\t}\n"
       
  2490     "\tprint \"\\\\\" . $command . \"Node{\" . $name . \"}%\\n\";\n"
       
  2491     "}\n"
       
  2492     "\n"
       
  2493     "process($doxystructure);\n";
       
  2494 
       
  2495   return true;
       
  2496 }
       
  2497 
       
  2498 bool PerlModGenerator::generateDoxyLatexPL()
       
  2499 {
       
  2500   QFile doxyLatexPL;
       
  2501   if (!createOutputFile(doxyLatexPL, pathDoxyLatexPL))
       
  2502     return false;
       
  2503 
       
  2504   QTextStream doxyLatexPLStream(&doxyLatexPL);
       
  2505   doxyLatexPLStream << 
       
  2506     "use DoxyStructure;\n"
       
  2507     "use DoxyDocs;\n"
       
  2508     "\n"
       
  2509     "sub latex_quote($) {\n"
       
  2510     "\tmy $text = $_[0];\n"
       
  2511     "\t$text =~ s/\\\\/\\\\textbackslash /g;\n"
       
  2512     "\t$text =~ s/\\|/\\\\textbar /g;\n"
       
  2513     "\t$text =~ s/</\\\\textless /g;\n"
       
  2514     "\t$text =~ s/>/\\\\textgreater /g;\n"
       
  2515     "\t$text =~ s/~/\\\\textasciitilde /g;\n"
       
  2516     "\t$text =~ s/\\^/\\\\textasciicircum /g;\n"
       
  2517     "\t$text =~ s/[\\$&%#_{}]/\\\\$&/g;\n"
       
  2518     "\tprint $text;\n"
       
  2519     "}\n"
       
  2520     "\n"
       
  2521     "sub generate_doc($) {\n"
       
  2522     "\tmy $doc = $_[0];\n"
       
  2523     "\tfor my $item (@$doc) {\n"
       
  2524     "\t\tmy $type = $$item{type};\n"
       
  2525     "\t\tif ($type eq \"text\") {\n"
       
  2526     "\t\t\tlatex_quote($$item{content});\n"
       
  2527     "\t\t} elsif ($type eq \"parbreak\") {\n"
       
  2528     "\t\t\tprint \"\\n\\n\";\n"
       
  2529     "\t\t} elsif ($type eq \"style\") {\n"
       
  2530     "\t\t\tmy $style = $$item{style};\n"
       
  2531     "\t\t\tif ($$item{enable} eq \"yes\") {\n"
       
  2532     "\t\t\t\tif ($style eq \"bold\") { print '\\bfseries'; }\n"
       
  2533     "\t\t\t\tif ($style eq \"italic\") { print '\\itshape'; }\n"
       
  2534     "\t\t\t\tif ($style eq \"code\") { print '\\ttfamily'; }\n"
       
  2535     "\t\t\t} else {\n"
       
  2536     "\t\t\t\tif ($style eq \"bold\") { print '\\mdseries'; }\n"
       
  2537     "\t\t\t\tif ($style eq \"italic\") { print '\\upshape'; }\n"
       
  2538     "\t\t\t\tif ($style eq \"code\") { print '\\rmfamily'; }\n"
       
  2539     "\t\t\t}\n"
       
  2540     "\t\t\tprint '{}';\n"
       
  2541     "\t\t} elsif ($type eq \"symbol\") {\n"
       
  2542     "\t\t\tmy $symbol = $$item{symbol};\n"
       
  2543     "\t\t\tif ($symbol eq \"copyright\") { print '\\copyright'; }\n"
       
  2544     "\t\t\telsif ($symbol eq \"szlig\") { print '\\ss'; }\n"
       
  2545     "\t\t\tprint '{}';\n"
       
  2546     "\t\t} elsif ($type eq \"accent\") {\n"
       
  2547     "\t\t\tmy ($accent) = $$item{accent};\n"
       
  2548     "\t\t\tif ($accent eq \"umlaut\") { print '\\\"'; }\n"
       
  2549     "\t\t\telsif ($accent eq \"acute\") { print '\\\\\\''; }\n"
       
  2550     "\t\t\telsif ($accent eq \"grave\") { print '\\`'; }\n"
       
  2551     "\t\t\telsif ($accent eq \"circ\") { print '\\^'; }\n"
       
  2552     "\t\t\telsif ($accent eq \"tilde\") { print '\\~'; }\n"
       
  2553     "\t\t\telsif ($accent eq \"cedilla\") { print '\\c'; }\n"
       
  2554     "\t\t\telsif ($accent eq \"ring\") { print '\\r'; }\n"
       
  2555     "\t\t\tprint \"{\" . $$item{letter} . \"}\"; \n"
       
  2556     "\t\t} elsif ($type eq \"list\") {\n"
       
  2557     "\t\t\tmy $env = ($$item{style} eq \"ordered\") ? \"enumerate\" : \"itemize\";\n"
       
  2558     "\t\t\tprint \"\\n\\\\begin{\" . $env .\"}\";\n"
       
  2559     "\t\t  \tfor my $subitem (@{$$item{content}}) {\n"
       
  2560     "\t\t\t\tprint \"\\n\\\\item \";\n"
       
  2561     "\t\t\t\tgenerate_doc($subitem);\n"
       
  2562     "\t\t  \t}\n"
       
  2563     "\t\t\tprint \"\\n\\\\end{\" . $env .\"}\";\n"
       
  2564     "\t\t} elsif ($type eq \"url\") {\n"
       
  2565     "\t\t\tlatex_quote($$item{content});\n"
       
  2566     "\t\t}\n"
       
  2567     "\t}\n"
       
  2568     "}\n"
       
  2569     "\n"
       
  2570     "sub generate($$) {\n"
       
  2571     "\tmy ($item, $node) = @_;\n"
       
  2572     "\tmy ($type, $name) = @$node[0, 1];\n"
       
  2573     "\tif ($type eq \"string\") {\n"
       
  2574     "\t\tprint \"\\\\\" . $name . \"{\";\n"
       
  2575     "\t\tlatex_quote($item);\n"
       
  2576     "\t\tprint \"}\";\n"
       
  2577     "\t} elsif ($type eq \"doc\") {\n"
       
  2578     "\t\tif (@$item) {\n"
       
  2579     "\t\t\tprint \"\\\\\" . $name . \"{\";\n"
       
  2580     "\t\t\tgenerate_doc($item);\n"
       
  2581     "\t\t\tprint \"}%\\n\";\n"
       
  2582     "\t\t} else {\n"
       
  2583     "#\t\t\tprint \"\\\\\" . $name . \"Empty%\\n\";\n"
       
  2584     "\t\t}\n"
       
  2585     "\t} elsif ($type eq \"hash\") {\n"
       
  2586     "\t\tmy ($key, $value);\n"
       
  2587     "\t\twhile (($key, $subnode) = each %{$$node[2]}) {\n"
       
  2588     "\t\t\tmy $subname = $$subnode[1];\n"
       
  2589     "\t\t\tprint \"\\\\Defcs{field\" . $subname . \"}{\";\n"
       
  2590     "\t\t\tif ($$item{$key}) {\n"
       
  2591     "\t\t\t\tgenerate($$item{$key}, $subnode);\n"
       
  2592     "\t\t\t} else {\n"
       
  2593     "#\t\t\t\t\tprint \"\\\\\" . $subname . \"Empty%\\n\";\n"
       
  2594     "\t\t\t}\n"
       
  2595     "\t\t\tprint \"}%\\n\";\n"
       
  2596     "\t\t}\n"
       
  2597     "\t\tprint \"\\\\\" . $name . \"%\\n\";\n"
       
  2598     "\t} elsif ($type eq \"list\") {\n"
       
  2599     "\t\tmy $index = 0;\n"
       
  2600     "\t\tif (@$item) {\n"
       
  2601     "\t\t\tprint \"\\\\\" . $name . \"{%\\n\";\n"
       
  2602     "\t\t\tfor my $subitem (@$item) {\n"
       
  2603     "\t\t\t\tif ($index) {\n"
       
  2604     "\t\t\t\t\tprint \"\\\\\" . $name . \"Sep%\\n\";\n"
       
  2605     "\t\t\t\t}\n"
       
  2606     "\t\t\t\tgenerate($subitem, $$node[2]);\n"
       
  2607     "\t\t\t\t$index++;\n"
       
  2608     "\t\t\t}\n"
       
  2609     "\t\t\tprint \"}%\\n\";\n"
       
  2610     "\t\t} else {\n"
       
  2611     "#\t\t\tprint \"\\\\\" . $name . \"Empty%\\n\";\n"
       
  2612     "\t\t}\n"
       
  2613     "\t}\n"
       
  2614     "}\n"
       
  2615     "\n"
       
  2616     "generate($doxydocs, $doxystructure);\n";
       
  2617 
       
  2618   return true;
       
  2619 }
       
  2620 
       
  2621 bool PerlModGenerator::generateDoxyFormatTex()
       
  2622 {
       
  2623   QFile doxyFormatTex;
       
  2624   if (!createOutputFile(doxyFormatTex, pathDoxyFormatTex))
       
  2625     return false;
       
  2626 
       
  2627   QTextStream doxyFormatTexStream(&doxyFormatTex);
       
  2628   doxyFormatTexStream << 
       
  2629     "\\def\\Defcs#1{\\long\\expandafter\\def\\csname#1\\endcsname}\n"
       
  2630     "\\Defcs{Empty}{}\n"
       
  2631     "\\def\\IfEmpty#1{\\expandafter\\ifx\\csname#1\\endcsname\\Empty}\n"
       
  2632     "\n"
       
  2633     "\\def\\StringNode#1{\\Defcs{#1}##1{##1}}\n"
       
  2634     "\\def\\DocNode#1{\\Defcs{#1}##1{##1}}\n"
       
  2635     "\\def\\ListNode#1{\\Defcs{#1}##1{##1}\\Defcs{#1Sep}{}}\n"
       
  2636     "\\def\\HashNode#1{\\Defcs{#1}{}}\n"
       
  2637     "\n"
       
  2638     "\\input{" << pathDoxyStructureTex << "}\n"
       
  2639     "\n"
       
  2640     "\\newbox\\BoxA\n"
       
  2641     "\\dimendef\\DimenA=151\\relax\n"
       
  2642     "\\dimendef\\DimenB=152\\relax\n"
       
  2643     "\\countdef\\ZoneDepth=151\\relax\n"
       
  2644     "\n"
       
  2645     "\\def\\Cs#1{\\csname#1\\endcsname}\n"
       
  2646     "\\def\\Letcs#1{\\expandafter\\let\\csname#1\\endcsname}\n"
       
  2647     "\\def\\Heading#1{\\vskip 4mm\\relax\\textbf{#1}}\n"
       
  2648     "\\def\\See#1{\\begin{flushleft}\\Heading{See also: }#1\\end{flushleft}}\n"
       
  2649     "\n"
       
  2650     "\\def\\Frame#1{\\vskip 3mm\\relax\\fbox{ \\vbox{\\hsize0.95\\hsize\\vskip 1mm\\relax\n"
       
  2651     "\\raggedright#1\\vskip 0.5mm\\relax} }}\n"
       
  2652     "\n"
       
  2653     "\\def\\Zone#1#2#3{%\n"
       
  2654     "\\Defcs{Test#1}{#2}%\n"
       
  2655     "\\Defcs{Emit#1}{#3}%\n"
       
  2656     "\\Defcs{#1}{%\n"
       
  2657     "\\advance\\ZoneDepth1\\relax\n"
       
  2658     "\\Letcs{Mode\\number\\ZoneDepth}0\\relax\n"
       
  2659     "\\Letcs{Present\\number\\ZoneDepth}0\\relax\n"
       
  2660     "\\Cs{Test#1}\n"
       
  2661     "\\expandafter\\if\\Cs{Present\\number\\ZoneDepth}1%\n"
       
  2662     "\\advance\\ZoneDepth-1\\relax\n"
       
  2663     "\\Letcs{Present\\number\\ZoneDepth}1\\relax\n"
       
  2664     "\\expandafter\\if\\Cs{Mode\\number\\ZoneDepth}1%\n"
       
  2665     "\\advance\\ZoneDepth1\\relax\n"
       
  2666     "\\Letcs{Mode\\number\\ZoneDepth}1\\relax\n"
       
  2667     "\\Cs{Emit#1}\n"
       
  2668     "\\advance\\ZoneDepth-1\\relax\\fi\n"
       
  2669     "\\advance\\ZoneDepth1\\relax\\fi\n"
       
  2670     "\\advance\\ZoneDepth-1\\relax}}\n"
       
  2671     "\n"
       
  2672     "\\def\\Member#1#2{%\n"
       
  2673     "\\Defcs{Test#1}{\\Cs{field#1Detailed}\n"
       
  2674     "\\IfEmpty{field#1DetailedDoc}\\else\\Letcs{Present#1}1\\fi}\n"
       
  2675     "\\Defcs{#1}{\\Letcs{Present#1}0\\relax\n"
       
  2676     "\\Cs{Test#1}\\if1\\Cs{Present#1}\\Letcs{Present\\number\\ZoneDepth}1\\relax\n"
       
  2677     "\\if1\\Cs{Mode\\number\\ZoneDepth}#2\\fi\\fi}}\n"
       
  2678     "\n"
       
  2679     "\\def\\TypedefMemberList#1#2{%\n"
       
  2680     "\\Defcs{#1DetailedDoc}##1{\\vskip 5.5mm\\relax##1}%\n"
       
  2681     "\\Defcs{#1Name}##1{\\textbf{##1}}%\n"
       
  2682     "\\Defcs{#1See}##1{\\See{##1}}%\n"
       
  2683     "%\n"
       
  2684     "\\Zone{#1s}{\\Cs{field#1List}}{\\subsubsection{#2}\\Cs{field#1List}}%\n"
       
  2685     "\\Member{#1}{\\Frame{typedef \\Cs{field#1Type} \\Cs{field#1Name}}%\n"
       
  2686     "\\Cs{field#1DetailedDoc}\\Cs{field#1See}\\vskip 5mm\\relax}}%\n"
       
  2687     "\n"
       
  2688     "\\def\\VariableMemberList#1#2{%\n"
       
  2689     "\\Defcs{#1DetailedDoc}##1{\\vskip 5.5mm\\relax##1}%\n"
       
  2690     "\\Defcs{#1Name}##1{\\textbf{##1}}%\n"
       
  2691     "\\Defcs{#1See}##1{\\See{##1}}%\n"
       
  2692     "%\n"
       
  2693     "\\Zone{#1s}{\\Cs{field#1List}}{\\subsubsection{#2}\\Cs{field#1List}}%\n"
       
  2694     "\\Member{#1}{\\Frame{\\Cs{field#1Type}{} \\Cs{field#1Name}}%\n"
       
  2695     "\\Cs{field#1DetailedDoc}\\Cs{field#1See}\\vskip 5mm\\relax}}%\n"
       
  2696     "\n"
       
  2697     "\\def\\FunctionMemberList#1#2{%\n"
       
  2698     "\\Defcs{#1PDParamName}##1{\\textit{##1}}%\n"
       
  2699     "\\Defcs{#1PDParam}{\\Cs{field#1PDParamName}}%\n"
       
  2700     "\\Defcs{#1PDParamsSep}{, }%\n"
       
  2701     "\\Defcs{#1PDBlocksSep}{\\vskip 2mm\\relax}%\n"
       
  2702     "%\n"
       
  2703     "\\Defcs{#1PDBlocks}##1{%\n"
       
  2704     "\\Heading{Parameters:}\\vskip 1.5mm\\relax\n"
       
  2705     "\\DimenA0pt\\relax\n"
       
  2706     "\\Defcs{#1PDBlock}{\\setbox\\BoxA\\hbox{\\Cs{field#1PDParams}}%\n"
       
  2707     "\\ifdim\\DimenA<\\wd\\BoxA\\DimenA\\wd\\BoxA\\fi}%\n"
       
  2708     "##1%\n"
       
  2709     "\\advance\\DimenA3mm\\relax\n"
       
  2710     "\\DimenB\\hsize\\advance\\DimenB-\\DimenA\\relax\n"
       
  2711     "\\Defcs{#1PDBlock}{\\hbox to\\hsize{\\vtop{\\hsize\\DimenA\\relax\n"
       
  2712     "\\Cs{field#1PDParams}}\\hfill\n"
       
  2713     "\\vtop{\\hsize\\DimenB\\relax\\Cs{field#1PDDoc}}}}%\n"
       
  2714     "##1}\n"
       
  2715     "\n"
       
  2716     "\\Defcs{#1ParamName}##1{\\textit{##1}}\n"
       
  2717     "\\Defcs{#1Param}{\\Cs{field#1ParamType}{} \\Cs{field#1ParamName}}\n"
       
  2718     "\\Defcs{#1ParamsSep}{, }\n"
       
  2719     "\n"
       
  2720     "\\Defcs{#1Name}##1{\\textbf{##1}}\n"
       
  2721     "\\Defcs{#1See}##1{\\See{##1}}\n"
       
  2722     "\\Defcs{#1Return}##1{\\Heading{Returns: }##1}\n"
       
  2723     "\\Defcs{field#1Title}{\\Frame{\\Cs{field#1Type}{} \\Cs{field#1Name}(\\Cs{field#1Params})}}%\n"
       
  2724     "%\n"
       
  2725     "\\Zone{#1s}{\\Cs{field#1List}}{\\subsubsection{#2}\\Cs{field#1List}}%\n"
       
  2726     "\\Member{#1}{%\n"
       
  2727     "\\Cs{field#1Title}\\vskip 6mm\\relax\\Cs{field#1DetailedDoc}\n"
       
  2728     "\\Cs{field#1Return}\\Cs{field#1PDBlocks}\\Cs{field#1See}\\vskip 5mm\\relax}}\n"
       
  2729     "\n"
       
  2730     "\\def\\FileDetailed{\\fieldFileDetailedDoc\\par}\n"
       
  2731     "\\def\\ClassDetailed{\\fieldClassDetailedDoc\\par}\n"
       
  2732     "\n"
       
  2733     "\\def\\FileSubzones{\\fieldFileTypedefs\\fieldFileVariables\\fieldFileFunctions}\n"
       
  2734     "\n"
       
  2735     "\\def\\ClassSubzones{%\n"
       
  2736     "\\fieldClassPublicTypedefs\\fieldClassPublicMembers\\fieldClassPublicMethods\n"
       
  2737     "\\fieldClassProtectedTypedefs\\fieldClassProtectedMembers\\fieldClassProtectedMethods\n"
       
  2738     "\\fieldClassPrivateTypedefs\\fieldClassPrivateMembers\\fieldClassPrivateMethods}\n"
       
  2739     "\n"
       
  2740     "\\Member{Page}{\\subsection{\\fieldPageName}\\fieldPageDetailedDoc}\n"
       
  2741     "\n"
       
  2742     "\\TypedefMemberList{FileTypedef}{Typedefs}\n"
       
  2743     "\\VariableMemberList{FileVariable}{Variables}\n"
       
  2744     "\\FunctionMemberList{FileFunction}{Functions}\n"
       
  2745     "\\Zone{File}{\\FileSubzones}{\\subsection{\\fieldFileName}\\fieldFileDetailed\\FileSubzones}\n"
       
  2746     "\n"
       
  2747     "\\TypedefMemberList{ClassPublicTypedef}{Public Typedefs}\n"
       
  2748     "\\TypedefMemberList{ClassProtectedTypedef}{Protected Typedefs}\n"
       
  2749     "\\TypedefMemberList{ClassPrivateTypedef}{Private Typedefs}\n"
       
  2750     "\\VariableMemberList{ClassPublicMember}{Public Members}\n"
       
  2751     "\\VariableMemberList{ClassProtectedMember}{Protected Members}\n"
       
  2752     "\\VariableMemberList{ClassPrivateMember}{Private Members}\n"
       
  2753     "\\FunctionMemberList{ClassPublicMethod}{Public Methods}\n"
       
  2754     "\\FunctionMemberList{ClassProtectedMethod}{Protected Methods}\n"
       
  2755     "\\FunctionMemberList{ClassPrivateMethod}{Private Methods}\n"
       
  2756     "\\Zone{Class}{\\ClassSubzones}{\\subsection{\\fieldClassName}\\fieldClassDetailed\\ClassSubzones}\n"
       
  2757     "\n"
       
  2758     "\\Zone{AllPages}{\\fieldPages}{\\section{Pages}\\fieldPages}\n"
       
  2759     "\\Zone{AllFiles}{\\fieldFiles}{\\section{Files}\\fieldFiles}\n"
       
  2760     "\\Zone{AllClasses}{\\fieldClasses}{\\section{Classes}\\fieldClasses}\n"
       
  2761     "\n"
       
  2762     "\\newlength{\\oldparskip}\n"
       
  2763     "\\newlength{\\oldparindent}\n"
       
  2764     "\\newlength{\\oldfboxrule}\n"
       
  2765     "\n"
       
  2766     "\\ZoneDepth0\\relax\n"
       
  2767     "\\Letcs{Mode0}1\\relax\n"
       
  2768     "\n"
       
  2769     "\\def\\EmitDoxyDocs{%\n"
       
  2770     "\\setlength{\\oldparskip}{\\parskip}\n"
       
  2771     "\\setlength{\\oldparindent}{\\parindent}\n"
       
  2772     "\\setlength{\\oldfboxrule}{\\fboxrule}\n"
       
  2773     "\\setlength{\\parskip}{0cm}\n"
       
  2774     "\\setlength{\\parindent}{0cm}\n"
       
  2775     "\\setlength{\\fboxrule}{1pt}\n"
       
  2776     "\\AllPages\\AllFiles\\AllClasses\n"
       
  2777     "\\setlength{\\parskip}{\\oldparskip}\n"
       
  2778     "\\setlength{\\parindent}{\\oldparindent}\n"
       
  2779     "\\setlength{\\fboxrule}{\\oldfboxrule}}\n";
       
  2780 
       
  2781   return true;
       
  2782 }
       
  2783 
       
  2784 bool PerlModGenerator::generateDoxyLatexTex()
       
  2785 {
       
  2786   QFile doxyLatexTex;
       
  2787   if (!createOutputFile(doxyLatexTex, pathDoxyLatexTex))
       
  2788     return false;
       
  2789 
       
  2790   QTextStream doxyLatexTexStream(&doxyLatexTex);
       
  2791   doxyLatexTexStream <<
       
  2792     "\\documentclass[a4paper,12pt]{article}\n"
       
  2793     "\\usepackage[latin1]{inputenc}\n"
       
  2794     "\\usepackage[none]{hyphenat}\n"
       
  2795     "\\usepackage[T1]{fontenc}\n"
       
  2796     "\\usepackage{hyperref}\n"
       
  2797     "\\usepackage{times}\n"
       
  2798     "\n"
       
  2799     "\\input{doxyformat}\n"
       
  2800     "\n"
       
  2801     "\\begin{document}\n"
       
  2802     "\\input{" << pathDoxyDocsTex << "}\n"
       
  2803     "\\sloppy\n"
       
  2804     "\\EmitDoxyDocs\n"
       
  2805     "\\end{document}\n";
       
  2806 
       
  2807   return true;
       
  2808 }
       
  2809 
       
  2810 void PerlModGenerator::generate()
       
  2811 {
       
  2812   // + classes
       
  2813   // + namespaces
       
  2814   // + files
       
  2815   // - packages
       
  2816   // + groups
       
  2817   // + related pages
       
  2818   // - examples
       
  2819 
       
  2820   QDir perlModDir;
       
  2821   if (!createOutputDir(perlModDir))
       
  2822     return;
       
  2823 
       
  2824   bool perlmodLatex = Config_getBool("PERLMOD_LATEX");
       
  2825 
       
  2826   pathDoxyDocsPM = perlModDir.absPath() + "/DoxyDocs.pm";
       
  2827   pathDoxyStructurePM = perlModDir.absPath() + "/DoxyStructure.pm";
       
  2828   pathMakefile = perlModDir.absPath() + "/Makefile";
       
  2829   pathDoxyRules = perlModDir.absPath() + "/doxyrules.make";
       
  2830 
       
  2831   if (perlmodLatex) {
       
  2832     pathDoxyStructureTex = perlModDir.absPath() + "/doxystructure.tex";
       
  2833     pathDoxyFormatTex = perlModDir.absPath() + "/doxyformat.tex";
       
  2834     pathDoxyLatexTex = perlModDir.absPath() + "/doxylatex.tex";
       
  2835     pathDoxyLatexDVI = perlModDir.absPath() + "/doxylatex.dvi";
       
  2836     pathDoxyLatexPDF = perlModDir.absPath() + "/doxylatex.pdf";
       
  2837     pathDoxyDocsTex = perlModDir.absPath() + "/doxydocs.tex";
       
  2838     pathDoxyLatexPL = perlModDir.absPath() + "/doxylatex.pl";
       
  2839     pathDoxyLatexStructurePL = perlModDir.absPath() + "/doxylatex-structure.pl";
       
  2840   }
       
  2841 
       
  2842   if (!(generatePerlModOutput()
       
  2843 	&& generateDoxyStructurePM()
       
  2844 	&& generateMakefile()
       
  2845 	&& generateDoxyRules()))
       
  2846     return;
       
  2847 
       
  2848   if (perlmodLatex) {
       
  2849     if (!(generateDoxyLatexStructurePL()
       
  2850 	  && generateDoxyLatexPL()
       
  2851 	  && generateDoxyLatexTex()
       
  2852 	  && generateDoxyFormatTex()))
       
  2853       return;
       
  2854   }
       
  2855 }
       
  2856 
       
  2857 void generatePerlMod()
       
  2858 {
       
  2859   PerlModGenerator pmg(Config_getBool("PERLMOD_PRETTY"));
       
  2860   pmg.generate();
       
  2861 }
       
  2862 
       
  2863 // Local Variables:
       
  2864 // c-basic-offset: 2
       
  2865 // End:
       
  2866 
       
  2867 /* This elisp function for XEmacs makes Control-Z transform
       
  2868    the text in the region into a valid C string.
       
  2869 
       
  2870   (global-set-key '(control z) (lambda () (interactive)
       
  2871    (save-excursion
       
  2872     (if (< (mark) (point)) (exchange-point-and-mark))
       
  2873     (let ((start (point)) (replacers 
       
  2874      '(("\\\\" "\\\\\\\\")
       
  2875        ("\"" "\\\\\"")
       
  2876        ("\t" "\\\\t")
       
  2877        ("^.*$" "\"\\&\\\\n\""))))
       
  2878      (while replacers   
       
  2879       (while (re-search-forward (caar replacers) (mark) t)
       
  2880        (replace-match (cadar replacers) t))
       
  2881       (goto-char start)
       
  2882       (setq replacers (cdr replacers)))))))
       
  2883 */