diff --git a/CHANGES.current b/CHANGES.current index 15a2fc516..09facd90b 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -7,6 +7,14 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/ Version 4.0.2 (in progress) =========================== +2019-12-10: wsfulton + #1679 Fix parsing of C++11 identifiers with special meaning (final and override) when + they are used as part of the scope name of an identifier, such as a namespace name. + +2019-11-26: wsfulton + [C#] #1628 'out' or 'ref' used in a cstype typemap was not always stripped out in parts + of director code generation. + 2019-11-01: wsfulton [Python] #1595 Fix bug in support for keyword arguments (kwargs feature or -keyword) when using -builtin. The fix is in the argument error checking when wrapping zero diff --git a/Doc/Manual/CSharp.html b/Doc/Manual/CSharp.html index 1fc2d211e..d041bf5dd 100644 --- a/Doc/Manual/CSharp.html +++ b/Doc/Manual/CSharp.html @@ -66,7 +66,16 @@ PInvoke is part of the ECMA/ISO C# specification. It is also better suited for robust production environments due to the Managed C++ flaw called the Mixed DLL Loading Problem. SWIG C# works equally well on non-Microsoft operating systems such as Linux, Solaris and Apple Mac using -Mono and Portable.NET. +Mono. +

+ +

+SWIG 3 and later requires .NET 2.0 at a minimum. +There are some minor exceptions, where the minimum required is .NET 4.0. +This is when using the std::complex and std::list STL containers. +

+ +

diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk index 5f7792810..c817bdf80 100644 --- a/Examples/test-suite/common.mk +++ b/Examples/test-suite/common.mk @@ -610,11 +610,14 @@ CPP11_TEST_BROKEN = \ # cpp11_reference_wrapper \ # No typemaps # Doxygen support test cases: can only be used with languages supporting -# Doxygen comment translation, currently only Python and Java. +# Doxygen comment translation (currently Python and Java) and only if not +# disabled by configure via SKIP_DOXYGEN_TEST_CASES. +ifneq ($(SKIP_DOXYGEN_TEST_CASES),1) python_HAS_DOXYGEN := 1 java_HAS_DOXYGEN := 1 $(eval HAS_DOXYGEN := $($(LANGUAGE)_HAS_DOXYGEN)) +endif ifdef HAS_DOXYGEN DOXYGEN_TEST_CASES += \ diff --git a/Examples/test-suite/cpp11_final_override.i b/Examples/test-suite/cpp11_final_override.i index 8d275b322..c31ae73b6 100644 --- a/Examples/test-suite/cpp11_final_override.i +++ b/Examples/test-suite/cpp11_final_override.i @@ -138,3 +138,31 @@ void DerivedNoVirtualStruct::ef() {} DerivedNoVirtualStruct::~DerivedNoVirtualStruct() {} %} +%inline %{ +namespace Outer { + namespace final { + template struct smart_ptr { + typedef T type; + }; + } + namespace override { + template struct dumb_ptr { + typedef T type; + }; + } +} +%} + +%template(SmartPtrBaseStruct) Outer::final::smart_ptr; + +%inline %{ +class ObjectDB +{ +public: + static void smart1(typename Outer::final::smart_ptr::type *objectT) {} + static void smart2(Outer::final::smart_ptr::type *objectT) {} + static void dumb1(typename Outer::override::dumb_ptr::type *objectT) {} + static void dumb2(Outer::override::dumb_ptr::type *objectT) {} + static Outer::final::smart_ptr::type get() { return DerivedStruct(); } +}; +%} diff --git a/Examples/test-suite/csharp/Makefile.in b/Examples/test-suite/csharp/Makefile.in index 8272864d5..57a81e357 100644 --- a/Examples/test-suite/csharp/Makefile.in +++ b/Examples/test-suite/csharp/Makefile.in @@ -16,6 +16,7 @@ CPP_TEST_CASES = \ complextest \ csharp_attributes \ csharp_swig2_compatibility \ + csharp_director_typemaps \ csharp_exceptions \ csharp_features \ csharp_lib_arrays \ diff --git a/Examples/test-suite/csharp/csharp_director_typemaps_runme.cs b/Examples/test-suite/csharp/csharp_director_typemaps_runme.cs new file mode 100644 index 000000000..6143332db --- /dev/null +++ b/Examples/test-suite/csharp/csharp_director_typemaps_runme.cs @@ -0,0 +1,53 @@ + +using System; +using System.Reflection; +using csharp_director_typemapsNamespace; + +public class csharp_director_typemaps_runme { + + class CSharpDirectorTypemaps_InStreamDerived : InStream + { + private int constant; + public CSharpDirectorTypemaps_InStreamDerived(int constant) { this.constant = constant; } + public override int Read(global::System.IntPtr buf, int len, out int readLen) { + readLen = (buf == global::System.IntPtr.Zero) ? -len - constant : len + constant; + return readLen; + } + public override int Write(global::System.IntPtr buf, int len, out int writeLen) { + writeLen = (buf == global::System.IntPtr.Zero) ? -len - constant : len + constant; + return writeLen; + } + } + public static void Main() { + int outLen = -1; + int k = 100; + int j = 23; + InStream instream = new CSharpDirectorTypemaps_InStreamDerived(k); + + { + int ret = csharp_director_typemaps.callRead(instream, InStream.getCPtr(instream).Handle, j, out outLen); + Assert(outLen, j + k); + Assert(ret, j + k); + } + { + int ret = csharp_director_typemaps.callRead(instream, global::System.IntPtr.Zero, j, out outLen); + Assert(outLen, -j - k); + Assert(ret, -j - k); + } + + { + int ret = csharp_director_typemaps.callWrite(instream, InStream.getCPtr(instream).Handle, j, out outLen); + Assert(outLen, j + k); + Assert(ret, j + k); + } + { + int ret = csharp_director_typemaps.callWrite(instream, global::System.IntPtr.Zero, j, out outLen); + Assert(outLen, -j - k); + Assert(ret, -j - k); + } + } + private static void Assert(int i1, int i2) { + if (i1 != i2) + throw new Exception("assertion failure. " + i1 + " != " + i2); + } +} diff --git a/Examples/test-suite/csharp_director_typemaps.i b/Examples/test-suite/csharp_director_typemaps.i new file mode 100644 index 000000000..614bdbf23 --- /dev/null +++ b/Examples/test-suite/csharp_director_typemaps.i @@ -0,0 +1,37 @@ +%module (directors="1") csharp_director_typemaps + +// This tests that the csout typemap is handled correctly in the director code. +// The 'out' needs stripping in some parts of the generated director code. + +%feature("director") InStream; + +%apply void *VOID_INT_PTR { void * } + +%typemap(ctype) int* readLen, int* writeLen "/*ctype*/ int*" +%typemap(imtype) int* readLen, int* writeLen "/*imtype*/ out int" +%typemap(cstype) int* readLen "/*cstype*/ out int" +// Note for below: 'out' used in typemap comment +%typemap(cstype) int* writeLen "/*out cstype out*/ out int" +%typemap(csin) int* readLen, int* writeLen "/*csin*/ out $csinput" +%typemap(in) int* readLen, int* writeLen %{/*in*/ $1 = ($1_ltype)$input; %} +%typemap(out) int* readLen, int* writeLen %{/*out*/ $result = (void *)$1; %} +%typemap(csdirectorin) int* readLen, int* writeLen "/*csdirectorin*/ out $iminput" +%typemap(csdirectorout) int* readLen, int* writeLen "/*csdirectorout*/ $cscall" +%typemap(directorin) int* readLen, int* writeLen "/*directorin*/ $input = $1;" +%typemap(directorout) int* readLen, int* writeLen %{/*directorout*/ $result = ($1_ltype)$input; %} + +%inline %{ +class InStream +{ +public: + virtual int Read(void* buf, int len, int* readLen) = 0; + virtual int Write(void* buf, int len, int* writeLen) = 0; + virtual ~InStream() {} +}; +int callRead(InStream* stream, void* buf, int len, int* readLen) { + return stream->Read(buf, len, readLen); +} +int callWrite(InStream* stream, void* buf, int len, int* writeLen) { + return stream->Write(buf, len, writeLen); +} +%} diff --git a/Examples/test-suite/java/CommentParser.java b/Examples/test-suite/java/CommentParser.java index 7dc6d591d..1fc6f646a 100644 --- a/Examples/test-suite/java/CommentParser.java +++ b/Examples/test-suite/java/CommentParser.java @@ -1,5 +1,6 @@ -import com.sun.javadoc.*; +import com.sun.source.doctree.*; +import com.sun.source.util.DocTrees; import java.util.HashMap; import java.util.Map.Entry; import java.util.Map; @@ -9,45 +10,120 @@ import java.io.BufferedWriter; import java.io.OutputStreamWriter; import java.io.FileOutputStream; import java.io.IOException; +import java.util.*; +import java.util.spi.ToolProvider; +import javax.lang.model.*; +import javax.lang.model.element.*; +import javax.lang.model.util.*; +import jdk.javadoc.doclet.*; -public class CommentParser { +public class CommentParser implements Doclet { private static Map m_parsedComments = new HashMap(); - public static boolean start(RootDoc root) { + // We need to implement these base class pure virtual methods. + @Override + public void init(Locale locale, Reporter reporter) { + } + + @Override + public Set getSupportedOptions() { + return new HashSet<>(); + } + + @Override + public SourceVersion getSupportedSourceVersion() { + return SourceVersion.latest(); + } + + @Override + public String getName() { + return "CommentParser"; + } + + // Element name must be the fully qualified name of the element. + // + // If there is no comment associated with this element, simply do nothing. + private void storeCommentFor(DocTrees docTrees, String fullName, Element e) { + DocCommentTree docCommentTree = docTrees.getDocCommentTree(e); + if (docCommentTree == null) + return; + + StringBuilder name = new StringBuilder(fullName); + + // We must use signature in the key for methods for compatibility with + // the existing tests and to allow distinguishing between overloaded + // methods. + if (e instanceof ExecutableElement) { + ExecutableElement ex = (ExecutableElement)e; + name.append("("); + + boolean firstParam = true; + for (VariableElement p : ex.getParameters()) { + if (firstParam) { + firstParam = false; + } else { + name.append(", "); + } + + name.append(p.asType().toString()); + } + + name.append(")"); + } + + // For some reason the comment in the source is split into "body" and + // "block tags" parts, so we need to concatenate them back together. + StringBuilder comment = new StringBuilder(); + for (DocTree d : docCommentTree.getFullBody()) { + comment.append(d.toString()); + comment.append("\n"); + } + + boolean firstBlockTag = true; + for (DocTree d : docCommentTree.getBlockTags()) { + if (firstBlockTag) { + firstBlockTag = false; + comment.append("\n"); + } + + comment.append(d.toString()); + comment.append("\n"); + } + + m_parsedComments.put(name.toString(), comment.toString()); + } + + @Override + public boolean run(DocletEnvironment docEnv) { /* * This method is called by 'javadoc' and gets the whole parsed java * file, we get comments and store them */ + DocTrees docTrees = docEnv.getDocTrees(); + for (TypeElement t : ElementFilter.typesIn(docEnv.getIncludedElements())) { + String typeName = t.getQualifiedName().toString(); - for (ClassDoc classDoc : root.classes()) { + storeCommentFor(docTrees, typeName, t); - if (classDoc.getRawCommentText().length() > 0) - m_parsedComments.put(classDoc.qualifiedName(), classDoc.getRawCommentText()); + for (Element e : t.getEnclosedElements()) { + // Omit the method name for ctors: this is a bit weird, but + // this is what the existing tests expect. + String fullName = typeName; + if (e.getKind() != ElementKind.CONSTRUCTOR) { + fullName = fullName + "." + e.getSimpleName(); + } - for (FieldDoc f : classDoc.enumConstants()) { - if (f.getRawCommentText().length() > 0) - m_parsedComments.put(f.qualifiedName(), f.getRawCommentText()); - } - for (FieldDoc f : classDoc.fields()) { - if (f.getRawCommentText().length() > 0) - m_parsedComments.put(f.qualifiedName(), f.getRawCommentText()); - } - for (ConstructorDoc c : classDoc.constructors()) { - if (c.getRawCommentText().length() > 0) - m_parsedComments.put(c.toString(), c.getRawCommentText()); - } - for (MethodDoc m : classDoc.methods()) { - if (m.getRawCommentText().length() > 0) - m_parsedComments.put(m.toString(), m.getRawCommentText()); + storeCommentFor(docTrees, fullName, e); } } + return true; } - public int check(Map wantedComments) { + public static int check(Map wantedComments) { int errorCount=0; Iterator> it = m_parsedComments.entrySet().iterator(); @@ -93,13 +169,14 @@ public class CommentParser { System.out.println("Output is also saved to files '" + expectedFileName + "' and '" + gotFileName + "'"); // here we print original strings, for nicer output - System.out.println("\n\n---\nexpected:\n" + wantedComments.get(e.getKey())); + System.out.println("\n\n---\nexpected:\n" + wantedStr); System.out.println("\n\n---\ngot:\n" + e.getValue()); try { // write expected string to file BufferedWriter expectedFile = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(expectedFileName))); - expectedFile.write(wantedComments.get(e.getKey())); + if (wantedStr != null) + expectedFile.write(wantedStr); expectedFile.close(); // write translated string to file @@ -130,7 +207,7 @@ public class CommentParser { } - private void printKeys(Map map) { + private static void printKeys(Map map) { Set keys = map.keySet(); for (String key : keys) { @@ -154,6 +231,15 @@ public class CommentParser { } } + public static void parse(String sourcefile) { + ToolProvider javadoc = ToolProvider.findFirst("javadoc").orElseThrow(); + int result = javadoc.run(System.out, System.err, new String[]{"-quiet", "-doclet", "CommentParser", sourcefile}); + if (result != 0) { + System.err.println("Executing javadoc failed."); + System.exit(result); + } + } + public static void main(String argv[]) { @@ -162,8 +248,7 @@ public class CommentParser { System.exit(1); } - com.sun.tools.javadoc.Main.execute("The comment parser program", - "CommentParser", new String[]{"-quiet", argv[0]}); + parse(argv[0]); // if we are run as standalone app, print the list of found comments as it would appear in java source diff --git a/Examples/test-suite/java/Makefile.in b/Examples/test-suite/java/Makefile.in index 2e788fa07..f8e290ee3 100644 --- a/Examples/test-suite/java/Makefile.in +++ b/Examples/test-suite/java/Makefile.in @@ -9,6 +9,7 @@ JAVAFLAGS = @JAVAFLAGS@ JAVA_CLASSPATH_SEP = @JAVA_CLASSPATH_SEP@ JAVA_TOOLS_JAR = @JAVA_TOOLS_JAR@ SCRIPTSUFFIX = _runme.java +SKIP_DOXYGEN_TEST_CASES = @JAVA_SKIP_DOXYGEN_TEST_CASES@ srcdir = @srcdir@ top_srcdir = ../@top_srcdir@ @@ -108,13 +109,11 @@ setup = \ mkdir $(JAVA_PACKAGE); \ fi -# Doxygen test cases need to be compiled together with the CommentParser class -# which depends on com.sun.javadoc package which is located in this JAR. +# Doxygen test cases need to be compiled together with the CommentParser class. CommentParser.class: $(COMPILETOOL) $(JAVAC) -classpath $(JAVA_CLASSPATH) -d . $(srcdir)/CommentParser.java JAVA_CLASSPATH := . -$(DOXYGEN_TEST_CASES:=.cpptest): JAVA_CLASSPATH := "$(JAVA_TOOLS_JAR)$(JAVA_CLASSPATH_SEP)." $(DOXYGEN_TEST_CASES:=.cpptest): CommentParser.class # Compiles java files then runs the testcase. A testcase is only run if diff --git a/Examples/test-suite/java/doxygen_alias_runme.java b/Examples/test-suite/java/doxygen_alias_runme.java index e21ed6d19..98cd97752 100644 --- a/Examples/test-suite/java/doxygen_alias_runme.java +++ b/Examples/test-suite/java/doxygen_alias_runme.java @@ -1,6 +1,5 @@ import doxygen_alias.*; -import com.sun.javadoc.*; import java.util.HashMap; public class doxygen_alias_runme { @@ -15,10 +14,7 @@ public class doxygen_alias_runme { public static void main(String argv[]) { - CommentParser parser = new CommentParser(); - com.sun.tools.javadoc.Main.execute("doxygen_alias runtime test", - "CommentParser", - new String[]{"-quiet", "doxygen_alias"}); + CommentParser.parse("doxygen_alias"); HashMap wantedComments = new HashMap(); wantedComments.put("doxygen_alias.doxygen_alias.make_something()", @@ -27,6 +23,6 @@ public class doxygen_alias_runme { " @return A new object which may be null.\n" + ""); - System.exit(parser.check(wantedComments)); + System.exit(CommentParser.check(wantedComments)); } } diff --git a/Examples/test-suite/java/doxygen_basic_notranslate_runme.java b/Examples/test-suite/java/doxygen_basic_notranslate_runme.java index e3d9b0279..621cc9eef 100644 --- a/Examples/test-suite/java/doxygen_basic_notranslate_runme.java +++ b/Examples/test-suite/java/doxygen_basic_notranslate_runme.java @@ -1,6 +1,5 @@ import doxygen_basic_notranslate.*; -import com.sun.javadoc.*; import java.util.HashMap; public class doxygen_basic_notranslate_runme { @@ -15,14 +14,7 @@ public class doxygen_basic_notranslate_runme { 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_notranslate runtime test", - "CommentParser", - new String[]{"-quiet", "doxygen_basic_notranslate"}); + CommentParser.parse("doxygen_basic_notranslate"); HashMap wantedComments = new HashMap(); wantedComments.put("doxygen_basic_notranslate.doxygen_basic_notranslate.function3(int)", @@ -97,6 +89,6 @@ public class doxygen_basic_notranslate_runme { ""); // and ask the parser to check comments for us - System.exit(parser.check(wantedComments)); + System.exit(CommentParser.check(wantedComments)); } } diff --git a/Examples/test-suite/java/doxygen_basic_translate_runme.java b/Examples/test-suite/java/doxygen_basic_translate_runme.java index ab343b560..f0b1efb6b 100644 --- a/Examples/test-suite/java/doxygen_basic_translate_runme.java +++ b/Examples/test-suite/java/doxygen_basic_translate_runme.java @@ -1,6 +1,5 @@ import doxygen_basic_translate.*; -import com.sun.javadoc.*; import java.util.HashMap; public class doxygen_basic_translate_runme { @@ -15,14 +14,7 @@ public class doxygen_basic_translate_runme { 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 runtime test", - "CommentParser", - new String[]{"-quiet", "doxygen_basic_translate"}); + CommentParser.parse("doxygen_basic_translate"); HashMap wantedComments = new HashMap(); @@ -96,6 +88,6 @@ public class doxygen_basic_translate_runme { ""); // and ask the parser to check comments for us - System.exit(parser.check(wantedComments)); + System.exit(CommentParser.check(wantedComments)); } } diff --git a/Examples/test-suite/java/doxygen_basic_translate_style2_runme.java b/Examples/test-suite/java/doxygen_basic_translate_style2_runme.java index 05e51cff8..28cf2daba 100644 --- a/Examples/test-suite/java/doxygen_basic_translate_style2_runme.java +++ b/Examples/test-suite/java/doxygen_basic_translate_style2_runme.java @@ -1,6 +1,5 @@ import doxygen_basic_translate_style2.*; -import com.sun.javadoc.*; import java.util.HashMap; public class doxygen_basic_translate_style2_runme { @@ -15,14 +14,7 @@ public class doxygen_basic_translate_style2_runme { 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"}); + CommentParser.parse("doxygen_basic_translate_style2"); HashMap wantedComments = new HashMap(); @@ -96,6 +88,6 @@ public class doxygen_basic_translate_style2_runme { ""); // and ask the parser to check comments for us - System.exit(parser.check(wantedComments)); + System.exit(CommentParser.check(wantedComments)); } } diff --git a/Examples/test-suite/java/doxygen_ignore_runme.java b/Examples/test-suite/java/doxygen_ignore_runme.java index 6250ce525..29b6e0640 100644 --- a/Examples/test-suite/java/doxygen_ignore_runme.java +++ b/Examples/test-suite/java/doxygen_ignore_runme.java @@ -1,6 +1,5 @@ import doxygen_ignore.*; -import com.sun.javadoc.*; import java.util.HashMap; public class doxygen_ignore_runme { @@ -15,10 +14,7 @@ public class doxygen_ignore_runme { public static void main(String argv[]) { - CommentParser parser = new CommentParser(); - com.sun.tools.javadoc.Main.execute("doxygen_ignore runtime test", - "CommentParser", - new String[]{"-quiet", "doxygen_ignore"}); + CommentParser.parse("doxygen_ignore"); HashMap wantedComments = new HashMap(); wantedComments.put("doxygen_ignore.doxygen_ignore.func()", @@ -39,6 +35,6 @@ public class doxygen_ignore_runme { "\n" + ""); - System.exit(parser.check(wantedComments)); + System.exit(CommentParser.check(wantedComments)); } } diff --git a/Examples/test-suite/java/doxygen_misc_constructs_runme.java b/Examples/test-suite/java/doxygen_misc_constructs_runme.java index 5d95bd565..b1f4e2ef5 100644 --- a/Examples/test-suite/java/doxygen_misc_constructs_runme.java +++ b/Examples/test-suite/java/doxygen_misc_constructs_runme.java @@ -1,6 +1,5 @@ import doxygen_misc_constructs.*; -import com.sun.javadoc.*; import java.util.HashMap; public class doxygen_misc_constructs_runme { @@ -15,14 +14,7 @@ public class doxygen_misc_constructs_runme { 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_misc_constructs runtime test", - "CommentParser", - new String[]{"-quiet", "doxygen_misc_constructs"}); + CommentParser.parse("doxygen_misc_constructs"); HashMap wantedComments = new HashMap(); @@ -195,6 +187,6 @@ public class doxygen_misc_constructs_runme { // and ask the parser to check comments for us - System.exit(parser.check(wantedComments)); + System.exit(CommentParser.check(wantedComments)); } } diff --git a/Examples/test-suite/java/doxygen_nested_class_runme.java b/Examples/test-suite/java/doxygen_nested_class_runme.java index 3ffa796f0..e9d1a068e 100644 --- a/Examples/test-suite/java/doxygen_nested_class_runme.java +++ b/Examples/test-suite/java/doxygen_nested_class_runme.java @@ -1,5 +1,4 @@ import doxygen_nested_class.*; -import com.sun.javadoc.*; import java.util.HashMap; public class doxygen_nested_class_runme { @@ -14,14 +13,7 @@ public class doxygen_nested_class_runme { 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_nested_class runtime test", - "CommentParser", - new String[]{"-quiet", "doxygen_nested_class"}); + CommentParser.parse("doxygen_nested_class"); HashMap wantedComments = new HashMap(); @@ -43,6 +35,6 @@ public class doxygen_nested_class_runme { " doxShort const variable "); // and ask the parser to check comments for us - System.exit(parser.check(wantedComments)); + System.exit(CommentParser.check(wantedComments)); } } diff --git a/Examples/test-suite/java/doxygen_parsing_enums_proper_runme.java b/Examples/test-suite/java/doxygen_parsing_enums_proper_runme.java index ef1f06af5..6b1e2b08e 100644 --- a/Examples/test-suite/java/doxygen_parsing_enums_proper_runme.java +++ b/Examples/test-suite/java/doxygen_parsing_enums_proper_runme.java @@ -1,6 +1,5 @@ import doxygen_parsing_enums_proper.*; -import com.sun.javadoc.*; import java.util.HashMap; public class doxygen_parsing_enums_proper_runme { @@ -15,14 +14,7 @@ public class doxygen_parsing_enums_proper_runme { 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_parsing_enums_proper runtime test", - "CommentParser", - new String[]{"-quiet", "doxygen_parsing_enums_proper"}); + CommentParser.parse("doxygen_parsing_enums_proper"); HashMap wantedComments = new HashMap(); @@ -61,6 +53,6 @@ public class doxygen_parsing_enums_proper_runme { "Post comment after last comma."); // and ask the parser to check comments for us - System.exit(parser.check(wantedComments)); + System.exit(CommentParser.check(wantedComments)); } } diff --git a/Examples/test-suite/java/doxygen_parsing_enums_simple_runme.java b/Examples/test-suite/java/doxygen_parsing_enums_simple_runme.java index 85ec0cb55..1e0dd74ee 100644 --- a/Examples/test-suite/java/doxygen_parsing_enums_simple_runme.java +++ b/Examples/test-suite/java/doxygen_parsing_enums_simple_runme.java @@ -1,6 +1,5 @@ import doxygen_parsing_enums_simple.*; -import com.sun.javadoc.*; import java.util.HashMap; public class doxygen_parsing_enums_simple_runme { @@ -15,14 +14,7 @@ public class doxygen_parsing_enums_simple_runme { 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_parsing_enums_simple runtime test", - "CommentParser", - new String[]{"-quiet", "doxygen_parsing_enums_simple"}); + CommentParser.parse("doxygen_parsing_enums_simple"); HashMap wantedComments = new HashMap(); @@ -53,6 +45,6 @@ public class doxygen_parsing_enums_simple_runme { "Post comment after last comma."); // and ask the parser to check comments for us - System.exit(parser.check(wantedComments)); + System.exit(CommentParser.check(wantedComments)); } } diff --git a/Examples/test-suite/java/doxygen_parsing_enums_typesafe_runme.java b/Examples/test-suite/java/doxygen_parsing_enums_typesafe_runme.java index 4e5f4b489..7cf3b17ef 100644 --- a/Examples/test-suite/java/doxygen_parsing_enums_typesafe_runme.java +++ b/Examples/test-suite/java/doxygen_parsing_enums_typesafe_runme.java @@ -1,6 +1,5 @@ import doxygen_parsing_enums_typesafe.*; -import com.sun.javadoc.*; import java.util.HashMap; public class doxygen_parsing_enums_typesafe_runme { @@ -15,14 +14,7 @@ public class doxygen_parsing_enums_typesafe_runme { 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_parsing_enums_typesafe runtime test", - "CommentParser", - new String[]{"-quiet", "doxygen_parsing_enums_typesafe"}); + CommentParser.parse("doxygen_parsing_enums_typesafe"); HashMap wantedComments = new HashMap(); @@ -62,6 +54,6 @@ public class doxygen_parsing_enums_typesafe_runme { // and ask the parser to check comments for us - System.exit(parser.check(wantedComments)); + System.exit(CommentParser.check(wantedComments)); } } diff --git a/Examples/test-suite/java/doxygen_parsing_enums_typeunsafe_runme.java b/Examples/test-suite/java/doxygen_parsing_enums_typeunsafe_runme.java index 428649196..3a41fe56f 100644 --- a/Examples/test-suite/java/doxygen_parsing_enums_typeunsafe_runme.java +++ b/Examples/test-suite/java/doxygen_parsing_enums_typeunsafe_runme.java @@ -1,6 +1,5 @@ import doxygen_parsing_enums_typeunsafe.*; -import com.sun.javadoc.*; import java.util.HashMap; public class doxygen_parsing_enums_typeunsafe_runme { @@ -15,14 +14,7 @@ public class doxygen_parsing_enums_typeunsafe_runme { 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_parsing_enums_typeunsafe runtime test", - "CommentParser", - new String[]{"-quiet", "doxygen_parsing_enums_typeunsafe"}); + CommentParser.parse("doxygen_parsing_enums_typeunsafe"); HashMap wantedComments = new HashMap(); @@ -61,6 +53,6 @@ public class doxygen_parsing_enums_typeunsafe_runme { "Post comment after last comma."); // and ask the parser to check comments for us - System.exit(parser.check(wantedComments)); + System.exit(CommentParser.check(wantedComments)); } } diff --git a/Examples/test-suite/java/doxygen_parsing_runme.java b/Examples/test-suite/java/doxygen_parsing_runme.java index d58b1f486..10d65fca8 100644 --- a/Examples/test-suite/java/doxygen_parsing_runme.java +++ b/Examples/test-suite/java/doxygen_parsing_runme.java @@ -1,6 +1,5 @@ import doxygen_parsing.*; -import com.sun.javadoc.*; import java.util.HashMap; public class doxygen_parsing_runme { @@ -15,14 +14,7 @@ public class doxygen_parsing_runme { 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_parsing runtime test", - "CommentParser", - new String[]{"-quiet", "doxygen_parsing"}); + CommentParser.parse("doxygen_parsing"); HashMap wantedComments = new HashMap(); @@ -136,6 +128,6 @@ public class doxygen_parsing_runme { ""); // and ask the parser to check comments for us - System.exit(parser.check(wantedComments)); + System.exit(CommentParser.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 d5c533f4e..40702bdff 100644 --- a/Examples/test-suite/java/doxygen_translate_all_tags_runme.java +++ b/Examples/test-suite/java/doxygen_translate_all_tags_runme.java @@ -1,6 +1,5 @@ import doxygen_translate_all_tags.*; -import com.sun.javadoc.*; import java.util.HashMap; public class doxygen_translate_all_tags_runme { @@ -15,14 +14,7 @@ public class doxygen_translate_all_tags_runme { 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_translate_all_tags runtime test", - "CommentParser", - new String[]{"-quiet", "doxygen_translate_all_tags"}); + CommentParser.parse("doxygen_translate_all_tags"); HashMap wantedComments = new HashMap(); @@ -154,6 +146,6 @@ public class doxygen_translate_all_tags_runme { " And here goes simple text \n" + ""); // and ask the parser to check comments for us - System.exit(parser.check(wantedComments)); + System.exit(CommentParser.check(wantedComments)); } } diff --git a/Examples/test-suite/java/doxygen_translate_links_runme.java b/Examples/test-suite/java/doxygen_translate_links_runme.java index 6d74e16fe..afee4eac6 100644 --- a/Examples/test-suite/java/doxygen_translate_links_runme.java +++ b/Examples/test-suite/java/doxygen_translate_links_runme.java @@ -1,6 +1,5 @@ import doxygen_translate_links.*; -import com.sun.javadoc.*; import java.util.HashMap; public class doxygen_translate_links_runme { @@ -15,14 +14,7 @@ public class doxygen_translate_links_runme { 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_translate_links runtime test", - "CommentParser", - new String[]{"-quiet", "doxygen_translate_links"}); + CommentParser.parse("doxygen_translate_links"); HashMap wantedComments = new HashMap(); @@ -64,6 +56,6 @@ public class doxygen_translate_links_runme { ""); // and ask the parser to check comments for us - System.exit(parser.check(wantedComments)); + System.exit(CommentParser.check(wantedComments)); } } \ No newline at end of file diff --git a/Examples/test-suite/java/doxygen_translate_runme.java b/Examples/test-suite/java/doxygen_translate_runme.java index 55e5d23d3..b049a6466 100644 --- a/Examples/test-suite/java/doxygen_translate_runme.java +++ b/Examples/test-suite/java/doxygen_translate_runme.java @@ -1,6 +1,5 @@ import doxygen_translate.*; -import com.sun.javadoc.*; import java.util.HashMap; import java.util.Map; @@ -16,14 +15,7 @@ public class doxygen_translate_runme { 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_translate runtime test", - "CommentParser", - new String[]{"-quiet", "doxygen_translate"}); + CommentParser.parse("doxygen_translate"); Map wantedComments = new HashMap(); @@ -274,6 +266,6 @@ public class doxygen_translate_runme { ""); // and ask the parser to check comments for us - System.exit(parser.check(wantedComments)); + System.exit(CommentParser.check(wantedComments)); } } diff --git a/Source/CParse/cscanner.c b/Source/CParse/cscanner.c index 4566817a0..7a9c05c95 100644 --- a/Source/CParse/cscanner.c +++ b/Source/CParse/cscanner.c @@ -873,10 +873,14 @@ int yylex(void) { return (USING); if (strcmp(yytext, "namespace") == 0) return (NAMESPACE); - if (strcmp(yytext, "override") == 0) + if (strcmp(yytext, "override") == 0) { + last_id = 1; return (OVERRIDE); - if (strcmp(yytext, "final") == 0) + } + if (strcmp(yytext, "final") == 0) { + last_id = 1; return (FINAL); + } } else { if (strcmp(yytext, "class") == 0) { Swig_warning(WARN_PARSE_CLASS_KEYWORD, cparse_file, cparse_line, "class keyword used, but not in C++ mode.\n"); diff --git a/Source/DOH/README b/Source/DOH/README index 8be5f652a..be90f25b4 100644 --- a/Source/DOH/README +++ b/Source/DOH/README @@ -73,11 +73,17 @@ Replace(obj, orig, rep, flags) Replace occurrences of orig with rep. Chop(obj) Remove trailing whitespace flags is one of the following: - DOH_REPLACE_ANY - DOH_REPLACE_NOQUOTE - DOH_REPLACE_ID - DOH_REPLACE_FIRST - + DOH_REPLACE_ID + DOH_REPLACE_ID_BEGIN + DOH_REPLACE_ID_END + DOH_REPLACE_NUMBER_END + +and can be combined with one or more of the following: + DOH_REPLACE_ANY + DOH_REPLACE_NOQUOTE + DOH_REPLACE_NOCOMMENT + DOH_REPLACE_FIRST + Callable Operations ------------------- Call(obj, args) Perform a function call with arguments args. diff --git a/Source/DOH/doh.h b/Source/DOH/doh.h index 7fb64c058..fd0530e9c 100644 --- a/Source/DOH/doh.h +++ b/Source/DOH/doh.h @@ -289,11 +289,12 @@ extern char *DohStrchr(const DOHString_or_char *s1, int ch); #define DOH_REPLACE_ANY 0x01 #define DOH_REPLACE_NOQUOTE 0x02 -#define DOH_REPLACE_ID 0x04 -#define DOH_REPLACE_FIRST 0x08 -#define DOH_REPLACE_ID_BEGIN 0x10 -#define DOH_REPLACE_ID_END 0x20 -#define DOH_REPLACE_NUMBER_END 0x40 +#define DOH_REPLACE_NOCOMMENT 0x04 +#define DOH_REPLACE_ID 0x08 +#define DOH_REPLACE_FIRST 0x10 +#define DOH_REPLACE_ID_BEGIN 0x20 +#define DOH_REPLACE_ID_END 0x40 +#define DOH_REPLACE_NUMBER_END 0x80 #define Replaceall(s,t,r) DohReplace(s,t,r,DOH_REPLACE_ANY) #define Replaceid(s,t,r) DohReplace(s,t,r,DOH_REPLACE_ID) diff --git a/Source/DOH/string.c b/Source/DOH/string.c index 6c6728578..3689f4ffe 100644 --- a/Source/DOH/string.c +++ b/Source/DOH/string.c @@ -595,6 +595,13 @@ static char *end_quote(char *s) { } } +static char *end_comment(char *s) { + char *substring = strstr(s, "*/"); + if (substring) + ++substring; + return substring; +} + static char *match_simple(char *base, char *s, char *token, int tokenlen) { (void) base; (void) tokenlen; @@ -677,6 +684,7 @@ static int replace_simple(String *str, char *token, char *rep, int flags, int co int ic; int rcount = 0; int noquote = 0; + int nocomment = 0; char *c, *s, *t, *first; char *q, *q2; char *base; @@ -698,6 +706,11 @@ static int replace_simple(String *str, char *token, char *rep, int flags, int co if (flags & DOH_REPLACE_NOQUOTE) noquote = 1; + if (flags & DOH_REPLACE_NOCOMMENT) + nocomment = 1; + + assert(!(noquote && nocomment)); /* quote and comment combination not implemented */ + /* If we are not replacing inside quotes, we need to do a little extra work */ if (noquote) { q = strpbrk(base, "\"\'"); @@ -723,6 +736,31 @@ static int replace_simple(String *str, char *token, char *rep, int flags, int co } } + /* If we are not replacing inside comments, we need to do a little extra work */ + if (nocomment) { + q = strstr(base, "/*"); + if (!q) { + nocomment = 0; /* Well, no comments to worry about. Oh well */ + } else { + while (q && (q < s)) { + /* First match was found inside a comment. Try to find another match */ + q2 = end_comment(q); + if (!q2) { + return 0; + } + if (q2 > s) { + /* Find next match */ + s = (*match) (base, q2 + 1, token, tokenlen); + } + if (!s) + return 0; /* Oh well, no matches */ + q = strstr(q2 + 1, "/*"); + if (!q) + nocomment = 0; /* No more comments */ + } + } + } + first = s; replen = (int)strlen(rep); @@ -768,6 +806,28 @@ static int replace_simple(String *str, char *token, char *rep, int flags, int co } } } + if (nocomment) { + q = strstr(s, "/*"); + if (!q) { + nocomment = 0; + } else { + while (q && (q < c)) { + /* First match was found inside a comment. Try to find another match */ + q2 = end_comment(q); + if (!q2) { + c = 0; + break; + } + if (q2 > c) + c = (*match) (base, q2 + 1, token, tokenlen); + if (!c) + break; + q = strstr(q2 + 1, "/*"); + if (!q) + nocomment = 0; /* No more comments */ + } + } + } if (delta) { if (c) { memmove(t, s, c - s); @@ -823,6 +883,29 @@ static int replace_simple(String *str, char *token, char *rep, int flags, int co } } } + if (nocomment) { + q = strstr(s, "/*"); + if (!q) { + break; + } else { + while (q && (q < c)) { + /* First match was found inside a comment. Try to find another match */ + q2 = end_comment(q); + if (!q2) { + c = 0; + break; + } + if (q2 > c) { + c = (*match) (base, q2 + 1, token, tokenlen); + if (!c) + break; + } + q = strstr(q2 + 1, "/*"); + if (!q) + nocomment = 0; + } + } + } if (c) { rcount++; ic--; @@ -875,6 +958,29 @@ static int replace_simple(String *str, char *token, char *rep, int flags, int co } } } + if (nocomment) { + q = strstr(s, "/*"); + if (!q) { + nocomment = 0; + } else { + while (q && (q < c)) { + /* First match was found inside a comment. Try to find another match */ + q2 = end_comment(q); + if (!q2) { + c = 0; + break; + } + if (q2 > c) { + c = (*match) (base, q2 + 1, token, tokenlen); + if (!c) + break; + } + q = strstr(q2 + 1, "/*"); + if (!q) + nocomment = 0; /* No more comments */ + } + } + } if (i < (rcount - 1)) { memcpy(t, s, c - s); t += (c - s); diff --git a/Source/Modules/csharp.cxx b/Source/Modules/csharp.cxx index 17100b330..d08884b0f 100644 --- a/Source/Modules/csharp.cxx +++ b/Source/Modules/csharp.cxx @@ -4064,11 +4064,10 @@ public: /* Get the C# parameter type */ if ((tm = Getattr(p, "tmap:cstype"))) { substituteClassname(pt, tm); - if (Strncmp(tm, "ref ", 4) == 0) { - Replace(tm, "ref ", "", DOH_REPLACE_FIRST); + int flags = DOH_REPLACE_FIRST | DOH_REPLACE_ID_BEGIN | DOH_REPLACE_NOCOMMENT; + if (Replace(tm, "ref ", "", flags) || Replace(tm, "ref\t", "", flags)) { Printf(proxy_method_types, "typeof(%s).MakeByRefType()", tm); - } else if (Strncmp(tm, "out ", 4) == 0) { - Replace(tm, "out ", "", DOH_REPLACE_FIRST); + } else if (Replace(tm, "out ", "", flags) || Replace(tm, "out\t", "", flags)) { Printf(proxy_method_types, "typeof(%s).MakeByRefType()", tm); } else { Printf(proxy_method_types, "typeof(%s)", tm); diff --git a/appveyor.yml b/appveyor.yml index 42eaa36f4..f87cefd0f 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -16,10 +16,10 @@ environment: - SWIGLANG: python VSVER: 14 VER: 27 - - SWIGLANG: python - VSVER: 14 - VER: 36 - PY3: 3 +# - SWIGLANG: python +# VSVER: 14 +# VER: 36 +# PY3: 3 - SWIGLANG: python OSVARIANT: cygwin - SWIGLANG: python diff --git a/configure.ac b/configure.ac index ea469c24e..b4cadefd0 100644 --- a/configure.ac +++ b/configure.ac @@ -1348,6 +1348,33 @@ else JAVAC="$JAVACBIN" fi +# Check Java version: we require Java 9 or later for Doxygen tests. +if test -n "$JAVAC"; then + AC_MSG_CHECKING(if java version is 9 or greater) + javac_version=`"$JAVAC" -version 2>&1` + java_version_num=`echo $javac_version | sed -n 's/^javac //p'` + if test -z "$java_version_num"; then + AC_MSG_WARN([unknown format for Java version returned by "$JAVAC" ($javac_version)]) + JAVA_SKIP_DOXYGEN_TEST_CASES=1 + AC_MSG_RESULT(unknown) + else + dnl Until Java 8 version number was in format "1.x", starting from + dnl Java 9 it's just "x". + case $java_version_num in + 1.*) + JAVA_SKIP_DOXYGEN_TEST_CASES=1 + AC_MSG_RESULT([no, disabling Doxygen tests]) + ;; + + *) + AC_MSG_RESULT(yes) + ;; + esac + fi + + AC_SUBST(JAVA_SKIP_DOXYGEN_TEST_CASES) +fi + AC_MSG_CHECKING(for java include file jni.h) AC_ARG_WITH(javaincl, [ --with-javaincl=path Set location of Java include directory], [JAVAINCDIR="$withval"], [JAVAINCDIR=]) @@ -1408,15 +1435,6 @@ if test -z "$JAVA_HOME" && test -n "$JAVA_HOME_MAYBE" ; then fi fi -# Javadoc support required for the Java test-suite is available by default in jdk9+ and in tools.jar in earlier jdk versions -AC_MSG_CHECKING(for java tools.jar) -if test -n "$JAVA_HOME" && test -r "$JAVA_HOME/lib/tools.jar" ; then - JAVA_TOOLS_JAR="$JAVA_HOME/lib/tools.jar" - AC_MSG_RESULT([$JAVA_TOOLS_JAR]) -else - AC_MSG_RESULT(not found) -fi - case $host in *-*-cygwin*) # TODO: Only use this flag if the compiler supports it, later versions of gcc no longer have it @@ -1483,7 +1501,6 @@ AC_SUBST(JAVA) AC_SUBST(JAVAC) AC_SUBST(JAVAINC) AC_SUBST(JAVA_CLASSPATH_SEP) -AC_SUBST(JAVA_TOOLS_JAR) AC_SUBST(JAVADYNAMICLINKING) AC_SUBST(JAVALIBRARYPREFIX) AC_SUBST(JAVASO)