~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/_dirstate_helpers_pyx.pyx

  • Committer: Brian de Alwis
  • Date: 2009-09-24 19:51:37 UTC
  • mto: (4715.4.1 integration)
  • mto: This revision was merged to the branch mainline in revision 4727.
  • Revision ID: bsd@acm.org-20090924195137-wubyeqv515mkigi8
Introduce new mailer to support MacOS X's Mail.app

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2007-2010 Canonical Ltd
 
1
# Copyright (C) 2007, 2008 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
118
118
    # ??? memrchr is a GNU extension :(
119
119
    # void *memrchr(void *s, int c, size_t len)
120
120
 
121
 
# cimport all of the definitions we will need to access
122
 
from _static_tuple_c cimport import_static_tuple_c, StaticTuple, \
123
 
    StaticTuple_New, StaticTuple_SET_ITEM
124
 
 
125
 
import_static_tuple_c()
126
 
 
127
 
cdef void* _my_memrchr(void *s, int c, size_t n): # cannot_raise
 
121
 
 
122
cdef void* _my_memrchr(void *s, int c, size_t n):
128
123
    # memrchr seems to be a GNU extension, so we have to implement it ourselves
129
124
    cdef char *pos
130
125
    cdef char *start
161
156
        return None
162
157
    return <char*>found - <char*>_s
163
158
 
164
 
 
165
159
cdef object safe_string_from_size(char *s, Py_ssize_t size):
166
160
    if size < 0:
 
161
        # XXX: On 64-bit machines the <int> cast causes a C compiler warning.
167
162
        raise AssertionError(
168
 
            'tried to create a string with an invalid size: %d'
169
 
            % (size))
 
163
            'tried to create a string with an invalid size: %d @0x%x'
 
164
            % (size, <int>s))
170
165
    return PyString_FromStringAndSize(s, size)
171
166
 
172
167
 
173
 
cdef int _is_aligned(void *ptr): # cannot_raise
 
168
cdef int _is_aligned(void *ptr):
174
169
    """Is this pointer aligned to an integer size offset?
175
170
 
176
171
    :return: 1 if this pointer is aligned, 0 otherwise.
178
173
    return ((<intptr_t>ptr) & ((sizeof(int))-1)) == 0
179
174
 
180
175
 
181
 
cdef int _cmp_by_dirs(char *path1, int size1, char *path2, int size2): # cannot_raise
 
176
cdef int _cmp_by_dirs(char *path1, int size1, char *path2, int size2):
182
177
    cdef unsigned char *cur1
183
178
    cdef unsigned char *cur2
184
179
    cdef unsigned char *end1
300
295
 
301
296
 
302
297
cdef int _cmp_path_by_dirblock_intern(char *path1, int path1_len,
303
 
                                      char *path2, int path2_len): # cannot_raise
 
298
                                      char *path2, int path2_len):
304
299
    """Compare two paths by what directory they are in.
305
300
 
306
301
    see ``_cmp_path_by_dirblock`` for details.
615
610
        :param new_block: This is to let the caller know that it needs to
616
611
            create a new directory block to store the next entry.
617
612
        """
618
 
        cdef StaticTuple path_name_file_id_key
619
 
        cdef StaticTuple tmp
 
613
        cdef object path_name_file_id_key
620
614
        cdef char *entry_size_cstr
621
615
        cdef unsigned long int entry_size
622
616
        cdef char* executable_cstr
656
650
        # Build up the key that will be used.
657
651
        # By using <object>(void *) Pyrex will automatically handle the
658
652
        # Py_INCREF that we need.
659
 
        cur_dirname = <object>p_current_dirname[0]
660
 
        # Use StaticTuple_New to pre-allocate, rather than creating a regular
661
 
        # tuple and passing it to the StaticTuple constructor.
662
 
        # path_name_file_id_key = StaticTuple(<object>p_current_dirname[0],
663
 
        #                          self.get_next_str(),
664
 
        #                          self.get_next_str(),
665
 
        #                         )
666
 
        tmp = StaticTuple_New(3)
667
 
        Py_INCREF(cur_dirname); StaticTuple_SET_ITEM(tmp, 0, cur_dirname)
668
 
        cur_basename = self.get_next_str()
669
 
        cur_file_id = self.get_next_str()
670
 
        Py_INCREF(cur_basename); StaticTuple_SET_ITEM(tmp, 1, cur_basename)
671
 
        Py_INCREF(cur_file_id); StaticTuple_SET_ITEM(tmp, 2, cur_file_id)
672
 
        path_name_file_id_key = tmp
 
653
        path_name_file_id_key = (<object>p_current_dirname[0],
 
654
                                 self.get_next_str(),
 
655
                                 self.get_next_str(),
 
656
                                )
673
657
 
674
658
        # Parse all of the per-tree information. current has the information in
675
659
        # the same location as parent trees. The only difference is that 'info'
693
677
            executable_cstr = self.get_next(&cur_size)
694
678
            is_executable = (executable_cstr[0] == c'y')
695
679
            info = self.get_next_str()
696
 
            # TODO: If we want to use StaticTuple_New here we need to be pretty
697
 
            #       careful. We are relying on a bit of Pyrex
698
 
            #       automatic-conversion from 'int' to PyInt, and that doesn't
699
 
            #       play well with the StaticTuple_SET_ITEM macro.
700
 
            #       Timing doesn't (yet) show a worthwile improvement in speed
701
 
            #       versus complexity and maintainability.
702
 
            # tmp = StaticTuple_New(5)
703
 
            # Py_INCREF(minikind); StaticTuple_SET_ITEM(tmp, 0, minikind)
704
 
            # Py_INCREF(fingerprint); StaticTuple_SET_ITEM(tmp, 1, fingerprint)
705
 
            # Py_INCREF(entry_size); StaticTuple_SET_ITEM(tmp, 2, entry_size)
706
 
            # Py_INCREF(is_executable); StaticTuple_SET_ITEM(tmp, 3, is_executable)
707
 
            # Py_INCREF(info); StaticTuple_SET_ITEM(tmp, 4, info)
708
 
            # PyList_Append(trees, tmp)
709
 
            PyList_Append(trees, StaticTuple(
 
680
            PyList_Append(trees, (
710
681
                minikind,     # minikind
711
682
                fingerprint,  # fingerprint
712
683
                entry_size,   # size
797
768
    state._dirblock_state = DirState.IN_MEMORY_UNMODIFIED
798
769
 
799
770
 
800
 
cdef int minikind_from_mode(int mode): # cannot_raise
 
771
cdef int minikind_from_mode(int mode):
801
772
    # in order of frequency:
802
773
    if S_ISREG(mode):
803
774
        return c"f"
944
915
    return link_or_sha1
945
916
 
946
917
 
947
 
# TODO: Do we want to worry about exceptions here?
948
 
cdef char _minikind_from_string(object string) except? -1:
 
918
cdef char _minikind_from_string(object string):
949
919
    """Convert a python string to a char."""
950
920
    return PyString_AsString(string)[0]
951
921
 
983
953
    raise KeyError(PyString_FromStringAndSize(_minikind, 1))
984
954
 
985
955
 
986
 
cdef int _versioned_minikind(char minikind): # cannot_raise
 
956
cdef int _versioned_minikind(char minikind):
987
957
    """Return non-zero if minikind is in fltd"""
988
958
    return (minikind == c'f' or
989
959
            minikind == c'd' or
1232
1202
                        content_change = 0
1233
1203
                    target_exec = False
1234
1204
                else:
1235
 
                    if path is None:
1236
 
                        path = self.pathjoin(old_dirname, old_basename)
1237
 
                    raise errors.BadFileKindError(path, path_info[2])
 
1205
                    raise Exception, "unknown kind %s" % path_info[2]
1238
1206
            if source_minikind == c'd':
1239
1207
                if path is None:
1240
1208
                    old_path = path = self.pathjoin(old_dirname, old_basename)
1248
1216
            else:
1249
1217
                try:
1250
1218
                    source_parent_id = self.old_dirname_to_file_id[old_dirname]
1251
 
                except KeyError, _:
 
1219
                except KeyError:
1252
1220
                    source_parent_entry = self.state._get_entry(self.source_index,
1253
1221
                                                           path_utf8=old_dirname)
1254
1222
                    source_parent_id = source_parent_entry[0][2]
1265
1233
            else:
1266
1234
                try:
1267
1235
                    target_parent_id = self.new_dirname_to_file_id[new_dirname]
1268
 
                except KeyError, _:
 
1236
                except KeyError:
1269
1237
                    # TODO: We don't always need to do the lookup, because the
1270
1238
                    #       parent entry will be the same as the source entry.
1271
1239
                    target_parent_entry = self.state._get_entry(self.target_index,
1403
1371
    def iter_changes(self):
1404
1372
        return self
1405
1373
 
1406
 
    cdef int _gather_result_for_consistency(self, result) except -1:
 
1374
    cdef void _gather_result_for_consistency(self, result):
1407
1375
        """Check a result we will yield to make sure we are consistent later.
1408
1376
        
1409
1377
        This gathers result's parents into a set to output later.
1411
1379
        :param result: A result tuple.
1412
1380
        """
1413
1381
        if not self.partial or not result[0]:
1414
 
            return 0
 
1382
            return
1415
1383
        self.seen_ids.add(result[0])
1416
1384
        new_path = result[1][1]
1417
1385
        if new_path:
1421
1389
            # Add the root directory which parent_directories does not
1422
1390
            # provide.
1423
1391
            self.search_specific_file_parents.add('')
1424
 
        return 0
1425
1392
 
1426
 
    cdef int _update_current_block(self) except -1:
 
1393
    cdef void _update_current_block(self):
1427
1394
        if (self.block_index < len(self.state._dirblocks) and
1428
1395
            osutils.is_inside(self.current_root, self.state._dirblocks[self.block_index][0])):
1429
1396
            self.current_block = self.state._dirblocks[self.block_index]
1432
1399
        else:
1433
1400
            self.current_block = None
1434
1401
            self.current_block_list = None
1435
 
        return 0
1436
1402
 
1437
1403
    def __next__(self):
1438
1404
        # Simple thunk to allow tail recursion without pyrex confusion
1507
1473
            # interface doesn't require it.
1508
1474
            try:
1509
1475
                self.current_root = self.search_specific_files.pop()
1510
 
            except KeyError, _:
 
1476
            except KeyError:
1511
1477
                raise StopIteration()
1512
1478
            self.searched_specific_files.add(self.current_root)
1513
1479
            # process the entries for this containing directory: the rest will be
1596
1562
                        #            and e.winerror == ERROR_DIRECTORY
1597
1563
                        try:
1598
1564
                            e_winerror = e.winerror
1599
 
                        except AttributeError, _:
 
1565
                        except AttributeError:
1600
1566
                            e_winerror = None
1601
1567
                        win_errors = (ERROR_DIRECTORY, ERROR_PATH_NOT_FOUND)
1602
1568
                        if (e.errno in win_errors or e_winerror in win_errors):
1685
1651
                    try:
1686
1652
                        self.current_dir_info = self.dir_iterator.next()
1687
1653
                        self.current_dir_list = self.current_dir_info[1]
1688
 
                    except StopIteration, _:
 
1654
                    except StopIteration:
1689
1655
                        self.current_dir_info = None
1690
1656
                else: #(dircmp > 0)
1691
1657
                    # We have a dirblock entry for this location, but there
1832
1798
                                and stat.S_IEXEC & current_path_info[3].st_mode)
1833
1799
                            try:
1834
1800
                                relpath_unicode = self.utf8_decode(current_path_info[0])[0]
1835
 
                            except UnicodeDecodeError, _:
 
1801
                            except UnicodeDecodeError:
1836
1802
                                raise errors.BadFilenameEncoding(
1837
1803
                                    current_path_info[0], osutils._fs_enc)
1838
1804
                            if changed is not None:
1880
1846
                try:
1881
1847
                    self.current_dir_info = self.dir_iterator.next()
1882
1848
                    self.current_dir_list = self.current_dir_info[1]
1883
 
                except StopIteration, _:
 
1849
                except StopIteration:
1884
1850
                    self.current_dir_info = None
1885
1851
 
1886
1852
    cdef object _next_consistent_entries(self):