comparison rust/hg-cpython/src/dirstate.rs @ 43210:3fec5244aff1

rust-cpython: fix signature of make_dirstate_tuple() Fortunately, the layout of PyObject {} is compatible with a C pointer, but we shouldn't rely on that. This also fixes the handling of NULL pointer.
author Yuya Nishihara <yuya@tcha.org>
date Sun, 13 Oct 2019 17:01:10 +0900
parents 8b355cbef16d
children 88a9930e92e4
comparison
equal deleted inserted replaced
43209:8b355cbef16d 43210:3fec5244aff1
21 utils::hg_path::HgPathBuf, DirstateEntry, DirstateParseError, EntryState, 21 utils::hg_path::HgPathBuf, DirstateEntry, DirstateParseError, EntryState,
22 StateMap, 22 StateMap,
23 }; 23 };
24 use libc::{c_char, c_int}; 24 use libc::{c_char, c_int};
25 #[cfg(feature = "python27")] 25 #[cfg(feature = "python27")]
26 use python27_sys::PyCapsule_Import; 26 use python27_sys as python_sys;
27 #[cfg(feature = "python3")] 27 #[cfg(feature = "python3")]
28 use python3_sys::PyCapsule_Import; 28 use python3_sys as python_sys;
29 use python_sys::PyCapsule_Import;
29 use std::convert::TryFrom; 30 use std::convert::TryFrom;
30 use std::ffi::CStr; 31 use std::ffi::CStr;
31 use std::mem::transmute; 32 use std::mem::transmute;
32 33
33 /// C code uses a custom `dirstate_tuple` type, checks in multiple instances 34 /// C code uses a custom `dirstate_tuple` type, checks in multiple instances
39 type MakeDirstateTupleFn = unsafe extern "C" fn( 40 type MakeDirstateTupleFn = unsafe extern "C" fn(
40 state: c_char, 41 state: c_char,
41 mode: c_int, 42 mode: c_int,
42 size: c_int, 43 size: c_int,
43 mtime: c_int, 44 mtime: c_int,
44 ) -> PyObject; 45 ) -> *mut python_sys::PyObject;
45 46
46 /// This is largely a copy/paste from cindex.rs, pending the merge of a 47 /// This is largely a copy/paste from cindex.rs, pending the merge of a
47 /// `py_capsule_fn!` macro in the rust-cpython project: 48 /// `py_capsule_fn!` macro in the rust-cpython project:
48 /// https://github.com/dgrunwald/rust-cpython/pull/169 49 /// https://github.com/dgrunwald/rust-cpython/pull/169
49 fn decapsule_make_dirstate_tuple(py: Python) -> PyResult<MakeDirstateTupleFn> { 50 fn decapsule_make_dirstate_tuple(py: Python) -> PyResult<MakeDirstateTupleFn> {
74 // Explicitly go through u8 first, then cast to platform-specific `c_char` 75 // Explicitly go through u8 first, then cast to platform-specific `c_char`
75 // because Into<u8> has a specific implementation while `as c_char` would 76 // because Into<u8> has a specific implementation while `as c_char` would
76 // just do a naive enum cast. 77 // just do a naive enum cast.
77 let state_code: u8 = state.into(); 78 let state_code: u8 = state.into();
78 79
79 unsafe { 80 let maybe_obj = unsafe {
80 let ptr = make(state_code as c_char, mode, size, mtime); 81 let ptr = make(state_code as c_char, mode, size, mtime);
81 Ok(ptr) 82 PyObject::from_owned_ptr_opt(py, ptr)
82 } 83 };
84 maybe_obj.ok_or_else(|| PyErr::fetch(py))
83 } 85 }
84 86
85 pub fn extract_dirstate(py: Python, dmap: &PyDict) -> Result<StateMap, PyErr> { 87 pub fn extract_dirstate(py: Python, dmap: &PyDict) -> Result<StateMap, PyErr> {
86 dmap.items(py) 88 dmap.items(py)
87 .iter() 89 .iter()