Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Read builtin #1

Merged
merged 6 commits into from

3 participants

@Aparicio99

Hi, I'm making this pull request as you suggested. :)

@qiaomuf qiaomuf was assigned
src/builtins/unset_builtin.cpp
@@ -26,6 +26,10 @@
#include "core/interpreter.h"
+using namespace boost::xpressive;
+
+sregex index_pattern = sregex::compile("^(.*)\\[(\\d*)\\]$");
@betelgeuse Collaborator

this creates a global variable. It needs to be either static or inside an anonymous namespace

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@qiaomuf qiaomuf merged commit f6fa493 into qiaomuf:master
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
View
7 Makefile.am
@@ -105,6 +105,9 @@ cppunittests_SOURCES = test/run_tests.cpp \
src/builtins/tests/shift_tests.cpp \
src/builtins/tests/shopt_tests.cpp \
src/builtins/tests/return_tests.cpp \
+ src/builtins/tests/read_tests.cpp \
+ src/builtins/tests/set_tests.cpp \
+ src/builtins/tests/unset_tests.cpp \
src/builtins/tests/printf_tests.cpp \
test/test.h \
test/test.cpp \
@@ -236,6 +239,10 @@ libbash_la_SOURCES = include/common.h \
src/builtins/inherit_builtin.cpp \
src/builtins/unset_builtin.h \
src/builtins/unset_builtin.cpp \
+ src/builtins/read_builtin.h \
+ src/builtins/read_builtin.cpp \
+ src/builtins/set_builtin.h \
+ src/builtins/set_builtin.cpp \
src/builtins/builtin_exceptions.h \
$(GENERATED_PARSER_C) \
$(GENERATED_PARSER_H) \
View
9 bashast/libbashWalker.g
@@ -649,7 +649,7 @@ execute_command[std::string& name, std::vector<std::string>& libbash_args]
bool redirection = false;
}
@init {
- if(name != "local")
+ if(name != "local" && name != "set")
current_scope.reset(new interpreter::local_scope(*walker));
}
:var_def[true]* (redirect[out, err, in]{ redirection = true; })* {
@@ -736,18 +736,19 @@ argument[std::vector<std::string>& args, bool split]
}
};
-logic_command_list
+logic_command
@declarations {
bool logic_and;
}
- :command
- |^((LOGICAND { logic_and = true; } | LOGICOR { logic_and = false; }) command {
+ : ^((LOGICAND { logic_and = true; } | LOGICOR { logic_and = false; }) logic_command_list {
if(logic_and ? !walker->get_status() : walker->get_status())
command(ctx);
else
seek_to_next_tree(ctx);
});
+logic_command_list: command | logic_command;
+
command_list: ^(LIST logic_command_list+);
compound_command
View
3  scripts/command_execution.bash
@@ -17,6 +17,9 @@ false && echo "wrong"
false || echo "right"
true ||
echo "wrong"
+echo right1 && echo right2 && false && echo wrong
+false || echo right3 || echo wrong
+true && false || echo right4 && echo right5
echo "end"
: ${DEFAULTED:="yes"}
FOO="abc" echo "command environment"
View
15 scripts/function_def.bash
@@ -76,6 +76,21 @@ func_positional_args() {
func_positional_args 1 2 3
IFS=" \t\n"
+nested_func_override_positional_args() {
+ echo $@
+ set -- 40 50 60
+ echo $@
+}
+func_override_positional_args() {
+ echo $@
+ nested_func_override_positional_args 4 5 6
+ set -- 10 20 30
+ echo $@
+}
+set -- foo bar
+func_override_positional_args 1 2 3
+echo $@
+
if true; then
function_in_compound_statement() {
echo "function_in_compound_statement"
View
94 src/builtins/read_builtin.cpp
@@ -0,0 +1,94 @@
+/*
+ Please use git log for copyright holder and year information
+
+ This file is part of libbash.
+
+ libbash 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 2 of the License, or
+ (at your option) any later version.
+
+ libbash 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 libbash. If not, see <http://www.gnu.org/licenses/>.
+*/
+///
+/// \file read_builtin.cpp
+/// \brief class that implements the read builtin
+///
+
+#include "builtins/read_builtin.h"
+
+#include <string.h>
+#include <boost/algorithm/string.hpp>
+
+#include "core/interpreter.h"
+#include "builtins/builtin_exceptions.h"
+
+void read_builtin::process(const std::vector<std::string>& args, const std::string& input)
+{
+ std::vector<std::string> split_input;
+ boost::split(split_input, input, boost::is_any_of(" "));
+
+ auto vars = args.begin();
+ for(auto words = split_input.begin(); vars != args.end() && words != split_input.end(); ++vars, ++words)
+ {
+ if(vars != args.end() - 1)
+ {
+ _walker.set_value(*vars, *words);
+ }
+ else
+ {
+ std::string rest;
+ for(; words != split_input.end() - 1; ++words)
+ rest += *words + " ";
+ rest += *words;
+ _walker.set_value(*vars, rest);
+ }
+ }
+
+ for(; vars != args.end(); ++vars)
+ _walker.set_value(*vars, "");
+}
+
+int read_builtin::exec(const std::vector<std::string>& bash_args)
+{
+ int return_value = 0;
+ std::string input;
+ std::stringstream formated_input;
+
+ getline(this->input_buffer(), input);
+
+ if(this->input_buffer().eof())
+ return_value = 1;
+
+ if(input.size() < 1)
+ return return_value;
+
+ while(input[input.length()-1] == '\\') {
+ input.erase(input.end()-1);
+ std::string input_line;
+ getline(this->input_buffer(), input_line);
+
+ if(this->input_buffer().eof())
+ return_value = 1;
+
+ if(input.size() < 1)
+ return return_value;
+
+ input += input_line;
+ }
+
+ cppbash_builtin::transform_escapes(input, formated_input, false);
+
+ if(bash_args.empty())
+ process({"REPLY"}, formated_input.str());
+ else
+ process(bash_args, formated_input.str());
+
+ return return_value;
+}
View
54 src/builtins/read_builtin.h
@@ -0,0 +1,54 @@
+/*
+ Please use git log for copyright holder and year information
+
+ This file is part of libbash.
+
+ libbash 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 2 of the License, or
+ (at your option) any later version.
+
+ libbash 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 libbash. If not, see <http://www.gnu.org/licenses/>.
+*/
+///
+/// \file read_builtin.h
+/// \brief class that implements the read builtin
+///
+
+#ifndef LIBBASH_BUILTINS_READ_BUILTIN_H_
+#define LIBBASH_BUILTINS_READ_BUILTIN_H_
+
+#include "../cppbash_builtin.h"
+
+///
+/// \class read_builtin
+/// \brief the read builtin for bash
+///
+class read_builtin: public virtual cppbash_builtin
+{
+ public:
+ BUILTIN_CONSTRUCTOR(read)
+
+ ///
+ /// \brief runs the read builtin on the supplied arguments
+ /// \param bash_args the arguments to the read builtin
+ /// \return exit status of read
+ ///
+ virtual int exec(const std::vector<std::string>& bash_args);
+
+ private:
+ ///
+ /// \brief assigns words from input to the variables
+ /// \param args the variables to be used
+ /// \param input the input to be assigned to the variables
+ ///
+ virtual void process(const std::vector<std::string>& bash_args, const std::string& input);
+};
+
+#endif
View
81 src/builtins/set_builtin.cpp
@@ -0,0 +1,81 @@
+/*
+ Please use git log for copyright holder and year information
+
+ This file is part of libbash.
+
+ libbash 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 2 of the License, or
+ (at your option) any later version.
+
+ libbash 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 libbash. If not, see <http://www.gnu.org/licenses/>.
+*/
+///
+/// \file set_builtin.cpp
+/// \brief class that implements the set builtin
+///
+#include "builtins/set_builtin.h"
+
+#include "core/interpreter.h"
+#include "exceptions.h"
+
+int set_builtin::exec(const std::vector<std::string>& bash_args)
+{
+ if(bash_args.empty())
+ {
+ throw libbash::unsupported_exception("set: variables printing are not supported");
+ return 1;
+ }
+
+ if(bash_args[0][0] != '-' && bash_args[0][0] != '+')
+ {
+ throw libbash::illegal_argument_exception("set: invalid option");
+ return 1;
+ }
+
+ switch(bash_args[0][1])
+ {
+ case '-':
+ if(bash_args[0][0] != '-') {
+ throw libbash::unsupported_exception("set: invalid option");
+ return 1;
+ }
+ else
+ {
+ _walker.define_positional_arguments(bash_args.begin() + 1, bash_args.end());
+ return 0;
+ }
+ case 'a':
+ case 'b':
+ case 'e':
+ case 'f':
+ case 'h':
+ case 'k':
+ case 'm':
+ case 'n':
+ case 'p':
+ case 't':
+ case 'u':
+ _walker.set_option('u', bash_args[0][0] == '-');
+ return 0;
+ case 'v':
+ case 'x':
+ case 'B':
+ case 'C':
+ case 'E':
+ case 'H':
+ case 'P':
+ case 'T':
+ throw libbash::unsupported_exception("set " + bash_args[0] + " is not supported yet");
+ return 1;
+ default:
+ throw libbash::illegal_argument_exception("set: unrecognized option: " + bash_args[0]);
+ return 1;
+ }
+}
View
46 src/builtins/set_builtin.h
@@ -0,0 +1,46 @@
+/*
+ Please use git log for copyright holder and year information
+
+ This file is part of libbash.
+
+ libbash 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 2 of the License, or
+ (at your option) any later version.
+
+ libbash 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 libbash. If not, see <http://www.gnu.org/licenses/>.
+*/
+///
+/// \file set_builtin.h
+/// \brief class that implements the set builtin
+///
+
+#ifndef LIBBASH_BUILTINS_SET_BUILTIN_H_
+#define LIBBASH_BUILTINS_SET_BUILTIN_H_
+
+#include "cppbash_builtin.h"
+
+///
+/// \class set_builtin
+/// \brief the set builtin for bash
+///
+class set_builtin: public virtual cppbash_builtin
+{
+public:
+ BUILTIN_CONSTRUCTOR(set)
+
+ ///
+ /// \brief runs the set builtin on the supplied arguments
+ /// \param bash_args the arguments to the set builtin
+ /// \return exit status of set
+ ///
+ virtual int exec(const std::vector<std::string>& bash_args);
+};
+
+#endif
View
76 src/builtins/tests/read_tests.cpp
@@ -0,0 +1,76 @@
+/*
+ Please use git log for copyright holder and year information
+
+ This file is part of libbash.
+
+ libbash 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 2 of the License, or
+ (at your option) any later version.
+
+ libbash 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 libbash. If not, see <http://www.gnu.org/licenses/>.
+*/
+///
+/// \file read_tests.cpp
+/// \brief series of unit tests for read builtin
+///
+#include <iostream>
+#include <sstream>
+#include <vector>
+
+#include <gtest/gtest.h>
+
+#include "core/interpreter.h"
+#include "cppbash_builtin.h"
+
+using namespace std;
+
+static void test_read(interpreter& walker, const string& input, std::initializer_list<string> args)
+{
+ stringstream test_input;
+ test_input << input;
+ cppbash_builtin::exec("read", args, std::cout, cerr, test_input, walker);
+}
+
+TEST(read_builtin_test, argument_assignment)
+{
+ interpreter walker;
+
+ test_read(walker, "foo bar", {});
+ EXPECT_STREQ("foo bar", walker.resolve<std::string>("REPLY").c_str());
+
+ test_read(walker, "foo bar", {"var"});
+ EXPECT_STREQ("foo bar", walker.resolve<std::string>("var").c_str());
+
+ test_read(walker, "foo bar", {"var1", "var2"});
+ EXPECT_STREQ("foo", walker.resolve<std::string>("var1").c_str());
+ EXPECT_STREQ("bar", walker.resolve<std::string>("var2").c_str());
+
+ test_read(walker, "1 2 3 4", {"var1", "var2"});
+ EXPECT_STREQ("1", walker.resolve<std::string>("var1").c_str());
+ EXPECT_STREQ("2 3 4", walker.resolve<std::string>("var2").c_str());
+
+ test_read(walker, "foo", {"var1", "var2"});
+ EXPECT_STREQ("foo", walker.resolve<std::string>("var1").c_str());
+ EXPECT_STREQ("", walker.resolve<std::string>("var2").c_str());
+
+ test_read(walker, "foo bar", {"var"});
+ EXPECT_STREQ("foo bar", walker.resolve<std::string>("var").c_str());
+}
+
+TEST(read_builtin_test, line_continuation)
+{
+ interpreter walker;
+
+ test_read(walker, "foo\\\nbar", {});
+ EXPECT_STREQ("foobar", walker.resolve<std::string>("REPLY").c_str());
+
+ test_read(walker, "foo \\\n bar", {});
+ EXPECT_STREQ("foo bar", walker.resolve<std::string>("REPLY").c_str());
+}
View
62 src/builtins/tests/set_tests.cpp
@@ -0,0 +1,62 @@
+/*
+ Please use git log for copyright holder and year information
+
+ This file is part of libbash.
+
+ libbash 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 2 of the License, or
+ (at your option) any later version.
+
+ libbash 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 libbash. If not, see <http://www.gnu.org/licenses/>.
+*/
+///
+/// \file set_tests.cpp
+/// \brief series of unit tests for set builtin
+///
+#include <boost/lexical_cast.hpp>
+#include <gtest/gtest.h>
+
+#include "core/interpreter.h"
+#include "cppbash_builtin.h"
+#include "exceptions.h"
+
+TEST(set_builtin_test, positional)
+{
+ interpreter walker;
+
+ EXPECT_EQ(0, cppbash_builtin::exec("set", {"--", "1", "2", "3"}, std::cout, std::cerr, std::cin, walker));
+ EXPECT_EQ(3, walker.get_array_length("*"));
+ EXPECT_STREQ("1", walker.resolve<std::string>("*", 1).c_str());
+ EXPECT_STREQ("2", walker.resolve<std::string>("*", 2).c_str());
+ EXPECT_STREQ("3", walker.resolve<std::string>("*", 3).c_str());
+
+ EXPECT_EQ(0, cppbash_builtin::exec("set", {"--"}, std::cout, std::cerr, std::cin, walker));
+ EXPECT_EQ(0, walker.get_array_length("*"));
+ EXPECT_STREQ("", walker.resolve<std::string>("*", 1).c_str());
+}
+
+TEST(set_builtin_test, u_option)
+{
+ interpreter walker;
+
+ EXPECT_EQ(0, cppbash_builtin::exec("set", {"-u"}, std::cout, std::cerr, std::cin, walker));
+ EXPECT_THROW(walker.resolve<std::string>("VAR1").c_str(), libbash::unsupported_exception);
+
+ walker.set_value("ARRAY", "foo");
+ EXPECT_NO_THROW(walker.resolve<std::string>("ARRAY").c_str());
+ EXPECT_THROW(walker.resolve<std::string>("ARRAY", 2).c_str(), libbash::unsupported_exception);
+
+ walker.set_value("ARRAY", "foo", 3);
+ EXPECT_NO_THROW(walker.resolve<std::string>("ARRAY", 3).c_str());
+
+ EXPECT_EQ(0, cppbash_builtin::exec("set", {"+u"}, std::cout, std::cerr, std::cin, walker));
+ EXPECT_NO_THROW(walker.resolve<std::string>("VAR2", 1).c_str());
+
+}
View
50 src/builtins/tests/unset_tests.cpp
@@ -0,0 +1,50 @@
+/*
+ Please use git log for copyright holder and year information
+
+ This file is part of libbash.
+
+ libbash 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 2 of the License, or
+ (at your option) any later version.
+
+ libbash 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 libbash. If not, see <http://www.gnu.org/licenses/>.
+*/
+///
+/// \file unset_tests.cpp
+/// \brief series of unit tests for unset builtin
+///
+#include <boost/lexical_cast.hpp>
+#include <gtest/gtest.h>
+
+#include "core/interpreter.h"
+#include "cppbash_builtin.h"
+#include "exceptions.h"
+
+TEST(unset_builtin_test, normal)
+{
+ interpreter walker;
+
+ walker.set_value("var", "foo");
+ EXPECT_EQ(0, cppbash_builtin::exec("unset", {"var"}, std::cout, std::cerr, std::cin, walker));
+ EXPECT_STREQ("", walker.resolve<std::string>("var").c_str());
+}
+
+TEST(unset_builtin_test, array)
+{
+ interpreter walker;
+
+ walker.set_value("array", "foo bar", 2);
+ EXPECT_EQ(0, cppbash_builtin::exec("unset", {"array"}, std::cout, std::cerr, std::cin, walker));
+ EXPECT_STREQ("", walker.resolve<std::string>("array", 2).c_str());
+
+ walker.set_value("array", "foo bar", 2);
+ EXPECT_EQ(0, cppbash_builtin::exec("unset", {"array[2]"}, std::cout, std::cerr, std::cin, walker));
+ EXPECT_STREQ("", walker.resolve<std::string>("array", 2).c_str());
+}
View
11 src/builtins/unset_builtin.cpp
@@ -26,6 +26,8 @@
#include "core/interpreter.h"
+using namespace boost::xpressive;
+
int unset_builtin::exec(const std::vector<std::string>& bash_args)
{
if(bash_args.empty())
@@ -51,7 +53,14 @@ int unset_builtin::exec(const std::vector<std::string>& bash_args)
* */
for_each(bash_args.front() == "-v" ? bash_args.begin() + 1 : bash_args.begin(),
bash_args.end(),
- [&](const std::string& name) { _walker.unset(name); });
+ [&](const std::string& name) {
+ static const sregex index_pattern = sregex::compile("^(.*)\\[(\\d*)\\]$");
+ smatch match;
+ if(regex_match(name, match, index_pattern))
+ _walker.unset(match[1], boost::lexical_cast<unsigned int>(match[2]));
+ else
+ _walker.unset(name);
+ });
return 0;
}
View
37 src/core/interpreter.cpp
@@ -248,7 +248,7 @@ std::string::size_type interpreter::get_length(const std::string& name,
const unsigned index) const
{
auto var = resolve_variable(name);
- if(!var)
+ if(!is_valid(var, name))
return 0;
return var->get_length(index);
}
@@ -256,7 +256,7 @@ std::string::size_type interpreter::get_length(const std::string& name,
variable::size_type interpreter::get_array_length(const std::string& name) const
{
auto var = resolve_variable(name);
- if(!var)
+ if(!is_valid(var, name))
return 0;
return var->get_array_length();
}
@@ -312,6 +312,21 @@ void interpreter::define_function_arguments(scope& current_stack,
current_stack["*"].reset(new variable("*", positional_args));
}
+void interpreter::define_positional_arguments(const std::vector<std::string>::const_iterator begin,
+ const std::vector<std::string>::const_iterator end)
+{
+ std::map<unsigned, std::string> positional_args;
+ std::vector<std::string>::const_iterator iter = begin;
+
+ for(auto i = 1u; iter != end ; ++i, ++iter)
+ positional_args[i] = *iter;
+
+ if(local_members.size() < 1)
+ define("*", positional_args);
+ else
+ define_local("*", positional_args);
+}
+
namespace
{
bool check_function_name(const std::string& name)
@@ -456,6 +471,24 @@ void interpreter::set_additional_option(const std::string& name, bool value)
iter->second = value;
}
+bool interpreter::get_option(const char name) const
+{
+ auto iter = options.find(name);
+ if(iter == options.end())
+ throw libbash::illegal_argument_exception("Invalid bash option");
+
+ return iter->second;
+}
+
+void interpreter::set_option(const char name, bool value)
+{
+ auto iter = options.find(name);
+ if(iter == options.end())
+ throw libbash::illegal_argument_exception(name + " is not a valid bash option");
+
+ iter->second = value;
+}
+
long interpreter::eval_arithmetic(const std::string& expression)
{
bash_ast ast(std::stringstream(expression), &bash_ast::parser_arithmetics);
View
52 src/core/interpreter.h
@@ -189,6 +189,20 @@ class interpreter: public boost::noncopyable
_out = &std::cout;
}
+ /// \brief check whether a variable is valid and can be used
+ /// \param var variable
+ /// \return whether the variable is valid
+ bool is_valid(const std::shared_ptr<variable>& var, const std::string& name) const
+ {
+ if(var)
+ return true;
+
+ if(get_option('u'))
+ throw libbash::unsupported_exception(name + ": unbound variable");
+
+ return false;
+ }
+
/// \brief resolve string/long variable, local scope will be
/// checked first, then global scope
/// \param name variable name
@@ -199,10 +213,25 @@ class interpreter: public boost::noncopyable
T resolve(const std::string& name, const unsigned index=0) const
{
auto var = resolve_variable(name);
- if(var)
+ if(is_valid(var, name))
+ {
+ if(get_option('u') && var->is_unset(index))
+ {
+ if(name == "*")
+ throw libbash::unsupported_exception("$" + boost::lexical_cast<std::string>(index) + ": unbound variable");
+ else if(index == 0)
+ throw libbash::unsupported_exception(name + ": unbound variable");
+ else
+ throw libbash::unsupported_exception(name + "[" + boost::lexical_cast<std::string>(index) + "]: unbound variable");
+ }
return var->get_value<T>(index);
+ }
else
+ {
+ if(get_option('u'))
+ throw libbash::unsupported_exception(name + ": unbound variable");
return T{};
+ }
}
/// \brief resolve array variable
@@ -212,7 +241,7 @@ class interpreter: public boost::noncopyable
bool resolve_array(const std::string& name, std::vector<T>& values) const
{
auto var = resolve_variable(name);
- if(!var)
+ if(!is_valid(var, name))
return false;
var->get_all_values(values);
@@ -467,7 +496,10 @@ class interpreter: public boost::noncopyable
variable::size_type get_max_index(const std::string& name) const
{
auto var = resolve_variable(name);
- return var ? var->get_max_index() : 0;
+ if(is_valid(var, name))
+ return var->get_max_index();
+ else
+ return 0;
}
/// \brief get all array elements concatenated by space
@@ -496,6 +528,17 @@ class interpreter: public boost::noncopyable
/// \return zero unless the name is not a valid shell option
void set_additional_option(const std::string& name, bool value);
+ /// \brief get the status of shell optional behavior
+ /// \param name the option name
+ /// \return zero unless the name is not a valid shell option
+ bool get_option(const char name) const;
+
+ /// \brief set the status of shell optional behavior
+ /// \param name the option name
+ /// \param[in] value true if option is enabled, false otherwise
+ /// \return zero unless the name is not a valid shell option
+ void set_option(const char name, bool value);
+
/// \brief return an iterator referring to the first variable
/// \return iterator referring to the first variable
option_iterator additional_options_begin() const
@@ -521,6 +564,9 @@ class interpreter: public boost::noncopyable
/// \return zero unless n is greater than $# or less than zero, non-zero otherwise.
int shift(int shift_number);
+ void define_positional_arguments(const std::vector<std::string>::const_iterator begin,
+ const std::vector<std::string>::const_iterator end);
+
/// \brief perform expansion like ${var//foo/bar}
/// \param value the value to be expanded
/// \param pattern the pattern used to match the value
View
5 src/cppbash_builtin.cpp
@@ -44,6 +44,9 @@
#include "builtins/shopt_builtin.h"
#include "builtins/source_builtin.h"
#include "builtins/unset_builtin.h"
+#include "builtins/read_builtin.h"
+#include "builtins/set_builtin.h"
+#include "builtins/unset_builtin.h"
namespace qi = boost::spirit::qi;
namespace karma = boost::spirit::karma;
@@ -73,6 +76,8 @@ cppbash_builtin::builtins_type& cppbash_builtin::builtins() {
{"printf", boost::factory<printf_builtin*>()},
{"let", boost::factory<let_builtin*>()},
{"unset", boost::factory<unset_builtin*>()},
+ {"read", boost::factory<read_builtin*>()},
+ {"set", boost::factory<set_builtin*>()},
});
return *p;
}
View
11 utils/command_line.cpp
@@ -41,15 +41,12 @@ CommandLine::CommandLine() :
a_no_color(&a_no_colour, "no-color"),
a_force_colour(&general_args, "force-colour", '\0', "Force the use of colour", false),
a_force_color(&a_force_colour, "force-color"),
- a_repository_directory(&general_args, "repository-dir", 'D',
- "Where to find the repository (default: current directory)"),
+ a_package_manager(&general_args, "package-manager", 'p',
+ "What package manager to use (default: portage)"),
a_output_directory(&general_args, "output-dir", 'o',
"Where to place generated metadata (default: current directory)"),
- a_master_repository_name(&general_args, "master-repository-name", '\0',
- "Use the specified name for the master repository. Specify the location using --extra-repository-dir. "
- "Only for repositories with no metadata/layout.conf."),
- a_extra_repository_dir(&general_args, "extra-repository-dir", '\0',
- "Also include the repository at this location. May be specified multiple times, in creation order."),
+ a_repository_name(&general_args, "repository-name", 'n',
+ "Use the specified name for the repository (default: gentoo)"),
a_report_file(&general_args, "report-file", 'r',
"Write report to the specified file, rather than stdout")
{
View
5 utils/command_line.h
@@ -52,10 +52,9 @@ class CommandLine :
paludis::args::AliasArg a_no_color;
paludis::args::SwitchArg a_force_colour;
paludis::args::AliasArg a_force_color;
- paludis::args::StringArg a_repository_directory;
+ paludis::args::StringArg a_package_manager;
paludis::args::StringArg a_output_directory;
- paludis::args::StringArg a_master_repository_name;
- paludis::args::StringSequenceArg a_extra_repository_dir;
+ paludis::args::StringArg a_repository_name;
paludis::args::StringArg a_report_file;
};
View
91 utils/instruo.cpp
@@ -25,33 +25,37 @@
#include <iostream>
#include <map>
-#include <paludis/args/do_help.hh>
#include <paludis/about.hh>
#include <paludis/action.hh>
-#include <paludis/package_id.hh>
-#include <paludis/generator.hh>
+#include <paludis/args/do_help.hh>
+#include <paludis/environment.hh>
+#include <paludis/environment_factory.hh>
#include <paludis/filter.hh>
#include <paludis/filtered_generator.hh>
+#include <paludis/generator.hh>
+#include <paludis/metadata_key.hh>
+#include <paludis/name.hh>
+#include <paludis/package_id.hh>
+#include <paludis/repository.hh>
#include <paludis/selection.hh>
-#include <paludis/util/system.hh>
+#include <paludis/util/accept_visitor.hh>
+#include <paludis/util/destringify.hh>
+#include <paludis/util/fs_path.hh>
+#include <paludis/util/indirect_iterator-impl.hh>
#include <paludis/util/join.hh>
#include <paludis/util/log.hh>
-#include <paludis/util/sequence.hh>
-#include <paludis/util/map.hh>
-#include <paludis/util/visitor_cast.hh>
-#include <paludis/util/set.hh>
#include <paludis/util/make_named_values.hh>
+#include <paludis/util/map.hh>
#include <paludis/util/mutex.hh>
-#include <paludis/util/thread_pool.hh>
-#include <paludis/util/destringify.hh>
-#include <paludis/util/safe_ofstream.hh>
#include <paludis/util/pretty_print.hh>
-#include <paludis/util/indirect_iterator-impl.hh>
+#include <paludis/util/safe_ofstream.hh>
+#include <paludis/util/sequence.hh>
+#include <paludis/util/set.hh>
+#include <paludis/util/system.hh>
+#include <paludis/util/thread_pool.hh>
#include <paludis/util/timestamp.hh>
-#include <paludis/util/accept_visitor.hh>
-#include <paludis/environments/no_config/no_config_environment.hh>
-#include <paludis/package_database.hh>
-#include <paludis/metadata_key.hh>
+#include <paludis/util/visitor_cast.hh>
+#include <paludis/version_spec.hh>
#include "command_line.h"
#include "exceptions.h"
@@ -64,7 +68,7 @@ using std::cout;
using std::cerr;
using std::endl;
-void worker(const std::shared_ptr<PackageIDSequence> &ids)
+void worker(const std::shared_ptr<PackageIDSequence> &ids, const std::string &repository_path)
{
unsigned total(0);
CategoryNamePart old_cat("OLDCAT");
@@ -99,7 +103,7 @@ void worker(const std::shared_ptr<PackageIDSequence> &ids)
variables["CATEGORY"].push_back(stringify(id->name().category()));
std::vector<std::string> functions;
- std::string ebuild_path(CommandLine::get_instance()->a_repository_directory.argument() +
+ std::string ebuild_path(repository_path + "/" +
variables["CATEGORY"][0] + "/" +
variables["PN"][0] + "/" +
variables["PN"][0] + "-" +
@@ -126,6 +130,7 @@ void worker(const std::shared_ptr<PackageIDSequence> &ids)
}
}
+
int main(int argc, char** argv)
{
try
@@ -153,8 +158,11 @@ int main(int argc, char** argv)
))
throw args::DoHelp("you should specify exactly one action");
- if (! CommandLine::get_instance()->a_repository_directory.specified())
- CommandLine::get_instance()->a_repository_directory.set_argument(stringify(FSPath::cwd()));
+ if (! CommandLine::get_instance()->a_package_manager.specified())
+ CommandLine::get_instance()->a_package_manager.set_argument("portage");
+
+ if (! CommandLine::get_instance()->a_repository_name.specified())
+ CommandLine::get_instance()->a_repository_name.set_argument("gentoo");
if (CommandLine::get_instance()->a_version.specified())
{
@@ -170,42 +178,25 @@ int main(int argc, char** argv)
return EXIT_SUCCESS;
}
- if ((
- CommandLine::get_instance()->a_repository_directory.specified() +
- CommandLine::get_instance()->a_output_directory.specified()
- ) < 1)
- throw args::DoHelp("at least one of '--" + CommandLine::get_instance()->a_repository_directory.long_name() + "' or '--"
- + CommandLine::get_instance()->a_output_directory.long_name() + "' must be specified");
-
if (! CommandLine::get_instance()->a_output_directory.specified())
CommandLine::get_instance()->a_output_directory.set_argument(stringify(FSPath::cwd()));
- std::shared_ptr<FSPathSequence> extra_repository_dirs(std::make_shared<FSPathSequence>());
- for (args::StringSequenceArg::ConstIterator d(CommandLine::get_instance()->a_extra_repository_dir.begin_args()),
- d_end(CommandLine::get_instance()->a_extra_repository_dir.end_args()) ;
- d != d_end ; ++d)
- extra_repository_dirs->push_back(FSPath(*d));
+ FSPath(CommandLine::get_instance()->a_output_directory.argument()).mkdir(0755, {fspmkdo_ok_if_exists});
- std::shared_ptr<Map<std::string, std::string> > keys(std::make_shared<Map<std::string, std::string>>());
- keys->insert("append_repository_name_to_write_cache", "false");
- NoConfigEnvironment env(make_named_values<no_config_environment::Params>(
- n::accept_unstable() = true,
- n::disable_metadata_cache() = true,
- n::extra_accept_keywords() = "",
- n::extra_params() = keys,
- n::extra_repository_dirs() = extra_repository_dirs,
- n::master_repository_name() = CommandLine::get_instance()->a_master_repository_name.argument(),
- n::profiles_if_not_auto() = "",
- n::repository_dir() = CommandLine::get_instance()->a_repository_directory.argument(),
- n::repository_type() = no_config_environment::ncer_ebuild,
- n::write_cache() = CommandLine::get_instance()->a_output_directory.argument()
- ));
+ std::shared_ptr<Environment> env(EnvironmentFactory::get_instance()->create(CommandLine::get_instance()->a_package_manager.argument()));
- FSPath(CommandLine::get_instance()->a_output_directory.argument()).mkdir(0755, {fspmkdo_ok_if_exists});
+ std::shared_ptr<Repository> repo = env->fetch_repository(RepositoryName(CommandLine::get_instance()->a_repository_name.argument()));
+
+ Repository::MetadataConstIterator distdir_metadata(repo->find_metadata("location"));
+ const MetadataValueKey<FSPath> *path_key;
+ if(distdir_metadata != repo->end_metadata())
+ {
+ path_key = visitor_cast<const MetadataValueKey<FSPath>>(**distdir_metadata);
- std::shared_ptr<PackageIDSequence> ids(env[selection::AllVersionsSorted(
- generator::InRepository(env.main_repository()->name()))]);
- worker(ids);
+ std::shared_ptr<PackageIDSequence> ids((*env)[selection::AllVersionsSorted(
+ generator::InRepository(RepositoryName(CommandLine::get_instance()->a_repository_name.argument())))]);
+ worker(ids, stringify(path_key->parse_value().realpath()));
+ }
}
catch (const paludis::args::ArgsError & e)
{
View
2  utils/metadata_diff.sh
@@ -11,7 +11,7 @@ fi
echo "Generating metadata at $outputdir"
-time ./instruo -D ${PORTDIR:-/usr/portage/} -o $outputdir 2>$outputdir/error_output
+time ./instruo -p portage -n gentoo -o $outputdir 2>$outputdir/error_output
echo "Running diff..."
Something went wrong with that request. Please try again.