Professional Documents
Culture Documents
macro_rules! module_add {
($mod:ident << $fun:ident [$($lt:expr),*] [$($ty:expr),*] $ret:expr) => {
$mod.add(
Arc::new(stringify!($fun).into()),
$fun,
Dfn { lts: vec![$($lt),*], tys: vec![$($ty),*], ret: $ret, ext: vec![],
lazy: &[] }
)
}
}
macro_rules! wrap_var {
(rustobj, $value:expr) => {
Variable::RustObject(Arc::new(Mutex::new($value)) as RustObject)
};
(arr $typ:ident, $value:expr) => {
Variable::Array(Arc::new($value.into_iter().map(|o| wrap_var!($typ,
o)).collect::<Vec<_>>()) as Array)
};
}
macro_rules! with_unwrapped_device {
($thing:expr, $fn:expr) => {
match $thing {
&Variable::RustObject(ref o) => {
let mut guard = o.lock().expect(".lock()");
let dev = guard.downcast_mut::<Device>().expect("downcast_mut()");
($fn)(dev)
},
ref x => panic!("What is this?? {:?}", x),
}
}
}
enum ScriptSource {
Expr(String),
Read(Box<dyn io::Read>),
}
impl ScriptSource {
fn read(self) -> (String, bool) {
match self {
ScriptSource::Expr(s) => (
format!("fn main() ~ evdevs, uinput {{\n{}\n}}", s.replace(");",
")\n").replace("};", "}\n").replace(";", "\n")),
true,
),
ScriptSource::Read(mut r) => {
let mut result = String::new();
let _ = r.read_to_string(&mut result).expect("read_to_string");
(result, false)
},
}
}
}
#[derive(Default, serde::Deserialize)]
struct DeviceConfig {
name: Option<String>,
bustype: Option<u16>,
vendor: Option<u16>,
product: Option<u16>,
version: Option<u16>,
}
#[derive(Default, serde::Deserialize)]
struct EventsConfig {
keys: Option<Vec<String>>,
// TODO: other events
}
#[derive(Default, serde::Deserialize)]
struct ScriptConfig {
device: Option<DeviceConfig>,
events: EventsConfig,
}
fn main() {
let matches = clap::App::new("evscript")
.version(env!("CARGO_PKG_VERSION"))
.author("Val Packett <val@packett.cool>")
.about("A tiny sandboxed Dyon scripting environment for evdev input
devices.")
.arg(
clap::Arg::with_name("FILE")
.short("f")
.long("file")
.takes_value(true)
.help("The script file to run, by default - (stdin)"),
)
.arg(
clap::Arg::with_name("EXPR")
.short("e")
.long("expr")
.takes_value(true)
.help("The script expression to run (inside main), overrides the
file if present"),
)
.arg(
clap::Arg::with_name("DEV")
.short("d")
.long("device")
.takes_value(true)
.multiple(true)
.help("A device to get events from"),
)
.get_matches();
drop_privileges();