mirror of https://github.com/swig/swig
Merge branch 'fbo/indus_doc_csharp'
This commit is contained in:
commit
e02efe25db
|
@ -137,6 +137,12 @@ swig -csharp -help
|
|||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>-doxygen</td>
|
||||
<td> Convert C++ doxygen comments to CSharp comments
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
<p>
|
||||
|
|
|
@ -37,6 +37,13 @@
|
|||
<li><a href="#Doxygen_python_unsupported_tags">Unsupported tags</a>
|
||||
<li><a href="#Doxygen_python_further_details">Further details</a>
|
||||
</ul>
|
||||
<li><a href="#Doxygen_to_csharpXml">Doxygen to CSharp XML</a>
|
||||
<ul>
|
||||
<li><a href="#Doxygen_csharp_basic_example">Basic example</a>
|
||||
<li><a href="#Doxygen_csharp_tags">CSharp XML tags</a>
|
||||
<li><a href="#Doxygen_csharp_unsupported_tags">Unsupported tags</a>
|
||||
<li><a href="#Doxygen_csharp_further_details">Further details</a>
|
||||
</ul>
|
||||
<li><a href="#Doxygen_troubleshooting">Troubleshooting</a>
|
||||
<ul>
|
||||
<li><a href="#troubleshooting_ifndef">Problem with conditional compilation</a>
|
||||
|
@ -1550,7 +1557,570 @@ Here is the list of these tags:
|
|||
TO BE ADDED.
|
||||
</p>
|
||||
|
||||
<H2><a name="Doxygen_troubleshooting">18.5 Troubleshooting</a></H2>
|
||||
|
||||
<H2><a name="Doxygen_to_csharpXml">18.5 Doxygen to XML Csharp documentation</a></H2>
|
||||
|
||||
|
||||
<p>
|
||||
If translation is enabled, XML formatted comments should be
|
||||
automatically placed in the correct locations in the resulting module
|
||||
and proxy files.
|
||||
</p>
|
||||
|
||||
<H3><a name="Doxygen_csharp_basic_example">18.5.1 Basic example</a></H3>
|
||||
|
||||
|
||||
<p>
|
||||
Here is an example segment from an included header file
|
||||
</p>
|
||||
<div class="code"><pre>
|
||||
/*! This is describing class Shape
|
||||
\author Bob
|
||||
*/
|
||||
|
||||
class Shape {
|
||||
public:
|
||||
Shape() {
|
||||
nshapes++;
|
||||
}
|
||||
virtual ~Shape() {
|
||||
nshapes--;
|
||||
};
|
||||
/** Important Variables x*/
|
||||
double x;
|
||||
/** Important Variables y*/
|
||||
double y;
|
||||
/** Moves the Shape
|
||||
* @param dx delta on x
|
||||
* @param dy delta on y */
|
||||
void move(double dx, double dy);
|
||||
/** \return the area */
|
||||
virtual double area(void) = 0;
|
||||
/** \return the perimeter */
|
||||
virtual double perimeter(void) = 0;
|
||||
static int nshapes;
|
||||
};
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
Simply running SWIG should result in the following code being present in Shapes.cs
|
||||
</p>
|
||||
|
||||
<div class="targetlang"><pre>
|
||||
|
||||
/// <summary>This is describing class Shape
|
||||
/// Author: Bob
|
||||
/// </summary>
|
||||
public class Shape {
|
||||
|
||||
...
|
||||
/// Important Variables x
|
||||
public double x {
|
||||
set {
|
||||
ShapesCsPINVOKE.Shape_x_set(swigCPtr, value);
|
||||
}
|
||||
get {
|
||||
double ret = ShapesCsPINVOKE.Shape_x_get(swigCPtr);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/// Important Variables y
|
||||
public double y {
|
||||
set {
|
||||
ShapesCsPINVOKE.Shape_y_set(swigCPtr, value);
|
||||
}
|
||||
get {
|
||||
double ret = ShapesCsPINVOKE.Shape_y_get(swigCPtr);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/// Moves the Shape
|
||||
/// <param name="dx"> delta on x</param>
|
||||
/// <param name="dy"> delta on y</param>
|
||||
public void move(double dx, double dy) {
|
||||
ShapesCsPINVOKE.Shape_move(swigCPtr, dx, dy);
|
||||
}
|
||||
|
||||
/// <returns>the area</returns>
|
||||
public virtual double area() {
|
||||
double ret = ShapesCsPINVOKE.Shape_area(swigCPtr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// <returns>the perimeter</returns>
|
||||
public virtual double perimeter() {
|
||||
double ret = ShapesCsPINVOKE.Shape_perimeter(swigCPtr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static int nshapes {
|
||||
set {
|
||||
ShapesCsPINVOKE.Shape_nshapes_set(value);
|
||||
}
|
||||
get {
|
||||
int ret = ShapesCsPINVOKE.Shape_nshapes_get();
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
The code CSharp-wise should be identical to what would have been
|
||||
generated without the doxygen functionality enabled. When the Doxygen Translator
|
||||
module encounters a comment that contains nothing useful or a doxygen comment that it cannot
|
||||
parse, it will not affect the functionality of the SWIG generated
|
||||
code.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The translator will handle most of the tags conversions (see the
|
||||
table below). It will also automatically translate link-objects
|
||||
params, in <seealso> tags .
|
||||
Also all '\param' and '\tparam' commands are stripped out, if the specified parameter is not present in
|
||||
the function. Use 'doxygen:nostripparams' to avoid.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
CSharp translator features summary
|
||||
(see <a href="Customization.html#Customization_features">%feature
|
||||
directives</a>):
|
||||
</p>
|
||||
|
||||
<H3><a name="Doxygen_csharp_tags">18.5.2 CSharp tags</a></H3>
|
||||
|
||||
|
||||
<p>
|
||||
Here is the list of all Doxygen tags and the description of how they are translated to CSharp XML
|
||||
</p>
|
||||
<div class="diagram">
|
||||
<table border="0" summary="CSharp XML Doxygen tags">
|
||||
<tr>
|
||||
<th align="left">Doxygen tags</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>\a</td>
|
||||
<td>wrapped with '*' markdown character</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>\arg</td>
|
||||
<td>prefixed with '*' markdown character</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>\author</td>
|
||||
<td>Made simple text with prefix 'Author:'</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>\authors</td>
|
||||
<td>Made simple text with prefix 'Author:'</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>\b</td>
|
||||
<td>wrapped with '**' markdown character</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>\c</td>
|
||||
<td>wrapped with `` markdown character</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>\cite</td>
|
||||
<td>started with ' markdown character</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>\code</td>
|
||||
<td>wrapped in <code> tag </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>\code{<ext>}</td>
|
||||
<td>wrapped in <code> tag. code language extension is ignored</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>\cond</td>
|
||||
<td>Ignored</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>\copyright</td>
|
||||
<td>wrapped in <remark> tag</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>\deprecated</td>
|
||||
<td>Made simple text with prefix 'Deprecated:' </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>\e</td>
|
||||
<td>prefixed with '*' markdown character</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>\else</td>
|
||||
<td>Ignored</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>\elseif</td>
|
||||
<td>Ignored</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>\em</td>
|
||||
<td>prefixed with '*' markdown character</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>\endcode</td>
|
||||
<td>wrapped in <code> tag. code language extension is ignored</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>\endcond</td>
|
||||
<td>Ignored</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>\endif</td>
|
||||
<td>Ignored</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>\endlink</td>
|
||||
<td>Ignored</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>\endverbatim</td>
|
||||
<td>see note for \verbatim</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>\exception</td>
|
||||
<td>translated to <exception> section</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>\f$, \f[, \f], \f{, \f}</td>
|
||||
<td>Ignored</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>\if</td>
|
||||
<td>Ignored</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>\ifnot</td>
|
||||
<td>Ignored</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>\image</td>
|
||||
<td>Ignored</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>\li</td>
|
||||
<td>Ignored</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>\link</td>
|
||||
<td>Ignored</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>\n</td>
|
||||
<td>replaced with newline char</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>\note</td>
|
||||
<td>Content copied</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>\overload</td>
|
||||
<td>Ignored</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>\p</td>
|
||||
<td>wrapped with `` markdown characters</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>\par</td>
|
||||
<td>Made simple text with prefix "Title:"</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>\param</td>
|
||||
<td>translated to <param> xml section</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>\param[<dir>]</td>
|
||||
<td>translated to <param> xml section; parameter direction ('in'; 'out'; or 'in,out') is ignored</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>\remark</td>
|
||||
<td>Made simple text with prefix "remarks:"</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>\remarks</td>
|
||||
<td>Made simple text with prefix "remarks:"</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>\result</td>
|
||||
<td>translated to <return> xml section</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>\return</td>
|
||||
<td>translated to <return> xml section</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>\returns</td>
|
||||
<td>translated to <return> xml section</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>\sa</td>
|
||||
<td>translated to <seealso> xml section</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>\see</td>
|
||||
<td>translated to <seealso> xml section</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>\since</td>
|
||||
<td>Content copied</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>\throw</td>
|
||||
<td>translated to <exception></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>\throws</td>
|
||||
<td>translated to <exception></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>\todo</td>
|
||||
<td>Prefixed with 'TODO:'</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>\tparam</td>
|
||||
<td>translated to <exception> xml section</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>\verbatim</td>
|
||||
<td>copied without any processing</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>\version</td>
|
||||
<td>Made simple text with prefix 'Version:"</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>\warning</td>
|
||||
<td>Made simple text with prefix 'remarks:"</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>\$</td>
|
||||
<td>prints $ char</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>\@</td>
|
||||
<td>prints @ char</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>\\</td>
|
||||
<td>prints \ char</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>\&</td>
|
||||
<td>prints & char</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>\~</td>
|
||||
<td>prints ~ char</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>\<</td>
|
||||
<td>prints < char</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>\></td>
|
||||
<td>prints > char</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>\#</td>
|
||||
<td>prints # char</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>\%</td>
|
||||
<td>prints % char</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>\"</td>
|
||||
<td>prints " char</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>\.</td>
|
||||
<td>prints . char</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>\::</td>
|
||||
<td>prints ::</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<H3><a name="Doxygen_csharp_unsupported_tags">18.5.3 Unsupported tags</a></H3>
|
||||
|
||||
|
||||
<p>
|
||||
Doxygen has a wealth of tags such as @latexonly that have no
|
||||
equivalent in CSharp XML (all supported tags are listed in
|
||||
<a href="https://www.doxygen.nl/manual/xmlcmds.html">XML documentation</a>).
|
||||
As a result several tags have no
|
||||
translation or particular use, such as some linking and section tags.
|
||||
These are suppressed with their content just printed out (if the tag has any
|
||||
sense, typically text content).
|
||||
Here is the list of these tags:
|
||||
</p>
|
||||
|
||||
<div class="diagram">
|
||||
<b>Unsupported Doxygen tags</b>
|
||||
|
||||
<ul style="list-style-type:none;column-count:4;">
|
||||
<li>\addindex</li>
|
||||
<li>\addtogroup</li>
|
||||
<li>\anchor</li>
|
||||
<li>\attention</li>
|
||||
<li>\brief</li>
|
||||
<li>\bug</li>
|
||||
<li>\callergraph</li>
|
||||
<li>\callgraph</li>
|
||||
<li>\category</li>
|
||||
<li>\class</li>
|
||||
<li>\copybrief</li>
|
||||
<li>\copydetails</li>
|
||||
<li>\copydoc</li>
|
||||
<li>\date</li>
|
||||
<li>\def</li>
|
||||
<li>\defgroup</li>
|
||||
<li>\details</li>
|
||||
<li>\dir</li>
|
||||
<li>\dontinclude</li>
|
||||
<li>\dot</li>
|
||||
<li>\dotfile</li>
|
||||
<li>\enddot</li>
|
||||
<li>\endhtmlonly</li>
|
||||
<li>\endinternal</li>
|
||||
<li>\endlatexonly</li>
|
||||
<li>\endmanonly</li>
|
||||
<li>\endmsc</li>
|
||||
<li>\endrtfonly</li>
|
||||
<li>\endxmlonly</li>
|
||||
<li>\enum</li>
|
||||
<li>\example</li>
|
||||
<li>\extends</li>
|
||||
<li>\file</li>
|
||||
<li>\fn</li>
|
||||
<li>\headerfile</li>
|
||||
<li>\hideinitializer</li>
|
||||
<li>\htmlinclude</li>
|
||||
<li>\htmlonly</li>
|
||||
<li>\implements</li>
|
||||
<li>\include</li>
|
||||
<li>\includelineno</li>
|
||||
<li>\ingroup</li>
|
||||
<li>\interface</li>
|
||||
<li>\internal</li>
|
||||
<li>\invariant</li>
|
||||
<li>\latexonly</li>
|
||||
<li>\line</li>
|
||||
<li>\mainpage</li>
|
||||
<li>\manonly</li>
|
||||
<li>\memberof</li>
|
||||
<li>\msc</li>
|
||||
<li>\mscfile</li>
|
||||
<li>\name</li>
|
||||
<li>\namespace</li>
|
||||
<li>\nosubgrouping</li>
|
||||
<li>\package</li>
|
||||
<li>\page</li>
|
||||
<li>\paragraph</li>
|
||||
<li>\post</li>
|
||||
<li>\pre</li>
|
||||
<li>\private</li>
|
||||
<li>\privatesection</li>
|
||||
<li>\property</li>
|
||||
<li>\protected</li>
|
||||
<li>\protectedsection</li>
|
||||
<li>\protocol</li>
|
||||
<li>\public</li>
|
||||
<li>\publicsection</li>
|
||||
<li>\ref</li>
|
||||
<li>\related</li>
|
||||
<li>\relatedalso</li>
|
||||
<li>\relates</li>
|
||||
<li>\relatesalso</li>
|
||||
<li>\retval</li>
|
||||
<li>\rtfonly</li>
|
||||
<li>\section</li>
|
||||
<li>\short</li>
|
||||
<li>\showinitializer</li>
|
||||
<li>\skip</li>
|
||||
<li>\skipline</li>
|
||||
<li>\snippet</li>
|
||||
<li>\struct</li>
|
||||
<li>\subpage</li>
|
||||
<li>\subsection</li>
|
||||
<li>\subsubsection</li>
|
||||
<li>\tableofcontents</li>
|
||||
<li>\test</li>
|
||||
<li>\typedef</li>
|
||||
<li>\union</li>
|
||||
<li>\until</li>
|
||||
<li>\var</li>
|
||||
<li>\verbinclude</li>
|
||||
<li>\weakgroup</li>
|
||||
<li>\xmlonly</li>
|
||||
<li>\xrefitem</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
|
||||
If one of the following Doxygen tags appears as the first tag in a
|
||||
comment, the whole comment block is ignored:
|
||||
<!-- see parser.y, function isStructuralDoxygen() -->
|
||||
|
||||
</p>
|
||||
|
||||
<div class="diagram">
|
||||
<b>Ignored Doxygen tags</b>
|
||||
|
||||
<ul style="list-style-type:none;column-count:4;">
|
||||
<li>\addtogroup</li>
|
||||
<li>\callergraph</li>
|
||||
<li>\callgraph</li>
|
||||
<li>\category</li>
|
||||
<li>\class</li>
|
||||
<li>\def</li>
|
||||
<li>\defgroup</li>
|
||||
<li>\dir</li>
|
||||
<li>\enum</li>
|
||||
<li>\example</li>
|
||||
<li>\file</li>
|
||||
<li>\fn</li>
|
||||
<li>\headerfile</li>
|
||||
<li>\hideinitializer</li>
|
||||
<li>\interface</li>
|
||||
<li>\internal</li>
|
||||
<li>\mainpage</li>
|
||||
<li>\name</li>
|
||||
<li>\namespace</li>
|
||||
<li>\nosubgrouping</li>
|
||||
<li>\overload</li>
|
||||
<li>\package</li>
|
||||
<li>\page</li>
|
||||
<li>\property</li>
|
||||
<li>\protocol</li>
|
||||
<li>\relates</li>
|
||||
<li>\relatesalso</li>
|
||||
<li>\showinitializer</li>
|
||||
<li>\struct</li>
|
||||
<li>\typedef</li>
|
||||
<li>\union</li>
|
||||
<li>\var</li>
|
||||
<li>\weakgroup</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<H3><a name="Doxygen_csharp_further_details">18.5.4 Further details</a></H3>
|
||||
|
||||
|
||||
|
||||
<H2><a name="Doxygen_troubleshooting">18.6 Troubleshooting</a></H2>
|
||||
|
||||
|
||||
<p>
|
||||
|
@ -1572,7 +2142,7 @@ include the option and fix problems with Doxygen comments.
|
|||
</p>
|
||||
|
||||
|
||||
<H3><a name="troubleshooting_ifndef">18.5.1 Problem with conditional compilation</a></H3>
|
||||
<H3><a name="troubleshooting_ifndef">18.6.1 Problem with conditional compilation</a></H3>
|
||||
|
||||
|
||||
<p>
|
||||
|
@ -1612,14 +2182,14 @@ class A {
|
|||
</pre></div>
|
||||
|
||||
|
||||
<H2><a name="Doxygen_developer_details">18.6 Developer information</a></H2>
|
||||
<H2><a name="Doxygen_developer_details">18.7 Developer information</a></H2>
|
||||
|
||||
|
||||
<p>
|
||||
This section contains information for developers enhancing the Doxygen translator.
|
||||
</p>
|
||||
|
||||
<H3><a name="Doxygen_translator_design">18.6.1 Doxygen translator design</a></H3>
|
||||
<H3><a name="Doxygen_translator_design">18.7.1 Doxygen translator design</a></H3>
|
||||
|
||||
|
||||
<p>
|
||||
|
@ -1645,7 +2215,7 @@ class for translation into the target documentation language. For
|
|||
example, <tt>JavaDocConverter</tt> is the Javadoc module class.
|
||||
</p>
|
||||
|
||||
<H3><a name="Doxygen_debugging_commands">18.6.2 Debugging the Doxygen parser and translator</a></H3>
|
||||
<H3><a name="Doxygen_debugging_commands">18.7.2 Debugging the Doxygen parser and translator</a></H3>
|
||||
|
||||
|
||||
<p>
|
||||
|
@ -1658,7 +2228,7 @@ detailed debug information printing.
|
|||
-debug-doxygen-translator - Display Doxygen translator module debugging information
|
||||
</pre></div>
|
||||
|
||||
<H3><a name="Doxygen_tests">18.6.3 Tests</a></H3>
|
||||
<H3><a name="Doxygen_tests">18.7.3 Tests</a></H3>
|
||||
|
||||
|
||||
<p>
|
||||
|
@ -1690,7 +2260,7 @@ tool, for example:
|
|||
Examples/test-suite/java $ kdiff3 expected.txt got.txt
|
||||
</pre></div>
|
||||
|
||||
|
||||
|
||||
<p>
|
||||
Runtime tests in Java are implemented using Javadoc doclets. To make that work, you
|
||||
should have tools.jar from the JDK in your classpath. Or you should have JAVA_HOME
|
||||
|
@ -1710,7 +2280,7 @@ Runtime tests in Python are just plain string comparisons of the __doc__
|
|||
properties.
|
||||
</p>
|
||||
|
||||
<H2><a name="Doxygen_language_extension">18.7 Extending to other languages</a></H2>
|
||||
<H2><a name="Doxygen_language_extension">18.8 Extending to other languages</a></H2>
|
||||
|
||||
|
||||
<p>
|
||||
|
|
|
@ -711,11 +711,12 @@ CPP20_TEST_CASES += \
|
|||
CPP20_TEST_BROKEN = \
|
||||
|
||||
# Doxygen support test cases: can only be used with languages supporting
|
||||
# Doxygen comment translation (currently Python and Java) and only if not
|
||||
# Doxygen comment translation (currently a subset of languages) and only if not
|
||||
# disabled by configure via SKIP_DOXYGEN_TEST_CASES.
|
||||
ifneq ($(SKIP_DOXYGEN_TEST_CASES),1)
|
||||
python_HAS_DOXYGEN := 1
|
||||
csharp_HAS_DOXYGEN := 1
|
||||
java_HAS_DOXYGEN := 1
|
||||
python_HAS_DOXYGEN := 1
|
||||
|
||||
HAS_DOXYGEN := $($(LANGUAGE)_HAS_DOXYGEN)
|
||||
endif
|
||||
|
|
|
@ -59,11 +59,14 @@ SWIGOPT += -namespace $*Namespace
|
|||
CSHARPFLAGSSPECIAL =
|
||||
|
||||
# Custom tests - tests with additional commandline options
|
||||
intermediary_classname.cpptest: SWIGOPT += -dllimport intermediary_classname
|
||||
complextest.cpptest: CSHARPFLAGSSPECIAL = -r:System.Numerics.dll
|
||||
csharp_lib_arrays.cpptest: CSHARPFLAGSSPECIAL = -unsafe
|
||||
csharp_lib_arrays_bool.cpptest: CSHARPFLAGSSPECIAL = -unsafe
|
||||
csharp_swig2_compatibility.cpptest: SWIGOPT += -DSWIG2_CSHARP
|
||||
# Doxygen tests have specific flags to generate XML documentation and deactivate warnings about XML generation
|
||||
doxygen_%.cpptest: CSHARPFLAGSSPECIAL = -doc:./$*/$*.xml -nowarn:"CS0419,CS1572,CS1573,CS1574,CS1584,CS1591"
|
||||
doxygen_%.cpptest: CSHARPSRCS_EXTRA_RUN = `$(CSHARPCONVERTPATH) $(SCRIPTDIR)/doxygen_checker.cs`
|
||||
intermediary_classname.cpptest: SWIGOPT += -dllimport intermediary_classname
|
||||
|
||||
# Rules for the different types of tests
|
||||
%.cpptest:
|
||||
|
@ -100,13 +103,12 @@ run_testcase = \
|
|||
if [ -f $(SCRIPTDIR)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX) ]; then \
|
||||
$(MAKE) -f $*/$(top_builddir)/$(EXAMPLES)/Makefile \
|
||||
CSHARPFLAGS='-nologo -debug+ $(CSHARPFLAGSSPECIAL) -out:$*_runme.exe' \
|
||||
CSHARPSRCS='`$(CSHARPCONVERTPATH) $(SCRIPTDIR)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX)` `find $* -name "*.cs" -exec $(CSHARPCONVERTPATH) "{}" \+`' csharp_compile && \
|
||||
CSHARPSRCS='`$(CSHARPCONVERTPATH) $(SCRIPTDIR)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX)` `find $* -name "*.cs" -exec $(CSHARPCONVERTPATH) "{}" \+` $(CSHARPSRCS_EXTRA_RUN)' csharp_compile && \
|
||||
env LD_LIBRARY_PATH="$*:$$LD_LIBRARY_PATH" PATH="$*:$$PATH" SHLIB_PATH="$*:$$SHLIB_PATH" DYLD_FALLBACK_LIBRARY_PATH= $(RUNTOOL) $(CSHARPCILINTERPRETER) $(CSHARPCILINTERPRETER_FLAGS) ./$*_runme.exe; \
|
||||
else \
|
||||
cd $* && \
|
||||
$(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile \
|
||||
CSHARPFLAGS='-nologo -debug+ $(CSHARPFLAGSSPECIAL) -t:module -out:$*.netmodule' \
|
||||
CSHARPSRCS='`find . -name "*.cs" -exec ../$(CSHARPCONVERTPATH) "{}" \+`' csharp_compile; \
|
||||
$(MAKE) -f $*/$(top_builddir)/$(EXAMPLES)/Makefile \
|
||||
CSHARPFLAGS='-nologo -debug+ $(CSHARPFLAGSSPECIAL) -t:module -out:$*/$*.netmodule' \
|
||||
CSHARPSRCS='`find $* -name "*.cs" -exec $(CSHARPCONVERTPATH) "{}" \+`' csharp_compile; \
|
||||
fi
|
||||
|
||||
# Clean: remove testcase directories
|
||||
|
|
|
@ -0,0 +1,138 @@
|
|||
using System;
|
||||
using System.Xml;
|
||||
using System.IO;
|
||||
using doxygen_basic_translateNamespace;
|
||||
|
||||
public class doxygen_basic_translate_runme {
|
||||
|
||||
doxygen_checker _checker;
|
||||
|
||||
public static void Main() {
|
||||
doxygen_basic_translate_runme runme = new doxygen_basic_translate_runme();
|
||||
|
||||
runme.test_function1();
|
||||
runme.test_function2();
|
||||
runme.test_function3();
|
||||
runme.test_function3_bis();
|
||||
runme.test_function4();
|
||||
runme.test_function5();
|
||||
runme.test_function6();
|
||||
runme.test_function6_bis();
|
||||
runme.test_function7();
|
||||
runme.test_atan2();
|
||||
runme.test_function8();
|
||||
runme.test_function9();
|
||||
}
|
||||
|
||||
public doxygen_basic_translate_runme()
|
||||
{
|
||||
_checker = new doxygen_checker("doxygen_basic_translate", "doxygen_basic_translate","./doxygen_basic_translate/doxygen_basic_translate.xml");
|
||||
}
|
||||
|
||||
public void test_function1()
|
||||
{
|
||||
_checker.checkObject(doxygen_checker.CodeType.MEMBER, "function", "summary", 0, "Brief description.");
|
||||
_checker.checkText(doxygen_checker.CodeType.MEMBER, "function", @"
|
||||
The comment text.
|
||||
Author: Some author
|
||||
|
||||
|
||||
");
|
||||
_checker.checkObject(doxygen_checker.CodeType.MEMBER, "function", "returns", 0, "Some number");
|
||||
_checker.checkObjectAttribute(doxygen_checker.CodeType.MEMBER, "function", "seealso", 0, "cref", "M:doxygen_basic_translateNamespace.doxygen_basic_translate.function2");
|
||||
}
|
||||
|
||||
public void test_function2()
|
||||
{
|
||||
_checker.checkText(doxygen_checker.CodeType.MEMBER, "function2", @"
|
||||
A test of a very very very very very very very very very very very very very very very very
|
||||
very very very very very long comment string.
|
||||
");
|
||||
}
|
||||
|
||||
public void test_function3()
|
||||
{
|
||||
_checker.checkText(doxygen_checker.CodeType.MEMBER, "function3(System.Int32)", @"
|
||||
A test for overloaded functions
|
||||
This is function **one**
|
||||
");
|
||||
}
|
||||
|
||||
public void test_function3_bis()
|
||||
{
|
||||
_checker.checkText(doxygen_checker.CodeType.MEMBER, "function3(System.Int32,System.Int32)", @"
|
||||
A test for overloaded functions
|
||||
This is function **two**
|
||||
");
|
||||
}
|
||||
|
||||
public void test_function4()
|
||||
{
|
||||
_checker.checkText(doxygen_checker.CodeType.MEMBER, "function4", @"
|
||||
A test of some mixed tag usage
|
||||
|
||||
This *code* fragment shows us something .
|
||||
Title: Minuses:
|
||||
* it's senseless
|
||||
* it's stupid
|
||||
* it's null
|
||||
|
||||
");
|
||||
}
|
||||
|
||||
public void test_function5()
|
||||
{
|
||||
_checker.checkText(doxygen_checker.CodeType.MEMBER, "function5(System.Int32)", @"
|
||||
This is a post comment.
|
||||
");
|
||||
}
|
||||
|
||||
public void test_function6()
|
||||
{
|
||||
_checker.checkText(doxygen_checker.CodeType.MEMBER, "function6(System.Int32)", @"
|
||||
Test for default args
|
||||
");
|
||||
_checker.checkObjectAttribute(doxygen_checker.CodeType.MEMBER, "function6(System.Int32)", "param", 0, "name", "a");
|
||||
_checker.checkObject(doxygen_checker.CodeType.MEMBER, "function6(System.Int32)", "param", 0, " Some parameter, default is 42");
|
||||
}
|
||||
|
||||
public void test_function6_bis()
|
||||
{
|
||||
_checker.checkText(doxygen_checker.CodeType.MEMBER, "function6", @"
|
||||
Test for default args
|
||||
");
|
||||
}
|
||||
|
||||
public void test_function7()
|
||||
{
|
||||
_checker.checkText(doxygen_checker.CodeType.MEMBER, "function7(doxygen_basic_translateNamespace.SWIGTYPE_p_p_p_Shape)", @"
|
||||
Test for a parameter with difficult type
|
||||
(mostly for python)
|
||||
");
|
||||
_checker.checkObjectAttribute(doxygen_checker.CodeType.MEMBER, "function7(doxygen_basic_translateNamespace.SWIGTYPE_p_p_p_Shape)", "param", 0, "name", "a");
|
||||
_checker.checkObject(doxygen_checker.CodeType.MEMBER, "function7(doxygen_basic_translateNamespace.SWIGTYPE_p_p_p_Shape)", "param", 0, " Very strange param");
|
||||
}
|
||||
|
||||
public void test_atan2()
|
||||
{
|
||||
_checker.checkText(doxygen_checker.CodeType.MEMBER, "Atan2(System.Double,System.Double)", @"
|
||||
Multiple parameters test.
|
||||
|
||||
");
|
||||
_checker.checkObjectAttribute(doxygen_checker.CodeType.MEMBER, "Atan2(System.Double,System.Double)", "param", 0, "name", "y");
|
||||
_checker.checkObjectAttribute(doxygen_checker.CodeType.MEMBER, "Atan2(System.Double,System.Double)", "param", 1, "name", "x");
|
||||
_checker.checkObject(doxygen_checker.CodeType.MEMBER, "Atan2(System.Double,System.Double)", "param", 0, " Vertical coordinate.");
|
||||
_checker.checkObject(doxygen_checker.CodeType.MEMBER, "Atan2(System.Double,System.Double)", "param", 1, " Horizontal coordinate.");
|
||||
_checker.checkObject(doxygen_checker.CodeType.MEMBER, "Atan2(System.Double,System.Double)", "returns", 0, "Arc tangent of ``y/x``.");
|
||||
}
|
||||
|
||||
public void test_function8()
|
||||
{
|
||||
_checker.checkObject(doxygen_checker.CodeType.MEMBER, "function8", "summary", 0, "Test variadic function");
|
||||
}
|
||||
|
||||
public void test_function9()
|
||||
{
|
||||
_checker.checkObject(doxygen_checker.CodeType.MEMBER, "function9(System.Int32)", "summary", 0, "Test unnamed argument");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,183 @@
|
|||
using System;
|
||||
using System.Xml;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
/// Class used to check XML documentation content generated
|
||||
/// by C# compiler for Doxygen tests.
|
||||
/// Methods allow to look for the documentation of a specific object (method, type, variable)
|
||||
/// and to check its content.
|
||||
public class doxygen_checker{
|
||||
|
||||
private XmlElement _root;
|
||||
private string _namespace_prefix;
|
||||
|
||||
/// Enum to identify the different types of objects in XML
|
||||
public enum CodeType
|
||||
{
|
||||
/// <summary>member of a class/type</summary>
|
||||
MEMBER,
|
||||
/// <summary>class/type itself</summary>
|
||||
TYPE
|
||||
};
|
||||
|
||||
/// <summary> Constructor </summary>
|
||||
///
|
||||
/// <param name="namespaceName"> The name of namespace to consider </param>
|
||||
/// <param name="className"> The name of the class inside the namespace </param>
|
||||
/// <param name="xmlFilePath"> The file path where the XML to parse is located</param>
|
||||
public doxygen_checker(string namespaceName, string className, string xmlFilePath)
|
||||
{
|
||||
XmlDocument doc = new XmlDocument();
|
||||
|
||||
string fileContent;
|
||||
try{
|
||||
fileContent = File.ReadAllText(xmlFilePath);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new ApplicationException("Error: " + e.Message);
|
||||
}
|
||||
|
||||
doc.LoadXml(fileContent);
|
||||
_root = doc.DocumentElement; //get the root element.
|
||||
_namespace_prefix = namespaceName +"Namespace." + className + ".";
|
||||
}
|
||||
|
||||
/// <summary>Check general content (not included in a tag) of an object </summary>
|
||||
///
|
||||
/// <param name="codeType"> The type of object to check </param>
|
||||
/// <param name="objectName"> The name of the object (function mostly) to check </param>
|
||||
/// <param name="expectedContent"> The content of the documentation for the given object </param>
|
||||
/// <exception cref="ApplicationException"> When object or expected content is not found </exception>
|
||||
public void checkText(CodeType codeType, string objectName, string expectedContent)
|
||||
{
|
||||
string completeObjectName = _createObjectName(codeType, objectName);
|
||||
bool found = false;
|
||||
|
||||
_root.SelectNodes("members/member").Cast<XmlElement>().ToList().ForEach(member =>
|
||||
{
|
||||
if (member.Attributes["name"].Value == completeObjectName)
|
||||
{
|
||||
found = true;
|
||||
|
||||
// parse all children of member until #text is found
|
||||
string valMember = member.ChildNodes.Cast<XmlNode>().ToList().Find(node => node.Name == "#text").InnerText;
|
||||
|
||||
if (uniformizeString(expectedContent) != uniformizeString(valMember))
|
||||
{
|
||||
throw new ApplicationException("Error: " + objectName + " contains '" + valMember + "', expected '" + expectedContent + "'");
|
||||
}
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
if (!found)
|
||||
throw new ApplicationException("Object '" + objectName + "' not found");
|
||||
}
|
||||
|
||||
/// <summary>Check field content from an object</summary>
|
||||
///
|
||||
/// <param name="codeType">The type of object to check </param>
|
||||
/// <param name="objectName">The name of object (function mostly) to check </param>
|
||||
/// <param name="fieldName">The name of the XML tag (summary, param,...) of the object to check </param>
|
||||
/// <param name="itemIndex"> The index of the field (0 for the first one, 1 for the second, etc) to check </param>
|
||||
/// <param name="expectedContent"> The content of the documentation for the given object </param>
|
||||
/// <exception cref="ApplicationException"> When object, field, or expected content is not found </exception>
|
||||
public void checkObject(CodeType codeType, string objectName, string fieldName, int itemIndex, string expectedContent)
|
||||
{
|
||||
string completeObjectName = _createObjectName(codeType, objectName);
|
||||
bool found = false;
|
||||
|
||||
_root.SelectNodes("members/member").Cast<XmlElement>().ToList().ForEach(member =>
|
||||
{
|
||||
if (member.Attributes["name"].Value == completeObjectName)
|
||||
{
|
||||
found = true;
|
||||
var field = member.SelectNodes(fieldName);
|
||||
|
||||
if (field == null)
|
||||
throw new ApplicationException("Field " + fieldName + " is not found");
|
||||
|
||||
if (itemIndex >= field.Count)
|
||||
{
|
||||
throw new ApplicationException("Error: " + objectName + " has " + field.Count + " fields, "+ itemIndex +"th value does not exist");
|
||||
}
|
||||
else
|
||||
{
|
||||
var valField = field.Item(itemIndex).InnerText;
|
||||
|
||||
if (uniformizeString(expectedContent) != uniformizeString(valField))
|
||||
{
|
||||
throw new ApplicationException("Error: " + objectName + " field '" + fieldName + "' is '" + valField + "', expected '" + expectedContent + "'");
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
if(!found)
|
||||
throw new ApplicationException("Object '" + objectName + "' not found" );
|
||||
}
|
||||
|
||||
private string _createObjectName(CodeType codeType, string objectName)
|
||||
{
|
||||
if(codeType == CodeType.MEMBER)
|
||||
return "M:" + _namespace_prefix + objectName;
|
||||
else
|
||||
return "T:" + _namespace_prefix + objectName;
|
||||
}
|
||||
|
||||
/// Returns a string without break lines so as to avoid issues during string comparison
|
||||
private string uniformizeString(string str)
|
||||
{
|
||||
// remove line breaks in string
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
|
||||
return Regex.Replace(str, @"\t|\n|\r", "");
|
||||
else
|
||||
return Regex.Replace(str, @"\s|\n|\r", "");
|
||||
}
|
||||
|
||||
/// <summary> Check field attribute from an object </summary>
|
||||
///
|
||||
/// <param name="codeType">The type of object to check </param>
|
||||
/// <param name="objectName">The name of object (function mostly) to check </param>
|
||||
/// <param name="fieldName">The name of the XML tag (summary, param,...) of the object to check </param>
|
||||
/// <param name="itemIndex"> The index of the field (0 for the first one, 1 for the second, etc) to check </param>
|
||||
/// <param name="attributeName"> The XML attribute to consider </param>
|
||||
/// <param name="expectedContent"> The content of the documentation for the given object </param>
|
||||
/// <exception cref="ApplicationException"> When object, field, attribute or expected content is not found </exception>
|
||||
public void checkObjectAttribute(CodeType codeType, string objectName, string fieldName, int itemIndex, string attributeName, string expectedContent)
|
||||
{
|
||||
string completeObjectName = _createObjectName(codeType, objectName);
|
||||
bool found = false;
|
||||
|
||||
_root.SelectNodes("members/member").Cast<XmlElement>().ToList().ForEach(member =>
|
||||
{
|
||||
if (member.Attributes["name"].Value == completeObjectName)
|
||||
{
|
||||
found = true;
|
||||
var field = member.SelectNodes(fieldName);
|
||||
|
||||
if (field == null)
|
||||
throw new ApplicationException("Field " + fieldName + " is not found");
|
||||
|
||||
if(field.Count == 0)
|
||||
throw new ApplicationException("Field " + fieldName + " is empty");
|
||||
|
||||
// read attribute of first field's item
|
||||
string valItem = field.Item(itemIndex).Attributes[attributeName].Value;
|
||||
|
||||
if(uniformizeString(valItem) != uniformizeString(expectedContent))
|
||||
throw new ApplicationException("Error: " + objectName + " field " + fieldName + " is '" + valItem + "', expected '" + expectedContent + "'");
|
||||
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
if (!found)
|
||||
throw new ApplicationException("Object '" + objectName + "' not found");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
using System;
|
||||
using System.Xml;
|
||||
using System.IO;
|
||||
using doxygen_nested_classNamespace;
|
||||
|
||||
public class doxygen_nested_class_runme {
|
||||
|
||||
doxygen_checker _checker;
|
||||
|
||||
public static void Main() {
|
||||
doxygen_nested_class_runme runme = new doxygen_nested_class_runme();
|
||||
|
||||
runme.test_class();
|
||||
}
|
||||
|
||||
public doxygen_nested_class_runme()
|
||||
{
|
||||
_checker = new doxygen_checker("doxygen_nested_class", "DoxOuter", "./doxygen_nested_class/doxygen_nested_class.xml");
|
||||
}
|
||||
|
||||
public void test_class()
|
||||
{
|
||||
_checker.checkText(doxygen_checker.CodeType.MEMBER, "#ctor", @"
|
||||
DoxOuter constructor
|
||||
");
|
||||
_checker.checkText(doxygen_checker.CodeType.TYPE, "DoxInner", @"
|
||||
DoxInner class description
|
||||
");
|
||||
_checker.checkText(doxygen_checker.CodeType.MEMBER, "DoxInner.#ctor", @"
|
||||
DoxInner constructor
|
||||
");
|
||||
_checker.checkText(doxygen_checker.CodeType.MEMBER, "DoxInner.doxMethod", @"
|
||||
doxMethod description
|
||||
");
|
||||
_checker.checkText(doxygen_checker.CodeType.MEMBER, "DoxInner.doxStaticMethod", @"
|
||||
doxStaticMethod description
|
||||
");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,189 @@
|
|||
using System;
|
||||
using System.Xml;
|
||||
using System.IO;
|
||||
using doxygen_translateNamespace;
|
||||
|
||||
public class doxygen_translate_runme {
|
||||
|
||||
doxygen_checker _checker;
|
||||
|
||||
public static void Main() {
|
||||
doxygen_translate_runme runme = new doxygen_translate_runme();
|
||||
|
||||
runme.test_function1();
|
||||
runme.test_function2();
|
||||
runme.test_function3();
|
||||
runme.test_function4();
|
||||
}
|
||||
|
||||
public doxygen_translate_runme()
|
||||
{
|
||||
_checker = new doxygen_checker("doxygen_translate", "doxygen_translate", "./doxygen_translate/doxygen_translate.xml");
|
||||
}
|
||||
|
||||
public void test_function1()
|
||||
{
|
||||
string function_name = "function(System.Int32,System.Single)";
|
||||
_checker.checkObject(doxygen_checker.CodeType.MEMBER, function_name, "code", 0, " some test code");
|
||||
_checker.checkObject(doxygen_checker.CodeType.MEMBER, function_name, "remarks", 0, "some copyright");
|
||||
_checker.checkObjectAttribute(doxygen_checker.CodeType.MEMBER, function_name, "exception", 0, "cref", "!:SuperError");
|
||||
_checker.checkObjectAttribute(doxygen_checker.CodeType.MEMBER, function_name, "param", 0, "name", "a");
|
||||
_checker.checkObject(doxygen_checker.CodeType.MEMBER, function_name, "param", 0, " the first param");
|
||||
_checker.checkObject(doxygen_checker.CodeType.MEMBER, function_name, "remarks", 1, "Some remark text");
|
||||
_checker.checkObject(doxygen_checker.CodeType.MEMBER, function_name, "remarks", 2, "Another remarks section");
|
||||
_checker.checkObject(doxygen_checker.CodeType.MEMBER, function_name, "returns", 0, "Whatever");
|
||||
_checker.checkObject(doxygen_checker.CodeType.MEMBER, function_name, "returns", 1, "it");
|
||||
_checker.checkObject(doxygen_checker.CodeType.MEMBER, function_name, "returns", 2, "may return");
|
||||
_checker.checkObjectAttribute(doxygen_checker.CodeType.MEMBER, function_name, "seealso", 0, "cref", "!:someOtherMethod");
|
||||
_checker.checkObjectAttribute(doxygen_checker.CodeType.MEMBER, function_name, "seealso", 1, "cref", "M:doxygen_translateNamespace.doxygen_translate.function(System.Int32,System.Single)");
|
||||
_checker.checkObjectAttribute(doxygen_checker.CodeType.MEMBER, function_name, "exception", 1, "cref", "!:superException");
|
||||
_checker.checkObjectAttribute(doxygen_checker.CodeType.MEMBER, function_name, "exception", 2, "cref", "!:RuntimeError");
|
||||
_checker.checkObjectAttribute(doxygen_checker.CodeType.MEMBER, function_name, "param", 1, "name", "b");
|
||||
_checker.checkObject(doxygen_checker.CodeType.MEMBER, function_name, "param", 1, " B is mentioned again...");
|
||||
_checker.checkObject(doxygen_checker.CodeType.MEMBER, function_name, "remarks", 3, "This is senseless!");
|
||||
|
||||
string description = @"
|
||||
*Hello*
|
||||
|
||||
* some list item
|
||||
Author: lots of them
|
||||
|
||||
|
||||
Author: Zubr
|
||||
|
||||
|
||||
**boldword**
|
||||
|
||||
``codeword``
|
||||
|
||||
'citationword'
|
||||
|
||||
";
|
||||
|
||||
_checker.checkText(doxygen_checker.CodeType.MEMBER, function_name, description);
|
||||
}
|
||||
|
||||
public void test_function2()
|
||||
{
|
||||
string function_name = "htmlFunction(System.Int32,System.Single)";
|
||||
|
||||
|
||||
string description = @"
|
||||
Test for html tags. See Doxygen doc for list of tags recognized by Doxygen.
|
||||
This is link (""http://acme.com/index.html"")
|
||||
**bold**
|
||||
Quote:
|
||||
Quotation block.
|
||||
(""http://www.worldwildlife.org/who/index.html"")
|
||||
|
||||
|
||||
center
|
||||
``this is code``
|
||||
Starts an item title.
|
||||
Starts an item description.
|
||||
Starts a piece of text displayed in a typewriter font.
|
||||
|
||||
Starts a section with a specific style (HTML only)
|
||||
|
||||
**Starts a piece of text displayed in an italic font.**
|
||||
'Form' does not generate any output.
|
||||
|
||||
--------------------------------------------------------------------
|
||||
|
||||
# Heading 1
|
||||
|
||||
## Heading 2
|
||||
|
||||
### Heading 3
|
||||
|
||||
*Starts a piece of text displayed in an italic font.*
|
||||
Input tag.
|
||||
Image: src=""slika.png""
|
||||
Meta tag.
|
||||
Multicol is ignored by doxygen.
|
||||
* List item 1.
|
||||
* List item 2.
|
||||
|
||||
Starts a new paragraph.
|
||||
|
||||
Starts a preformatted fragment.
|
||||
|
||||
Starts a section of text displayed in a smaller font.
|
||||
|
||||
'Starts an inline text fragment with a specific style.'
|
||||
**Starts a section of bold text.**
|
||||
Starts a piece of text displayed in subscript.
|
||||
Starts a piece of text displayed in superscript.
|
||||
Animals
|
||||
| Column 1 | Column 2 |
|
||||
-----------------------
|
||||
| cow | dog |
|
||||
| cat | mouse |
|
||||
| horse | parrot |
|
||||
Starts a piece of text displayed in a typewriter font.
|
||||
|
||||
Starts a piece of text displayed in a typewriter font.
|
||||
* List item 1.
|
||||
* List item 2.
|
||||
* List item 3.
|
||||
*Starts a piece of text displayed in an italic font.*
|
||||
<u>underlined \b bold text - doxy commands are ignored inside 'htmlonly' section </u>
|
||||
";
|
||||
|
||||
_checker.checkText(doxygen_checker.CodeType.MEMBER, function_name, description);
|
||||
}
|
||||
|
||||
public void test_function3()
|
||||
{
|
||||
string function_name = "htmlTableFunction(System.Int32)";
|
||||
|
||||
_checker.checkObjectAttribute(doxygen_checker.CodeType.MEMBER, function_name, "param", 0, "name", "byFlags");
|
||||
|
||||
string paramDesc = @" bits marking required items:
|
||||
|
||||
| Size in bits| Items Required |
|
||||
--------------------------------
|
||||
| 1 - 8 | 1 |
|
||||
| 9 - 16 | 2 |
|
||||
| 17 - 32 | 4 |
|
||||
|
||||
Almost all combinations of above flags are supported by
|
||||
``htmlTable...`` functions.";
|
||||
|
||||
_checker.checkObject(doxygen_checker.CodeType.MEMBER, function_name, "param", 0, paramDesc);
|
||||
}
|
||||
|
||||
public void test_function4()
|
||||
{
|
||||
string function_name = "htmlEntitiesFunction(System.Int32,System.Single)";
|
||||
|
||||
string description = @"
|
||||
All entities are treated as commands (C) TM (R)
|
||||
should work also<in text
|
||||
>
|
||||
&
|
||||
'
|
||||
""
|
||||
`
|
||||
'
|
||||
""
|
||||
""
|
||||
-
|
||||
--
|
||||
|
||||
x
|
||||
-
|
||||
.
|
||||
~
|
||||
<=
|
||||
>=
|
||||
<--
|
||||
-->
|
||||
Not an html entity - ignored by Doxygen.
|
||||
Not an &text html entity - ampersand is replaced with entity.
|
||||
";
|
||||
|
||||
_checker.checkText(doxygen_checker.CodeType.MEMBER, function_name, description);
|
||||
}
|
||||
|
||||
}
|
|
@ -42,6 +42,12 @@ int someVar=42;
|
|||
*/
|
||||
#define CONSTANT_VALUE 4242
|
||||
|
||||
/**
|
||||
* A two line
|
||||
* constant comment
|
||||
*/
|
||||
#define CONSTANT_VALUE_TWO_LINE 5353
|
||||
|
||||
/// SomeAnotherClass description
|
||||
class SomeAnotherClass
|
||||
{
|
||||
|
@ -63,6 +69,12 @@ public:
|
|||
int classAttr3; ///< The class attribute post-comment
|
||||
//!< with details
|
||||
|
||||
/**
|
||||
* The class attribute comment with
|
||||
* two lines of comments
|
||||
*/
|
||||
int classAttr4;
|
||||
|
||||
/**
|
||||
* The class method comment.
|
||||
*
|
||||
|
@ -105,6 +117,12 @@ struct SomeAnotherStruct
|
|||
int structAttr3; ///< The struct attribute post-comment
|
||||
//!< with details
|
||||
|
||||
/**
|
||||
* The struct attribute comment with
|
||||
* two lines of comments
|
||||
*/
|
||||
int structAttr4;
|
||||
|
||||
/**
|
||||
* The struct method comment
|
||||
*/
|
||||
|
@ -131,6 +149,24 @@ struct SomeAnotherStruct
|
|||
void structMethodExtended2(int a, int b)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* The struct static method one line comment
|
||||
*/
|
||||
static void structStaticMethod(int xxx, int yyy)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* The struct static method with parameters
|
||||
* Two lines of comments
|
||||
*
|
||||
* @param aaa Parameter aaa
|
||||
* @param bbb Parameter bbb
|
||||
*/
|
||||
static void structStaticMethod2(int aaa, int bbb)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct Foo1636
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
/**
|
||||
* Testing comments before enum items
|
||||
* Including two line comments
|
||||
*/
|
||||
enum SomeAnotherEnum
|
||||
{
|
||||
|
@ -19,7 +20,12 @@
|
|||
/**
|
||||
* The comment for the third item
|
||||
*/
|
||||
SOME_ITEM_3
|
||||
SOME_ITEM_3,
|
||||
/**
|
||||
* The comment for the fourth item
|
||||
* over two lines
|
||||
*/
|
||||
SOME_ITEM_4
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -27,6 +27,7 @@ public class doxygen_parsing_enums_proper_runme {
|
|||
"");
|
||||
wantedComments.put("doxygen_parsing_enums_proper.SomeAnotherEnum",
|
||||
" Testing comments before enum items \n" +
|
||||
" Including two line comments \n" +
|
||||
" \n" +
|
||||
"");
|
||||
wantedComments.put("doxygen_parsing_enums_proper.SomeAnotherEnum2.SOME_ITEM_30",
|
||||
|
@ -36,6 +37,11 @@ public class doxygen_parsing_enums_proper_runme {
|
|||
" Testing comments after enum items \n" +
|
||||
" \n" +
|
||||
"");
|
||||
wantedComments.put("doxygen_parsing_enums_proper.SomeAnotherEnum.SOME_ITEM_4",
|
||||
" The comment for the fourth item \n" +
|
||||
" over two lines \n" +
|
||||
" \n" +
|
||||
"");
|
||||
wantedComments.put("doxygen_parsing_enums_proper.SomeAnotherEnum.SOME_ITEM_3",
|
||||
" The comment for the third item \n" +
|
||||
" \n" +
|
||||
|
|
|
@ -25,6 +25,11 @@ public class doxygen_parsing_enums_simple_runme {
|
|||
" The comment for the third item \n" +
|
||||
" \n" +
|
||||
"");
|
||||
wantedComments.put("doxygen_parsing_enums_simple.doxygen_parsing_enums_simpleConstants.SOME_ITEM_4",
|
||||
" The comment for the fourth item \n" +
|
||||
" over two lines \n" +
|
||||
" \n" +
|
||||
"");
|
||||
wantedComments.put("doxygen_parsing_enums_simple.doxygen_parsing_enums_simpleConstants.SOME_ITEM_2",
|
||||
" The comment for the second item \n" +
|
||||
" \n" +
|
||||
|
|
|
@ -35,6 +35,7 @@ public class doxygen_parsing_enums_typesafe_runme {
|
|||
"");
|
||||
wantedComments.put("doxygen_parsing_enums_typesafe.SomeAnotherEnum",
|
||||
" Testing comments before enum items \n" +
|
||||
" Including two line comments \n" +
|
||||
" \n" +
|
||||
"");
|
||||
wantedComments.put("doxygen_parsing_enums_typesafe.SomeAnotherEnum2.SOME_ITEM_10",
|
||||
|
@ -44,6 +45,11 @@ public class doxygen_parsing_enums_typesafe_runme {
|
|||
" The comment for the third item \n" +
|
||||
" \n" +
|
||||
"");
|
||||
wantedComments.put("doxygen_parsing_enums_typesafe.SomeAnotherEnum.SOME_ITEM_4",
|
||||
" The comment for the fourth item \n" +
|
||||
" over two lines \n" +
|
||||
" \n" +
|
||||
"");
|
||||
wantedComments.put("doxygen_parsing_enums_typesafe.SomeAnotherEnum2.SOME_ITEM_30",
|
||||
"Post comment for the third item \n" +
|
||||
"");
|
||||
|
|
|
@ -26,6 +26,11 @@ public class doxygen_parsing_enums_typeunsafe_runme {
|
|||
" The comment for the third item \n" +
|
||||
" \n" +
|
||||
"");
|
||||
wantedComments.put("doxygen_parsing_enums_typeunsafe.SomeAnotherEnum.SOME_ITEM_4",
|
||||
" The comment for the fourth item \n" +
|
||||
" over two lines \n" +
|
||||
" \n" +
|
||||
"");
|
||||
wantedComments.put("doxygen_parsing_enums_typeunsafe.SomeAnotherEnum.SOME_ITEM_1",
|
||||
" The comment for the first item \n" +
|
||||
" \n" +
|
||||
|
@ -35,6 +40,7 @@ public class doxygen_parsing_enums_typeunsafe_runme {
|
|||
"");
|
||||
wantedComments.put("doxygen_parsing_enums_typeunsafe.SomeAnotherEnum",
|
||||
" Testing comments before enum items \n" +
|
||||
" Including two line comments \n" +
|
||||
" \n" +
|
||||
"");
|
||||
wantedComments.put("doxygen_parsing_enums_typeunsafe.SomeAnotherEnum2",
|
||||
|
|
|
@ -31,9 +31,17 @@ public class doxygen_parsing_runme {
|
|||
wantedComments.put("doxygen_parsing.SomeAnotherClass.setClassAttr3(int)",
|
||||
"The class attribute post-comment with details \n" +
|
||||
"");
|
||||
wantedComments.put("doxygen_parsing.SomeAnotherClass.setClassAttr4(int)",
|
||||
" The class attribute comment with \n" +
|
||||
" two lines of comments \n" +
|
||||
"");
|
||||
wantedComments.put("doxygen_parsing.SomeAnotherStruct.setStructAttr3(int)",
|
||||
"The struct attribute post-comment with details \n" +
|
||||
"");
|
||||
wantedComments.put("doxygen_parsing.SomeAnotherStruct.setStructAttr4(int)",
|
||||
" The struct attribute comment with \n" +
|
||||
" two lines of comments \n" +
|
||||
"");
|
||||
wantedComments.put("doxygen_parsing.SomeAnotherClass.classMethodExtended2(int, int)",
|
||||
" The class method with parameter \n" +
|
||||
" \n" +
|
||||
|
@ -90,6 +98,10 @@ public class doxygen_parsing_runme {
|
|||
wantedComments.put("doxygen_parsing.SomeAnotherStruct.getStructAttr3()",
|
||||
"The struct attribute post-comment with details \n" +
|
||||
"");
|
||||
wantedComments.put("doxygen_parsing.SomeAnotherStruct.getStructAttr4()",
|
||||
" The struct attribute comment with \n" +
|
||||
" two lines of comments \n" +
|
||||
"");
|
||||
wantedComments.put("doxygen_parsing.doxygen_parsing.getSomeVar()",
|
||||
" The var comment \n" +
|
||||
" \n" +
|
||||
|
@ -114,6 +126,10 @@ public class doxygen_parsing_runme {
|
|||
wantedComments.put("doxygen_parsing.SomeAnotherClass.getClassAttr3()",
|
||||
"The class attribute post-comment with details \n" +
|
||||
"");
|
||||
wantedComments.put("doxygen_parsing.SomeAnotherClass.getClassAttr4()",
|
||||
" The class attribute comment with \n" +
|
||||
" two lines of comments \n" +
|
||||
"");
|
||||
wantedComments.put("doxygen_parsing.SomeAnotherClass.classMethod()",
|
||||
" The class method comment.<br>\n" +
|
||||
" <br>\n" +
|
||||
|
@ -126,12 +142,28 @@ public class doxygen_parsing_runme {
|
|||
" @param b Parameter b \n" +
|
||||
" \n" +
|
||||
"");
|
||||
wantedComments.put("doxygen_parsing.SomeAnotherStruct.structStaticMethod(int, int)",
|
||||
" The struct static method one line comment \n" +
|
||||
" \n" +
|
||||
"");
|
||||
wantedComments.put("doxygen_parsing.SomeAnotherStruct.structStaticMethod2(int, int)",
|
||||
" The struct static method with parameters \n" +
|
||||
" Two lines of comments \n" +
|
||||
" \n" +
|
||||
" @param aaa Parameter aaa \n" +
|
||||
" @param bbb Parameter bbb \n" +
|
||||
" \n" +
|
||||
"");
|
||||
wantedComments.put("doxygen_parsing.SomeAnotherClass.setClassAttr2(int)",
|
||||
"The class attribute post-comment \n" +
|
||||
"");
|
||||
wantedComments.put("doxygen_parsing.doxygen_parsingConstants.CONSTANT_VALUE",
|
||||
"The constant comment \n" +
|
||||
"");
|
||||
wantedComments.put("doxygen_parsing.doxygen_parsingConstants.CONSTANT_VALUE_TWO_LINE",
|
||||
" A two line \n" +
|
||||
" constant comment \n" +
|
||||
"");
|
||||
wantedComments.put("doxygen_parsing.Foo1636.getGroupmember1()",
|
||||
"groupmember1 description");
|
||||
wantedComments.put("doxygen_parsing.Foo1636.setGroupmember1(int)",
|
||||
|
|
|
@ -0,0 +1,989 @@
|
|||
/* -----------------------------------------------------------------------------
|
||||
* This file is part of SWIG, which is licensed as a whole under version 3
|
||||
* (or any later version) of the GNU General Public License. Some additional
|
||||
* terms also apply to certain portions of SWIG. The full details of the SWIG
|
||||
* license and copyrights can be found in the LICENSE and COPYRIGHT files
|
||||
* included with the SWIG source code as distributed by the SWIG developers
|
||||
* and at http://www.swig.org/legal.html.
|
||||
*
|
||||
* csharpdoc.cxx
|
||||
*
|
||||
* Module to return documentation for nodes formatted for CSharpDoc
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
#include "csharpdoc.h"
|
||||
#include "doxyparser.h"
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
|
||||
#include "swigmod.h"
|
||||
|
||||
// define static tables, they are filled in CSharpDocConverter's constructor
|
||||
CSharpDocConverter::TagHandlersMap CSharpDocConverter::tagHandlers;
|
||||
|
||||
using std::string;
|
||||
|
||||
// Helper class increasing the provided indent string in its ctor and decreasing
|
||||
// it in its dtor.
|
||||
class IndentGuard {
|
||||
public:
|
||||
// One indent level.
|
||||
static const char *Level() {
|
||||
return " ";
|
||||
}
|
||||
// Default ctor doesn't do anything and prevents the dtor from doing anything// too and should only be used when the guard needs to be initialized// conditionally as Init() can then be called after checking some condition.// Otherwise, prefer to use the non default ctor below.
|
||||
IndentGuard() {
|
||||
m_initialized = false;
|
||||
}
|
||||
|
||||
// Ctor takes the output to determine the current indent and to remove the
|
||||
// extra indent added to it in the dtor and the variable containing the indent
|
||||
// to use, which must be used after every new line by the code actually
|
||||
// updating the output.
|
||||
IndentGuard(string &output, string &indent) {
|
||||
Init(output, indent);
|
||||
}
|
||||
|
||||
// Really initializes the object created using the default ctor.
|
||||
void Init(string &output, string &indent) {
|
||||
m_output = &output;
|
||||
m_indent = &indent;
|
||||
|
||||
const string::size_type lastNonSpace = m_output->find_last_not_of(' ');
|
||||
if (lastNonSpace == string::npos) {
|
||||
m_firstLineIndent = m_output->length();
|
||||
} else if ((*m_output)[lastNonSpace] == '\n') {
|
||||
m_firstLineIndent = m_output->length() - (lastNonSpace + 1);
|
||||
} else {
|
||||
m_firstLineIndent = 0;
|
||||
}
|
||||
|
||||
// Notice that the indent doesn't include the first line indent because it's
|
||||
// implicit, i.e. it is present in the input and so is copied into the
|
||||
// output anyhow.
|
||||
*m_indent = Level();
|
||||
|
||||
m_initialized = true;
|
||||
}
|
||||
|
||||
// Get the indent for the first line of the paragraph, which is smaller than
|
||||
// the indent for the subsequent lines.
|
||||
string getFirstLineIndent() const {
|
||||
return string(m_firstLineIndent, ' ');
|
||||
}
|
||||
|
||||
~IndentGuard() {
|
||||
if (!m_initialized)
|
||||
return;
|
||||
|
||||
m_indent->clear();
|
||||
|
||||
// Get rid of possible remaining extra indent, e.g. if there were any trailing
|
||||
// new lines: we shouldn't add the extra indent level to whatever follows
|
||||
// this paragraph.
|
||||
static const size_t lenIndentLevel = strlen(Level());
|
||||
if (m_output->length() > lenIndentLevel) {
|
||||
const size_t start = m_output->length() - lenIndentLevel;
|
||||
if (m_output->compare(start, string::npos, Level()) == 0)
|
||||
m_output->erase(start);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
string *m_output;
|
||||
string *m_indent;
|
||||
string::size_type m_firstLineIndent;
|
||||
bool m_initialized;
|
||||
|
||||
IndentGuard(const IndentGuard &);
|
||||
};
|
||||
|
||||
static void replaceAll(std::string &src, const std::string &token, const std::string &replace) {
|
||||
std::string::size_type pos = src.find(token);
|
||||
|
||||
while (pos != std::string::npos) {
|
||||
src.replace(pos, token.size(), replace);
|
||||
pos = src.find(token, pos + replace.size());
|
||||
}
|
||||
}
|
||||
|
||||
static void trimWhitespace(string &s) {
|
||||
const string::size_type lastNonSpace = s.find_last_not_of(' ');
|
||||
if (lastNonSpace == string::npos)
|
||||
s.clear();
|
||||
else
|
||||
s.erase(lastNonSpace + 1);
|
||||
}
|
||||
|
||||
// Erase the first character in the string if it is a newline
|
||||
static void eraseLeadingNewLine(string &s) {
|
||||
if (!s.empty() && s[0] == '\n')
|
||||
s.erase(s.begin());
|
||||
}
|
||||
|
||||
// Erase the first character in the string if it is a newline
|
||||
static void eraseAllNewLine(string &str) {
|
||||
for (size_t i = 0; i < str.size(); i++) {
|
||||
// if the character is a newline character
|
||||
if (str[i] == '\n') {
|
||||
// remove the character
|
||||
str.erase(i, 1);
|
||||
// decrement the index to account for the removed character
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Erase last characters in the string if it is a newline or a space
|
||||
static void eraseTrailingSpaceNewLines(string &s) {
|
||||
while (!s.empty() && (s[s.size() - 1] == '\n' || s[s.size() - 1] == ' '))
|
||||
s.erase(s.size() - 1);
|
||||
}
|
||||
|
||||
// escape some characters which cannot appear as it in C# comments
|
||||
static void escapeSpecificCharacters(string &str) {
|
||||
for (size_t i = 0; i < str.size(); i++) {
|
||||
if (str[i] == '<') {
|
||||
str.replace(i, 1, "<");
|
||||
} else if (str[i] == '>') {
|
||||
str.replace(i, 1, ">");
|
||||
} else if (str[i] == '&') {
|
||||
str.replace(i, 1, "&");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check the generated docstring line by line and make sure that any
|
||||
// code and verbatim blocks have an empty line preceding them, which
|
||||
// is necessary for Sphinx. Additionally, this strips any empty lines
|
||||
// appearing at the beginning of the docstring.
|
||||
static string padCodeAndVerbatimBlocks(const string &docString) {
|
||||
std::string result;
|
||||
|
||||
std::istringstream iss(docString);
|
||||
|
||||
// Initialize to false because there is no previous line yet
|
||||
bool lastLineWasNonBlank = false;
|
||||
|
||||
for (string line; std::getline(iss, line); result += line) {
|
||||
if (!result.empty()) {
|
||||
// Terminate the previous line
|
||||
result += '\n';
|
||||
}
|
||||
|
||||
const size_t pos = line.find_first_not_of(" \t");
|
||||
if (pos == string::npos) {
|
||||
lastLineWasNonBlank = false;
|
||||
} else {
|
||||
if (lastLineWasNonBlank &&
|
||||
(line.compare(pos, 13, ".. code-block") == 0 ||
|
||||
line.compare(pos, 7, ".. math") == 0 ||
|
||||
line.compare(pos, 3, ">>>") == 0)) {
|
||||
// Must separate code or math blocks from the previous line
|
||||
result += '\n';
|
||||
}
|
||||
lastLineWasNonBlank = true;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/* static */
|
||||
CSharpDocConverter::TagHandlersMap::mapped_type CSharpDocConverter::make_handler(tagHandler handler) {
|
||||
return make_pair(handler, std::string());
|
||||
}
|
||||
|
||||
/* static */
|
||||
CSharpDocConverter::TagHandlersMap::mapped_type CSharpDocConverter::make_handler(tagHandler handler, const char *arg) {
|
||||
return make_pair(handler, arg);
|
||||
}
|
||||
|
||||
void CSharpDocConverter::fillStaticTables() {
|
||||
if (tagHandlers.size()) // fill only once
|
||||
return;
|
||||
|
||||
|
||||
tagHandlers["a"] = make_handler(&CSharpDocConverter::handleTagWrap, "*");
|
||||
tagHandlers["b"] = make_handler(&CSharpDocConverter::handleTagWrap, "**");
|
||||
// \c command is translated as single quotes around next word
|
||||
tagHandlers["c"] = make_handler(&CSharpDocConverter::handleTagWrap, "``");
|
||||
tagHandlers["cite"] = make_handler(&CSharpDocConverter::handleTagWrap, "'");
|
||||
tagHandlers["e"] = make_handler(&CSharpDocConverter::handleTagWrap, "*");
|
||||
// these commands insert just a single char, some of them need to be escaped
|
||||
tagHandlers["$"] = make_handler(&CSharpDocConverter::handleTagChar);
|
||||
tagHandlers["@"] = make_handler(&CSharpDocConverter::handleTagChar);
|
||||
tagHandlers["\\"] = make_handler(&CSharpDocConverter::handleTagChar);
|
||||
tagHandlers["<"] = make_handler(&CSharpDocConverter::handleTagCharReplace, "<");
|
||||
tagHandlers[">"] = make_handler(&CSharpDocConverter::handleTagCharReplace, ">");
|
||||
tagHandlers["&"] = make_handler(&CSharpDocConverter::handleTagCharReplace, "&");
|
||||
tagHandlers["#"] = make_handler(&CSharpDocConverter::handleTagChar);
|
||||
tagHandlers["%"] = make_handler(&CSharpDocConverter::handleTagChar);
|
||||
tagHandlers["~"] = make_handler(&CSharpDocConverter::handleTagChar);
|
||||
tagHandlers["\""] = make_handler(&CSharpDocConverter::handleTagChar);
|
||||
tagHandlers["."] = make_handler(&CSharpDocConverter::handleTagChar);
|
||||
tagHandlers["::"] = make_handler(&CSharpDocConverter::handleTagChar);
|
||||
// these commands are stripped out, and only their content is printed
|
||||
tagHandlers["attention"] = make_handler(&CSharpDocConverter::handleParagraph, "remarks");
|
||||
tagHandlers["author"] = make_handler(&CSharpDocConverter::handleTagWord, "Author");
|
||||
tagHandlers["authors"] = make_handler(&CSharpDocConverter::handleTagWord, "Author");
|
||||
tagHandlers["brief"] = make_handler(&CSharpDocConverter::handleSummary);
|
||||
tagHandlers["bug"] = make_handler(&CSharpDocConverter::handleTagWord, "Bug:");
|
||||
tagHandlers["code"] = make_handler(&CSharpDocConverter::handleCode);
|
||||
tagHandlers["copyright"] = make_handler(&CSharpDocConverter::handleParagraph, "remarks");
|
||||
tagHandlers["date"] = make_handler(&CSharpDocConverter::handleTagWord, "Date");
|
||||
tagHandlers["deprecated"] = make_handler(&CSharpDocConverter::handleTagWord, "Deprecated");
|
||||
tagHandlers["details"] = make_handler(&CSharpDocConverter::handleParagraph, "remarks");
|
||||
tagHandlers["em"] = make_handler(&CSharpDocConverter::handleTagWrap, "*");
|
||||
tagHandlers["example"] = make_handler(&CSharpDocConverter::handleTagWord, "Example");
|
||||
tagHandlers["exception"] = tagHandlers["throw"] = tagHandlers["throws"] = make_handler(&CSharpDocConverter::handleTagException);
|
||||
tagHandlers["htmlonly"] = make_handler(&CSharpDocConverter::handleNotHandled);
|
||||
tagHandlers["invariant"] = make_handler(&CSharpDocConverter::handleNotHandled);
|
||||
tagHandlers["latexonly"] = make_handler(&CSharpDocConverter::handleNotHandled);
|
||||
tagHandlers["link"] = make_handler(&CSharpDocConverter::handleNotHandled);
|
||||
tagHandlers["manonly"] = make_handler(&CSharpDocConverter::handleNotHandled);
|
||||
tagHandlers["note"] = make_handler(&CSharpDocConverter::handleNotHandled);
|
||||
tagHandlers["p"] = make_handler(&CSharpDocConverter::handleTagWrap, "``");
|
||||
tagHandlers["partofdescription"] = make_handler(&CSharpDocConverter::handleNotHandled);
|
||||
tagHandlers["rtfonly"] = make_handler(&CSharpDocConverter::handleNotHandled);
|
||||
tagHandlers["remark"] = make_handler(&CSharpDocConverter::handleParagraph, "remarks");
|
||||
tagHandlers["remarks"] = make_handler(&CSharpDocConverter::handleParagraph, "remarks");
|
||||
tagHandlers["sa"] = make_handler(&CSharpDocConverter::handleTagSee);
|
||||
tagHandlers["see"] = make_handler(&CSharpDocConverter::handleTagSee);
|
||||
tagHandlers["since"] = make_handler(&CSharpDocConverter::handleNotHandled);
|
||||
tagHandlers["short"] = make_handler(&CSharpDocConverter::handleNotHandled);
|
||||
tagHandlers["todo"] = make_handler(&CSharpDocConverter::handleTagWord, "TODO");
|
||||
tagHandlers["version"] = make_handler(&CSharpDocConverter::handleTagWord, "Version");
|
||||
tagHandlers["verbatim"] = make_handler(&CSharpDocConverter::handleVerbatimBlock);
|
||||
tagHandlers["warning"] = make_handler(&CSharpDocConverter::handleLine, "remarks");
|
||||
tagHandlers["xmlonly"] = make_handler(&CSharpDocConverter::handleNotHandled);
|
||||
// these commands have special handlers
|
||||
tagHandlers["arg"] = make_handler(&CSharpDocConverter::handleAddList);
|
||||
tagHandlers["cond"] = make_handler(&CSharpDocConverter::handleIgnore);
|
||||
tagHandlers["else"] = make_handler(&CSharpDocConverter::handleIgnore);
|
||||
tagHandlers["elseif"] = make_handler(&CSharpDocConverter::handleIgnore);
|
||||
tagHandlers["endcond"] = make_handler(&CSharpDocConverter::handleIgnore);
|
||||
tagHandlers["if"] = make_handler(&CSharpDocConverter::handleIgnore);
|
||||
tagHandlers["ifnot"] = make_handler(&CSharpDocConverter::handleIgnore);
|
||||
tagHandlers["image"] = make_handler(&CSharpDocConverter::handleIgnore);
|
||||
tagHandlers["li"] = make_handler(&CSharpDocConverter::handleIgnore);
|
||||
tagHandlers["overload"] = make_handler(&CSharpDocConverter::handleIgnore);
|
||||
|
||||
tagHandlers["par"] = make_handler(&CSharpDocConverter::handleTagWord, "Title");
|
||||
tagHandlers["param"] = tagHandlers["tparam"] = make_handler(&CSharpDocConverter::handleTagParam);
|
||||
tagHandlers["ref"] = make_handler(&CSharpDocConverter::handleTagRef);
|
||||
tagHandlers["result"] = tagHandlers["return"] = tagHandlers["returns"] = make_handler(&CSharpDocConverter::handleTagReturn);
|
||||
|
||||
// this command just prints its contents
|
||||
// (it is internal command of swig's parser, contains plain text)
|
||||
tagHandlers["plainstd::string"] = make_handler(&CSharpDocConverter::handlePlainString);
|
||||
tagHandlers["plainstd::endl"] = make_handler(&CSharpDocConverter::handleNewLine);
|
||||
tagHandlers["n"] = make_handler(&CSharpDocConverter::handleNewLine);
|
||||
|
||||
// \f commands output literal Latex formula, which is still better than nothing.
|
||||
tagHandlers["f$"] = tagHandlers["f["] = tagHandlers["f{"] = make_handler(&CSharpDocConverter::handleMath);
|
||||
|
||||
// HTML tags
|
||||
tagHandlers["<a"] = make_handler(&CSharpDocConverter::handleDoxyHtmlTag_A);
|
||||
tagHandlers["<b"] = make_handler(&CSharpDocConverter::handleDoxyHtmlTag2, "**");
|
||||
tagHandlers["<blockquote"] = make_handler(&CSharpDocConverter::handleDoxyHtmlTag_A, "Quote: ");
|
||||
tagHandlers["<body"] = make_handler(&CSharpDocConverter::handleDoxyHtmlTag);
|
||||
tagHandlers["<br"] = make_handler(&CSharpDocConverter::handleDoxyHtmlTag, "\n");
|
||||
|
||||
// there is no formatting for this tag as it was deprecated in HTML 4.01 and
|
||||
// not used in HTML 5
|
||||
tagHandlers["<center"] = make_handler(&CSharpDocConverter::handleDoxyHtmlTag);
|
||||
tagHandlers["<caption"] = make_handler(&CSharpDocConverter::handleDoxyHtmlTag);
|
||||
tagHandlers["<code"] = make_handler(&CSharpDocConverter::handleDoxyHtmlTag2, "``");
|
||||
|
||||
tagHandlers["<dl"] = make_handler(&CSharpDocConverter::handleDoxyHtmlTag);
|
||||
tagHandlers["<dd"] = make_handler(&CSharpDocConverter::handleDoxyHtmlTag, " ");
|
||||
tagHandlers["<dt"] = make_handler(&CSharpDocConverter::handleDoxyHtmlTag);
|
||||
|
||||
tagHandlers["<dfn"] = make_handler(&CSharpDocConverter::handleDoxyHtmlTag);
|
||||
tagHandlers["<div"] = make_handler(&CSharpDocConverter::handleDoxyHtmlTag);
|
||||
tagHandlers["<em"] = make_handler(&CSharpDocConverter::handleDoxyHtmlTag2, "**");
|
||||
tagHandlers["<form"] = make_handler(&CSharpDocConverter::handleDoxyHtmlTag);
|
||||
tagHandlers["<hr"] = make_handler(&CSharpDocConverter::handleDoxyHtmlTag, "--------------------------------------------------------------------\n");
|
||||
tagHandlers["<h1"] = make_handler(&CSharpDocConverter::handleDoxyHtmlTag, "# ");
|
||||
tagHandlers["<h2"] = make_handler(&CSharpDocConverter::handleDoxyHtmlTag, "## ");
|
||||
tagHandlers["<h3"] = make_handler(&CSharpDocConverter::handleDoxyHtmlTag, "### ");
|
||||
tagHandlers["<i"] = make_handler(&CSharpDocConverter::handleDoxyHtmlTag2, "*");
|
||||
tagHandlers["<input"] = make_handler(&CSharpDocConverter::handleDoxyHtmlTag);
|
||||
tagHandlers["<img"] = make_handler(&CSharpDocConverter::handleDoxyHtmlTag, "Image:");
|
||||
tagHandlers["<li"] = make_handler(&CSharpDocConverter::handleDoxyHtmlTag, "* ");
|
||||
tagHandlers["<meta"] = make_handler(&CSharpDocConverter::handleDoxyHtmlTag);
|
||||
tagHandlers["<multicol"] = make_handler(&CSharpDocConverter::handleDoxyHtmlTag);
|
||||
tagHandlers["<ol"] = make_handler(&CSharpDocConverter::handleDoxyHtmlTag);
|
||||
tagHandlers["<p"] = make_handler(&CSharpDocConverter::handleDoxyHtmlTag, "\n");
|
||||
tagHandlers["<pre"] = make_handler(&CSharpDocConverter::handleDoxyHtmlTag);
|
||||
tagHandlers["<small"] = make_handler(&CSharpDocConverter::handleDoxyHtmlTag);
|
||||
tagHandlers["<span"] = make_handler(&CSharpDocConverter::handleDoxyHtmlTag2, "'");
|
||||
tagHandlers["<strong"] = make_handler(&CSharpDocConverter::handleDoxyHtmlTag2, "**");
|
||||
|
||||
// make a space between text and super/sub script.
|
||||
tagHandlers["<sub"] = make_handler(&CSharpDocConverter::handleDoxyHtmlTag, " ");
|
||||
tagHandlers["<sup"] = make_handler(&CSharpDocConverter::handleDoxyHtmlTag, " ");
|
||||
|
||||
tagHandlers["<table"] = make_handler(&CSharpDocConverter::handleDoxyHtmlTagNoParam);
|
||||
tagHandlers["<td"] = make_handler(&CSharpDocConverter::handleDoxyHtmlTag_td);
|
||||
tagHandlers["<th"] = make_handler(&CSharpDocConverter::handleDoxyHtmlTag_th);
|
||||
tagHandlers["<tr"] = make_handler(&CSharpDocConverter::handleDoxyHtmlTag_tr);
|
||||
tagHandlers["<tt"] = make_handler(&CSharpDocConverter::handleDoxyHtmlTag);
|
||||
tagHandlers["<kbd"] = make_handler(&CSharpDocConverter::handleDoxyHtmlTag);
|
||||
tagHandlers["<ul"] = make_handler(&CSharpDocConverter::handleDoxyHtmlTag);
|
||||
tagHandlers["<var"] = make_handler(&CSharpDocConverter::handleDoxyHtmlTag2, "*");
|
||||
|
||||
// HTML entities
|
||||
tagHandlers["©"] = make_handler(&CSharpDocConverter::handleHtmlEntity, "(C)");
|
||||
tagHandlers["&trade"] = make_handler(&CSharpDocConverter::handleHtmlEntity, " TM");
|
||||
tagHandlers["®"] = make_handler(&CSharpDocConverter::handleHtmlEntity, "(R)");
|
||||
tagHandlers["<"] = make_handler(&CSharpDocConverter::handleHtmlEntity, "<");
|
||||
tagHandlers[">"] = make_handler(&CSharpDocConverter::handleHtmlEntity, ">");
|
||||
tagHandlers["&"] = make_handler(&CSharpDocConverter::handleHtmlEntity, "&");
|
||||
tagHandlers["&apos"] = make_handler(&CSharpDocConverter::handleHtmlEntity, "'");
|
||||
tagHandlers["""] = make_handler(&CSharpDocConverter::handleHtmlEntity, "\"");
|
||||
tagHandlers["&lsquo"] = make_handler(&CSharpDocConverter::handleHtmlEntity, "`");
|
||||
tagHandlers["&rsquo"] = make_handler(&CSharpDocConverter::handleHtmlEntity, "'");
|
||||
tagHandlers["&ldquo"] = make_handler(&CSharpDocConverter::handleHtmlEntity, "\"");
|
||||
tagHandlers["&rdquo"] = make_handler(&CSharpDocConverter::handleHtmlEntity, "\"");
|
||||
tagHandlers["&ndash"] = make_handler(&CSharpDocConverter::handleHtmlEntity, "-");
|
||||
tagHandlers["&mdash"] = make_handler(&CSharpDocConverter::handleHtmlEntity, "--");
|
||||
tagHandlers[" "] = make_handler(&CSharpDocConverter::handleHtmlEntity, " ");
|
||||
tagHandlers["×"] = make_handler(&CSharpDocConverter::handleHtmlEntity, "x");
|
||||
tagHandlers["&minus"] = make_handler(&CSharpDocConverter::handleHtmlEntity, "-");
|
||||
tagHandlers["&sdot"] = make_handler(&CSharpDocConverter::handleHtmlEntity, ".");
|
||||
tagHandlers["&sim"] = make_handler(&CSharpDocConverter::handleHtmlEntity, "~");
|
||||
tagHandlers["&le"] = make_handler(&CSharpDocConverter::handleHtmlEntity, "<=");
|
||||
tagHandlers["&ge"] = make_handler(&CSharpDocConverter::handleHtmlEntity, ">=");
|
||||
tagHandlers["&larr"] = make_handler(&CSharpDocConverter::handleHtmlEntity, "<--");
|
||||
tagHandlers["&rarr"] = make_handler(&CSharpDocConverter::handleHtmlEntity, "-->");
|
||||
}
|
||||
|
||||
CSharpDocConverter::CSharpDocConverter(int flags):
|
||||
DoxygenTranslator(flags), m_tableLineLen(0), m_prevRowIsTH(false) {
|
||||
fillStaticTables();
|
||||
}
|
||||
|
||||
// Return the type as it should appear in the output documentation.
|
||||
static std::string getCSharpDocType(Node *n, const_String_or_char_ptr lname = "") {
|
||||
std::string type;
|
||||
|
||||
String *s = Swig_typemap_lookup("doctype", n, lname, 0);
|
||||
if (!s) {
|
||||
if (String *t = Getattr(n, "type"))
|
||||
s = SwigType_str(t, "");
|
||||
}
|
||||
/////////////////
|
||||
|
||||
if (!s)
|
||||
return type;
|
||||
|
||||
type = Char(s);
|
||||
|
||||
Delete(s);
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
std::string CSharpDocConverter::getParamType(std::string param) {
|
||||
std::string type;
|
||||
|
||||
ParmList *plist = CopyParmList(Getattr(currentNode, "parms"));
|
||||
for (Parm *p = plist; p; p = nextSibling(p)) {
|
||||
String *pname = Getattr(p, "name");
|
||||
if (pname && Char(pname) == param) {
|
||||
type = getCSharpDocType(p, pname);
|
||||
break;
|
||||
}
|
||||
}
|
||||
Delete(plist);
|
||||
return type;
|
||||
}
|
||||
|
||||
std::string CSharpDocConverter::getParamValue(std::string param) {
|
||||
std::string value;
|
||||
|
||||
ParmList *plist = CopyParmList(Getattr(currentNode, "parms"));
|
||||
for (Parm *p = plist; p; p = nextSibling(p)) {
|
||||
String *pname = Getattr(p, "name");
|
||||
if (pname && Char(pname) == param) {
|
||||
String *pval = Getattr(p, "value");
|
||||
if (pval)
|
||||
value = Char(pval);
|
||||
break;
|
||||
}
|
||||
}
|
||||
Delete(plist);
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true, if the given parameter exists in the current node
|
||||
* (for example param is a name of function parameter). If feature
|
||||
* 'doxygen:nostripparams' is set, then this method always returns
|
||||
* true - parameters are copied to output regardless of presence in
|
||||
* function params list.
|
||||
*/
|
||||
bool CSharpDocConverter::paramExists(std::string param) {
|
||||
|
||||
if (GetFlag(currentNode, "feature:doxygen:nostripparams")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
ParmList *plist = CopyParmList(Getattr(currentNode, "parms"));
|
||||
|
||||
for (Parm *p = plist; p;) {
|
||||
|
||||
if (Getattr(p, "name") && Char(Getattr(p, "name")) == param) {
|
||||
return true;
|
||||
}
|
||||
/* doesn't seem to work always: in some cases (especially for 'self' parameters)
|
||||
* tmap:in is present, but tmap:in:next is not and so this code skips all the parameters
|
||||
*/
|
||||
//p = Getattr(p, "tmap:in") ? Getattr(p, "tmap:in:next") : nextSibling(p);
|
||||
p = nextSibling(p);
|
||||
}
|
||||
|
||||
Delete(plist);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string CSharpDocConverter::translateSubtree(DoxygenEntity &doxygenEntity) {
|
||||
std::string translatedComment;
|
||||
|
||||
if (doxygenEntity.isLeaf)
|
||||
return translatedComment;
|
||||
|
||||
std::string currentSection;
|
||||
std::list<DoxygenEntity>::iterator p = doxygenEntity.entityList.begin();
|
||||
while (p != doxygenEntity.entityList.end()) {
|
||||
translateEntity(*p, translatedComment);
|
||||
translateSubtree(*p);
|
||||
p++;
|
||||
}
|
||||
|
||||
return translatedComment;
|
||||
}
|
||||
|
||||
void CSharpDocConverter::translateEntity(DoxygenEntity &doxyEntity, std::string &translatedComment) {
|
||||
// check if we have needed handler and call it
|
||||
std::map<std::string, std::pair<tagHandler, std::string> >::iterator it;
|
||||
it = tagHandlers.find(getBaseCommand(doxyEntity.typeOfEntity));
|
||||
if (it != tagHandlers.end())
|
||||
(this->*(it->second.first)) (doxyEntity, translatedComment, it->second.second);
|
||||
}
|
||||
|
||||
void CSharpDocConverter::handleIgnore(DoxygenEntity &tag, std::string &translatedComment, const std::string &) {
|
||||
if (tag.entityList.size()) {
|
||||
tag.entityList.pop_front();
|
||||
}
|
||||
|
||||
translatedComment += translateSubtree(tag);
|
||||
}
|
||||
|
||||
void CSharpDocConverter::handleSummary(DoxygenEntity &tag, std::string &translatedComment, const std::string &) {
|
||||
|
||||
translatedComment += "<summary>";
|
||||
std::string summary = translateSubtree(tag);
|
||||
|
||||
eraseAllNewLine(summary);
|
||||
trimWhitespace(summary);
|
||||
// remove final newlines
|
||||
eraseTrailingSpaceNewLines(summary);
|
||||
escapeSpecificCharacters(summary);
|
||||
|
||||
translatedComment += summary;
|
||||
|
||||
|
||||
translatedComment += "</summary>";
|
||||
translatedComment += "\n";
|
||||
}
|
||||
|
||||
void CSharpDocConverter::handleLine(DoxygenEntity &tag, std::string &translatedComment, const std::string &tagName) {
|
||||
|
||||
translatedComment += "<" + tagName + ">";
|
||||
if (tag.entityList.size()) {
|
||||
translatedComment += tag.entityList.begin()->data;
|
||||
tag.entityList.pop_front();
|
||||
}
|
||||
translatedComment += "</" + tagName + ">";
|
||||
}
|
||||
|
||||
|
||||
void CSharpDocConverter::handleNotHandled(DoxygenEntity &tag, std::string &translatedComment, const std::string &) {
|
||||
|
||||
std::string paragraph = translateSubtree(tag);
|
||||
|
||||
eraseLeadingNewLine(paragraph);
|
||||
eraseTrailingSpaceNewLines(paragraph);
|
||||
trimWhitespace(paragraph);
|
||||
escapeSpecificCharacters(paragraph);
|
||||
translatedComment += paragraph;
|
||||
translatedComment += "\n";
|
||||
}
|
||||
|
||||
void CSharpDocConverter::handleAddList(DoxygenEntity &tag, std::string &translatedComment, const std::string &) {
|
||||
std::string listItem = translateSubtree(tag);
|
||||
eraseAllNewLine(listItem);
|
||||
|
||||
translatedComment += "* ";
|
||||
translatedComment += listItem;
|
||||
translatedComment += "\n";
|
||||
}
|
||||
|
||||
|
||||
void CSharpDocConverter::handleParagraph(DoxygenEntity &tag, std::string &translatedComment, const std::string &tagName) {
|
||||
translatedComment += "<";
|
||||
translatedComment += tagName;
|
||||
translatedComment += ">";
|
||||
|
||||
std::string paragraph = translateSubtree(tag);
|
||||
|
||||
eraseAllNewLine(paragraph);
|
||||
trimWhitespace(paragraph);
|
||||
eraseTrailingSpaceNewLines(paragraph);
|
||||
escapeSpecificCharacters(paragraph);
|
||||
|
||||
translatedComment += paragraph;
|
||||
|
||||
translatedComment += "</";
|
||||
translatedComment += tagName;
|
||||
translatedComment += ">\n";
|
||||
}
|
||||
|
||||
void CSharpDocConverter::handleVerbatimBlock(DoxygenEntity &tag, std::string &translatedComment, const std::string &) {
|
||||
string verb = translateSubtree(tag);
|
||||
|
||||
eraseLeadingNewLine(verb);
|
||||
|
||||
// Remove the last newline to prevent doubling the newline already present after \endverbatim
|
||||
trimWhitespace(verb); // Needed to catch trailing newline below
|
||||
eraseTrailingSpaceNewLines(verb);
|
||||
escapeSpecificCharacters(verb);
|
||||
|
||||
translatedComment += verb;
|
||||
}
|
||||
|
||||
void CSharpDocConverter::handleMath(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg) {
|
||||
IndentGuard indent;
|
||||
|
||||
// Only \f$ is translated to inline formulae, \f[ and \f{ are for the block ones.
|
||||
const bool inlineFormula = tag.typeOfEntity == "f$";
|
||||
|
||||
string formulaNL;
|
||||
|
||||
if (inlineFormula) {
|
||||
translatedComment += ":math:`";
|
||||
} else {
|
||||
indent.Init(translatedComment, m_indent);
|
||||
|
||||
trimWhitespace(translatedComment);
|
||||
|
||||
const string formulaIndent = indent.getFirstLineIndent();
|
||||
translatedComment += formulaIndent;
|
||||
translatedComment += ".. math::\n";
|
||||
|
||||
formulaNL = '\n';
|
||||
formulaNL += formulaIndent;
|
||||
formulaNL += m_indent;
|
||||
translatedComment += formulaNL;
|
||||
}
|
||||
|
||||
std::string formula;
|
||||
handleTagVerbatim(tag, formula, arg);
|
||||
|
||||
// It is important to ensure that we have no spaces around the inline math
|
||||
// contents, so strip them.
|
||||
const size_t start = formula.find_first_not_of(" \t\n");
|
||||
const size_t end = formula.find_last_not_of(" \t\n");
|
||||
if (start != std::string::npos) {
|
||||
for (size_t n = start; n <= end; n++) {
|
||||
if (formula[n] == '\n') {
|
||||
// New lines must be suppressed in inline maths and indented in the block ones.
|
||||
if (!inlineFormula)
|
||||
translatedComment += formulaNL;
|
||||
} else {
|
||||
// Just copy everything else.
|
||||
translatedComment += formula[n];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (inlineFormula) {
|
||||
translatedComment += "`";
|
||||
}
|
||||
}
|
||||
|
||||
void CSharpDocConverter::handleCode(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg) {
|
||||
IndentGuard indent(translatedComment, m_indent);
|
||||
|
||||
trimWhitespace(translatedComment);
|
||||
|
||||
translatedComment += "<code>";
|
||||
|
||||
std::string code;
|
||||
handleTagVerbatim(tag, code, arg);
|
||||
|
||||
// Try and remove leading newline, which is present for block \code
|
||||
// command:
|
||||
escapeSpecificCharacters(code);
|
||||
eraseLeadingNewLine(code);
|
||||
trimWhitespace(code);
|
||||
|
||||
// Check for python doctest blocks, and treat them specially:
|
||||
bool isDocTestBlock = false;
|
||||
size_t startPos;
|
||||
// ">>>" would normally appear at the beginning, but doxygen comment
|
||||
// style may have space in front, so skip leading whitespace
|
||||
if ((startPos = code.find_first_not_of(" \t")) != string::npos && code.substr(startPos, 3) == ">>>")
|
||||
isDocTestBlock = true;
|
||||
|
||||
string codeIndent;
|
||||
if (!isDocTestBlock) {
|
||||
// Use the current indent for the code-block line itself.
|
||||
translatedComment += indent.getFirstLineIndent();
|
||||
|
||||
// Specify the level of extra indentation that will be used for
|
||||
// subsequent lines within the code block. Note that the correct
|
||||
// "starting indentation" is already present in the input, so we
|
||||
// only need to add the desired code block indentation.
|
||||
codeIndent = m_indent;
|
||||
}
|
||||
|
||||
translatedComment += codeIndent;
|
||||
for (size_t n = 0; n < code.length(); n++) {
|
||||
if (code[n] == '\n') {
|
||||
// Don't leave trailing white space, this results in PEP8 validation
|
||||
// errors in Python code (which are performed by our own unit tests).
|
||||
trimWhitespace(translatedComment);
|
||||
translatedComment += '\n';
|
||||
|
||||
// Ensure that we indent all the lines by the code indent.
|
||||
translatedComment += codeIndent;
|
||||
} else {
|
||||
// Just copy everything else.
|
||||
translatedComment += code[n];
|
||||
}
|
||||
}
|
||||
|
||||
trimWhitespace(translatedComment);
|
||||
|
||||
// For block commands, the translator adds the newline after
|
||||
// \endcode, so try and compensate by removing the last newline from
|
||||
// the code text:
|
||||
eraseTrailingSpaceNewLines(translatedComment);
|
||||
|
||||
translatedComment += "</code>";
|
||||
translatedComment += "\n";
|
||||
}
|
||||
|
||||
void CSharpDocConverter::handlePlainString(DoxygenEntity &tag, std::string &translatedComment, const std::string &) {
|
||||
translatedComment += tag.data;
|
||||
}
|
||||
|
||||
void CSharpDocConverter::handleTagVerbatim(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg) {
|
||||
translatedComment += arg;
|
||||
for (DoxygenEntityListCIt it = tag.entityList.begin(); it != tag.entityList.end(); it++) {
|
||||
translatedComment += it->data;
|
||||
}
|
||||
}
|
||||
|
||||
void CSharpDocConverter::handleTagMessage(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg) {
|
||||
translatedComment += arg;
|
||||
handleParagraph(tag, translatedComment);
|
||||
translatedComment += "\">\n";
|
||||
}
|
||||
|
||||
void CSharpDocConverter::handleTagSee(DoxygenEntity &tag, std::string &translatedComment, const std::string &) {
|
||||
translatedComment += "<seealso cref=\"";
|
||||
std::string seeAlso = translateSubtree(tag);
|
||||
escapeSpecificCharacters(seeAlso);
|
||||
|
||||
// Remove parameter list
|
||||
// Alternative would be to try and convert them into C# types similar to Java implementation
|
||||
std::string::size_type lbrace = seeAlso.find('(');
|
||||
if (lbrace != std::string::npos)
|
||||
seeAlso.erase(lbrace);
|
||||
|
||||
replaceAll(seeAlso, "::", ".");
|
||||
eraseTrailingSpaceNewLines(seeAlso);
|
||||
|
||||
translatedComment += seeAlso;
|
||||
translatedComment += "\"/>\n";
|
||||
}
|
||||
|
||||
void CSharpDocConverter::handleTagCharReplace(DoxygenEntity &, std::string &translatedComment, const std::string &arg) {
|
||||
translatedComment += arg;
|
||||
}
|
||||
|
||||
void CSharpDocConverter::handleTagChar(DoxygenEntity &tag, std::string &translatedComment, const std::string &) {
|
||||
translatedComment += tag.typeOfEntity;
|
||||
}
|
||||
|
||||
void CSharpDocConverter::handleTagIf(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg) {
|
||||
translatedComment += arg;
|
||||
if (tag.entityList.size()) {
|
||||
translatedComment += tag.entityList.begin()->data;
|
||||
tag.entityList.pop_front();
|
||||
translatedComment += " {" + translateSubtree(tag) + "}";
|
||||
}
|
||||
}
|
||||
|
||||
void CSharpDocConverter::handleTagWord(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg) {
|
||||
translatedComment += arg + ": ";
|
||||
if (tag.entityList.size())
|
||||
translatedComment += tag.entityList.begin()->data;
|
||||
tag.entityList.pop_front();
|
||||
translatedComment += translateSubtree(tag);
|
||||
translatedComment += "\n";
|
||||
}
|
||||
|
||||
void CSharpDocConverter::handleTagImage(DoxygenEntity &tag, std::string &translatedComment, const std::string &) {
|
||||
if (tag.entityList.size() < 2)
|
||||
return;
|
||||
tag.entityList.pop_front();
|
||||
translatedComment += "Image: ";
|
||||
translatedComment += tag.entityList.begin()->data;
|
||||
tag.entityList.pop_front();
|
||||
if (tag.entityList.size())
|
||||
translatedComment += "(" + tag.entityList.begin()->data + ")";
|
||||
}
|
||||
|
||||
void CSharpDocConverter::handleTagParam(DoxygenEntity &tag, std::string &translatedComment, const std::string &) {
|
||||
|
||||
if (tag.entityList.size() < 2)
|
||||
return;
|
||||
|
||||
if (!paramExists(tag.entityList.begin()->data))
|
||||
return;
|
||||
|
||||
IndentGuard indent(translatedComment, m_indent);
|
||||
|
||||
DoxygenEntity paramNameEntity = *tag.entityList.begin();
|
||||
tag.entityList.pop_front();
|
||||
|
||||
const std::string ¶mName = paramNameEntity.data;
|
||||
|
||||
const std::string paramValue = getParamValue(paramName);
|
||||
|
||||
translatedComment += "<param name=\"" + paramName + "\">";
|
||||
|
||||
translatedComment += translateSubtree(tag);
|
||||
eraseTrailingSpaceNewLines(translatedComment);
|
||||
|
||||
translatedComment += "</param> \n";
|
||||
}
|
||||
|
||||
|
||||
void CSharpDocConverter::handleTagReturn(DoxygenEntity &tag, std::string &translatedComment, const std::string &) {
|
||||
IndentGuard indent(translatedComment, m_indent);
|
||||
|
||||
translatedComment += "<returns>";
|
||||
translatedComment += translateSubtree(tag);
|
||||
eraseTrailingSpaceNewLines(translatedComment);
|
||||
translatedComment += "</returns> \n";
|
||||
}
|
||||
|
||||
|
||||
void CSharpDocConverter::handleTagException(DoxygenEntity &tag, std::string &translatedComment, const std::string &) {
|
||||
IndentGuard indent(translatedComment, m_indent);
|
||||
|
||||
DoxygenEntity paramNameEntity = *tag.entityList.begin();
|
||||
tag.entityList.pop_front();
|
||||
|
||||
const std::string ¶mName = paramNameEntity.data;
|
||||
|
||||
const std::string paramType = getParamType(paramName);
|
||||
const std::string paramValue = getParamValue(paramName);
|
||||
|
||||
translatedComment += "<exception cref=\"" + paramName + "\">";
|
||||
|
||||
translatedComment += translateSubtree(tag);
|
||||
eraseTrailingSpaceNewLines(translatedComment);
|
||||
|
||||
translatedComment += "</exception> \n";
|
||||
}
|
||||
|
||||
|
||||
void CSharpDocConverter::handleTagRef(DoxygenEntity &tag, std::string &translatedComment, const std::string &) {
|
||||
|
||||
if (!tag.entityList.size())
|
||||
return;
|
||||
|
||||
string anchor = tag.entityList.begin()->data;
|
||||
tag.entityList.pop_front();
|
||||
string anchorText = anchor;
|
||||
|
||||
size_t pos = anchorText.find('#');
|
||||
if (pos != string::npos) {
|
||||
anchorText = anchorText.substr(pos + 1);
|
||||
}
|
||||
|
||||
if (!tag.entityList.empty()) {
|
||||
anchorText = tag.entityList.begin()->data;
|
||||
}
|
||||
translatedComment += "\\ref " + anchorText;
|
||||
}
|
||||
|
||||
|
||||
void CSharpDocConverter::handleTagWrap(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg) {
|
||||
if (tag.entityList.size()) { // do not include empty tags
|
||||
std::string tagData = translateSubtree(tag);
|
||||
// wrap the thing, ignoring whitespace
|
||||
size_t wsPos = tagData.find_last_not_of("\n\t ");
|
||||
if (wsPos != std::string::npos && wsPos != tagData.size() - 1)
|
||||
translatedComment += arg + tagData.substr(0, wsPos + 1) + arg + tagData.substr(wsPos + 1);
|
||||
else
|
||||
translatedComment += arg + tagData + arg;
|
||||
}
|
||||
}
|
||||
|
||||
void CSharpDocConverter::handleDoxyHtmlTag(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg) {
|
||||
std::string htmlTagArgs = tag.data;
|
||||
if (htmlTagArgs == "/") {
|
||||
// end html tag, for example "</ul>
|
||||
// translatedComment += "</" + arg.substr(1) + ">";
|
||||
} else {
|
||||
translatedComment += arg + htmlTagArgs;
|
||||
}
|
||||
}
|
||||
|
||||
void CSharpDocConverter::handleDoxyHtmlTagNoParam(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg) {
|
||||
std::string htmlTagArgs = tag.data;
|
||||
if (htmlTagArgs == "/") {
|
||||
// end html tag, for example "</ul>
|
||||
} else {
|
||||
translatedComment += arg;
|
||||
}
|
||||
}
|
||||
|
||||
void CSharpDocConverter::handleDoxyHtmlTag_A(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg) {
|
||||
std::string htmlTagArgs = tag.data;
|
||||
if (htmlTagArgs == "/") {
|
||||
// end html tag, "</a>
|
||||
translatedComment += " (" + m_url + ')';
|
||||
m_url.clear();
|
||||
} else {
|
||||
m_url.clear();
|
||||
size_t pos = htmlTagArgs.find('=');
|
||||
if (pos != string::npos) {
|
||||
m_url = htmlTagArgs.substr(pos + 1);
|
||||
}
|
||||
translatedComment += arg;
|
||||
}
|
||||
}
|
||||
|
||||
void CSharpDocConverter::handleDoxyHtmlTag2(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg) {
|
||||
std::string htmlTagArgs = tag.data;
|
||||
if (htmlTagArgs == "/") {
|
||||
// end html tag, for example "</em>
|
||||
translatedComment += arg;
|
||||
} else {
|
||||
translatedComment += arg;
|
||||
}
|
||||
}
|
||||
|
||||
void CSharpDocConverter::handleDoxyHtmlTag_tr(DoxygenEntity &tag, std::string &translatedComment, const std::string &) {
|
||||
std::string htmlTagArgs = tag.data;
|
||||
size_t nlPos = translatedComment.rfind('\n');
|
||||
if (htmlTagArgs == "/") {
|
||||
// end tag, </tr> appends vertical table line '|'
|
||||
translatedComment += '|';
|
||||
if (nlPos != string::npos) {
|
||||
size_t startOfTableLinePos = translatedComment.find_first_not_of(" \t", nlPos + 1);
|
||||
if (startOfTableLinePos != string::npos) {
|
||||
m_tableLineLen = translatedComment.size() - startOfTableLinePos;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (m_prevRowIsTH) {
|
||||
// if previous row contained <th> tag, add horizontal separator
|
||||
// but first get leading spaces, because they'll be needed for the next row
|
||||
size_t numLeadingSpaces = translatedComment.size() - nlPos - 1;
|
||||
|
||||
translatedComment += string(m_tableLineLen, '-') + '\n';
|
||||
|
||||
if (nlPos != string::npos) {
|
||||
translatedComment += string (numLeadingSpaces, ' ');
|
||||
}
|
||||
m_prevRowIsTH = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CSharpDocConverter::handleDoxyHtmlTag_th(DoxygenEntity &tag, std::string &translatedComment, const std::string &) {
|
||||
std::string htmlTagArgs = tag.data;
|
||||
if (htmlTagArgs == "/") {
|
||||
// end tag, </th> is ignored
|
||||
} else {
|
||||
translatedComment += '|';
|
||||
m_prevRowIsTH = true;
|
||||
}
|
||||
}
|
||||
|
||||
void CSharpDocConverter::handleDoxyHtmlTag_td(DoxygenEntity &tag, std::string &translatedComment, const std::string &) {
|
||||
std::string htmlTagArgs = tag.data;
|
||||
if (htmlTagArgs == "/") {
|
||||
// end tag, </td> is ignored
|
||||
} else {
|
||||
translatedComment += '|';
|
||||
}
|
||||
}
|
||||
|
||||
void CSharpDocConverter::handleHtmlEntity(DoxygenEntity &, std::string &translatedComment, const std::string &arg) {
|
||||
// html entities
|
||||
translatedComment += arg;
|
||||
}
|
||||
|
||||
void CSharpDocConverter::handleNewLine(DoxygenEntity &, std::string &translatedComment, const std::string &) {
|
||||
trimWhitespace(translatedComment);
|
||||
|
||||
translatedComment += "\n";
|
||||
|
||||
if (!m_indent.empty())
|
||||
translatedComment += m_indent;
|
||||
}
|
||||
|
||||
String *CSharpDocConverter::makeDocumentation(Node *n) {
|
||||
String *documentation;
|
||||
std::string csharpDocString;
|
||||
|
||||
// store the node, we may need it later
|
||||
currentNode = n;
|
||||
|
||||
documentation = getDoxygenComment(n);
|
||||
if (documentation != NULL) {
|
||||
if (GetFlag(n, "feature:doxygen:notranslate")) {
|
||||
String *comment = NewString("");
|
||||
Append(comment, documentation);
|
||||
Replaceall(comment, "\n *", "\n");
|
||||
csharpDocString = Char(comment);
|
||||
Delete(comment);
|
||||
} else {
|
||||
std::list<DoxygenEntity> entityList = parser.createTree(n, documentation);
|
||||
DoxygenEntity root("root", entityList);
|
||||
csharpDocString = translateSubtree(root);
|
||||
}
|
||||
}
|
||||
|
||||
// if we got something log the result
|
||||
if (!csharpDocString.empty()) {
|
||||
|
||||
// remove the last spaces and '\n' since additional one is added during writing to file
|
||||
eraseTrailingSpaceNewLines(csharpDocString);
|
||||
|
||||
// ensure that a blank line occurs before code or math blocks
|
||||
csharpDocString = padCodeAndVerbatimBlocks(csharpDocString);
|
||||
|
||||
if (m_flags & debug_translator) {
|
||||
std::cout << "\n---RESULT IN CSHARPDOC---" << std::endl;
|
||||
std::cout << csharpDocString;
|
||||
std::cout << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
return NewString(csharpDocString.c_str());
|
||||
}
|
|
@ -0,0 +1,243 @@
|
|||
/* -----------------------------------------------------------------------------
|
||||
* This file is part of SWIG, which is licensed as a whole under version 3
|
||||
* (or any later version) of the GNU General Public License. Some additional
|
||||
* terms also apply to certain portions of SWIG. The full details of the SWIG
|
||||
* license and copyrights can be found in the LICENSE and COPYRIGHT files
|
||||
* included with the SWIG source code as distributed by the SWIG developers
|
||||
* and at http://www.swig.org/legal.html.
|
||||
*
|
||||
* csharpdoc.h
|
||||
*
|
||||
* Module to return documentation for nodes formatted for CSharp
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
#ifndef CSHARPDOCCONVERTER_H_
|
||||
#define CSHARPDOCCONVERTER_H_
|
||||
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include "swig.h"
|
||||
#include "doxyentity.h"
|
||||
#include "doxytranslator.h"
|
||||
|
||||
#define DOC_STRING_LENGTH 64 // characters per line allowed
|
||||
#define DOC_PARAM_STRING_LENGTH 30 // characters reserved for param name / type
|
||||
|
||||
class CSharpDocConverter : public DoxygenTranslator {
|
||||
public:
|
||||
CSharpDocConverter(int flags = 0);
|
||||
|
||||
String *makeDocumentation(Node *node);
|
||||
|
||||
protected:
|
||||
|
||||
size_t m_tableLineLen;
|
||||
bool m_prevRowIsTH;
|
||||
std::string m_url;
|
||||
|
||||
/*
|
||||
* Translate every entity in a tree, also manages sections
|
||||
* display. Prints title for every group of tags that have
|
||||
* a section title associated with them
|
||||
*/
|
||||
std::string translateSubtree(DoxygenEntity &doxygenEntity);
|
||||
|
||||
/*
|
||||
* Translate one entity with the appropriate handler, according
|
||||
* to the tagHandlers
|
||||
*/
|
||||
void translateEntity(DoxygenEntity &doxyEntity, std::string &translatedComment);
|
||||
|
||||
/*
|
||||
* Typedef for the function that handles one tag
|
||||
* arg - some string argument to easily pass it through lookup table
|
||||
*/
|
||||
typedef void (CSharpDocConverter::*tagHandler) (DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
|
||||
|
||||
/*
|
||||
* Wrap the command data with the some string
|
||||
* arg - string to wrap with, like '_' or '*'
|
||||
*/
|
||||
void handleTagWrap(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
|
||||
|
||||
/*
|
||||
* Just prints new line
|
||||
*/
|
||||
void handleNewLine(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
|
||||
|
||||
/*
|
||||
* Replace char by the one ine argument
|
||||
*/
|
||||
void handleTagCharReplace(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
|
||||
|
||||
/*
|
||||
* Print the name of tag to the output, used for escape-commands
|
||||
*/
|
||||
void handleTagChar(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
|
||||
|
||||
/*
|
||||
* Format the contents of the \exception tag or its synonyms.
|
||||
*/
|
||||
void handleTagException(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
|
||||
|
||||
/**
|
||||
* Print the content without any tag
|
||||
*/
|
||||
void handleNotHandled(DoxygenEntity &tag, std::string &translatedComment, const std::string &tagName);
|
||||
|
||||
/**
|
||||
* Print the content as an item of a list
|
||||
*/
|
||||
void handleAddList(DoxygenEntity &tag, std::string &translatedComment, const std::string &tagName);
|
||||
|
||||
/*
|
||||
* Print only the content and strip original tag
|
||||
*/
|
||||
void handleParagraph(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg = std::string());
|
||||
|
||||
/*
|
||||
* Ignore the tag
|
||||
*/
|
||||
void handleIgnore(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg = std::string());
|
||||
|
||||
/*
|
||||
* Print only the line content and strip original tag
|
||||
*/
|
||||
void handleLine(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg = std::string());
|
||||
|
||||
/*
|
||||
* Print summary
|
||||
*/
|
||||
void handleSummary(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg = std::string());
|
||||
|
||||
/*
|
||||
* Handle Doxygen verbatim tag
|
||||
*/
|
||||
void handleVerbatimBlock(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg = std::string());
|
||||
|
||||
/*
|
||||
* Handle one of the Doxygen formula-related tags.
|
||||
*/
|
||||
void handleMath(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
|
||||
|
||||
/*
|
||||
* Handle a code snippet.
|
||||
*/
|
||||
void handleCode(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
|
||||
|
||||
/*
|
||||
* Print only data part of code
|
||||
*/
|
||||
void handlePlainString(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
|
||||
|
||||
/**
|
||||
* Copies verbatim args of the tag to output, used for commands like \f$, ...
|
||||
*/
|
||||
void handleTagVerbatim(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
|
||||
|
||||
/*
|
||||
* Print the if-elseif-else-endif section
|
||||
*/
|
||||
void handleTagIf(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
|
||||
|
||||
/*
|
||||
* Prints the specified message, than the contents of the tag
|
||||
* arg - message
|
||||
*/
|
||||
void handleTagMessage(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
|
||||
|
||||
/*
|
||||
* Prints the seealso tag
|
||||
*/
|
||||
void handleTagSee(DoxygenEntity &tag, std::string &translatedComment, const std::string &);
|
||||
|
||||
/*
|
||||
* Insert 'Word: ...'
|
||||
*/
|
||||
void handleTagWord(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
|
||||
|
||||
/*
|
||||
* Insert 'Image: ...'
|
||||
*/
|
||||
void handleTagImage(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
|
||||
|
||||
/*
|
||||
* Format nice param description with type information
|
||||
*/
|
||||
void handleTagParam(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
|
||||
|
||||
/*
|
||||
* Format the contents of the \return tag or its synonyms.
|
||||
*/
|
||||
void handleTagReturn(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
|
||||
|
||||
/*
|
||||
* Writes text for \ref tag.
|
||||
*/
|
||||
void handleTagRef(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
|
||||
|
||||
/* Handles HTML tags recognized by Doxygen, like <A ...>, <ul>, <table>, ... */
|
||||
|
||||
void handleDoxyHtmlTag(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
|
||||
|
||||
/** Does not output params of HTML tag, for example in <table border='1'>
|
||||
* 'border=1' is not written to output.
|
||||
*/
|
||||
void handleDoxyHtmlTagNoParam(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
|
||||
|
||||
/** Translates tag <a href = "url">text</a> to: text ("url"). */
|
||||
void handleDoxyHtmlTag_A(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
|
||||
|
||||
/*
|
||||
* Handles HTML tags, which are translated to markdown-like syntax, for example
|
||||
* <i>text</i> --> _text_. Appends arg for start HTML tag and end HTML tag.
|
||||
*/
|
||||
void handleDoxyHtmlTag2(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
|
||||
|
||||
/* Handles HTML table, tag <tr> */
|
||||
void handleDoxyHtmlTag_tr(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
|
||||
|
||||
/* Handles HTML table, tag <th> */
|
||||
void handleDoxyHtmlTag_th(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
|
||||
|
||||
/* Handles HTML table, tag <td> */
|
||||
void handleDoxyHtmlTag_td(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
|
||||
|
||||
/* Handles HTML entities recognized by Doxygen, like <, ©, ... */
|
||||
void handleHtmlEntity(DoxygenEntity &, std::string &translatedComment, const std::string &arg);
|
||||
|
||||
|
||||
/*
|
||||
* Simple helper function that calculates correct parameter type
|
||||
* of the node stored in 'currentNode'
|
||||
* If param with specified name is not found, empty string is returned
|
||||
*/
|
||||
std::string getParamType(std::string name);
|
||||
|
||||
/*
|
||||
* Simple helper function to retrieve the parameter value
|
||||
*/
|
||||
std::string getParamValue(std::string name);
|
||||
|
||||
private:
|
||||
// temporary thing, should be refactored somehow
|
||||
Node *currentNode;
|
||||
|
||||
// Extra indent for the current paragraph, must be output after each new line.
|
||||
std::string m_indent;
|
||||
|
||||
// this contains the handler pointer and one string argument
|
||||
typedef std::map<std::string, std::pair<tagHandler, std::string> >TagHandlersMap;
|
||||
static TagHandlersMap tagHandlers;
|
||||
|
||||
|
||||
// Helper functions for fillStaticTables(): make a new tag handler object.
|
||||
TagHandlersMap::mapped_type make_handler(tagHandler handler);
|
||||
TagHandlersMap::mapped_type make_handler(tagHandler handler, const char *arg);
|
||||
|
||||
void fillStaticTables();
|
||||
|
||||
bool paramExists(std::string param);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -15,7 +15,6 @@
|
|||
#include "swigwarn.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
using std::string;
|
||||
|
|
|
@ -34,6 +34,8 @@ eswig_SOURCES = CParse/cscanner.c \
|
|||
DOH/memory.c \
|
||||
DOH/string.c \
|
||||
DOH/void.c \
|
||||
Doxygen/csharpdoc.cxx \
|
||||
Doxygen/csharpdoc.h \
|
||||
Doxygen/doxyentity.cxx \
|
||||
Doxygen/doxyentity.h \
|
||||
Doxygen/doxyparser.cxx \
|
||||
|
@ -121,7 +123,7 @@ distclean-local:
|
|||
# swig executable as a way of checking before and after the 'beautifying'.
|
||||
# Single files can be beautified with the beautify-file target, eg: 'make beautify-file INDENTFILE=chosenfile.c'
|
||||
|
||||
SWIGTYPEDEFS=-T bool -T File -T DohObjInfo -T Parm -T Language -T List -T TargetLanguageModule -T Typetab -T ModuleFactory -T ErrorMessageFormat -T Symtab -T Hash -T Scanner -T String -T DohBase -T Node -T String_or_char -T SwigType -T Dispatcher -T Wrapper -T DohStringMethods -T DohFileMethods -T DohListMethods -T DohHashMethods -T DOH -T DohIterator -T ParmList -T FILE -T HashNode -T DOHObj_or_char -T DOHFile -T DOHString -T DOHString_or_char -T UpcallData
|
||||
SWIGTYPEDEFS=-T bool -T File -T DohObjInfo -T Parm -T Language -T List -T TargetLanguageModule -T Typetab -T ModuleFactory -T ErrorMessageFormat -T Symtab -T Hash -T Scanner -T String -T DohBase -T Node -T String_or_char -T SwigType -T Dispatcher -T Wrapper -T DohStringMethods -T DohFileMethods -T DohListMethods -T DohHashMethods -T DOH -T DohIterator -T ParmList -T FILE -T HashNode -T DOHObj_or_char -T DOHFile -T DOHString -T DOHString_or_char -T UpcallData -T DoxygenEntity -T string
|
||||
INDENTBAKSDIR=../IndentBaks
|
||||
|
||||
beautify:
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "cparse.h"
|
||||
#include <limits.h> // for INT_MAX
|
||||
#include <ctype.h>
|
||||
#include <csharpdoc.h>
|
||||
|
||||
/* Hash type used for upcalls from C/C++ */
|
||||
typedef DOH UpcallData;
|
||||
|
@ -46,6 +47,7 @@ class CSHARP:public Language {
|
|||
bool global_variable_flag; // Flag for when wrapping a global variable
|
||||
bool old_variable_names; // Flag for old style variable names in the intermediary class
|
||||
bool generate_property_declaration_flag; // Flag for generating properties
|
||||
bool doxygen; // Flag for Doxygen generation
|
||||
|
||||
String *imclass_name; // intermediary class name
|
||||
String *module_class_name; // module class name
|
||||
|
@ -123,6 +125,7 @@ public:
|
|||
global_variable_flag(false),
|
||||
old_variable_names(false),
|
||||
generate_property_declaration_flag(false),
|
||||
doxygen(false),
|
||||
imclass_name(NULL),
|
||||
module_class_name(NULL),
|
||||
imclass_class_code(NULL),
|
||||
|
@ -171,6 +174,14 @@ public:
|
|||
directorLanguage();
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* ~CSHARP()
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
~CSHARP() {
|
||||
delete doxygenTranslator;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* getProxyName()
|
||||
*
|
||||
|
@ -223,6 +234,8 @@ public:
|
|||
|
||||
SWIG_library_directory("csharp");
|
||||
|
||||
int doxygen_translator_flags = 0;
|
||||
|
||||
// Look for certain command line options
|
||||
for (int i = 1; i < argc; i++) {
|
||||
if (argv[i]) {
|
||||
|
@ -266,12 +279,25 @@ public:
|
|||
} else {
|
||||
Swig_arg_error();
|
||||
}
|
||||
} else if (strcmp(argv[i], "-doxygen") == 0) {
|
||||
doxygen = true;
|
||||
scan_doxygen_comments = 1;
|
||||
Swig_mark_arg(i);
|
||||
} else if (strcmp(argv[i], "-debug-doxygen-translator") == 0) {
|
||||
doxygen_translator_flags |= DoxygenTranslator::debug_translator;
|
||||
Swig_mark_arg(i);
|
||||
} else if (strcmp(argv[i], "-debug-doxygen-parser") == 0) {
|
||||
doxygen_translator_flags |= DoxygenTranslator::debug_parser;
|
||||
Swig_mark_arg(i);
|
||||
} else if (strcmp(argv[i], "-help") == 0) {
|
||||
Printf(stdout, "%s\n", usage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (doxygen)
|
||||
doxygenTranslator = new CSharpDocConverter(doxygen_translator_flags);
|
||||
|
||||
// Add a symbol to the parser for conditional compilation
|
||||
Preprocessor_define("SWIGCSHARP 1", 0);
|
||||
|
||||
|
@ -1185,6 +1211,13 @@ public:
|
|||
EnumFeature enum_feature = decodeEnumFeature(n);
|
||||
String *typemap_lookup_type = Getattr(n, "name");
|
||||
|
||||
// Translate documentation comments
|
||||
if (have_docstring(n)) {
|
||||
String *ds = docstring(n, tab0);
|
||||
Printv(enum_code, ds, NIL);
|
||||
Delete(ds);
|
||||
}
|
||||
|
||||
if ((enum_feature != SimpleEnum) && symname && typemap_lookup_type) {
|
||||
// Wrap (non-anonymous) C/C++ enum within a typesafe, typeunsafe or proper C# enum
|
||||
|
||||
|
@ -1394,6 +1427,12 @@ public:
|
|||
if (csattributes)
|
||||
Printf(enum_code, " %s\n", csattributes);
|
||||
|
||||
// Translate documentation comments
|
||||
if (have_docstring(n)) {
|
||||
String *ds = docstring(n, tab2);
|
||||
Printv(enum_code, ds, NIL);
|
||||
Delete(ds);
|
||||
}
|
||||
Printf(enum_code, " %s", symname);
|
||||
|
||||
// Check for the %csconstvalue feature
|
||||
|
@ -1551,6 +1590,13 @@ public:
|
|||
const String *methodmods = Getattr(n, "feature:cs:methodmodifiers");
|
||||
methodmods = methodmods ? methodmods : (is_public(n) ? public_string : protected_string);
|
||||
|
||||
// Translate documentation comments
|
||||
if (have_docstring(n)) {
|
||||
String *ds = docstring(n, tab2);
|
||||
Printv(constants_code, ds, NIL);
|
||||
Delete(ds);
|
||||
}
|
||||
|
||||
Printf(constants_code, " %s %s %s %s = ", methodmods, (const_feature_flag ? "const" : "static readonly"), return_type, itemname);
|
||||
|
||||
// Check for the %csconstvalue feature
|
||||
|
@ -2227,6 +2273,13 @@ public:
|
|||
|
||||
Language::classHandler(n);
|
||||
|
||||
// Translate documentation comments
|
||||
if (have_docstring(n)) {
|
||||
String *ds = docstring(n, tab0);
|
||||
Printv(proxy_class_def, ds, NIL);
|
||||
Delete(ds);
|
||||
}
|
||||
|
||||
if (proxy_flag) {
|
||||
|
||||
emitProxyClassDefAndCPPCasts(n);
|
||||
|
@ -2404,6 +2457,7 @@ public:
|
|||
Parm *p;
|
||||
Parm *last_parm = 0;
|
||||
int i;
|
||||
String *comment_code = NewString("");
|
||||
String *imcall = NewString("");
|
||||
String *return_type = NewString("");
|
||||
String *function_code = NewString("");
|
||||
|
@ -2501,7 +2555,6 @@ public:
|
|||
Printf(function_code, "%s %s(", return_type, proxy_function_name);
|
||||
if (is_interface)
|
||||
Printf(interface_class_code, " %s %s(", return_type, proxy_function_name);
|
||||
|
||||
|
||||
Printv(imcall, full_imclass_name, ".$imfuncname(", NIL);
|
||||
if (!static_flag)
|
||||
|
@ -2601,6 +2654,13 @@ public:
|
|||
if (is_interface)
|
||||
Printf(interface_class_code, ");\n");
|
||||
|
||||
// Translate documentation comments
|
||||
if (have_docstring(n)) {
|
||||
String *ds = docstring(n, tab2);
|
||||
Printv(comment_code, ds, NIL);
|
||||
Delete(ds);
|
||||
}
|
||||
|
||||
// Transform return type used in PInvoke function (in intermediary class) to type used in C# wrapper function (in proxy class)
|
||||
if ((tm = Swig_typemap_lookup("csout", n, "", 0))) {
|
||||
excodeSubstitute(n, tm, "csout", n);
|
||||
|
@ -2695,6 +2755,13 @@ public:
|
|||
if (!methodmods)
|
||||
methodmods = (is_public(n) ? public_string : protected_string);
|
||||
|
||||
// Translate documentation comments
|
||||
if (have_docstring(n)) {
|
||||
String *ds = docstring(n, tab2);
|
||||
Printv(proxy_class_code, ds, NIL);
|
||||
Delete(ds);
|
||||
}
|
||||
|
||||
// Start property declaration
|
||||
Printf(proxy_class_code, " %s %s%s %s {", methodmods, static_flag ? "static " : "", variable_type, variable_name);
|
||||
}
|
||||
|
@ -2734,6 +2801,7 @@ public:
|
|||
} else {
|
||||
// Normal function call
|
||||
Printf(function_code, " %s\n\n", tm ? (const String *) tm : empty_string);
|
||||
Printv(proxy_class_code, comment_code, NIL);
|
||||
Printv(proxy_class_code, function_code, NIL);
|
||||
}
|
||||
|
||||
|
@ -2756,6 +2824,7 @@ public:
|
|||
Parm *p;
|
||||
int i;
|
||||
String *function_code = NewString("");
|
||||
String *comment_code = NewString("");
|
||||
String *helper_code = NewString(""); // Holds code for the constructor helper method generated only when the csin typemap has code in the pre or post attributes
|
||||
String *helper_args = NewString("");
|
||||
String *pre_code = NewString("");
|
||||
|
@ -2952,6 +3021,14 @@ public:
|
|||
Replaceall(function_code, "$imcall", imcall);
|
||||
}
|
||||
|
||||
// Translate documentation comments
|
||||
if (have_docstring(n)) {
|
||||
String *ds = docstring(n, tab2);
|
||||
Printv(comment_code, ds, NIL);
|
||||
Delete(ds);
|
||||
}
|
||||
|
||||
Printv(proxy_class_code, comment_code, NIL);
|
||||
Printv(proxy_class_code, function_code, "\n", NIL);
|
||||
|
||||
Delete(helper_args);
|
||||
|
@ -3132,6 +3209,14 @@ public:
|
|||
Printf(function_code, " %s\n", csattributes);
|
||||
const String *methodmods = Getattr(n, "feature:cs:methodmodifiers");
|
||||
methodmods = methodmods ? methodmods : (is_public(n) ? public_string : protected_string);
|
||||
|
||||
// Translate documentation comments
|
||||
if (have_docstring(n)) {
|
||||
String *ds = docstring(n, tab2);
|
||||
Printv(function_code, ds, NIL);
|
||||
Delete(ds);
|
||||
}
|
||||
|
||||
Printf(function_code, " %s static %s %s(", methodmods, return_type, func_name);
|
||||
Printv(imcall, imclass_name, ".", overloaded_name, "(", NIL);
|
||||
|
||||
|
@ -4665,6 +4750,134 @@ public:
|
|||
Delete(dirclassname);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------
|
||||
* have_docstring()
|
||||
*
|
||||
* Check for Doxygen comments
|
||||
*--------------------------------------------------------------------*/
|
||||
|
||||
bool have_docstring(Node *n) {
|
||||
/* autodoc and docstring features not supported in C#
|
||||
String *str = Getattr(n, "feature:docstring");
|
||||
|
||||
return ((str && Len(str) > 0)
|
||||
|| (Getattr(n, "feature:autodoc") && !GetFlag(n, "feature:noautodoc"))
|
||||
|| (doxygen && doxygenTranslator->hasDocumentation(n))
|
||||
);
|
||||
*/
|
||||
return doxygen && doxygenTranslator->hasDocumentation(n);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------
|
||||
* docstring()
|
||||
*
|
||||
* Get documentation comments, if any
|
||||
*
|
||||
* Return new documentation string to be deleted by caller (never NULL but
|
||||
* may be empty if there is no docstring).
|
||||
*--------------------------------------------------------------------*/
|
||||
|
||||
String *docstring(Node *n, const char *indent = "") {
|
||||
String *docstr = NULL;
|
||||
|
||||
if (doxygen && doxygenTranslator->hasDocumentation(n)) {
|
||||
docstr = doxygenTranslator->getDocumentation(n, 0);
|
||||
}
|
||||
|
||||
if (!docstr)
|
||||
docstr = NewString("");
|
||||
|
||||
// If there is more than one line then make docstrings like this:
|
||||
//
|
||||
// This is line1
|
||||
// And here is line2 followed by the rest of them
|
||||
//
|
||||
// otherwise, put it all on a single line
|
||||
if (Strchr(docstr, '\n')) {
|
||||
String *tmp = NewString("");
|
||||
Append(tmp, indent_docstring(docstr, indent));
|
||||
Delete(docstr);
|
||||
docstr = tmp;
|
||||
} else {
|
||||
String *tmp = NewString(indent);
|
||||
Append(tmp, "/// ");
|
||||
Append(tmp, docstr);
|
||||
Append(tmp, "\n");
|
||||
Delete(docstr);
|
||||
docstr = tmp;
|
||||
}
|
||||
|
||||
return docstr;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------
|
||||
* indent_docstring()
|
||||
*
|
||||
* Format (indent) a CSharp docstring.
|
||||
* Remove leading whitespace from 'code' and re-indent using
|
||||
* the indentation string in 'indent'.
|
||||
* ------------------------------------------------------------ */
|
||||
|
||||
String *indent_docstring(const String *code, const char *indent) {
|
||||
String *out = NewString("");
|
||||
String *temp;
|
||||
char *t;
|
||||
if (!indent)
|
||||
indent = "";
|
||||
|
||||
temp = NewString(code);
|
||||
|
||||
t = Char(temp);
|
||||
if (*t == '{') {
|
||||
Delitem(temp, 0);
|
||||
Delitem(temp, DOH_END);
|
||||
}
|
||||
|
||||
/* Split the input text into lines */
|
||||
List *clist = SplitLines(temp);
|
||||
Delete(temp);
|
||||
|
||||
Iterator si;
|
||||
|
||||
int truncate_characters_count = INT_MAX;
|
||||
for (si = First(clist); si.item; si = Next(si)) {
|
||||
const char *c = Char(si.item);
|
||||
int i;
|
||||
for (i = 0; isspace((unsigned char)c[i]); i++) {
|
||||
// Scan forward until we find a non-space (which may be a null byte).
|
||||
}
|
||||
char ch = c[i];
|
||||
if (ch) {
|
||||
// Found a line which isn't just whitespace
|
||||
if (i < truncate_characters_count)
|
||||
truncate_characters_count = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (truncate_characters_count == INT_MAX)
|
||||
truncate_characters_count = 0;
|
||||
|
||||
for (si = First(clist); si.item; si = Next(si)) {
|
||||
const char *c = Char(si.item);
|
||||
|
||||
int i;
|
||||
for (i = 0; isspace((unsigned char)c[i]); i++) {
|
||||
// Scan forward until we find a non-space (which may be a null byte).
|
||||
}
|
||||
char ch = c[i];
|
||||
if (!ch) {
|
||||
// Line is just whitespace - emit an empty line.
|
||||
Printv(out, indent, "///", NIL);
|
||||
Putc('\n', out);
|
||||
continue;
|
||||
}
|
||||
|
||||
Printv(out, indent, "/// ", c + truncate_characters_count, "\n", NIL);
|
||||
}
|
||||
Delete(clist);
|
||||
return out;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
* nestedClassesSupport()
|
||||
*--------------------------------------------------------------------*/
|
||||
|
|
|
@ -1384,7 +1384,7 @@ public:
|
|||
* the indentation string in 'indent'.
|
||||
* ------------------------------------------------------------ */
|
||||
|
||||
String *indent_docstring(const String *code, const_String_or_char_ptr indent) {
|
||||
String *indent_docstring(const String *code, const char *indent) {
|
||||
String *out = NewString("");
|
||||
String *temp;
|
||||
char *t;
|
||||
|
@ -1523,7 +1523,7 @@ public:
|
|||
* may be empty if there is no docstring).
|
||||
* ------------------------------------------------------------ */
|
||||
|
||||
String *build_combined_docstring(Node *n, autodoc_t ad_type, const String *indent = "", bool low_level = false) {
|
||||
String *build_combined_docstring(Node *n, autodoc_t ad_type, const char *indent = "", bool low_level = false) {
|
||||
bool add_autodoc = true;
|
||||
String *docstr = Getattr(n, "feature:docstring");
|
||||
if (docstr) {
|
||||
|
@ -1612,7 +1612,7 @@ public:
|
|||
* set then it will build a combined docstring.
|
||||
* ------------------------------------------------------------ */
|
||||
|
||||
String *docstring(Node *n, autodoc_t ad_type, const String *indent, bool low_level = false) {
|
||||
String *docstring(Node *n, autodoc_t ad_type, const char *indent, bool low_level = false) {
|
||||
String *docstr = build_combined_docstring(n, ad_type, indent, low_level);
|
||||
const int len = Len(docstr);
|
||||
if (!len)
|
||||
|
|
|
@ -40,6 +40,7 @@ extern String *argc_template_string;
|
|||
|
||||
/* Miscellaneous stuff */
|
||||
|
||||
#define tab0 ""
|
||||
#define tab2 " "
|
||||
#define tab4 " "
|
||||
#define tab8 " "
|
||||
|
|
Loading…
Reference in New Issue