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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
40272
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
1 // Copyright 2018 Georges Racinet <gracinet@anybox.fr>
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
2 //
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
3 // This software may be used and distributed according to the terms of the
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
4 // GNU General Public License version 2 or any later version.
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
5
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
6 //! Bindings for CPython extension code
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
7 //!
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
8 //! This exposes methods to build and use a `rustlazyancestors` iterator
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
9 //! from C code, using an index and its parents function that are passed
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
10 //! from the caller at instantiation.
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
11
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
12 use hg::AncestorsIterator;
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
13 use hg::{Graph, GraphError, Revision, NULL_REVISION};
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
14 use libc::{c_int, c_long, c_void, ssize_t};
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
15 use std::ptr::null_mut;
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
16 use std::slice;
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
17
a36c5e23c055 rust: iterator bindings to C code
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
18 type IndexPtr = *mut c_void;
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
6a551a2dc666 rust: run cargo fmt
Rapha?l Gom?s <rgomes@octobus.net>
parents: 40933
diff changeset
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
6a551a2dc666 rust: run cargo fmt
Rapha?l Gom?s <rgomes@octobus.net>
parents: 40933
diff changeset
47 let code = unsafe {
6a551a2dc666 rust: run cargo fmt
Rapha?l Gom?s <rgomes@octobus.net>
parents: 40933
diff changeset
48 HgRevlogIndex_GetParents(
6a551a2dc666 rust: run cargo fmt
Rapha?l Gom?s <rgomes@octobus.net>
parents: 40933
diff changeset
49 self.index,
6a551a2dc666 rust: run cargo fmt
Rapha?l Gom?s <rgomes@octobus.net>
parents: 40933
diff changeset
50 rev,
6a551a2dc666 rust: run cargo fmt
Rapha?l Gom?s <rgomes@octobus.net>
parents: 40933
diff changeset
51 &mut res as *mut [c_int; 2],
6a551a2dc666 rust: run cargo fmt
Rapha?l Gom?s <rgomes@octobus.net>
parents: 40933
diff changeset
52 )
6a551a2dc666 rust: run cargo fmt
Rapha?l Gom?s <rgomes@octobus.net>
parents: 40933
diff changeset
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
6a551a2dc666 rust: run cargo fmt
Rapha?l Gom?s <rgomes@octobus.net>
parents: 40933
diff changeset
104 Box::into_raw(Box::new(
6a551a2dc666 rust: run cargo fmt
Rapha?l Gom?s <rgomes@octobus.net>
parents: 40933
diff changeset
105 match AncestorsIterator::new(
6a551a2dc666 rust: run cargo fmt
Rapha?l Gom?s <rgomes@octobus.net>
parents: 40933
diff changeset
106 graph,
6a551a2dc666 rust: run cargo fmt
Rapha?l Gom?s <rgomes@octobus.net>
parents: 40933
diff changeset
107 slice.into_iter().map(|&r| r as Revision),
6a551a2dc666 rust: run cargo fmt
Rapha?l Gom?s <rgomes@octobus.net>
parents: 40933
diff changeset
108 stoprev as Revision,
6a551a2dc666 rust: run cargo fmt
Rapha?l Gom?s <rgomes@octobus.net>
parents: 40933
diff changeset
109 inclb,
6a551a2dc666 rust: run cargo fmt
Rapha?l Gom?s <rgomes@octobus.net>
parents: 40933
diff changeset
110 ) {
6a551a2dc666 rust: run cargo fmt
Rapha?l Gom?s <rgomes@octobus.net>
parents: 40933
diff changeset
111 Ok(it) => it,
6a551a2dc666 rust: run cargo fmt
Rapha?l Gom?s <rgomes@octobus.net>
parents: 40933
diff changeset
112 Err(_) => {
6a551a2dc666 rust: run cargo fmt
Rapha?l Gom?s <rgomes@octobus.net>
parents: 40933
diff changeset
113 return null_mut();
6a551a2dc666 rust: run cargo fmt
Rapha?l Gom?s <rgomes@octobus.net>
parents: 40933
diff changeset
114 }
6a551a2dc666 rust: run cargo fmt
Rapha?l Gom?s <rgomes@octobus.net>
parents: 40933
diff changeset
115 },
6a551a2dc666 rust: run cargo fmt
Rapha?l Gom?s <rgomes@octobus.net>
parents: 40933
diff changeset
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
6a551a2dc666 rust: run cargo fmt
Rapha?l Gom?s <rgomes@octobus.net>
parents: 40933
diff changeset
121 pub extern "C" fn rustlazyancestors_drop(
6a551a2dc666 rust: run cargo fmt
Rapha?l Gom?s <rgomes@octobus.net>
parents: 40933
diff changeset
122 raw_iter: *mut AncestorsIterator<Index>,
6a551a2dc666 rust: run cargo fmt
Rapha?l Gom?s <rgomes@octobus.net>
parents: 40933
diff changeset
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
6a551a2dc666 rust: run cargo fmt
Rapha?l Gom?s <rgomes@octobus.net>
parents: 40933
diff changeset
141 pub extern "C" fn rustlazyancestors_next(
6a551a2dc666 rust: run cargo fmt
Rapha?l Gom?s <rgomes@octobus.net>
parents: 40933
diff changeset
142 raw: *mut AncestorsIterator<Index>,
6a551a2dc666 rust: run cargo fmt
Rapha?l Gom?s <rgomes@octobus.net>
parents: 40933
diff changeset
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
6a551a2dc666 rust: run cargo fmt
Rapha?l Gom?s <rgomes@octobus.net>
parents: 40933
diff changeset
239 let handler = thread::spawn(move || {
6a551a2dc666 rust: run cargo fmt
Rapha?l Gom?s <rgomes@octobus.net>
parents: 40933
diff changeset
240 stub_raw_init(initrevs_len, initrevs_ptr, 0, 1)
6a551a2dc666 rust: run cargo fmt
Rapha?l Gom?s <rgomes@octobus.net>
parents: 40933
diff changeset
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 }