Skip to main content

yash_builtin/
unset.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//! Unset built-in
18//!
19//! This module implements the [`unset` built-in], which unsets shell variables
20//! or functions.
21//!
22//! [`unset` built-in]: https://magicant.github.io/yash-rs/builtins/unset.html
23
24use crate::Result;
25use crate::common::report::{merge_reports, report_error, report_failure};
26use yash_env::Env;
27use yash_env::semantics::Field;
28use yash_env::system::{Fcntl, Isatty, Write};
29
30/// Selection of what to unset
31#[derive(Debug, Clone, Copy, Default, Eq, Hash, PartialEq)]
32#[non_exhaustive]
33pub enum Mode {
34    /// Unsets shell variables.
35    #[default]
36    Variables,
37
38    /// Unsets shell functions.
39    Functions,
40}
41
42/// Parsed command line arguments
43#[derive(Debug, Clone, Default, Eq, PartialEq)]
44#[non_exhaustive]
45pub struct Command {
46    /// What to unset
47    pub mode: Mode,
48
49    /// Names of shell variables or functions to unset
50    pub names: Vec<Field>,
51}
52
53pub mod semantics;
54pub mod syntax;
55
56/// Entry point of the `unset` built-in
57pub async fn main<S>(env: &mut Env<S>, args: Vec<Field>) -> Result
58where
59    S: Fcntl + Isatty + Write,
60{
61    let command = match syntax::parse(env, args) {
62        Ok(command) => command,
63        Err(e) => return report_error(env, &e).await,
64    };
65
66    match command.mode {
67        Mode::Variables => {
68            let errors = semantics::unset_variables(env, &command.names);
69            match merge_reports(&errors) {
70                None => Result::default(),
71                Some(report) => report_failure(env, report).await,
72            }
73        }
74
75        Mode::Functions => {
76            let errors = semantics::unset_functions(env, &command.names);
77            match merge_reports(&errors) {
78                None => Result::default(),
79                Some(report) => report_failure(env, report).await,
80            }
81        }
82    }
83}