Mercurial > hg
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() |