aboutsummaryrefslogtreecommitdiff
path: root/src/socket/parser.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/socket/parser.rs')
-rw-r--r--src/socket/parser.rs215
1 files changed, 163 insertions, 52 deletions
diff --git a/src/socket/parser.rs b/src/socket/parser.rs
index e8dd9ec..0de0248 100644
--- a/src/socket/parser.rs
+++ b/src/socket/parser.rs
@@ -9,94 +9,205 @@ use x11::xlib;
use x11::keysym;
use command::*;
-use dotwm::DotWM;
+use ::socket::ParsedCmd;
+use ::socket::FnType;
-use nom::{IResult,alpha,multispace};
-use nom::IResult::*;
-use std::str;
-
-named!(token<&str>,
- map_res!(
- alpha, str::from_utf8));
+macro_rules! simple_try {
+ ($expr:expr) => (match $expr {
+ Ok(val) => val,
+ Err(err) => {
+ return Err(err)
+ }
+ })
+}
-fn slice2str(input: Vec<&[u8]>) -> Vec<&str> {
- let res: Vec<&str> = input.iter()
- .map(|x| str::from_utf8(x).unwrap())
- .collect();
- res
+fn modifier_from<'a>(s: &'a str) -> Result<u32, &'static str> {
+ match s {
+ "Mod1" => Ok(xlib::Mod4Mask),
+ "Mod2" => Ok(xlib::Mod4Mask),
+ "Mod3" => Ok(xlib::Mod4Mask),
+ "Mod4" => Ok(xlib::Mod4Mask),
+ "Control" => Ok(xlib::ControlMask),
+ "Shift" => Ok(xlib::ShiftMask),
+ _ => Err("unknown modifier"),
+ }
}
-named!(args<Vec<&str> >,
- map!(
- separated_list!(
- multispace, alpha),
- slice2str));
+fn modifiers<'a>(s: &'a str) -> Result<Vec<u32>, &'static str> {
+ let mut result = vec![];
-fn modifier<'a>(s: &'a str) -> Result<u32, ()> {
- match s {
- "Mod1Mask" => Ok(xlib::Mod4Mask),
- "Mod2Mask" => Ok(xlib::Mod4Mask),
- "Mod3Mask" => Ok(xlib::Mod4Mask),
- "Mod4Mask" => Ok(xlib::Mod4Mask),
- "ControlMask" => Ok(xlib::ControlMask),
- "ShiftMask" => Ok(xlib::ShiftMask),
- _ => Err(()),
+ for smod in s.split("-") {
+ let modifier = simple_try!(modifier_from(smod));
+ result.push(modifier);
}
+
+ Ok(result)
}
-fn str_to_key<'a>(s: &'a str) -> Result<u32, ()> {
+fn key<'a>(s: &'a str) -> Result<u32, &'static str> {
match s {
+ "a" => Ok(keysym::XK_a),
+ "b" => Ok(keysym::XK_b),
+ "c" => Ok(keysym::XK_c),
+ "d" => Ok(keysym::XK_d),
+ "e" => Ok(keysym::XK_e),
+ "f" => Ok(keysym::XK_f),
+ "g" => Ok(keysym::XK_g),
"h" => Ok(keysym::XK_h),
+ "i" => Ok(keysym::XK_i),
"j" => Ok(keysym::XK_j),
"k" => Ok(keysym::XK_k),
"l" => Ok(keysym::XK_l),
- "Tab" => Ok(keysym::XK_Tab),
+ "m" => Ok(keysym::XK_m),
+ "n" => Ok(keysym::XK_n),
+ "o" => Ok(keysym::XK_o),
"p" => Ok(keysym::XK_p),
- "Return" => Ok(keysym::XK_Return),
"q" => Ok(keysym::XK_q),
- _ => Err(()),
+ "r" => Ok(keysym::XK_r),
+ "s" => Ok(keysym::XK_s),
+ "t" => Ok(keysym::XK_t),
+ "u" => Ok(keysym::XK_u),
+ "v" => Ok(keysym::XK_v),
+ "w" => Ok(keysym::XK_w),
+ "x" => Ok(keysym::XK_x),
+ "y" => Ok(keysym::XK_y),
+ "z" => Ok(keysym::XK_z),
+ "A" => Ok(keysym::XK_A),
+ "B" => Ok(keysym::XK_B),
+ "C" => Ok(keysym::XK_C),
+ "D" => Ok(keysym::XK_D),
+ "E" => Ok(keysym::XK_E),
+ "F" => Ok(keysym::XK_F),
+ "G" => Ok(keysym::XK_G),
+ "H" => Ok(keysym::XK_H),
+ "I" => Ok(keysym::XK_I),
+ "J" => Ok(keysym::XK_J),
+ "K" => Ok(keysym::XK_K),
+ "L" => Ok(keysym::XK_L),
+ "M" => Ok(keysym::XK_M),
+ "N" => Ok(keysym::XK_N),
+ "O" => Ok(keysym::XK_O),
+ "P" => Ok(keysym::XK_P),
+ "Q" => Ok(keysym::XK_Q),
+ "R" => Ok(keysym::XK_R),
+ "S" => Ok(keysym::XK_S),
+ "T" => Ok(keysym::XK_T),
+ "U" => Ok(keysym::XK_U),
+ "V" => Ok(keysym::XK_V),
+ "W" => Ok(keysym::XK_W),
+ "X" => Ok(keysym::XK_X),
+ "Y" => Ok(keysym::XK_Y),
+ "Z" => Ok(keysym::XK_Z),
+ "Tab" => Ok(keysym::XK_Tab),
+ "Return" => Ok(keysym::XK_Return),
+ _ => Err("unknown key"),
}
}
-fn str_to_func<'a>(s: &'a str) -> Result<ExecFn,()> {
+fn func<'a>(s: &'a str) -> Result<ExecFn, &'static str> {
match s {
"exec" => Ok(exec),
- "move_win" => Ok(move_win),
- "resize_win" => Ok(resize_win),
- _ => Err(()),
+ "move-win" => Ok(move_win),
+ "move-win-to" => Ok(move_win_to),
+ "resize-win" => Ok(resize_win),
+ "focus-next" => Ok(focus_next),
+ "quit" => Ok(quit_dotwm),
+ _ => Err("unknown function"),
}
}
-pub fn parse<'a>(dotwm: &mut DotWM, bindings: &mut BindingHash, input: &'a str) -> &'a str {
- let args: Vec<&str> = input.split_whitespace().collect();
+pub fn parse<'a>(input: &'a str) -> Result<ParsedCmd<'a>, &'static str> {
+ let args: Vec<&'a str> = input.split_whitespace().collect();
match args.first() {
Some(cmd) => {
match cmd {
- &"add-binding" => {
- let modifier = modifier(args[1]).unwrap();
- let key = str_to_key(args[2]).unwrap();
- let func = str_to_func(args[3]).unwrap();
- let arguments = &args[4..];
+ &"bind" => {
+ if args.len() > 2 {
+ let modifiers = simple_try!(modifiers(args[1]));
+ let key = simple_try!(key(args[2]));
+ let func = simple_try!(func(args[3]));
+ let arguments: &[&'a str]= &args[4..];
- add_binding(dotwm, bindings, key, modifier, func, arguments);
+ Ok(ParsedCmd {
+ f: FnType::Bind,
+ modifiers: modifiers,
+ key: key,
+ args: arguments.to_vec(),
+ func: func,
+ })
+ } else {
+ Err("missing arguments")
+ }
+ },
+ &"exec" => {
+ Ok(ParsedCmd {
+ f: FnType::Exec,
+ modifiers: vec![],
+ key: 0,
+ args: vec![],
+ func: exec
+ })
+ },
+ _ => {
+ Err("unknown command")
},
- &"exec" => { println!("exec"); },
- _ => { println!("anotherthing ._."); },
}
},
- None => println!("error"),
+ None => Err("no input"),
+ }
+}
+
+#[test]
+fn parse_unknown() {
+ let res = parse("unknown");
+ if let Err(e) = res {
+ assert_eq!(e, "unknown command");
+ } else {
+ assert!(false);
}
- "ok"
}
#[test]
-fn parse_test() {
- assert_eq!(token(&b"exec"[..]), IResult::Done(&b""[..], "exec"));
+fn parse_bind_modifier() {
+ let res = parse("bind modifier1 k exec ");
+ if let Err(e) = res {
+ assert_eq!(e, "unknown modifier");
+ } else {
+ assert!(false);
+ }
+
+ let res2 = parse("bind Mod4 k exec ");
+ if let Ok(modifier) = res2 {
+ assert_eq!(modifier.modifiers[0], xlib::Mod4Mask);
+ } else {
+ assert!(false);
+ }
}
#[test]
-fn parse_args() {
- assert_eq!(args(&b"hola chau"[..]),
- IResult::Done(&b""[..], vec!["hola", "chau"]));
+fn parse_bind_key() {
+ let res = parse("bind Mod4 ' exec ");
+ if let Err(e) = res {
+ assert_eq!(e, "unknown key");
+ } else {
+ assert!(false);
+ }
+
+ let res2 = parse("bind Mod4 k exec ");
+ if let Ok(modifier) = res2 {
+ assert_eq!(modifier.key, keysym::XK_k);
+ } else {
+ assert!(false);
+ }
+}
+
+#[test]
+fn parse_exec() {
+ let res = parse("exec Mod4 ' exec ");
+ if let Ok(pcmd) = res {
+ assert_eq!(pcmd.f, FnType::Exec);
+ } else {
+ assert!(false);
+ }
}