Skip to content

Commit

Permalink
Ensure parse errors are displayed
Browse files Browse the repository at this point in the history
Signed-off-by: Sean Young <[email protected]>
  • Loading branch information
seanyoung committed Apr 27, 2024
1 parent a246b1a commit 9aa773b
Show file tree
Hide file tree
Showing 5 changed files with 258 additions and 25 deletions.
5 changes: 4 additions & 1 deletion src/bin/commands/transmit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,10 @@ fn encode_args(transmit: &crate::Transmit) -> Message {
fn encode_keymap(args: &crate::TransmitKeymap) -> Message {
let remotes = match Keymap::parse(&args.keymap) {
Ok(r) => r,
Err(_) => std::process::exit(2),
Err(e) => {
log::error!("{e}");
std::process::exit(2);
}
};

if !args.codes.is_empty() {
Expand Down
2 changes: 2 additions & 0 deletions src/keymap/encode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,8 @@ impl Keymap {
}
};

log::debug!("using irp for encoding: {irp}");

let irp = Irp::parse(irp)?;

let mut vars = Vartable::new();
Expand Down
63 changes: 44 additions & 19 deletions src/keymap/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,12 @@ fn string_to_scancode(s: &str) -> Result<u64, std::num::ParseIntError> {
}
impl Keymap {
pub fn parse(path: &Path) -> Result<Vec<Keymap>, String> {
let mut f = File::open(path).map_err(|e| format!("{e}"))?;
let mut f = File::open(path).map_err(|e| format!("{}: {e}", path.display()))?;

let mut contents = String::new();

f.read_to_string(&mut contents)
.map_err(|e| format!("{e}"))?;
.map_err(|e| format!("{}: {e}", path.display()))?;

Keymap::parse_text(&contents, path)
}
Expand All @@ -86,13 +86,16 @@ impl Keymap {
if filename.extension() == Some(OsStr::new("toml")) {
parse_toml(contents, filename)
} else {
text_keymap::keymap(contents).map_err(|pos| format!("parse error at {pos}"))
text_keymap::keymap(contents)
.map_err(|pos| format!("{}: parse error at {pos}", filename.display()))
}
}
}

fn parse_toml(contents: &str, filename: &Path) -> Result<Vec<Keymap>, String> {
let top = contents.parse::<Table>().map_err(|e| e.to_string())?;
let top = contents
.parse::<Table>()
.map_err(|e| format!("{}: {e}", filename.display()))?;

let Some(Value::Array(protocols)) = top.get("protocols") else {
return Err(format!(
Expand Down Expand Up @@ -136,44 +139,59 @@ fn parse_toml(contents: &str, filename: &Path) -> Result<Vec<Keymap>, String> {
if protocol == "raw" {
// find raw entries
let Some(Value::Array(e)) = entry.get("raw") else {
return Err("raw protocol is misssing raw entries".into());
return Err(format!(
"{}: raw protocol is misssing raw entries",
filename.display()
));
};

for e in e {
let Some(Value::String(keycode)) = e.get("keycode") else {
return Err("missing keycode".into());
return Err(format!("{}: missing keycode", filename.display()));
};

let raw = if let Some(Value::String(raw)) = e.get("raw") {
let raw = Message::parse(raw)?;
let raw =
Message::parse(raw).map_err(|e| format!("{}: {e}", filename.display()))?;
Some(raw)
} else {
None
};

let repeat = if let Some(Value::String(repeat)) = e.get("repeat") {
let repeat = Message::parse(repeat)?;
let repeat = Message::parse(repeat)
.map_err(|e| format!("{}: {e}", filename.display()))?;
Some(repeat)
} else {
None
};

let pronto = if let Some(Value::String(pronto)) = e.get("pronto") {
let pronto = Pronto::parse(pronto)?;
let pronto = Pronto::parse(pronto)
.map_err(|e| format!("{}: {e}", filename.display()))?;
Some(pronto)
} else {
None
};

if pronto.is_some() {
if raw.is_some() {
return Err("raw entry has both pronto hex code and raw".to_string());
return Err(format!(
"{}: raw entry has both pronto hex code and raw",
filename.display()
));
}
if repeat.is_some() {
return Err("raw entry has both pronto hex code and repeat".to_string());
return Err(format!(
"{}: raw entry has both pronto hex code and repeat",
filename.display()
));
}
} else if raw.is_none() {
return Err("raw entry has neither pronto hex code nor raw".to_string());
return Err(format!(
"{}: raw entry has neither pronto hex code nor raw",
filename.display()
));
}

raw_entries.push(Raw {
Expand All @@ -185,23 +203,30 @@ fn parse_toml(contents: &str, filename: &Path) -> Result<Vec<Keymap>, String> {
}
} else {
if entry.get("raw").is_some() {
return Err("raw entries for non-raw protocol".to_string());
return Err(format!(
"{}: raw entries for non-raw protocol",
filename.display()
));
}

if protocol == "irp" {
if let Some(Value::String(entry)) = entry.get("irp") {
irp = Some(entry.to_owned());
}
} else if entry.get("irp").is_some() {
return Err("set the protocol to irp when using irp".to_string());
return Err(format!(
"{}: set the protocol to irp when using irp",
filename.display()
));
} else {
irp = bpf_protocol_irp(protocol, entry.as_table().unwrap());
}

if let Some(Value::Table(codes)) = entry.get("scancodes") {
for (scancode, keycode) in codes {
let scancode = string_to_scancode(scancode)
.map_err(|_| format!("{scancode} is a not valid scancode"))?;
let scancode = string_to_scancode(scancode).map_err(|_| {
format!("{}: {scancode} is a not valid scancode", filename.display())
})?;
let Value::String(keycode) = keycode else {
return Err(format!("{}: keycode should be string", filename.display()));
};
Expand Down Expand Up @@ -441,7 +466,7 @@ fn parse_toml_test() {

assert_eq!(
Keymap::parse_text(s, Path::new("x.toml")),
Err("raw protocol is misssing raw entries".to_string())
Err("x.toml: raw protocol is misssing raw entries".to_string())
);

let s = r#"
Expand All @@ -454,7 +479,7 @@ fn parse_toml_test() {

assert_eq!(
Keymap::parse_text(s, Path::new("x.toml")),
Err("raw entry has neither pronto hex code nor raw".to_string())
Err("x.toml: raw entry has neither pronto hex code nor raw".to_string())
);

let s = r#"
Expand All @@ -468,7 +493,7 @@ fn parse_toml_test() {

assert_eq!(
Keymap::parse_text(s, Path::new("x.toml")),
Err("raw entry has neither pronto hex code nor raw".to_string())
Err("x.toml: raw entry has neither pronto hex code nor raw".to_string())
);
}

Expand Down
70 changes: 70 additions & 0 deletions testdata/rc_keymaps/rc6_mce.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# Generated with gen_keytables.pl from drivers/media/rc/keymaps/rc-rc6-mce.c
[[protocols]]
name = "rc6_mce"
protocol = "rc6"
variant = "rc6_mce"
[protocols.scancodes]
0x800f0400 = "KEY_NUMERIC_0"
0x800f0401 = "KEY_NUMERIC_1"
0x800f0402 = "KEY_NUMERIC_2"
0x800f0403 = "KEY_NUMERIC_3"
0x800f0404 = "KEY_NUMERIC_4"
0x800f0405 = "KEY_NUMERIC_5"
0x800f0406 = "KEY_NUMERIC_6"
0x800f0407 = "KEY_NUMERIC_7"
0x800f0408 = "KEY_NUMERIC_8"
0x800f0409 = "KEY_NUMERIC_9"
0x800f040a = "KEY_DELETE"
0x800f040b = "KEY_ENTER"
0x800f040c = "KEY_SLEEP"
0x800f040d = "KEY_MEDIA"
0x800f040e = "KEY_MUTE"
0x800f040f = "KEY_INFO"
0x800f0410 = "KEY_VOLUMEUP"
0x800f0411 = "KEY_VOLUMEDOWN"
0x800f0412 = "KEY_CHANNELUP"
0x800f0413 = "KEY_CHANNELDOWN"
0x800f0414 = "KEY_FASTFORWARD"
0x800f0415 = "KEY_REWIND"
0x800f0416 = "KEY_PLAY"
0x800f0417 = "KEY_RECORD"
0x800f0418 = "KEY_PAUSE"
0x800f0419 = "KEY_STOP"
0x800f041a = "KEY_NEXT"
0x800f041b = "KEY_PREVIOUS"
0x800f041c = "KEY_NUMERIC_POUND"
0x800f041d = "KEY_NUMERIC_STAR"
0x800f041e = "KEY_UP"
0x800f041f = "KEY_DOWN"
0x800f0420 = "KEY_LEFT"
0x800f0421 = "KEY_RIGHT"
0x800f0422 = "KEY_OK"
0x800f0423 = "KEY_EXIT"
0x800f0424 = "KEY_DVD"
0x800f0425 = "KEY_TUNER"
0x800f0426 = "KEY_EPG"
0x800f0427 = "KEY_ZOOM"
0x800f0432 = "KEY_MODE"
0x800f0433 = "KEY_PRESENTATION"
0x800f0434 = "KEY_EJECTCD"
0x800f043a = "KEY_BRIGHTNESSUP"
0x800f0446 = "KEY_TV"
0x800f0447 = "KEY_AUDIO"
0x800f0448 = "KEY_PVR"
0x800f0449 = "KEY_CAMERA"
0x800f044a = "KEY_VIDEO"
0x800f044c = "KEY_LANGUAGE"
0x800f044d = "KEY_TITLE"
0x800f044e = "KEY_PRINT"
0x800f0450 = "KEY_RADIO"
0x800f045a = "KEY_SUBTITLE"
0x800f045b = "KEY_RED"
0x800f045c = "KEY_GREEN"
0x800f045d = "KEY_YELLOW"
0x800f045e = "KEY_BLUE"
0x800f0465 = "KEY_POWER2"
0x800f0469 = "KEY_MESSENGER"
0x800f046e = "KEY_PLAYPAUSE"
0x800f046f = "KEY_PLAYER"
0x800f0480 = "KEY_BRIGHTNESSDOWN"
0x800f0481 = "KEY_PLAYPAUSE"
Loading

0 comments on commit 9aa773b

Please sign in to comment.