author | Gregory Szorc <gregory.szorc@gmail.com> |
Sat, 26 Jan 2019 13:58:58 -0800 | |
changeset 41432 | 0d226b2139df |
parent 40950 | 18513d6ef7d4 |
child 42829 | 6a551a2dc666 |
permissions | -rw-r--r-- |
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; |
40880
54a60968f0aa
rust: look up HgRevlogIndex_GetParents() from symbol table
Yuya Nishihara <yuya@tcha.org>
parents:
40428
diff
changeset
|
19 |
|
54a60968f0aa
rust: look up HgRevlogIndex_GetParents() from symbol table
Yuya Nishihara <yuya@tcha.org>
parents:
40428
diff
changeset
|
20 |
extern "C" { |
54a60968f0aa
rust: look up HgRevlogIndex_GetParents() from symbol table
Yuya Nishihara <yuya@tcha.org>
parents:
40428
diff
changeset
|
21 |
fn HgRevlogIndex_GetParents( |
54a60968f0aa
rust: look up HgRevlogIndex_GetParents() from symbol table
Yuya Nishihara <yuya@tcha.org>
parents:
40428
diff
changeset
|
22 |
op: IndexPtr, |
54a60968f0aa
rust: look up HgRevlogIndex_GetParents() from symbol table
Yuya Nishihara <yuya@tcha.org>
parents:
40428
diff
changeset
|
23 |
rev: c_int, |
54a60968f0aa
rust: look up HgRevlogIndex_GetParents() from symbol table
Yuya Nishihara <yuya@tcha.org>
parents:
40428
diff
changeset
|
24 |
parents: *mut [c_int; 2], |
54a60968f0aa
rust: look up HgRevlogIndex_GetParents() from symbol table
Yuya Nishihara <yuya@tcha.org>
parents:
40428
diff
changeset
|
25 |
) -> c_int; |
54a60968f0aa
rust: look up HgRevlogIndex_GetParents() from symbol table
Yuya Nishihara <yuya@tcha.org>
parents:
40428
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 { |
40880
54a60968f0aa
rust: look up HgRevlogIndex_GetParents() from symbol table
Yuya Nishihara <yuya@tcha.org>
parents:
40428
diff
changeset
|
38 |
pub fn new(index: IndexPtr) -> Self { |
40272
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
39 |
Index { |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
40 |
index: index, |
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 |
} |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
44 |
|
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
45 |
impl Graph for Index { |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
46 |
/// wrap a call to the C extern parents function |
40950
18513d6ef7d4
rust: changed Graph.parents to return [Revision; 2]
Georges Racinet <gracinet@anybox.fr>
parents:
40881
diff
changeset
|
47 |
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
|
48 |
let mut res: [c_int; 2] = [0; 2]; |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
49 |
let code = |
40880
54a60968f0aa
rust: look up HgRevlogIndex_GetParents() from symbol table
Yuya Nishihara <yuya@tcha.org>
parents:
40428
diff
changeset
|
50 |
unsafe { HgRevlogIndex_GetParents(self.index, rev, &mut res as *mut [c_int; 2]) }; |
40272
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
51 |
match code { |
40950
18513d6ef7d4
rust: changed Graph.parents to return [Revision; 2]
Georges Racinet <gracinet@anybox.fr>
parents:
40881
diff
changeset
|
52 |
0 => Ok(res), |
40272
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
53 |
_ => Err(GraphError::ParentOutOfRange(rev)), |
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 |
} |
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 |
|
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
58 |
/// Wrapping of AncestorsIterator<Index> constructor, for C callers. |
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 |
/// Besides `initrevs`, `stoprev` and `inclusive`, that are converted |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
61 |
/// 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
|
62 |
#[no_mangle] |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
63 |
pub extern "C" fn rustlazyancestors_init( |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
64 |
index: IndexPtr, |
40428
a91a2837150b
rust: fix signature of rustlazyancestors_init() function
Yuya Nishihara <yuya@tcha.org>
parents:
40300
diff
changeset
|
65 |
initrevslen: ssize_t, |
40272
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
66 |
initrevs: *mut c_long, |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
67 |
stoprev: c_long, |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
68 |
inclusive: c_int, |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
69 |
) -> *mut AncestorsIterator<Index> { |
40428
a91a2837150b
rust: fix signature of rustlazyancestors_init() function
Yuya Nishihara <yuya@tcha.org>
parents:
40300
diff
changeset
|
70 |
assert!(initrevslen >= 0); |
40272
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
71 |
unsafe { |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
72 |
raw_init( |
40880
54a60968f0aa
rust: look up HgRevlogIndex_GetParents() from symbol table
Yuya Nishihara <yuya@tcha.org>
parents:
40428
diff
changeset
|
73 |
Index::new(index), |
40428
a91a2837150b
rust: fix signature of rustlazyancestors_init() function
Yuya Nishihara <yuya@tcha.org>
parents:
40300
diff
changeset
|
74 |
initrevslen as usize, |
40272
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
75 |
initrevs, |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
76 |
stoprev, |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
77 |
inclusive, |
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 |
} |
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 |
/// Testable (for any Graph) version of rustlazyancestors_init |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
83 |
#[inline] |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
84 |
unsafe fn raw_init<G: Graph>( |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
85 |
graph: G, |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
86 |
initrevslen: usize, |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
87 |
initrevs: *mut c_long, |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
88 |
stoprev: c_long, |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
89 |
inclusive: c_int, |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
90 |
) -> *mut AncestorsIterator<G> { |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
91 |
let inclb = match inclusive { |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
92 |
0 => false, |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
93 |
1 => true, |
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 |
return null_mut(); |
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 |
}; |
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 |
let slice = slice::from_raw_parts(initrevs, initrevslen); |
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 |
Box::into_raw(Box::new(match AncestorsIterator::new( |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
102 |
graph, |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
103 |
slice.into_iter().map(|&r| r as Revision), |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
104 |
stoprev as Revision, |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
105 |
inclb, |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
106 |
) { |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
107 |
Ok(it) => it, |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
108 |
Err(_) => { |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
109 |
return null_mut(); |
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 |
} |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
113 |
|
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
114 |
/// Deallocator to be called from C code |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
115 |
#[no_mangle] |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
116 |
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
|
117 |
raw_drop(raw_iter); |
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 |
|
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
120 |
/// Testable (for any Graph) version of rustlazayancestors_drop |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
121 |
#[inline] |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
122 |
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
|
123 |
unsafe { |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
124 |
Box::from_raw(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 |
|
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
128 |
/// Iteration main method to be called from C code |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
129 |
/// |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
130 |
/// We convert the end of iteration into NULL_REVISION, |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
131 |
/// 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
|
132 |
/// iteration |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
133 |
#[no_mangle] |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
134 |
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
|
135 |
raw_next(raw) |
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 |
|
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
138 |
/// Testable (for any Graph) version of rustlazayancestors_next |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
139 |
#[inline] |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
140 |
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
|
141 |
let as_ref = unsafe { &mut *raw }; |
40881
443eb4bc41af
rust: propagate error of index_get_parents() properly
Yuya Nishihara <yuya@tcha.org>
parents:
40880
diff
changeset
|
142 |
let rev = match as_ref.next() { |
443eb4bc41af
rust: propagate error of index_get_parents() properly
Yuya Nishihara <yuya@tcha.org>
parents:
40880
diff
changeset
|
143 |
Some(Ok(rev)) => rev, |
443eb4bc41af
rust: propagate error of index_get_parents() properly
Yuya Nishihara <yuya@tcha.org>
parents:
40880
diff
changeset
|
144 |
Some(Err(_)) | None => NULL_REVISION, |
443eb4bc41af
rust: propagate error of index_get_parents() properly
Yuya Nishihara <yuya@tcha.org>
parents:
40880
diff
changeset
|
145 |
}; |
443eb4bc41af
rust: propagate error of index_get_parents() properly
Yuya Nishihara <yuya@tcha.org>
parents:
40880
diff
changeset
|
146 |
rev as c_long |
40272
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
147 |
} |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
148 |
|
40300
72b94f946e90
rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents:
40272
diff
changeset
|
149 |
#[no_mangle] |
72b94f946e90
rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents:
40272
diff
changeset
|
150 |
pub extern "C" fn rustlazyancestors_contains( |
72b94f946e90
rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents:
40272
diff
changeset
|
151 |
raw: *mut AncestorsIterator<Index>, |
72b94f946e90
rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents:
40272
diff
changeset
|
152 |
target: c_long, |
72b94f946e90
rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents:
40272
diff
changeset
|
153 |
) -> c_int { |
72b94f946e90
rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents:
40272
diff
changeset
|
154 |
raw_contains(raw, target) |
72b94f946e90
rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents:
40272
diff
changeset
|
155 |
} |
72b94f946e90
rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents:
40272
diff
changeset
|
156 |
|
72b94f946e90
rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents:
40272
diff
changeset
|
157 |
/// Testable (for any Graph) version of rustlazayancestors_next |
72b94f946e90
rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents:
40272
diff
changeset
|
158 |
#[inline] |
72b94f946e90
rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents:
40272
diff
changeset
|
159 |
fn raw_contains<G: Graph>( |
72b94f946e90
rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents:
40272
diff
changeset
|
160 |
raw: *mut AncestorsIterator<G>, |
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 |
let as_ref = unsafe { &mut *raw }; |
40881
443eb4bc41af
rust: propagate error of index_get_parents() properly
Yuya Nishihara <yuya@tcha.org>
parents:
40880
diff
changeset
|
164 |
match as_ref.contains(target as Revision) { |
443eb4bc41af
rust: propagate error of index_get_parents() properly
Yuya Nishihara <yuya@tcha.org>
parents:
40880
diff
changeset
|
165 |
Ok(r) => r as c_int, |
443eb4bc41af
rust: propagate error of index_get_parents() properly
Yuya Nishihara <yuya@tcha.org>
parents:
40880
diff
changeset
|
166 |
Err(_) => -1, |
40300
72b94f946e90
rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents:
40272
diff
changeset
|
167 |
} |
72b94f946e90
rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents:
40272
diff
changeset
|
168 |
} |
72b94f946e90
rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents:
40272
diff
changeset
|
169 |
|
40272
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
170 |
#[cfg(test)] |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
171 |
mod tests { |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
172 |
use super::*; |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
173 |
use std::thread; |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
174 |
|
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
175 |
#[derive(Clone, Debug)] |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
176 |
struct Stub; |
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 |
impl Graph for Stub { |
40950
18513d6ef7d4
rust: changed Graph.parents to return [Revision; 2]
Georges Racinet <gracinet@anybox.fr>
parents:
40881
diff
changeset
|
179 |
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
|
180 |
match r { |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
181 |
25 => Err(GraphError::ParentOutOfRange(25)), |
40950
18513d6ef7d4
rust: changed Graph.parents to return [Revision; 2]
Georges Racinet <gracinet@anybox.fr>
parents:
40881
diff
changeset
|
182 |
_ => Ok([1, 2]), |
40272
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 |
} |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
185 |
} |
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 |
/// Helper for test_init_next() |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
188 |
fn stub_raw_init( |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
189 |
initrevslen: usize, |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
190 |
initrevs: usize, |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
191 |
stoprev: c_long, |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
192 |
inclusive: c_int, |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
193 |
) -> usize { |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
194 |
unsafe { |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
195 |
raw_init( |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
196 |
Stub, |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
197 |
initrevslen, |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
198 |
initrevs as *mut c_long, |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
199 |
stoprev, |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
200 |
inclusive, |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
201 |
) as usize |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
202 |
} |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
203 |
} |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
204 |
|
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
205 |
fn stub_raw_init_from_vec( |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
206 |
mut initrevs: Vec<c_long>, |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
207 |
stoprev: c_long, |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
208 |
inclusive: c_int, |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
209 |
) -> *mut AncestorsIterator<Stub> { |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
210 |
unsafe { |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
211 |
raw_init( |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
212 |
Stub, |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
213 |
initrevs.len(), |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
214 |
initrevs.as_mut_ptr(), |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
215 |
stoprev, |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
216 |
inclusive, |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
217 |
) |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
218 |
} |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
219 |
} |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
220 |
|
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
221 |
#[test] |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
222 |
// 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
|
223 |
// and try to use it afterwards |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
224 |
// 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
|
225 |
// 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
|
226 |
fn test_init_next() { |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
227 |
let mut initrevs: Vec<c_long> = vec![11, 13]; |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
228 |
let initrevs_len = initrevs.len(); |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
229 |
let initrevs_ptr = initrevs.as_mut_ptr() as usize; |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
230 |
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
|
231 |
let raw = handler.join().unwrap() as *mut AncestorsIterator<Stub>; |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
232 |
|
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
233 |
assert_eq!(raw_next(raw), 13); |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
234 |
assert_eq!(raw_next(raw), 11); |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
235 |
assert_eq!(raw_next(raw), 2); |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
236 |
assert_eq!(raw_next(raw), 1); |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
237 |
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
|
238 |
raw_drop(raw); |
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 |
|
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
241 |
#[test] |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
242 |
fn test_init_wrong_bool() { |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
243 |
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
|
244 |
} |
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 |
#[test] |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
247 |
fn test_empty() { |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
248 |
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
|
249 |
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
|
250 |
raw_drop(raw); |
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 |
|
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
253 |
#[test] |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
254 |
fn test_init_err_out_of_range() { |
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
255 |
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
|
256 |
} |
40300
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 |
#[test] |
72b94f946e90
rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents:
40272
diff
changeset
|
259 |
fn test_contains() { |
72b94f946e90
rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents:
40272
diff
changeset
|
260 |
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
|
261 |
assert_eq!(raw_contains(raw, 5), 1); |
72b94f946e90
rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents:
40272
diff
changeset
|
262 |
assert_eq!(raw_contains(raw, 2), 1); |
72b94f946e90
rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents:
40272
diff
changeset
|
263 |
} |
72b94f946e90
rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents:
40272
diff
changeset
|
264 |
|
72b94f946e90
rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents:
40272
diff
changeset
|
265 |
#[test] |
72b94f946e90
rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents:
40272
diff
changeset
|
266 |
fn test_contains_exclusive() { |
72b94f946e90
rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents:
40272
diff
changeset
|
267 |
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
|
268 |
assert_eq!(raw_contains(raw, 5), 0); |
72b94f946e90
rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents:
40272
diff
changeset
|
269 |
assert_eq!(raw_contains(raw, 2), 1); |
72b94f946e90
rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents:
40272
diff
changeset
|
270 |
} |
40272
a36c5e23c055
rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
271 |
} |