yash_builtin/source.rs
1// This file is part of yash, an extended POSIX shell.
2// Copyright (C) 2023 WATANABE Yuki
3//
4// This program is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with this program. If not, see <https://www.gnu.org/licenses/>.
16
17//! Source (`.`) built-in
18//!
19//! This module implements the [`source` (`.`) built-in], which reads and executes
20//! commands from a file.
21//!
22//! [`source` (`.`) built-in]: https://magicant.github.io/yash-rs/builtins/source.html
23//!
24//! # Implementation notes
25//!
26//! When there are any positional parameters specified, a regular
27//! [variable context](yash_env::variable::Context) is pushed to secure the
28//! existing positional parameters. The context is popped when the execution of
29//! the file is finished.
30//!
31//! This built-in requires a [`RunReadEvalLoop`] instance to be available in the
32//! environment's [`any`](yash_env::Env::any) storage.
33//!
34//! [`RunReadEvalLoop`]: yash_env::semantics::RunReadEvalLoop
35
36use crate::Result;
37use yash_env::Env;
38#[cfg(doc)]
39use yash_env::semantics::ExitStatus;
40use yash_env::semantics::Field;
41use yash_env::system::{Close, Dup, Fcntl, Isatty, Open, Read, Write};
42
43mod semantics;
44pub mod syntax;
45
46/// Set of information that defines the behavior of a single invocation of the
47/// `.` built-in
48///
49/// The [`syntax::parse`] function parses the command line arguments and
50/// constructs a `Command` value. The [`execute`](Self::execute) method
51/// executes the command.
52#[derive(Clone, Debug, Eq, PartialEq)]
53#[non_exhaustive]
54pub struct Command {
55 /// Pathname of the file to be executed
56 pub file: Field,
57 /// Arguments to be passed to the file
58 pub params: Vec<Field>,
59}
60
61/// Entry point of the `.` built-in execution
62pub async fn main<S>(env: &mut Env<S>, args: Vec<Field>) -> Result
63where
64 S: Close + Dup + Fcntl + Isatty + Open + Read + Write + 'static,
65{
66 match syntax::parse(env, args) {
67 Ok(command) => command.execute(env).await,
68 Err(error) => error.report(env).await,
69 }
70}