comparison rust/hgcli/src/main.rs @ 35631:edbe11cfedcf

rust: extract function to convert Path to platform CString It can be better on Unix.
author Yuya Nishihara <yuya@tcha.org>
date Fri, 12 Jan 2018 22:09:34 +0900
parents 74bec9e74831
children fa9747e7fc86
comparison
equal deleted inserted replaced
35630:6061e54ff81d 35631:edbe11cfedcf
12 use cpython::{NoArgs, ObjectProtocol, PyModule, PyResult, Python}; 12 use cpython::{NoArgs, ObjectProtocol, PyModule, PyResult, Python};
13 use libc::{c_char, c_int}; 13 use libc::{c_char, c_int};
14 14
15 use std::env; 15 use std::env;
16 use std::path::PathBuf; 16 use std::path::PathBuf;
17 use std::ffi::CString; 17 use std::ffi::{CString, OsStr};
18 #[cfg(target_family = "unix")] 18 #[cfg(target_family = "unix")]
19 use std::os::unix::ffi::OsStringExt; 19 use std::os::unix::ffi::OsStringExt;
20 20
21 #[derive(Debug)] 21 #[derive(Debug)]
22 struct Environment { 22 struct Environment {
58 _exe: exe.clone(), 58 _exe: exe.clone(),
59 python_exe: python_exe, 59 python_exe: python_exe,
60 python_home: python_home, 60 python_home: python_home,
61 mercurial_modules: mercurial_modules.to_path_buf(), 61 mercurial_modules: mercurial_modules.to_path_buf(),
62 } 62 }
63 }
64
65 fn cstring_from_os<T: AsRef<OsStr>>(s: T) -> CString {
66 CString::new(s.as_ref().to_str().unwrap()).unwrap()
63 } 67 }
64 68
65 // On UNIX, argv starts as an array of char*. So it is easy to convert 69 // On UNIX, argv starts as an array of char*. So it is easy to convert
66 // to C strings. 70 // to C strings.
67 #[cfg(target_family = "unix")] 71 #[cfg(target_family = "unix")]
84 fn args_to_cstrings() -> Vec<CString> { 88 fn args_to_cstrings() -> Vec<CString> {
85 env::args().map(|a| CString::new(a).unwrap()).collect() 89 env::args().map(|a| CString::new(a).unwrap()).collect()
86 } 90 }
87 91
88 fn set_python_home(env: &Environment) { 92 fn set_python_home(env: &Environment) {
89 let raw = CString::new(env.python_home.to_str().unwrap()) 93 let raw = cstring_from_os(&env.python_home).into_raw();
90 .unwrap()
91 .into_raw();
92 unsafe { 94 unsafe {
93 python27_sys::Py_SetPythonHome(raw); 95 python27_sys::Py_SetPythonHome(raw);
94 } 96 }
95 } 97 }
96 98
131 // Yes, we use the path to the Python interpreter not argv[0] here. The 133 // Yes, we use the path to the Python interpreter not argv[0] here. The
132 // reason is because Python uses the given path to find the location of 134 // reason is because Python uses the given path to find the location of
133 // Python files. Apparently we could define our own ``Py_GetPath()`` 135 // Python files. Apparently we could define our own ``Py_GetPath()``
134 // implementation. But this may require statically linking Python, which is 136 // implementation. But this may require statically linking Python, which is
135 // not desirable. 137 // not desirable.
136 let program_name = CString::new(env.python_exe.to_str().unwrap()) 138 let program_name = cstring_from_os(&env.python_exe).as_ptr();
137 .unwrap()
138 .as_ptr();
139 unsafe { 139 unsafe {
140 python27_sys::Py_SetProgramName(program_name as *mut i8); 140 python27_sys::Py_SetProgramName(program_name as *mut i8);
141 } 141 }
142 142
143 unsafe { 143 unsafe {