//
// Automated Testing Framework (atf)
//
// Copyright (c) 2008 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
//
// 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 <limits.h>
#include <signal.h>
#include <unistd.h>
}
#include <cerrno>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <ios>
#include <iostream>
#include <iterator>
#include <list>
#include <memory>
#include <utility>
#include "atf-c++/check.hpp"
#include "atf-c++/config.hpp"
#include "atf-c++/detail/application.hpp"
#include "atf-c++/detail/auto_array.hpp"
#include "atf-c++/detail/exceptions.hpp"
#include "atf-c++/detail/process.hpp"
#include "atf-c++/detail/sanity.hpp"
// ------------------------------------------------------------------------
// Auxiliary functions.
// ------------------------------------------------------------------------
namespace {
enum status_check_t {
};
struct status_check {
bool negated;
int value;
const int p_value) :
{
}
};
enum output_check_t {
};
struct output_check {
bool negated;
{
}
};
int m_fd;
public:
m_fd(-1)
{
if (m_fd == -1)
errno);
}
~temp_file(void)
{
close();
try {
} catch (const atf::system_error&) {
// Ignore deletion errors.
}
}
get_path(void) const
{
return *m_path;
}
void
{
}
void
close(void)
{
if (m_fd != -1) {
flush();
m_fd = -1;
}
}
};
} // anonymous namespace
static int
{
try {
return value;
} catch (const std::runtime_error&) {
"must be an integer in range 0-255");
}
}
static struct name_number {
const char *name;
int signo;
} signal_names_to_numbers[] = {
{ "hup", SIGHUP },
{ "int", SIGINT },
{ "quit", SIGQUIT },
{ "trap", SIGTRAP },
{ "abrt", SIGABRT },
{ "kill", SIGKILL },
{ "segv", SIGSEGV },
{ "pipe", SIGPIPE },
{ "alrm", SIGALRM },
{ "term", SIGTERM },
{ "usr1", SIGUSR1 },
{ "usr2", SIGUSR2 },
};
static int
{
else
iter++;
}
return signo;
}
static int
{
try {
} catch (std::runtime_error) {
"in -s option");
}
}
return signo;
}
static status_check
{
int value;
if (action == "eq") {
// Deprecated; use exit instead. TODO: Remove after 0.10.
if (negated)
negated = false;
} else if (action == "exit") {
else
} else if (action == "ignore") {
if (negated)
} else if (action == "ne") {
// Deprecated; use not-exit instead. TODO: Remove after 0.10.
if (negated)
negated = true;
} else if (action == "signal") {
else
} else
}
static
{
if (action == "empty")
else if (action == "file")
else if (action == "ignore") {
if (negated)
} else if (action == "inline")
else if (action == "match")
else if (action == "save") {
if (negated)
} else
}
static
{
cmdline += ' ';
arg++;
}
return cmdline;
}
static
{
}
static
{
}
static
void
{
if (!stream)
}
static
bool
{
if (!stream)
bool found = false;
found = true;
}
return found;
}
static
bool
{
return (f.get_size() == 0);
}
static bool
{
bool equal = false;
if (!f1)
if (!f2)
for (;;) {
equal = true;
break;
}
break;
}
}
return equal;
}
static
void
{
if (!s.exited())
if (s.exitstatus() != 1)
}
static
{
size_t i;
i = 0;
while (i < s.length()) {
char c = s[i++];
if (c == '\\') {
switch (s[i++]) {
case 'a': c = '\a'; break;
case 'b': c = '\b'; break;
case 'c': break;
case 'e': c = 033; break;
case 'f': c = '\f'; break;
case 'n': c = '\n'; break;
case 'r': c = '\r'; break;
case 't': c = '\t'; break;
case 'v': c = '\v'; break;
case '\\': break;
case '0':
{
c = 0;
c = (c << 3) + (s[i++] - '0');
break;
}
default:
--i;
break;
}
}
}
return res;
}
static
bool
{
bool result;
<< status << ", expected: "
result = false;
<< "anything else\n";
result = false;
} else
result = true;
result = true;
} else {
result = false;
}
result = true;
result = false;
<< "anything else\n";
result = false;
} else
result = true;
result = true;
} else {
result = false;
}
} else {
result = false;
}
if (result == false) {
}
return result;
}
static
bool
{
bool ok = false;
}
return ok;
}
static
bool
{
bool result;
result = false;
result = false;
} else
result = true;
"output\n";
result = false;
result = false;
} else
result = true;
result = true;
/ "inline.XXXXXX";
"value\n";
result = false;
result = false;
} else
result = true;
<< "\n";
result = false;
<< "\n";
result = false;
} else
result = true;
result = true;
} else {
result = false;
}
return result;
}
static
bool
{
bool ok = true;
}
return ok;
}
// ------------------------------------------------------------------------
// The "atf_check" application.
// ------------------------------------------------------------------------
namespace {
bool m_xflag;
static const char* m_description;
options_set specific_options(void) const;
void process_option(int, const char*);
public:
atf_check(void);
int main(void);
};
} // anonymous namespace
"atf-check executes given command and analyzes its results.";
m_xflag(false)
{
}
bool
const
{
if (stdxxx == "stdout") {
return ::run_output_checks(m_stdout_checks,
} else if (stdxxx == "stderr") {
return ::run_output_checks(m_stderr_checks,
} else {
return false;
}
}
const
{
return "<command>";
}
const
{
"must be one of: ignore exit:<num> signal:<name|num>"));
"one of: empty ignore file:<path> inline:<val> match:regexp "
"save:<path>"));
"one of: empty ignore file:<path> inline:<val> match:regexp "
"save:<path>"));
return opts;
}
void
{
switch (ch) {
case 's':
break;
case 'o':
break;
case 'e':
break;
case 'x':
m_xflag = true;
break;
default:
}
}
int
{
if (m_argc < 1)
if (m_status_checks.empty())
// TODO: Remove this restriction.
}
if (m_stdout_checks.empty())
if (m_stderr_checks.empty())
if ((run_status_checks(m_status_checks, *r) == false) ||
(run_output_checks(*r, "stderr") == false) ||
(run_output_checks(*r, "stdout") == false))
else
return status;
}
int
{
}