Mercurial > public > mercurial-scm > hg-stable
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 |
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 } |