You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by ju...@apache.org on 2022/01/14 14:01:51 UTC
svn commit: r1897034 [7/37] - in /subversion/branches/multi-wc-format: ./ build/ build/ac-macros/ build/generator/ build/generator/swig/ build/generator/templates/ contrib/client-side/ contrib/client-side/svn_load_dirs/ contrib/hook-scripts/ contrib/se...
Modified: subversion/branches/multi-wc-format/subversion/bindings/javahl/tests/org/apache/subversion/javahl/BasicTests.java
URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/bindings/javahl/tests/org/apache/subversion/javahl/BasicTests.java?rev=1897034&r1=1897033&r2=1897034&view=diff
==============================================================================
--- subversion/branches/multi-wc-format/subversion/bindings/javahl/tests/org/apache/subversion/javahl/BasicTests.java (original)
+++ subversion/branches/multi-wc-format/subversion/bindings/javahl/tests/org/apache/subversion/javahl/BasicTests.java Fri Jan 14 14:01:45 2022
@@ -22,7 +22,10 @@
*/
package org.apache.subversion.javahl;
+import static org.junit.Assert.*;
+
import org.apache.subversion.javahl.callback.*;
+import org.apache.subversion.javahl.remote.*;
import org.apache.subversion.javahl.types.*;
import java.io.File;
@@ -34,6 +37,7 @@ import java.io.PrintWriter;
import java.io.ByteArrayOutputStream;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
+import java.nio.channels.ClosedChannelException;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
import java.text.ParseException;
@@ -2736,7 +2740,7 @@ public class BasicTests extends SVNTests
public void singleMessage(Set<ChangePath> changedPaths,
long revision, Map<String, byte[]> revprops,
boolean hasChildren)
- { revList.add(new Long(revision)); }
+ { revList.add(Long.valueOf(revision)); }
});
long[] revisions = new long[revList.size()];
@@ -4093,6 +4097,7 @@ public class BasicTests extends SVNTests
* @throws Throwable
* @since 1.5
*/
+ @SuppressWarnings("deprecation")
public void testBasicBlame() throws Throwable
{
OneTest thisTest = new OneTest();
@@ -4122,6 +4127,7 @@ public class BasicTests extends SVNTests
* Test blame with diff options.
* @since 1.9
*/
+ @SuppressWarnings("deprecation")
public void testBlameWithDiffOptions() throws Throwable
{
OneTest thisTest = new OneTest();
@@ -4155,6 +4161,49 @@ public class BasicTests extends SVNTests
}
/**
+ * Test the new 1.12 blame interface on a file with null bytes.
+ * @throws Throwable
+ * @since 1.12
+ */
+ public void testBinaryBlame() throws Throwable
+ {
+ final byte[] lineIn = {0x0, 0x0, 0x0, 0xa};
+ final byte[] lineOut = {0x0, 0x0, 0x0};
+
+ OneTest thisTest = new OneTest();
+ // Modify the file iota, adding null bytes.
+ File iota = new File(thisTest.getWorkingCopy(), "iota");
+ FileOutputStream stream = new FileOutputStream(iota, false);
+ stream.write(lineIn);
+ stream.close();
+ Set<String> srcPaths = new HashSet<String>(1);
+ srcPaths.add(thisTest.getWCPath());
+ try {
+ client.username("rayjandom");
+ client.commit(srcPaths, Depth.infinity, false, false, null, null,
+ new ConstMsg("NUL bytes written to /iota"), null);
+ } finally {
+ client.username("jrandom");
+ }
+
+ // Test the current interface
+ BlameRangeCallbackImpl rangeCallback = new BlameRangeCallbackImpl();
+ BlameLineCallbackImpl lineCallback = new BlameLineCallbackImpl();
+ client.blame(thisTest.getWCPath() + "/iota", Revision.HEAD,
+ Revision.getInstance(0), Revision.HEAD,
+ false, false, null, rangeCallback, lineCallback);
+ assertEquals(0, rangeCallback.startRevnum);
+ assertEquals(2, rangeCallback.endRevnum);
+ assertEquals(1, lineCallback.numberOfLines());
+
+ BlameLineCallbackImpl.BlameLine line = lineCallback.getBlameLine(0);
+ assertNotNull(line);
+ assertEquals(2, line.getRevision());
+ assertEquals("rayjandom", line.getAuthor());
+ assertArrayEquals(lineOut, line.getLine());
+ }
+
+ /**
* Test commit of arbitrary revprops.
* @throws Throwable
* @since 1.5
@@ -4370,6 +4419,320 @@ public class BasicTests extends SVNTests
assertEquals("fake", new String(revprop));
}
+ public static int FLAG_ECHO = 0x00000001;
+ public static int FLAG_THROW_IN_OPEN = 0x00000002;
+
+ public enum Actions
+ {
+ READ_CLIENT, // Read a request from SVN client
+ EMUL_SERVER, // Emulate server response
+ WAIT_TUNNEL, // Wait for tunnel to be closed
+ };
+
+ public static class ScriptItem
+ {
+ Actions action;
+ String value;
+
+ ScriptItem(Actions action, String value)
+ {
+ this.action = action;
+ this.value = value;
+ }
+ }
+
+ private static class TestTunnelAgent extends Thread
+ implements TunnelAgent
+ {
+ ScriptItem[] script;
+ int flags;
+ String error = null;
+ ReadableByteChannel request;
+ WritableByteChannel response;
+
+ final CloseTunnelCallback closeTunnelCallback = () ->
+ {
+ if ((flags & FLAG_ECHO) != 0)
+ System.out.println("TunnelAgent.CloseTunnelCallback");
+ };
+
+ TestTunnelAgent(int flags, ScriptItem[] script)
+ {
+ this.flags = flags;
+ this.script = script;
+ }
+
+ public void joinAndTest()
+ {
+ try
+ {
+ join();
+ }
+ catch (InterruptedException e)
+ {
+ fail("InterruptedException was caught");
+ }
+
+ if (error != null)
+ fail(error);
+ }
+
+ @Override
+ public boolean checkTunnel(String name)
+ {
+ return true;
+ }
+
+ private String readClient(ByteBuffer readBuffer)
+ throws IOException
+ {
+ readBuffer.reset();
+ request.read(readBuffer);
+
+ final int offset = readBuffer.arrayOffset();
+ return new String(readBuffer.array(),
+ offset,
+ readBuffer.position() - offset);
+ }
+
+ private void emulateServer(String serverMessage)
+ throws IOException
+ {
+ final byte[] responseBytes = serverMessage.getBytes();
+ response.write(ByteBuffer.wrap(responseBytes));
+ }
+
+ private void doScriptItem(ScriptItem scriptItem, ByteBuffer readBuffer)
+ throws Exception
+ {
+ switch (scriptItem.action)
+ {
+ case READ_CLIENT:
+ final String actualLine = readClient(readBuffer);
+
+ if ((flags & FLAG_ECHO) != 0)
+ {
+ System.out.println("SERVER: " + scriptItem.value);
+ System.out.flush();
+ }
+
+ if (!actualLine.contains(scriptItem.value))
+ {
+ System.err.println("Expected: " + scriptItem.value);
+ System.err.println("Actual: " + actualLine);
+ System.err.flush();
+
+ // Unblock the SVN thread by emulating a server error
+ final String serverError = "( success ( ( ) 0: ) ) ( failure ( ( 160000 39:Test script received unexpected request 0: 0 ) ) ) ";
+ emulateServer(serverError);
+
+ fail("Unexpected client request");
+ }
+ break;
+ case EMUL_SERVER:
+ if ((flags & FLAG_ECHO) != 0)
+ {
+ System.out.println("CLIENT: " + scriptItem.value);
+ System.out.flush();
+ }
+
+ emulateServer(scriptItem.value);
+ break;
+ case WAIT_TUNNEL:
+ // The loop will end with an exception when tunnel is closed
+ for (;;)
+ {
+ readClient(readBuffer);
+ }
+ }
+ }
+
+ public void run()
+ {
+ final ByteBuffer readBuffer = ByteBuffer.allocate(1024 * 1024);
+ readBuffer.mark();
+
+ for (ScriptItem scriptItem : script)
+ {
+ try
+ {
+ doScriptItem(scriptItem, readBuffer);
+ }
+ catch (ClosedChannelException ex)
+ {
+ // Expected when closed properly
+ }
+ catch (IOException e)
+ {
+ // IOException occurs when already-freed apr_file_t was lucky
+ // to have reasonable fields to avoid the crash. It still
+ // indicates a problem.
+ error = "IOException was caught in run()";
+ return;
+ }
+ catch (Throwable t)
+ {
+ // No other exceptions are expected here.
+ error = "Exception was caught in run()";
+ t.printStackTrace();
+ return;
+ }
+ }
+ }
+
+ @Override
+ public CloseTunnelCallback openTunnel(ReadableByteChannel request,
+ WritableByteChannel response,
+ String name,
+ String user,
+ String hostname,
+ int port)
+ throws Throwable
+ {
+ this.request = request;
+ this.response = response;
+
+ start();
+
+ if ((flags & FLAG_THROW_IN_OPEN) != 0)
+ throw ClientException.fromException(new RuntimeException("Test exception"));
+
+ return closeTunnelCallback;
+ }
+ };
+
+ /**
+ * Test scenario which previously caused a JVM crash.
+ * In this scenario, GC is invoked before closing tunnel.
+ */
+ public void testCrash_RemoteSession_nativeDispose()
+ {
+ final ScriptItem[] script = new ScriptItem[]
+ {
+ new ScriptItem(Actions.EMUL_SERVER, "( success ( 2 2 ( ) ( edit-pipeline svndiff1 absent-entries commit-revprops depth log-revprops atomic-revprops partial-replay inherited-props ephemeral-txnprops file-revs-reverse ) ) ) "),
+ new ScriptItem(Actions.READ_CLIENT, "edit-pipeline"),
+ new ScriptItem(Actions.EMUL_SERVER, "( success ( ( ANONYMOUS ) 36:0113e071-0208-4a7b-9f20-3038f9caf0f0 ) ) "),
+ new ScriptItem(Actions.READ_CLIENT, "ANONYMOUS"),
+ new ScriptItem(Actions.EMUL_SERVER, "( success ( ) ) ( success ( 36:00000000-0000-0000-0000-000000000000 25:svn+test://localhost/test ( mergeinfo ) ) ) "),
+ };
+
+ final TestTunnelAgent tunnelAgent = new TestTunnelAgent(0, script);
+ final RemoteFactory remoteFactory = new RemoteFactory();
+ remoteFactory.setTunnelAgent(tunnelAgent);
+
+ ISVNRemote remote = null;
+ try
+ {
+ remote = remoteFactory.openRemoteSession("svn+test://localhost/test", 1);
+ }
+ catch (SubversionException e)
+ {
+ fail("SubversionException was caught");
+ }
+
+ // Previously, 'OperationContext::openTunnel()' didn't 'NewGlobalRef()'
+ // callback returned by 'TunnelAgent.openTunnel()'. This caused JVM to
+ // dispose it on next GC. JavaHL calls callback in 'remote.dispose()'.
+ // If the callback was disposed, this caused a JVM crash.
+ System.gc();
+ remote.dispose();
+
+ tunnelAgent.joinAndTest();
+ }
+
+ /**
+ * Test scenario which previously caused a JVM crash.
+ * In this scenario, tunnel was not properly closed after exception in
+ * 'TunnelAgent.openTunnel()'.
+ */
+ public void testCrash_RequestChannel_nativeRead_AfterException()
+ {
+ // Previously, exception caused TunnelChannel's native side to be
+ // destroyed with the following abbreviated stack:
+ // TunnelChannel.nativeClose()
+ // svn_pool_destroy(sesspool)
+ // svn_ra_open5()
+ // TunnelAgent was unaware and called 'RequestChannel.nativeRead()'
+ // or 'ResponseChannel.nativeWrite()', causing either a crash or
+ // an attempt to use a random file.
+ final int flags = FLAG_THROW_IN_OPEN;
+
+ final ScriptItem[] script = new ScriptItem[]
+ {
+ new ScriptItem(Actions.EMUL_SERVER, "( success ( 2 2 ( ) ( edit-pipeline svndiff1 absent-entries commit-revprops depth log-revprops atomic-revprops partial-replay inherited-props ephemeral-txnprops file-revs-reverse ) ) ) "),
+ new ScriptItem(Actions.WAIT_TUNNEL, ""),
+ };
+
+ final TestTunnelAgent tunnelAgent = new TestTunnelAgent(flags, script);
+ final SVNClient svnClient = new SVNClient();
+ svnClient.setTunnelAgent(tunnelAgent);
+
+ try
+ {
+ svnClient.openRemoteSession("svn+test://localhost/test");
+ }
+ catch (SubversionException e)
+ {
+ // RuntimeException("Test exception") is expected here
+ }
+
+ tunnelAgent.joinAndTest();
+ }
+
+ /**
+ * Test scenario which previously caused a JVM crash.
+ * In this scenario, tunnel was not properly closed after an SVN error.
+ */
+ public void testCrash_RequestChannel_nativeRead_AfterSvnError()
+ {
+ final String wcRoot = new File("tempSvnRepo").getAbsolutePath();
+
+ final ScriptItem[] script = new ScriptItem[]
+ {
+ // openRemoteSession
+ new ScriptItem(Actions.EMUL_SERVER, "( success ( 2 2 ( ) ( edit-pipeline svndiff1 absent-entries commit-revprops depth log-revprops atomic-revprops partial-replay inherited-props ephemeral-txnprops file-revs-reverse ) ) ) "),
+ new ScriptItem(Actions.READ_CLIENT, "edit-pipeline"),
+ new ScriptItem(Actions.EMUL_SERVER, "( success ( ( ANONYMOUS ) 36:0113e071-0208-4a7b-9f20-3038f9caf0f0 ) ) "),
+ new ScriptItem(Actions.READ_CLIENT, "ANONYMOUS"),
+ new ScriptItem(Actions.EMUL_SERVER, "( success ( ) ) ( success ( 36:00000000-0000-0000-0000-000000000000 25:svn+test://localhost/test ( mergeinfo ) ) ) "),
+ // checkout
+ new ScriptItem(Actions.READ_CLIENT, "( get-latest-rev ( ) ) "),
+ // Previously, error caused a SubversionException to be created,
+ // which then skipped closing the Tunnel properly due to
+ // 'ExceptionOccurred()' in 'OperationContext::closeTunnel()'.
+ // If TunnelAgent was unaware and called 'RequestChannel.nativeRead()',
+ // it either crashed or tried to use a random file.
+ new ScriptItem(Actions.EMUL_SERVER, "( success ( ( ) 0: ) ) ( failure ( ( 160006 20:This is a test error 0: 0 ) ) ) "),
+ // Pretend that TunnelAgent tries to read more
+ new ScriptItem(Actions.WAIT_TUNNEL, ""),
+ };
+
+ final TestTunnelAgent tunnelAgent = new TestTunnelAgent(0, script);
+ final SVNClient svnClient = new SVNClient();
+ svnClient.setTunnelAgent(tunnelAgent);
+
+ try
+ {
+ svnClient.checkout("svn+test://localhost/test",
+ wcRoot,
+ Revision.getInstance(1),
+ null,
+ Depth.infinity,
+ true,
+ false);
+
+ svnClient.dispose();
+ }
+ catch (ClientException ex)
+ {
+ final int SVN_ERR_FS_NO_SUCH_REVISION = 160006;
+ if (SVN_ERR_FS_NO_SUCH_REVISION != ex.getAllMessages().get(0).getCode())
+ ex.printStackTrace();
+ }
+
+ tunnelAgent.joinAndTest();
+ }
+
/**
* @return <code>file</code> converted into a -- possibly
* <code>canonical</code>-ized -- Subversion-internal path
@@ -4679,6 +5042,7 @@ public class BasicTests extends SVNTests
return callback.getMessages();
}
+ @SuppressWarnings("deprecation")
private byte[] collectBlameLines(String path, Revision pegRevision,
Revision revisionStart,
Revision revisionEnd,
@@ -4766,6 +5130,7 @@ public class BasicTests extends SVNTests
}
/* A blame callback implementation. */
+ @SuppressWarnings("deprecation")
protected class BlameCallbackImpl implements BlameCallback
{
@@ -4978,6 +5343,158 @@ public class BasicTests extends SVNTests
}
}
}
+
+ /* A blame range callback implementation. */
+ protected class BlameRangeCallbackImpl implements BlameRangeCallback
+ {
+ public long startRevnum = -1;
+ public long endRevnum = -1;
+ public void setRange(long start, long end)
+ {
+ startRevnum = start;
+ endRevnum = end;
+ }
+ }
+
+ /* A blame line callback implementation. */
+ protected class BlameLineCallbackImpl implements BlameLineCallback
+ {
+
+ /** list of blame records (lines) */
+ private List<BlameLine> lines = new ArrayList<BlameLine>();
+
+ public void singleLine(long lineNum, long rev,
+ Map<String, byte[]> revProps,
+ long mergedRevision,
+ Map<String, byte[]> mergedRevProps,
+ String mergedPath, boolean localChange,
+ byte[] line)
+ throws ClientException
+ {
+ DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
+
+ try {
+ insertLine(
+ df.parse(new String(revProps.get("svn:date"))),
+ rev,
+ new String(revProps.get("svn:author")),
+ mergedRevProps == null ? null
+ : df.parse(new String(mergedRevProps.get("svn:date"))),
+ mergedRevision,
+ mergedRevProps == null ? null
+ : new String(mergedRevProps.get("svn:author")),
+ mergedPath, line);
+ } catch (ParseException e) {
+ throw ClientException.fromException(e);
+ }
+ }
+
+ private Date getDate(Date date, Date merged_date) {
+ return (merged_date == null ? date : merged_date);
+ }
+
+ private String getAuthor(String author, String merged_author) {
+ return (merged_author == null ? author : merged_author);
+ }
+
+ private long getRevision(long revision, long merged_revision) {
+ return (merged_revision == -1 ? revision : merged_revision);
+ }
+
+ private void insertLine(Date date, long revision, String author,
+ Date merged_date, long merged_revision,
+ String merged_author, String merged_path,
+ byte[] line)
+ {
+ this.lines.add(new BlameLine(getRevision(revision, merged_revision),
+ getAuthor(author, merged_author),
+ getDate(date, merged_date),
+ line));
+ }
+
+ /**
+ * Retrieve the number of line of blame information
+ * @return number of lines of blame information
+ */
+ public int numberOfLines()
+ {
+ return this.lines.size();
+ }
+
+ /**
+ * Retrieve blame information for specified line number
+ * @param i the line number to retrieve blame information about
+ * @return Returns object with blame information for line
+ */
+ public BlameLine getBlameLine(int i)
+ {
+ if (i >= this.lines.size())
+ {
+ return null;
+ }
+ return this.lines.get(i);
+ }
+
+ /**
+ * Class represeting one line of the lines, i.e. a blame record
+ */
+ public final class BlameLine
+ {
+ private long revision;
+ private String author;
+ private Date changed;
+ private byte[] line;
+
+ /**
+ * Constructor
+ *
+ * @param revision
+ * @param author
+ * @param changed
+ * @param line
+ */
+ public BlameLine(long revision, String author,
+ Date changed, byte[] line)
+ {
+ this.revision = revision;
+ this.author = author;
+ this.changed = changed;
+ this.line = line;
+ }
+
+ /**
+ * @return Returns the author.
+ */
+ public String getAuthor()
+ {
+ return author;
+ }
+
+ /**
+ * @return Returns the date changed.
+ */
+ public Date getChanged()
+ {
+ return changed;
+ }
+
+ /**
+ * @return Returns the source line content.
+ */
+ public byte[] getLine()
+ {
+ return line;
+ }
+
+ /**
+ * @return Returns the revision.
+ */
+ public long getRevision()
+ {
+ return revision;
+ }
+ }
+ }
/** A helper which calls update with a bunch of default args. */
private long update(OneTest thisTest)
Modified: subversion/branches/multi-wc-format/subversion/bindings/javahl/tests/org/apache/subversion/javahl/ExceptionTests.java
URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/bindings/javahl/tests/org/apache/subversion/javahl/ExceptionTests.java?rev=1897034&r1=1897033&r2=1897034&view=diff
==============================================================================
--- subversion/branches/multi-wc-format/subversion/bindings/javahl/tests/org/apache/subversion/javahl/ExceptionTests.java (original)
+++ subversion/branches/multi-wc-format/subversion/bindings/javahl/tests/org/apache/subversion/javahl/ExceptionTests.java Fri Jan 14 14:01:45 2022
@@ -206,18 +206,17 @@ public class ExceptionTests extends SVNT
{
client.blame(thisTest.getWorkingCopy() + "/iota",
Revision.getInstance(1), Revision.getInstance(1),
- Revision.getInstance(1), false, false,
- new BlameCallback()
- {
- public void singleLine(long lineNum, long revision,
- Map<String, byte[]> revProps, long mergedRevision,
- Map<String, byte[]> mergedRevProps,
- String mergedPath, String line,
- boolean localChange)
- {
- throw new TestException("inner", theException);
- }
- });
+ Revision.getInstance(1), false, false, null, null,
+ new BlameLineCallback() {
+ public void singleLine(long lineNum, long revision,
+ Map<String, byte[]> revProps, long mergedRevision,
+ Map<String, byte[]> mergedRevProps,
+ String mergedPath, boolean localChange,
+ byte[] line)
+ {
+ throw new TestException("inner", theException);
+ }
+ });
}
catch (ClientException e)
{
Modified: subversion/branches/multi-wc-format/subversion/bindings/javahl/tests/org/apache/subversion/javahl/SVNRemoteTests.java
URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/bindings/javahl/tests/org/apache/subversion/javahl/SVNRemoteTests.java?rev=1897034&r1=1897033&r2=1897034&view=diff
==============================================================================
--- subversion/branches/multi-wc-format/subversion/bindings/javahl/tests/org/apache/subversion/javahl/SVNRemoteTests.java (original)
+++ subversion/branches/multi-wc-format/subversion/bindings/javahl/tests/org/apache/subversion/javahl/SVNRemoteTests.java Fri Jan 14 14:01:45 2022
@@ -1383,9 +1383,9 @@ public class SVNRemoteTests extends SVNT
{
ISVNRemote session = getSession();
- Long expected = new Long(1L);
+ Long expected = Long.valueOf(1L);
ArrayList<Long> revs = new ArrayList<Long>(3);
- revs.add(new Long(0L));
+ revs.add(Long.valueOf(0L));
revs.add(expected);
Map<Long, String> locs = session.getLocations("A", 1, revs);
Modified: subversion/branches/multi-wc-format/subversion/bindings/javahl/tests/org/apache/subversion/javahl/SVNTests.java
URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/bindings/javahl/tests/org/apache/subversion/javahl/SVNTests.java?rev=1897034&r1=1897033&r2=1897034&view=diff
==============================================================================
--- subversion/branches/multi-wc-format/subversion/bindings/javahl/tests/org/apache/subversion/javahl/SVNTests.java (original)
+++ subversion/branches/multi-wc-format/subversion/bindings/javahl/tests/org/apache/subversion/javahl/SVNTests.java Fri Jan 14 14:01:45 2022
@@ -224,7 +224,7 @@ class SVNTests extends TestCase
rootUrl = rootUrl.replaceFirst("file:/", "file:///");
// According to
- // http://java.sun.com/j2se/1.5.0/docs/api/java/io/File.html#toURL()
+ // https://docs.oracle.com/javase/1.5.0/docs/api/java/io/File.html#toURL()
// the URL from rootDir.toURI() may end with a trailing /
// if rootDir exists and is a directory, so depending if
// the test suite has been previously run and rootDir
Modified: subversion/branches/multi-wc-format/subversion/bindings/javahl/tests/org/tigris/subversion/javahl/SVNTests.java
URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/bindings/javahl/tests/org/tigris/subversion/javahl/SVNTests.java?rev=1897034&r1=1897033&r2=1897034&view=diff
==============================================================================
--- subversion/branches/multi-wc-format/subversion/bindings/javahl/tests/org/tigris/subversion/javahl/SVNTests.java (original)
+++ subversion/branches/multi-wc-format/subversion/bindings/javahl/tests/org/tigris/subversion/javahl/SVNTests.java Fri Jan 14 14:01:45 2022
@@ -183,7 +183,7 @@ class SVNTests extends TestCase
rootUrl = rootUrl.replaceFirst("file:/", "file:///");
// According to
- // http://java.sun.com/j2se/1.5.0/docs/api/java/io/File.html#toURL()
+ // https://docs.oracle.com/javase/1.5.0/docs/api/java/io/File.html#toURL()
// the URL from rootDir.toURI() may end with a trailing /
// if rootDir exists and is a directory, so depending if
// the test suite has been previously run and rootDir
Modified: subversion/branches/multi-wc-format/subversion/bindings/swig/INSTALL
URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/bindings/swig/INSTALL?rev=1897034&r1=1897033&r2=1897034&view=diff
==============================================================================
--- subversion/branches/multi-wc-format/subversion/bindings/swig/INSTALL (original)
+++ subversion/branches/multi-wc-format/subversion/bindings/swig/INSTALL Fri Jan 14 14:01:45 2022
@@ -5,7 +5,12 @@ STATUS OF THE SWIG BINDINGS
* Python
The Python bindings are fairly well developed, although there are some
- missing parts.
+ missing parts. We support both of Python 2.7 and Python 3.x; however,
+ SWIG Python bindings for different versions of Python cannot be
+ simultaneously installed in the same environment, because they need to
+ install mutually incompatible C shared libraries under the same name. The
+ distribution tarballs are shipped with SWIG-generated C source files for
+ Python 3.x.
(N.B. As discussed below, they will not compile in Debug mode on Windows.)
@@ -64,15 +69,36 @@ STATUS OF THE SWIG BINDINGS
BUILDING SWIG BINDINGS FOR SVN ON UNIX
-Step 1: Install a suitable version of SWIG (which is
- currently SWIG version 1.3.24 or later).
+Step 1: [Optional] Install a suitable version of SWIG
- * Perhaps your distribution packages a suitable version - if it does
- install it, and skip to the last bullet point in this section.
+ * SWIG installation is optional. You do not need to install SWIG
+ if you are using a Subversion distribution tarball because it already
+ contains the source files generated by SWIG. You will need a suitable
+ version of SWIG if you are using a working copy of Subversion's sources
+ checked out from the repository; if you want to generate the SWIG
+ language bindings C source files by yourself; or if you want to build
+ Python 2.x bindings (since the SWIG-generated C source files in the
+ distribution tarballs target Python 3.x).
+
+ * We currently support SWIG versions 2.0.0 and later, with the
+ following notes:
+ - SWIG 1.3.24 and later 1.3.x may work, but we do not test these
+ versions on our latest source code.
+ - For Python 2 bindings, SWIG 4.0.0 or later is not supported.
+ - For Python 3 bindings, SWIG 3.0.10 or later is required.
+ - Note that SWIG 3.0.9 has some trouble with Python support.
+ (See https://sourceforge.net/p/swig/news/2016/06/swig-3010-released/)
+ - For Perl 5.16 and later, SWIG 2.0.8 or later is required.
+ - For Ruby bindings, SWIG 3.0.8 is not supported.
+
+ * Perhaps your distribution packages a suitable version of SWIG.
+ If so, install it and skip to the last bullet point of this
+ section.
* Go to http://www.swig.org/, download the source tarball, and unpack.
- * In the SWIG-1.3.xx directory, run ./configure.
+ * In the swig-x.y.z, directory, run ./configure (where x.y.z is
+ SWIG version, e.g., 3.0.12).
If you plan to build the Python bindings, and have a system
with more than one version of Python installed, you may need
@@ -95,43 +121,74 @@ Step 1: Install a suitable version of S
Run 'make && make install'
* To verify you have SWIG installed correctly, run "swig -version"
- from the command line. SWIG should report that it is version 1.3.24
- or newer.
+ from the command line. SWIG should report that it is one of the
+ suitable versions mentioned above.
+
+
+Step 1a: Install py3c library if building Python SWIG bindings.
+
+ * Check your distribution packages first for a suitable version, and
+ if found install from there.
+
+ * To install from source, download the latest release from
+ https://github.com/encukou/py3c.
+
+ * This is a header-only library, so no configuring or compiling is
+ necessary, simply 'make install'.
+
Step 2: Build and Install Subversion.
See Subversion's own INSTALL file for details.
- Make sure that Subversion's ./configure script sees your installed SWIG!
+ If you are using a Subversion distribution tarball and want to rebuild
+ the SWIG language bindings C source files with your installed SWIG,
+ you need to execute autogen.sh, because the bundled configure script
+ and makefiles don't support it.
+
+ If you don't use SWIG bindings C source files already generated,
+ make sure that Subversion's ./configure script sees your installed SWIG!
It tries to detect SWIG near the very end of its output.
+ You can find it by running 'grep "^SWIG=" config.log'.
- Also make sure that the configure script sees the paths to the perl and/or
- python executable you used to configure SWIG as above. If it does not then
- you can specify the correct path by adding PYTHON=/path/to/python or
- PERL=/path/to/perl onto the command line for configure. For example:
- ./configure PYTHON=/usr/bin/python2.7 PERL=/usr/bin/perl5.8.0
+ Also make sure that the configure script sees the paths to the perl,
+ ruby, and/or python executable you used to configure SWIG as above.
+ If it does not then you can specify the correct path by specifying
+ --with-swig-python=/path/to/python, --with-swig-perl=/path/to/perl,
+ and/or --with-swig-ruby=/path/to/ruby to the command line for configure.
+ For example:
+ ./configure --with-swig-python=/usr/bin/python3.7 \
+ --with-swig-perl=/usr/bin/perl5.28.2 \
+ --with-swig-ruby=/usr/bin/ruby2.7
If Subversion's ./configure finds a SWIG that it's happy with, then
it will build special glue libraries to link svn to the swig bindings:
- libsvn_swig_py.so (for Python)
- libsvn_swig_perl.so (for Perl)
-
+ libsvn_swig_py-1.so (for Python)
+ libsvn_swig_perl-1.so (for Perl)
+ libsvn_swig_ruby-1.so (for Ruby)
Step 3: Install Specific Language Bindings
* Python
- 1. Run 'make swig-py' from the top of the Subversion build tree,
+ 1. (Optional) If you want to build Python bindings for a version of
+ Python than other than that the prebuilt bindings C sources target
+ (e.g., if you use the Subversion distribution tarball but want to build
+ Python 2 bindings), run 'make clean-swig-py' from the top of the
+ Subversion build tree, to ensure not to use incompatible version of
+ bindings source files.
+
+ 2. Run 'make swig-py' from the top of the Subversion build tree,
to build the bindings.
(This will invoke SWIG on the *.i files, resulting in a collection
of .c source files. It will then compile and link those .c files into
Python libraries.)
- 2. Run 'make check-swig-py' from the top of the Subversion build
- tree, to test the bindings
+ 3. Run 'make check-swig-py' from the top of the Subversion build
+ tree, to test the bindings
- 3. Run 'make install-swig-py' (as root, typically)
+ 4. Run 'make install-swig-py' (as root, typically)
from the top of the Subversion build tree. This will copy
your new Python libraries into the appropriate system location.
@@ -145,14 +202,14 @@ Step 3: Install Specific Language Bindi
example of doing this for building rpms looks like
'make install-swig-py DESTDIR=$RPM_BUILD_ROOT/usr'.
- 4. Make sure that whatever directory the bindings got installed in
+ 5. Make sure that whatever directory the bindings got installed in
is in your Python search path. That directory depends on how you
installed; a typical location is /usr/local/lib/svn-python/.
There are several ways to do this. See Python's documentation for
'sys.path' and 'PYTHONPATH'. A nice way to do this is:
$ echo /usr/local/lib/svn-python \
- > /usr/lib/python2.x/site-packages/subversion.pth
+ > /usr/lib/python3.x/site-packages/subversion.pth
You may also need to update your operating system's dynamic linker
configuration to enable Python to load these new libraries. On some
@@ -162,15 +219,15 @@ Step 3: Install Specific Language Bindi
* Perl
Perl 5.8.0 is required. You can specify the perl binary by passing
- PERL=/path/to/perl as part of the configure command in the top level
- of the Subversion source tree. Make sure that the Perl version used
- is the same one that you configured SWIG to run against during the
- SWIG configure (see above).
+ --with-swig-perl=/path/to/perl as an option to the configure command
+ in the top level of the Subversion source tree. Make sure that the
+ Perl version used is the same one that you configured SWIG to run
+ against during the SWIG configure (see above).
1. Run `make swig-pl' from the top of the Subversion build tree.
2. Run `make check-swig-pl' from the top of the Subversion build
- tree, to test the bindings
+ tree, to test the bindings
3. to install run `make install-swig-pl' from the top of the
Subversion build tree.
@@ -182,9 +239,9 @@ Step 3: Install Specific Language Bindi
2. Run `make install-swig-pl-lib'
- 3. cd subversion/bindings/swig/perl/native
+ 3. cd subversion/bindings/swig/perl/native
- 4. Run `perl Makefile.PL EXTRAOPTIONSHERE`
+ 4. Run `perl Makefile.PL EXTRAOPTIONSHERE`
5. Run `make install'
@@ -194,21 +251,22 @@ Step 3: Install Specific Language Bindi
* Ruby
-
+
1. Run `make swig-rb' from the top of the Subversion build tree,
to build the bindings.
2. Run `make check-swig-rb' from the top of the Subversion build
tree, to test the bindings.
- 3. To install, run `make install-swig-rb' from the top of the
+ 3. To install, run `make install-swig-rb' from the top of the
Subversion build tree.
- You can specify the ruby binary by passing RUBY=/path/to/ruby as part
- of the configure command in the top level of the Subversion source
- tree. Make sure that the Ruby version used is the same one that you
- configured SWIG to run against during the SWIG configure (see above).
-
+ You can specify the ruby binary by passing --with-swig-ruby=/path/to/ruby
+ as an option to the configure command in the top level of the
+ Subversion source tree. Make sure that the Ruby version used is
+ the same one that you configured SWIG to run against during the
+ SWIG configure (see above).
+
BUILDING SWIG BINDINGS FOR SVN ON WINDOWS
@@ -226,6 +284,9 @@ BUILDING SWIG BINDINGS FOR SVN ON WINDOW
http://www.python.org/
http://www.activestate.com/ActivePerl/
+ If you plan to build python bindings, you will also need to download and
+ extract the py3c library from https://github.com/encukou/py3c/releases.
+
NOTE: Our Python SWIG bindings will currently NOT compile in Debug mode
unless you have python24_d.lib (which binary distributions of
Python do not contain). Therefore, the Python bindings will only
@@ -242,6 +303,11 @@ BUILDING SWIG BINDINGS FOR SVN ON WINDOW
> gen-make.py <other options> --with-swig="C:\Program Files\SWIG-2.0.2"
+ If you are building python bindings, point to the py3c directory as well:
+
+ > gen-make.py <other options> --with-swig="C:\Program Files\SWIG-2.0.2" \
+ --with-py3c="C:\SVN\py3c"
+
4. If you haven't already built Subversion, you should do so now.
Instructions are in the main INSTALL file.
@@ -324,12 +390,12 @@ TESTING SWIG BINDINGS
* Perl
The Perl bindings are using the standard module testing facilities
- to do regression tests. Simply run 'make check-swig-pl' as described in
+ to do regression tests. Simply run 'make check-swig-pl' as described in
the install section.
* Ruby
- To test the Ruby bindings, simply run `make check-swig-rb' as described
+ To test the Ruby bindings, simply run `make check-swig-rb' as described
in the install section.
@@ -361,7 +427,7 @@ USING SWIG BINDINGS
sample/demo programs found in tools/examples/ in the Subversion
source code tree. Additionally, there are several third-party
tools that make use of these bindings, including ViewVC
- (http://viewvc.tigris.org/) and Trac (http://trac.edgewall.org/).
+ (http://www.viewvc.org/) and Trac (https://trac.edgewall.org/).
* Perl
Modified: subversion/branches/multi-wc-format/subversion/bindings/swig/core.i
URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/bindings/swig/core.i?rev=1897034&r1=1897033&r2=1897034&view=diff
==============================================================================
--- subversion/branches/multi-wc-format/subversion/bindings/swig/core.i (original)
+++ subversion/branches/multi-wc-format/subversion/bindings/swig/core.i Fri Jan 14 14:01:45 2022
@@ -23,16 +23,16 @@
* of the more specific module files.
*/
+%include svn_global.swg
+
#if defined(SWIGPYTHON)
-%module(package="libsvn") core
+%module(package="libsvn", moduleimport=SVN_PYTHON_MODULEIMPORT) core
#elif defined(SWIGPERL)
%module "SVN::_Core"
#elif defined(SWIGRUBY)
%module "svn::ext::core"
#endif
-%include svn_global.swg
-
%{
#include <apr.h>
#include <apr_general.h>
@@ -362,7 +362,9 @@
/* svn_config_get */
const char *default_value,
/* svn_config_read_auth_data */
- const char *config_dir,
+ const char *config_dir,
+ /* svn_config_get_user_config_path */
+ const char *fname,
/* svn_diff_file_output_merge */
const char *conflict_original,
const char *conflict_modified,
@@ -381,6 +383,7 @@
if (PyLong_Check($input)) {
temp = PyLong_AsUnsignedLong($input);
}
+%#if IS_PY3 != 1
else if (PyInt_Check($input)) {
/* wish there was a PyInt_AsUnsignedLong but there isn't
the mask version doesn't do bounds checking for us.
@@ -389,6 +392,7 @@
problem goes away because PyInt is gone anyway. */
temp = PyInt_AsUnsignedLongMask($input);
}
+%#endif
else {
PyErr_SetString(PyExc_TypeError,
"expecting an integer for the buffer size");
@@ -418,7 +422,7 @@
#ifdef SWIGPYTHON
%typemap(argout) (char *buffer, apr_size_t *len) {
- %append_output(PyString_FromStringAndSize($1, *$2));
+ %append_output(PyBytes_FromStringAndSize($1, *$2));
free($1);
}
#endif
@@ -440,13 +444,24 @@
*/
#ifdef SWIGPYTHON
%typemap(in) (const char *data, apr_size_t *len) ($*2_type temp) {
- if (!PyString_Check($input)) {
+ Py_ssize_t length;
+ if (PyBytes_Check($input)) {
+ if (PyBytes_AsStringAndSize($input, (char **)&$1, &length) == -1) {
+ SWIG_fail;
+ }
+ }
+ else if (PyUnicode_Check($input)) {
+ $1 = (char *)PyStr_AsUTF8AndSize($input, &length);
+ if (PyErr_Occurred()) {
+ SWIG_fail;
+ }
+ }
+ else {
PyErr_SetString(PyExc_TypeError,
- "expecting a string for the buffer");
+ "expecting a bytes or str object for the buffer");
SWIG_fail;
}
- $1 = PyString_AS_STRING($input);
- temp = PyString_GET_SIZE($input);
+ temp = ($*2_type)length;
$2 = ($2_ltype)&temp;
}
#endif
@@ -499,8 +514,8 @@
SWIG_fail;
}
- if (PyString_Check($input)) {
- char *value = PyString_AS_STRING($input);
+ if (PyBytes_Check($input)) {
+ const char *value = PyBytes_AsString($input);
$1 = apr_pstrdup(_global_pool, value);
}
else if (PyLong_Check($input)) {
@@ -605,7 +620,7 @@
*/
#ifdef SWIGPYTHON
%typemap(in) FILE * {
- $1 = PyFile_AsFile($input);
+ $1 = svn_swig_py_as_file($input);
if ($1 == NULL) {
PyErr_SetString(PyExc_ValueError, "Must pass in a valid file object");
SWIG_fail;
@@ -710,11 +725,6 @@ core_set_current_pool (apr_pool_t *pool)
svn_swig_rb_config_section_enumerator)
#endif
-/* Allow None to be passed as config_dir argument */
-#ifdef SWIGPYTHON
-%typemap(in,parse="z") const char *config_dir "";
-#endif
-
/* -----------------------------------------------------------------------
thunk the various authentication prompt functions.
PERL NOTE: store the inputed SV in _global_callback for use in the
@@ -816,6 +826,7 @@ core_set_current_pool (apr_pool_t *pool)
%include svn_error_codes_h.swg
%include svn_time_h.swg
+%include svn_types_impl_h.swg
%include svn_types_h.swg
%include svn_pools_h.swg
%include svn_version_h.swg
@@ -827,6 +838,7 @@ core_set_current_pool (apr_pool_t *pool)
%include svn_props_h.swg
#pragma SWIG nowarn=+305
+%include svn_opt_impl_h.swg
%include svn_opt_h.swg
%include svn_cmdline_h.swg
%include svn_auth_h.swg
Modified: subversion/branches/multi-wc-format/subversion/bindings/swig/include/proxy.py
URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/bindings/swig/include/proxy.py?rev=1897034&r1=1897033&r2=1897034&view=diff
==============================================================================
--- subversion/branches/multi-wc-format/subversion/bindings/swig/include/proxy.py (original)
+++ subversion/branches/multi-wc-format/subversion/bindings/swig/include/proxy.py Fri Jan 14 14:01:45 2022
@@ -12,23 +12,57 @@
if "_is_valid" in self.__dict__:
assert self.__dict__["_is_valid"](), "Variable has already been deleted"
- def __getattr__(self, name):
- """Get an attribute from this object"""
- self.assert_valid()
-
- value = _swig_getattr(self, self.__class__, name)
-
- # If we got back a different object than we have, we need to copy all our
- # metadata into it, so that it looks identical
- members = self.__dict__.get("_members")
- if members is not None:
- _copy_metadata_deep(value, members.get(name))
+ def _retrieve_swig_value(self, name, value):
+ # If we got back a different object than we have cached, we need to copy
+ # all our metadata into it, so that it looks identical to the one
+ # originally set.
+ members = self.__dict__.get('_members')
+ if members is not None and name in members:
+ _copy_metadata_deep(value, members[name])
# Verify that the new object is good
_assert_valid_deep(value)
return value
+ # Attribute access must be intercepted to ensure that objects coming from
+ # read attribute access match those that are set with write attribute access.
+ # Specifically the metadata, such as the associated apr_pool object, should
+ # match the originally assigned object.
+ #
+ # For classic classes it is enough to use __getattr__ to intercept swig
+ # derived attributes. However, with new style classes SWIG makes use of
+ # descriptors which mean that __getattr__ is never called. Therefore,
+ # __getattribute__ must be used for the interception.
+
+ if _newclass:
+ def __getattribute__(self, name):
+ """Manage access to all attributes of this object."""
+
+ # Start by mimicking __getattr__ behavior: immediately return __dict__ or
+ # items directly present in __dict__
+ mydict = object.__getattribute__(self, '__dict__')
+
+ if name == "__dict__":
+ return mydict
+
+ if name in mydict:
+ return mydict[name]
+
+ object.__getattribute__(self, 'assert_valid')()
+
+ value = _get_instance_attr(self, name)
+ fn = object.__getattribute__(self, '_retrieve_swig_value')
+ return fn(name, value)
+ else:
+ def __getattr__(self, name):
+ """Get an attribute from this object"""
+ self.assert_valid()
+
+ value = _swig_getattr(self, self.__class__, name)
+
+ return self._retrieve_swig_value(name, value)
+
def __setattr__(self, name, value):
"""Set an attribute on this object"""
self.assert_valid()
@@ -38,4 +72,4 @@
# SWIG-land
self.__dict__.setdefault("_members",{})[name] = value
- return _swig_setattr(self, self.__class__, name, value)
+ return _set_instance_attr(self, name, value)
Modified: subversion/branches/multi-wc-format/subversion/bindings/swig/include/proxy.swg
URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/bindings/swig/include/proxy.swg?rev=1897034&r1=1897033&r2=1897034&view=diff
==============================================================================
--- subversion/branches/multi-wc-format/subversion/bindings/swig/include/proxy.swg (original)
+++ subversion/branches/multi-wc-format/subversion/bindings/swig/include/proxy.swg Fri Jan 14 14:01:45 2022
@@ -36,8 +36,8 @@
if value is None or old_value is None or value is old_value: return
if isinstance(value, dict):
- for k, v in value.iteritems():
- _copy_metadata_deep(v, old_value[k])
+ for k in value:
+ _copy_metadata_deep(value[k], old_value[k])
elif isinstance(value, list):
for v, old_v in zip(value, old_value):
_copy_metadata_deep(v, old_v)
@@ -50,15 +50,72 @@
def _assert_valid_deep(value):
"""Assert value's validity, recursively traversing lists and dicts."""
if isinstance(value, dict):
- for v in value.itervalues():
- _assert_valid_deep(v)
+ for k in value:
+ _assert_valid_deep(value[k])
elif isinstance(value, list):
for v in value:
_assert_valid_deep(v)
- else:
- if hasattr(value, "assert_valid"):
- value.assert_valid()
+ # Ensure that the passed in value isn't a type, which could have an
+ # assert_valid attribute, but it can not be called without an instance.
+ elif type(value) != type:
+ try:
+ fn = value.assert_valid
+ except AttributeError:
+ pass
+ else:
+ fn()
+
+%}
+#if defined(SWIGPYTHON_PY3)
+#if SWIG_VERSION >= 0x040000
+%pythoncode %{
+ # -classic and -modern options have been dropped and this variable
+ # is not generated since SWIG 4
+ _newclass = 1
+ _get_instance_attr = object.__getattribute__
+ _set_instance_attr = _swig_setattr_nondynamic_instance_variable(object.__setattr__)
+
+%}
+#else
+%pythoncode %{
+ # SWIG classes generated with -modern do not define this variable
+ try:
+ _newclass
+ except NameError:
+ _newclass = 1
+ else:
+ raise RuntimeError("Require -modern option, but _newclass is defined")
+
+ _get_instance_attr = object.__getattribute__
+ _set_instance_attr = _swig_setattr_nondynamic_method(object.__setattr__)
+
+%}
+#endif
+#else
+%pythoncode %{
+ # SWIG classes generated with -classic do not define this variable,
+ # so set it to 0 when it doesn't exist
+ try:
+ _newclass
+ except NameError:
+ _newclass = 0
+
+ if _newclass:
+ def _get_instance_attr(self, name):
+ try:
+ return object.__getattribute__(self, name)
+ except AttributeError:
+ return _swig_getattr(self, object.__getattribute__(self, '__class__'),
+ name)
+ else:
+ def _get_instance_attr(self, name):
+ return _swig_getattr(self, self.__class__, name)
+
+ def _set_instance_attr(self, name, value):
+ return _swig_setattr(self, self.__class__, name, value)
+
%}
+#endif
/* Default code for all wrapped proxy classes in Python.
* Inline the code from a separate file to avoid issues with
Modified: subversion/branches/multi-wc-format/subversion/bindings/swig/include/proxy_apr.swg
URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/bindings/swig/include/proxy_apr.swg?rev=1897034&r1=1897033&r2=1897034&view=diff
==============================================================================
--- subversion/branches/multi-wc-format/subversion/bindings/swig/include/proxy_apr.swg (original)
+++ subversion/branches/multi-wc-format/subversion/bindings/swig/include/proxy_apr.swg Fri Jan 14 14:01:45 2022
@@ -84,6 +84,7 @@ class GenericSWIGWrapper:
def set_parent_pool(self, pool):
"""Set the parent pool of this object"""
self._parent_pool = pool
+ self._is_valid = weakref.ref(pool._is_valid)
def valid(self):
"""Is this object valid?"""
@@ -99,8 +100,14 @@ class GenericSWIGWrapper:
return self.this
def _mark_weakpool_invalid(weakpool):
- if weakpool and weakpool() and hasattr(weakpool(), "_is_valid"):
- del weakpool()._is_valid
+ if weakpool:
+ pool = weakpool()
+ if pool:
+ try:
+ del pool._is_valid
+ except AttributeError:
+ pass
+
%}
@@ -133,7 +140,17 @@ struct apr_pool_t {
def valid(self):
"""Check whether this memory pool and its parents
are still valid"""
- return hasattr(self,"_is_valid")
+ try:
+ self._is_valid
+ except AttributeError:
+ return False
+ # We must check whether the parent pool is valid even if
+ # the pool is valid because weakref's callback is not
+ # invoked when it is finalized by cyclic garbage collector
+ if self._parent_pool:
+ return self._parent_pool.valid()
+ else:
+ return True
def assert_valid(self):
"""Assert that this memory_pool is still valid."""
@@ -164,10 +181,15 @@ struct apr_pool_t {
self._svn_swig_py_clear_application_pool()
# Mark self as invalid
- if hasattr(self, "_parent_pool"):
+ try:
del self._parent_pool
- if hasattr(self, "_is_valid"):
+ except AttributeError:
+ pass
+
+ try:
del self._is_valid
+ except AttributeError:
+ pass
def __del__(self):
"""Automatically destroy memory pools, if necessary"""
@@ -200,8 +222,11 @@ struct apr_pool_t {
def _wrap(self, obj):
"""Mark a SWIG object as owned by this pool"""
self.assert_valid()
- if hasattr(obj, "set_parent_pool"):
- obj.set_parent_pool(self)
+
+ fn = getattr(obj, 'set_parent_pool', None)
+
+ if fn is not None:
+ fn(self)
return obj
elif obj is None:
return None
Modified: subversion/branches/multi-wc-format/subversion/bindings/swig/include/svn_containers.swg
URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/bindings/swig/include/svn_containers.swg?rev=1897034&r1=1897033&r2=1897034&view=diff
==============================================================================
--- subversion/branches/multi-wc-format/subversion/bindings/swig/include/svn_containers.swg (original)
+++ subversion/branches/multi-wc-format/subversion/bindings/swig/include/svn_containers.swg Fri Jan 14 14:01:45 2022
@@ -527,7 +527,10 @@
apr_array_header_t **logfiles,
apr_array_header_t **names_p,
apr_array_header_t **targets_p,
- apr_array_header_t **args_p
+ apr_array_header_t **args_p,
+ apr_array_header_t **props_conflicted,
+ apr_array_header_t **possible_moved_to_repos_relpaths,
+ apr_array_header_t **possible_moved_to_abspaths
};
/* -----------------------------------------------------------------------
@@ -577,6 +580,40 @@
}
#endif
+/* -----------------------------------------------------------------------
+ apr_array_header_t **options
+ For svn_client_conflict_option_t
+*/
+
+#ifdef SWIGPYTHON
+%typemap(argout) apr_array_header_t **options {
+ %append_output
+ (svn_swig_py_pointerlist_to_list(*$1,
+ $descriptor(svn_client_conflict_option_t *),
+ _global_py_pool));
+ if (PyErr_Occurred()) {
+ SWIG_fail;
+ }
+}
+#endif
+
+/* -----------------------------------------------------------------------
+ apr_array_header_t **versions_p
+ For svn_client__shelf_get_all_versions
+*/
+
+#ifdef SWIGPYTHON
+%typemap(argout) apr_array_header_t **versions_p {
+ %append_output
+ (svn_swig_py_pointerlist_to_list(*$1,
+ $descriptor(svn_client__shelf_version_t *),
+ _global_py_pool));
+ if (PyErr_Occurred()) {
+ SWIG_fail;
+ }
+}
+#endif
+
/* =======================================================================
%typemap(in) apr_array_header_t *
*/
Modified: subversion/branches/multi-wc-format/subversion/bindings/swig/include/svn_global.swg
URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/bindings/swig/include/svn_global.swg?rev=1897034&r1=1897033&r2=1897034&view=diff
==============================================================================
--- subversion/branches/multi-wc-format/subversion/bindings/swig/include/svn_global.swg (original)
+++ subversion/branches/multi-wc-format/subversion/bindings/swig/include/svn_global.swg Fri Jan 14 14:01:45 2022
@@ -31,6 +31,17 @@
#define SVN_DEPRECATED
#endif
+#ifdef SWIGPYTHON
+%begin %{
+#define SWIG_PYTHON_STRICT_BYTE_CHAR
+#if defined(_MSC_VER)
+/* Prevent "non-constant aggregate initializer" errors from Python.h in
+ * Python 3.9 */
+# pragma warning(default : 4204)
+#endif
+%}
+#endif
+
%include typemaps.i
%include constraints.i
%include exception.i
@@ -54,6 +65,7 @@
#ifdef SWIGPYTHON
%{
#include "swigutil_py.h"
+#include "swigutil_py3c.h"
%}
#endif
#ifdef SWIGPERL
@@ -135,9 +147,8 @@ static PyObject * _global_py_pool = NULL
/* Python format specifiers. Use Python instead of SWIG to parse
these basic types, because Python reports better error messages
(with correct argument numbers). */
-%typemap (in, parse="s")
- char *, char const *, char * const, char const * const "";
%typemap (in, parse="c") char "";
+
%typemap (in, fragment=SWIG_As_frag(long)) long
{
$1 = ($1_ltype)SWIG_As(long)($input);
@@ -236,3 +247,40 @@ static VALUE *_global_vresult_address =
/* Now, include the main Subversion typemap library. */
%include svn_types.swg
%include proxy.swg
+
+
+#ifdef SWIGPYTHON
+/* Since Python 3.8+ on Windows, DLL dependencies when loading *.pyd file
+ * searches only the system paths, the directory containing the *.pyd file and
+ * the directories added with os.add_dll_directory().
+ * See also https://bugs.python.org/issue36085.
+ */
+%define SVN_PYTHON_MODULEIMPORT
+"
+def _dll_paths():
+ import os
+ if hasattr(os, 'add_dll_directory'): # Python 3.8+ on Windows
+ cookies = []
+ for path in os.environ.get('PATH', '').split(os.pathsep):
+ if path and os.path.isabs(path):
+ try:
+ cookie = os.add_dll_directory(path)
+ except OSError:
+ continue
+ else:
+ cookies.append(cookie)
+ return cookies
+ else:
+ return ()
+
+_dll_paths = _dll_paths()
+try:
+ from . import $module
+finally:
+ _dll_path = None
+ for _dll_path in _dll_paths:
+ _dll_path.close()
+ del _dll_paths, _dll_path
+"
+%enddef
+#endif
Modified: subversion/branches/multi-wc-format/subversion/bindings/swig/include/svn_string.swg
URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/bindings/swig/include/svn_string.swg?rev=1897034&r1=1897033&r2=1897034&view=diff
==============================================================================
--- subversion/branches/multi-wc-format/subversion/bindings/swig/include/svn_string.swg (original)
+++ subversion/branches/multi-wc-format/subversion/bindings/swig/include/svn_string.swg Fri Jan 14 14:01:45 2022
@@ -36,9 +36,8 @@ typedef struct svn_string_t svn_string_t
if (*$1 == NULL) {
Py_INCREF(Py_None);
s = Py_None;
- }
- else {
- s = PyString_FromStringAndSize((*$1)->data, (*$1)->len);
+ } else {
+ s = PyBytes_FromStringAndSize((*$1)->data, (*$1)->len);
if (s == NULL)
SWIG_fail;
}
@@ -75,14 +74,33 @@ typedef struct svn_string_t svn_string_t
#ifdef SWIGPYTHON
%typemap(in) svn_stringbuf_t * {
- if (!PyString_Check($input)) {
- PyErr_SetString(PyExc_TypeError, "not a string");
- SWIG_fail;
- }
- $1 = svn_stringbuf_ncreate(PyString_AS_STRING($input),
- PyString_GET_SIZE($input),
- /* ### gah... what pool to use? */
- _global_pool);
+ if ($input == Py_None) {
+ $1 = NULL;
+ }
+ else {
+ Py_ssize_t strBufLen;
+ char *strBufChar;
+ if (PyBytes_Check($input)) {
+ if (-1 == PyBytes_AsStringAndSize($input, &strBufChar,
+ &strBufLen)) {
+ SWIG_fail;
+ }
+ }
+ else if (PyUnicode_Check($input)) {
+ strBufChar = (char *)PyStr_AsUTF8AndSize($input, &strBufLen);
+ if (PyErr_Occurred()) {
+ SWIG_fail;
+ }
+ }
+ else {
+ PyErr_SetString(PyExc_TypeError,
+ "not a bytes, str or None object");
+ SWIG_fail;
+ }
+ $1 = svn_stringbuf_ncreate((const char *)strBufChar, strBufLen,
+ /* ### gah... what pool to use? */
+ _global_pool);
+ }
}
#endif
@@ -139,7 +157,7 @@ typedef struct svn_string_t svn_string_t
#ifdef SWIGPYTHON
%typemap(out) svn_stringbuf_t * {
- $result = PyString_FromStringAndSize($1->data, $1->len);
+ $result = PyBytes_FromStringAndSize($1->data, (Py_ssize_t)($1->len));
}
#endif
@@ -171,15 +189,29 @@ typedef struct svn_string_t svn_string_t
/* const svn_string_t * is always an input parameter */
#ifdef SWIGPYTHON
%typemap(in) const svn_string_t * (svn_string_t value) {
- if ($input == Py_None)
+ if ($input == Py_None) {
$1 = NULL;
+ }
else {
- if (!PyString_Check($input)) {
- PyErr_SetString(PyExc_TypeError, "not a string");
+ Py_ssize_t pyStrLen;
+ if (PyBytes_Check($input)) {
+ if (PyBytes_AsStringAndSize($input, (char **)&(value.data),
+ &pyStrLen) == -1) {
+ SWIG_fail;
+ }
+ }
+ else if (PyUnicode_Check($input)) {
+ value.data = PyStr_AsUTF8AndSize($input, &pyStrLen);
+ if ((value.data == NULL) || PyErr_Occurred()) {
+ SWIG_fail;
+ }
+ }
+ else {
+ PyErr_SetString(PyExc_TypeError,
+ "not a bytes, str, or None object");
SWIG_fail;
}
- value.data = PyString_AS_STRING($input);
- value.len = PyString_GET_SIZE($input);
+ value.len = pyStrLen;
$1 = &value;
}
}
@@ -223,7 +255,7 @@ typedef struct svn_string_t svn_string_t
#ifdef SWIGPYTHON
%typemap(out) svn_string_t * {
- $result = PyString_FromStringAndSize($1->data, $1->len);
+ $result = PyBytes_FromStringAndSize($1->data, $1->len);
}
#endif
#ifdef SWIGPERL
@@ -242,6 +274,26 @@ typedef struct svn_string_t svn_string_t
}
#endif
+ /* -----------------------------------------------------------------------
+ Type: char * (input)
+*/
+#ifdef SWIGPYTHON
+%typemap (in) IN_STRING
+{
+ $1 = svn_swig_py_string_to_cstring($input, FALSE, "$symname", "$1_name");
+ if (PyErr_Occurred()) SWIG_fail;
+}
+
+%typemap (freearg) IN_STRING "";
+
+%apply IN_STRING {
+ const char *,
+ char *,
+ char const *,
+ char * const,
+ char const * const
+};
+#endif
/* -----------------------------------------------------------------------
define a way to return a 'const char *'
*/
@@ -253,7 +305,7 @@ typedef struct svn_string_t svn_string_t
s = Py_None;
}
else {
- s = PyString_FromString(*$1);
+ s = PyBytes_FromString(*$1);
if (s == NULL)
SWIG_fail;
}
@@ -283,4 +335,8 @@ typedef struct svn_string_t svn_string_t
#endif
/* svn_wc_get_ancestry() lacks a 'const' */
-%apply const char **OUTPUT { const char **, char **url };
+%apply const char **OUTPUT {
+ const char **,
+ char **url,
+ char **log_message
+};
Modified: subversion/branches/multi-wc-format/subversion/bindings/swig/include/svn_swigcompat.swg
URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/bindings/swig/include/svn_swigcompat.swg?rev=1897034&r1=1897033&r2=1897034&view=diff
==============================================================================
--- subversion/branches/multi-wc-format/subversion/bindings/swig/include/svn_swigcompat.swg (original)
+++ subversion/branches/multi-wc-format/subversion/bindings/swig/include/svn_swigcompat.swg Fri Jan 14 14:01:45 2022
@@ -45,7 +45,7 @@
#if SWIG_VERSION <= 0x010327
#ifdef SWIGPYTHON
%define %set_constant(name, value)
-PyDict_SetItemString(d, name, value);
+PyDict_SetItem(d, PyBytes_FromString(name), value);
%enddef
#endif
#endif
Modified: subversion/branches/multi-wc-format/subversion/bindings/swig/include/svn_types.swg
URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/bindings/swig/include/svn_types.swg?rev=1897034&r1=1897033&r2=1897034&view=diff
==============================================================================
--- subversion/branches/multi-wc-format/subversion/bindings/swig/include/svn_types.swg (original)
+++ subversion/branches/multi-wc-format/subversion/bindings/swig/include/svn_types.swg Fri Jan 14 14:01:45 2022
@@ -93,6 +93,7 @@
%apply SWIGTYPE **OUTPARAM {
/* apr */
apr_file_t **,
+ apr_hash_t **,
/* svn_types.h */
svn_commit_info_t **,
svn_dirent_t **,
@@ -116,10 +117,16 @@
void **credentials,
void **iter_baton,
void **token,
+ /* svn_checksum */
+ svn_checksum_t **,
/* svn_client */
svn_client_commit_info_t **,
+ svn_client_conflict_t **,
+ svn_client_conflict_option_t **,
svn_client_ctx_t **,
const svn_client_commit_item3_t **,
+ svn_client__shelf_t **,
+ svn_client__shelf_version_t **,
/* svn_delta */
const svn_delta_editor_t **,
svn_txdelta_stream_t **,
@@ -129,6 +136,7 @@
svn_txdelta_window_handler_t *,
#endif
void **handler_baton,
+ void **handler2_baton,
void **root_baton,
void **child_baton,
void **file_baton,
@@ -142,6 +150,9 @@
svn_fs_root_t **,
svn_fs_txn_t **,
void **contents_baton_p,
+ /* svn_io */
+ svn_io_dirent2_t **,
+ svn_stream_mark_t **,
/* svn_ra */
svn_ra_callbacks2_t **,
svn_ra_plugin_t **,
@@ -335,7 +346,11 @@ svn_ ## TYPE ## _swig_rb_closed(VALUE se
Create a typemap for specifying string args that may be NULL.
*/
#ifdef SWIGPYTHON
-%typemap(in, parse="z") const char *MAY_BE_NULL "";
+%typemap(in) const char *MAY_BE_NULL
+{
+ $1 = svn_swig_py_string_to_cstring($input, TRUE, "$symname", "$1_name");
+ if (PyErr_Occurred()) SWIG_fail;
+}
#endif
#ifdef SWIGPERL
@@ -423,6 +438,55 @@ svn_ ## TYPE ## _swig_rb_closed(VALUE se
Py_INCREF(Py_None);
$result = Py_None;
}
+
+%typemap(out) svn_error_t * SVN_ERR_WITH_ATTRS (apr_status_t apr_err,
+ PyObject *exc_class,
+ PyObject *exc_ob) {
+ apr_err = 0;
+ exc_class = exc_ob = NULL;
+ if ($1 != NULL)
+ {
+ apr_err = $1->apr_err;
+ if (apr_err != SVN_ERR_SWIG_PY_EXCEPTION_SET)
+ {
+ svn_swig_py_build_svn_exception(&exc_class, &exc_ob, $1);
+ if (exc_ob == NULL)
+ {
+ /* We couldn't get an exception instance. */
+ if (exc_class != NULL)
+ {
+ /* Raise an exception without instance ... */
+ PyErr_SetNone(exc_class);
+ Py_DECREF(exc_class);
+ }
+ SWIG_fail;
+ }
+ /* We have an exeception instance, but we don't raise it until
+ typemap(ret) block after typemap(argout) blocks. */
+ }
+ else
+ {
+ svn_error_clear($1);
+ SWIG_fail;
+ }
+ }
+ else
+ {
+ Py_INCREF(Py_None);
+ $result = Py_None;
+ }
+}
+
+%typemap(ret) svn_error_t * SVN_ERR_WITH_ATTRS {
+ if (exc_ob != NULL)
+ {
+ PyErr_SetObject(exc_class, exc_ob);
+ Py_DECREF(exc_class);
+ Py_DECREF(exc_ob);
+ Py_XDECREF($result);
+ SWIG_fail;
+ }
+}
#endif
#ifdef SWIGPERL
@@ -464,12 +528,23 @@ svn_ ## TYPE ## _swig_rb_closed(VALUE se
*/
#ifdef SWIGPYTHON
%typemap(in) (const char *PTR, apr_size_t LEN) {
- if (!PyString_Check($input)) {
- PyErr_SetString(PyExc_TypeError, "expecting a string");
+ Py_ssize_t pyStrLen;
+ if (PyBytes_Check($input)) {
+ if (PyBytes_AsStringAndSize($input, (char **)&$1, &pyStrLen) == -1) {
+ SWIG_fail;
+ }
+ }
+ else if (PyUnicode_Check($input)) {
+ $1 = (char *)PyStr_AsUTF8AndSize($input, &pyStrLen);
+ if (PyErr_Occurred()) {
+ SWIG_fail;
+ }
+ }
+ else {
+ PyErr_SetString(PyExc_TypeError, "expecting a bytes or str");
SWIG_fail;
}
- $1 = PyString_AS_STRING($input);
- $2 = PyString_GET_SIZE($input);
+ $2 = pyStrLen;
}
#endif
@@ -941,7 +1016,15 @@ svn_ ## TYPE ## _swig_rb_closed(VALUE se
#ifdef SWIGPYTHON
%typemap(in) svn_stream_t *WRAPPED_STREAM {
- $1 = svn_swig_py_make_stream ($input, _global_pool);
+ if ($input == Py_None) {
+ $1 = NULL;
+ }
+ else {
+ $1 = svn_swig_py_make_stream ($input, _global_pool);
+ if ($1 == NULL) {
+ SWIG_fail;
+ }
+ }
}
#endif
@@ -1094,7 +1177,7 @@ svn_ ## TYPE ## _swig_rb_closed(VALUE se
#ifdef SWIGPYTHON
%typemap(argout) unsigned char digest[ANY]
{
- %append_output(PyString_FromStringAndSize((char *)$1, APR_MD5_DIGESTSIZE));
+ %append_output(PyBytes_FromStringAndSize((const char *)$1, APR_MD5_DIGESTSIZE));
}
#endif
@@ -1167,7 +1250,7 @@ svn_ ## TYPE ## _swig_rb_closed(VALUE se
if ($input == Py_None) {
$1 = NULL;
} else {
- $1 = (unsigned char *) PyString_AsString($input);
+ $1 = (unsigned char *) PyBytes_AsString($input);
if ($1 == NULL) SWIG_fail;
}
}
Modified: subversion/branches/multi-wc-format/subversion/bindings/swig/perl/libsvn_swig_perl/swigutil_pl.c
URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/bindings/swig/perl/libsvn_swig_perl/swigutil_pl.c?rev=1897034&r1=1897033&r2=1897034&view=diff
==============================================================================
--- subversion/branches/multi-wc-format/subversion/bindings/swig/perl/libsvn_swig_perl/swigutil_pl.c (original)
+++ subversion/branches/multi-wc-format/subversion/bindings/swig/perl/libsvn_swig_perl/swigutil_pl.c Fri Jan 14 14:01:45 2022
@@ -284,7 +284,7 @@ apr_array_header_t *svn_swig_pl_objs_to_
/* Convert a single revision range or an array of revisions ranges
* Note: We can't simply use svn_swig_pl_to_array() as is, since
- * it immediatley checks whether source is an array reference and then
+ * it immediately checks whether source is an array reference and then
* proceeds to treat this as the "array of ..." case. But a revision range
* may be specified as a (two-element) array. Hence we first try to
* convert source as a single revision range. Failing that and if it's
@@ -591,7 +591,7 @@ svn_error_t *svn_swig_pl_callback_thunk(
case 'L': /* apr_int64_t */
/* Pass into perl as a string because some implementations may
* not be able to handle a 64-bit int. If it's too long to
- * fit in Perl's interal IV size then perl will only make
+ * fit in Perl's internal IV size then perl will only make
* it available as a string. If not then perl will convert
* it to an IV for us. So this handles the problem gracefully */
c = malloc(30);
@@ -634,7 +634,7 @@ svn_error_t *svn_swig_pl_callback_thunk(
count = call_method(func, call_flags );
break;
default:
- croak("unkonwn calling type");
+ croak("unknown calling type");
break;
}
SPAGAIN ;
Modified: subversion/branches/multi-wc-format/subversion/bindings/swig/perl/native/Client.pm
URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/bindings/swig/perl/native/Client.pm?rev=1897034&r1=1897033&r2=1897034&view=diff
==============================================================================
--- subversion/branches/multi-wc-format/subversion/bindings/swig/perl/native/Client.pm (original)
+++ subversion/branches/multi-wc-format/subversion/bindings/swig/perl/native/Client.pm Fri Jan 14 14:01:45 2022
@@ -1029,7 +1029,7 @@ is updated.
If $ignore_externals is set, don't process externals definitions as part of
this operation.
-If $depth is $SVN::Depth::infinity, update fully recursivelly. Else if it is
+If $depth is $SVN::Depth::infinity, update fully recursively. Else if it is
$SVN::Depth::immediates or $SVN::Depth::files, update each target and its file
entries, but not its subdirectories. Else if $SVN::Depth::empty, update
exactly each target, nonrecursively (essentially, update the target's
Modified: subversion/branches/multi-wc-format/subversion/bindings/swig/perl/native/Core.pm
URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/bindings/swig/perl/native/Core.pm?rev=1897034&r1=1897033&r2=1897034&view=diff
==============================================================================
--- subversion/branches/multi-wc-format/subversion/bindings/swig/perl/native/Core.pm (original)
+++ subversion/branches/multi-wc-format/subversion/bindings/swig/perl/native/Core.pm Fri Jan 14 14:01:45 2022
@@ -784,7 +784,7 @@ $SVN::Depth::infinity.
Exclude (i.e., don't descend into) directory D.
-Note: In Subversion 1.5, $SVN::Depth::exclude is B<not> supported anyhwere in
+Note: In Subversion 1.5, $SVN::Depth::exclude is B<not> supported anywhere in
the client-side (Wc/Client/etc) code; it is only supported as an argument to
set_path functions in the Ra and Repos reporters. (This will enable future
versions of Subversion to run updates, etc, against 1.5 servers with proper
Propchange: subversion/branches/multi-wc-format/subversion/bindings/swig/python/
------------------------------------------------------------------------------
--- svn:ignore (original)
+++ svn:ignore Fri Jan 14 14:01:45 2022
@@ -1,5 +1,6 @@
*.pyc
*.py
+__pycache__
*.c
*.la
*.lo