Import atf-0.20.

This is a MFC of r261897 and r262000 and should allow all of the atf
tests to pass.
This commit is contained in:
jmmv 2014-03-06 14:11:44 +00:00
parent 6c6bd8779d
commit fe643776c1
47 changed files with 291 additions and 3666 deletions

View File

@ -18,3 +18,4 @@ configure*
doc/atf-formats.5
doc/atf.7.in
m4/
tools/

View File

@ -6,13 +6,3 @@ include("atf-c/Kyuafile")
include("atf-c++/Kyuafile")
include("atf-sh/Kyuafile")
include("test-programs/Kyuafile")
if fs.exists("atf-config/Kyuafile") then
include("atf-config/Kyuafile")
end
if fs.exists("atf-report/Kyuafile") then
include("atf-report/Kyuafile")
end
if fs.exists("atf-run/Kyuafile") then
include("atf-run/Kyuafile")
end

View File

@ -2,6 +2,51 @@ Major changes between releases Automated Testing Framework
===========================================================================
Changes in version 0.20
***********************
Experimental version released on February 7th, 2014.
This is the first release without the code for the deprecated tools. If
you require such code, please fetch a copy of the 0.19 release and extract
the 'tools' directory for your own consumption.
* Removed the deprecated tools. This includes atf-config, atf-report,
atf-run and atf-version.
Changes in version 0.19
***********************
Experimental version released on February 7th, 2014.
This is the last release to bundle the code for the deprecated tools.
The next release will drop their code and will stop worrying about
backwards compatibility between the ATF libraries and what the old tools
may or may not support.
If you still require the old tools for some reason, grab a copy of the
'tools' directory now. The code in this directory is standalone and
does not depend on any internal details of atf-c++ any longer.
* Various fixes and improvements to support running as part of the FreeBSD
test suite.
* Project hosting moved from Google Code (as a subproject of Kyua) to
GitHub (as a first-class project). The main reason for the change is
the suppression of binary downloads in Google Code on Jan 15th, 2014.
See https://github.com/jmmv/atf/
* Removed builtin help from atf-sh(1) and atf-check(1) for simplicity
reasons. In other words, their -h option is gone.
* Moved the code of the deprecated tools into a 'tools' directory and
completely decoupled their code from the internals of atf-c++. The
reason for this is to painlessly allow a third-party to maintain a
copy of these tools after we delete them because upcoming changes to
atf-c++ would break the stale tools.
Changes in version 0.18
***********************

View File

@ -5,21 +5,18 @@ Introductory information Automated Testing Framework
Introduction
************
The Automated Testing Framework (ATF) is a collection of libraries and
utilities designed to ease unattended application testing in the hands of
developers and end users of a specific piece of software.
The Automated Testing Framework (ATF) is a collection of libraries to
implement test programs in a variety of languages. At the moment, ATF
offers C, C++ and POSIX shell bindings with which to implement tests.
These bindings all offer a similar set of functionality and any test
program written with them exposes a consistent user interface.
As regards developers, ATF provides the necessary means to easily create
test suites composed of multiple test programs, which in turn are a
collection of test cases. It also attempts to simplify the debugging of
problems when these test cases detect an error by providing as much
information as possible about the failure.
As regards users, it simplifies the process of running the test suites and,
in special, encourages end users to run them often: they do not need to
have source trees around nor any other development tools installed to be
able to certify that a given piece of software works on their machine as
advertised.
ATF-based test programs rely on a separate runtime engine to execute them.
The runtime engine is in charge of isolating the test programs from the
rest of the system to ensure that their results are deterministic and that
they cannot affect the running system. The runtime engine is also
responsible for gathering the results of all tests and composing reports.
The current runtime of choice is Kyua.
Other documents

View File

@ -39,8 +39,6 @@ extern "C" {
#include <string>
#include <vector>
#include <atf-c++/noncopyable.hpp>
namespace atf {
namespace process {
@ -60,7 +58,11 @@ namespace check {
//! of executing arbitrary command and manages files containing
//! its output.
//!
class check_result : noncopyable {
class check_result {
// Non-copyable.
check_result(const check_result&);
check_result& operator=(const check_result&);
//!
//! \brief Internal representation of a result.
//!

View File

@ -52,18 +52,14 @@ init_variables(void)
{
PRE(m_variables.empty());
m_variables["atf_arch"] = atf_config_get("atf_arch");
m_variables["atf_build_cc"] = atf_config_get("atf_build_cc");
m_variables["atf_build_cflags"] = atf_config_get("atf_build_cflags");
m_variables["atf_build_cpp"] = atf_config_get("atf_build_cpp");
m_variables["atf_build_cppflags"] = atf_config_get("atf_build_cppflags");
m_variables["atf_build_cxx"] = atf_config_get("atf_build_cxx");
m_variables["atf_build_cxxflags"] = atf_config_get("atf_build_cxxflags");
m_variables["atf_confdir"] = atf_config_get("atf_confdir");
m_variables["atf_includedir"] = atf_config_get("atf_includedir");
m_variables["atf_libdir"] = atf_config_get("atf_libdir");
m_variables["atf_libexecdir"] = atf_config_get("atf_libexecdir");
m_variables["atf_machine"] = atf_config_get("atf_machine");
m_variables["atf_pkgdatadir"] = atf_config_get("atf_pkgdatadir");
m_variables["atf_shell"] = atf_config_get("atf_shell");
m_variables["atf_workdir"] = atf_config_get("atf_workdir");

View File

@ -44,18 +44,14 @@ static struct varnames {
const char *uc;
bool can_be_empty;
} all_vars[] = {
{ "atf_arch", "ATF_ARCH", false },
{ "atf_build_cc", "ATF_BUILD_CC", false },
{ "atf_build_cflags", "ATF_BUILD_CFLAGS", true },
{ "atf_build_cpp", "ATF_BUILD_CPP", false },
{ "atf_build_cppflags", "ATF_BUILD_CPPFLAGS", true },
{ "atf_build_cxx", "ATF_BUILD_CXX", false },
{ "atf_build_cxxflags", "ATF_BUILD_CXXFLAGS", true },
{ "atf_confdir", "ATF_CONFDIR", false },
{ "atf_includedir", "ATF_INCLUDEDIR", false },
{ "atf_libdir", "ATF_LIBDIR", false },
{ "atf_libexecdir", "ATF_LIBEXECDIR", false },
{ "atf_machine", "ATF_MACHINE", false },
{ "atf_pkgdatadir", "ATF_PKGDATADIR", false },
{ "atf_shell", "ATF_SHELL", false },
{ "atf_workdir", "ATF_WORKDIR", false },

View File

@ -6,9 +6,7 @@ atf_test_program{name="application_test"}
atf_test_program{name="auto_array_test"}
atf_test_program{name="env_test"}
atf_test_program{name="exceptions_test"}
atf_test_program{name="expand_test"}
atf_test_program{name="fs_test"}
atf_test_program{name="parser_test"}
atf_test_program{name="process_test"}
atf_test_program{name="sanity_test"}
atf_test_program{name="text_test"}
atf_test_program{name="ui_test"}

View File

@ -47,7 +47,6 @@ extern "C" {
#include "application.hpp"
#include "sanity.hpp"
#include "ui.hpp"
#if !defined(HAVE_VSNPRINTF_IN_STD)
namespace std {
@ -106,17 +105,12 @@ impl::option::operator<(const impl::option& o)
}
impl::app::app(const std::string& description,
const std::string& manpage,
const std::string& global_manpage,
const bool use_ui) :
m_hflag(false),
const std::string& manpage) :
m_argc(-1),
m_argv(NULL),
m_prog_name(NULL),
m_description(description),
m_manpage(manpage),
m_global_manpage(global_manpage),
m_use_ui(use_ui)
m_manpage(manpage)
{
}
@ -133,11 +127,7 @@ impl::app::inited(void)
impl::app::options_set
impl::app::options(void)
{
options_set opts = specific_options();
if (m_use_ui) {
opts.insert(option('h', "", "Shows this help message"));
}
return opts;
return specific_options();
}
std::string
@ -187,11 +177,6 @@ impl::app::process_options(void)
::opterr = 0;
while ((ch = ::getopt(m_argc, m_argv, optstr.c_str())) != -1) {
switch (ch) {
case 'h':
INV(m_use_ui);
m_hflag = true;
break;
case ':':
throw usage_error("Option -%c requires an argument.",
::optopt);
@ -214,51 +199,6 @@ impl::app::process_options(void)
#endif
}
void
impl::app::usage(std::ostream& os)
{
PRE(inited());
std::string args = specific_args();
if (!args.empty())
args = " " + args;
os << ui::format_text_with_tag(std::string(m_prog_name) + " [options]" +
args, "Usage: ", false) << "\n\n"
<< ui::format_text(m_description) << "\n\n";
options_set opts = options();
INV(!opts.empty());
os << "Available options:\n";
size_t coldesc = 0;
for (options_set::const_iterator iter = opts.begin();
iter != opts.end(); iter++) {
const option& opt = (*iter);
if (opt.m_argument.length() + 1 > coldesc)
coldesc = opt.m_argument.length() + 1;
}
for (options_set::const_iterator iter = opts.begin();
iter != opts.end(); iter++) {
const option& opt = (*iter);
std::string tag = std::string(" -") + opt.m_character;
if (opt.m_argument.empty())
tag += " ";
else
tag += " " + opt.m_argument + " ";
os << ui::format_text_with_tag(opt.m_description, tag, false,
coldesc + 10) << "\n";
}
os << "\n";
std::string gmp;
if (!m_global_manpage.empty())
gmp = " and " + m_global_manpage;
os << ui::format_text("For more details please see " + m_manpage +
gmp + ".")
<< "\n";
}
int
impl::app::run(int argc, char* const* argv)
{
@ -290,55 +230,22 @@ impl::app::run(int argc, char* const* argv)
int errcode;
try {
int oldargc = m_argc;
process_options();
if (m_hflag) {
INV(m_use_ui);
if (oldargc != 2)
throw usage_error("-h must be given alone.");
usage(std::cout);
errcode = EXIT_SUCCESS;
} else
errcode = main();
errcode = main();
} catch (const usage_error& e) {
if (m_use_ui) {
std::cerr << ui::format_error(m_prog_name, e.what()) << "\n"
<< ui::format_info(m_prog_name, std::string("Type `") +
m_prog_name + " -h' for more details.")
<< "\n";
} else {
std::cerr << m_prog_name << ": ERROR: " << e.what() << "\n";
std::cerr << m_prog_name << ": See " << m_manpage << " for usage "
"details.\n";
}
std::cerr << m_prog_name << ": ERROR: " << e.what() << "\n";
std::cerr << m_prog_name << ": See " << m_manpage << " for usage "
"details.\n";
errcode = EXIT_FAILURE;
} catch (const std::runtime_error& e) {
if (m_use_ui) {
std::cerr << ui::format_error(m_prog_name, std::string(e.what()))
<< "\n";
} else {
std::cerr << m_prog_name << ": ERROR: " << e.what() << "\n";
}
std::cerr << m_prog_name << ": ERROR: " << e.what() << "\n";
errcode = EXIT_FAILURE;
} catch (const std::exception& e) {
if (m_use_ui) {
std::cerr << ui::format_error(m_prog_name, std::string("Caught "
"unexpected error: ") + e.what() + "\n" + bug) << "\n";
} else {
std::cerr << m_prog_name << ": ERROR: Caught unexpected error: "
<< e.what() << "\n";
}
std::cerr << m_prog_name << ": ERROR: Caught unexpected error: "
<< e.what() << "\n";
errcode = EXIT_FAILURE;
} catch (...) {
if (m_use_ui) {
std::cerr << ui::format_error(m_prog_name, std::string("Caught "
"unknown error\n") + bug) << "\n";
} else {
std::cerr << m_prog_name << ": ERROR: Caught unknown error\n";
}
std::cerr << m_prog_name << ": ERROR: Caught unknown error\n";
errcode = EXIT_FAILURE;
}
return errcode;

View File

@ -74,8 +74,6 @@ class option {
// ------------------------------------------------------------------------
class app {
bool m_hflag;
void process_options(void);
void usage(std::ostream&);
@ -90,8 +88,7 @@ class app {
const char* m_argv0;
const char* m_prog_name;
std::string m_description;
std::string m_manpage, m_global_manpage;
const bool m_use_ui;
std::string m_manpage;
options_set options(void);
@ -102,8 +99,7 @@ class app {
virtual int main(void) = 0;
public:
app(const std::string&, const std::string&, const std::string&,
bool = true);
app(const std::string&, const std::string&);
virtual ~app(void);
int run(int, char* const*);

View File

@ -37,7 +37,7 @@ extern "C" {
class getopt_app : public atf::application::app {
public:
getopt_app(void) : app("description", "manpage", "other") {}
getopt_app(void) : app("description", "manpage") {}
int main(void)
{

View File

@ -39,47 +39,6 @@ struct atf_error;
namespace atf {
template< class T >
class not_found_error :
public std::runtime_error
{
T m_value;
public:
not_found_error(const std::string& message, const T& value) throw();
virtual ~not_found_error(void) throw();
const T& get_value(void) const throw();
};
template< class T >
inline
not_found_error< T >::not_found_error(const std::string& message,
const T& value)
throw() :
std::runtime_error(message),
m_value(value)
{
}
template< class T >
inline
not_found_error< T >::~not_found_error(void)
throw()
{
}
template< class T >
inline
const T&
not_found_error< T >::get_value(void)
const
throw()
{
return m_value;
}
class system_error : public std::runtime_error {
int m_sys_err;
mutable std::string m_message;

View File

@ -1,81 +0,0 @@
//
// Automated Testing Framework (atf)
//
// Copyright (c) 2007 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#include <stdexcept>
#include "expand.hpp"
#include "text.hpp"
namespace impl = atf::expand;
#define IMPL_NAME "atf::expand"
// ------------------------------------------------------------------------
// Auxiliary functions.
// ------------------------------------------------------------------------
namespace {
std::string
glob_to_regex(const std::string& glob)
{
std::string regex;
regex.reserve(glob.length() * 2);
regex += '^';
for (std::string::const_iterator iter = glob.begin(); iter != glob.end();
iter++) {
switch (*iter) {
case '*': regex += ".*"; break;
case '?': regex += "."; break;
default: regex += *iter;
}
}
regex += '$';
return regex;
}
} // anonymous namespace
// ------------------------------------------------------------------------
// Free functions.
// ------------------------------------------------------------------------
bool
impl::is_glob(const std::string& glob)
{
// NOTE: Keep this in sync with glob_to_regex!
return glob.find_first_of("*?") != std::string::npos;
}
bool
impl::matches_glob(const std::string& glob, const std::string& candidate)
{
return atf::text::match(candidate, glob_to_regex(glob));
}

View File

@ -1,82 +0,0 @@
//
// Automated Testing Framework (atf)
//
// Copyright (c) 2007 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#if !defined(_ATF_CXX_EXPAND_HPP_)
#define _ATF_CXX_EXPAND_HPP_
#include <string>
#include <vector>
namespace atf {
namespace expand {
// ------------------------------------------------------------------------
// Free functions.
// ------------------------------------------------------------------------
//!
//! \brief Checks if the given string is a glob pattern.
//!
//! Returns true if the given string is a glob pattern; i.e. if it contains
//! any character that will be expanded by expand_glob.
//!
bool is_glob(const std::string&);
//!
//! \brief Checks if a given string matches a glob pattern.
//!
//! Given a glob pattern and a string, checks whether the former matches
//! the latter. Returns a boolean indicating this condition.
//!
bool matches_glob(const std::string&, const std::string&);
//!
//! \brief Expands a glob pattern among multiple candidates.
//!
//! Given a glob pattern and a set of candidate strings, checks which of
//! those strings match the glob pattern and returns them.
//!
template< class T >
std::vector< std::string > expand_glob(const std::string& glob,
const T& candidates)
{
std::vector< std::string > exps;
for (typename T::const_iterator iter = candidates.begin();
iter != candidates.end(); iter++)
if (matches_glob(glob, *iter))
exps.push_back(*iter);
return exps;
}
} // namespace expand
} // namespace atf
#endif // !defined(_ATF_CXX_EXPAND_HPP_)

View File

@ -1,272 +0,0 @@
//
// Automated Testing Framework (atf)
//
// Copyright (c) 2007 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#include <cstring>
#include "../macros.hpp"
#include "expand.hpp"
// XXX Many of the tests here are duplicated in atf-c/t_expand. Should
// find a way to easily share them, or maybe remove the ones here.
// ------------------------------------------------------------------------
// Test cases for the free functions.
// ------------------------------------------------------------------------
ATF_TEST_CASE(is_glob);
ATF_TEST_CASE_HEAD(is_glob)
{
set_md_var("descr", "Tests the is_glob function.");
}
ATF_TEST_CASE_BODY(is_glob)
{
using atf::expand::is_glob;
ATF_REQUIRE(!is_glob(""));
ATF_REQUIRE(!is_glob("a"));
ATF_REQUIRE(!is_glob("foo"));
ATF_REQUIRE( is_glob("*"));
ATF_REQUIRE( is_glob("a*"));
ATF_REQUIRE( is_glob("*a"));
ATF_REQUIRE( is_glob("a*b"));
ATF_REQUIRE( is_glob("?"));
ATF_REQUIRE( is_glob("a?"));
ATF_REQUIRE( is_glob("?a"));
ATF_REQUIRE( is_glob("a?b"));
}
ATF_TEST_CASE(matches_glob_plain);
ATF_TEST_CASE_HEAD(matches_glob_plain)
{
set_md_var("descr", "Tests the matches_glob function by using plain "
"text strings as patterns only.");
}
ATF_TEST_CASE_BODY(matches_glob_plain)
{
using atf::expand::matches_glob;
ATF_REQUIRE( matches_glob("", ""));
ATF_REQUIRE(!matches_glob("a", ""));
ATF_REQUIRE(!matches_glob("", "a"));
ATF_REQUIRE( matches_glob("ab", "ab"));
ATF_REQUIRE(!matches_glob("abc", "ab"));
ATF_REQUIRE(!matches_glob("ab", "abc"));
}
ATF_TEST_CASE(matches_glob_star);
ATF_TEST_CASE_HEAD(matches_glob_star)
{
set_md_var("descr", "Tests the matches_glob function by using the '*' "
"meta-character as part of the pattern.");
}
ATF_TEST_CASE_BODY(matches_glob_star)
{
using atf::expand::matches_glob;
ATF_REQUIRE( matches_glob("*", ""));
ATF_REQUIRE( matches_glob("*", "a"));
ATF_REQUIRE( matches_glob("*", "ab"));
ATF_REQUIRE(!matches_glob("a*", ""));
ATF_REQUIRE( matches_glob("a*", "a"));
ATF_REQUIRE( matches_glob("a*", "aa"));
ATF_REQUIRE( matches_glob("a*", "ab"));
ATF_REQUIRE( matches_glob("a*", "abc"));
ATF_REQUIRE(!matches_glob("a*", "ba"));
ATF_REQUIRE( matches_glob("*a", "a"));
ATF_REQUIRE( matches_glob("*a", "ba"));
ATF_REQUIRE(!matches_glob("*a", "bc"));
ATF_REQUIRE(!matches_glob("*a", "bac"));
ATF_REQUIRE( matches_glob("*ab", "ab"));
ATF_REQUIRE( matches_glob("*ab", "aab"));
ATF_REQUIRE( matches_glob("*ab", "aaab"));
ATF_REQUIRE( matches_glob("*ab", "bab"));
ATF_REQUIRE(!matches_glob("*ab", "bcb"));
ATF_REQUIRE(!matches_glob("*ab", "bacb"));
ATF_REQUIRE( matches_glob("a*b", "ab"));
ATF_REQUIRE( matches_glob("a*b", "acb"));
ATF_REQUIRE( matches_glob("a*b", "acdeb"));
ATF_REQUIRE(!matches_glob("a*b", "acdebz"));
ATF_REQUIRE(!matches_glob("a*b", "zacdeb"));
}
ATF_TEST_CASE(matches_glob_question);
ATF_TEST_CASE_HEAD(matches_glob_question)
{
set_md_var("descr", "Tests the matches_glob function by using the '?' "
"meta-character as part of the pattern.");
}
ATF_TEST_CASE_BODY(matches_glob_question)
{
using atf::expand::matches_glob;
ATF_REQUIRE(!matches_glob("?", ""));
ATF_REQUIRE( matches_glob("?", "a"));
ATF_REQUIRE(!matches_glob("?", "ab"));
ATF_REQUIRE( matches_glob("?", "b"));
ATF_REQUIRE( matches_glob("?", "c"));
ATF_REQUIRE( matches_glob("a?", "ab"));
ATF_REQUIRE( matches_glob("a?", "ac"));
ATF_REQUIRE(!matches_glob("a?", "ca"));
ATF_REQUIRE( matches_glob("???", "abc"));
ATF_REQUIRE( matches_glob("???", "def"));
ATF_REQUIRE(!matches_glob("???", "a"));
ATF_REQUIRE(!matches_glob("???", "ab"));
ATF_REQUIRE(!matches_glob("???", "abcd"));
}
ATF_TEST_CASE(expand_glob_base);
ATF_TEST_CASE_HEAD(expand_glob_base)
{
set_md_var("descr", "Tests the expand_glob function with random "
"patterns.");
}
ATF_TEST_CASE_BODY(expand_glob_base)
{
using atf::expand::expand_glob;
std::vector< std::string > candidates;
candidates.push_back("foo");
candidates.push_back("bar");
candidates.push_back("baz");
candidates.push_back("foobar");
candidates.push_back("foobarbaz");
candidates.push_back("foobarbazfoo");
std::vector< std::string > exps;
exps = expand_glob("foo", candidates);
ATF_REQUIRE_EQ(exps.size(), 1);
ATF_REQUIRE(exps[0] == "foo");
exps = expand_glob("bar", candidates);
ATF_REQUIRE_EQ(exps.size(), 1);
ATF_REQUIRE(exps[0] == "bar");
exps = expand_glob("foo*", candidates);
ATF_REQUIRE_EQ(exps.size(), 4);
ATF_REQUIRE(exps[0] == "foo");
ATF_REQUIRE(exps[1] == "foobar");
ATF_REQUIRE(exps[2] == "foobarbaz");
ATF_REQUIRE(exps[3] == "foobarbazfoo");
exps = expand_glob("*foo", candidates);
ATF_REQUIRE_EQ(exps.size(), 2);
ATF_REQUIRE(exps[0] == "foo");
ATF_REQUIRE(exps[1] == "foobarbazfoo");
exps = expand_glob("*foo*", candidates);
ATF_REQUIRE_EQ(exps.size(), 4);
ATF_REQUIRE(exps[0] == "foo");
ATF_REQUIRE(exps[1] == "foobar");
ATF_REQUIRE(exps[2] == "foobarbaz");
ATF_REQUIRE(exps[3] == "foobarbazfoo");
exps = expand_glob("ba", candidates);
ATF_REQUIRE_EQ(exps.size(), 0);
exps = expand_glob("ba*", candidates);
ATF_REQUIRE_EQ(exps.size(), 2);
ATF_REQUIRE(exps[0] == "bar");
ATF_REQUIRE(exps[1] == "baz");
exps = expand_glob("*ba", candidates);
ATF_REQUIRE_EQ(exps.size(), 0);
exps = expand_glob("*ba*", candidates);
ATF_REQUIRE_EQ(exps.size(), 5);
ATF_REQUIRE(exps[0] == "bar");
ATF_REQUIRE(exps[1] == "baz");
ATF_REQUIRE(exps[2] == "foobar");
ATF_REQUIRE(exps[3] == "foobarbaz");
ATF_REQUIRE(exps[4] == "foobarbazfoo");
}
ATF_TEST_CASE(expand_glob_tps);
ATF_TEST_CASE_HEAD(expand_glob_tps)
{
set_md_var("descr", "Tests the expand_glob function with patterns that "
"match typical test program names. This is just a subcase "
"of expand_base, but it is nice to make sure that it really "
"works.");
}
ATF_TEST_CASE_BODY(expand_glob_tps)
{
using atf::expand::expand_glob;
std::vector< std::string > candidates;
candidates.push_back("Atffile");
candidates.push_back("h_foo");
candidates.push_back("t_foo");
candidates.push_back("t_bar");
candidates.push_back("t_baz");
candidates.push_back("foo_helper");
candidates.push_back("foo_test");
candidates.push_back("bar_test");
candidates.push_back("baz_test");
std::vector< std::string > exps;
exps = expand_glob("t_*", candidates);
ATF_REQUIRE_EQ(exps.size(), 3);
ATF_REQUIRE(exps[0] == "t_foo");
ATF_REQUIRE(exps[1] == "t_bar");
ATF_REQUIRE(exps[2] == "t_baz");
exps = expand_glob("*_test", candidates);
ATF_REQUIRE_EQ(exps.size(), 3);
ATF_REQUIRE(exps[0] == "foo_test");
ATF_REQUIRE(exps[1] == "bar_test");
ATF_REQUIRE(exps[2] == "baz_test");
}
// ------------------------------------------------------------------------
// Main.
// ------------------------------------------------------------------------
ATF_INIT_TEST_CASES(tcs)
{
// Add the tests for the free functions.
ATF_ADD_TEST_CASE(tcs, is_glob);
ATF_ADD_TEST_CASE(tcs, matches_glob_plain);
ATF_ADD_TEST_CASE(tcs, matches_glob_star);
ATF_ADD_TEST_CASE(tcs, matches_glob_question);
ATF_ADD_TEST_CASE(tcs, expand_glob_base);
ATF_ADD_TEST_CASE(tcs, expand_glob_tps);
}

View File

@ -1,384 +0,0 @@
//
// Automated Testing Framework (atf)
//
// Copyright (c) 2007 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#include <sstream>
#include "parser.hpp"
#include "sanity.hpp"
#include "text.hpp"
namespace impl = atf::parser;
#define IMPL_NAME "atf::parser"
// ------------------------------------------------------------------------
// The "parse_error" class.
// ------------------------------------------------------------------------
impl::parse_error::parse_error(size_t line, std::string msg) :
std::runtime_error(msg),
std::pair< size_t, std::string >(line, msg)
{
}
impl::parse_error::~parse_error(void)
throw()
{
}
const char*
impl::parse_error::what(void)
const throw()
{
try {
std::ostringstream oss;
oss << "LONELY PARSE ERROR: " << first << ": " << second;
m_msg = oss.str();
return m_msg.c_str();
} catch (...) {
return "Could not format message for parsing error.";
}
}
impl::parse_error::operator std::string(void)
const
{
return atf::text::to_string(first) + ": " + second;
}
// ------------------------------------------------------------------------
// The "parse_errors" class.
// ------------------------------------------------------------------------
impl::parse_errors::parse_errors(void) :
std::runtime_error("No parsing errors yet")
{
m_msg.clear();
}
impl::parse_errors::~parse_errors(void)
throw()
{
}
const char*
impl::parse_errors::what(void)
const throw()
{
try {
m_msg = atf::text::join(*this, "\n");
return m_msg.c_str();
} catch (...) {
return "Could not format messages for parsing errors.";
}
}
// ------------------------------------------------------------------------
// The "format_error" class.
// ------------------------------------------------------------------------
impl::format_error::format_error(const std::string& w) :
std::runtime_error(w.c_str())
{
}
// ------------------------------------------------------------------------
// The "token" class.
// ------------------------------------------------------------------------
impl::token::token(void) :
m_inited(false)
{
}
impl::token::token(size_t p_line,
const token_type& p_type,
const std::string& p_text) :
m_inited(true),
m_line(p_line),
m_type(p_type),
m_text(p_text)
{
}
size_t
impl::token::lineno(void)
const
{
return m_line;
}
const impl::token_type&
impl::token::type(void)
const
{
return m_type;
}
const std::string&
impl::token::text(void)
const
{
return m_text;
}
impl::token::operator bool(void)
const
{
return m_inited;
}
bool
impl::token::operator!(void)
const
{
return !m_inited;
}
// ------------------------------------------------------------------------
// The "header_entry" class.
// ------------------------------------------------------------------------
impl::header_entry::header_entry(void)
{
}
impl::header_entry::header_entry(const std::string& n, const std::string& v,
attrs_map as) :
m_name(n),
m_value(v),
m_attrs(as)
{
}
const std::string&
impl::header_entry::name(void) const
{
return m_name;
}
const std::string&
impl::header_entry::value(void) const
{
return m_value;
}
const impl::attrs_map&
impl::header_entry::attrs(void) const
{
return m_attrs;
}
bool
impl::header_entry::has_attr(const std::string& n) const
{
return m_attrs.find(n) != m_attrs.end();
}
const std::string&
impl::header_entry::get_attr(const std::string& n) const
{
attrs_map::const_iterator iter = m_attrs.find(n);
PRE(iter != m_attrs.end());
return (*iter).second;
}
// ------------------------------------------------------------------------
// The header tokenizer.
// ------------------------------------------------------------------------
namespace header {
static const impl::token_type eof_type = 0;
static const impl::token_type nl_type = 1;
static const impl::token_type text_type = 2;
static const impl::token_type colon_type = 3;
static const impl::token_type semicolon_type = 4;
static const impl::token_type dblquote_type = 5;
static const impl::token_type equal_type = 6;
class tokenizer : public impl::tokenizer< std::istream > {
public:
tokenizer(std::istream& is, size_t curline) :
impl::tokenizer< std::istream >
(is, true, eof_type, nl_type, text_type, curline)
{
add_delim(';', semicolon_type);
add_delim(':', colon_type);
add_delim('=', equal_type);
add_quote('"', dblquote_type);
}
};
static
impl::parser< header::tokenizer >&
read(impl::parser< header::tokenizer >& p, impl::header_entry& he)
{
using namespace header;
impl::token t = p.expect(text_type, nl_type, "a header name");
if (t.type() == nl_type) {
he = impl::header_entry();
return p;
}
std::string hdr_name = t.text();
t = p.expect(colon_type, "`:'");
t = p.expect(text_type, "a textual value");
std::string hdr_value = t.text();
impl::attrs_map attrs;
for (;;) {
t = p.expect(eof_type, semicolon_type, nl_type,
"eof, `;' or new line");
if (t.type() == eof_type || t.type() == nl_type)
break;
t = p.expect(text_type, "an attribute name");
std::string attr_name = t.text();
t = p.expect(equal_type, "`='");
t = p.expect(text_type, "word or quoted string");
std::string attr_value = t.text();
attrs[attr_name] = attr_value;
}
he = impl::header_entry(hdr_name, hdr_value, attrs);
return p;
}
static
std::ostream&
write(std::ostream& os, const impl::header_entry& he)
{
std::string line = he.name() + ": " + he.value();
impl::attrs_map as = he.attrs();
for (impl::attrs_map::const_iterator iter = as.begin(); iter != as.end();
iter++) {
PRE((*iter).second.find('\"') == std::string::npos);
line += "; " + (*iter).first + "=\"" + (*iter).second + "\"";
}
os << line << "\n";
return os;
}
} // namespace header
// ------------------------------------------------------------------------
// Free functions.
// ------------------------------------------------------------------------
std::pair< size_t, impl::headers_map >
impl::read_headers(std::istream& is, size_t curline)
{
using impl::format_error;
headers_map hm;
//
// Grammar
//
// header = entry+ nl
// entry = line nl
// line = text colon text
// (semicolon (text equal (text | dblquote string dblquote)))*
// string = quoted_string
//
header::tokenizer tkz(is, curline);
impl::parser< header::tokenizer > p(tkz);
bool first = true;
for (;;) {
try {
header_entry he;
if (!header::read(p, he).good() || he.name().empty())
break;
if (first && he.name() != "Content-Type")
throw format_error("Could not determine content type");
else
first = false;
hm[he.name()] = he;
} catch (const impl::parse_error& pe) {
p.add_error(pe);
p.reset(header::nl_type);
}
}
if (!is.good())
throw format_error("Unexpected end of stream");
return std::pair< size_t, headers_map >(tkz.lineno(), hm);
}
void
impl::write_headers(const impl::headers_map& hm, std::ostream& os)
{
PRE(!hm.empty());
headers_map::const_iterator ct = hm.find("Content-Type");
PRE(ct != hm.end());
header::write(os, (*ct).second);
for (headers_map::const_iterator iter = hm.begin(); iter != hm.end();
iter++) {
if ((*iter).first != "Content-Type")
header::write(os, (*iter).second);
}
os << "\n";
}
void
impl::validate_content_type(const impl::headers_map& hm, const std::string& fmt,
int version)
{
using impl::format_error;
headers_map::const_iterator iter = hm.find("Content-Type");
if (iter == hm.end())
throw format_error("Could not determine content type");
const header_entry& he = (*iter).second;
if (he.value() != fmt)
throw format_error("Mismatched content type: expected `" + fmt +
"' but got `" + he.value() + "'");
if (!he.has_attr("version"))
throw format_error("Could not determine version");
const std::string& vstr = atf::text::to_string(version);
if (he.get_attr("version") != vstr)
throw format_error("Mismatched version: expected `" +
vstr + "' but got `" +
he.get_attr("version") + "'");
}

View File

@ -1,607 +0,0 @@
//
// Automated Testing Framework (atf)
//
// Copyright (c) 2007 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#if !defined(_ATF_CXX_PARSER_HPP_)
#define _ATF_CXX_PARSER_HPP_
#include <istream>
#include <map>
#include <ostream>
#include <stdexcept>
#include <string>
#include <utility>
#include <vector>
namespace atf {
namespace parser {
// ------------------------------------------------------------------------
// The "parse_error" class.
// ------------------------------------------------------------------------
class parse_error : public std::runtime_error,
public std::pair< size_t, std::string > {
mutable std::string m_msg;
public:
parse_error(size_t, std::string);
~parse_error(void) throw();
const char* what(void) const throw();
operator std::string(void) const;
};
// ------------------------------------------------------------------------
// The "parse_errors" class.
// ------------------------------------------------------------------------
class parse_errors : public std::runtime_error,
public std::vector< parse_error > {
std::vector< parse_error > m_errors;
mutable std::string m_msg;
public:
parse_errors(void);
~parse_errors(void) throw();
const char* what(void) const throw();
};
// ------------------------------------------------------------------------
// The "format_error" class.
// ------------------------------------------------------------------------
class format_error : public std::runtime_error {
public:
format_error(const std::string&);
};
// ------------------------------------------------------------------------
// The "token" class.
// ------------------------------------------------------------------------
typedef int token_type;
//!
//! \brief Representation of a read token.
//!
//! A pair that contains the information of a token read from a stream.
//! It contains the token's type and its associated data, if any.
//!
struct token {
bool m_inited;
size_t m_line;
token_type m_type;
std::string m_text;
public:
token(void);
token(size_t, const token_type&, const std::string& = "");
size_t lineno(void) const;
const token_type& type(void) const;
const std::string& text(void) const;
operator bool(void) const;
bool operator!(void) const;
};
// ------------------------------------------------------------------------
// The "tokenizer" class.
// ------------------------------------------------------------------------
//!
//! \brief A stream tokenizer.
//!
//! This template implements an extremely simple, line-oriented stream
//! tokenizer. It is only able to recognize one character-long delimiters,
//! random-length keywords, skip whitespace and, anything that does not
//! match these rules is supposed to be a word.
//!
//! Parameter IS: The input stream's type.
//!
template< class IS >
class tokenizer {
IS& m_is;
size_t m_lineno;
token m_la;
bool m_skipws;
token_type m_eof_type, m_nl_type, m_text_type;
std::map< char, token_type > m_delims_map;
std::string m_delims_str;
char m_quotech;
token_type m_quotetype;
std::map< std::string, token_type > m_keywords_map;
token_type alloc_type(void);
template< class TKZ >
friend
class parser;
public:
tokenizer(IS&, bool, const token_type&, const token_type&,
const token_type&, size_t = 1);
size_t lineno(void) const;
void add_delim(char, const token_type&);
void add_keyword(const std::string&, const token_type&);
void add_quote(char, const token_type&);
token next(void);
std::string rest_of_line(void);
};
template< class IS >
tokenizer< IS >::tokenizer(IS& p_is,
bool p_skipws,
const token_type& p_eof_type,
const token_type& p_nl_type,
const token_type& p_text_type,
size_t p_lineno) :
m_is(p_is),
m_lineno(p_lineno),
m_skipws(p_skipws),
m_eof_type(p_eof_type),
m_nl_type(p_nl_type),
m_text_type(p_text_type),
m_quotech(-1)
{
}
template< class IS >
size_t
tokenizer< IS >::lineno(void)
const
{
return m_lineno;
}
template< class IS >
void
tokenizer< IS >::add_delim(char delim, const token_type& type)
{
m_delims_map[delim] = type;
m_delims_str += delim;
}
template< class IS >
void
tokenizer< IS >::add_keyword(const std::string& keyword,
const token_type& type)
{
m_keywords_map[keyword] = type;
}
template< class IS >
void
tokenizer< IS >::add_quote(char ch, const token_type& type)
{
m_quotech = ch;
m_quotetype = type;
}
template< class IS >
token
tokenizer< IS >::next(void)
{
if (m_la) {
token t = m_la;
m_la = token();
if (t.type() == m_nl_type)
m_lineno++;
return t;
}
char ch;
std::string text;
bool done = false, quoted = false;
token t(m_lineno, m_eof_type, "<<EOF>>");
while (!done && m_is.get(ch).good()) {
if (ch == m_quotech) {
if (text.empty()) {
bool escaped = false;
while (!done && m_is.get(ch).good()) {
if (!escaped) {
if (ch == '\\')
escaped = true;
else if (ch == '\n') {
m_la = token(m_lineno, m_nl_type, "<<NEWLINE>>");
throw parse_error(t.lineno(),
"Missing double quotes before "
"end of line");
} else if (ch == m_quotech)
done = true;
else
text += ch;
} else {
text += ch;
escaped = false;
}
}
if (!m_is.good())
throw parse_error(t.lineno(),
"Missing double quotes before "
"end of file");
t = token(m_lineno, m_text_type, text);
quoted = true;
} else {
m_is.putback(ch);
done = true;
}
} else {
typename std::map< char, token_type >::const_iterator idelim;
idelim = m_delims_map.find(ch);
if (idelim != m_delims_map.end()) {
done = true;
if (text.empty())
t = token(m_lineno, (*idelim).second,
std::string("") + ch);
else
m_is.putback(ch);
} else if (ch == '\n') {
done = true;
if (text.empty())
t = token(m_lineno, m_nl_type, "<<NEWLINE>>");
else
m_is.putback(ch);
} else if (m_skipws && (ch == ' ' || ch == '\t')) {
if (!text.empty())
done = true;
} else
text += ch;
}
}
if (!quoted && !text.empty()) {
typename std::map< std::string, token_type >::const_iterator ikw;
ikw = m_keywords_map.find(text);
if (ikw != m_keywords_map.end())
t = token(m_lineno, (*ikw).second, text);
else
t = token(m_lineno, m_text_type, text);
}
if (t.type() == m_nl_type)
m_lineno++;
return t;
}
template< class IS >
std::string
tokenizer< IS >::rest_of_line(void)
{
std::string str;
while (m_is.good() && m_is.peek() != '\n')
str += m_is.get();
return str;
}
// ------------------------------------------------------------------------
// The "parser" class.
// ------------------------------------------------------------------------
template< class TKZ >
class parser {
TKZ& m_tkz;
token m_last;
parse_errors m_errors;
bool m_thrown;
public:
parser(TKZ& tkz);
~parser(void);
bool good(void) const;
void add_error(const parse_error&);
bool has_errors(void) const;
token next(void);
std::string rest_of_line(void);
token reset(const token_type&);
token
expect(const token_type&,
const std::string&);
token
expect(const token_type&,
const token_type&,
const std::string&);
token
expect(const token_type&,
const token_type&,
const token_type&,
const std::string&);
token
expect(const token_type&,
const token_type&,
const token_type&,
const token_type&,
const std::string&);
token
expect(const token_type&,
const token_type&,
const token_type&,
const token_type&,
const token_type&,
const token_type&,
const token_type&,
const std::string&);
token
expect(const token_type&,
const token_type&,
const token_type&,
const token_type&,
const token_type&,
const token_type&,
const token_type&,
const token_type&,
const std::string&);
};
template< class TKZ >
parser< TKZ >::parser(TKZ& tkz) :
m_tkz(tkz),
m_thrown(false)
{
}
template< class TKZ >
parser< TKZ >::~parser(void)
{
if (!m_errors.empty() && !m_thrown)
throw m_errors;
}
template< class TKZ >
bool
parser< TKZ >::good(void)
const
{
return m_tkz.m_is.good();
}
template< class TKZ >
void
parser< TKZ >::add_error(const parse_error& pe)
{
m_errors.push_back(pe);
}
template< class TKZ >
bool
parser< TKZ >::has_errors(void)
const
{
return !m_errors.empty();
}
template< class TKZ >
token
parser< TKZ >::next(void)
{
token t = m_tkz.next();
m_last = t;
if (t.type() == m_tkz.m_eof_type) {
if (!m_errors.empty()) {
m_thrown = true;
throw m_errors;
}
}
return t;
}
template< class TKZ >
std::string
parser< TKZ >::rest_of_line(void)
{
return m_tkz.rest_of_line();
}
template< class TKZ >
token
parser< TKZ >::reset(const token_type& stop)
{
token t = m_last;
while (t.type() != m_tkz.m_eof_type && t.type() != stop)
t = next();
return t;
}
template< class TKZ >
token
parser< TKZ >::expect(const token_type& t1,
const std::string& textual)
{
token t = next();
if (t.type() != t1)
throw parse_error(t.lineno(),
"Unexpected token `" + t.text() +
"'; expected " + textual);
return t;
}
template< class TKZ >
token
parser< TKZ >::expect(const token_type& t1,
const token_type& t2,
const std::string& textual)
{
token t = next();
if (t.type() != t1 && t.type() != t2)
throw parse_error(t.lineno(),
"Unexpected token `" + t.text() +
"'; expected " + textual);
return t;
}
template< class TKZ >
token
parser< TKZ >::expect(const token_type& t1,
const token_type& t2,
const token_type& t3,
const std::string& textual)
{
token t = next();
if (t.type() != t1 && t.type() != t2 && t.type() != t3)
throw parse_error(t.lineno(),
"Unexpected token `" + t.text() +
"'; expected " + textual);
return t;
}
template< class TKZ >
token
parser< TKZ >::expect(const token_type& t1,
const token_type& t2,
const token_type& t3,
const token_type& t4,
const std::string& textual)
{
token t = next();
if (t.type() != t1 && t.type() != t2 && t.type() != t3 &&
t.type() != t4)
throw parse_error(t.lineno(),
"Unexpected token `" + t.text() +
"'; expected " + textual);
return t;
}
template< class TKZ >
token
parser< TKZ >::expect(const token_type& t1,
const token_type& t2,
const token_type& t3,
const token_type& t4,
const token_type& t5,
const token_type& t6,
const token_type& t7,
const std::string& textual)
{
token t = next();
if (t.type() != t1 && t.type() != t2 && t.type() != t3 &&
t.type() != t4 && t.type() != t5 && t.type() != t6 &&
t.type() != t7)
throw parse_error(t.lineno(),
"Unexpected token `" + t.text() +
"'; expected " + textual);
return t;
}
template< class TKZ >
token
parser< TKZ >::expect(const token_type& t1,
const token_type& t2,
const token_type& t3,
const token_type& t4,
const token_type& t5,
const token_type& t6,
const token_type& t7,
const token_type& t8,
const std::string& textual)
{
token t = next();
if (t.type() != t1 && t.type() != t2 && t.type() != t3 &&
t.type() != t4 && t.type() != t5 && t.type() != t6 &&
t.type() != t7 && t.type() != t8)
throw parse_error(t.lineno(),
"Unexpected token `" + t.text() +
"'; expected " + textual);
return t;
}
#define ATF_PARSER_CALLBACK(parser, func) \
do { \
if (!(parser).has_errors()) \
func; \
} while (false)
// ------------------------------------------------------------------------
// Header parsing.
// ------------------------------------------------------------------------
typedef std::map< std::string, std::string > attrs_map;
class header_entry {
std::string m_name;
std::string m_value;
attrs_map m_attrs;
public:
header_entry(void);
header_entry(const std::string&, const std::string&,
attrs_map = attrs_map());
const std::string& name(void) const;
const std::string& value(void) const;
const attrs_map& attrs(void) const;
bool has_attr(const std::string&) const;
const std::string& get_attr(const std::string&) const;
};
typedef std::map< std::string, header_entry > headers_map;
std::pair< size_t, headers_map > read_headers(std::istream&, size_t);
void write_headers(const headers_map&, std::ostream&);
void validate_content_type(const headers_map&, const std::string&, int);
} // namespace parser
} // namespace atf
#endif // !defined(_ATF_CXX_PARSER_HPP_)

File diff suppressed because it is too large Load Diff

View File

@ -52,28 +52,24 @@ static const char* atf_c_tests_base = NULL;
#endif
#undef ATF_C_TESTS_BASE
void
build_check_cxx_o_aux(const atf::fs::path& sfile, const char* failmsg,
const bool expect_pass)
bool
build_check_cxx_o(const char* sfile)
{
std::vector< std::string > optargs;
optargs.push_back("-I" + atf::config::get("atf_includedir"));
optargs.push_back("-Wall");
optargs.push_back("-Werror");
const bool result = atf::check::build_cxx_o(
sfile.str(), "test.o", atf::process::argv_array(optargs));
if ((expect_pass && !result) || (!expect_pass && result))
ATF_FAIL(failmsg);
return atf::check::build_cxx_o(sfile, "test.o",
atf::process::argv_array(optargs));
}
void
build_check_cxx_o(const atf::tests::tc& tc, const char* sfile,
const char* failmsg, const bool expect_pass)
bool
build_check_cxx_o_srcdir(const atf::tests::tc& tc, const char* sfile)
{
const atf::fs::path sfilepath =
atf::fs::path(tc.get_config_var("srcdir")) / sfile;
build_check_cxx_o_aux(sfilepath, failmsg, expect_pass);
return build_check_cxx_o(sfilepath.c_str());
}
void
@ -86,7 +82,8 @@ header_check(const char *hdrname)
const std::string failmsg = std::string("Header check failed; ") +
hdrname + " is not self-contained";
build_check_cxx_o_aux(atf::fs::path("test.cpp"), failmsg.c_str(), true);
if (!build_check_cxx_o("test.cpp"))
ATF_FAIL(failmsg);
}
atf::fs::path
@ -104,37 +101,3 @@ get_process_helpers_path(const atf::tests::tc& tc, bool is_detail)
return atf::fs::path(atf_c_tests_base) / helper;
}
}
void
test_helpers_detail::check_equal(const char* expected[],
const string_vector& actual)
{
const char** expected_iter = expected;
string_vector::const_iterator actual_iter = actual.begin();
bool equals = true;
while (equals && *expected_iter != NULL && actual_iter != actual.end()) {
if (*expected_iter != *actual_iter) {
equals = false;
} else {
expected_iter++;
actual_iter++;
}
}
if (equals && ((*expected_iter == NULL && actual_iter != actual.end()) ||
(*expected_iter != NULL && actual_iter == actual.end())))
equals = false;
if (!equals) {
std::cerr << "EXPECTED:\n";
for (expected_iter = expected; *expected_iter != NULL; expected_iter++)
std::cerr << *expected_iter << "\n";
std::cerr << "ACTUAL:\n";
for (actual_iter = actual.begin(); actual_iter != actual.end();
actual_iter++)
std::cerr << *actual_iter << "\n";
ATF_FAIL("Expected results differ to actual values");
}
}

View File

@ -40,9 +40,7 @@
#include "../macros.hpp"
#include "../tests.hpp"
#include "parser.hpp"
#include "process.hpp"
#include "text.hpp"
#define HEADER_TC(name, hdrname) \
ATF_TEST_CASE(name); \
@ -64,18 +62,8 @@
} \
ATF_TEST_CASE_BODY(name) \
{ \
build_check_cxx_o(*this, sfile, failmsg, true); \
}
#define BUILD_TC_FAIL(name, sfile, descr, failmsg) \
ATF_TEST_CASE(name); \
ATF_TEST_CASE_HEAD(name) \
{ \
set_md_var("descr", descr); \
} \
ATF_TEST_CASE_BODY(name) \
{ \
build_check_cxx_o(*this, sfile, failmsg, false); \
if (!build_check_cxx_o_srcdir(*this, sfile)) \
ATF_FAIL(failmsg); \
}
namespace atf {
@ -85,7 +73,8 @@ class tc;
}
void header_check(const char*);
void build_check_cxx_o(const atf::tests::tc&, const char*, const char*, bool);
bool build_check_cxx_o(const char*);
bool build_check_cxx_o_srcdir(const atf::tests::tc&, const char*);
atf::fs::path get_process_helpers_path(const atf::tests::tc&, bool);
struct run_h_tc_data {
@ -120,45 +109,3 @@ run_h_tc(atf::tests::vars_map config = atf::tests::vars_map())
const atf::process::status s = c.wait();
ATF_REQUIRE(s.exited());
}
namespace test_helpers_detail {
typedef std::vector< std::string > string_vector;
template< class Reader >
std::pair< string_vector, string_vector >
do_read(const char* input)
{
string_vector errors;
std::istringstream is(input);
Reader reader(is);
try {
reader.read();
} catch (const atf::parser::parse_errors& pes) {
for (std::vector< atf::parser::parse_error >::const_iterator iter =
pes.begin(); iter != pes.end(); iter++)
errors.push_back(*iter);
} catch (const atf::parser::parse_error& pe) {
ATF_FAIL("Raised a lonely parse error: " +
atf::text::to_string(pe.first) + ": " + pe.second);
}
return std::make_pair(reader.m_calls, errors);
}
void check_equal(const char*[], const string_vector&);
} // namespace test_helpers_detail
template< class Reader >
void
do_parser_test(const char* input, const char* exp_calls[],
const char* exp_errors[])
{
const std::pair< test_helpers_detail::string_vector,
test_helpers_detail::string_vector >
actual = test_helpers_detail::do_read< Reader >(input);
test_helpers_detail::check_equal(exp_calls, actual.first);
test_helpers_detail::check_equal(exp_errors, actual.second);
}

View File

@ -1,173 +0,0 @@
//
// Automated Testing Framework (atf)
//
// Copyright (c) 2007 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
extern "C" {
#include <sys/ioctl.h>
#include <termios.h>
#include <unistd.h>
}
#include <sstream>
#include "env.hpp"
#include "text.hpp"
#include "sanity.hpp"
#include "text.hpp"
#include "ui.hpp"
namespace impl = atf::ui;
#define IMPL_NAME "atf::ui"
static
size_t
terminal_width(void)
{
static bool done = false;
static size_t width = 0;
if (!done) {
if (atf::env::has("COLUMNS")) {
const std::string cols = atf::env::get("COLUMNS");
if (cols.length() > 0) {
width = atf::text::to_type< size_t >(cols);
}
} else {
struct winsize ws;
if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) != -1)
width = ws.ws_col;
}
if (width >= 80)
width -= 5;
done = true;
}
return width;
}
static
std::string
format_paragraph(const std::string& text,
const std::string& tag,
const bool first,
const bool repeat,
const size_t col)
{
PRE(text.find('\n') == std::string::npos);
const std::string pad(col - tag.length(), ' ');
const std::string fullpad(col, ' ');
std::string formatted;
if (first || repeat)
formatted = tag + pad;
else
formatted = fullpad;
INV(formatted.length() == col);
size_t curcol = col;
const size_t maxcol = terminal_width();
std::vector< std::string > words = atf::text::split(text, " ");
for (std::vector< std::string >::const_iterator iter = words.begin();
iter != words.end(); iter++) {
const std::string& word = *iter;
if (iter != words.begin() && maxcol > 0 &&
curcol + word.length() + 1 > maxcol) {
if (repeat)
formatted += '\n' + tag + pad;
else
formatted += '\n' + fullpad;
curcol = col;
} else if (iter != words.begin()) {
formatted += ' ';
curcol++;
}
formatted += word;
curcol += word.length();
}
return formatted;
}
std::string
impl::format_error(const std::string& prog_name, const std::string& error)
{
return format_text_with_tag("ERROR: " + error, prog_name + ": ", true);
}
std::string
impl::format_info(const std::string& prog_name, const std::string& msg)
{
return format_text_with_tag(msg, prog_name + ": ", true);
}
std::string
impl::format_text(const std::string& text)
{
return format_text_with_tag(text, "", false, 0);
}
std::string
impl::format_text_with_tag(const std::string& text, const std::string& tag,
bool repeat, size_t col)
{
PRE(col == 0 || col >= tag.length());
if (col == 0)
col = tag.length();
std::string formatted;
std::vector< std::string > lines = atf::text::split(text, "\n");
for (std::vector< std::string >::const_iterator iter = lines.begin();
iter != lines.end(); iter++) {
const std::string& line = *iter;
formatted += format_paragraph(line, tag, iter == lines.begin(),
repeat, col);
if (iter + 1 != lines.end()) {
if (repeat)
formatted += "\n" + tag + "\n";
else
formatted += "\n\n";
}
}
return formatted;
}
std::string
impl::format_warning(const std::string& prog_name, const std::string& error)
{
return format_text_with_tag("WARNING: " + error, prog_name + ": ", true);
}

View File

@ -1,105 +0,0 @@
//
// Automated Testing Framework (atf)
//
// Copyright (c) 2007 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#if !defined(_ATF_CXX_UI_HPP_)
#define _ATF_CXX_UI_HPP_
#include <string>
namespace atf {
namespace ui {
//!
//! \brief Formats an error message to fit on screen.
//!
//! Given the program's name and an error message, properly formats it to
//! fit on screen.
//!
//! The program's name is not stored globally to prevent the usage of this
//! function from inside the library. Making it a explicit parameter
//! restricts its usage to the frontend.
//!
std::string format_error(const std::string&, const std::string&);
//!
//! \brief Formats an informational message to fit on screen.
//!
//! Given the program's name and an informational message, properly formats
//! it to fit on screen.
//!
//! The program's name is not stored globally to prevent the usage of this
//! function from inside the library. Making it a explicit parameter
//! restricts its usage to the frontend.
//!
std::string format_info(const std::string&, const std::string&);
//!
//! \brief Formats a block of text to fit nicely on screen.
//!
//! Given a text, which is composed of multiple paragraphs separated by
//! a single '\n' character, reformats it to fill on the current screen's
//! width with proper line wrapping.
//!
//! This is just a special case of format_text_with_tag, provided for
//! simplicity.
//!
std::string format_text(const std::string&);
//!
//! \brief Formats a block of text to fit nicely on screen, prepending a
//! tag to it.
//!
//! Given a text, which is composed of multiple paragraphs separated by
//! a single '\n' character, reformats it to fill on the current screen's
//! width with proper line wrapping. The text is prepended with a tag;
//! i.e. a word that is printed at the beginning of the first paragraph and
//! optionally repeated at the beginning of each word. The last parameter
//! specifies the column on which the text should start, and that position
//! must be greater than the tag's length or 0, in which case it
//! automatically takes the correct value.
//!
std::string format_text_with_tag(const std::string&, const std::string&,
bool, size_t = 0);
//!
//! \brief Formats a warning message to fit on screen.
//!
//! Given the program's name and a warning message, properly formats it to
//! fit on screen.
//!
//! The program's name is not stored globally to prevent the usage of this
//! function from inside the library. Making it a explicit parameter
//! restricts its usage to the frontend.
//!
std::string format_warning(const std::string&, const std::string&);
} // namespace ui
} // namespace atf
#endif // !defined(_ATF_CXX_UI_HPP_)

View File

@ -1,462 +0,0 @@
//
// Automated Testing Framework (atf)
//
// Copyright (c) 2009 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#include <cstring>
#include <iostream>
#include "../macros.hpp"
#include "env.hpp"
#include "ui.hpp"
// ------------------------------------------------------------------------
// Test cases for the free functions.
// ------------------------------------------------------------------------
struct test {
const char *tc;
const char *tag;
bool repeat;
size_t col;
const char *fmt;
const char *result;
} tests[] = {
//
// wo_tag
//
{
"wo_tag",
"",
false,
0,
"12345",
"12345",
},
{
"wo_tag",
"",
false,
0,
"12345 ",
"12345",
},
{
"wo_tag",
"",
false,
0,
"12345 7890",
"12345 7890",
},
{
"wo_tag",
"",
false,
0,
"12345 789012 45",
"12345 789012 45",
},
{
"wo_tag",
"",
false,
0,
"12345 789012 456",
"12345 789012\n456",
},
{
"wo_tag",
"",
false,
0,
"1234567890123456",
"1234567890123456",
},
// TODO(jmmv): Fix the code to pass this test...
// {
// "wo_tag",
// "",
// false,
// 0,
// " 2345678901234567",
// "\n2345678901234567",
// },
{
"wo_tag",
"",
false,
0,
"12345 789012345 78",
"12345 789012345\n78",
},
//
// wo_tag_col
//
{
"wo_tag_col",
"",
false,
10,
"12345",
" 12345",
},
{
"wo_tag_col",
"",
false,
10,
"12345 7890",
" 12345\n"
" 7890",
},
{
"wo_tag_col",
"",
false,
10,
"1 3 5 7 9",
" 1 3 5\n"
" 7 9",
},
//
// w_tag_no_repeat
//
{
"w_tag_no_repeat",
"1234: ",
false,
0,
"789012345",
"1234: 789012345",
},
{
"w_tag_no_repeat",
"1234: ",
false,
0,
"789 1234 56789",
"1234: 789 1234\n"
" 56789",
},
{
"w_tag_no_repeat",
"1234: ",
false,
0,
"789012345",
"1234: 789012345",
},
{
"w_tag_no_repeat",
"1234: ",
false,
0,
"789012345 7890",
"1234: 789012345\n"
" 7890",
},
//
// w_tag_repeat
//
{
"w_tag_repeat",
"1234: ",
true,
0,
"789012345",
"1234: 789012345",
},
{
"w_tag_repeat",
"1234: ",
true,
0,
"789 1234 56789",
"1234: 789 1234\n"
"1234: 56789",
},
{
"w_tag_repeat",
"1234: ",
true,
0,
"789012345",
"1234: 789012345",
},
{
"w_tag_no_repeat",
"1234: ",
true,
0,
"789012345 7890",
"1234: 789012345\n"
"1234: 7890",
},
//
// w_tag_col
//
{
"w_tag_col",
"1234:",
false,
10,
"1 3 5",
"1234: 1 3 5",
},
{
"w_tag_col",
"1234:",
false,
10,
"1 3 5 7 9",
"1234: 1 3 5\n"
" 7 9",
},
{
"w_tag_col",
"1234:",
true,
10,
"1 3 5 7 9",
"1234: 1 3 5\n"
"1234: 7 9",
},
//
// paragraphs
//
{
"paragraphs",
"",
false,
0,
"1 3 5\n\n",
"1 3 5"
},
{
"paragraphs",
"",
false,
0,
"1 3 5\n2 4 6",
"1 3 5\n\n2 4 6"
},
{
"paragraphs",
"",
false,
0,
"1234 6789 123456\n2 4 6",
"1234 6789\n123456\n\n2 4 6"
},
{
"paragraphs",
"12: ",
false,
0,
"56789 123456\n2 4 6",
"12: 56789\n 123456\n\n 2 4 6"
},
{
"paragraphs",
"12: ",
true,
0,
"56789 123456\n2 4 6",
"12: 56789\n12: 123456\n12: \n12: 2 4 6"
},
{
"paragraphs",
"12:",
false,
4,
"56789 123456\n2 4 6",
"12: 56789\n 123456\n\n 2 4 6"
},
{
"paragraphs",
"12:",
true,
4,
"56789 123456\n2 4 6",
"12: 56789\n12: 123456\n12:\n12: 2 4 6"
},
//
// end
//
{
NULL,
NULL,
false,
0,
NULL,
NULL,
},
};
static
void
run_tests(const char *tc)
{
struct test *t;
std::cout << "Running tests for " << tc << "\n";
atf::env::set("COLUMNS", "15");
for (t = &tests[0]; t->tc != NULL; t++) {
if (std::strcmp(t->tc, tc) == 0) {
std::cout << "\n";
std::cout << "Testing with tag '" << t->tag << "', '"
<< (t->repeat ? "repeat" : "no repeat") << "', col "
<< t->col << "\n";
std::cout << "Input: >>>" << t->fmt << "<<<\n";
std::cout << "Expected output: >>>" << t->result << "<<<\n";
std::string result = atf::ui::format_text_with_tag(t->fmt, t->tag,
t->repeat, t->col);
std::cout << "Output : >>>" << result << "<<<\n";
ATF_REQUIRE_EQ(t->result, result);
}
}
}
ATF_TEST_CASE(wo_tag);
ATF_TEST_CASE_HEAD(wo_tag)
{
set_md_var("descr", "Checks formatting without tags");
}
ATF_TEST_CASE_BODY(wo_tag)
{
run_tests("wo_tag");
}
ATF_TEST_CASE(wo_tag_col);
ATF_TEST_CASE_HEAD(wo_tag_col)
{
set_md_var("descr", "Checks formatting without tags and with a non-zero "
"starting column");
}
ATF_TEST_CASE_BODY(wo_tag_col)
{
run_tests("wo_tag_col");
}
ATF_TEST_CASE(w_tag_no_repeat);
ATF_TEST_CASE_HEAD(w_tag_no_repeat)
{
set_md_var("descr", "Checks formatting with a tag");
}
ATF_TEST_CASE_BODY(w_tag_no_repeat)
{
run_tests("w_tag_no_repeat");
}
ATF_TEST_CASE(w_tag_repeat);
ATF_TEST_CASE_HEAD(w_tag_repeat)
{
set_md_var("descr", "Checks formatting with a tag and repeating it on "
"each line");
}
ATF_TEST_CASE_BODY(w_tag_repeat)
{
run_tests("w_tag_repeat");
}
ATF_TEST_CASE(w_tag_col);
ATF_TEST_CASE_HEAD(w_tag_col)
{
set_md_var("descr", "Checks formatting with a tag and starting at a "
"column greater than its length");
}
ATF_TEST_CASE_BODY(w_tag_col)
{
run_tests("w_tag_col");
}
ATF_TEST_CASE(paragraphs);
ATF_TEST_CASE_HEAD(paragraphs)
{
set_md_var("descr", "Checks formatting a string that contains multiple "
"paragraphs");
}
ATF_TEST_CASE_BODY(paragraphs)
{
run_tests("paragraphs");
}
// ------------------------------------------------------------------------
// Main.
// ------------------------------------------------------------------------
ATF_INIT_TEST_CASES(tcs)
{
// Add the test cases for the free functions.
ATF_ADD_TEST_CASE(tcs, wo_tag);
ATF_ADD_TEST_CASE(tcs, wo_tag_col);
ATF_ADD_TEST_CASE(tcs, w_tag_no_repeat);
ATF_ADD_TEST_CASE(tcs, w_tag_repeat);
ATF_ADD_TEST_CASE(tcs, w_tag_col);
ATF_ADD_TEST_CASE(tcs, paragraphs);
}

View File

@ -0,0 +1,41 @@
// Copyright 2014 Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of Google Inc. nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#if defined(HAVE_CONFIG_H)
#include "bconfig.h"
#endif
#include <cstdlib>
#include <iostream>
int
main(void)
{
std::cout << PACKAGE_VERSION << "\n";
return EXIT_SUCCESS;
}

View File

@ -763,11 +763,30 @@ BUILD_TC(use, "macros_hpp_test.cpp",
"do not cause syntax errors when used",
"Build of macros_hpp_test.cpp failed; some macros in "
"atf-c++/macros.hpp are broken");
BUILD_TC_FAIL(detect_unused_tests, "unused_test.cpp",
"Tests that defining an unused test case raises a warning (and thus "
"an error)",
"Build of unused_test.cpp passed; unused test cases are not properly "
"detected");
ATF_TEST_CASE(detect_unused_tests);
ATF_TEST_CASE_HEAD(detect_unused_tests)
{
set_md_var("descr",
"Tests that defining an unused test case raises a warning (and "
"thus an error)");
}
ATF_TEST_CASE_BODY(detect_unused_tests)
{
const char* validate_compiler =
"class test_class { public: int dummy; };\n"
"#define define_unused static test_class unused\n"
"define_unused;\n";
atf::utils::create_file("compiler_test.cpp", validate_compiler);
if (build_check_cxx_o("compiler_test.cpp"))
expect_fail("Compiler does not raise a warning on an unused "
"static global variable declared by a macro");
if (build_check_cxx_o_srcdir(*this, "unused_test.cpp"))
ATF_FAIL("Build of unused_test.cpp passed; unused test cases are "
"not properly detected");
}
// ------------------------------------------------------------------------
// Main.

View File

@ -1,56 +0,0 @@
//
// Automated Testing Framework (atf)
//
// Copyright (c) 2007 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#if !defined(_ATF_CXX_NONCOPYABLE_HPP_)
#define _ATF_CXX_NONCOPYABLE_HPP_
namespace atf {
// ------------------------------------------------------------------------
// The "noncopyable" class.
// ------------------------------------------------------------------------
class noncopyable {
// The class cannot be empty; otherwise we get ABI-stability warnings
// during the build, which will break it due to strict checking.
int m_noncopyable_dummy;
noncopyable(const noncopyable& nc);
noncopyable& operator=(const noncopyable& nc);
protected:
// Explicitly needed to provide some non-private functions. Otherwise
// we also get some warnings during the build.
noncopyable(void) {}
~noncopyable(void) {}
};
} // namespace atf
#endif // !defined(_ATF_CXX_NONCOPYABLE_HPP_)

View File

@ -43,10 +43,8 @@ require_pc()
check_version()
{
atf_check -s eq:0 -o save:stdout -e empty -x \
"atf-version | head -n 1 | cut -d ' ' -f 4"
ver1=$(cat stdout)
echo "Version reported by atf-version: ${ver1}"
ver1=$($(atf_get_srcdir)/detail/version_helper)
echo "Version reported by builtin PACKAGE_VERSION: ${ver1}"
atf_check -s eq:0 -o save:stdout -e empty pkg-config --modversion "${1}"
ver2=$(cat stdout)
@ -59,7 +57,7 @@ atf_test_case version
version_head()
{
atf_set "descr" "Checks that the version in atf-c++ is correct"
atf_set "require.progs" "atf-version pkg-config"
atf_set "require.progs" "pkg-config"
}
version_body()
{

View File

@ -55,7 +55,6 @@ extern "C" {
#include "atf-c/utils.h"
}
#include "noncopyable.hpp"
#include "tests.hpp"
#include "detail/application.hpp"
@ -63,7 +62,6 @@ extern "C" {
#include "detail/env.hpp"
#include "detail/exceptions.hpp"
#include "detail/fs.hpp"
#include "detail/parser.hpp"
#include "detail/sanity.hpp"
#include "detail/text.hpp"
@ -79,12 +77,7 @@ detail::atf_tp_writer::atf_tp_writer(std::ostream& os) :
m_os(os),
m_is_first(true)
{
atf::parser::headers_map hm;
atf::parser::attrs_map ct_attrs;
ct_attrs["version"] = "1";
hm["Content-Type"] = atf::parser::header_entry("Content-Type",
"application/X-atf-tp", ct_attrs);
atf::parser::write_headers(hm, m_os);
m_os << "Content-Type: application/X-atf-tp; version=\"1\"\n\n";
}
void
@ -129,7 +122,13 @@ detail::match(const std::string& regexp, const std::string& str)
static std::map< atf_tc_t*, impl::tc* > wraps;
static std::map< const atf_tc_t*, const impl::tc* > cwraps;
struct impl::tc_impl : atf::noncopyable {
struct impl::tc_impl {
private:
// Non-copyable.
tc_impl(const tc_impl&);
tc_impl& operator=(const tc_impl&);
public:
std::string m_ident;
atf_tc_t m_tc;
bool m_has_cleanup;
@ -435,7 +434,7 @@ const char* tp::m_description =
"This is an independent atf test program.";
tp::tp(void (*add_tcs)(tc_vector&)) :
app(m_description, "atf-test-program(1)", "atf(7)", false),
app(m_description, "atf-test-program(1)"),
m_lflag(false),
m_resfile("/dev/stdout"),
m_srcdir("."),

View File

@ -38,8 +38,6 @@ extern "C" {
#include <atf-c/defs.h>
}
#include <atf-c++/noncopyable.hpp>
namespace atf {
namespace tests {
@ -74,7 +72,11 @@ typedef std::map< std::string, std::string > vars_map;
struct tc_impl;
class tc : noncopyable {
class tc {
// Non-copyable.
tc(const tc&);
tc& operator=(const tc&);
std::auto_ptr< tc_impl > pimpl;
protected:

View File

@ -40,8 +40,8 @@ extern "C" {
#include "macros.hpp"
#include "detail/parser.hpp"
#include "detail/test_helpers.hpp"
#include "detail/text.hpp"
// ------------------------------------------------------------------------
// Tests for the "atf_tp_writer" class.

View File

@ -45,18 +45,14 @@ static struct var {
const char *value;
bool can_be_empty;
} vars[] = {
{ "atf_arch", ATF_ARCH, NULL, false, },
{ "atf_build_cc", ATF_BUILD_CC, NULL, false, },
{ "atf_build_cflags", ATF_BUILD_CFLAGS, NULL, true, },
{ "atf_build_cpp", ATF_BUILD_CPP, NULL, false, },
{ "atf_build_cppflags", ATF_BUILD_CPPFLAGS, NULL, true, },
{ "atf_build_cxx", ATF_BUILD_CXX, NULL, false, },
{ "atf_build_cxxflags", ATF_BUILD_CXXFLAGS, NULL, true, },
{ "atf_confdir", ATF_CONFDIR, NULL, false, },
{ "atf_includedir", ATF_INCLUDEDIR, NULL, false, },
{ "atf_libdir", ATF_LIBDIR, NULL, false, },
{ "atf_libexecdir", ATF_LIBEXECDIR, NULL, false, },
{ "atf_machine", ATF_MACHINE, NULL, false, },
{ "atf_pkgdatadir", ATF_PKGDATADIR, NULL, false, },
{ "atf_shell", ATF_SHELL, NULL, false, },
{ "atf_workdir", ATF_WORKDIR, NULL, false, },

View File

@ -44,18 +44,14 @@ static struct varnames {
const char *uc;
bool can_be_empty;
} all_vars[] = {
{ "atf_arch", "ATF_ARCH", false },
{ "atf_build_cc", "ATF_BUILD_CC", false },
{ "atf_build_cflags", "ATF_BUILD_CFLAGS", true },
{ "atf_build_cpp", "ATF_BUILD_CPP", false },
{ "atf_build_cppflags", "ATF_BUILD_CPPFLAGS", true },
{ "atf_build_cxx", "ATF_BUILD_CXX", false },
{ "atf_build_cxxflags", "ATF_BUILD_CXXFLAGS", true },
{ "atf_confdir", "ATF_CONFDIR", false },
{ "atf_includedir", "ATF_INCLUDEDIR", false },
{ "atf_libdir", "ATF_LIBDIR", false },
{ "atf_libexecdir", "ATF_LIBEXECDIR", false },
{ "atf_machine", "ATF_MACHINE", false },
{ "atf_pkgdatadir", "ATF_PKGDATADIR", false },
{ "atf_shell", "ATF_SHELL", false },
{ "atf_workdir", "ATF_WORKDIR", false },

View File

@ -43,10 +43,8 @@
#include "process.h"
#include "test_helpers.h"
static
void
build_check_c_o_aux(const char *path, const char *failmsg,
const bool expect_pass)
bool
build_check_c_o(const char *path)
{
bool success;
atf_dynstr_t iflag;
@ -63,20 +61,19 @@ build_check_c_o_aux(const char *path, const char *failmsg,
atf_dynstr_fini(&iflag);
if ((expect_pass && !success) || (!expect_pass && success))
atf_tc_fail("%s", failmsg);
return success;
}
void
build_check_c_o(const atf_tc_t *tc, const char *sfile, const char *failmsg,
const bool expect_pass)
bool
build_check_c_o_srcdir(const atf_tc_t *tc, const char *sfile)
{
atf_fs_path_t path;
RE(atf_fs_path_init_fmt(&path, "%s/%s",
atf_tc_get_config_var(tc, "srcdir"), sfile));
build_check_c_o_aux(atf_fs_path_cstring(&path), failmsg, expect_pass);
const bool result = build_check_c_o(atf_fs_path_cstring(&path));
atf_fs_path_fini(&path);
return result;
}
void
@ -93,7 +90,8 @@ header_check(const char *hdrname)
snprintf(failmsg, sizeof(failmsg),
"Header check failed; %s is not self-contained", hdrname);
build_check_c_o_aux("test.c", failmsg, true);
if (!build_check_c_o("test.c"))
atf_tc_fail("%s", failmsg);
}
void

View File

@ -63,21 +63,12 @@ struct atf_fs_path;
} \
ATF_TC_BODY(name, tc) \
{ \
build_check_c_o(tc, sfile, failmsg, true); \
if (!build_check_c_o_srcdir(tc, sfile)) \
atf_tc_fail("%s", failmsg); \
}
#define BUILD_TC_FAIL(name, sfile, descr, failmsg) \
ATF_TC(name); \
ATF_TC_HEAD(name, tc) \
{ \
atf_tc_set_md_var(tc, "descr", descr); \
} \
ATF_TC_BODY(name, tc) \
{ \
build_check_c_o(tc, sfile, failmsg, false); \
}
void build_check_c_o(const atf_tc_t *, const char *, const char *, const bool);
bool build_check_c_o(const char *);
bool build_check_c_o_srcdir(const atf_tc_t *, const char *);
void header_check(const char *);
void get_process_helpers_path(const atf_tc_t *, const bool,
struct atf_fs_path *);

View File

@ -0,0 +1,43 @@
/*
* Copyright 2014 Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Google Inc. nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#if defined(HAVE_CONFIG_H)
#include "bconfig.h"
#endif
#include <stdio.h>
#include <stdlib.h>
int
main(void)
{
printf("%s\n", PACKAGE_VERSION);
return EXIT_SUCCESS;
}

View File

@ -843,11 +843,30 @@ BUILD_TC(use, "macros_h_test.c",
"do not cause syntax errors when used",
"Build of macros_h_test.c failed; some macros in atf-c/macros.h "
"are broken");
BUILD_TC_FAIL(detect_unused_tests, "unused_test.c",
"Tests that defining an unused test case raises a warning (and thus "
"an error)",
"Build of unused_test.c passed; unused test cases are not properly "
"detected");
ATF_TC(detect_unused_tests);
ATF_TC_HEAD(detect_unused_tests, tc)
{
atf_tc_set_md_var(tc, "descr",
"Tests that defining an unused test case raises a "
"warning (and thus an error)");
}
ATF_TC_BODY(detect_unused_tests, tc)
{
const char* validate_compiler =
"struct test_struct { int dummy; };\n"
"#define define_unused static struct test_struct unused\n"
"define_unused;\n";
atf_utils_create_file("compiler_test.c", "%s", validate_compiler);
if (build_check_c_o("compiler_test.c"))
atf_tc_expect_fail("Compiler does not raise a warning on an unused "
"static global variable declared by a macro");
if (build_check_c_o_srcdir(tc, "unused_test.c"))
atf_tc_fail("Build of unused_test.c passed; unused test cases are "
"not properly detected");
}
/* ---------------------------------------------------------------------
* Main.

View File

@ -43,10 +43,8 @@ require_pc()
check_version()
{
atf_check -s eq:0 -o save:stdout -e empty -x \
"atf-version | head -n 1 | cut -d ' ' -f 4"
ver1=$(cat stdout)
echo "Version reported by atf-version: ${ver1}"
ver1=$($(atf_get_srcdir)/detail/version_helper)
echo "Version reported by builtin PACKAGE_VERSION: ${ver1}"
atf_check -s eq:0 -o save:stdout -e empty pkg-config --modversion "${1}"
ver2=$(cat stdout)
@ -59,7 +57,7 @@ atf_test_case version
version_head()
{
atf_set "descr" "Checks that the version in atf-c is correct"
atf_set "require.progs" "atf-version pkg-config"
atf_set "require.progs" "pkg-config"
}
version_body()
{

View File

@ -724,7 +724,7 @@ const char* atf_check::m_description =
"atf-check executes given command and analyzes its results.";
atf_check::atf_check(void) :
app(m_description, "atf-check(1)", "atf(7)"),
app(m_description, "atf-check(1)"),
m_xflag(false)
{
}

View File

@ -122,7 +122,7 @@ const char* atf_sh::m_description =
"system sh(1) with the atf-sh library.";
atf_sh::atf_sh(void) :
app(m_description, "atf-sh(1)", "atf(7)")
app(m_description, "atf-sh(1)")
{
}

View File

@ -54,7 +54,7 @@ atf_test_case expout_mismatch
expout_mismatch_head()
{
atf_set "descr" "Verifies that atf_check prints a diff of the" \
"stdout and the expected stdout of the two do not" \
"stdout and the expected stdout if the two do not" \
"match"
}
expout_mismatch_body()
@ -79,7 +79,7 @@ atf_test_case experr_mismatch
experr_mismatch_head()
{
atf_set "descr" "Verifies that atf_check prints a diff of the" \
"stderr and the expected stderr of the two do not" \
"stderr and the expected stderr if the two do not" \
"match"
}
experr_mismatch_body()

View File

@ -38,7 +38,7 @@ no_args_body()
{
cat >experr <<EOF
atf-sh: ERROR: No test program provided
atf-sh: Type \`atf-sh -h' for more details.
atf-sh: See atf-sh(1) for usage details.
EOF
atf_check -s eq:1 -o ignore -e file:experr atf-sh
}

View File

@ -28,18 +28,9 @@
/* Define to 1 if you have the `putenv' function. */
#define HAVE_PUTENV 1
/* Define to 1 if putenv is in std */
/* #undef HAVE_PUTENV_IN_STD */
/* Define to 1 if you have the `setenv' function. */
#define HAVE_SETENV 1
/* Define to 1 if setenv is in std */
/* #undef HAVE_SETENV_IN_STD */
/* Define to 1 if snprintf is in std */
/* #undef HAVE_SNPRINTF_IN_STD */
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
@ -61,21 +52,12 @@
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* Define to 1 if you have the `unmount' function. */
#define HAVE_UNMOUNT 1
/* Define to 1 if you have the `unsetenv' function. */
#define HAVE_UNSETENV 1
/* Define to 1 if unsetenv is in std */
/* #undef HAVE_UNSETENV_IN_STD */
/* Define to 1 if vsnprintf is in std */
/* #undef HAVE_VSNPRINTF_IN_STD */
/* Define to the last valid signal number */
#define LAST_SIGNO 128
/* Define to the sub-directory in which libtool stores uninstalled libraries.
*/
#define LT_OBJDIR ".libs/"
@ -93,19 +75,19 @@
#define PACKAGE_NAME "Automated Testing Framework"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "Automated Testing Framework 0.18"
#define PACKAGE_STRING "Automated Testing Framework 0.20"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "atf"
/* Define to the home page for this package. */
#define PACKAGE_URL "http://code.google.com/p/kyua/wiki/ATF"
#define PACKAGE_URL "https://github.com/jmmv/atf/"
/* Define to the version of this package. */
#define PACKAGE_VERSION "0.18"
#define PACKAGE_VERSION "0.20"
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* Version number of package */
#define VERSION "0.18"
#define VERSION "0.20"

View File

@ -123,8 +123,9 @@ The usefulness of the
.Sq expected_*
results comes when writing test cases that verify known failures caused,
in general, due to programming errors (aka bugs).
Whenever the faulty condition that the expectation is trying to convery is
fixed, then the test case will be reported as
Whenever the faulty condition that the
.Sq expected_*
result is trying to cover is fixed, then the test case will be reported as
.Sq failed
and the developer will have to adjust it to match its new condition.
.Pp

View File

@ -28,7 +28,7 @@
.include <bsd.init.mk>
LIB= atf-c++
SHLIB_MAJOR= 1
SHLIB_MAJOR= 2
# libatf-c++ depends on the C version of the ATF library to build.
DPADD= ${LIBATFC}
@ -53,20 +53,16 @@ SRCS= application.cpp \
config.cpp \
env.cpp \
exceptions.cpp \
expand.cpp \
fs.cpp \
parser.cpp \
process.cpp \
tests.cpp \
text.cpp \
ui.cpp \
utils.cpp
INCS= build.hpp \
check.hpp \
config.hpp \
macros.hpp \
noncopyable.hpp \
tests.hpp \
utils.hpp
INCSDIR= ${INCLUDEDIR}/atf-c++

View File

@ -12,15 +12,21 @@ CFLAGS+= -I${ATF}
.for _T in application_test \
env_test \
exceptions_test \
expand_test \
fs_test \
parser_test \
process_test \
sanity_test \
text_test \
ui_test
text_test
ATF_TESTS_CXX+= ${_T}
SRCS.${_T}= ${_T}.cpp test_helpers.cpp
.endfor
.for p in version_helper
PROGS_CXX+= ${p}
SRCS.${p}= ${p}.cpp
MAN.${p}= # defined
BINDIR.${p}= ${TESTSDIR}
.endfor
version_helper.o: atf-version
.include "../../../common.mk"
.include <atf.test.mk>

View File

@ -22,9 +22,13 @@ ATF_TESTS_C+= ${_T}
SRCS.${_T}= ${_T}.c test_helpers.c
.endfor
PROGS+= process_helpers
SRCS.process_helpers= process_helpers.c
MAN.process_helpers= # defined
BINDIR.process_helpers= ${TESTSDIR}
.for p in process_helpers version_helper
PROGS+= ${p}
SRCS.${p}= ${p}.c
MAN.${p}= # defined
BINDIR.${p}= ${TESTSDIR}
.endfor
version_helper.o: atf-version
.include "../../../common.mk"
.include <atf.test.mk>

View File

@ -4100,9 +4100,13 @@ OLD_FILES+=usr/share/man/man8/telnetd.8.gz
.endif
.if ${MK_TESTS} == yes
OLD_LIBS+=usr/lib/libatf-c++.so.1
OLD_FILES+=usr/tests/lib/atf/libatf-c/test_helpers_test
OLD_FILES+=usr/tests/lib/atf/test-programs/fork_test
OLD_FILES+=usr/tests/lib/atf/libatf-c++/application_test
OLD_FILES+=usr/tests/lib/atf/libatf-c++/detail/expand_test
OLD_FILES+=usr/tests/lib/atf/libatf-c++/detail/parser_test
OLD_FILES+=usr/tests/lib/atf/libatf-c++/detail/ui_test
OLD_FILES+=usr/tests/lib/atf/libatf-c++/env_test
OLD_FILES+=usr/tests/lib/atf/libatf-c++/exceptions_test
OLD_FILES+=usr/tests/lib/atf/libatf-c++/expand_test