use crate::{
simics_exception,
sys::{
init_arg_t, init_arg_t__bindgen_ty_1, SIM_init_command_line, SIM_init_environment,
SIM_init_simulator2, SIM_main_loop,
},
Result,
};
use paste::paste;
use raw_cstr::raw_cstr;
use std::{
fmt::{self, Display, Formatter},
mem::forget,
ptr::null,
};
#[cfg(simics_version = "6")]
pub type CpuVariant = crate::sys::cpu_variant_t;
#[cfg(simics_version = "6")]
#[derive(Debug, Clone)]
pub struct GuiMode(crate::sys::gui_mode_t);
#[cfg(simics_version = "6")]
impl ToString for GuiMode {
fn to_string(&self) -> String {
match self.0 {
crate::sys::gui_mode_t::GUI_Mode_None => "no-gui",
crate::sys::gui_mode_t::GUI_Mode_Mixed => "mixed",
crate::sys::gui_mode_t::GUI_Mode_Only => "gui",
crate::sys::gui_mode_t::GUI_Mode_Default => "default",
}
.to_string()
}
}
#[derive(Copy, Clone, Debug)]
#[repr(u32)]
pub enum DeprecationLevel {
NoWarnings = 0,
MajorReleaseDeprecated = 1,
NewAndFutureDeprecated = 2,
}
impl Display for DeprecationLevel {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
let val: u32 = *self as u32;
write!(f, "{}", val)
}
}
#[derive(Clone)]
pub struct InitArg(init_arg_t);
impl From<InitArg> for init_arg_t {
fn from(value: InitArg) -> Self {
value.0
}
}
macro_rules! impl_bool_arg {
($struct_name:ident, $name:expr) => {
paste! {
impl $struct_name {
pub fn [< $name:snake:lower >](value: bool) -> Result<Self> {
Self::boolean($name, value)
}
}
}
};
}
macro_rules! impl_string_arg {
($struct_name:ident, $name:expr) => {
paste! {
impl $struct_name {
pub fn [< $name:snake:lower >]<T>(value: T) -> Result<Self> where T: ToString {
let value = value.to_string();
Self::string($name, &value.to_string())
}
}
}
};
}
impl InitArg {
pub fn boolean<S>(name: S, enabled: bool) -> Result<Self>
where
S: AsRef<str>,
{
Ok(InitArg(init_arg_t {
name: raw_cstr(name)?,
boolean: true,
u: init_arg_t__bindgen_ty_1 { enabled },
}))
}
pub fn string<S>(name: S, value: S) -> Result<Self>
where
S: AsRef<str>,
{
Ok(InitArg(init_arg_t {
name: raw_cstr(name)?,
boolean: false,
u: init_arg_t__bindgen_ty_1 {
string: raw_cstr(value)?,
},
}))
}
pub fn last() -> Self {
InitArg(init_arg_t {
name: null(),
boolean: false,
u: init_arg_t__bindgen_ty_1 { string: null() },
})
}
}
impl_bool_arg!(InitArg, "batch-mode");
impl_string_arg!(InitArg, "deprecation-level");
impl_string_arg!(InitArg, "expire-time");
impl_string_arg!(InitArg, "gui-mode");
impl_bool_arg!(InitArg, "fail-on-warnings");
impl_string_arg!(InitArg, "license-file");
impl_bool_arg!(InitArg, "log-enable");
impl_string_arg!(InitArg, "log-file");
impl_bool_arg!(InitArg, "no-settings");
impl_bool_arg!(InitArg, "no-windows");
impl_bool_arg!(InitArg, "python-verbose");
impl_string_arg!(InitArg, "project");
impl_bool_arg!(InitArg, "quiet");
impl_bool_arg!(InitArg, "script-trace");
impl_bool_arg!(InitArg, "verbose");
impl_bool_arg!(InitArg, "allow-license-gui");
impl_string_arg!(InitArg, "alt-settings-dir");
impl_string_arg!(InitArg, "application-mode");
impl_bool_arg!(InitArg, "check-ifaces");
impl_bool_arg!(InitArg, "disable-dstc");
impl_bool_arg!(InitArg, "disable-istc");
impl_string_arg!(InitArg, "eclipse-params");
impl_string_arg!(InitArg, "package-list");
impl_bool_arg!(InitArg, "py3k-warnings");
impl_bool_arg!(InitArg, "sign-module");
impl_bool_arg!(InitArg, "as-py-module");
impl_bool_arg!(InitArg, "py-import-all");
impl_bool_arg!(InitArg, "use-module-cache");
#[derive(Clone)]
pub struct InitArgs {
args: Vec<init_arg_t>,
}
impl Default for InitArgs {
fn default() -> Self {
Self {
args: vec![InitArg::last().into()],
}
}
}
impl InitArgs {
pub fn arg(mut self, arg: InitArg) -> Self {
self.args.insert(0, arg.into());
self
}
pub fn as_mut_ptr(&mut self) -> *mut init_arg_t {
self.args.as_mut_ptr()
}
}
#[simics_exception]
pub fn init_environment<I, S>(argv: I, handle_signals: bool, allow_core_dumps: bool) -> Result<()>
where
I: IntoIterator<Item = S>,
S: AsRef<str>,
{
let mut args = Vec::new();
for arg in argv {
args.push(raw_cstr(arg)?);
}
let args_ptr = args.as_mut_ptr();
forget(args);
unsafe { SIM_init_environment(args_ptr, handle_signals, allow_core_dumps) };
Ok(())
}
#[simics_exception]
pub fn init_simulator(args: &mut InitArgs) {
unsafe { SIM_init_simulator2(args.as_mut_ptr()) };
}
#[simics_exception]
pub fn init_command_line() {
unsafe { SIM_init_command_line() };
}
pub fn main_loop() -> ! {
unsafe { SIM_main_loop() };
unreachable!("Something went wrong initializing the SIMICS main loop")
}