/*
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 .
*/
///
/// \file echo_builtin.cpp
/// \brief class that implements the echo builtin
///
#include "echo_builtin.h"
#include
#include
#include
#include "builtins/builtin_exceptions.h"
namespace qi = boost::spirit::qi;
namespace karma = boost::spirit::karma;
namespace phoenix = boost::phoenix;
int echo_builtin::exec(const std::vector& bash_args)
{
bool suppress_nl = false;
bool enable_escapes = false;
bool options_parsed = false;
if(bash_args.empty())
{
this->out_buffer() << std::endl;
return 0;
}
for(auto i = bash_args.begin(); i != bash_args.end(); i++)
{
const std::string& str = *i;
if(!options_parsed)
{
options_parsed = determine_options(str, suppress_nl, enable_escapes);
}
if(options_parsed)
{
if(enable_escapes)
{
for(; i != bash_args.end(); i++)
{
try
{
cppbash_builtin::transform_escapes(*i, out_buffer(), false);
}
catch(suppress_output)
{
return 0;
}
}
}
else
{
this->out_buffer() << karma::format(karma::string % ' ', std::vector(i, bash_args.end()));
}
if(!suppress_nl)
this->out_buffer() << std::endl;
return 0;
}
}
return 0;
}
bool echo_builtin::determine_options(const std::string &string, bool &suppress_nl, bool &enable_escapes)
{
using phoenix::ref;
using qi::char_;
bool n_matched = false, e_matched = false, E_matched = false;
auto options = '-' >>
+(
char_('n')[ref(n_matched) = true] |
char_('e')[ref(e_matched) = true, ref(E_matched) = false] |
char_('E')[ref(E_matched) = true, ref(e_matched) = false]
);
auto first = string.begin();
qi::parse(first, string.end(), options);
if(first != string.end()) {
return true;
}
else
{
if(n_matched)
suppress_nl = true;
if(e_matched)
enable_escapes = true;
if(E_matched)
enable_escapes = false;
return false;
}
}