diff options
19 files changed, 466 insertions, 43 deletions
diff --git a/.travis.yml b/.travis.yml index 60196c3c5..bf9010973 100644 --- a/.travis.yml +++ b/.travis.yml @@ -383,6 +383,18 @@ matrix: env: SWIGLANG=python GCC=8 CPP17=1 PY3=3 VER=3.7 sudo: required dist: xenial + - os: linux + env: SWIGLANG=csharp GCC=9 CPP17=1 + sudo: required + dist: xenial + - os: linux + env: SWIGLANG=java GCC=9 CPP17=1 + sudo: required + dist: xenial + - os: linux + env: SWIGLANG=python GCC=9 CPP17=1 PY3=3 VER=3.7 + sudo: required + dist: xenial - compiler: gcc os: osx env: SWIGLANG= diff --git a/CHANGES.current b/CHANGES.current index 8aef21f75..22f074616 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -11,6 +11,14 @@ Version 4.0.1 (in progress) [C#, Java] #1570 Fix name of generated C#/Java classes for %interface macros in swiginterface.i when wrapping nested C++ classes. +2019-07-05: wsfulton + [Python] #1547 Whitespace fixes in Doxygen translated comments into pydoc comments + for Sphinx compatibility. + +2019-06-28: wsfulton + [MzScheme, OCaml] #1559 $arg and $input were incorrectly substituted in the + argout typemap when two or more arguments were present. + 2019-06-24: wsfulton [Python, Ruby] #1538 Remove the UnknownExceptionHandler class in order to be C++17 compliant as it uses std::unexpected_handler which was removed in C++17. diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk index 795dc6209..742536201 100644 --- a/Examples/test-suite/common.mk +++ b/Examples/test-suite/common.mk @@ -621,6 +621,7 @@ DOXYGEN_TEST_CASES += \ doxygen_alias \ doxygen_basic_notranslate \ doxygen_basic_translate \ + doxygen_basic_translate_style2 \ doxygen_ignore \ doxygen_misc_constructs \ doxygen_nested_class \ diff --git a/Examples/test-suite/cpp11_initializer_list.i b/Examples/test-suite/cpp11_initializer_list.i index 58d2ecc50..b309576c1 100644 --- a/Examples/test-suite/cpp11_initializer_list.i +++ b/Examples/test-suite/cpp11_initializer_list.i @@ -6,12 +6,21 @@ %ignore A::A(std::initializer_list<int>); %ignore B::method; -%typemap(in) std::initializer_list<const char *> { +%typemap(in) std::initializer_list<const char *> %{ $1 = {"Ab", "Fab"}; -} +%} + +%begin %{ +#if __GNUC__ >= 9 +/* warning: ‘new’ of initializer_list does not extend the lifetime of the underlying array [-Winit-list-lifetime] */ +/* incorrect warning for C::C(std::initializer_list<const char *>) */ +#pragma GCC diagnostic ignored "-Winit-list-lifetime" +#endif +%} %inline %{ #include <initializer_list> +#include <string> class A { public: @@ -26,9 +35,16 @@ public: void method(std::initializer_list<int> init) {} }; class C { + std::string joined; public: - C(std::initializer_list<const char *>) {} + C(std::initializer_list<const char *> init) { + for (auto& val : init) + joined += val; + } C() {} + const char * get_joined_string() { + return joined.c_str(); + } }; %} diff --git a/Examples/test-suite/cpp11_rvalue_reference2.i b/Examples/test-suite/cpp11_rvalue_reference2.i index 9aaf4accb..a2a0020f5 100644 --- a/Examples/test-suite/cpp11_rvalue_reference2.i +++ b/Examples/test-suite/cpp11_rvalue_reference2.i @@ -31,7 +31,7 @@ struct Thingy { // test both primitive and user defined rvalue reference default arguments and compactdefaultargs void compactDefaultArgs(const bool &&b = (const bool &&)PublicGlobalTrue, const UserDef &&u = (const UserDef &&)PublicUserDef) {} void privateDefaultArgs(const bool &&b = (const bool &&)PrivateTrue) {} - operator int &&() { return std::move(0); } + operator int &&() { return std::move(val); } Thingy(const Thingy& rhs) : val(rhs.val), lvalref(rhs.lvalref), rvalref(std::move(rhs.rvalref)) {} Thingy& operator=(const Thingy& rhs) { val = rhs.val; diff --git a/Examples/test-suite/doxygen_basic_translate_style2.i b/Examples/test-suite/doxygen_basic_translate_style2.i new file mode 100644 index 000000000..23e8de4f7 --- /dev/null +++ b/Examples/test-suite/doxygen_basic_translate_style2.i @@ -0,0 +1,105 @@ +%module doxygen_basic_translate_style2 + +%include "doxygen_basic_translate.h" + +// This test demonstrates a doxygen comment style that starts on the +// first line and so uses extra spacing in subsequent lines. + +%inline %{ + +/** \brief + * Brief description. + * + * The comment text. + * + * \author Some author + * + * \return Some number + * + * \sa function2 + */ +int function() +{ + return 0; +} + +/** 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. + */ +void function2() +{ +} + +/** A test for overloaded functions + * This is function \b one + */ +void function3(int a) +{ +} + +/** A test for overloaded functions + * This is function \b two + */ +void function3(int a, int b) +{ +} + +/** A test of some mixed tag usage + * \if CONDITION + * This \a code fragment shows us something \. + * \par Minuses: + * \arg it's senseless + * \arg it's stupid + * \arg it's null + * + * \warning This may not work as expected + * \code + * int main() { while(true); } + * \endcode + * \endif + */ +void function4() +{ +} + + +void function5(int a) +{ +} +/**< This is a post comment. */ + +/** Test for default args + * @param a Some parameter, default is 42 + */ +void function6(int a=42) +{ +} + +class Shape +{ +public: + typedef Shape* superType; +}; + +/** Test for a parameter with difficult type + * (mostly for python) + * @param a Very strange param + */ +void function7(Shape::superType *a[10]) +{ +} + +/** Multiple parameters test. + * + * @param y Vertical coordinate. + * @param x Horizontal coordinate. + * @return Arc tangent of @c y/x. + */ +double Atan2(double y, double x) +{ + return 0; +} + +/** Comment at the end of file should be ignored. + */ +%} diff --git a/Examples/test-suite/doxygen_translate_all_tags.i b/Examples/test-suite/doxygen_translate_all_tags.i index 6e96a57c5..8da683d52 100644 --- a/Examples/test-suite/doxygen_translate_all_tags.i +++ b/Examples/test-suite/doxygen_translate_all_tags.i @@ -38,6 +38,10 @@ * \cite citationword * \class someClass headerFile.h headerName * \code some test code \endcode + * + * Code immediately following text. Pydoc translation must add an + * empty line before: + * \code more test code \endcode */ void func01(int a) { @@ -121,6 +125,12 @@ void func03(int a) * \sqrt{(x_2-x_1)^2+(y_2-y_1)^2} * \f} * + * Math immediately following text. Pydoc translation must add an + * empty line before: + * \f[ + * \sqrt{(x_2-x_1)^2+(y_2-y_1)^2} + * \f] + * * \file file.h * * \fn someFn diff --git a/Examples/test-suite/java/cpp11_initializer_list_runme.java b/Examples/test-suite/java/cpp11_initializer_list_runme.java new file mode 100644 index 000000000..0318c9e90 --- /dev/null +++ b/Examples/test-suite/java/cpp11_initializer_list_runme.java @@ -0,0 +1,21 @@ + +import cpp11_initializer_list.*; + +public class cpp11_initializer_list_runme { + + static { + try { + System.loadLibrary("cpp11_initializer_list"); + } catch (UnsatisfiedLinkError e) { + System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e); + System.exit(1); + } + } + + public static void main(String argv[]) { + C c = new C(null); + String joined = c.get_joined_string(); + if (!joined.equals("AbFab")) + throw new RuntimeException("Wrong joined string " + joined); + } +} diff --git a/Examples/test-suite/java/doxygen_basic_translate_style2_runme.java b/Examples/test-suite/java/doxygen_basic_translate_style2_runme.java new file mode 100644 index 000000000..aa015eeac --- /dev/null +++ b/Examples/test-suite/java/doxygen_basic_translate_style2_runme.java @@ -0,0 +1,99 @@ + +import doxygen_basic_translate_style2.*; +import com.sun.javadoc.*; +import java.util.HashMap; + +public class doxygen_basic_translate_style2_runme { + static { + try { + System.loadLibrary("doxygen_basic_translate_style2"); + } catch (UnsatisfiedLinkError e) { + System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e); + System.exit(1); + } + } + + public static void main(String argv[]) + { + /* + Here we are using internal javadoc tool, it accepts the name of the class as paramterer, + and calls the start() method of that class with parsed information. + */ + CommentParser parser = new CommentParser(); + com.sun.tools.javadoc.Main.execute("doxygen_basic_translate_style2 runtime test", + "CommentParser", + new String[]{"-quiet", "doxygen_basic_translate_style2"}); + + HashMap<String, String> wantedComments = new HashMap<String, String>(); + + wantedComments.put("doxygen_basic_translate_style2.doxygen_basic_translate_style2.function()", + " \n" + + " Brief description.\n" + + " \n" + + " The comment text.\n" + + " @author Some author\n" + + " @return Some number\n" + + " @see function2\n" + + " \n" + + ""); + wantedComments.put("doxygen_basic_translate_style2.doxygen_basic_translate_style2.function2()", + " A test of a very very very very very very very very very very very very very very very very \n" + + " very very very very very long comment string. \n" + + " \n" + + ""); + wantedComments.put("doxygen_basic_translate_style2.doxygen_basic_translate_style2.function4()", + " A test of some mixed tag usage \n" + + " If: CONDITION {\n" + + " This <i>code </i>fragment shows us something . \n" + + " <p alt=\"Minuses: \">\n" + + " <li>it's senseless \n" + + " </li><li>it's stupid \n" + + " </li><li>it's null \n" + + " \n" + + " </li></p>Warning: This may not work as expected \n" + + " \n" + + " {@code \n" + + "int main() { while(true); } \n" + + " }\n" + + " }\n" + + " \n" + + ""); + wantedComments.put("doxygen_basic_translate_style2.doxygen_basic_translate_style2.function3(int)", + " A test for overloaded functions \n" + + " This is function <b>one </b>\n" + + " \n" + + ""); + wantedComments.put("doxygen_basic_translate_style2.doxygen_basic_translate_style2.function5(int)", + " This is a post comment. \n" + + ""); + wantedComments.put("doxygen_basic_translate_style2.doxygen_basic_translate_style2.function6(int)", + " Test for default args \n" + + " @param a Some parameter, default is 42" + + " \n" + + ""); + wantedComments.put("doxygen_basic_translate_style2.doxygen_basic_translate_style2.function6()", + " Test for default args \n" + + " \n" + + ""); + wantedComments.put("doxygen_basic_translate_style2.doxygen_basic_translate_style2.function7(doxygen_basic_translate_style2.SWIGTYPE_p_p_p_Shape)", + " Test for a parameter with difficult type \n" + + " (mostly for python) \n" + + " @param a Very strange param \n" + + ""); + wantedComments.put("doxygen_basic_translate_style2.doxygen_basic_translate_style2.function3(int, int)", + " A test for overloaded functions \n" + + " This is function <b>two </b>\n" + + " \n" + + ""); + wantedComments.put("doxygen_basic_translate_style2.doxygen_basic_translate_style2.Atan2(double, double)", + " Multiple parameters test.\n" + + " \n" + + " @param y Vertical coordinate.\n" + + " @param x Horizontal coordinate.\n" + + " @return Arc tangent of <code>y/x</code>.\n" + + ""); + + // and ask the parser to check comments for us + System.exit(parser.check(wantedComments)); + } +} diff --git a/Examples/test-suite/java/doxygen_translate_all_tags_runme.java b/Examples/test-suite/java/doxygen_translate_all_tags_runme.java index 8bd65224f..d5c533f4e 100644 --- a/Examples/test-suite/java/doxygen_translate_all_tags_runme.java +++ b/Examples/test-suite/java/doxygen_translate_all_tags_runme.java @@ -40,7 +40,10 @@ public class doxygen_translate_all_tags_runme { " Not everything works right now...\n" + " <code>codeword</code>\n\n\n\n\n\n" + " <i>citationword</i>\n" + - " {@code some test code }\n"); + " {@code some test code }\n\n" + + " Code immediately following text. Pydoc translation must add an\n" + + " empty line before:\n" + + " {@code more test code }"); wantedComments.put("doxygen_translate_all_tags.doxygen_translate_all_tags.func02(int)", " Conditional comment: SOMECONDITION \n" + @@ -63,8 +66,11 @@ public class doxygen_translate_all_tags_runme { " @exception SuperError \n" + " \\sqrt{(x_2-x_1)^2+(y_2-y_1)^2} \n" + " \\sqrt{(x_2-x_1)^2+(y_2-y_1)^2} \n" + - " \\sqrt{(x_2-x_1)^2+(y_2-y_1)^2} \n" + - " This will only appear in hmtl \n"); + " \\sqrt{(x_2-x_1)^2+(y_2-y_1)^2} \n\n" + + "Math immediately following text. Pydoc translation must add an\n" + + "empty line before:\n\n" + + " \\sqrt{(x_2-x_1)^2+(y_2-y_1)^2}\n" + + " This will only appear in hmtl \n"); wantedComments.put("doxygen_translate_all_tags.doxygen_translate_all_tags.func05(int)", " If: ANOTHERCONDITION {\n" + diff --git a/Examples/test-suite/python/doxygen_basic_translate_runme.py b/Examples/test-suite/python/doxygen_basic_translate_runme.py index e664e06f6..b6023224d 100644 --- a/Examples/test-suite/python/doxygen_basic_translate_runme.py +++ b/Examples/test-suite/python/doxygen_basic_translate_runme.py @@ -49,9 +49,7 @@ Warning: This may not work as expected .. code-block:: c++ - int main() { while(true); } - }""" ) comment_verifier.check(inspect.getdoc(doxygen_basic_translate.function5), diff --git a/Examples/test-suite/python/doxygen_basic_translate_style2_runme.py b/Examples/test-suite/python/doxygen_basic_translate_style2_runme.py new file mode 100644 index 000000000..2d62eecbd --- /dev/null +++ b/Examples/test-suite/python/doxygen_basic_translate_style2_runme.py @@ -0,0 +1,80 @@ +import doxygen_basic_translate_style2 +import inspect +import string +import sys +import comment_verifier + +comment_verifier.check(inspect.getdoc(doxygen_basic_translate_style2.function), + """\ +Brief description. + +The comment text. + +Author: Some author + +:rtype: int +:return: Some number + +See also: function2""" +) +comment_verifier.check(inspect.getdoc(doxygen_basic_translate_style2.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.""" +) +comment_verifier.check(inspect.getdoc(doxygen_basic_translate_style2.function3), + """*Overload 1:* +A test for overloaded functions +This is function **one** + +| + +*Overload 2:* +A test for overloaded functions +This is function **two**""" +) +comment_verifier.check(inspect.getdoc(doxygen_basic_translate_style2.function4), + """\ +A test of some mixed tag usage +If: CONDITION { +This *code* fragment shows us something . +Title: Minuses: +* it\'s senseless +* it\'s stupid +* it\'s null + +Warning: This may not work as expected + +.. code-block:: c++ + + int main() { while(true); } +}""" +) +comment_verifier.check(inspect.getdoc(doxygen_basic_translate_style2.function5), + """This is a post comment.""" +) +comment_verifier.check(inspect.getdoc(doxygen_basic_translate_style2.function6), + """\ +Test for default args +:type a: int +:param a: Some parameter, default is 42""" +) +comment_verifier.check(inspect.getdoc(doxygen_basic_translate_style2.function7), + """\ +Test for a parameter with difficult type +(mostly for python) +:type a: :py:class:`Shape` +:param a: Very strange param""" +) + +comment_verifier.check(inspect.getdoc(doxygen_basic_translate_style2.Atan2), + """\ +Multiple parameters test. + +:type y: float +:param y: Vertical coordinate. +:type x: float +:param x: Horizontal coordinate. +:rtype: float +:return: Arc tangent of ``y/x``.""" +) diff --git a/Examples/test-suite/python/doxygen_translate_all_tags_runme.py b/Examples/test-suite/python/doxygen_translate_all_tags_runme.py index 53d087e69..df1c0eba5 100644 --- a/Examples/test-suite/python/doxygen_translate_all_tags_runme.py +++ b/Examples/test-suite/python/doxygen_translate_all_tags_runme.py @@ -34,10 +34,16 @@ Not everything works right now... 'citationword' +.. code-block:: c++ + + some test code + +Code immediately following text. Pydoc translation must add an +empty line before: .. code-block:: c++ - some test code""") + more test code""") comment_verifier.check(inspect.getdoc(doxygen_translate_all_tags.func02), r"""Conditional comment: SOMECONDITION @@ -90,12 +96,16 @@ r""":raises: SuperError :math:`\sqrt{(x_2-x_1)^2+(y_2-y_1)^2}` - .. math:: \sqrt{(x_2-x_1)^2+(y_2-y_1)^2} +.. math:: + + \sqrt{(x_2-x_1)^2+(y_2-y_1)^2} +Math immediately following text. Pydoc translation must add an +empty line before: .. math:: @@ -111,7 +121,6 @@ r""":raises: SuperError - This will only appear in hmtl""") comment_verifier.check(inspect.getdoc(doxygen_translate_all_tags.func05), @@ -283,13 +292,11 @@ r"""TODO: Some very important task - very long text with tags <sometag> - Version: 0.0.0.2 Warning: This is senseless! diff --git a/Examples/test-suite/python/doxygen_translate_runme.py b/Examples/test-suite/python/doxygen_translate_runme.py index 2d0840a1f..d698ba873 100644 --- a/Examples/test-suite/python/doxygen_translate_runme.py +++ b/Examples/test-suite/python/doxygen_translate_runme.py @@ -20,11 +20,9 @@ Author: Zubr 'citationword' - .. code-block:: c++ - some test code - + some test code Conditional comment: SOMECONDITION Some conditional comment @@ -121,11 +119,9 @@ TODO: Some very important task :type b: float :param b: B is mentioned again... - very long text with tags <sometag> - Version: 0.0.0.2 Warning: This is senseless! diff --git a/Source/Doxygen/pydoc.cxx b/Source/Doxygen/pydoc.cxx index fc3b0ea09..eb489932a 100644 --- a/Source/Doxygen/pydoc.cxx +++ b/Source/Doxygen/pydoc.cxx @@ -138,6 +138,52 @@ static void trimWhitespace(string &s) { 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 last character in the string if it is a newline +static void eraseTrailingNewLine(string &s) { + if (!s.empty() && s[s.size() - 1] == '\n') + s.erase(s.size() - 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)) { + // Must separate code or math blocks from the previous line + result += '\n'; + } + lastLineWasNonBlank = true; + } + } + return result; +} + /* static */ PyDocConverter::TagHandlersMap::mapped_type PyDocConverter::make_handler(tagHandler handler) { return make_pair(handler, std::string()); @@ -219,7 +265,7 @@ void PyDocConverter::fillStaticTables() { tagHandlers["short"] = make_handler(&PyDocConverter::handleParagraph); tagHandlers["todo"] = make_handler(&PyDocConverter::handleParagraph); tagHandlers["version"] = make_handler(&PyDocConverter::handleParagraph); - tagHandlers["verbatim"] = make_handler(&PyDocConverter::handleParagraph); + tagHandlers["verbatim"] = make_handler(&PyDocConverter::handleVerbatimBlock); tagHandlers["warning"] = make_handler(&PyDocConverter::handleParagraph); tagHandlers["xmlonly"] = make_handler(&PyDocConverter::handleParagraph); // these commands have special handlers @@ -419,6 +465,17 @@ void PyDocConverter::handleParagraph(DoxygenEntity &tag, std::string &translated translatedComment += translateSubtree(tag); } +void PyDocConverter::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 + eraseTrailingNewLine(verb); + translatedComment += verb; +} + void PyDocConverter::handleMath(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg) { IndentGuard indent; @@ -433,7 +490,6 @@ void PyDocConverter::handleMath(DoxygenEntity &tag, std::string &translatedComme indent.Init(translatedComment, m_indent); trimWhitespace(translatedComment); - translatedComment += '\n'; const string formulaIndent = indent.getFirstLineIndent(); translatedComment += formulaIndent; @@ -467,8 +523,6 @@ void PyDocConverter::handleMath(DoxygenEntity &tag, std::string &translatedComme if (inlineFormula) { translatedComment += "`"; - } else { - translatedComment += '\n'; } } @@ -476,23 +530,28 @@ void PyDocConverter::handleCode(DoxygenEntity &tag, std::string &translatedComme IndentGuard indent(translatedComment, m_indent); trimWhitespace(translatedComment); - translatedComment += '\n'; // Use the current indent for the code-block line itself. - string codeIndent = indent.getFirstLineIndent(); - translatedComment += codeIndent; + translatedComment += indent.getFirstLineIndent(); // Go out on a limb and assume that examples in the C or C++ sources use C++. // In the worst case, we'll highlight C code using C++ syntax which is not a // big deal (TODO: handle Doxygen code command language argument). translatedComment += ".. code-block:: c++\n\n"; - // For now on, use extra indent level for all the subsequent lines. - codeIndent += m_indent; + // 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. + string codeIndent = m_indent; std::string code; handleTagVerbatim(tag, code, arg); + // Try and remove leading newline, which is present for block \code + // command: + eraseLeadingNewLine(code); + translatedComment += codeIndent; for (size_t n = 0; n < code.length(); n++) { if (code[n] == '\n') { @@ -510,8 +569,11 @@ void PyDocConverter::handleCode(DoxygenEntity &tag, std::string &translatedComme } trimWhitespace(translatedComment); - if (*translatedComment.rbegin() != '\n') - translatedComment += '\n'; + + // For block commands, the translator adds the newline after + // \endcode, so try and compensate by removing the last newline from + // the code text: + eraseTrailingNewLine(translatedComment); } void PyDocConverter::handlePlainString(DoxygenEntity &tag, std::string &translatedComment, const std::string &) { @@ -519,7 +581,7 @@ void PyDocConverter::handlePlainString(DoxygenEntity &tag, std::string &translat } void PyDocConverter::handleTagVerbatim(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg) { - translatedComment += arg + " "; + translatedComment += arg; for (DoxygenEntityListCIt it = tag.entityList.begin(); it != tag.entityList.end(); it++) { translatedComment += it->data; } @@ -833,9 +895,10 @@ String *PyDocConverter::makeDocumentation(Node *n) { if (!pyDocString.empty()) { // remove the last '\n' since additional one is added during writing to file - if (pyDocString[pyDocString.size() - 1] == '\n') { - pyDocString.erase(pyDocString.size() - 1); - } + eraseTrailingNewLine(pyDocString); + + // ensure that a blank line occurs before code or math blocks + pyDocString = padCodeAndVerbatimBlocks(pyDocString); if (m_flags & debug_translator) { std::cout << "\n---RESULT IN PYDOC---" << std::endl; diff --git a/Source/Doxygen/pydoc.h b/Source/Doxygen/pydoc.h index 8f432fd18..df8997d76 100644 --- a/Source/Doxygen/pydoc.h +++ b/Source/Doxygen/pydoc.h @@ -80,6 +80,11 @@ protected: void handleParagraph(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); diff --git a/Source/Modules/mzscheme.cxx b/Source/Modules/mzscheme.cxx index 543874172..788681330 100644 --- a/Source/Modules/mzscheme.cxx +++ b/Source/Modules/mzscheme.cxx @@ -221,7 +221,6 @@ public: Wrapper *f = NewWrapper(); String *proc_name = NewString(""); - String *source = NewString(""); String *target = NewString(""); String *arg = NewString(""); String *cleanup = NewString(""); @@ -312,10 +311,9 @@ public: String *ln = Getattr(p, "lname"); // Produce names of source and target - Clear(source); Clear(target); Clear(arg); - Printf(source, "argv[%d]", i); + String *source = NewStringf("argv[%d]", i); Printf(target, "%s", ln); Printv(arg, Getattr(p, "name"), NIL); @@ -339,6 +337,7 @@ public: if (i >= numreq) { Printf(f->code, "}\n"); } + Delete(source); } /* Insert constraint checking code */ @@ -465,7 +464,6 @@ public: } Delete(proc_name); - Delete(source); Delete(target); Delete(arg); Delete(outarg); diff --git a/Source/Modules/ocaml.cxx b/Source/Modules/ocaml.cxx index ad9c94800..6f2a34962 100644 --- a/Source/Modules/ocaml.cxx +++ b/Source/Modules/ocaml.cxx @@ -473,7 +473,6 @@ public: Wrapper *f = NewWrapper(); String *proc_name = NewString(""); - String *source = NewString(""); String *target = NewString(""); String *arg = NewString(""); String *cleanup = NewString(""); @@ -580,10 +579,9 @@ public: pt = SwigType_typedef_qualified(pt); // Produce names of source and target - Clear(source); Clear(target); Clear(arg); - Printf(source, "caml_list_nth(args,%d)", i); + String *source = NewStringf("caml_list_nth(args,%d)", i); Printf(target, "%s", ln); Printv(arg, Getattr(p, "name"), NIL); @@ -607,6 +605,7 @@ public: if (i >= numreq) { Printf(f->code, "}\n"); } + Delete(source); } /* Insert constraint checking code */ @@ -787,7 +786,6 @@ public: Printf(f_mlibody, "val %s : c_obj -> c_obj\n", mangled_name); Delete(proc_name); - Delete(source); Delete(target); Delete(arg); Delete(outarg); diff --git a/appveyor.yml b/appveyor.yml index 10bf064df..42eaa36f4 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -89,7 +89,7 @@ install: - if "%OSVARIANT%"=="" bash -c "cl.exe /? 2>&1 | head -n 1" - if "%OSVARIANT%"=="" bash -c "which csc.exe" - if "%OSVARIANT%"=="" bash -c "csc.exe /? | head -n 1" -- if "%OSVARIANT%"=="cygwin" %CYGWINSETUP% --quiet-mode --packages python-devel,libpcre-devel,libboost-devel > cygwin-install.txt || bash -c "cat cygwin-install.txt" +- if "%OSVARIANT%"=="cygwin" %CYGWINSETUP% --quiet-mode --packages python2-devel,libpcre-devel,libboost-devel > cygwin-install.txt || bash -c "cat cygwin-install.txt" - if "%OSVARIANT%"=="mingw" bash -c "pacman --noconfirm --sync mingw%MBITS%/mingw-w64-%MARCH%-pcre mingw%MBITS%/mingw-w64-%MARCH%-boost" - if not "%WITHLANG%"=="" set SWIGWITHLANG==%WITHLANG% - if not "%WITHLANG%"=="" where %WITHLANG% |