Skip to content

Commit

Permalink
Define Handle and implement for expansion error
Browse files Browse the repository at this point in the history
  • Loading branch information
magicant committed Aug 25, 2021
1 parent 2dd6f1a commit b536888
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 1 deletion.
3 changes: 2 additions & 1 deletion yash-semantics/src/expansion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,10 @@ pub use yash_env::expansion::*;
pub use quote_removal::*;

/// Types of errors that may occur in the word expansion.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum ErrorCause {
// TODO Define error cause types
Dummy(String),
}

/// Explanation of an expansion failure.
Expand Down
45 changes: 45 additions & 0 deletions yash-semantics/src/handle_impl.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// This file is part of yash, an extended POSIX shell.
// Copyright (C) 2021 WATANABE Yuki
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.

//! Implementations of [`Handle`].

use crate::ExitStatus;
use crate::Handle;
use async_trait::async_trait;
use yash_env::Env;

#[async_trait(?Send)]
impl Handle<crate::expansion::Error> for Env {
/// Prints an error message and sets the exit status to non-zero.
///
/// This function handles an expansion error by printing an error message
/// that describes the error to the standard error and setting the exit
/// status to [`ExitStatus::ERROR`]. Note that other POSIX-compliant
/// implementations may use different non-zero exit statuses.
async fn handle(&mut self, error: crate::expansion::Error) -> super::Result {
use crate::expansion::ErrorCause::*;
// TODO Localize the message
// TODO Pretty-print the error location
match error.cause {
Dummy(message) => {
self.print_error(&format_args!("dummy error: {}", message))
.await
}
};
self.exit_status = ExitStatus::ERROR;
Ok(())
}
}
12 changes: 12 additions & 0 deletions yash-semantics/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ pub mod command_search;
mod compound;
pub mod expansion;
mod function_definition;
mod handle_impl;
mod pipeline;
mod simple_command;

Expand All @@ -45,6 +46,17 @@ pub trait Command {
async fn execute(&self, env: &mut Env) -> Result;
}

/// Error handler.
///
/// Most errors in the shell are handled by printing an error message to the
/// standard error and returning a non-zero exit status. This trait provides a
/// standard interface for implementing that behavior.
#[async_trait(?Send)]
pub trait Handle<E> {
/// Handles the argument error.
async fn handle(&mut self, error: E) -> Result;
}

// TODO Probably we should implement a read-execute loop in here

#[cfg(test)]
Expand Down

0 comments on commit b536888

Please sign in to comment.