/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/_readdir_pyx.pyx

  • Committer: Robert Collins
  • Date: 2010-05-06 23:41:35 UTC
  • mto: This revision was merged to the branch mainline in revision 5223.
  • Revision ID: robertc@robertcollins.net-20100506234135-yivbzczw1sejxnxc
Lock methods on ``Tree``, ``Branch`` and ``Repository`` are now
expected to return an object which can be used to unlock them. This reduces
duplicate code when using cleanups. The previous 'tokens's returned by
``Branch.lock_write`` and ``Repository.lock_write`` are now attributes
on the result of the lock_write. ``repository.RepositoryWriteLockResult``
and ``branch.BranchWriteLockResult`` document this. (Robert Collins)

``log._get_info_for_log_files`` now takes an add_cleanup callable.
(Robert Collins)

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
 
17
17
"""Wrapper for readdir which returns files ordered by inode."""
18
18
 
19
 
from __future__ import absolute_import
20
 
 
21
19
 
22
20
import os
23
21
import sys
24
22
 
 
23
#python2.4 support
25
24
cdef extern from "python-compat.h":
26
25
    pass
27
26
 
80
79
 
81
80
cdef extern from 'Python.h':
82
81
    int PyErr_CheckSignals() except -1
83
 
    char * PyBytes_AS_STRING(object)
 
82
    char * PyString_AS_STRING(object)
 
83
    ctypedef int Py_ssize_t # Required for older pyrex versions
84
84
    ctypedef struct PyObject:
85
85
        pass
86
 
    Py_ssize_t PyBytes_Size(object s)
 
86
    Py_ssize_t PyString_Size(object s)
87
87
    object PyList_GetItem(object lst, Py_ssize_t index)
88
88
    void *PyList_GetItem_object_void "PyList_GET_ITEM" (object lst, int index)
89
89
    int PyList_Append(object lst, object item) except -1
92
92
    int PyTuple_SetItem_obj "PyTuple_SetItem" (void *, Py_ssize_t pos, PyObject * item) except -1
93
93
    void Py_INCREF(object o)
94
94
    void Py_DECREF(object o)
95
 
    void PyBytes_Concat(PyObject **string, object newpart)
 
95
    void PyString_Concat(PyObject **string, object newpart)
96
96
 
97
97
 
98
98
cdef extern from 'dirent.h':
106
106
    int closedir(DIR * dir)
107
107
    dirent *readdir(DIR *dir)
108
108
 
109
 
cdef object _directory
110
109
_directory = 'directory'
111
 
cdef object _chardev
112
110
_chardev = 'chardev'
113
 
cdef object _block
114
111
_block = 'block'
115
 
cdef object _file
116
112
_file = 'file'
117
 
cdef object _fifo
118
113
_fifo = 'fifo'
119
 
cdef object _symlink
120
114
_symlink = 'symlink'
121
 
cdef object _socket
122
115
_socket = 'socket'
123
 
cdef object _unknown
124
116
_unknown = 'unknown'
 
117
_missing = 'missing'
125
118
 
126
119
# add a typedef struct dirent dirent to workaround pyrex
127
120
cdef extern from 'readdir.h':
166
159
                     self.st_mtime, self.st_ctime))
167
160
 
168
161
 
169
 
from . import osutils
 
162
from bzrlib import osutils
170
163
 
171
 
cdef object _safe_utf8
172
 
_safe_utf8 = osutils.safe_utf8
173
164
 
174
165
cdef class UTF8DirReader:
175
166
    """A dir reader for utf8 file systems."""
176
167
 
 
168
    cdef readonly object _safe_utf8
 
169
    cdef _directory, _chardev, _block, _file, _fifo, _symlink
 
170
    cdef _socket, _unknown
 
171
 
 
172
    def __init__(self):
 
173
        self._safe_utf8 = osutils.safe_utf8
 
174
        self._directory = _directory
 
175
        self._chardev = _chardev
 
176
        self._block = _block
 
177
        self._file = _file
 
178
        self._fifo = _fifo
 
179
        self._symlink = _symlink
 
180
        self._socket = _socket
 
181
        self._unknown = _unknown
 
182
 
177
183
    def kind_from_mode(self, int mode):
178
184
        """Get the kind of a path from a mode status."""
179
185
        return self._kind_from_mode(mode)
181
187
    cdef _kind_from_mode(self, int mode):
182
188
        # Files and directories are the most common - check them first.
183
189
        if S_ISREG(mode):
184
 
            return _file
 
190
            return self._file
185
191
        if S_ISDIR(mode):
186
 
            return _directory
 
192
            return self._directory
187
193
        if S_ISCHR(mode):
188
 
            return _chardev
 
194
            return self._chardev
189
195
        if S_ISBLK(mode):
190
 
            return _block
 
196
            return self._block
191
197
        if S_ISLNK(mode):
192
 
            return _symlink
 
198
            return self._symlink
193
199
        if S_ISFIFO(mode):
194
 
            return _fifo
 
200
            return self._fifo
195
201
        if S_ISSOCK(mode):
196
 
            return _socket
197
 
        return _unknown
 
202
            return self._socket
 
203
        return self._unknown
198
204
 
199
205
    def top_prefix_to_starting_dir(self, top, prefix=""):
200
206
        """See DirReader.top_prefix_to_starting_dir."""
201
 
        return (_safe_utf8(prefix), None, None, None, _safe_utf8(top))
 
207
        return (self._safe_utf8(prefix), None, None, None,
 
208
            self._safe_utf8(top))
202
209
 
203
210
    def read_dir(self, prefix, top):
204
211
        """Read a single directory from a utf8 file system.
220
227
        cdef object name
221
228
        cdef PyObject * new_val_obj
222
229
 
223
 
        if PyBytes_Size(prefix):
224
 
            relprefix = prefix + b'/'
 
230
        if PyString_Size(prefix):
 
231
            relprefix = prefix + '/'
225
232
        else:
226
 
            relprefix = b''
227
 
        top_slash = top + b'/'
 
233
            relprefix = ''
 
234
        top_slash = top + '/'
228
235
 
229
236
        # read_dir supplies in should-stat order.
230
237
        # for _, name in sorted(_listdir(top)):
240
247
            # direct concat - faster than operator +.
241
248
            new_val_obj = <PyObject *>relprefix
242
249
            Py_INCREF(relprefix)
243
 
            PyBytes_Concat(&new_val_obj, name)
 
250
            PyString_Concat(&new_val_obj, name)
244
251
            if NULL == new_val_obj:
245
 
                # PyBytes_Concat will have setup an exception, but how to get
 
252
                # PyString_Concat will have setup an exception, but how to get
246
253
                # at it?
247
254
                raise Exception("failed to strcat")
248
255
            PyTuple_SetItem_obj(atuple, 0, new_val_obj)
256
263
            # direct concat - faster than operator +.
257
264
            new_val_obj = <PyObject *>top_slash
258
265
            Py_INCREF(top_slash)
259
 
            PyBytes_Concat(&new_val_obj, name)
 
266
            PyString_Concat(&new_val_obj, name)
260
267
            if NULL == new_val_obj:
261
 
                # PyBytes_Concat will have setup an exception, but how to get
 
268
                # PyString_Concat will have setup an exception, but how to get
262
269
                # at it?
263
270
                raise Exception("failed to strcat")
264
271
            PyTuple_SetItem_obj(atuple, 4, new_val_obj)
292
299
 
293
300
    # Avoid chdir('') because it causes problems on Sun OS, and avoid this if
294
301
    # staying in .
295
 
    if path != b"" and path != b'.':
 
302
    if path != "" and path != '.':
296
303
        # we change into the requested directory before reading, and back at the
297
304
        # end, because that turns out to make the stat calls measurably faster than
298
305
        # passing full paths every time.
300
307
        if orig_dir_fd == -1:
301
308
            raise_os_error(errno, "open: ", ".")
302
309
        if -1 == chdir(path):
303
 
            # Ignore the return value, because we are already raising an
304
 
            # exception
305
 
            close(orig_dir_fd)
306
310
            raise_os_error(errno, "chdir: ", path)
307
311
    else:
308
312
        orig_dir_fd = -1
309
313
 
310
314
    try:
311
 
        the_dir = opendir(b".")
 
315
        the_dir = opendir(".")
312
316
        if NULL == the_dir:
313
317
            raise_os_error(errno, "opendir: ", path)
314
318
        try:
346
350
                    if stat_result != 0:
347
351
                        if errno != ENOENT:
348
352
                            raise_os_error(errno, "lstat: ",
349
 
                                path + b"/" + entry.d_name)
 
353
                                path + "/" + entry.d_name)
350
354
                        else:
351
355
                            # the file seems to have disappeared after being
352
356
                            # seen by readdir - perhaps a transient temporary