Browse Source

[2853] provided more helpful and detailed doc for doxygen2pydoc.py

JINMEI Tatuya 12 years ago
parent
commit
b18071c40b
1 changed files with 132 additions and 9 deletions
  1. 132 9
      src/lib/util/python/doxygen2pydoc.py.in

+ 132 - 9
src/lib/util/python/doxygen2pydoc.py.in

@@ -15,11 +15,137 @@
 # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
 # WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
-r'''
-How to use it
+r"""
+A helper to semi-auto generate Python docstring text from C++ Doxygen
+documentation.
+
+This script converts an XML-format doxygen documentation for C++ library
+into a template Python docstring for the corresponding Python version
+of the library.  While it's not perfect and you'll still need to edit the
+output by hand, but past experiments showed the script produces a pretty
+good template.  It will help provide more compatible documentation for
+both C++ and Python versions of library from a unified source (C++ Doxygen
+documentation) with minimizing error-prone and boring manual conversion.
+
+HOW TO USE IT
+
+1. Generate XML output by doxygen.  Use bind10/doc/Doxyfile-xml:
+
+  % cd bind10/doc
+  % doxygen Doxyfile-xml
+  (XML files will be generated under bind10/doc/html/xml)
+
+2. Identify the xml file of the conversion target (C++ class, function, etc)
+
+  This is a bit tricky.  You'll probably need to do manual search.
+  For example, to identify the xml file for a C++ class
+  isc::datasrc::memory::ZoneWriter, you might do:
+
+  % cd bind10/doc/html/xml
+  % grep ZoneWriter *.xml | grep 'kind="class"'
+  index.xml:  <compound refid="d4/d3c/classisc_1_1datasrc_1_1memory_1_1ZoneWriter" kind="class"><name>isc::datasrc::memory::ZoneWriter</name>
+
+  In this case the file under the d4/d3c directory (with .xml suffix) would
+  be the file you're looking for.
+
+3. Run this script for the xml file:
+
+  % python3 doxygen2pydoc.py <top_srcdir>/doc/html/xml/d4/d3c/classisc_1_1datasrc_1_1memory_1_1ZoneWriter.xml > output.cc
+
+  The template content is dumped to standard out (redirected to file
+  "output.cc" in this example).
+
+  Sometimes the script produces additional output to standard error,
+  like this:
+
+    Replaced camelCased terms:
+    resetMemorySegment => reset_memory_segment
+    getConfiguration => get_configuration
+
+  In BIND 10 naming convention for methods is different for C++ and
+  Python.  This script uses some heuristic guess to convert the
+  C++-style method names to likely Python-style ones, and the converted
+  method names are used in the dumped template.  In many cases the guessed
+  names are correct, but you should check this list and make adjustments
+  by hand if necessary.
+
+  If there's no standard error output, this type of conversion didn't
+  happen.
+
+4. Edit and copy the template
+
+  The dumped template has the following organization:
+
+    namespace {
+    #ifdef COPY_THIS_TO_MAIN_CC
+        { "cleanup", ZoneWriter_cleanup, METH_NOARGS, ZoneWriter_cleanup_doc },
+        { "install", ZoneWriter_install, METH_NOARGS, ZoneWriter_install_doc },
+        { "load", ZoneWriter_load, METH_VARARGS, ZoneWriter_load_doc },
+    #endif // COPY_THIS_TO_MAIN_CC
+
+    const char* const ZoneWriter_doc = "\
+      ...
+    ";
+
+    const char* const ZoneWriter_install_doc = "\
+      ...
+    ";
+
+    ...
+    }
+
+  The ifdef-ed block is a template for class methods information
+  to be added to the corresponding PyMethodDef structure array
+  (your wrapper C++ source would have something like ZoneWriter_methods
+  of this type).  These lines should be copied there.  As long as
+  the method names and corresponding wrapper function (such as
+  ZoneWriter_cleanup) are correct you shouldn't have to edit this part
+  (and they would be normally correct, unless the guessed method name
+  conversion was needed).
+
+  The rest of the content is a sequence of constant C-string variables.
+  Usually the first variable corresponds to the class description, and
+  the rest are method descriptions (note that ZoneWriter_install_doc
+  is referenced from the ifdef-ed block).  The content of this part
+  would generally make sense, but you'll often need to make some
+  adjsutments by hand.  A common examples of such adjustment is to
+  replace "NULL" with "None".  Also, it's not uncommon that some part
+  of the description simply doesn't apply to the Python version or
+  that Python specific notes are needed.  So go through the description
+  carefully and make necessary changes.  A common practice is to add
+  comments for a summary of adjustments like this:
+
+    // Modifications:
+    // NULL->None
+    //  - removed notes about derived classes (which doesn't apply for python)
+    const char* const ZoneWriter_doc = "\
+      ...
+    ";
+  This note will help next time you need to auto-generate and edit the
+  template (probably because the original C++ document is updated).
 
-Use the "xmlonly" doxygen command to generate a special XML tag in the
-XML output.  The block enclosed by \xmlonly and \endxmlonly should contain
+  You can simply copy this part to the main C++ wrapper file, but since
+  it's relatively large a common practice is to maintain it in a separate
+  file that is exclusively included from the main file: if the name of
+  the main file is zonewriter_python.cc, the pydoc strings would be copied
+  in zonewriter_python_inc.cc, and the main file would have this line:
+
+      #include "zonewriter_inc.cc"
+
+  (In case you are C++ language police: it's okay to use the unnamed
+  name space for a file to be included because it's essentially a part
+  of the single .cc file, not expected to be included by others).
+
+  In either case, the ifdef-ed part should be removed.
+
+ADVANCED FEATURES
+
+You can use a special "xmlonly" doxygen command in C++ doxygent document
+in order to include Python code excerpt (while hiding it from the doxygen
+output for the C++ version).  This command will be converted to
+a special XML tag in the XML output.
+
+The block enclosed by \xmlonly and \endxmlonly should contain
 a verbatim XML tag named "pythonlisting", in which the python code should
 be placed.
 /// \code
@@ -37,10 +163,7 @@ doxygen2pydoc assume the pythonlisting tag is in a separate <para> node.
 This blank ensures doxygen will produce the XML file that meets the
 assumption.
 
-generate XML output by doxygen.  Use bind10/doc/Doxyfile-xml:
-% cd bind10/doc
-% doxygen Doxyfile-xml
-(XML files will be generated under bind10/doc/html/xml)
+INTERNAL MEMO (incomplete, and not very unredable yet)
 
 This simplified utility assumes the following structure:
 ...
@@ -100,7 +223,7 @@ This simplified utility assumes the following structure:
       class's detailed description
     </detaileddescription>
   </compounddef>
-'''
+"""
 
 import re, string, sys, textwrap
 from xml.dom.minidom import parse