--- /bulk2/wxdev/wxwidgets2.6-raboof-2.6.0/utils/HelpGen/src/HelpGen.cpp	2005-06-01 05:03:42.000000000 +0200
+++ HelpGen.cpp	2005-10-08 19:09:01.000000000 +0200
@@ -91,6 +91,9 @@
 static void TeXFilter(wxString* str);
 static void TeXUnfilter(wxString* str); // also trims spaces
 
+// quote special XML characters (in place)
+static void XMLFilter(wxString* str);
+
 // get all comments associated with this context
 static wxString GetAllComments(const spContext& ctx);
 
@@ -166,13 +169,28 @@
 
 WX_DEFINE_OBJARRAY(FunctionDocEntries);
 
+enum FileFormat
+{
+  Format_Tex,
+  Format_Xml,
+  Format_Unknown
+}; 
+
 // add a function which sanitazes the string before writing it to the file and
 // also capable of delaying output and sorting it before really writing it to
 // the file (done from FlushAll())
-class wxTeXFile : public wxFile
+class wxOutFile : public wxFile
 {
 public:
-    wxTeXFile() { }
+    wxOutFile() 
+    { 
+        m_format = Format_Unknown;
+    }
+
+    void SetFormat(FileFormat format)
+    {
+        m_format = format;
+    }
 
     // write a string to file verbatim (should only be used for the strings
     // inside verbatim environment)
@@ -182,10 +200,16 @@
     }
 
     // write a string quoting TeX specials in it
-    void WriteTeX(const wxString& s)
+    void WriteEscaped(const wxString& s)
     {
         wxString t(s);
-        TeXFilter(&t);
+        if (m_format == Format_Tex) {
+            TeXFilter(&t);
+        } else if (m_format == Format_Xml) {
+            XMLFilter(&t);
+        } else if (m_format == Format_Unknown) {
+            wxLogError("The file format must be set before writing escaped strings.");
+        }
 
         m_text += t;
     }
@@ -208,10 +232,11 @@
     }
 
 private:
-    wxTeXFile(const wxTeXFile&);
-    wxTeXFile& operator=(const wxTeXFile&);
+    wxOutFile(const wxOutFile&);
+    wxOutFile& operator=(const wxOutFile&);
 
     wxString m_text;
+    FileFormat m_format;
 };
 
 // helper class which manages the classes and function names to ignore for
@@ -279,7 +304,7 @@
 {
 public:
     // ctor
-    HelpGenVisitor(const wxString& directoryOut, bool overwrite);
+    HelpGenVisitor(const wxString& directoryOut, bool overwrite, FileFormat format);
 
     virtual void VisitFile( spFile& fl );
     virtual void VisitClass( spClass& cl );
@@ -309,6 +334,7 @@
 
     // write the headers for corresponding sections (only once)
     void InsertDataStructuresHeader();
+    void InsertDataStructuresFooter();
     void InsertMethodsHeader();
 
     // terminate the function documentation if it was started
@@ -318,10 +344,14 @@
     // after sorting them in alphabetical order
     void CloseClass();
 
-    wxString  m_directoryOut,   // directory for the output
-              m_fileHeader;     // name of the .h file we parse
-    bool      m_overwrite;      // overwrite existing files?
-    wxTeXFile m_file;           // file we're writing to now
+    // generate a filename (including path)
+    wxString HelpGenVisitor::GetFileName (wxString name);
+
+    wxString   m_directoryOut,   // directory for the output
+               m_fileHeader;     // name of the .h file we parse
+    bool       m_overwrite;      // overwrite existing files?
+    FileFormat m_format;
+    wxOutFile  m_file;           // file we're writing to now
 
     // state variables
     bool m_inClass,         // true after file successfully opened
@@ -561,6 +591,8 @@
 "   dump means generate .tex files for TeX2RTF converter from specified\n"
 "   headers files, mode options are:\n"
 "       -f          overwrite existing files\n"
+"       -t          generate TeX output (default)\n"
+"       -x          generate XML output\n"
 "       -o outdir   directory for generated files\n"
 "\n"
 "   diff means compare the set of methods documented .tex file with the\n"
@@ -592,12 +624,14 @@
         Mode_Diff
     } mode = Mode_None;
 
+    FileFormat format = Format_Tex;
+
     if ( argc < 2 ) {
         usage();
     }
 
     wxArrayString filesH, filesTeX;
-    wxString directoryOut,      // directory for 'dmup' output
+    wxString directoryOut,      // directory for 'dump' output
              ignoreFile;        // file with classes/functions to ignore
     bool overwrite = false,     // overwrite existing files during 'dump'?
          paramNames = false;    // check param names during 'diff'?
@@ -612,6 +646,20 @@
                         wxLog::GetActiveTarget()->SetVerbose();
                         continue;
 
+                    case 'x':
+                        // use XML output format
+                        if ( mode != Mode_Dump ) {
+                            wxLogError("XML is only supported in dump mode.");
+                            break;
+                        }
+                        format = Format_Xml;
+                        continue;
+
+                    case 't':
+                        // use TeX output format 
+                        format = Format_Tex;
+                        continue;
+
                     case 'q':
                         // be quiet
                         wxLog::GetActiveTarget()->SetVerbose(false);
@@ -734,7 +782,7 @@
 
     // create a parser object and a visitor derivation
     CJSourceParser parser;
-    HelpGenVisitor visitor(directoryOut, overwrite);
+    HelpGenVisitor visitor(directoryOut, overwrite, format);
     if ( !ignoreFile.empty() && mode == Mode_Dump )
         visitor.GetIgnoreHandler().AddNamesFromFile(ignoreFile);
 
@@ -763,6 +811,7 @@
 
     // parse all TeX files
     if ( mode == Mode_Diff ) {
+        wxASSERT ( format == Format_TeX );
         if ( !ctxTop ) {
             wxLogError("Can't complete diff.");
 
@@ -795,10 +844,13 @@
 // -----------------------------------------------------------------------------
 
 HelpGenVisitor::HelpGenVisitor(const wxString& directoryOut,
-                               bool overwrite)
+                               bool overwrite,
+                               FileFormat format)
               : m_directoryOut(directoryOut)
 {
     m_overwrite = overwrite;
+    m_format = format;
+    m_file.SetFormat(format);
 
     Reset();
 }
@@ -824,7 +876,7 @@
 
 void HelpGenVisitor::InsertTypedefDocs()
 {
-    m_file.WriteTeX(m_textStoredTypedefs);
+    m_file.WriteEscaped(m_textStoredTypedefs);
     m_textStoredTypedefs.Empty();
 }
 
@@ -833,7 +885,7 @@
     size_t count = m_storedEnums.GetCount();
     for ( size_t n = 0; n < count; n++ )
     {
-        m_file.WriteTeX(m_storedEnums[n]);
+        m_file.WriteEscaped(m_storedEnums[n]);
         m_file.WriteVerbatim(m_storedEnumsVerb[n] + '\n');
     }
 
@@ -846,16 +898,37 @@
     if ( !m_inTypesSection ) {
         m_inTypesSection = true;
 
-        m_file.WriteVerbatim("\\wxheading{Data structures}\n\n");
+        if (m_format == Format_Tex) {
+            m_file.WriteVerbatim("\\wxheading{Data structures}\n\n");
+        } else {
+            m_file.WriteVerbatim("<structs>\n");
+        }
+    }
+}
+
+void HelpGenVisitor::InsertDataStructuresFooter()
+{
+    if ( m_inTypesSection ) {
+        m_inTypesSection = false;
+        if (m_format == Format_Xml) {
+            m_file.WriteVerbatim("</structs>\n");
+        }
     }
 }
 
 void HelpGenVisitor::InsertMethodsHeader()
 {
+    // if needed, close data structures section
+    InsertDataStructuresFooter();
+
     if ( !m_inMethodSection ) {
         m_inMethodSection = true;
 
-        m_file.WriteVerbatim( "\\latexignore{\\rtfignore{\\wxheading{Members}}}\n\n");
+        if (m_format == Format_Tex) {
+            m_file.WriteVerbatim( "\\latexignore{\\rtfignore{\\wxheading{Members}}}\n\n");
+        } else {
+            m_file.WriteVerbatim( "<members>\n");
+        }
     }
 }
 
@@ -864,13 +937,32 @@
     if ( !m_funcName.empty() ) {
         if ( m_isFirstParam ) {
             // no params found
-            m_textFunc << "\\void";
+            if (m_format == Format_Tex) {
+                m_textFunc << "\\void";
+            }
+        } else {
+            // params found
+            if (m_format == Format_Xml) {
+                m_textFunc << "</parameter>\n</parameters>\n";
+            }
         }
 
-        m_textFunc << "}\n\n";
+        if (m_format == Format_Tex) {
+            m_textFunc << "}\n\n";
+        } 
 
         if ( !m_textStoredFunctionComment.empty() ) {
+            if (m_format == Format_Xml) {
+                m_textFunc << "<description><p>";
+            }
             m_textFunc << m_textStoredFunctionComment << '\n';
+            if (m_format == Format_Xml) {
+                m_textFunc << "</p></description>\n";
+            }
+        }
+
+        if (m_format == Format_Xml) {
+            m_textFunc << "</function>\n";
         }
 
         m_arrayFuncDocs.Add(new FunctionDocEntry(m_funcName, m_textFunc));
@@ -902,7 +994,13 @@
                 wxString section(m_arrayFuncDocs[n].text);
 
                 // Strip leading whitespace
-                int pos = section.Find(_T("\\membersection"));
+                int pos;
+                if (m_format == Format_Tex) {
+                    pos = section.Find(_T("\\membersection"));
+                } else {
+                    pos = section.Find(_T("<member "));
+                }
+
                 if (pos > -1)
                 {
                     section = section.Mid(pos);
@@ -920,7 +1018,7 @@
             }
 
             for ( n = 0; n < count; n++ ) {
-                m_file.WriteTeX(m_arrayFuncDocs[n].text);
+                m_file.WriteEscaped(m_arrayFuncDocs[n].text);
             }
 
             m_arrayFuncDocs.Empty();
@@ -930,6 +1028,7 @@
         m_classname.clear();
     }
     m_file.FlushAll();
+    m_file.Write("</member></members></class>");
 }
 
 void HelpGenVisitor::EndVisit()
@@ -958,6 +1057,29 @@
                  GetCurrentTimeFormatted("%H:%M:%S"), m_fileHeader.c_str());
 }
 
+wxString HelpGenVisitor::GetFileName (wxString name)
+{
+    wxString filename;
+
+    if (m_format == Format_Tex) {
+        if ( name(0, 2) == "wx" ) {
+            filename << name.c_str() + 2;
+        }
+        else {
+            filename << name;
+        }
+
+        filename.MakeLower();
+        filename += ".tex";
+        filename.Prepend(m_directoryOut);
+        return filename;
+    } else {
+        filename = name + ".xml";
+        filename.Prepend(m_directoryOut);
+        return filename;
+    }
+}
+
 void HelpGenVisitor::VisitClass( spClass& cl )
 {
     CloseClass();
@@ -978,18 +1100,7 @@
 
     // the file name is built from the class name by removing the leading "wx"
     // if any and converting it to the lower case
-    wxString filename;
-    if ( name(0, 2) == "wx" ) {
-        filename << name.c_str() + 2;
-    }
-    else {
-        filename << name;
-    }
-
-    filename.MakeLower();
-    filename += ".tex";
-    filename.Prepend(m_directoryOut);
-
+    wxString filename = GetFileName(name);
     if ( !m_overwrite && wxFile::Exists(filename) ) {
         wxLogError("Won't overwrite existing file '%s' - please use '-f'.",
                    filename.c_str());
@@ -1013,7 +1124,9 @@
 
     // write out the header
     wxString header;
-    header.Printf("%%\n"
+
+    if (m_format == Format_Tex) {
+        header.Printf("%%\n"
                   "%% automatically generated by HelpGen %s from\n"
                   "%% %s at %s\n"
                   "%%\n"
@@ -1025,6 +1138,19 @@
                   GetCurrentTimeFormatted("%d/%b/%y %H:%M:%S"),
                   name.c_str(),
                   wxString(name).MakeLower().c_str());
+    } else {
+        header.Printf("<!--\n"
+                  " automatically generated by HelpGen %s from\n"
+                  " %s at %s\n"
+                  "-->\n"
+                  "\n"
+                  "\n"
+                  "<class name=\"%s\">",
+                  GetVersionString().c_str(),
+                  m_fileHeader.c_str(),
+                  GetCurrentTimeFormatted("%d/%b/%y %H:%M:%S"),
+                  name.c_str());
+    }
 
     m_file.WriteVerbatim(header);
 
@@ -1080,7 +1206,11 @@
 
         if ( !interestingClasses.IsEmpty() ) {
             // do generate "See also" clause
-            totalText << "\\wxheading{See also:}\n\n";
+            if (m_format == Format_Tex) {
+                totalText << "\\wxheading{See also:}\n\n";
+            } else if (m_format == Format_Xml) {
+                totalText << "<seealso>\n\n";
+            }
 
             count = interestingClasses.Count();
             for ( index = 0; index < count; index++ ) {
@@ -1090,7 +1220,11 @@
                 totalText << MakeHelpref(classes[interestingClasses[index]]);
             }
 
-            totalText << "\n\n";
+            if (m_format == Format_Tex) {
+                totalText << "\n\n";
+            } else if (m_format == Format_Xml) {
+                totalText << "</seealso>\n";
+            }
         }
     }
 
@@ -1099,15 +1233,26 @@
     if ( cl.HasComments() ) {
         wxString comment = GetAllComments(cl);
 
-        totalText << '\n' << comment << '\n';
+        if (m_format == Format_Tex) {
+            totalText << '\n' << comment << '\n';
+        } else {
+            totalText << "<description>\n<p>" << comment << "</p></description>\n";
+        }
     }
 
     // derived from section
-    wxString derived = "\\wxheading{Derived from}\n\n";
+    wxString derived;
+    if (m_format == Format_Tex) {
+        derived = "\\wxheading{Derived from}\n\n";
+    } else if (m_format == Format_Xml) {
+        derived = "<parents>\n";
+    }
 
     const StrListT& baseClasses = cl.m_SuperClassNames;
     if ( baseClasses.size() == 0 ) {
-        derived << "No base class";
+        if (m_format == Format_Tex) {
+            derived << "No base class";
+        }
     }
     else {
         bool first = true;
@@ -1116,32 +1261,50 @@
               i++ ) {
             if ( !first ) {
                 // separate from the previous one
-                derived << "\\\\\n";
+                if (m_format == Format_Tex) {
+                    derived << "\\\\\n";
+                }
             }
             else {
                 first = false;
             }
 
             wxString baseclass = *i;
-            derived << "\\helpref{" << baseclass << "}";
-            derived << "{" << baseclass.MakeLower()  << "}";
+            if (m_format == Format_Tex) {
+                derived << "\\helpref{" << baseclass << "}";
+                derived << "{" << baseclass.MakeLower()  << "}";
+            } else if (m_format == Format_Xml) {
+                derived << "<ref type='class' target='" << baseclass << "'/>\n";
+            }
         }
     }
-    totalText << derived << "\n\n";
+    if (m_format == Format_Tex) {
+        totalText << derived << "\n\n";
+    } else if (m_format == Format_Xml) {
+        totalText << derived << "</parents>\n";
+    }
 
     // include file section
-    wxString includeFile = "\\wxheading{Include files}\n\n";
-    includeFile << "<" << m_fileHeader << ">";
+    wxString includeFile;
+    if (m_format == Format_Tex) {
+        includeFile = "\\wxheading{Include files}\n\n";
+        includeFile << "<" << m_fileHeader << ">";
+    } else if (m_format == Format_Xml) {
+        includeFile = "<includes>\n";
+        includeFile << "<header name=\"" << m_fileHeader << "\"/>\n";
+        includeFile << "</includes>\n";
+    }
 
     totalText << includeFile << "\n\n";
 
     // write all this to file
-    m_file.WriteTeX(totalText);
+    m_file.WriteEscaped(totalText);
 
     // if there were any enums/typedefs before, insert their documentation now
     InsertDataStructuresHeader();
     InsertTypedefDocs();
     InsertEnumDocs();
+    InsertDataStructuresFooter();
 
     //m_file.Flush();
 }
@@ -1176,7 +1339,7 @@
         // write the header for this section if not done yet
         InsertDataStructuresHeader();
 
-        m_file.WriteTeX(enumeration);
+        m_file.WriteEscaped(enumeration);
         m_file.WriteVerbatim(enumerationVerb);
         m_file.WriteVerbatim('\n');
     }
@@ -1212,7 +1375,7 @@
         InsertDataStructuresHeader();
 
         typedefdoc << '\n';
-        m_file.WriteTeX(typedefdoc);
+        m_file.WriteEscaped(typedefdoc);
     }
 }
 
@@ -1272,7 +1435,14 @@
         return;
     }
 
-    InsertMethodsHeader();
+    wxString prefix = "";
+    if ( m_inMethodSection ) {
+        if ( m_format == Format_Xml ) {
+            prefix += "</member>\n";
+        }
+    } else {
+        InsertMethodsHeader();
+    }
 
     // save state info
     m_funcName = funcname;
@@ -1280,9 +1450,6 @@
 
     m_textStoredFunctionComment = GetAllComments(op);
 
-    // start function documentation
-    wxString totalText;
-
     // check for the special case of dtor
     wxString dtor;
     if ( (funcname[0u] == '~') && (m_classname == funcname.c_str() + 1) ) {
@@ -1290,10 +1457,16 @@
         funcname = dtor;
     }
 
-    m_textFunc.Printf("\n"
-        "\\membersection{%s::%s}\\label{%s}\n",
-        m_classname.c_str(), funcname.c_str(),
-        MakeLabel(m_classname, funcname).c_str());
+    if (m_format == Format_Tex) {
+        m_textFunc.Printf("\n"
+            "\\membersection{%s::%s}\\label{%s}\n",
+            m_classname.c_str(), funcname.c_str(),
+            MakeLabel(m_classname, funcname).c_str());
+    } else {
+        m_textFunc.Printf("\n"
+            "%s<member class=\"%s\" name=\"%s\">\n",
+            prefix.c_str(), m_classname.c_str(), funcname.c_str());
+    }
 
     wxString constStr;
     if(op.mIsConstant) constStr = _T("const");
@@ -1302,12 +1475,20 @@
     if(op.mIsVirtual) virtualStr = _T("virtual ");
 
     wxString func;
-    func.Printf(_T("\n")
+    if (m_format == Format_Tex) {
+        func.Printf(_T("\n")
                 _T("\\%sfunc{%s%s}{%s}{"),
                 constStr.c_str(),
                 virtualStr.c_str(),
                 op.m_RetType.c_str(),
                 funcname.c_str());
+    } else {
+        // TODO add constStr.c_str() and virtualStr.c_str() if applicable
+        func.Printf(_T("\n")
+                _T("<function type=\"%s\" name=\"%s\">\n"),
+                op.m_RetType.c_str(),
+                funcname.c_str());
+    }
     m_textFunc += func;
 }
 
@@ -1318,18 +1499,32 @@
 
     if ( m_isFirstParam ) {
         m_isFirstParam = false;
+        if (m_format == Format_Xml) {
+            m_textFunc << "<parameters>";
+        }
     }
     else {
-        m_textFunc << ", ";
+        if (m_format == Format_Tex) {
+            m_textFunc << ", ";
+        } else {
+            m_textFunc << "</parameter>";
+        }
     }
 
-    m_textFunc << "\\param{" << param.m_Type << " }{" << param.GetName();
     wxString defvalue = param.m_InitVal;
-    if ( !defvalue.empty() ) {
-        m_textFunc << " = " << defvalue;
+    if (m_format == Format_Tex) {
+        m_textFunc << "\\param{" << param.m_Type << " }{" << param.GetName();
+        if ( !defvalue.empty() ) {
+            m_textFunc << " = " << defvalue;
+        }
+        m_textFunc << '}';
+    } else {
+        m_textFunc << "<parameter type=\"" << param.m_Type << "\" name=\"" << param.GetName() << "\"";
+        if ( !defvalue.empty() ) {
+            m_textFunc << " value=\"" << defvalue << "\"";
+        }
+        m_textFunc << ">\n";
     }
-
-    m_textFunc << '}';
 }
 
 // ---------------------------------------------------------------------------
@@ -2167,6 +2362,13 @@
     reAccents.ReplaceAll(str, "\\1");
 }
 
+// TODO properly implement those
+static void XMLFilter(wxString* str)
+{
+    str->Replace("&", "&amp;");
+    return;
+}
+
 static wxString GetAllComments(const spContext& ctx)
 {
     wxString comments;

