* [gentoo-commits] proj/libbash:master commit in: src/, src/builtins/tests/, src/core/, bashast/, test/, src/core/tests/, utils/, ...
@ 2011-06-03 14:42 Petteri Räty
0 siblings, 0 replies; only message in thread
From: Petteri Räty @ 2011-06-03 14:42 UTC (permalink / raw
To: gentoo-commits
commit: 5454166103257b3f19b829dbc2c824ad67acf344
Author: Mu Qiao <qiaomuf <AT> gentoo <DOT> org>
AuthorDate: Thu Jun 2 11:27:04 2011 +0000
Commit: Petteri Räty <betelgeuse <AT> gentoo <DOT> org>
CommitDate: Fri Jun 3 13:31:00 2011 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/libbash.git;a=commit;h=54541661
Core: make error handling POSIX compliant
For a non-interactive shell, an error condition encountered by a special
built-in or other type of utility shall cause the shell to write a
diagnostic message to standard error and exit.
---
bashast/libbashWalker.g | 2 +-
src/builtins/shopt_builtin.cpp | 38 ++++++--------------
src/builtins/shopt_builtin.h | 2 +-
src/builtins/source_builtin.cpp | 7 ----
src/builtins/tests/shopt_tests.cpp | 40 +++++++++++++--------
src/builtins/tests/source_tests.cpp | 6 ++--
src/core/bash_ast.cpp | 21 +++--------
src/core/bash_ast.h | 6 ---
src/core/interpreter.cpp | 2 +-
src/core/tests/bash_ast_test.cpp | 10 ++----
src/libbash.cpp | 12 +------
test/api_test.cpp | 17 ++++-----
utils/ast_printer.cpp | 66 +++++++++++++++++------------------
utils/variable_printer.cpp | 10 +++++-
14 files changed, 99 insertions(+), 140 deletions(-)
diff --git a/bashast/libbashWalker.g b/bashast/libbashWalker.g
index bbf442c..3bb0f40 100644
--- a/bashast/libbashWalker.g
+++ b/bashast/libbashWalker.g
@@ -494,8 +494,8 @@ execute_command[const std::string& name, std::vector<std::string>& libbash_args]
}
else
{
- std::cerr << name << " is not supported yet" << std::endl;
walker->set_status(1);
+ throw interpreter_exception(name + " is not supported yet");
}
}
(BANG { walker->set_status(!walker->get_status()); })?;
diff --git a/src/builtins/shopt_builtin.cpp b/src/builtins/shopt_builtin.cpp
index e9e239a..45e564c 100644
--- a/src/builtins/shopt_builtin.cpp
+++ b/src/builtins/shopt_builtin.cpp
@@ -27,49 +27,33 @@
#include "core/interpreter_exception.h"
#include "cppbash_builtin.h"
-int shopt_builtin::set_opt(const std::vector<std::string>& bash_args, bool value)
+void shopt_builtin::set_opt(const std::vector<std::string>& bash_args, bool value)
{
- int result = 0;
for(auto iter = bash_args.begin() + 1; iter != bash_args.end(); ++iter)
- {
- try
- {
_walker.set_option(*iter, value);
- }
- catch(interpreter_exception& e)
- {
- std::cerr << *iter << " is not a valid bash option" << std::endl;
- result = 1;
- }
- }
- return result;
}
int shopt_builtin::exec(const std::vector<std::string>& bash_args)
{
if(bash_args.empty())
- {
- *_err_stream << "Arguments required for shopt" << std::endl;
- return 1;
- }
+ throw interpreter_exception("Arguments required for shopt");
else if(bash_args[0].size() != 2)
- {
- *_err_stream << "Multiple arguments are not supported" << std::endl;
- return 1;
- }
+ throw interpreter_exception("Multiple arguments are not supported");
switch(bash_args[0][1])
{
case 'u':
- return set_opt(bash_args, false);
+ set_opt(bash_args, false);
+ break;
case 's':
- return set_opt(bash_args, true);
+ set_opt(bash_args, true);
+ break;
case 'q':
case 'o':
- *_err_stream << "shopt " << bash_args[0] << " is not supported yet" << std::endl;
- return 1;
+ throw interpreter_exception("shopt " + bash_args[0] + " is not supported yet");
default:
- *_err_stream << "Unrecognized option for shopt: " << bash_args[0] << std::endl;
- return 1;
+ throw interpreter_exception("Unrecognized option for shopt: " + bash_args[0]);
}
+
+ return 0;
}
diff --git a/src/builtins/shopt_builtin.h b/src/builtins/shopt_builtin.h
index d274dc3..905e4ba 100644
--- a/src/builtins/shopt_builtin.h
+++ b/src/builtins/shopt_builtin.h
@@ -27,7 +27,7 @@
class shopt_builtin : public virtual cppbash_builtin
{
- int set_opt(const std::vector<std::string>& bash_args, bool value);
+ void set_opt(const std::vector<std::string>& bash_args, bool value);
public:
BUILTIN_CONSTRUCTOR(shopt)
virtual int exec(const std::vector<std::string>& );
diff --git a/src/builtins/source_builtin.cpp b/src/builtins/source_builtin.cpp
index 4103576..6d43463 100644
--- a/src/builtins/source_builtin.cpp
+++ b/src/builtins/source_builtin.cpp
@@ -46,14 +46,7 @@ int source_builtin::exec(const std::vector<std::string>& bash_args)
auto& stored_ast = ast_cache[path];
if(!stored_ast)
- {
stored_ast.reset(new bash_ast(path));
- if(stored_ast->get_error_count())
- {
- std::cerr << path << " could not be parsed properly" << std::endl;
- return 1;
- }
- }
const std::string& original_path = _walker.resolve<std::string>("0");
try
diff --git a/src/builtins/tests/shopt_tests.cpp b/src/builtins/tests/shopt_tests.cpp
index e8cd013..8d53434 100644
--- a/src/builtins/tests/shopt_tests.cpp
+++ b/src/builtins/tests/shopt_tests.cpp
@@ -26,11 +26,27 @@
#include "core/interpreter.h"
#include "cppbash_builtin.h"
-TEST(shopt_builtin_test, disable_extglob)
+static void test_shopt_builtin(const std::string& expected, const std::vector<std::string>& args)
{
+ std::stringstream output;
interpreter walker;
- EXPECT_EQ(1, cppbash_builtin::exec("shopt", {"-u", "not exist"}, std::cout, std::cerr, std::cin, walker));
+ try
+ {
+ cppbash_builtin::exec("shopt", args, std::cout, output, std::cin, walker);
+ FAIL();
+ }
+ catch(interpreter_exception& e)
+ {
+ EXPECT_STREQ(expected.c_str(), e.what());
+ }
+}
+
+TEST(shopt_builtin_test, disable_extglob)
+{
+ test_shopt_builtin("not exist is not a valid bash option", {"-u", "not exist"});
+
+ interpreter walker;
walker.set_option("autocd", true);
EXPECT_EQ(0, cppbash_builtin::exec("shopt", {"-u", "autocd", "cdspell"}, std::cout, std::cerr, std::cin, walker));
EXPECT_FALSE(walker.get_option("autocd"));
@@ -39,26 +55,18 @@ TEST(shopt_builtin_test, disable_extglob)
TEST(shopt_builtin_test, enable_extglob)
{
- interpreter walker;
- EXPECT_EQ(1, cppbash_builtin::exec("shopt", {"-s", "not exist"}, std::cout, std::cerr, std::cin, walker));
+ test_shopt_builtin("not exist is not a valid bash option", {"-s", "not exist"});
+ interpreter walker;
EXPECT_EQ(0, cppbash_builtin::exec("shopt", {"-s", "autocd", "cdspell"}, std::cout, std::cerr, std::cin, walker));
EXPECT_TRUE(walker.get_option("autocd"));
EXPECT_TRUE(walker.get_option("cdspell"));
}
-static void test_shopt_builtin(const std::string& expected, const std::vector<std::string>& args, int status)
-{
- std::stringstream output;
- interpreter walker;
- EXPECT_EQ(status, cppbash_builtin::exec("shopt", args, std::cout, output, std::cin, walker));
- EXPECT_STREQ(expected.c_str(), output.str().c_str());
-}
-
TEST(shopt_builtin_test, invalid_argument)
{
- test_shopt_builtin("Arguments required for shopt\n", {}, 1);
- test_shopt_builtin("Multiple arguments are not supported\n", {"-so"}, 1);
- test_shopt_builtin("shopt -q is not supported yet\n", {"-q"}, 1);
- test_shopt_builtin("Unrecognized option for shopt: -d\n", {"-d"}, 1);
+ test_shopt_builtin("Arguments required for shopt", {});
+ test_shopt_builtin("Multiple arguments are not supported", {"-so"});
+ test_shopt_builtin("shopt -q is not supported yet", {"-q"});
+ test_shopt_builtin("Unrecognized option for shopt: -d", {"-d"});
}
diff --git a/src/builtins/tests/source_tests.cpp b/src/builtins/tests/source_tests.cpp
index b051de3..e1fecee 100644
--- a/src/builtins/tests/source_tests.cpp
+++ b/src/builtins/tests/source_tests.cpp
@@ -84,11 +84,11 @@ TEST(source_builtin_test, invalid)
std::cin,
walker),
interpreter_exception);
- int status = cppbash_builtin::exec("source",
+ EXPECT_THROW(cppbash_builtin::exec("source",
{get_src_dir() + "/scripts/illegal_script.sh"},
std::cout,
std::cerr,
std::cin,
- walker);
- EXPECT_NE(status, 0);
+ walker),
+ interpreter_exception);
}
diff --git a/src/core/bash_ast.cpp b/src/core/bash_ast.cpp
index 8eafb3e..8f06311 100644
--- a/src/core/bash_ast.cpp
+++ b/src/core/bash_ast.cpp
@@ -78,31 +78,20 @@ void bash_ast::init_parser(const std::string& script, const std::string& script_
lexer = libbashLexerNew(input);
if ( lexer == NULL )
- {
- std::cerr << "Unable to create the lexer due to malloc() failure" << std::endl;
- error_count = 1;
- return;
- }
+ throw interpreter_exception("Unable to create the lexer due to malloc() failure");
token_stream = antlr3CommonTokenStreamSourceNew(
ANTLR3_SIZE_HINT, lexer->pLexer->rec->state->tokSource);
if (token_stream == NULL)
- {
- std::cerr << "Out of memory trying to allocate token stream" << std::endl;
- error_count = 1;
- return;
- }
+ throw interpreter_exception("Out of memory trying to allocate token stream");
parser = libbashParserNew(token_stream);
if (parser == NULL)
- {
- std::cerr << "Out of memory trying to allocate parser" << std::endl;
- error_count = 1;
- return;
- }
+ throw interpreter_exception("Out of memory trying to allocate parser");
ast = parse(parser);
- error_count = parser->pParser->rec->getNumberOfSyntaxErrors(parser->pParser->rec);
+ if(parser->pParser->rec->getNumberOfSyntaxErrors(parser->pParser->rec))
+ throw interpreter_exception("Something wrong happened while parsing");
nodes = antlr3CommonTreeNodeStreamNewTree(ast, ANTLR3_SIZE_HINT);
}
diff --git a/src/core/bash_ast.h b/src/core/bash_ast.h
index dab71f5..d5d7f83 100644
--- a/src/core/bash_ast.h
+++ b/src/core/bash_ast.h
@@ -51,7 +51,6 @@ class bash_ast: public boost::noncopyable
libbashParser_Ctx_struct* parser;
pANTLR3_BASE_TREE ast;
pANTLR3_COMMON_TREE_NODE_STREAM nodes;
- unsigned error_count;
std::function<pANTLR3_BASE_TREE(libbashParser_Ctx_struct*)> parse;
void init_parser(const std::string& script, const std::string& script_path);
@@ -65,11 +64,6 @@ public:
~bash_ast();
- unsigned get_error_count() const
- {
- return error_count;
- }
-
static void walker_start(plibbashWalker tree_parser);
static int walker_arithmetics(plibbashWalker tree_parser);
diff --git a/src/core/interpreter.cpp b/src/core/interpreter.cpp
index 378c3d2..b0d32c0 100644
--- a/src/core/interpreter.cpp
+++ b/src/core/interpreter.cpp
@@ -414,7 +414,7 @@ void interpreter::set_option(const std::string& name, bool value)
{
auto iter = bash_options.find(name);
if(iter == bash_options.end())
- throw interpreter_exception("Invalid bash option");
+ throw interpreter_exception(name + " is not a valid bash option");
iter->second = value;
}
diff --git a/src/core/tests/bash_ast_test.cpp b/src/core/tests/bash_ast_test.cpp
index d335d80..0b94d67 100644
--- a/src/core/tests/bash_ast_test.cpp
+++ b/src/core/tests/bash_ast_test.cpp
@@ -33,17 +33,13 @@
TEST(bash_ast, parse_illegal_script)
{
- bash_ast ast(get_src_dir() + std::string("/scripts/illegal_script.sh"));
- EXPECT_NE(0, ast.get_error_count());
+ EXPECT_THROW(bash_ast ast(get_src_dir() + std::string("/scripts/illegal_script.sh")), interpreter_exception);
}
TEST(bash_ast, parse_legal_script)
{
- bash_ast ast(get_src_dir() + std::string("/scripts/source_true.sh"));
- EXPECT_EQ(0, ast.get_error_count());
-
- bash_ast ast2(get_src_dir() + std::string("/scripts/source_false.sh"));
- EXPECT_EQ(0, ast2.get_error_count());
+ bash_ast(get_src_dir() + std::string("/scripts/source_true.sh"));
+ bash_ast(get_src_dir() + std::string("/scripts/source_false.sh"));
}
TEST(bash_ast, parse_arithmetics)
diff --git a/src/libbash.cpp b/src/libbash.cpp
index d636f59..98f20b6 100644
--- a/src/libbash.cpp
+++ b/src/libbash.cpp
@@ -37,8 +37,6 @@ namespace internal
std::unordered_map<std::string, std::vector<std::string>>& variables,
std::vector<std::string>& functions)
{
- int result = 0;
-
// Initialize bash environment
for(auto iter = variables.begin(); iter != variables.end(); ++iter)
walker.define(iter->first, (iter->second)[0]);
@@ -47,14 +45,12 @@ namespace internal
bash_ast ast(path);
ast.interpret_with(walker);
- result += boost::numeric_cast<int>(ast.get_error_count());
for(auto iter = walker.begin(); iter != walker.end(); ++iter)
iter->second->get_all_values<std::string>(variables[iter->first]);
walker.get_all_function_names(functions);
- result += walker.get_status();
- return result;
+ return walker.get_status();
}
}
@@ -78,12 +74,6 @@ namespace libbash
// Preloading
bash_ast preload_ast(preload_path);
preload_ast.interpret_with(walker);
- int result = boost::numeric_cast<int>(preload_ast.get_error_count());
- if(result)
- {
- std::cerr << "Error occured while preloading" << std::endl;
- return result;
- }
return internal::interpret(walker, target_path, variables, functions);
}
diff --git a/test/api_test.cpp b/test/api_test.cpp
index 7744ebf..38972fe 100644
--- a/test/api_test.cpp
+++ b/test/api_test.cpp
@@ -40,10 +40,8 @@ TEST(libbashapi, illegal_script)
{
std::unordered_map<std::string, std::vector<std::string>> variables;
std::vector<std::string> functions;
- int result = libbash::interpret(get_src_dir() + "/scripts/illegal_script.sh",
- variables,
- functions);
- EXPECT_NE(0, result);
+ EXPECT_THROW(libbash::interpret(get_src_dir() + "/scripts/illegal_script.sh", variables, functions),
+ interpreter_exception);
}
TEST(libbashapi, legal_script)
@@ -78,9 +76,10 @@ TEST(libbashapi, preload)
variables,
functions);
EXPECT_NE(0, result);
- result = libbash::interpret(get_src_dir() + std::string("/scripts/source_true.sh"),
- get_src_dir() + std::string("/scripts/illegal_script.sh"),
- variables,
- functions);
- EXPECT_NE(0, result);
+
+ EXPECT_THROW(libbash::interpret(get_src_dir() + std::string("/scripts/source_true.sh"),
+ get_src_dir() + std::string("/scripts/illegal_script.sh"),
+ variables,
+ functions),
+ interpreter_exception);
}
diff --git a/utils/ast_printer.cpp b/utils/ast_printer.cpp
index b7dcfc1..e55df78 100644
--- a/utils/ast_printer.cpp
+++ b/utils/ast_printer.cpp
@@ -34,6 +34,7 @@
#include <boost/fusion/include/adapt_struct.hpp>
#include "core/bash_ast.h"
+#include "core/interpreter_exception.h"
#include "libbashParser.h"
namespace po = boost::program_options;
@@ -48,19 +49,17 @@ BOOST_FUSION_ADAPT_STRUCT(
(ANTLR3_INT32, first)
)
-static int print_ast(std::istream& input, bool silent, bool dot)
+static void print_ast(std::istream& input, bool silent, bool dot)
{
bash_ast ast(input);
if(silent)
- return ast.get_error_count();
+ return;
if(dot)
std::cout << ast.get_dot_graph() << std::endl;
else
std::cout << ast.get_string_tree() << std::endl;
-
- return ast.get_error_count();
}
static inline std::string token_mapper(std::unordered_map<ANTLR3_INT32, std::string> token_map,
@@ -85,58 +84,49 @@ static bool build_token_map(std::unordered_map<ANTLR3_INT32, std::string>& token
return qi::parse(first, last, line % qi::eol >> qi::eol, token_map) && first == last;
}
-static int print_token(std::istream& input,
+static void print_token(std::istream& input,
const std::string& token_path,
bool silent)
{
if(silent)
- return 0;
+ return;
bash_ast ast(input);
std::unordered_map<ANTLR3_INT32, std::string> token_map;
if(build_token_map(token_map, token_path))
- {
std::cout << ast.get_tokens(std::bind(&token_mapper,
token_map,
std::placeholders::_1))
<< std::endl;
- return ast.get_error_count();
- }
else
- {
std::cerr << "Building token map failed" << std::endl;
- return ast.get_error_count() + 1;
- }
}
-static int print_files(const std::vector<std::string>& files,
+static void print_files(const std::vector<std::string>& files,
bool print_name,
- std::function<int(std::istream&)> printer)
+ std::function<void(std::istream&)> printer)
{
- int result = 0;
for(auto iter = files.begin(); iter != files.end(); ++iter)
{
if(print_name)
std::cout << "Interpreting " << *iter << std::endl;
std::ifstream input(iter->c_str());
- result += printer(input);
+ printer(input);
}
-
- return result;
}
-static inline int print_expression(const std::string& expr,
- std::function<int(std::istream&)> printer)
+static inline void print_expression(const std::string& expr,
+ std::function<void(std::istream&)> printer)
{
std::istringstream input(expr);
- return printer(input);
+ printer(input);
}
-static inline int print_cin(std::function<int(std::istream&)> printer)
+static inline void print_cin(std::function<void(std::istream&)> printer)
{
- return printer(std::cin);
+ printer(std::cin);
}
int main(int argc, char** argv)
@@ -168,7 +158,7 @@ int main(int argc, char** argv)
return EXIT_FAILURE;
}
- std::function<int(std::istream&)> printer;
+ std::function<void(std::istream&)> printer;
if(vm.count("token"))
printer = std::bind(&print_token,
std::placeholders::_1,
@@ -180,15 +170,23 @@ int main(int argc, char** argv)
vm.count("silent"),
vm.count("dot"));
- int result;
- if(vm.count("files"))
- result = print_files(vm["files"].as<std::vector<std::string>>(),
- vm.count("name"),
- printer);
- else if(vm.count("expr"))
- result = print_expression(vm["expr"].as<std::string>(), printer);
- else
- result = print_cin(printer);
+ try
+ {
+ if(vm.count("files"))
+ print_files(vm["files"].as<std::vector<std::string>>(),
+ vm.count("name"),
+ printer);
+ else if(vm.count("expr"))
+ print_expression(vm["expr"].as<std::string>(), printer);
+ else
+ print_cin(printer);
+ }
+ catch(interpreter_exception& e)
+ {
+ if(!vm.count("silent"))
+ std::cerr << e.what() << std::endl;
+ return EXIT_FAILURE;
+ }
- return result;
+ return EXIT_SUCCESS;
}
diff --git a/utils/variable_printer.cpp b/utils/variable_printer.cpp
index 001e75e..252ee9b 100644
--- a/utils/variable_printer.cpp
+++ b/utils/variable_printer.cpp
@@ -46,7 +46,15 @@ int main(int argc, char** argv)
std::unordered_map<std::string, std::vector<std::string>> variables;
std::vector<std::string> functions;
- libbash::interpret(argv[1], variables, functions);
+ try
+ {
+ libbash::interpret(argv[1], variables, functions);
+ }
+ catch(interpreter_exception& e)
+ {
+ std::cerr << e.what() << std::endl;
+ return EXIT_FAILURE;
+ }
std::map<std::string, std::vector<std::string>> sorted(variables.begin(), variables.end());
// Currently we don't need internal variables
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2011-06-03 14:42 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-06-03 14:42 [gentoo-commits] proj/libbash:master commit in: src/, src/builtins/tests/, src/core/, bashast/, test/, src/core/tests/, utils/, Petteri Räty
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox