annotate rust/hg-direct-ffi/src/ancestors.rs @ 40450:41f0529b5112 stable

commandserver: get around ETIMEDOUT raised by selectors2 selector.select() should exits with an empty event list on timed out, but selectors2 raises OSError if timeout expires while recovering from EINTR. Spotted while debugging new chg feature.
author Yuya Nishihara <yuya@tcha.org>
date Mon, 03 Dec 2018 21:45:15 +0900
parents a91a2837150b
children 54a60968f0aa
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
40272
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
1 // Copyright 2018 Georges Racinet <gracinet@anybox.fr>
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
2 //
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
3 // This software may be used and distributed according to the terms of the
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
4 // GNU General Public License version 2 or any later version.
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
5
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
6 //! Bindings for CPython extension code
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
7 //!
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
8 //! This exposes methods to build and use a `rustlazyancestors` iterator
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
9 //! from C code, using an index and its parents function that are passed
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
10 //! from the caller at instantiation.
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
11
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
12 use hg::AncestorsIterator;
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
13 use hg::{Graph, GraphError, Revision, NULL_REVISION};
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
14 use libc::{c_int, c_long, c_void, ssize_t};
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
15 use std::ptr::null_mut;
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
16 use std::slice;
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
17
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
18 type IndexPtr = *mut c_void;
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
19 type IndexParentsFn =
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
20 unsafe extern "C" fn(index: IndexPtr, rev: ssize_t, ps: *mut [c_int; 2], max_rev: c_int)
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
21 -> c_int;
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
22
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
23 /// A Graph backed up by objects and functions from revlog.c
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
24 ///
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
25 /// This implementation of the Graph trait, relies on (pointers to)
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
26 /// - the C index object (`index` member)
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
27 /// - the `index_get_parents()` function (`parents` member)
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
28 pub struct Index {
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
29 index: IndexPtr,
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
30 parents: IndexParentsFn,
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
31 }
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
32
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
33 impl Index {
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
34 pub fn new(index: IndexPtr, parents: IndexParentsFn) -> Self {
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
35 Index {
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
36 index: index,
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
37 parents: parents,
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
38 }
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
39 }
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
40 }
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
41
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
42 impl Graph for Index {
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
43 /// wrap a call to the C extern parents function
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
44 fn parents(&self, rev: Revision) -> Result<(Revision, Revision), GraphError> {
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
45 let mut res: [c_int; 2] = [0; 2];
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
46 let code =
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
47 unsafe { (self.parents)(self.index, rev as ssize_t, &mut res as *mut [c_int; 2], rev) };
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
48 match code {
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
49 0 => Ok((res[0], res[1])),
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
50 _ => Err(GraphError::ParentOutOfRange(rev)),
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
51 }
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
52 }
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
53 }
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
54
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
55 /// Wrapping of AncestorsIterator<Index> constructor, for C callers.
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
56 ///
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
57 /// Besides `initrevs`, `stoprev` and `inclusive`, that are converted
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
58 /// we receive the index and the parents function as pointers
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
59 #[no_mangle]
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
60 pub extern "C" fn rustlazyancestors_init(
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
61 index: IndexPtr,
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
62 parents: IndexParentsFn,
40428
a91a2837150b rust: fix signature of rustlazyancestors_init() function
Yuya Nishihara <yuya@tcha.org>
parents: 40300
diff changeset
63 initrevslen: ssize_t,
40272
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
64 initrevs: *mut c_long,
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
65 stoprev: c_long,
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
66 inclusive: c_int,
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
67 ) -> *mut AncestorsIterator<Index> {
40428
a91a2837150b rust: fix signature of rustlazyancestors_init() function
Yuya Nishihara <yuya@tcha.org>
parents: 40300
diff changeset
68 assert!(initrevslen >= 0);
40272
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
69 unsafe {
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
70 raw_init(
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
71 Index::new(index, parents),
40428
a91a2837150b rust: fix signature of rustlazyancestors_init() function
Yuya Nishihara <yuya@tcha.org>
parents: 40300
diff changeset
72 initrevslen as usize,
40272
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
73 initrevs,
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
74 stoprev,
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
75 inclusive,
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
76 )
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
77 }
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
78 }
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
79
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
80 /// Testable (for any Graph) version of rustlazyancestors_init
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
81 #[inline]
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
82 unsafe fn raw_init<G: Graph>(
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
83 graph: G,
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
84 initrevslen: usize,
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
85 initrevs: *mut c_long,
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
86 stoprev: c_long,
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
87 inclusive: c_int,
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
88 ) -> *mut AncestorsIterator<G> {
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
89 let inclb = match inclusive {
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
90 0 => false,
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
91 1 => true,
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
92 _ => {
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
93 return null_mut();
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
94 }
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
95 };
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
96
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
97 let slice = slice::from_raw_parts(initrevs, initrevslen);
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
98
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
99 Box::into_raw(Box::new(match AncestorsIterator::new(
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
100 graph,
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
101 slice.into_iter().map(|&r| r as Revision),
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
102 stoprev as Revision,
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
103 inclb,
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
104 ) {
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
105 Ok(it) => it,
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
106 Err(_) => {
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
107 return null_mut();
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
108 }
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
109 }))
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
110 }
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
111
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
112 /// Deallocator to be called from C code
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
113 #[no_mangle]
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
114 pub extern "C" fn rustlazyancestors_drop(raw_iter: *mut AncestorsIterator<Index>) {
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
115 raw_drop(raw_iter);
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
116 }
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
117
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
118 /// Testable (for any Graph) version of rustlazayancestors_drop
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
119 #[inline]
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
120 fn raw_drop<G: Graph>(raw_iter: *mut AncestorsIterator<G>) {
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
121 unsafe {
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
122 Box::from_raw(raw_iter);
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
123 }
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
124 }
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
125
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
126 /// Iteration main method to be called from C code
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
127 ///
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
128 /// We convert the end of iteration into NULL_REVISION,
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
129 /// it will be up to the C wrapper to convert that back into a Python end of
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
130 /// iteration
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
131 #[no_mangle]
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
132 pub extern "C" fn rustlazyancestors_next(raw: *mut AncestorsIterator<Index>) -> c_long {
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
133 raw_next(raw)
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
134 }
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
135
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
136 /// Testable (for any Graph) version of rustlazayancestors_next
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
137 #[inline]
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
138 fn raw_next<G: Graph>(raw: *mut AncestorsIterator<G>) -> c_long {
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
139 let as_ref = unsafe { &mut *raw };
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
140 as_ref.next().unwrap_or(NULL_REVISION) as c_long
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
141 }
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
142
40300
72b94f946e90 rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents: 40272
diff changeset
143 #[no_mangle]
72b94f946e90 rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents: 40272
diff changeset
144 pub extern "C" fn rustlazyancestors_contains(
72b94f946e90 rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents: 40272
diff changeset
145 raw: *mut AncestorsIterator<Index>,
72b94f946e90 rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents: 40272
diff changeset
146 target: c_long,
72b94f946e90 rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents: 40272
diff changeset
147 ) -> c_int {
72b94f946e90 rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents: 40272
diff changeset
148 raw_contains(raw, target)
72b94f946e90 rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents: 40272
diff changeset
149 }
72b94f946e90 rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents: 40272
diff changeset
150
72b94f946e90 rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents: 40272
diff changeset
151 /// Testable (for any Graph) version of rustlazayancestors_next
72b94f946e90 rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents: 40272
diff changeset
152 #[inline]
72b94f946e90 rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents: 40272
diff changeset
153 fn raw_contains<G: Graph>(
72b94f946e90 rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents: 40272
diff changeset
154 raw: *mut AncestorsIterator<G>,
72b94f946e90 rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents: 40272
diff changeset
155 target: c_long,
72b94f946e90 rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents: 40272
diff changeset
156 ) -> c_int {
72b94f946e90 rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents: 40272
diff changeset
157 let as_ref = unsafe { &mut *raw };
72b94f946e90 rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents: 40272
diff changeset
158 if as_ref.contains(target as Revision) {
72b94f946e90 rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents: 40272
diff changeset
159 return 1;
72b94f946e90 rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents: 40272
diff changeset
160 }
72b94f946e90 rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents: 40272
diff changeset
161 0
72b94f946e90 rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents: 40272
diff changeset
162 }
72b94f946e90 rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents: 40272
diff changeset
163
40272
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
164 #[cfg(test)]
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
165 mod tests {
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
166 use super::*;
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
167 use std::thread;
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
168
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
169 #[derive(Clone, Debug)]
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
170 struct Stub;
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
171
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
172 impl Graph for Stub {
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
173 fn parents(&self, r: Revision) -> Result<(Revision, Revision), GraphError> {
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
174 match r {
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
175 25 => Err(GraphError::ParentOutOfRange(25)),
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
176 _ => Ok((1, 2)),
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
177 }
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
178 }
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
179 }
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
180
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
181 /// Helper for test_init_next()
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
182 fn stub_raw_init(
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
183 initrevslen: usize,
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
184 initrevs: usize,
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
185 stoprev: c_long,
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
186 inclusive: c_int,
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
187 ) -> usize {
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
188 unsafe {
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
189 raw_init(
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
190 Stub,
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
191 initrevslen,
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
192 initrevs as *mut c_long,
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
193 stoprev,
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
194 inclusive,
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
195 ) as usize
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
196 }
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
197 }
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
198
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
199 fn stub_raw_init_from_vec(
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
200 mut initrevs: Vec<c_long>,
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
201 stoprev: c_long,
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
202 inclusive: c_int,
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
203 ) -> *mut AncestorsIterator<Stub> {
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
204 unsafe {
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
205 raw_init(
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
206 Stub,
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
207 initrevs.len(),
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
208 initrevs.as_mut_ptr(),
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
209 stoprev,
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
210 inclusive,
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
211 )
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
212 }
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
213 }
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
214
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
215 #[test]
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
216 // Test what happens when we init an Iterator as with the exposed C ABI
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
217 // and try to use it afterwards
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
218 // We spawn new threads, in order to make memory consistency harder
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
219 // but this forces us to convert the pointers into shareable usizes.
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
220 fn test_init_next() {
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
221 let mut initrevs: Vec<c_long> = vec![11, 13];
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
222 let initrevs_len = initrevs.len();
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
223 let initrevs_ptr = initrevs.as_mut_ptr() as usize;
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
224 let handler = thread::spawn(move || stub_raw_init(initrevs_len, initrevs_ptr, 0, 1));
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
225 let raw = handler.join().unwrap() as *mut AncestorsIterator<Stub>;
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
226
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
227 assert_eq!(raw_next(raw), 13);
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
228 assert_eq!(raw_next(raw), 11);
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
229 assert_eq!(raw_next(raw), 2);
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
230 assert_eq!(raw_next(raw), 1);
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
231 assert_eq!(raw_next(raw), NULL_REVISION as c_long);
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
232 raw_drop(raw);
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
233 }
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
234
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
235 #[test]
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
236 fn test_init_wrong_bool() {
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
237 assert_eq!(stub_raw_init_from_vec(vec![11, 13], 0, 2), null_mut());
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
238 }
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
239
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
240 #[test]
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
241 fn test_empty() {
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
242 let raw = stub_raw_init_from_vec(vec![], 0, 1);
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
243 assert_eq!(raw_next(raw), NULL_REVISION as c_long);
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
244 raw_drop(raw);
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
245 }
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
246
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
247 #[test]
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
248 fn test_init_err_out_of_range() {
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
249 assert!(stub_raw_init_from_vec(vec![25], 0, 0).is_null());
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
250 }
40300
72b94f946e90 rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents: 40272
diff changeset
251
72b94f946e90 rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents: 40272
diff changeset
252 #[test]
72b94f946e90 rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents: 40272
diff changeset
253 fn test_contains() {
72b94f946e90 rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents: 40272
diff changeset
254 let raw = stub_raw_init_from_vec(vec![5, 6], 0, 1);
72b94f946e90 rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents: 40272
diff changeset
255 assert_eq!(raw_contains(raw, 5), 1);
72b94f946e90 rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents: 40272
diff changeset
256 assert_eq!(raw_contains(raw, 2), 1);
72b94f946e90 rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents: 40272
diff changeset
257 }
72b94f946e90 rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents: 40272
diff changeset
258
72b94f946e90 rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents: 40272
diff changeset
259 #[test]
72b94f946e90 rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents: 40272
diff changeset
260 fn test_contains_exclusive() {
72b94f946e90 rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents: 40272
diff changeset
261 let raw = stub_raw_init_from_vec(vec![5, 6], 0, 0);
72b94f946e90 rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents: 40272
diff changeset
262 assert_eq!(raw_contains(raw, 5), 0);
72b94f946e90 rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents: 40272
diff changeset
263 assert_eq!(raw_contains(raw, 2), 1);
72b94f946e90 rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents: 40272
diff changeset
264 }
40272
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
265 }