diff --git a/yash-semantics/src/command_impl/compound_command.rs b/yash-semantics/src/command_impl/compound_command.rs index 051ed6a0..529d8ae4 100644 --- a/yash-semantics/src/command_impl/compound_command.rs +++ b/yash-semantics/src/command_impl/compound_command.rs @@ -16,6 +16,7 @@ //! Implementation of the compound command semantics. +mod case; mod for_loop; mod r#if; mod subshell; @@ -25,7 +26,6 @@ use super::perform_redirs; use super::Command; use crate::redir::RedirGuard; use async_trait::async_trait; -use std::ops::ControlFlow::Continue; use yash_env::semantics::Result; use yash_env::Env; use yash_syntax::syntax; @@ -80,7 +80,14 @@ impl Command for syntax::FullCompoundCommand { /// status, it runs the `else` clause, if any. In case the command has no `else` /// clause, the final exit status will be zero. /// -/// TODO Elaborate +/// # Case conditional construct +/// +/// The "case" command expands the subject word and executes the body of the +/// first item with a pattern matching the word. Each pattern is subjected to +/// word expansion before matching. +/// +/// POSIX does not specify the order in which the shell tests multiple patterns +/// in an item. This implementation tries them in the order of appearance. #[async_trait(?Send)] impl Command for syntax::CompoundCommand { async fn execute(&self, env: &mut Env) -> Result { @@ -97,12 +104,7 @@ impl Command for syntax::CompoundCommand { elifs, r#else, } => r#if::execute(env, condition, body, elifs, r#else).await, - // TODO execute case - _ => { - env.print_error(&format!("Not implemented: {}\n", self)) - .await; - Continue(()) - } + Case { subject, items } => case::execute(env, subject, items).await, } } } @@ -114,6 +116,7 @@ mod tests { use crate::tests::return_builtin; use assert_matches::assert_matches; use futures_executor::block_on; + use std::ops::ControlFlow::Continue; use std::rc::Rc; use std::str::from_utf8; use yash_env::semantics::ExitStatus; diff --git a/yash-semantics/src/command_impl/compound_command/case.rs b/yash-semantics/src/command_impl/compound_command/case.rs new file mode 100644 index 00000000..e4c2d6c5 --- /dev/null +++ b/yash-semantics/src/command_impl/compound_command/case.rs @@ -0,0 +1,28 @@ +// This file is part of yash, an extended POSIX shell. +// Copyright (C) 2022 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 . + +//! Execution of the case command + +use yash_env::semantics::Result; +use yash_env::Env; +use yash_syntax::syntax::CaseItem; +use std::ops::ControlFlow::Continue; +use yash_syntax::syntax::Word; + +/// Executes the case command. +pub async fn execute(_env: &mut Env, _subject: &Word, _items: &[CaseItem]) -> Result { + Continue(()) +}