aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJonas Maier <>2026-03-05 08:45:45 +0100
committerJonas Maier <>2026-03-05 08:45:45 +0100
commit9e617dde12565ba4e0ec737893b204a5e5271689 (patch)
tree69ed1d0fb097e5df0101871904f7fefc4519adf2 /src
parentdb1d0bb7c37e2c2943fe0fd8b6857110fdd00087 (diff)
downloadpish-9e617dde12565ba4e0ec737893b204a5e5271689.tar.gz
some parsing, also add panic that does not spill
Diffstat (limited to 'src')
-rw-r--r--src/main.rs7
-rw-r--r--src/panic.rs48
-rw-r--r--src/parse.rs7
-rw-r--r--src/raw.rs4
4 files changed, 65 insertions, 1 deletions
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<u8>) {
+
+ 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<u8>) {
}
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<Command>,
}
+#[derive(Debug)]
pub struct Command {
pub path: Vec<u8>,
pub args: Vec<Vec<u8>>,
}
-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();
}
}