From 9e617dde12565ba4e0ec737893b204a5e5271689 Mon Sep 17 00:00:00 2001 From: Jonas Maier <> Date: Thu, 5 Mar 2026 08:45:45 +0100 Subject: some parsing, also add panic that does not spill --- src/main.rs | 7 +++++++ src/panic.rs | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ src/parse.rs | 7 ++++++- src/raw.rs | 4 ++++ 4 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 src/panic.rs (limited to 'src') diff --git a/src/main.rs b/src/main.rs index 9b10890..edf5cb0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,6 +9,7 @@ mod cursor; mod linebuf; mod parse; mod raw; +mod panic; use linebuf::LineBuf; use raw::*; @@ -36,6 +37,10 @@ macro_rules! println { const PROMPT: &str = "> "; fn run_command(raw: &ScopedRawMode, line: Vec) { + + let parsed = parse::do_parse(&line); + println!("{parsed:?}"); + let mut words: Vec<&[u8]> = line.split(|x| *x == b' ').collect(); words.retain(|w| !w.is_empty()); @@ -84,6 +89,8 @@ fn run_command(raw: &ScopedRawMode, line: Vec) { } fn main() { + crate::panic::hook(); + let stdin = io::stdin(); let stdout = io::stdout(); diff --git a/src/panic.rs b/src/panic.rs new file mode 100644 index 0000000..0df0a4e --- /dev/null +++ b/src/panic.rs @@ -0,0 +1,48 @@ +use std::backtrace::{Backtrace, BacktraceStatus}; +use std::io::{self, Write}; +use std::panic::{self, PanicHookInfo}; +use std::sync::atomic::{AtomicBool, Ordering}; + +static EMIT_CARRIAGE_RETURN: AtomicBool = AtomicBool::new(false); + +pub fn enable_cr() { + EMIT_CARRIAGE_RETURN.store(true, Ordering::SeqCst); +} + +pub fn disable_cr() { + EMIT_CARRIAGE_RETURN.store(false, Ordering::SeqCst); +} + +// thread 'main' panicked at src/main.rs:59:25: +// not yet implemented: homedir +// stack backtrace: +// 0: __rustc::rust_begin_unwind at /rustc/1159e78c4747b02ef996e55082b704c09b970588/library/std/src/panicking.rs:697:5 +// 1: core::panicking::panic_fmt at /rustc/1159e78c4747b02ef996e55082b704c09b970588/library/core/src/panicking.rs:75:14 +// 2: pish::run_command at ./src/main.rs:59:25 +// note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace + +fn panic_hook(info: &PanicHookInfo<'_>) { + let mut msg = format!("{}\n", info); + + let bt = Backtrace::capture(); + match bt.status() { + BacktraceStatus::Unsupported => msg += "backtrace unsupported\n", + BacktraceStatus::Disabled => msg += "no backtrace", + _ => { + msg += &format!("{bt}\n"); + }, + } + + // TODO: add link to repo or sth + msg += "\n -== this is a bug ==-\n"; + + if EMIT_CARRIAGE_RETURN.load(Ordering::SeqCst) { + msg = msg.replace("\n", "\r\n"); + } + + let _ = io::stderr().write_all(msg.as_bytes()); +} + +pub fn hook() { + panic::set_hook(Box::new(panic_hook)); +} diff --git a/src/parse.rs b/src/parse.rs index ec4be30..27b07de 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -1,23 +1,28 @@ +#[derive(Debug)] pub enum Ast { AssignVar(AssignVar), Pipes(Pipes), } +#[derive(Debug)] pub struct AssignVar { pub to: String, // TODO: body } +#[derive(Debug)] pub struct Pipes { pub cmds: Vec, } +#[derive(Debug)] pub struct Command { pub path: Vec, pub args: Vec>, } -enum ParseError { +#[derive(Debug)] +pub enum ParseError { /// "clean" EOF, i.e. not in the middle of something Eof, diff --git a/src/raw.rs b/src/raw.rs index e116620..db2d269 100644 --- a/src/raw.rs +++ b/src/raw.rs @@ -1,5 +1,7 @@ use termios::*; +use crate::panic; + /// can toggle raw mode on a fd, at the latest disables it when it gets dropped pub struct ScopedRawMode { fd: i32, @@ -22,9 +24,11 @@ impl ScopedRawMode { let mut settings = self.settings.clone(); cfmakeraw(&mut settings); tcsetattr(self.fd, TCSANOW, &settings).unwrap(); + panic::enable_cr(); } pub fn disable(&self) { tcsetattr(self.fd, TCSANOW, &self.settings).unwrap(); + panic::disable_cr(); } } -- cgit v1.2.3