[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

[PATCH] SWIG bindings refactoring (esp. python)

From: Philipp von Weitershausen <philipp_at_weitershausen.de>
Date: 2003-05-13 23:36:14 CEST

My goal is to make the SWIG bindings to python as easy to use and as
pythonic as possible. The following patch is a result of the previous
discussion with cmpilato and Greg Stein ("eliminate -noproxy flat to SWIG").

When this patch is applied, all python code should still run unless it
uses accessor functions. Instead of using accessor functions, you can
now simply acquire the attribute of your struct wrapping object to
acquire a struct member (e.g. ctx.auth_baton instead of
svn_client_ctx_t_auth_baton_get(ctx).).

Log Message:

* Makefile.in
   subversion/bindings/swig/*.i
   - Do not call SWIG with the -noproxy flag: build shadow classes
     instead of accessor functions for structs.
   - The pure SWIG bindings are available as the 'libsvn' package while
     the 'svn' package provides extra auxiliary classes and functions
     for the python programmer.

* subversion/bindings/swig/python/__init__.py
   Added file to repository. It makes 'libsvn' a package.

* build.conf
   subversion/bindings/swig/util.i
   subversion/bindings/swig/core.i
   Renamed the 'util' module to 'core' since it does not provide simple
   utilities but core funtionality. Importing 'util' still works for
   compatability reasons, but be aware that this is likely to go away in
   the future.

* tools/*.py
   Make use of the changes above:
   - Use 'core' module instead of 'util'. 'util' is depecreated.
   - Use attributes instead of accessor functions.

Index: Makefile.in
===================================================================
--- Makefile.in (revision 5921)
+++ Makefile.in (working copy)
@@ -71,7 +71,8 @@
 swig_java_libdir = @libdir@
 
 ### these possibly need further discussion
-swig_pydir = @libdir@/svn-python/svn
+swig_pydir = @libdir@/svn-python/libsvn
+swig_pydir_extra = @libdir@/svn-python/svn
 swig_javadir = @libdir@/svn-java
 
 ### should search for these...
@@ -134,8 +135,8 @@
 
 # these commands run SWIG to generate wrapper source files (*.c)
 ### should we protect against swig not being available?
-RUN_SWIG_PY = $(SWIG) -c -python -noproxy $(SWIG_INCLUDES) $(SWIG_PY_INCLUDES) -o $@
-RUN_SWIG_JAVA = cd ${SWIG_SRC_DIR}/java/org/tigris/subversion/swig && $(SWIG) -c -java -noproxy -package 'org.tigris.subversion.swig' $(SWIG_INCLUDES) -o ${abs_builddir}/$@
+RUN_SWIG_PY = $(SWIG) -c -python $(SWIG_INCLUDES) $(SWIG_PY_INCLUDES) -o $@
+RUN_SWIG_JAVA = cd ${SWIG_SRC_DIR}/java/org/tigris/subversion/swig && $(SWIG) -c -java -package 'org.tigris.subversion.swig' $(SWIG_INCLUDES) -o ${abs_builddir}/$@
 
 # Compilation of SWIG-generated C source code
 COMPILE_PY_WRAPPER = $(LIBTOOL) $(LTFLAGS) --mode=compile $(SWIG_PY_COMPILE) $(SWIG_INCLUDES) $(SWIG_PY_INCLUDES) -prefer-pic -c -o $@
@@ -165,7 +166,9 @@
 INSTALL_SWIG_JAVA_LIB = $(INSTALL_LIB)
 
 # additional installation rules for the SWIG wrappers
-INSTALL_EXTRA_SWIG_PY=$(top_srcdir)/build/copy-swig-py.sh "$(PYTHON)" "$(INSTALL_DATA)" "${SWIG_SRC_DIR}/python/svn" "$(DESTDIR)$(swig_pydir)"
+INSTALL_EXTRA_SWIG_PY=\
+ $(top_srcdir)/build/copy-swig-py.sh "$(PYTHON)" "$(INSTALL_DATA)" "${SWIG_SRC_DIR}/python" "$(DESTDIR)$(swig_pydir)" ; \
+ $(top_srcdir)/build/copy-swig-py.sh "$(PYTHON)" "$(INSTALL_DATA)" "${SWIG_SRC_DIR}/python/svn" "$(DESTDIR)$(swig_pydir_extra)"
 INSTALL_EXTRA_SWIG_JAVA=:
 
 APXS = @APXS@
Index: build.conf
===================================================================
--- build.conf (revision 5921)
+++ build.conf (working copy)
@@ -246,10 +246,10 @@
 sources = svn_wc.i
 libs = libsvn_wc
 
-[swig_util]
+[swig_core]
 type = swig
 path = subversion/bindings/swig
-sources = util.i
+sources = core.i
 libs = libsvn_subr $(SVN_APR_LIBS)
 
 # SWIG utility library for Python modules
Index: subversion/bindings/swig/core.i
===================================================================
--- subversion/bindings/swig/core.i (working copy)
+++ subversion/bindings/swig/core.i (working copy)
@@ -0,0 +1,256 @@
+/*
+ * core.i : SWIG interface file for various core SVN and APR components
+ *
+ * ====================================================================
+ * Copyright (c) 2000-2003 CollabNet. All rights reserved.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://subversion.tigris.org/license-1.html.
+ * If newer versions of this license are posted there, you may use a
+ * newer version instead, at your option.
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals. For exact contribution history, see the revision
+ * history and logs, available at http://subversion.tigris.org/.
+ * ====================================================================
+ */
+
+%module core
+
+%include typemaps.i
+
+%{
+#include "svn_opt.h"
+%}
+
+/* -----------------------------------------------------------------------
+ include svn_types.h early. other .i files will import svn_types.i which
+ then includes svn_types.h, making further includes get skipped. we want
+ to actually generate wrappers, so manage svn_types.h right here.
+*/
+%ignore svn_error;
+
+/* ### for now, let's not try to handle these structures. swig complains
+ ### about setting the 'const char *' inside the struct might leak mem */
+%ignore svn_log_changed_path_t;
+
+/* ### We also get complaints about possible memory leakage for svn_dirent,
+ ### but we can live with it for now. */
+/* %ignore svn_dirent; */
+
+/* ### for now, let's ignore this thing. */
+%ignore svn_prop_t;
+
+%include svn_types.h
+
+
+/* -----------------------------------------------------------------------
+ moving along...
+*/
+%import apr.i
+%import svn_types.i
+%import svn_string.i
+
+/* -----------------------------------------------------------------------
+ completely ignore a number of functions. the presumption is that the
+ scripting language already has facilities for these things (or they
+ are relatively trivial).
+*/
+%ignore svn_io_check_path;
+%ignore svn_io_check_resolved_path;
+%ignore svn_io_copy_file;
+%ignore svn_io_copy_dir_recursively;
+%ignore svn_io_append_file;
+%ignore svn_io_read_length_line;
+%ignore svn_io_file_affected_time;
+%ignore svn_io_fd_from_file;
+%ignore svn_io_get_dirents;
+%ignore svn_io_run_cmd;
+%ignore svn_io_remove_file;
+%ignore svn_io_remove_dir;
+%ignore svn_io_make_dir_recursively;
+%ignore svn_io_set_file_read_only;
+%ignore svn_io_set_file_read_write;
+%ignore svn_io_set_file_executable;
+%ignore svn_io_filesizes_different_p;
+%ignore svn_io_file_printf;
+
+%ignore apr_check_dir_empty;
+
+/* scripts can do the printf, then write to a stream. we can't really
+ handle the variadic, so ignore it. */
+%ignore svn_stream_printf;
+
+
+/* -----------------------------------------------------------------------
+ these types (as 'type **') will always be an OUT param
+*/
+%apply SWIGTYPE **OUTPARAM {
+ svn_auth_baton_t **
+}
+
+/* -----------------------------------------------------------------------
+ apr_size_t * is always an IN/OUT parameter in svn_io.h
+*/
+%apply apr_size_t *INOUT { apr_size_t * };
+
+/* -----------------------------------------------------------------------
+ handle the MIME type return value of svn_io_detect_mimetype()
+*/
+%apply const char **OUTPUT { const char ** };
+
+/* -----------------------------------------------------------------------
+ handle the providers array as an input type.
+*/
+%typemap(python, in) apr_array_header_t *providers {
+ svn_auth_provider_object_t *provider;
+ int targlen;
+ if (!PySequence_Check($input)) {
+ PyErr_SetString(PyExc_TypeError, "not a sequence");
+ return NULL;
+ }
+ targlen = PySequence_Length($input);
+ $1 = apr_array_make(_global_pool, targlen, sizeof(provider));
+ ($1)->nelts = targlen;
+ while (targlen--) {
+ SWIG_ConvertPtr(PySequence_GetItem($input, targlen),
+ (void **)&provider,
+ $descriptor(svn_auth_provider_object_t *),
+ SWIG_POINTER_EXCEPTION | 0);
+ APR_ARRAY_IDX($1, targlen, svn_auth_provider_object_t *) = provider;
+ }
+}
+
+/* -----------------------------------------------------------------------
+ fix up the svn_stream_read() ptr/len arguments
+*/
+%typemap(python, in) (char *buffer, apr_size_t *len) ($*2_type temp) {
+ if (!PyInt_Check($input)) {
+ PyErr_SetString(PyExc_TypeError,
+ "expecting an integer for the buffer size");
+ return NULL;
+ }
+ temp = PyInt_AsLong($input);
+ if (temp < 0) {
+ PyErr_SetString(PyExc_ValueError,
+ "buffer size must be a positive integer");
+ return NULL;
+ }
+ $1 = malloc(temp);
+ $2 = ($2_ltype)&temp;
+}
+%typemap(perl5, in) (char *buffer, apr_size_t *len) ($*2_type temp) {
+ /* ### FIXME-perl */
+}
+
+/* ### need to use freearg or somesuch to ensure the string is freed.
+ ### watch out for 'return' anywhere in the binding code. */
+
+%typemap(python, argout, fragment="t_output_helper") (char *buffer, apr_size_t *len) {
+ $result = t_output_helper($result, PyString_FromStringAndSize($1, *$2));
+ free($1);
+}
+%typemap(perl5, argout) (char *buffer, apr_size_t *len) {
+ /* ### FIXME-perl */
+}
+
+/* -----------------------------------------------------------------------
+ fix up the svn_stream_write() ptr/len arguments
+*/
+%typemap(python, in) (const char *data, apr_size_t *len) ($*2_type temp) {
+ if (!PyString_Check($input)) {
+ PyErr_SetString(PyExc_TypeError,
+ "expecting a string for the buffer");
+ return NULL;
+ }
+ $1 = PyString_AS_STRING($input);
+ temp = PyString_GET_SIZE($input);
+ $2 = ($2_ltype)&temp;
+}
+%typemap(perl5, in) (const char *data, apr_size_t *len) ($*2_type temp) {
+ /* ### FIXME-perl */
+}
+
+%typemap(python, argout, fragment="t_output_helper") (const char *data, apr_size_t *len) {
+ $result = t_output_helper($result, PyInt_FromLong(*$2));
+}
+
+%typemap(perl5, argout, fragment="t_output_helper") (const char *data, apr_size_t *len) {
+ /* ### FIXME-perl */
+}
+
+/* -----------------------------------------------------------------------
+ describe how to pass a FILE* as a parameter (svn_stream_from_stdio)
+*/
+%typemap(python, in) FILE * {
+ $1 = PyFile_AsFile($input);
+ if ($1 == NULL) {
+ PyErr_SetString(PyExc_ValueError, "Must pass in a valid file object");
+ return NULL;
+ }
+}
+%typemap(perl5, in) FILE * {
+ /* ### FIXME-perl */
+}
+
+/* -----------------------------------------------------------------------
+ the second argument to svn_parse_date is unused: always pass NULL
+*/
+
+%typemap(python,in,numinputs=0) struct getdate_time *now {
+ $1 = NULL;
+}
+
+/* ignore the related structure */
+/* ### hmm... this structure isn't namespace protected?! */
+%ignore getdate_time;
+
+/* -----------------------------------------------------------------------
+ wrap some specific APR functionality
+*/
+
+apr_status_t apr_initialize(void);
+void apr_terminate(void);
+
+apr_status_t apr_time_ansi_put(apr_time_t *result, time_t input);
+
+void apr_pool_destroy(apr_pool_t *p);
+
+/* ----------------------------------------------------------------------- */
+
+%include svn_types.h
+%include svn_pools.h
+%include svn_version.h
+%include svn_time.h
+%include svn_props.h
+%include svn_opt.h
+%include svn_auth.h
+
+/* SWIG won't follow through to APR's defining this to be empty, so we
+ need to do it manually, before SWIG sees this in svn_io.h. */
+#define __attribute__(x)
+
+%include svn_io.h
+
+%{
+#include <apr.h>
+#include <apr_general.h>
+
+#include "svn_io.h"
+#include "svn_pools.h"
+#include "svn_version.h"
+#include "svn_time.h"
+#include "svn_props.h"
+#include "svn_opt.h"
+#include "svn_auth.h"
+
+#ifdef SWIGPYTHON
+#include "swigutil_py.h"
+#endif
+
+#ifdef SWIGJAVA
+#include "swigutil_java.h"
+#endif
+
+%}
Index: subversion/bindings/swig/svn_ra.i
===================================================================
--- subversion/bindings/swig/svn_ra.i (revision 5921)
+++ subversion/bindings/swig/svn_ra.i (working copy)
@@ -16,7 +16,7 @@
  * ====================================================================
  */
 
-%module _ra
+%module ra
 %include typemaps.i
 
 %import apr.i
Index: subversion/bindings/swig/python/svn/fs.py
===================================================================
--- subversion/bindings/swig/python/svn/fs.py (revision 5921)
+++ subversion/bindings/swig/python/svn/fs.py (working copy)
@@ -20,19 +20,21 @@
 import tempfile
 import os
 import popen2
-
-import _fs
-import _util
 import string
 
+import libsvn.fs
+import core
+
 # copy the wrapper functions out of the extension module, dropping the
 # 'svn_fs_' prefix.
-for name in dir(_fs):
+# XXX this might change in the future once we have a consistent naming
+# scheme
+for name in dir(libsvn.fs):
   if name[:7] == 'svn_fs_':
- vars()[name[7:]] = getattr(_fs, name)
+ vars()[name[7:]] = getattr(libsvn.fs, name)
 
 # we don't want these symbols exported
-del name, _fs
+del name, libsvn
 
 def entries(root, path, pool):
   "Call dir_entries returning a dictionary mappings names to IDs."
@@ -57,19 +59,19 @@
 
     # the caller can't manage this pool very well given our indirect use
     # of it. so we'll create a subpool and clear it at "proper" times.
- self.pool = _util.svn_pool_create(pool)
+ self.pool = core.svn_pool_create(pool)
 
   def either_binary(self):
     "Return true if either of the files are binary."
     if self.path1 is not None:
- prop = node_prop(self.root1, self.path1, _util.SVN_PROP_MIME_TYPE,
+ prop = node_prop(self.root1, self.path1, core.SVN_PROP_MIME_TYPE,
                        self.pool)
- if prop and _util.svn_mime_type_is_binary(prop):
+ if prop and core.svn_mime_type_is_binary(prop):
         return 1
     if self.path2 is not None:
- prop = node_prop(self.root2, self.path2, _util.SVN_PROP_MIME_TYPE,
+ prop = node_prop(self.root2, self.path2, core.SVN_PROP_MIME_TYPE,
                        self.pool)
- if prop and _util.svn_mime_type_is_binary(prop):
+ if prop and core.svn_mime_type_is_binary(prop):
         return 1
     return 0
 
@@ -83,7 +85,7 @@
     if self.path1 is not None:
       len = file_length(self.root1, self.path1, self.pool)
       stream = file_contents(self.root1, self.path1, self.pool)
- contents = _util.svn_stream_read(stream, len)
+ contents = core.svn_stream_read(stream, len)
     open(self.tempfile1, 'w+').write(contents)
 
     self.tempfile2 = tempfile.mktemp()
@@ -91,11 +93,11 @@
     if self.path2 is not None:
       len = file_length(self.root2, self.path2, self.pool)
       stream = file_contents(self.root2, self.path2, self.pool)
- contents = _util.svn_stream_read(stream, len)
+ contents = core.svn_stream_read(stream, len)
     open(self.tempfile2, 'w+').write(contents)
 
     # get rid of anything we put into our subpool
- _util.svn_pool_clear(self.pool)
+ core.svn_pool_clear(self.pool)
 
     return self.tempfile1, self.tempfile2
 
Index: subversion/bindings/swig/python/svn/repos.py
===================================================================
--- subversion/bindings/swig/python/svn/repos.py (revision 5921)
+++ subversion/bindings/swig/python/svn/repos.py (working copy)
@@ -14,4 +14,4 @@
 ######################################################################
 #
 
-from _repos import *
+from libsvn.repos import *
Index: subversion/bindings/swig/python/svn/core.py
===================================================================
--- subversion/bindings/swig/python/svn/core.py (working copy)
+++ subversion/bindings/swig/python/svn/core.py (working copy)
@@ -0,0 +1,71 @@
+#
+# svn.core: public Python interface for core compontents
+#
+# Subversion is a tool for revision control.
+# See http://subversion.tigris.org for more information.
+#
+# ====================================================================
+# Copyright (c) 2000-2003 CollabNet. All rights reserved.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at http://subversion.tigris.org/license-1.html.
+# If newer versions of this license are posted there, you may use a
+# newer version instead, at your option.
+#
+######################################################################
+#
+
+# bring all the symbols up into this module
+### in the future, we may want to limit this, rename things, etc
+from libsvn.core import *
+
+def run_app(func, *args, **kw):
+ '''Run a function as an "APR application".
+
+ APR is initialized, and an application pool is created. Cleanup is
+ performed as the function exits (normally or via an exception.
+ '''
+ apr_initialize()
+ try:
+ pool = svn_pool_create(None)
+ try:
+ return apply(func, (pool,) + args, kw)
+ finally:
+ svn_pool_destroy(pool)
+ finally:
+ apr_terminate()
+
+# some minor patchups
+svn_pool_destroy = apr_pool_destroy
+
+
+class Stream:
+ def __init__(self, stream):
+ self._stream = stream
+
+ def read(self, amt=None):
+ if amt is None:
+ # read the rest of the stream
+ chunks = [ ]
+ while 1:
+ data = svn_stream_read(self._stream, SVN_STREAM_CHUNK_SIZE)
+ if not data:
+ break
+ chunks.append(data)
+ return ''.join(chunks)
+
+ # read the amount specified
+ return svn_stream_read(self._stream, int(amt))
+
+ def write(self, buf):
+ ### what to do with the amount written? (the result value)
+ svn_stream_write(self._stream, buf)
+
+def secs_from_timestr(svn_datetime, pool):
+ aprtime = svn_time_from_cstring(svn_datetime, pool)
+
+ # ### convert to a time_t; this requires intimate knowledge of
+ # ### the apr_time_t type
+ # ### aprtime is microseconds; turn it into seconds
+ return aprtime / 1000000
Index: subversion/bindings/swig/python/svn/wc.py
===================================================================
--- subversion/bindings/swig/python/svn/wc.py (revision 5921)
+++ subversion/bindings/swig/python/svn/wc.py (working copy)
@@ -14,4 +14,4 @@
 ######################################################################
 #
 
-from _wc import *
+from libsvn.wc import *
Index: subversion/bindings/swig/python/svn/delta.py
===================================================================
--- subversion/bindings/swig/python/svn/delta.py (revision 5921)
+++ subversion/bindings/swig/python/svn/delta.py (working copy)
@@ -14,7 +14,7 @@
 ######################################################################
 #
 
-from _delta import *
+from libsvn.delta import *
 
 class Editor:
 
Index: subversion/bindings/swig/python/svn/util.py
===================================================================
--- subversion/bindings/swig/python/svn/util.py (revision 5921)
+++ subversion/bindings/swig/python/svn/util.py (working copy)
@@ -16,61 +16,6 @@
 ######################################################################
 #
 
-# to retain backwards Python compat, we don't use 'import foo as bar'
-import string
-_string = string
-del string
-
-# bring all the symbols up into this module
-### in the future, we may want to limit this, rename things, etc
-from _util import *
-
-def run_app(func, *args, **kw):
- '''Run a function as an "APR application".
-
- APR is initialized, and an application pool is created. Cleanup is
- performed as the function exits (normally or via an exception.
- '''
- apr_initialize()
- try:
- pool = svn_pool_create(None)
- try:
- return apply(func, (pool,) + args, kw)
- finally:
- svn_pool_destroy(pool)
- finally:
- apr_terminate()
-
-# some minor patchups
-svn_pool_destroy = apr_pool_destroy
-
-
-class Stream:
- def __init__(self, stream):
- self._stream = stream
-
- def read(self, amt=None):
- if amt is None:
- # read the rest of the stream
- chunks = [ ]
- while 1:
- data = svn_stream_read(self._stream, SVN_STREAM_CHUNK_SIZE)
- if not data:
- break
- chunks.append(data)
- return _string.join(chunks, '')
-
- # read the amount specified
- return svn_stream_read(self._stream, int(amt))
-
- def write(self, buf):
- ### what to do with the amount written? (the result value)
- svn_stream_write(self._stream, buf)
-
-def secs_from_timestr(svn_datetime, pool):
- aprtime = svn_time_from_cstring(svn_datetime, pool)
-
- # ### convert to a time_t; this requires intimate knowledge of
- # ### the apr_time_t type
- # ### aprtime is microseconds; turn it into seconds
- return aprtime / 1000000
+# XXX This package might go a way eventually or get different contents
+# For compatability reasons, we import everything from core
+from core import *
Index: subversion/bindings/swig/python/svn/client.py
===================================================================
--- subversion/bindings/swig/python/svn/client.py (revision 5921)
+++ subversion/bindings/swig/python/svn/client.py (working copy)
@@ -14,4 +14,4 @@
 ######################################################################
 #
 
-from _client import *
+from libsvn.client import *
Index: subversion/bindings/swig/python/svn/ra.py
===================================================================
--- subversion/bindings/swig/python/svn/ra.py (revision 5921)
+++ subversion/bindings/swig/python/svn/ra.py (working copy)
@@ -14,4 +14,4 @@
 ######################################################################
 #
 
-from _ra import *
+from libsvn.ra import *
Index: subversion/bindings/swig/python/__init__.py
===================================================================
--- subversion/bindings/swig/python/__init__.py (working copy)
+++ subversion/bindings/swig/python/__init__.py (working copy)
@@ -0,0 +1,17 @@
+#
+# __init__.py: defines this directory as the 'libsvn' package.
+#
+# Subversion is a tool for revision control.
+# See http://subversion.tigris.org for more information.
+#
+# ====================================================================
+# Copyright (c) 2000-2003 CollabNet. All rights reserved.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at http://subversion.tigris.org/license-1.html.
+# If newer versions of this license are posted there, you may use a
+# newer version instead, at your option.
+#
+######################################################################
+#
Index: subversion/bindings/swig/svn_fs.i
===================================================================
--- subversion/bindings/swig/svn_fs.i (revision 5921)
+++ subversion/bindings/swig/svn_fs.i (working copy)
@@ -16,7 +16,7 @@
  * ====================================================================
  */
 
-%module _fs
+%module fs
 %include typemaps.i
 
 %import apr.i
Index: subversion/bindings/swig/svn_wc.i
===================================================================
--- subversion/bindings/swig/svn_wc.i (revision 5921)
+++ subversion/bindings/swig/svn_wc.i (working copy)
@@ -16,7 +16,7 @@
  * ====================================================================
  */
 
-%module _wc
+%module wc
 %include typemaps.i
 
 %import apr.i
Index: subversion/bindings/swig/svn_client.i
===================================================================
--- subversion/bindings/swig/svn_client.i (revision 5921)
+++ subversion/bindings/swig/svn_client.i (working copy)
@@ -16,7 +16,7 @@
  * ====================================================================
  */
 
-%module _client
+%module client
 %include typemaps.i
 
 %import apr.i
Index: subversion/bindings/swig/util.i
===================================================================
--- subversion/bindings/swig/util.i (working copy)
+++ subversion/bindings/swig/util.i (working copy)
@@ -1,256 +0,0 @@
-/*
- * util.i : SWIG interface file for various SVN and APR utilities
- *
- * ====================================================================
- * Copyright (c) 2000-2003 CollabNet. All rights reserved.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://subversion.tigris.org/license-1.html.
- * If newer versions of this license are posted there, you may use a
- * newer version instead, at your option.
- *
- * This software consists of voluntary contributions made by many
- * individuals. For exact contribution history, see the revision
- * history and logs, available at http://subversion.tigris.org/.
- * ====================================================================
- */
-
-%module _util
-
-%include typemaps.i
-
-%{
-#include "svn_opt.h"
-%}
-
-/* -----------------------------------------------------------------------
- include svn_types.h early. other .i files will import svn_types.i which
- then includes svn_types.h, making further includes get skipped. we want
- to actually generate wrappers, so manage svn_types.h right here.
-*/
-%ignore svn_error;
-
-/* ### for now, let's not try to handle these structures. swig complains
- ### about setting the 'const char *' inside the struct might leak mem */
-%ignore svn_log_changed_path_t;
-
-/* ### We also get complaints about possible memory leakage for svn_dirent,
- ### but we can live with it for now. */
-/* %ignore svn_dirent; */
-
-/* ### for now, let's ignore this thing. */
-%ignore svn_prop_t;
-
-%include svn_types.h
-
-
-/* -----------------------------------------------------------------------
- moving along...
-*/
-%import apr.i
-%import svn_types.i
-%import svn_string.i
-
-/* -----------------------------------------------------------------------
- completely ignore a number of functions. the presumption is that the
- scripting language already has facilities for these things (or they
- are relatively trivial).
-*/
-%ignore svn_io_check_path;
-%ignore svn_io_check_resolved_path;
-%ignore svn_io_copy_file;
-%ignore svn_io_copy_dir_recursively;
-%ignore svn_io_append_file;
-%ignore svn_io_read_length_line;
-%ignore svn_io_file_affected_time;
-%ignore svn_io_fd_from_file;
-%ignore svn_io_get_dirents;
-%ignore svn_io_run_cmd;
-%ignore svn_io_remove_file;
-%ignore svn_io_remove_dir;
-%ignore svn_io_make_dir_recursively;
-%ignore svn_io_set_file_read_only;
-%ignore svn_io_set_file_read_write;
-%ignore svn_io_set_file_executable;
-%ignore svn_io_filesizes_different_p;
-%ignore svn_io_file_printf;
-
-%ignore apr_check_dir_empty;
-
-/* scripts can do the printf, then write to a stream. we can't really
- handle the variadic, so ignore it. */
-%ignore svn_stream_printf;
-
-
-/* -----------------------------------------------------------------------
- these types (as 'type **') will always be an OUT param
-*/
-%apply SWIGTYPE **OUTPARAM {
- svn_auth_baton_t **
-}
-
-/* -----------------------------------------------------------------------
- apr_size_t * is always an IN/OUT parameter in svn_io.h
-*/
-%apply apr_size_t *INOUT { apr_size_t * };
-
-/* -----------------------------------------------------------------------
- handle the MIME type return value of svn_io_detect_mimetype()
-*/
-%apply const char **OUTPUT { const char ** };
-
-/* -----------------------------------------------------------------------
- handle the providers array as an input type.
-*/
-%typemap(python, in) apr_array_header_t *providers {
- svn_auth_provider_object_t *provider;
- int targlen;
- if (!PySequence_Check($input)) {
- PyErr_SetString(PyExc_TypeError, "not a sequence");
- return NULL;
- }
- targlen = PySequence_Length($input);
- $1 = apr_array_make(_global_pool, targlen, sizeof(provider));
- ($1)->nelts = targlen;
- while (targlen--) {
- SWIG_ConvertPtr(PySequence_GetItem($input, targlen),
- (void **)&provider,
- $descriptor(svn_auth_provider_object_t *),
- SWIG_POINTER_EXCEPTION | 0);
- APR_ARRAY_IDX($1, targlen, svn_auth_provider_object_t *) = provider;
- }
-}
-
-/* -----------------------------------------------------------------------
- fix up the svn_stream_read() ptr/len arguments
-*/
-%typemap(python, in) (char *buffer, apr_size_t *len) ($*2_type temp) {
- if (!PyInt_Check($input)) {
- PyErr_SetString(PyExc_TypeError,
- "expecting an integer for the buffer size");
- return NULL;
- }
- temp = PyInt_AsLong($input);
- if (temp < 0) {
- PyErr_SetString(PyExc_ValueError,
- "buffer size must be a positive integer");
- return NULL;
- }
- $1 = malloc(temp);
- $2 = ($2_ltype)&temp;
-}
-%typemap(perl5, in) (char *buffer, apr_size_t *len) ($*2_type temp) {
- /* ### FIXME-perl */
-}
-
-/* ### need to use freearg or somesuch to ensure the string is freed.
- ### watch out for 'return' anywhere in the binding code. */
-
-%typemap(python, argout, fragment="t_output_helper") (char *buffer, apr_size_t *len) {
- $result = t_output_helper($result, PyString_FromStringAndSize($1, *$2));
- free($1);
-}
-%typemap(perl5, argout) (char *buffer, apr_size_t *len) {
- /* ### FIXME-perl */
-}
-
-/* -----------------------------------------------------------------------
- fix up the svn_stream_write() ptr/len arguments
-*/
-%typemap(python, in) (const char *data, apr_size_t *len) ($*2_type temp) {
- if (!PyString_Check($input)) {
- PyErr_SetString(PyExc_TypeError,
- "expecting a string for the buffer");
- return NULL;
- }
- $1 = PyString_AS_STRING($input);
- temp = PyString_GET_SIZE($input);
- $2 = ($2_ltype)&temp;
-}
-%typemap(perl5, in) (const char *data, apr_size_t *len) ($*2_type temp) {
- /* ### FIXME-perl */
-}
-
-%typemap(python, argout, fragment="t_output_helper") (const char *data, apr_size_t *len) {
- $result = t_output_helper($result, PyInt_FromLong(*$2));
-}
-
-%typemap(perl5, argout, fragment="t_output_helper") (const char *data, apr_size_t *len) {
- /* ### FIXME-perl */
-}
-
-/* -----------------------------------------------------------------------
- describe how to pass a FILE* as a parameter (svn_stream_from_stdio)
-*/
-%typemap(python, in) FILE * {
- $1 = PyFile_AsFile($input);
- if ($1 == NULL) {
- PyErr_SetString(PyExc_ValueError, "Must pass in a valid file object");
- return NULL;
- }
-}
-%typemap(perl5, in) FILE * {
- /* ### FIXME-perl */
-}
-
-/* -----------------------------------------------------------------------
- the second argument to svn_parse_date is unused: always pass NULL
-*/
-
-%typemap(python,in,numinputs=0) struct getdate_time *now {
- $1 = NULL;
-}
-
-/* ignore the related structure */
-/* ### hmm... this structure isn't namespace protected?! */
-%ignore getdate_time;
-
-/* -----------------------------------------------------------------------
- wrap some specific APR functionality
-*/
-
-apr_status_t apr_initialize(void);
-void apr_terminate(void);
-
-apr_status_t apr_time_ansi_put(apr_time_t *result, time_t input);
-
-void apr_pool_destroy(apr_pool_t *p);
-
-/* ----------------------------------------------------------------------- */
-
-%include svn_types.h
-%include svn_pools.h
-%include svn_version.h
-%include svn_time.h
-%include svn_props.h
-%include svn_opt.h
-%include svn_auth.h
-
-/* SWIG won't follow through to APR's defining this to be empty, so we
- need to do it manually, before SWIG sees this in svn_io.h. */
-#define __attribute__(x)
-
-%include svn_io.h
-
-%{
-#include <apr.h>
-#include <apr_general.h>
-
-#include "svn_io.h"
-#include "svn_pools.h"
-#include "svn_version.h"
-#include "svn_time.h"
-#include "svn_props.h"
-#include "svn_opt.h"
-#include "svn_auth.h"
-
-#ifdef SWIGPYTHON
-#include "swigutil_py.h"
-#endif
-
-#ifdef SWIGJAVA
-#include "swigutil_java.h"
-#endif
-
-%}
Index: subversion/bindings/swig/svn_repos.i
===================================================================
--- subversion/bindings/swig/svn_repos.i (revision 5921)
+++ subversion/bindings/swig/svn_repos.i (working copy)
@@ -16,7 +16,7 @@
  * ====================================================================
  */
 
-%module _repos
+%module repos
 %include typemaps.i
 
 %import apr.i
Index: subversion/bindings/swig/svn_delta.i
===================================================================
--- subversion/bindings/swig/svn_delta.i (revision 5921)
+++ subversion/bindings/swig/svn_delta.i (working copy)
@@ -16,7 +16,7 @@
  * ====================================================================
  */
 
-%module _delta
+%module delta
 
 %include "typemaps.i"
 
Index: subversion/bindings/swig/apr.i
===================================================================
--- subversion/bindings/swig/apr.i (revision 5921)
+++ subversion/bindings/swig/apr.i (working copy)
@@ -20,7 +20,7 @@
    because we aren't going to wrap the APR functions. Thus, we only define
    the various types in here, as necessary.
 
- Actually, util.i wraps a few, key functions.
+ Actually, core.i wraps a few, key functions.
 */
 
 %include typemaps.i
Index: tools/hook-scripts/tests/mailer-tweak.py
===================================================================
--- tools/hook-scripts/tests/mailer-tweak.py (revision 5921)
+++ tools/hook-scripts/tests/mailer-tweak.py (working copy)
@@ -13,7 +13,7 @@
 import os
 import getopt
 
-from svn import fs, util
+from svn import fs, core
 
 DATE_BASE = 1000000000
 DATE_INCR = 10000
@@ -29,16 +29,16 @@
 
   for i in range(fs.youngest_rev(fsob, pool)):
     # convert secs into microseconds, then a string
- date = util.svn_time_to_cstring((DATE_BASE+i*DATE_INCR) * 1000000L, pool)
+ date = core.svn_time_to_cstring((DATE_BASE+i*DATE_INCR) * 1000000L, pool)
     #print date
- fs.change_rev_prop(fsob, i+1, util.SVN_PROP_REVISION_DATE, date, pool)
+ fs.change_rev_prop(fsob, i+1, core.SVN_PROP_REVISION_DATE, date, pool)
 
 def main():
   if len(sys.argv) != 2:
     print 'USAGE: %s REPOS' % sys.argv[0]
     sys.exit(1)
 
- util.run_app(tweak_dates, sys.argv[1])
+ core.run_app(tweak_dates, sys.argv[1])
 
 if __name__ == '__main__':
   main()
Index: tools/examples/dumpprops.py
===================================================================
--- tools/examples/dumpprops.py (revision 5921)
+++ tools/examples/dumpprops.py (working copy)
@@ -10,7 +10,7 @@
 import getopt
 import pprint
 
-from svn import fs, util
+from svn import fs, core
 
 
 def dumpprops(pool, path='', rev=None, home='.'):
@@ -41,16 +41,16 @@
   pprint.pprint(props)
 
 def walk_tree(root, path, pool):
- subpool = util.svn_pool_create(pool)
+ subpool = core.svn_pool_create(pool)
   try:
     for name in fs.entries(root, path, subpool).keys():
       full = path + '/' + name
       print_props(root, full, subpool)
       if fs.is_dir(root, full, subpool):
         walk_tree(root, full, subpool)
- util.svn_pool_clear(subpool)
+ core.svn_pool_clear(subpool)
   finally:
- util.svn_pool_destroy(subpool)
+ core.svn_pool_destroy(subpool)
 
 def usage():
   print "USAGE: dumpprops.py [-r REV] [-h DBHOME] repos-path"
@@ -67,7 +67,7 @@
       rev = int(value)
     elif name == '-h':
       home = value
- util.run_app(dumpprops, args[0], rev, home)
+ core.run_app(dumpprops, args[0], rev, home)
 
 if __name__ == '__main__':
   main()
Index: tools/examples/svnlook.py
===================================================================
--- tools/examples/svnlook.py (revision 5921)
+++ tools/examples/svnlook.py (working copy)
@@ -20,15 +20,15 @@
 import time
 import os
 
-from svn import fs, util, delta, _repos
+from svn import core, fs, delta, repos
 
 
 class SVNLook:
   def __init__(self, pool, path, cmd, rev, txn):
     self.pool = pool
 
- repos = _repos.svn_repos_open(path, pool)
- self.fs_ptr = _repos.svn_repos_fs(repos)
+ repos = repos.svn_repos_open(path, pool)
+ self.fs_ptr = repos.svn_repos_fs(repos)
 
     if txn:
       self.txn_ptr = fs.open_txn(self.fs_ptr, txn, pool)
@@ -50,7 +50,7 @@
 
   def cmd_author(self):
     # get the author property, or empty string if the property is not present
- author = self._get_property(util.SVN_PROP_REVISION_AUTHOR) or ''
+ author = self._get_property(core.SVN_PROP_REVISION_AUTHOR) or ''
     print author
 
   def cmd_changed(self):
@@ -60,9 +60,9 @@
     if self.txn_ptr:
       print
     else:
- date = self._get_property(util.SVN_PROP_REVISION_DATE)
+ date = self._get_property(core.SVN_PROP_REVISION_DATE)
       if date:
- aprtime = util.svn_time_from_cstring(date, self.pool)
+ aprtime = core.svn_time_from_cstring(date, self.pool)
         # ### convert to a time_t; this requires intimate knowledge of
         # ### the apr_time_t type
         secs = aprtime / 1000000 # aprtime is microseconds; make seconds
@@ -89,7 +89,7 @@
 
   def cmd_log(self, print_size=0):
     # get the log property, or empty string if the property is not present
- log = self._get_property(util.SVN_PROP_REVISION_LOG) or ''
+ log = self._get_property(core.SVN_PROP_REVISION_LOG) or ''
     if print_size:
       print len(log)
     print log
@@ -129,8 +129,8 @@
     e_ptr, e_baton = delta.make_editor(editor, self.pool)
 
     # compute the delta, printing as we go
- _repos.svn_repos_dir_delta(base_root, '', None, root, '',
- e_ptr, e_baton, 0, 1, 0, 1, 0, self.pool)
+ repos.svn_repos_dir_delta(base_root, '', None, root, '',
+ e_ptr, e_baton, 0, 1, 0, 1, 0, self.pool)
 
 
 class Editor(delta.Editor):
@@ -385,7 +385,7 @@
   if not hasattr(SVNLook, 'cmd_' + cmd):
     usage(1)
 
- util.run_app(SVNLook, sys.argv[1], cmd, rev, txn)
+ core.run_app(SVNLook, sys.argv[1], cmd, rev, txn)
 
 if __name__ == '__main__':
   main()
Index: tools/examples/svnshell.py
===================================================================
--- tools/examples/svnshell.py (revision 5921)
+++ tools/examples/svnshell.py (working copy)
@@ -21,7 +21,7 @@
 import time
 import re
 from random import randint
-from svn import fs, util, repos
+from svn import fs, core, repos
 
 
 class SVNShell:
@@ -30,7 +30,7 @@
     if path[-1] == '/':
       path = path[:-1]
     self.pool = pool
- self.taskpool = util.svn_pool_create(pool)
+ self.taskpool = core.svn_pool_create(pool)
     self.fs_ptr = repos.svn_repos_fs(repos.svn_repos_open(path, pool))
     self.is_rev = 1
     self.rev = fs.youngest_rev(self.fs_ptr, pool)
@@ -60,17 +60,17 @@
       return
     catpath = self._parse_path(args[0])
     kind = fs.check_path(self.root, catpath, self.taskpool)
- if kind == util.svn_node_none:
+ if kind == core.svn_node_none:
       print "Path '%s' does not exist." % catpath
       return
- if kind == util.svn_node_dir:
+ if kind == core.svn_node_dir:
       print "Path '%s' is not a file." % catpath
       return
     ### be nice to get some paging in here. also, not reading the
     ### whole contents of the file at once. but whatever.
     filelen = fs.file_length(self.root, catpath, self.taskpool)
     stream = fs.file_contents(self.root, catpath, self.taskpool)
- print util.svn_stream_read(stream, filelen)
+ print core.svn_stream_read(stream, filelen)
     
   def cmd_cd(self, *args):
     """change directory"""
@@ -81,11 +81,11 @@
     
     # make sure that path actually exists in the filesystem as a directory
     kind = fs.check_path(self.root, newpath, self.taskpool)
- if kind != util.svn_node_dir:
+ if kind != core.svn_node_dir:
       print "Path '%s' is not a valid filesystem directory." % newpath
       return
     self.path = newpath
- util.svn_pool_clear(self.taskpool)
+ core.svn_pool_clear(self.taskpool)
 
   def cmd_ls(self, *args):
     """list the contents of the current directory or provided path"""
@@ -98,10 +98,10 @@
       # args? show a listing of that path.
       newpath = self._parse_path(args[0])
       kind = fs.check_path(self.root, newpath, self.taskpool)
- if kind == util.svn_node_dir:
+ if kind == core.svn_node_dir:
         parent = newpath
         entries = fs.dir_entries(self.root, parent, self.taskpool)
- elif kind == util.svn_node_file:
+ elif kind == core.svn_node_file:
         parts = self._path_to_parts(newpath)
         name = parts.pop(-1)
         parent = self._parts_to_path(parts)
@@ -130,15 +130,14 @@
       else:
         size = str(fs.file_length(self.root, fullpath, self.taskpool))
         name = entry
- node_id = fs.unparse_id(fs.dirent_t_id_get(entries[entry]),
- self.taskpool)
+ node_id = fs.unparse_id(entries[entry].id, self.taskpool)
       created_rev = fs.node_created_rev(self.root, fullpath, self.taskpool)
       author = fs.revision_prop(self.fs_ptr, created_rev,
- util.SVN_PROP_REVISION_AUTHOR, self.taskpool)
+ core.SVN_PROP_REVISION_AUTHOR, self.taskpool)
       if not author:
         author = ""
       date = fs.revision_prop(self.fs_ptr, created_rev,
- util.SVN_PROP_REVISION_DATE, self.taskpool)
+ core.SVN_PROP_REVISION_DATE, self.taskpool)
       if not date:
         date = ""
       else:
@@ -146,7 +145,7 @@
      
       print "%6s %8s <%10s> %8s %12s %s" % (created_rev, author[:8],
                                             node_id, size, date, name)
- util.svn_pool_clear(self.taskpool)
+ core.svn_pool_clear(self.taskpool)
   
   def cmd_lstxns(self, *args):
     """list the transactions available for browsing"""
@@ -160,7 +159,7 @@
         print ""
         counter = 0
     print ""
- util.svn_pool_clear(self.taskpool)
+ core.svn_pool_clear(self.taskpool)
     
   def cmd_pcat(self, *args):
     """list the properties of a path"""
@@ -169,7 +168,7 @@
     if args:
       catpath = self._parse_path(args[0])
     kind = fs.check_path(self.root, catpath, self.taskpool)
- if kind == util.svn_node_none:
+ if kind == core.svn_node_none:
       print "Path '%s' does not exist." % catpath
       return
     plist = fs.node_proplist(self.root, catpath, self.taskpool)
@@ -217,7 +216,7 @@
     """list the youngest revision available for browsing"""
     rev = fs.youngest_rev(self.fs_ptr, self.taskpool)
     print rev
- util.svn_pool_clear(self.taskpool)
+ core.svn_pool_clear(self.taskpool)
 
   def _path_to_parts(self, path):
     return filter(None, string.split(path, '/'))
@@ -251,7 +250,7 @@
     return self._parts_to_path(finalparts)
     
   def _format_date(self, date, pool):
- date = util.svn_time_from_cstring(date, pool)
+ date = core.svn_time_from_cstring(date, pool)
     date = time.asctime(time.localtime(date / 1000000))
     return date[4:-8]
   
@@ -261,14 +260,14 @@
     newpath = self.path
     while not_found:
       kind = fs.check_path(self.root, newpath, self.taskpool)
- if kind == util.svn_node_dir:
+ if kind == core.svn_node_dir:
         not_found = 0
       else:
         parts = self._path_to_parts(newpath)
         parts.pop(-1)
         newpath = self._parts_to_path(parts)
     self.path = newpath
- util.svn_pool_clear(self.taskpool)
+ core.svn_pool_clear(self.taskpool)
 
   _errors = ["Huh?",
              "Whatchoo talkin' 'bout, Willis?",
@@ -341,7 +340,7 @@
   except:
     pass
   
- util.run_app(SVNShell, sys.argv[1])
+ core.run_app(SVNShell, sys.argv[1])
 
 if __name__ == '__main__':
   main()
Index: tools/examples/getfile.py
===================================================================
--- tools/examples/getfile.py (revision 5921)
+++ tools/examples/getfile.py (working copy)
@@ -9,7 +9,7 @@
 import os
 import getopt
 
-from svn import fs, util
+from svn import fs, core
 
 CHUNK_SIZE = 16384
 
@@ -28,7 +28,7 @@
   root = fs.revision_root(fsob, rev, pool)
   file = fs.file_contents(root, path, pool)
   while 1:
- data = util.svn_stream_read(file, CHUNK_SIZE)
+ data = core.svn_stream_read(file, CHUNK_SIZE)
     if not data:
       break
     sys.stdout.write(data)
@@ -48,7 +48,7 @@
       rev = int(value)
     elif name == '-h':
       home = value
- util.run_app(getfile, args[0], rev, home)
+ core.run_app(getfile, args[0], rev, home)
 
 if __name__ == '__main__':
   main()
Index: tools/examples/blame.py
===================================================================
--- tools/examples/blame.py (revision 5921)
+++ tools/examples/blame.py (working copy)
@@ -7,7 +7,7 @@
 import os
 import getopt
 import difflib
-from svn import fs, util
+from svn import fs, core
 
 CHUNK_SIZE = 100000
 
@@ -25,7 +25,7 @@
   filedata = ''
   for i in xrange(0, rev+1):
     root = fs.revision_root(fsob, i, pool)
- if fs.check_path(root, path, pool) != util.svn_node_none:
+ if fs.check_path(root, path, pool) != core.svn_node_none:
       first = i
       break
   print "First revision is %d" % first
@@ -41,7 +41,7 @@
     previousdata = filedata
     filedata = ''
     while 1:
- data = util.svn_stream_read(file, CHUNK_SIZE)
+ data = core.svn_stream_read(file, CHUNK_SIZE)
       if not data:
         break
       filedata = filedata + data
@@ -87,7 +87,7 @@
       rev = int(value)
     elif name == '-h':
       home = value
- util.run_app(getfile, args[0], rev, home)
+ core.run_app(getfile, args[0], rev, home)
 
 if __name__ == '__main__':
   main()
Index: tools/examples/geturl.py
===================================================================
--- tools/examples/geturl.py (revision 5921)
+++ tools/examples/geturl.py (working copy)
@@ -19,7 +19,7 @@
     adm_baton = svn.wc.svn_wc_adm_open(None, dirpath, 1, 1, pool)
     try:
       entry = svn.wc.svn_wc_entry(fullpath, adm_baton, 0, pool)
- print svn.wc.svn_wc_entry_t_url_get(entry)
+ print entry.url
     finally:
       svn.wc.svn_wc_adm_close(adm_baton)
 

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Tue May 13 23:36:25 2003

This is an archived mail posted to the Subversion Dev mailing list.

This site is subject to the Apache Privacy Policy and the Apache Public Forum Archive Policy.