Mercurial > public > mercurial-scm > hg
annotate rust/hg-direct-ffi/src/ancestors.rs @ 43011:198b51d453fe
automation: use LSB_RELEASE instead of DEBIAN_VERSION
This should be more robust since I believe the minor version can
change mid release.
Differential Revision: https://phab.mercurial-scm.org/D6910
author | Gregory Szorc <gregory.szorc@gmail.com> |
---|---|
date | Sun, 29 Sep 2019 10:17:20 -0700 |
parents | 6a551a2dc666 |
children |
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; |
40862
54a60968f0aa
rust: look up HgRevlogIndex_GetParents() from symbol table
Yuya Nishihara <yuya@tcha.org>
parents:
40454
diff
changeset
|
19 |
54a60968f0aa
rust: look up HgRevlogIndex_GetParents() from symbol table
Yuya Nishihara <yuya@tcha.org>
parents:
40454
diff
changeset
|
20 extern "C" { |
54a60968f0aa
rust: look up HgRevlogIndex_GetParents() from symbol table
Yuya Nishihara <yuya@tcha.org>
parents:
40454
diff
changeset
|
21 fn HgRevlogIndex_GetParents( |
54a60968f0aa
rust: look up HgRevlogIndex_GetParents() from symbol table
Yuya Nishihara <yuya@tcha.org>
parents:
40454
diff
changeset
|
22 op: IndexPtr, |
54a60968f0aa
rust: look up HgRevlogIndex_GetParents() from symbol table
Yuya Nishihara <yuya@tcha.org>
parents:
40454
diff
changeset
|
23 rev: c_int, |
54a60968f0aa
rust: look up HgRevlogIndex_GetParents() from symbol table
Yuya Nishihara <yuya@tcha.org>
parents:
40454
diff
changeset
|
24 parents: *mut [c_int; 2], |
54a60968f0aa
rust: look up HgRevlogIndex_GetParents() from symbol table
Yuya Nishihara <yuya@tcha.org>
parents:
40454
diff
changeset
|
25 ) -> c_int; |
54a60968f0aa
rust: look up HgRevlogIndex_GetParents() from symbol table
Yuya Nishihara <yuya@tcha.org>
parents:
40454
diff
changeset
|
26 } |
40272
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
27 |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
28 /// 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
|
29 /// |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
30 /// 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
|
31 /// - the C index object (`index` member) |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
32 /// - the `index_get_parents()` function (`parents` member) |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
33 pub struct Index { |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
34 index: IndexPtr, |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
35 } |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
36 |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
37 impl Index { |
40862
54a60968f0aa
rust: look up HgRevlogIndex_GetParents() from symbol table
Yuya Nishihara <yuya@tcha.org>
parents:
40454
diff
changeset
|
38 pub fn new(index: IndexPtr) -> Self { |
42819 | 39 Index { index: index } |
40272
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 |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
43 impl Graph for Index { |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
44 /// wrap a call to the C extern parents function |
40933
18513d6ef7d4
rust: changed Graph.parents to return [Revision; 2]
Georges Racinet <gracinet@anybox.fr>
parents:
40863
diff
changeset
|
45 fn parents(&self, rev: Revision) -> Result<[Revision; 2], GraphError> { |
40272
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
46 let mut res: [c_int; 2] = [0; 2]; |
42819 | 47 let code = unsafe { |
48 HgRevlogIndex_GetParents( | |
49 self.index, | |
50 rev, | |
51 &mut res as *mut [c_int; 2], | |
52 ) | |
53 }; | |
40272
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
54 match code { |
40933
18513d6ef7d4
rust: changed Graph.parents to return [Revision; 2]
Georges Racinet <gracinet@anybox.fr>
parents:
40863
diff
changeset
|
55 0 => Ok(res), |
40272
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
56 _ => Err(GraphError::ParentOutOfRange(rev)), |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
57 } |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
58 } |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
59 } |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
60 |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
61 /// Wrapping of AncestorsIterator<Index> constructor, for C callers. |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
62 /// |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
63 /// Besides `initrevs`, `stoprev` and `inclusive`, that are converted |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
64 /// 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
|
65 #[no_mangle] |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
66 pub extern "C" fn rustlazyancestors_init( |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
67 index: IndexPtr, |
40454
a91a2837150b
rust: fix signature of rustlazyancestors_init() function
Yuya Nishihara <yuya@tcha.org>
parents:
40300
diff
changeset
|
68 initrevslen: ssize_t, |
40272
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
69 initrevs: *mut c_long, |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
70 stoprev: c_long, |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
71 inclusive: c_int, |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
72 ) -> *mut AncestorsIterator<Index> { |
40454
a91a2837150b
rust: fix signature of rustlazyancestors_init() function
Yuya Nishihara <yuya@tcha.org>
parents:
40300
diff
changeset
|
73 assert!(initrevslen >= 0); |
40272
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
74 unsafe { |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
75 raw_init( |
40862
54a60968f0aa
rust: look up HgRevlogIndex_GetParents() from symbol table
Yuya Nishihara <yuya@tcha.org>
parents:
40454
diff
changeset
|
76 Index::new(index), |
40454
a91a2837150b
rust: fix signature of rustlazyancestors_init() function
Yuya Nishihara <yuya@tcha.org>
parents:
40300
diff
changeset
|
77 initrevslen as usize, |
40272
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
78 initrevs, |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
79 stoprev, |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
80 inclusive, |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
81 ) |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
82 } |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
83 } |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
84 |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
85 /// Testable (for any Graph) version of rustlazyancestors_init |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
86 #[inline] |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
87 unsafe fn raw_init<G: Graph>( |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
88 graph: G, |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
89 initrevslen: usize, |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
90 initrevs: *mut c_long, |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
91 stoprev: c_long, |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
92 inclusive: c_int, |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
93 ) -> *mut AncestorsIterator<G> { |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
94 let inclb = match inclusive { |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
95 0 => false, |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
96 1 => true, |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
97 _ => { |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
98 return null_mut(); |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
99 } |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
100 }; |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
101 |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
102 let slice = slice::from_raw_parts(initrevs, initrevslen); |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
103 |
42819 | 104 Box::into_raw(Box::new( |
105 match AncestorsIterator::new( | |
106 graph, | |
107 slice.into_iter().map(|&r| r as Revision), | |
108 stoprev as Revision, | |
109 inclb, | |
110 ) { | |
111 Ok(it) => it, | |
112 Err(_) => { | |
113 return null_mut(); | |
114 } | |
115 }, | |
116 )) | |
40272
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 |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
119 /// Deallocator to be called from C code |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
120 #[no_mangle] |
42819 | 121 pub extern "C" fn rustlazyancestors_drop( |
122 raw_iter: *mut AncestorsIterator<Index>, | |
123 ) { | |
40272
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
124 raw_drop(raw_iter); |
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 |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
127 /// Testable (for any Graph) version of rustlazayancestors_drop |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
128 #[inline] |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
129 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
|
130 unsafe { |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
131 Box::from_raw(raw_iter); |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
132 } |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
133 } |
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 /// Iteration main method to be called from C code |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
136 /// |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
137 /// We convert the end of iteration into NULL_REVISION, |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
138 /// 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
|
139 /// iteration |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
140 #[no_mangle] |
42819 | 141 pub extern "C" fn rustlazyancestors_next( |
142 raw: *mut AncestorsIterator<Index>, | |
143 ) -> c_long { | |
40272
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
144 raw_next(raw) |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
145 } |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
146 |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
147 /// Testable (for any Graph) version of rustlazayancestors_next |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
148 #[inline] |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
149 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
|
150 let as_ref = unsafe { &mut *raw }; |
40863
443eb4bc41af
rust: propagate error of index_get_parents() properly
Yuya Nishihara <yuya@tcha.org>
parents:
40862
diff
changeset
|
151 let rev = match as_ref.next() { |
443eb4bc41af
rust: propagate error of index_get_parents() properly
Yuya Nishihara <yuya@tcha.org>
parents:
40862
diff
changeset
|
152 Some(Ok(rev)) => rev, |
443eb4bc41af
rust: propagate error of index_get_parents() properly
Yuya Nishihara <yuya@tcha.org>
parents:
40862
diff
changeset
|
153 Some(Err(_)) | None => NULL_REVISION, |
443eb4bc41af
rust: propagate error of index_get_parents() properly
Yuya Nishihara <yuya@tcha.org>
parents:
40862
diff
changeset
|
154 }; |
443eb4bc41af
rust: propagate error of index_get_parents() properly
Yuya Nishihara <yuya@tcha.org>
parents:
40862
diff
changeset
|
155 rev as c_long |
40272
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
156 } |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
157 |
40300
72b94f946e90
rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents:
40272
diff
changeset
|
158 #[no_mangle] |
72b94f946e90
rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents:
40272
diff
changeset
|
159 pub extern "C" fn rustlazyancestors_contains( |
72b94f946e90
rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents:
40272
diff
changeset
|
160 raw: *mut AncestorsIterator<Index>, |
72b94f946e90
rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents:
40272
diff
changeset
|
161 target: c_long, |
72b94f946e90
rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents:
40272
diff
changeset
|
162 ) -> c_int { |
72b94f946e90
rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents:
40272
diff
changeset
|
163 raw_contains(raw, target) |
72b94f946e90
rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents:
40272
diff
changeset
|
164 } |
72b94f946e90
rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents:
40272
diff
changeset
|
165 |
72b94f946e90
rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents:
40272
diff
changeset
|
166 /// Testable (for any Graph) version of rustlazayancestors_next |
72b94f946e90
rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents:
40272
diff
changeset
|
167 #[inline] |
72b94f946e90
rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents:
40272
diff
changeset
|
168 fn raw_contains<G: Graph>( |
72b94f946e90
rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents:
40272
diff
changeset
|
169 raw: *mut AncestorsIterator<G>, |
72b94f946e90
rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents:
40272
diff
changeset
|
170 target: c_long, |
72b94f946e90
rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents:
40272
diff
changeset
|
171 ) -> c_int { |
72b94f946e90
rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents:
40272
diff
changeset
|
172 let as_ref = unsafe { &mut *raw }; |
40863
443eb4bc41af
rust: propagate error of index_get_parents() properly
Yuya Nishihara <yuya@tcha.org>
parents:
40862
diff
changeset
|
173 match as_ref.contains(target as Revision) { |
443eb4bc41af
rust: propagate error of index_get_parents() properly
Yuya Nishihara <yuya@tcha.org>
parents:
40862
diff
changeset
|
174 Ok(r) => r as c_int, |
443eb4bc41af
rust: propagate error of index_get_parents() properly
Yuya Nishihara <yuya@tcha.org>
parents:
40862
diff
changeset
|
175 Err(_) => -1, |
40300
72b94f946e90
rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents:
40272
diff
changeset
|
176 } |
72b94f946e90
rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents:
40272
diff
changeset
|
177 } |
72b94f946e90
rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents:
40272
diff
changeset
|
178 |
40272
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
179 #[cfg(test)] |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
180 mod tests { |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
181 use super::*; |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
182 use std::thread; |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
183 |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
184 #[derive(Clone, Debug)] |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
185 struct Stub; |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
186 |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
187 impl Graph for Stub { |
40933
18513d6ef7d4
rust: changed Graph.parents to return [Revision; 2]
Georges Racinet <gracinet@anybox.fr>
parents:
40863
diff
changeset
|
188 fn parents(&self, r: Revision) -> Result<[Revision; 2], GraphError> { |
40272
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
189 match r { |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
190 25 => Err(GraphError::ParentOutOfRange(25)), |
40933
18513d6ef7d4
rust: changed Graph.parents to return [Revision; 2]
Georges Racinet <gracinet@anybox.fr>
parents:
40863
diff
changeset
|
191 _ => Ok([1, 2]), |
40272
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
192 } |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
193 } |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
194 } |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
195 |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
196 /// Helper for test_init_next() |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
197 fn stub_raw_init( |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
198 initrevslen: usize, |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
199 initrevs: usize, |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
200 stoprev: c_long, |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
201 inclusive: c_int, |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
202 ) -> usize { |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
203 unsafe { |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
204 raw_init( |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
205 Stub, |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
206 initrevslen, |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
207 initrevs as *mut c_long, |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
208 stoprev, |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
209 inclusive, |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
210 ) as usize |
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 fn stub_raw_init_from_vec( |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
215 mut initrevs: Vec<c_long>, |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
216 stoprev: c_long, |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
217 inclusive: c_int, |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
218 ) -> *mut AncestorsIterator<Stub> { |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
219 unsafe { |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
220 raw_init( |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
221 Stub, |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
222 initrevs.len(), |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
223 initrevs.as_mut_ptr(), |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
224 stoprev, |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
225 inclusive, |
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 } |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
228 } |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
229 |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
230 #[test] |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
231 // 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
|
232 // and try to use it afterwards |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
233 // 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
|
234 // 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
|
235 fn test_init_next() { |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
236 let mut initrevs: Vec<c_long> = vec![11, 13]; |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
237 let initrevs_len = initrevs.len(); |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
238 let initrevs_ptr = initrevs.as_mut_ptr() as usize; |
42819 | 239 let handler = thread::spawn(move || { |
240 stub_raw_init(initrevs_len, initrevs_ptr, 0, 1) | |
241 }); | |
40272
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
242 let raw = handler.join().unwrap() as *mut AncestorsIterator<Stub>; |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
243 |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
244 assert_eq!(raw_next(raw), 13); |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
245 assert_eq!(raw_next(raw), 11); |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
246 assert_eq!(raw_next(raw), 2); |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
247 assert_eq!(raw_next(raw), 1); |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
248 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
|
249 raw_drop(raw); |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
250 } |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
251 |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
252 #[test] |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
253 fn test_init_wrong_bool() { |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
254 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
|
255 } |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
256 |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
257 #[test] |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
258 fn test_empty() { |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
259 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
|
260 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
|
261 raw_drop(raw); |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
262 } |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
263 |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
264 #[test] |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
265 fn test_init_err_out_of_range() { |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
266 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
|
267 } |
40300
72b94f946e90
rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents:
40272
diff
changeset
|
268 |
72b94f946e90
rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents:
40272
diff
changeset
|
269 #[test] |
72b94f946e90
rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents:
40272
diff
changeset
|
270 fn test_contains() { |
72b94f946e90
rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents:
40272
diff
changeset
|
271 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
|
272 assert_eq!(raw_contains(raw, 5), 1); |
72b94f946e90
rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents:
40272
diff
changeset
|
273 assert_eq!(raw_contains(raw, 2), 1); |
72b94f946e90
rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents:
40272
diff
changeset
|
274 } |
72b94f946e90
rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents:
40272
diff
changeset
|
275 |
72b94f946e90
rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents:
40272
diff
changeset
|
276 #[test] |
72b94f946e90
rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents:
40272
diff
changeset
|
277 fn test_contains_exclusive() { |
72b94f946e90
rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents:
40272
diff
changeset
|
278 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
|
279 assert_eq!(raw_contains(raw, 5), 0); |
72b94f946e90
rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents:
40272
diff
changeset
|
280 assert_eq!(raw_contains(raw, 2), 1); |
72b94f946e90
rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents:
40272
diff
changeset
|
281 } |
40272
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
282 } |