aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Duerr <contact@christianduerr.com>2019-11-04 18:06:02 +0100
committerGitHub <noreply@github.com>2019-11-04 18:06:02 +0100
commit5e3690d7ca88ab7eaf766ebdf478bf0c8076e694 (patch)
tree8586a89828b19398b7ed8866a59209bc5f402bd8
parent084f853e3f4b566c783867d9f043f6a1d974ba59 (diff)
parentc093a671ce3abaebef4c8e2a71a76ad8cd4670a5 (diff)
downloadr-alacritty-vte-5e3690d7ca88ab7eaf766ebdf478bf0c8076e694.tar.gz
r-alacritty-vte-5e3690d7ca88ab7eaf766ebdf478bf0c8076e694.tar.bz2
r-alacritty-vte-5e3690d7ca88ab7eaf766ebdf478bf0c8076e694.zip
Bump version to 0.4.0
-rw-r--r--CHANGELOG.md4
-rw-r--r--Cargo.toml2
-rw-r--r--examples/parselog.rs23
-rw-r--r--src/lib.rs154
4 files changed, 109 insertions, 74 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ba861ac..443305b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,10 @@
CHANGELOG
=========
+## 0.4.0
+
+- Fix handling of DCS escapes
+
## 0.3.3
- Fix off-by-one error in CSI parsing when params list was at max length
diff --git a/Cargo.toml b/Cargo.toml
index 6cae249..2d7a457 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "vte"
-version = "0.3.3"
+version = "0.4.0"
authors = ["Joe Wilm <joe@jwilm.com>"]
license = "Apache-2.0 OR MIT"
description = "Parser for implementing terminal emulators"
diff --git a/examples/parselog.rs b/examples/parselog.rs
index acd56dc..b63bcf8 100644
--- a/examples/parselog.rs
+++ b/examples/parselog.rs
@@ -16,8 +16,10 @@ impl vte::Perform for Log {
}
fn hook(&mut self, params: &[i64], intermediates: &[u8], ignore: bool, c: char) {
- println!("[hook] params={:?}, intermediates={:?}, ignore={:?}, char={:?}",
- params, intermediates, ignore, c);
+ println!(
+ "[hook] params={:?}, intermediates={:?}, ignore={:?}, char={:?}",
+ params, intermediates, ignore, c
+ );
}
fn put(&mut self, byte: u8) {
@@ -33,15 +35,18 @@ impl vte::Perform for Log {
}
fn csi_dispatch(&mut self, params: &[i64], intermediates: &[u8], ignore: bool, c: char) {
- println!("[csi_dispatch] params={:?}, intermediates={:?}, ignore={:?}, char={:?}",
- params, intermediates, ignore, c);
+ println!(
+ "[csi_dispatch] params={:?}, intermediates={:?}, ignore={:?}, char={:?}",
+ params, intermediates, ignore, c
+ );
}
fn esc_dispatch(&mut self, params: &[i64], intermediates: &[u8], ignore: bool, byte: u8) {
- println!("[esc_dispatch] params={:?}, intermediates={:?}, ignore={:?}, byte={:02x}",
- params, intermediates, ignore, byte);
+ println!(
+ "[esc_dispatch] params={:?}, intermediates={:?}, ignore={:?}, byte={:02x}",
+ params, intermediates, ignore, byte
+ );
}
-
}
fn main() {
@@ -51,7 +56,7 @@ fn main() {
let mut statemachine = vte::Parser::new();
let mut parser = Log;
- let mut buf: [u8; 2048] = unsafe { std::mem::uninitialized() };
+ let mut buf = [0; 2048];
loop {
match handle.read(&mut buf) {
@@ -60,7 +65,7 @@ fn main() {
for byte in &buf[..n] {
statemachine.advance(&mut parser, *byte);
}
- },
+ }
Err(err) => {
println!("err: {}", err);
break;
diff --git a/src/lib.rs b/src/lib.rs
index 4bd5d78..1b9f58c 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -34,34 +34,29 @@
extern crate utf8parse as utf8;
-use core::mem;
+use core::mem::{self, MaybeUninit};
-mod table;
mod definitions;
+mod table;
-use definitions::{Action, State, unpack};
+use definitions::{unpack, Action, State};
-use table::{EXIT_ACTIONS, ENTRY_ACTIONS, STATE_CHANGE};
+use table::{ENTRY_ACTIONS, EXIT_ACTIONS, STATE_CHANGE};
impl State {
/// Get exit action for this state
#[inline(always)]
pub fn exit_action(&self) -> Action {
- unsafe {
- *EXIT_ACTIONS.get_unchecked(*self as usize)
- }
+ unsafe { *EXIT_ACTIONS.get_unchecked(*self as usize) }
}
/// Get entry action for this state
#[inline(always)]
pub fn entry_action(&self) -> Action {
- unsafe {
- *ENTRY_ACTIONS.get_unchecked(*self as usize)
- }
+ unsafe { *ENTRY_ACTIONS.get_unchecked(*self as usize) }
}
}
-
const MAX_INTERMEDIATES: usize = 2;
const MAX_OSC_RAW: usize = 1024;
const MAX_PARAMS: usize = 16;
@@ -156,7 +151,8 @@ impl Parser {
#[inline]
fn process_utf8<P>(&mut self, performer: &mut P, byte: u8)
- where P: Perform
+ where
+ P: Perform,
{
let mut receiver = VtUtf8Receiver(performer, &mut self.state);
let utf8_parser = &mut self.utf8_parser;
@@ -165,7 +161,8 @@ impl Parser {
#[inline]
fn perform_state_change<P>(&mut self, performer: &mut P, state: State, action: Action, byte: u8)
- where P: Perform
+ where
+ P: Perform,
{
macro_rules! maybe_action {
($action:expr, $arg:expr) => {
@@ -173,16 +170,16 @@ impl Parser {
Action::None => (),
action => {
self.perform_action(performer, action, $arg);
- },
+ }
}
- }
+ };
}
match state {
State::Anywhere => {
// Just run the action
self.perform_action(performer, action, byte);
- },
+ }
state => {
// Exit action for previous state
let exit_action = self.state.exit_action();
@@ -205,16 +202,19 @@ impl Parser {
/// The aliasing is needed here for multiple slices into self.osc_raw
#[inline]
fn osc_dispatch<P: Perform>(&self, performer: &mut P) {
- let mut slices: [&[u8]; MAX_PARAMS] = unsafe { mem::uninitialized() };
+ let mut slices: [MaybeUninit<&[u8]>; MAX_PARAMS] =
+ unsafe { MaybeUninit::uninit().assume_init() };
for i in 0..self.osc_num_params {
let indices = self.osc_params[i];
- slices[i] = &self.osc_raw[indices.0..indices.1];
+ slices[i] = MaybeUninit::new(&self.osc_raw[indices.0..indices.1]);
}
- performer.osc_dispatch(
- &slices[..self.osc_num_params],
- );
+ unsafe {
+ performer.osc_dispatch(mem::transmute::<_, &[&[u8]]>(
+ &slices[..self.osc_num_params],
+ ));
+ }
}
#[inline]
@@ -232,12 +232,12 @@ impl Parser {
self.ignoring,
byte as char,
);
- },
+ }
Action::Put => performer.put(byte),
Action::OscStart => {
self.osc_idx = 0;
self.osc_num_params = 0;
- },
+ }
Action::OscPut => {
let idx = self.osc_idx;
if idx == self.osc_raw.len() {
@@ -254,7 +254,7 @@ impl Parser {
// First param is special - 0 to current byte index
0 => {
self.osc_params[param_idx] = (0, idx);
- },
+ }
// All other params depend on previous indexing
_ => {
@@ -269,7 +269,7 @@ impl Parser {
self.osc_raw[idx] = byte;
self.osc_idx += 1;
}
- },
+ }
Action::OscEnd => {
let param_idx = self.osc_num_params;
let idx = self.osc_idx;
@@ -282,7 +282,7 @@ impl Parser {
0 => {
self.osc_params[param_idx] = (0, idx);
self.osc_num_params += 1;
- },
+ }
// All other params depend on previous indexing
_ => {
@@ -293,7 +293,7 @@ impl Parser {
}
}
self.osc_dispatch(performer);
- },
+ }
Action::Unhook => performer.unhook(),
Action::CsiDispatch => {
self.params[self.num_params] = self.param;
@@ -303,20 +303,15 @@ impl Parser {
self.params(),
self.intermediates(),
self.ignoring,
- byte as char
+ byte as char,
);
self.num_params = 0;
self.param = 0;
}
Action::EscDispatch => {
- performer.esc_dispatch(
- self.params(),
- self.intermediates(),
- self.ignoring,
- byte
- );
- },
+ performer.esc_dispatch(self.params(), self.intermediates(), self.ignoring, byte);
+ }
Action::Ignore | Action::None => (),
Action::Collect => {
if self.intermediate_idx == MAX_INTERMEDIATES {
@@ -325,7 +320,7 @@ impl Parser {
self.intermediates[self.intermediate_idx] = byte;
self.intermediate_idx += 1;
}
- },
+ }
Action::Param => {
if byte == b';' {
// Completed a param
@@ -343,15 +338,15 @@ impl Parser {
self.param = self.param.saturating_mul(10);
self.param = self.param.saturating_add((byte - b'0') as i64);
}
- },
+ }
Action::Clear => {
self.intermediate_idx = 0;
self.num_params = 0;
self.ignoring = false;
- },
+ }
Action::BeginUtf8 => {
self.process_utf8(performer, byte);
- },
+ }
}
}
}
@@ -416,15 +411,15 @@ extern crate std;
#[cfg(test)]
mod tests {
- use std::vec::Vec;
use super::{Parser, Perform};
use core::i64;
+ use std::vec::Vec;
- static OSC_BYTES: &'static [u8] = &[0x1b, 0x5d, // Begin OSC
- b'2', b';', b'j', b'w', b'i', b'l', b'm', b'@', b'j', b'w', b'i', b'l',
- b'm', b'-', b'd', b'e', b's', b'k', b':', b' ', b'~', b'/', b'c', b'o',
- b'd', b'e', b'/', b'a', b'l', b'a', b'c', b'r', b'i', b't', b't', b'y',
- 0x07 // End OSC
+ static OSC_BYTES: &'static [u8] = &[
+ 0x1b, 0x5d, // Begin OSC
+ b'2', b';', b'j', b'w', b'i', b'l', b'm', b'@', b'j', b'w', b'i', b'l', b'm', b'-', b'd',
+ b'e', b's', b'k', b':', b' ', b'~', b'/', b'c', b'o', b'd', b'e', b'/', b'a', b'l', b'a',
+ b'c', b'r', b'i', b't', b't', b'y', 0x07, // End OSC
];
#[derive(Default)]
@@ -445,8 +440,22 @@ mod tests {
self.dispatched_osc = true;
self.params = params.iter().map(|p| p.to_vec()).collect();
}
- fn csi_dispatch(&mut self, _params: &[i64], _intermediates: &[u8], _ignore: bool, _c: char) {}
- fn esc_dispatch(&mut self, _params: &[i64], _intermediates: &[u8], _ignore: bool, _byte: u8) {}
+ fn csi_dispatch(
+ &mut self,
+ _params: &[i64],
+ _intermediates: &[u8],
+ _ignore: bool,
+ _c: char,
+ ) {
+ }
+ fn esc_dispatch(
+ &mut self,
+ _params: &[i64],
+ _intermediates: &[u8],
+ _ignore: bool,
+ _byte: u8,
+ ) {
+ }
}
#[derive(Default)]
@@ -461,12 +470,19 @@ mod tests {
fn hook(&mut self, _params: &[i64], _intermediates: &[u8], _ignore: bool, _: char) {}
fn put(&mut self, _byte: u8) {}
fn unhook(&mut self) {}
- fn osc_dispatch(&mut self, _params: &[&[u8]]) { }
+ fn osc_dispatch(&mut self, _params: &[&[u8]]) {}
fn csi_dispatch(&mut self, params: &[i64], _intermediates: &[u8], _ignore: bool, _c: char) {
self.dispatched_csi = true;
self.params.push(params.to_vec());
}
- fn esc_dispatch(&mut self, _params: &[i64], _intermediates: &[u8], _ignore: bool, _byte: u8) {}
+ fn esc_dispatch(
+ &mut self,
+ _params: &[i64],
+ _intermediates: &[u8],
+ _ignore: bool,
+ _byte: u8,
+ ) {
+ }
}
#[derive(Default)]
@@ -490,9 +506,23 @@ mod tests {
fn unhook(&mut self) {
self.dispatched_dcs = true;
}
- fn osc_dispatch(&mut self, _params: &[&[u8]]) { }
- fn csi_dispatch(&mut self, _params: &[i64], _intermediates: &[u8], _ignore: bool, _c: char) {}
- fn esc_dispatch(&mut self, _params: &[i64], _intermediates: &[u8], _ignore: bool, _byte: u8) {}
+ fn osc_dispatch(&mut self, _params: &[&[u8]]) {}
+ fn csi_dispatch(
+ &mut self,
+ _params: &[i64],
+ _intermediates: &[u8],
+ _ignore: bool,
+ _c: char,
+ ) {
+ }
+ fn esc_dispatch(
+ &mut self,
+ _params: &[i64],
+ _intermediates: &[u8],
+ _ignore: bool,
+ _byte: u8,
+ ) {
+ }
}
#[test]
@@ -552,7 +582,6 @@ mod tests {
for param in dispatcher.params.iter() {
assert_eq!(param.len(), 0);
}
-
}
#[test]
@@ -565,7 +594,6 @@ mod tests {
let mut dispatcher = CsiDispatcher::default();
assert!(!dispatcher.dispatched_csi);
-
// Run parser using OSC_BYTES
let mut parser = Parser::new();
for byte in INPUT {
@@ -576,7 +604,6 @@ mod tests {
assert!(dispatcher.dispatched_csi);
assert_eq!(dispatcher.params.len(), 1);
assert_eq!(dispatcher.params[0].len(), MAX_PARAMS);
-
}
#[test]
@@ -594,7 +621,6 @@ mod tests {
#[test]
fn parse_semi_set_underline() {
-
// Create dispatcher and check state
let mut dispatcher = CsiDispatcher::default();
@@ -621,20 +647,21 @@ mod tests {
}
assert_eq!(dispatcher.params[0], &[i64::MAX as i64]);
-
}
#[test]
fn parse_osc_with_utf8_arguments() {
static INPUT: &'static [u8] = &[
- 0x0d, 0x1b, 0x5d, 0x32, 0x3b, 0x65, 0x63, 0x68, 0x6f, 0x20, 0x27,
- 0xc2, 0xaf, 0x5c, 0x5f, 0x28, 0xe3, 0x83, 0x84, 0x29, 0x5f, 0x2f,
- 0xc2, 0xaf, 0x27, 0x20, 0x26, 0x26, 0x20, 0x73, 0x6c, 0x65, 0x65,
- 0x70, 0x20, 0x31, 0x07
+ 0x0d, 0x1b, 0x5d, 0x32, 0x3b, 0x65, 0x63, 0x68, 0x6f, 0x20, 0x27, 0xc2, 0xaf, 0x5c,
+ 0x5f, 0x28, 0xe3, 0x83, 0x84, 0x29, 0x5f, 0x2f, 0xc2, 0xaf, 0x27, 0x20, 0x26, 0x26,
+ 0x20, 0x73, 0x6c, 0x65, 0x65, 0x70, 0x20, 0x31, 0x07,
];
// Create dispatcher and check state
- let mut dispatcher = OscDispatcher { params: vec![], dispatched_osc: false };
+ let mut dispatcher = OscDispatcher {
+ params: vec![],
+ dispatched_osc: false,
+ };
// Run parser using OSC_BYTES
let mut parser = Parser::new();
@@ -650,8 +677,7 @@ mod tests {
#[test]
fn parse_dcs() {
static INPUT: &'static [u8] = &[
- 0x1b, 0x50, 0x30, 0x3b, 0x31, 0x7c, 0x31, 0x37, 0x2f, 0x61, 0x62,
- 0x9c,
+ 0x1b, 0x50, 0x30, 0x3b, 0x31, 0x7c, 0x31, 0x37, 0x2f, 0x61, 0x62, 0x9c,
];
// Create dispatcher and check state