* subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c
[svn.git] / subversion / bindings / swig / python / svn / core.py
blob7e61534f5ec096effa0968eb638c244caf6763e6
2 # core.py: public Python interface for core components
4 # Subversion is a tool for revision control.
5 # See http://subversion.tigris.org for more information.
7 ######################################################################
9 # Copyright (c) 2003-2007 CollabNet. All rights reserved.
11 # This software is licensed as described in the file COPYING, which
12 # you should have received as part of this distribution. The terms
13 # are also available at http://subversion.tigris.org/license-1.html.
14 # If newer versions of this license are posted there, you may use a
15 # newer version instead, at your option.
17 ######################################################################
19 from libsvn.core import *
20 import libsvn.core as _libsvncore
21 import atexit as _atexit
23 class SubversionException(Exception):
24 def __init__(self, message=None, apr_err=None, child=None,
25 file=None, line=None):
26 """Initialize a new Subversion exception object.
28 Arguments:
29 message -- optional user-visible error message
30 apr_err -- optional integer error code (apr_status_t)
31 child -- optional SubversionException to wrap
32 file -- optional source file name where the error originated
33 line -- optional line number of the source file
35 file and line are for C, not Python; they are redundant to the
36 traceback information for exceptions raised in Python.
37 """
38 # Be compatible with pre-1.5 .args behavior:
39 args = []
40 if message is None:
41 # SubversionException().args => ()
42 pass
43 else:
44 # SubversionException('message').args => ('message',)
45 args.append(message)
46 if apr_err is not None:
47 # SubversionException('message', 123) => ('message', 123)
48 args.append(apr_err)
49 Exception.__init__(self, *args)
51 self.apr_err = apr_err
52 self.message = message
53 self.child = child
54 self.file = file
55 self.line = line
57 def _new_from_err_list(cls, errors):
58 """Return new Subversion exception object from list of svn_error_t data.
60 This alternative constructor is for turning a chain of svn_error_t
61 objects in C into a chain of SubversionException objects in Python.
62 errors is a list of (apr_err, message, file, line) tuples, in order
63 from outer-most child to inner-most.
65 Use svn_swig_py_svn_exception rather than calling this directly.
67 Note: this modifies the errors list provided by the caller by
68 reversing it.
69 """
70 child = None
71 errors.reverse()
72 for (apr_err, message, file, line) in errors:
73 child = cls(message, apr_err, child, file, line)
74 return child
75 # Don't use @classmethod, we support 2.2.
76 _new_from_err_list = classmethod(_new_from_err_list)
79 def _cleanup_application_pool():
80 """Cleanup the application pool before exiting"""
81 if application_pool and application_pool.valid():
82 application_pool.destroy()
83 _atexit.register(_cleanup_application_pool)
85 def _unprefix_names(symbol_dict, from_prefix, to_prefix = ''):
86 for name, value in symbol_dict.items():
87 if name.startswith(from_prefix):
88 symbol_dict[to_prefix + name[len(from_prefix):]] = value
91 Pool = _libsvncore.svn_pool_create
93 # Setup consistent names for revnum constants
94 SVN_IGNORED_REVNUM = SWIG_SVN_IGNORED_REVNUM
95 SVN_INVALID_REVNUM = SWIG_SVN_INVALID_REVNUM
97 def svn_path_compare_paths(path1, path2):
98 path1_len = len (path1);
99 path2_len = len (path2);
100 min_len = min(path1_len, path2_len)
101 i = 0
103 # Are the paths exactly the same?
104 if path1 == path2:
105 return 0
107 # Skip past common prefix
108 while (i < min_len) and (path1[i] == path2[i]):
109 i = i + 1
111 # Children of paths are greater than their parents, but less than
112 # greater siblings of their parents
113 char1 = '\0'
114 char2 = '\0'
115 if (i < path1_len):
116 char1 = path1[i]
117 if (i < path2_len):
118 char2 = path2[i]
120 if (char1 == '/') and (i == path2_len):
121 return 1
122 if (char2 == '/') and (i == path1_len):
123 return -1
124 if (i < path1_len) and (char1 == '/'):
125 return -1
126 if (i < path2_len) and (char2 == '/'):
127 return 1
129 # Common prefix was skipped above, next character is compared to
130 # determine order
131 return cmp(char1, char2)
133 def svn_mergeinfo_merge(mergeinfo, changes):
134 return _libsvncore.svn_swig_mergeinfo_merge(mergeinfo, changes)
136 def svn_mergeinfo_sort(mergeinfo):
137 return _libsvncore.svn_swig_mergeinfo_sort(mergeinfo)
139 def svn_rangelist_merge(rangelist, changes):
140 return _libsvncore.svn_swig_rangelist_merge(rangelist, changes)
142 def svn_rangelist_reverse(rangelist):
143 return _libsvncore.svn_swig_rangelist_reverse(rangelist)
145 class Stream:
146 """A file-object-like wrapper for Subversion svn_stream_t objects."""
147 def __init__(self, stream):
148 self._stream = stream
150 def read(self, amt=None):
151 if amt is None:
152 # read the rest of the stream
153 chunks = [ ]
154 while 1:
155 data = svn_stream_read(self._stream, SVN_STREAM_CHUNK_SIZE)
156 if not data:
157 break
158 chunks.append(data)
159 return ''.join(chunks)
161 # read the amount specified
162 return svn_stream_read(self._stream, int(amt))
164 def write(self, buf):
165 ### what to do with the amount written? (the result value)
166 svn_stream_write(self._stream, buf)
168 def secs_from_timestr(svn_datetime, pool=None):
169 """Convert a Subversion datetime string into seconds since the Epoch."""
170 aprtime = svn_time_from_cstring(svn_datetime, pool)
172 # ### convert to a time_t; this requires intimate knowledge of
173 # ### the apr_time_t type
174 # ### aprtime is microseconds; turn it into seconds
175 return aprtime / 1000000
178 # ============================================================================
179 # Variations on this code are used in other places:
180 # - subversion/build/generator/gen_win.py
181 # - cvs2svn/cvs2svn
183 # Names that are not to be exported
184 import sys as _sys
186 if _sys.platform == "win32":
187 import re as _re
188 _escape_shell_arg_re = _re.compile(r'(\\+)(\"|$)')
190 def escape_shell_arg(arg):
191 # The (very strange) parsing rules used by the C runtime library are
192 # described at:
193 # http://msdn.microsoft.com/library/en-us/vclang/html/_pluslang_Parsing_C.2b2b_.Command.2d.Line_Arguments.asp
195 # double up slashes, but only if they are followed by a quote character
196 arg = _re.sub(_escape_shell_arg_re, r'\1\1\2', arg)
198 # surround by quotes and escape quotes inside
199 arg = '"' + arg.replace('"', '"^""') + '"'
200 return arg
203 def argv_to_command_string(argv):
204 """Flatten a list of command line arguments into a command string.
206 The resulting command string is expected to be passed to the system
207 shell which os functions like popen() and system() invoke internally.
210 # According cmd's usage notes (cmd /?), it parses the command line by
211 # "seeing if the first character is a quote character and if so, stripping
212 # the leading character and removing the last quote character."
213 # So to prevent the argument string from being changed we add an extra set
214 # of quotes around it here.
215 return '"' + " ".join(map(escape_shell_arg, argv)) + '"'
217 else:
218 def escape_shell_arg(str):
219 return "'" + str.replace("'", "'\\''") + "'"
221 def argv_to_command_string(argv):
222 """Flatten a list of command line arguments into a command string.
224 The resulting command string is expected to be passed to the system
225 shell which os functions like popen() and system() invoke internally.
228 return " ".join(map(escape_shell_arg, argv))
229 # ============================================================================
230 # Deprecated functions
232 def apr_initialize():
233 """Deprecated. APR is now initialized automatically. This is
234 a compatibility wrapper providing the interface of the
235 Subversion 1.2.x and earlier bindings."""
236 pass
238 def apr_terminate():
239 """Deprecated. APR is now terminated automatically. This is
240 a compatibility wrapper providing the interface of the
241 Subversion 1.2.x and earlier bindings."""
242 pass
244 def svn_pool_create(parent_pool=None):
245 """Deprecated. Use Pool() instead. This is a compatibility
246 wrapper providing the interface of the Subversion 1.2.x and
247 earlier bindings."""
248 return Pool(parent_pool)
250 def svn_pool_destroy(pool):
251 """Deprecated. Pools are now destroyed automatically. If you
252 want to manually destroy a pool, use Pool.destroy. This is
253 a compatibility wrapper providing the interface of the
254 Subversion 1.2.x and earlier bindings."""
256 assert pool is not None
258 # New in 1.3.x: All pools are automatically destroyed when Python shuts
259 # down. For compatibility with 1.2.x, we won't report an error if your
260 # app tries to destroy a pool during the shutdown process. Instead, we
261 # check to make sure the application_pool is still around before calling
262 # pool.destroy().
263 if application_pool and application_pool.valid():
264 pool.destroy()
265 apr_pool_destroy = svn_pool_destroy
267 def svn_pool_clear(pool):
268 """Deprecated. Use Pool.clear instead. This is a compatibility
269 wrapper providing the interface of the Subversion 1.2.x and
270 earlier bindings."""
272 assert pool is not None
274 pool.clear()
275 apr_pool_clear = svn_pool_clear
277 def run_app(func, *args, **kw):
278 '''Deprecated: Application-level pools are now created
279 automatically. APR is also initialized and terminated
280 automatically. This is a compatibility wrapper providing the
281 interface of the Subversion 1.2.x and earlier bindings.
283 Run a function as an "APR application".
285 APR is initialized, and an application pool is created. Cleanup is
286 performed as the function exits (normally or via an exception).
288 return apply(func, (application_pool,) + args, kw)