aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJonas Maier <jonas@x77.dev>2026-05-03 16:44:08 +0200
committerJonas Maier <jonas@x77.dev>2026-05-03 16:44:08 +0200
commitf4d2b541f2dd499044ac428e4c266cf48c91b4d8 (patch)
tree1d1431914a0bc12049a721ae03bc99903de8d90a /src
parentf07eb9509920be72e98ebd51caf7a8edb768371c (diff)
downloadpish-f4d2b541f2dd499044ac428e4c266cf48c91b4d8.tar.gz
source builtin
Diffstat (limited to 'src')
-rw-r--r--src/main.rs29
-rw-r--r--src/run/builtin.rs27
-rw-r--r--src/run/mod.rs13
3 files changed, 40 insertions, 29 deletions
diff --git a/src/main.rs b/src/main.rs
index 5ec5a56..a54f4fc 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -374,34 +374,7 @@ impl Session {
}
fn exec_rc_file(se: Arc<Mutex<Session>>) {
- let rcfile = basedir::config_dir().join(".pishrc");
- let mut rc = Vec::new();
- if !rcfile.exists() {
- return;
- }
-
- let mut f = match File::open(&rcfile) {
- Ok(f) => f,
- Err(e) => {
- println!("failed to open {rcfile:?}: {e:?}");
- return;
- }
- };
-
- if let Err(e) = f.read_to_end(&mut rc) {
- println!("failed to read {rcfile:?}: {e:?}");
- return;
- }
-
- let script = match parse::Script::parse_from_bytes(&rc) {
- Ok(s) => s,
- Err(e) => {
- println!("failed to parse rc file: {e:?}");
- return;
- }
- };
-
- run::run_script(se, script);
+ let _ = run::source(se, basedir::config_dir().join(".pishrc").as_os_str().as_bytes());
}
fn event_loop() {
diff --git a/src/run/builtin.rs b/src/run/builtin.rs
index 4a7e332..a52c345 100644
--- a/src/run/builtin.rs
+++ b/src/run/builtin.rs
@@ -665,7 +665,7 @@ impl Builtin for bind {
if args.len() == 0 {
let mut dump = |map: &HashMap<BString, crate::parse::Command<PostExpansion>>,
- category: &str|
+ category: &str|
-> std::io::Result<()> {
let mut entries: Vec<_> = map.iter().collect();
entries.sort_by_key(|x| x.0);
@@ -766,6 +766,8 @@ impl Builtin for exit {
break num;
};
+ println!("bye!\r");
+
std::process::exit(exit_code);
}
@@ -831,3 +833,26 @@ impl Builtin for ct {
Ok(())
}
}
+
+#[derive(Copy, Clone)]
+pub struct source;
+
+impl Builtin for source {
+ fn name(&self) -> &str {
+ "source"
+ }
+
+ fn io(
+ &self,
+ session: Arc<Mutex<Session>>,
+ args: &[BString],
+ _stdin: &mut dyn Read,
+ _stdout: &mut dyn Write,
+ ) -> Result {
+ for file in args.iter() {
+ // TODO: useful error propagation (?)
+ super::source(session.clone(), file).map_err(|_| Error::Exit(-1))?;
+ }
+ Ok(())
+ }
+}
diff --git a/src/run/mod.rs b/src/run/mod.rs
index f727b01..459c898 100644
--- a/src/run/mod.rs
+++ b/src/run/mod.rs
@@ -19,6 +19,7 @@ pub enum ExecError {
ErrorStack(Vec<ExecError>),
Panic,
AliasDepthExceeded,
+ Parse(crate::parse::ParseError),
}
impl ExecError {
@@ -61,6 +62,7 @@ impl ExecError {
out
}
ExecError::AliasDepthExceeded => "alias depth exceeded".to_string(),
+ ExecError::Parse(pe) => format!("parse error: {pe:?}"),
}
}
}
@@ -515,6 +517,16 @@ pub fn run_script(se: Arc<Mutex<Session>>, script: crate::parse::Script) {
}
}
+pub fn source(se: Arc<Mutex<Session>>, file: &bstr) -> Result<(), ExecError> {
+ let mut f = File::open(OsStr::from_bytes(file)).map_err(ExecError::IO)?;
+ let mut buf = Vec::new();
+ f.read_to_end(&mut buf).map_err(ExecError::IO)?;
+ let script = parse::Script::parse_from_bytes(&buf).map_err(ExecError::Parse)?;
+ // TODO: error propagation
+ run_script(se, script);
+ Ok(())
+}
+
#[derive(Debug)]
pub enum BuiltinError {
IO(std::io::Error),
@@ -579,6 +591,7 @@ const BUILTINS: &[&'static dyn BuiltinClone] = &[
&builtin::bind::new(),
&builtin::exit,
&builtin::ct,
+ &builtin::source,
];
pub fn builtin_map() -> HashMap<BString, &'static dyn BuiltinClone> {