use crate::{lldb_pid_t, sys, LaunchFlags, SBFileSpec, SBListener};
use std::ffi::{CStr, CString};
use std::os::raw::c_char;
use std::ptr;
#[derive(Debug)]
pub struct SBLaunchInfo {
pub raw: sys::SBLaunchInfoRef,
}
impl SBLaunchInfo {
pub fn new() -> SBLaunchInfo {
SBLaunchInfo::wrap(unsafe { sys::CreateSBLaunchInfo(ptr::null_mut()) })
}
pub(crate) fn wrap(raw: sys::SBLaunchInfoRef) -> SBLaunchInfo {
SBLaunchInfo { raw }
}
#[allow(missing_docs)]
pub fn process_id(&self) -> lldb_pid_t {
unsafe { sys::SBLaunchInfoGetProcessID(self.raw) }
}
#[allow(missing_docs)]
pub fn user_id(&self) -> Option<u32> {
if unsafe { sys::SBLaunchInfoUserIDIsValid(self.raw) } {
Some(unsafe { sys::SBLaunchInfoGetUserID(self.raw) })
} else {
None
}
}
#[allow(missing_docs)]
pub fn set_user_id(&self, user_id: u32) {
unsafe { sys::SBLaunchInfoSetUserID(self.raw, user_id) };
}
#[allow(missing_docs)]
pub fn group_id(&self) -> Option<u32> {
if unsafe { sys::SBLaunchInfoGroupIDIsValid(self.raw) } {
Some(unsafe { sys::SBLaunchInfoGetGroupID(self.raw) })
} else {
None
}
}
#[allow(missing_docs)]
pub fn set_group_id(&self, group_id: u32) {
unsafe { sys::SBLaunchInfoSetGroupID(self.raw, group_id) };
}
#[allow(missing_docs)]
pub fn executable_file(&self) -> Option<SBFileSpec> {
SBFileSpec::maybe_wrap(unsafe { sys::SBLaunchInfoGetExecutableFile(self.raw) })
}
pub fn set_executable_file(&self, filespec: &SBFileSpec, add_as_first_arg: bool) {
unsafe { sys::SBLaunchInfoSetExecutableFile(self.raw, filespec.raw, add_as_first_arg) };
}
pub fn listener(&self) -> Option<SBListener> {
SBListener::maybe_wrap(unsafe { sys::SBLaunchInfoGetListener(self.raw) })
}
pub fn set_listener(&self, listener: &SBListener) {
unsafe { sys::SBLaunchInfoSetListener(self.raw, listener.raw) };
}
#[allow(missing_docs)]
pub fn launch_flags(&self) -> LaunchFlags {
LaunchFlags::from_bits_truncate(unsafe { sys::SBLaunchInfoGetLaunchFlags(self.raw) })
}
#[allow(missing_docs)]
pub fn set_launch_flags(&self, launch_flags: LaunchFlags) {
unsafe { sys::SBLaunchInfoSetLaunchFlags(self.raw, launch_flags.bits()) }
}
pub fn set_arguments<'a>(&self, args: impl IntoIterator<Item = &'a str>, append: bool) {
let cstrs: Vec<CString> = args.into_iter().map(|a| CString::new(a).unwrap()).collect();
let mut ptrs: Vec<*const c_char> = cstrs.iter().map(|cs| cs.as_ptr()).collect();
ptrs.push(ptr::null());
let argv = ptrs.as_ptr();
unsafe { sys::SBLaunchInfoSetArguments(self.raw, argv, append) };
}
pub fn arguments(&self) -> impl Iterator<Item = &str> {
SBLaunchInfoArgumentsIter {
launch_info: self,
index: 0,
}
}
#[allow(missing_docs)]
fn num_arguments(&self) -> u32 {
unsafe { sys::SBLaunchInfoGetNumArguments(self.raw) }
}
#[allow(missing_docs)]
fn argument_at_index(&self, index: u32) -> &str {
unsafe {
match CStr::from_ptr(sys::SBLaunchInfoGetArgumentAtIndex(self.raw, index)).to_str() {
Ok(s) => s,
_ => panic!("Invalid string?"),
}
}
}
#[allow(missing_docs)]
pub fn process_plugin_name(&self) -> Option<&str> {
unsafe {
match CStr::from_ptr(sys::SBLaunchInfoGetProcessPluginName(self.raw)).to_str() {
Ok(s) => Some(s),
_ => None,
}
}
}
#[allow(missing_docs)]
pub fn set_process_plugin_name(&self, plugin: &str) {
let plugin = CString::new(plugin).unwrap();
unsafe { sys::SBLaunchInfoSetProcessPluginName(self.raw, plugin.as_ptr()) };
}
#[allow(missing_docs)]
pub fn shell(&self) -> Option<&str> {
unsafe {
match CStr::from_ptr(sys::SBLaunchInfoGetShell(self.raw)).to_str() {
Ok(s) => Some(s),
_ => None,
}
}
}
#[allow(missing_docs)]
pub fn set_shell(&self, shell: &str) {
let shell = CString::new(shell).unwrap();
unsafe { sys::SBLaunchInfoSetShell(self.raw, shell.as_ptr()) };
}
#[allow(missing_docs)]
pub fn shell_expand_arguments(&self) -> bool {
unsafe { sys::SBLaunchInfoGetShellExpandArguments(self.raw) }
}
#[allow(missing_docs)]
pub fn set_shell_expand_arguments(&self, expand: bool) {
unsafe { sys::SBLaunchInfoSetShellExpandArguments(self.raw, expand) };
}
#[allow(missing_docs)]
pub fn resume_count(&self) -> u32 {
unsafe { sys::SBLaunchInfoGetResumeCount(self.raw) }
}
#[allow(missing_docs)]
pub fn set_resume_count(&self, resume_count: u32) {
unsafe { sys::SBLaunchInfoSetResumeCount(self.raw, resume_count) };
}
#[allow(missing_docs)]
pub fn add_close_file_action(&self, fd: i32) -> bool {
unsafe { sys::SBLaunchInfoAddCloseFileAction(self.raw, fd) }
}
#[allow(missing_docs)]
pub fn add_duplicate_file_action(&self, fd: i32, dup_fd: i32) -> bool {
unsafe { sys::SBLaunchInfoAddDuplicateFileAction(self.raw, fd, dup_fd) }
}
#[allow(missing_docs)]
pub fn add_open_file_action(&self, fd: i32, path: &str, read: bool, write: bool) -> bool {
let path = CString::new(path).unwrap();
unsafe { sys::SBLaunchInfoAddOpenFileAction(self.raw, fd, path.as_ptr(), read, write) }
}
#[allow(missing_docs)]
pub fn add_suppress_file_action(&self, fd: i32, read: bool, write: bool) -> bool {
unsafe { sys::SBLaunchInfoAddSuppressFileAction(self.raw, fd, read, write) }
}
#[allow(missing_docs)]
pub fn launch_event_data(&self) -> Option<&str> {
unsafe {
match CStr::from_ptr(sys::SBLaunchInfoGetLaunchEventData(self.raw)).to_str() {
Ok(s) => Some(s),
_ => None,
}
}
}
#[allow(missing_docs)]
pub fn set_launch_event_data(&self, data: &str) {
let data = CString::new(data).unwrap();
unsafe { sys::SBLaunchInfoSetLaunchEventData(self.raw, data.as_ptr()) };
}
#[allow(missing_docs)]
pub fn detach_on_error(&self) -> bool {
unsafe { sys::SBLaunchInfoGetDetachOnError(self.raw) }
}
#[allow(missing_docs)]
pub fn set_detach_on_error(&self, detach: bool) {
unsafe { sys::SBLaunchInfoSetDetachOnError(self.raw, detach) };
}
}
impl Clone for SBLaunchInfo {
fn clone(&self) -> SBLaunchInfo {
SBLaunchInfo {
raw: unsafe { sys::CloneSBLaunchInfo(self.raw) },
}
}
}
impl Default for SBLaunchInfo {
fn default() -> SBLaunchInfo {
SBLaunchInfo::new()
}
}
impl Drop for SBLaunchInfo {
fn drop(&mut self) {
unsafe { sys::DisposeSBLaunchInfo(self.raw) };
}
}
unsafe impl Send for SBLaunchInfo {}
unsafe impl Sync for SBLaunchInfo {}
pub struct SBLaunchInfoArgumentsIter<'d> {
launch_info: &'d SBLaunchInfo,
index: u32,
}
impl<'d> Iterator for SBLaunchInfoArgumentsIter<'d> {
type Item = &'d str;
fn next(&mut self) -> Option<&'d str> {
if self.index < self.launch_info.num_arguments() {
self.index += 1;
Some(self.launch_info.argument_at_index(self.index - 1))
} else {
None
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
let sz = self.launch_info.num_arguments();
(sz as usize - self.index as usize, Some(sz as usize))
}
}
impl ExactSizeIterator for SBLaunchInfoArgumentsIter<'_> {}