Remove ATF 0.5 from dist/atf and all of the reachover Makefiles used to

build it.  0.6 is going to be imported in external/bsd/atf, with all the
necessary Makefiles in that same hierarchy.
This commit is contained in:
jmmv 2009-01-19 07:08:14 +00:00
parent 2e51a772b3
commit 0cdcf7cea6
476 changed files with 13 additions and 106490 deletions

21
dist/atf/AUTHORS vendored
View File

@ -1,21 +0,0 @@
Automated Testing Framework (atf)
The NetBSD Foundation, Inc.
---------------------------------------------------------------------------
Authors
=======
* Julio M. Merino Vidal <jmmv@NetBSD.org>
Main developer. He started the work on this project when he took part
in the Google Summer of Code 2007 program as a student.
* Martin Husemann <martin@NetBSD.org>
Mentored this project during its development as part of the Google
Summer of Code 2007 program.
---------------------------------------------------------------------------
End of document

67
dist/atf/COPYING vendored
View File

@ -1,67 +0,0 @@
Automated Testing Framework (atf)
The NetBSD Foundation, Inc.
---------------------------------------------------------------------------
License
=======
Copyright (c) 2007, 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
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.
Relicensed code
===============
The following code snippets have been taken from other projects.
Even though they were not originally licensed under the terms above,
the original authors have agreed to relicense their work so that
this project can be distributed under a single license. This section
is put here just to clarify this fact.
* configure.ac, Makefile.am: The original versions were derived from
the ones in the XML Catalog Manager project, version 2.2.
Author: Julio M. Merino Vidal <jmmv@users.sourceforge.net>
* atf/ui.cpp: The format_paragraph and format_text functions were
derived form the ones in the Monotone project,
revision 3a0982da308228d796df35f98d787c5cff2bb5b6.
Author: Julio M. Merino Vidal <jmmv@NetBSD.org>
* atf/io.hpp, atf/io.cpp, tests/units/t_io.cpp: These files were derived
from the file_handle, systembuf, pipe, pistream and postream classes
and tests found in the Boost.Process library.
Author: Julio M. Merino Vidal <jmmv84@gmail.com>
* admin/check-style.sh, admin/check-style-common.awk,
admin/check-style-cpp.awk, admin/check-style-shell.awk: These files,
except the first one, were first implemented in the Buildtool project.
They were later adapted to be part of Boost.Process and, during that
process, the shell script was created.
Author: Julio M. Merino Vidal <jmmv84@gmail.com>
---------------------------------------------------------------------------
End of document

31
dist/atf/ChangeLog vendored
View File

@ -1,31 +0,0 @@
Automated Testing Framework (atf)
The NetBSD Foundation, Inc.
---------------------------------------------------------------------------
Detailed list of changes
========================
ATF does not use this file because the detailed list of changes is
available where it was meant to be: in the source code repository.
The repository's history contains a much more detailed list of changes
than what could be represented here, including ancestry graphs, patches
between revisions and digital signatures of every change.
In order to access the repository, please visit ATF's web site for more
instructions. At the time of this writing, the site was located at:
http://www.NetBSD.org/~jmmv/atf/
Also, at the time of this writing, the version control system used to
manage the ATF source code tree was Monotone, whose last known address
was:
http://www.monotone.ca/
Additionally you can find the list of the most important changes between
formal releases in the NEWS file.
---------------------------------------------------------------------------
End of document

175
dist/atf/INSTALL vendored
View File

@ -1,175 +0,0 @@
Automated Testing Framework (atf)
The NetBSD Foundation, Inc.
---------------------------------------------------------------------------
Introduction
============
ATF uses the GNU Automake, GNU Autoconf and GNU Libtool utilities as its
build system. These are used only when compiling the application from the
source code package. If you want to install ATF from a binary package, you
do not need to read this document.
For the impatient:
$ ./configure
$ make
$ make check
Gain root privileges
# make install
Drop root privileges
$ make installcheck
Or alternatively, install as a regular user into your home directory:
$ ./configure --prefix ~/local
$ make
$ make check
$ make install
$ make installcheck
Dependencies
============
To build and use ATF successfully you need:
* A standards-compliant C/C++ complier. For example, GNU GCC 2.95 will not
work.
* A POSIX shell interpreter.
* A make(1) utility.
If you are building ATF from the code on the repository, you will also need
the following tools. The versions listed here are the ones used to build
the files bundled in the last formal release, but these are not strictly
required. Newer ones will most likely work and, maybe, some slightly older
ones:
* GNU autoconf 2.61
* GNU automake 1.10.1
* GNU libtool 1.5.24 (1.1220.2.455 2007/06/24 02:13:29)
Regenerating the build system
=============================
If you are building ATF from code extracted from the repository, you must
first regenerate the files used by the build system. You will also need to
do this if you modify one of configure.ac or Makefile.am. To do this,
simply run:
$ autoreconf -is
For formal releases, no extra steps are needed.
General build procedure
=======================
To build and install the source package, you must follow these steps:
1. Configure the sources to adapt to your operating system. This is done
using the 'configure' script located on the sources' top directory, and
it is usually invoked without arguments unless you want to change the
installation prefix. More details on this procedure are given on a
later section.
2. Build the sources to generate the binaries and scripts. Simply run
'make' on the sources' top directory after configuring them. No
problems should arise.
3. Check that the programs built in the previous step work before
installing them. Run 'make check' for this. Any serious problems will
pop up here. (Be aware that on, some systems, GNU Libtool will break
these checks. If you get some failures, try reconfiguring the project
providing the '--disable-fast-install' flag to 'configure' and then
rebuild and recheck.
4. Install the program by running 'make install'. You may need to become
root to issue this step.
5. Issue any manual installation steps that may be required. These are
described later in their own section.
6. Check that the installed programs work by running 'make installcheck'.
You do not need to be root to do this, even though some checks will not
be run otherwise.
Configuration flags
===================
The most common, standard flags given to 'configure' are:
* Flag: --prefix=directory
Possible values: Any path
Default: /usr/local
Specifies where the program (binaries and all associated files) will be
installed.
* Flag: --sysconfdir=directory
Possible values: Any path
Default: /usr/local/etc
Specifies where the installed programs will look for configuration files.
'/atf' will be appended to the given path unless ATF_CONFSUBDIR is
redefined as explained later on.
* Flag: --help
Shows information about all available flags and exits immediately,
without running any configuration tasks.
The following flags are specific to ATF's 'configure' script:
* Variable: ATF_CONFSUBDIR
Possible values: empty, a relative path.
Default: atf.
Specifies the subdirectory of the configuration directory (given by the
--sysconfdir argument) under which ATF will search for its configuration
files.
* Variable: ATF_WORKDIR
Possible values: empty, an absolute path.
Default: /tmp or /var/tmp, depending on availability.
Specifies the directory that ATF will use to place its temporary files
and work directories for test cases. This is just a default and can
be overriden at run time.
* Flag: --enable-developer
Possible values: yes, no
Default: Depends on the version number. Stable versions define this
to 'no' while all others have it set to 'yes'.
Enables several features useful for development, such as the inclusion
of debugging symbols in all objects or the enabling of warnings during
compilation.
* Flag: --enable-unstable-shared
Possible values: yes, no
Default: no.
Forces the building of shared libraries in addition to static ones.
The build of shared libraries is currently disabled because their ABIs
and APIs are unstable and subject to change. This flag is provided for
development purposes only and will be removed once the libraries are
stable enough.
Post-installation steps
=======================
After installing ATF, you have to register the DTDs it provides into the
system-wide XML catalog. See the comments at the top of the files in
${datadir}/share/xml/atf to see the correct public identifiers. This
directory will typically be /usr/local/share/xml/atf or /usr/share/xml/atf.
Failure to do so will lead to further errors when processing the XML
files generated by atf-report.
---------------------------------------------------------------------------
End of document

1154
dist/atf/Makefile.am vendored

File diff suppressed because it is too large Load Diff

4097
dist/atf/Makefile.in vendored

File diff suppressed because it is too large Load Diff

155
dist/atf/NEWS vendored
View File

@ -1,155 +0,0 @@
Automated Testing Framework (atf)
The NetBSD Foundation, Inc.
---------------------------------------------------------------------------
Version 0.5
===========
Release date: May 1st, 2008
Status: Experimental
* Clauses 3 and 4 of the BSD license used by the project were dropped.
All the code is now under a 2-clause BSD license compatible with the
GNU General Public License (GPL).
* Added a C-only binding so that binary test programs do not need to be
tied to C++ at all. This binding is now known as the atf-c library.
* Renamed the C++ binding to atf-c++ for consistency with the new atf-c.
* Renamed the POSIX shell binding to atf-sh for consistency with the new
atf-c and atf-c++.
* Added a -w flag to test programs through which it is possible to specify
the work directory to be used. This was possible in prior releases by
defining the workdir configuration variable (-v workdir=...), but was a
conceptually incorrect mechanism.
* Test programs now preserve the execution order of test cases when they
are given in the command line. Even those mentioned more than once are
executed multiple times to comply with the user's requests.
Version 0.4
===========
Release date: February 4th, 2008
Status: Experimental
Changes:
* Added two new manual pages, atf-c++-api and atf-sh-api, describing the
C++ and POSIX shell interfaces used to write test programs.
* Added a pkg-config file, useful to get the flags to build against the
C++ library or to easily detect the presence of ATF.
* Added a way for test cases to require a specific architecture and/or
machine type through the new 'require.arch' and 'require.machine'
meta-data properties, respectively.
* Added the 'timeout' property to test cases, useful to set an upper-bound
limit for the test's run time and thus prevent global test program stalls
due to the test case's misbehavior.
* Added the atf-exec(1) internal utility, used to execute a command after
changing the process group it belongs to.
* Added the atf-killpg(1) internal utility, used to kill process groups.
* Multiple portability fixes. Of special interest, full support for SunOS
(Solaris Express Developer Edition 2007/09) using the Sun Studio 12 C++
compiler.
* Fixed a serious bug that prevented atf-run(1) from working at all under
Fedora 8 x86_64. Due to the nature of the bug, other platforms were
likely affected too.
Version 0.3
===========
Release date: November 11th, 2007
Status: Experimental
Changes:
* Added XML output support to atf-report. This is accompanied by a DTD for
the format's structure and sample XSLT/CSS files to post-process this
output and convert it to a plain HTML report.
* Changed atf-run to add system information to the report it generates.
This is currently used by atf-report's XML output only, and is later
printed in the HTML reports in a nice and useful summary table. The user
and system administrator are allowed to tune this feature by means of
hooks.
* Removed the test cases' 'isolated' property. This was intended to avoid
touching the file system at all when running the related test case, but
this has not been true for a long while: some control files are
unconditionally required for several purposes, and we cannot easily get
rid of them. This way we remove several critical and delicate pieces of
code.
* Improved atf-report's CSV output format to include information about
test programs too.
* Fixed the tests that used atf-compile to not require this tool as a
helper. Avoids systems without build-time utilities to skip many tests
that could otherwise be run. (E.g. NetBSD without the comp.tgz set
installed.)
* Many general cleanups: Fixed many pieces of code marked as ugly and/or
incomplete.
Version 0.2
===========
Release date: September 20th, 2007
Status: Experimental
Changes:
* Test cases now get a known umask on entry.
* atf-run now detects many unexpected failures caused by test programs
and reports them as bogus tests. atf-report is able to handle these
new errors and nicely reports them to the user.
* All the data formats read and written by the tools have been documented
and cleaned up. These include those grammars that define how the
different components communicate with each other as well as the format
of files written by the developers and users: the Atffiles and the
configuration files.
* Added the atf-version tool, a utility that displays information about the
currently installed version of ATF.
* Test cases can now define an optional cleanup routine to undo their
actions regardless of their exit status.
* atf-report now summarizes the list of failed (bogus) test programs when
using the ticker output format.
* Test programs now capture some termination signals and clean up any
temporary files before exiting the program.
* Multiple bug fixes and improvements all around.
Version 0.1
===========
Release date: August 20th, 2007
Status: Experimental
Changes:
* First public version. This was released coinciding with the end of the
Google Summer of Code 2007 program.
---------------------------------------------------------------------------
End of document

46
dist/atf/README vendored
View File

@ -1,46 +0,0 @@
Automated Testing Framework (atf)
The NetBSD Foundation, Inc.
---------------------------------------------------------------------------
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.
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.
Other documents
===============
* AUTHORS: List of authors and contributors for this project.
* COPYING: License information.
* ChangeLog: Pointers to the code repository. No actual history is
provided here.
* INSTALL: Compilation and installation instructions. These is not the
standard document shipped with many packages, so be sure to read it for
things that are specific to ATF's build.
* NEWS: List of major changes between formal, published releases.
* ROADMAP: List of changes planned for future releases.
---------------------------------------------------------------------------
End of document

164
dist/atf/ROADMAP vendored
View File

@ -1,164 +0,0 @@
Automated Testing Framework (atf)
The NetBSD Foundation, Inc.
---------------------------------------------------------------------------
Introduction
============
This document contains a *non-exhaustive* list of things that should be
addressed in ATF before it can be considered stable. Some of the items
are planned for specific future releases, but take this with a big grain
of salt: the focus of a specific release may change completely depending
on how things develop.
Plans for 0.6
=============
* Add a binary atf-check tool that replaces atf-sh's atf_check function.
I suspect this will speed things up considerably, and will also expose
this extremely useful functionality to C/C++ test programs.
* Add support for ATF_REQUIRE, making ATF_CHECK non-fatal. See Boost.Test
for details on this idea. Most useful for unit tests.
* Add a module to atf-c to manage dynamic memory. Should provide a "mem
chunk" object that can only be managed through functions (i.e. not
directly) so that access to buffers can be safely controlled. Dealing
with strdup and similar functions, for example, might be complex.
See these old revisions for a start, but these did not work correctly
because the use of (void **) casts brought aliasing problems:
78eeacf3b9284493e5e96b7866fc1d163a13bc02
8e200683a2b70eadca728c2e0347d4790777b3fc
872393ed0177cbcc30ffacede228eb3986c42ab7
* Optimize timeout handling in atf-sh: there are too many processes
involved to run each test case, and this hurts a lot in OS X, for
example. One possibility is to integrate the timeout handling in
atf-exec and then kill the auxiliary code in atf.footer.subr.
Plans for 0.7
=============
* Add a tool to collect multiple outputs of atf-run (from different
machines) and generate a single (XML-only?) log with everything.
Must allow easy conversion to HTML for online publishing.
* Allow grouping of test programs in tiers in an Atffile. This is to
permit the user specify "dependencies" between test programs: e.g. do
not run a specific test program if its dependencies have failed, because
it will certainly fail also.
* Provide a kernel-level unit testing API (for NetBSD only, at the moment).
This should come in the form of an atf.ko module that provides functions
to define and register test cases, functions for results reporting and
an interface (a trivial file system?) that transports the
application/X-atf-tcs output to user-space, provides information to
user-space about the available test cases (a list) and allows user-space
to launch the execution of test cases.
* Add expected failures and unexpected passes as test case results? The
former are used to indicate known failures at specific points and thus
not raise false positives when working on some unrelated feature. The
latter are used to detect changes that fixed expected failures. See
Monotone's test suite for an example.
Plans for pre-1.0
=================
* Fix all occurrences of XXX, TODO and FIXME.
* Think of a way to properly add tests for (almost?) all error paths.
Most of them are probably broken already.
* Improve error reporting: aside from clarifying error messages, this also
implies adding more error cases to give them more semantic meaning at the
source code level..
* Add an atf_check-like function to the C++ binding to allow easy testing
of executables.
* Make the shell library work with 'set -e'?
* Shell test programs dynamically locate where the shell library is by
calling atf-config (done by atf.init.subr). Contrarywise, binary test
programs are directly linked against the final location of libatf.
It may be nice if the latter loaded the library dynamically based on
what atf-config said, so the user could switch atf installations by
simply changing its PATH (and effectively making atf relocatable on the
file system). Why could this be nice? To painlessly run an older atf
test suite against a more recent version of the code base to ensure
there are no regressions even with older tests. Just a crazy idea, as
maybe what the shell test programs currently do is stupid.
* Allow users to customize the build of atf by defining additional meta-data
for test cases. At the moment this is possible because the meta-data is
not sanity-checked, but I think it should be. Following the previous
item, NetBSD could add a 'netbsd.pr' variable and then use this data when
generating reports to add direct links to the appropriate PRs.
* Make sure that the tests in tests/atf have, at the very least, the same
coverage as the ones in tests/bootstrap.
* Document the code.
* Possibly add a way to automatically gain or drop privileges when
require.user is set.
* Add a way to specify which bug/issue/whatever a given test case is
stress-testing. This information is useful when detecting regressions.
Plans for 1.0-RC1
=================
* Build libatf as a shared library and set -version-info accordingly.
* Set the DTDs' versions to 1.0.
Plans for post-1.0
==================
* Allow the parallel execution of tests. Achieving this with a test
program granularity is easy: only need to change atf-run. Lowering it
to a finer granularity (test cases) is harder and maybe not worth it.
Things that we will not do
==========================
This is a list of things that will *not* be addressed anytime soon in the
project. Of course most of them would be nice to have in the future, but
they will not block releases nor drive development. We can obviously
change our mind in the future and add move some of these to the above list.
* Native Win32 support: we are not talking about building atf with tools
such as Cygwin or MinGW, which should already be possible. Native Win32
support means modifying the code to use Win32 library calls and easily
build out of the box (i.e. the GNU Autotools are not useful in that
case).
* Extreme efficiency: even though we will focus on using the most suitable
data structures in each situation, we will not attempt to get extreme
efficiency by adding hacks that make the code uglier. Testing is a task
that requires a lot of resources on its own, and some tests will be
specially intensive, so there is no point in micro-optimizing atf if the
global gains are negligible.
* Extreme portability: the initial goal of this project was to provide a
testing framework for the NetBSD Operating System. Given that this
system has a very nice build framework, we can be sure that atf will be
built and used with sane tools (basically a decent C++ compiler and a
POSIX-compliant shell interpreter). We will definitely not aim for
portability to broken systems by tweaking our code to not follow the
standards.
---------------------------------------------------------------------------
End of document

7475
dist/atf/aclocal.m4 vendored

File diff suppressed because it is too large Load Diff

View File

@ -1,92 +0,0 @@
#! /bin/sh
#
# Automated Testing Framework (atf)
#
# Copyright (c) 2007, 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
# 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.
#
#
# A utility to ensure that INSTALL lists the correct versions of the
# tools used to generate the distfile.
#
Prog_Name=${0##*/}
#
# err message
#
err() {
echo "${Prog_Name}: ${@}" 1>&2
exit 1
}
#
# warn message
#
warn() {
echo "${Prog_Name}: ${@}" 1>&2
}
#
# check_tool readme_file prog_name verbose_name
#
# Executes 'prog_name' to determine its version and checks if the
# given 'readme_file' contains 'verbose_name <version>' in it.
#
check_tool() {
readme=${1}
prog=${2}
name=${3}
ver=$(${prog} --version | head -n 1 | cut -d ' ' -f 4-)
if grep "^\\* ${name} ${ver}$" ${readme} >/dev/null; then
true
else
warn "Incorrect version of ${name}"
false
fi
}
#
# main readme_file
#
# Entry point.
#
main() {
readme=${1}
ret=0
check_tool ${readme} autoconf "GNU autoconf" || ret=1
check_tool ${readme} automake "GNU automake" || ret=1
check_tool ${readme} libtool "GNU libtool" || ret=1
return ${ret}
}
main "${@}"
# vim: syntax=sh:expandtab:shiftwidth=4:softtabstop=4

View File

@ -1,94 +0,0 @@
#
# Automated Testing Framework (atf)
#
# Copyright (c) 2007, 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
# 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.
#
function warn(msg) {
print FILENAME "[" FNR "]: " msg > "/dev/stderr"
error = 1
}
BEGIN {
skip = 0
error = 0
}
/NO_CHECK_STYLE_BEGIN/ {
skip = 1
next
}
/NO_CHECK_STYLE_END/ {
skip = 0
next
}
/NO_CHECK_STYLE/ {
next
}
{
if (skip)
next
}
/#ifdef/ {
warn("Undesired usage of #ifdef; use #if defined()")
}
/#ifndef/ {
warn("Undesired usage of #ifndef; use #if !defined()")
}
/assert[ \t]*\(/ {
warn("Use the macros in sanity.h instead of assert");
}
/getprogname/ {
warn("getprogname(3) is not portable");
}
/include.*assert.h/ {
warn("Do not include assert.h");
}
/setprogname/ {
warn("setprogname(3) is not portable");
}
/\/\// {
warn("Do not use C99-style comments");
}
END {
if (skip)
warn("Missing NO_CHECK_STYLE_END");
if (error)
exit 1
}
# vim: syntax=awk:expandtab:shiftwidth=4:softtabstop=4

View File

@ -1,82 +0,0 @@
#
# Automated Testing Framework (atf)
#
# Copyright (c) 2007, 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
# 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.
#
function warn(msg) {
print FILENAME "[" FNR "]: " msg > "/dev/stderr"
error = 1
}
BEGIN {
skip = 0
error = 0
}
/NO_CHECK_STYLE_BEGIN/ {
skip = 1
next
}
/NO_CHECK_STYLE_END/ {
skip = 0
next
}
/NO_CHECK_STYLE/ {
next
}
{
if (skip)
next
if (length > 79)
warn("Line too long to fit on screen")
}
/^ *\t+/ {
if (! match(FILENAME, "Makefile"))
warn("Tab character used for indentation");
}
/[ \t]+$/ {
warn("Trailing spaces or tabs");
}
/#![^ ]/ { # NO_CHECK_STYLE
warn("Invalid shellbang: missing space after !");
}
END {
if (skip)
warn("Missing NO_CHECK_STYLE_END");
if (error)
exit 1
}
# vim: syntax=awk:expandtab:shiftwidth=4:softtabstop=4

View File

@ -1,81 +0,0 @@
#
# Automated Testing Framework (atf)
#
# Copyright (c) 2007, 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
# 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.
#
function warn(msg) {
print FILENAME "[" FNR "]: " msg > "/dev/stderr"
error = 1
}
BEGIN {
skip = 0
error = 0
}
/NO_CHECK_STYLE_BEGIN/ {
skip = 1
next
}
/NO_CHECK_STYLE_END/ {
skip = 0
next
}
/NO_CHECK_STYLE/ {
next
}
{
if (skip)
next
}
/#ifdef/ {
warn("Undesired usage of #ifdef; use #if defined()")
}
/#ifndef/ {
warn("Undesired usage of #ifndef; use #if !defined()")
}
/assert[ \t]*\(/ {
warn("Use the macros in sanity.hpp instead of assert");
}
/include.*assert/ {
warn("Do not include assert.h nor cassert");
}
END {
if (skip)
warn("Missing NO_CHECK_STYLE_END");
if (error)
exit 1
}
# vim: syntax=awk:expandtab:shiftwidth=4:softtabstop=4

View File

@ -1,78 +0,0 @@
#
# Automated Testing Framework (atf)
#
# Copyright (c) 2007, 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
# 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.
#
function warn(msg) {
print FILENAME "[" FNR "]: " msg > "/dev/stderr"
error = 1
}
BEGIN {
skip = 0
error = 0
}
/NO_CHECK_STYLE_BEGIN|^\.Bd/ {
skip = 1
next
}
/NO_CHECK_STYLE_END|^\.Ed/ {
skip = 0
next
}
/NO_CHECK_STYLE/ {
next
}
/^\.\\"/ {
next
}
{
if (skip)
next
}
/\.\.|e\.g\.|i\.e\./ {
next
}
/\.[ ]+[a-zA-Z]+/ {
warn("Sentence does not start on new line")
}
END {
if (skip)
warn("Missing NO_CHECK_STYLE_END");
if (error)
exit 1
}
# vim: syntax=awk:expandtab:shiftwidth=4:softtabstop=4

View File

@ -1,110 +0,0 @@
#
# Automated Testing Framework (atf)
#
# Copyright (c) 2007, 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
# 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.
#
function warn(msg) {
print FILENAME "[" FNR "]: " msg > "/dev/stderr"
error = 1
}
BEGIN {
skip = 0
error = 0
emacs_modeline = 0
vim_modeline = 0
}
/NO_CHECK_STYLE_BEGIN/ {
skip = 1
next
}
/NO_CHECK_STYLE_END/ {
skip = 0
next
}
/NO_CHECK_STYLE/ {
next
}
{
if (skip)
next
}
/vim: syntax=sh/ {
vim_modeline = 1
}
/^[ \t]*#/ {
next
}
/[$ \t]+_[a-zA-Z0-9]+=/ {
warn("Variable should not start with an underline")
}
/[^\\]\$[^0-9!'"$?@#*{}(|\/]+/ {
warn("Missing braces around variable name")
}
/=(""|'')/ {
warn("Assignment to the empty string does not need quotes");
}
/basename[ \t]+/ {
warn("Use parameter expansion instead of basename");
}
/dirname[ \t]+/ {
warn("Use parameter expansion instead of dirname");
}
/if[ \t]+(test|![ \t]+test)/ {
warn("Use [ instead of test");
}
/[ \t]+(test|\[).*==/ {
warn("test(1)'s == operator is not portable");
}
/if.*;[ \t]*fi$/ {
warn("Avoid using a single-line if conditional");
}
END {
if (skip)
warn("Missing NO_CHECK_STYLE_END");
if (! vim_modeline)
warn("Missing mode lines");
if (error)
exit 1
}
# vim: syntax=awk:expandtab:shiftwidth=4:softtabstop=4

View File

@ -1,183 +0,0 @@
#! /bin/sh
#
# Automated Testing Framework (atf)
#
# Copyright (c) 2007, 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
# 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.
#
#
# A utility to sanity check the coding style of all source files in the
# project tree.
#
Prog_Name=${0##*/}
#
# err message
#
err() {
echo "${Prog_Name}: ${@}" 1>&2
exit 1
}
#
# warn message
#
warn() {
echo "${Prog_Name}: ${@}" 1>&2
}
#
# guess_topdir
#
# Locates the project's top directory and prints its path. The caller
# must verify if the result is correct or not.
#
guess_topdir() {
olddir=$(pwd)
topdir=$(pwd)
while [ ${topdir} != / ]; do
if [ -f ./atf-c.h ]; then
break
else
cd ..
topdir=$(pwd)
fi
done
cd ${olddir}
echo ${topdir}
}
#
# find_sources
#
# Locates all source files within the project, relative to the current
# directory, and prints their paths.
#
find_sources() {
find . \( -name "AUTHORS" -o \
-name "COPYING" -o \
-name "ChangeLog" -o \
-name "NEWS" -o \
-name "README" -o \
-name "TODO" -o \
-name "*.[0-9]" -o \
-name "*.ac" -o \
-name "*.am" -o \
-name "*.at" -o \
-name "*.awk" -o \
-name "*.c" -o \
-name "*.cpp" -o \
-name "*.h" -o \
-name "*.hpp" -o \
-name "*.m4" -o \
-name "*.sh" \
\) -a \( \
\! -path "*autom4te*" -a \
-type f -a \
\! -name "aclocal.m4" \
\! -name "bconfig.h" \
\! -name "*.so.*" \
\)
}
#
# guess_formats file
#
# Guesses the formats applicable to the given file and prints the resulting
# list.
#
guess_formats() {
case ${1} in
*/ltmain.sh)
;;
*.[0-9])
echo common man
;;
*.c|*.h)
echo common c
;;
*.cpp|*.hpp)
echo common cpp
;;
*.sh)
echo common shell
;;
*)
echo common
;;
esac
}
#
# check_file file
#
# Checks the validity of the given file.
#
check_file() {
err=0
for format in $(guess_formats ${1}); do
awk -f ${topdir}/admin/check-style-${format}.awk ${1} || err=1
done
return ${err}
}
#
# main [file list]
#
# Entry point.
#
main() {
topdir=$(guess_topdir)
if [ ! -f ${topdir}/atf-c.h ]; then
err "Could not locate the project's top directory"
fi
if [ ${#} -gt 0 ]; then
sources=${@}
else
cd ${topdir}
sources=$(find_sources)
fi
ok=0
for file in ${sources}; do
file=$(echo ${file} | sed -e "s,\\./,,")
if [ ! -f ${file} ]; then
err "Could not open ${file}"
else
check_file ${file} || ok=1
fi
done
return ${ok}
}
main "${@}"
# vim: syntax=sh:expandtab:shiftwidth=4:softtabstop=4

142
dist/atf/admin/compile vendored
View File

@ -1,142 +0,0 @@
#! /bin/sh
# Wrapper for compilers which do not understand `-c -o'.
scriptversion=2005-05-14.22
# Copyright (C) 1999, 2000, 2003, 2004, 2005 Free Software Foundation, Inc.
# Written by Tom Tromey <tromey@cygnus.com>.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# This file is maintained in Automake, please report
# bugs to <bug-automake@gnu.org> or send patches to
# <automake-patches@gnu.org>.
case $1 in
'')
echo "$0: No command. Try \`$0 --help' for more information." 1>&2
exit 1;
;;
-h | --h*)
cat <<\EOF
Usage: compile [--help] [--version] PROGRAM [ARGS]
Wrapper for compilers which do not understand `-c -o'.
Remove `-o dest.o' from ARGS, run PROGRAM with the remaining
arguments, and rename the output as expected.
If you are trying to build a whole package this is not the
right script to run: please start by reading the file `INSTALL'.
Report bugs to <bug-automake@gnu.org>.
EOF
exit $?
;;
-v | --v*)
echo "compile $scriptversion"
exit $?
;;
esac
ofile=
cfile=
eat=
for arg
do
if test -n "$eat"; then
eat=
else
case $1 in
-o)
# configure might choose to run compile as `compile cc -o foo foo.c'.
# So we strip `-o arg' only if arg is an object.
eat=1
case $2 in
*.o | *.obj)
ofile=$2
;;
*)
set x "$@" -o "$2"
shift
;;
esac
;;
*.c)
cfile=$1
set x "$@" "$1"
shift
;;
*)
set x "$@" "$1"
shift
;;
esac
fi
shift
done
if test -z "$ofile" || test -z "$cfile"; then
# If no `-o' option was seen then we might have been invoked from a
# pattern rule where we don't need one. That is ok -- this is a
# normal compilation that the losing compiler can handle. If no
# `.c' file was seen then we are probably linking. That is also
# ok.
exec "$@"
fi
# Name of file we expect compiler to create.
cofile=`echo "$cfile" | sed -e 's|^.*/||' -e 's/\.c$/.o/'`
# Create the lock directory.
# Note: use `[/.-]' here to ensure that we don't use the same name
# that we are using for the .o file. Also, base the name on the expected
# object file name, since that is what matters with a parallel build.
lockdir=`echo "$cofile" | sed -e 's|[/.-]|_|g'`.d
while true; do
if mkdir "$lockdir" >/dev/null 2>&1; then
break
fi
sleep 1
done
# FIXME: race condition here if user kills between mkdir and trap.
trap "rmdir '$lockdir'; exit 1" 1 2 15
# Run the compile.
"$@"
ret=$?
if test -f "$cofile"; then
mv "$cofile" "$ofile"
elif test -f "${cofile}bj"; then
mv "${cofile}bj" "$ofile"
fi
rmdir "$lockdir"
exit $ret
# Local Variables:
# mode: shell-script
# sh-indentation: 2
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-end: "$"
# End:

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

589
dist/atf/admin/depcomp vendored
View File

@ -1,589 +0,0 @@
#! /bin/sh
# depcomp - compile a program generating dependencies as side-effects
scriptversion=2007-03-29.01
# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007 Free Software
# Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
case $1 in
'')
echo "$0: No command. Try \`$0 --help' for more information." 1>&2
exit 1;
;;
-h | --h*)
cat <<\EOF
Usage: depcomp [--help] [--version] PROGRAM [ARGS]
Run PROGRAMS ARGS to compile a file, generating dependencies
as side-effects.
Environment variables:
depmode Dependency tracking mode.
source Source file read by `PROGRAMS ARGS'.
object Object file output by `PROGRAMS ARGS'.
DEPDIR directory where to store dependencies.
depfile Dependency file to output.
tmpdepfile Temporary file to use when outputing dependencies.
libtool Whether libtool is used (yes/no).
Report bugs to <bug-automake@gnu.org>.
EOF
exit $?
;;
-v | --v*)
echo "depcomp $scriptversion"
exit $?
;;
esac
if test -z "$depmode" || test -z "$source" || test -z "$object"; then
echo "depcomp: Variables source, object and depmode must be set" 1>&2
exit 1
fi
# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
depfile=${depfile-`echo "$object" |
sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
rm -f "$tmpdepfile"
# Some modes work just like other modes, but use different flags. We
# parameterize here, but still list the modes in the big case below,
# to make depend.m4 easier to write. Note that we *cannot* use a case
# here, because this file can only contain one case statement.
if test "$depmode" = hp; then
# HP compiler uses -M and no extra arg.
gccflag=-M
depmode=gcc
fi
if test "$depmode" = dashXmstdout; then
# This is just like dashmstdout with a different argument.
dashmflag=-xM
depmode=dashmstdout
fi
case "$depmode" in
gcc3)
## gcc 3 implements dependency tracking that does exactly what
## we want. Yay! Note: for some reason libtool 1.4 doesn't like
## it if -MD -MP comes after the -MF stuff. Hmm.
## Unfortunately, FreeBSD c89 acceptance of flags depends upon
## the command line argument order; so add the flags where they
## appear in depend2.am. Note that the slowdown incurred here
## affects only configure: in makefiles, %FASTDEP% shortcuts this.
for arg
do
case $arg in
-c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;;
*) set fnord "$@" "$arg" ;;
esac
shift # fnord
shift # $arg
done
"$@"
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
mv "$tmpdepfile" "$depfile"
;;
gcc)
## There are various ways to get dependency output from gcc. Here's
## why we pick this rather obscure method:
## - Don't want to use -MD because we'd like the dependencies to end
## up in a subdir. Having to rename by hand is ugly.
## (We might end up doing this anyway to support other compilers.)
## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
## -MM, not -M (despite what the docs say).
## - Using -M directly means running the compiler twice (even worse
## than renaming).
if test -z "$gccflag"; then
gccflag=-MD,
fi
"$@" -Wp,"$gccflag$tmpdepfile"
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
echo "$object : \\" > "$depfile"
alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
## The second -e expression handles DOS-style file names with drive letters.
sed -e 's/^[^:]*: / /' \
-e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
## This next piece of magic avoids the `deleted header file' problem.
## The problem is that when a header file which appears in a .P file
## is deleted, the dependency causes make to die (because there is
## typically no way to rebuild the header). We avoid this by adding
## dummy dependencies for each header file. Too bad gcc doesn't do
## this for us directly.
tr ' ' '
' < "$tmpdepfile" |
## Some versions of gcc put a space before the `:'. On the theory
## that the space means something, we add a space to the output as
## well.
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
hp)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
sgi)
if test "$libtool" = yes; then
"$@" "-Wp,-MDupdate,$tmpdepfile"
else
"$@" -MDupdate "$tmpdepfile"
fi
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
echo "$object : \\" > "$depfile"
# Clip off the initial element (the dependent). Don't try to be
# clever and replace this with sed code, as IRIX sed won't handle
# lines with more than a fixed number of characters (4096 in
# IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
# the IRIX cc adds comments like `#:fec' to the end of the
# dependency line.
tr ' ' '
' < "$tmpdepfile" \
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
tr '
' ' ' >> $depfile
echo >> $depfile
# The second pass generates a dummy entry for each header file.
tr ' ' '
' < "$tmpdepfile" \
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
>> $depfile
else
# The sourcefile does not contain any dependencies, so just
# store a dummy comment line, to avoid errors with the Makefile
# "include basename.Plo" scheme.
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile"
;;
aix)
# The C for AIX Compiler uses -M and outputs the dependencies
# in a .u file. In older versions, this file always lives in the
# current directory. Also, the AIX compiler puts `$object:' at the
# start of each line; $object doesn't have directory information.
# Version 6 uses the directory in both cases.
dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
test "x$dir" = "x$object" && dir=
base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
if test "$libtool" = yes; then
tmpdepfile1=$dir$base.u
tmpdepfile2=$base.u
tmpdepfile3=$dir.libs/$base.u
"$@" -Wc,-M
else
tmpdepfile1=$dir$base.u
tmpdepfile2=$dir$base.u
tmpdepfile3=$dir$base.u
"$@" -M
fi
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
exit $stat
fi
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
do
test -f "$tmpdepfile" && break
done
if test -f "$tmpdepfile"; then
# Each line is of the form `foo.o: dependent.h'.
# Do two passes, one to just change these to
# `$object: dependent.h' and one to simply `dependent.h:'.
sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
# That's a tab and a space in the [].
sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
else
# The sourcefile does not contain any dependencies, so just
# store a dummy comment line, to avoid errors with the Makefile
# "include basename.Plo" scheme.
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile"
;;
icc)
# Intel's C compiler understands `-MD -MF file'. However on
# icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c
# ICC 7.0 will fill foo.d with something like
# foo.o: sub/foo.c
# foo.o: sub/foo.h
# which is wrong. We want:
# sub/foo.o: sub/foo.c
# sub/foo.o: sub/foo.h
# sub/foo.c:
# sub/foo.h:
# ICC 7.1 will output
# foo.o: sub/foo.c sub/foo.h
# and will wrap long lines using \ :
# foo.o: sub/foo.c ... \
# sub/foo.h ... \
# ...
"$@" -MD -MF "$tmpdepfile"
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
# Each line is of the form `foo.o: dependent.h',
# or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
# Do two passes, one to just change these to
# `$object: dependent.h' and one to simply `dependent.h:'.
sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
# Some versions of the HPUX 10.20 sed can't process this invocation
# correctly. Breaking it into two sed invocations is a workaround.
sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" |
sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
hp2)
# The "hp" stanza above does not work with aCC (C++) and HP's ia64
# compilers, which have integrated preprocessors. The correct option
# to use with these is +Maked; it writes dependencies to a file named
# 'foo.d', which lands next to the object file, wherever that
# happens to be.
# Much of this is similar to the tru64 case; see comments there.
dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
test "x$dir" = "x$object" && dir=
base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
if test "$libtool" = yes; then
tmpdepfile1=$dir$base.d
tmpdepfile2=$dir.libs/$base.d
"$@" -Wc,+Maked
else
tmpdepfile1=$dir$base.d
tmpdepfile2=$dir$base.d
"$@" +Maked
fi
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile1" "$tmpdepfile2"
exit $stat
fi
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2"
do
test -f "$tmpdepfile" && break
done
if test -f "$tmpdepfile"; then
sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile"
# Add `dependent.h:' lines.
sed -ne '2,${; s/^ *//; s/ \\*$//; s/$/:/; p;}' "$tmpdepfile" >> "$depfile"
else
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile" "$tmpdepfile2"
;;
tru64)
# The Tru64 compiler uses -MD to generate dependencies as a side
# effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
# At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
# dependencies in `foo.d' instead, so we check for that too.
# Subdirectories are respected.
dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
test "x$dir" = "x$object" && dir=
base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
if test "$libtool" = yes; then
# With Tru64 cc, shared objects can also be used to make a
# static library. This mechanism is used in libtool 1.4 series to
# handle both shared and static libraries in a single compilation.
# With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d.
#
# With libtool 1.5 this exception was removed, and libtool now
# generates 2 separate objects for the 2 libraries. These two
# compilations output dependencies in $dir.libs/$base.o.d and
# in $dir$base.o.d. We have to check for both files, because
# one of the two compilations can be disabled. We should prefer
# $dir$base.o.d over $dir.libs/$base.o.d because the latter is
# automatically cleaned when .libs/ is deleted, while ignoring
# the former would cause a distcleancheck panic.
tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4
tmpdepfile2=$dir$base.o.d # libtool 1.5
tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5
tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504
"$@" -Wc,-MD
else
tmpdepfile1=$dir$base.o.d
tmpdepfile2=$dir$base.d
tmpdepfile3=$dir$base.d
tmpdepfile4=$dir$base.d
"$@" -MD
fi
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
exit $stat
fi
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
do
test -f "$tmpdepfile" && break
done
if test -f "$tmpdepfile"; then
sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
# That's a tab and a space in the [].
sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
else
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile"
;;
#nosideeffect)
# This comment above is used by automake to tell side-effect
# dependency tracking mechanisms from slower ones.
dashmstdout)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout, regardless of -o.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test $1 != '--mode=compile'; do
shift
done
shift
fi
# Remove `-o $object'.
IFS=" "
for arg
do
case $arg in
-o)
shift
;;
$object)
shift
;;
*)
set fnord "$@" "$arg"
shift # fnord
shift # $arg
;;
esac
done
test -z "$dashmflag" && dashmflag=-M
# Require at least two characters before searching for `:'
# in the target name. This is to cope with DOS-style filenames:
# a dependency such as `c:/foo/bar' could be seen as target `c' otherwise.
"$@" $dashmflag |
sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile"
rm -f "$depfile"
cat < "$tmpdepfile" > "$depfile"
tr ' ' '
' < "$tmpdepfile" | \
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
dashXmstdout)
# This case only exists to satisfy depend.m4. It is never actually
# run, as this mode is specially recognized in the preamble.
exit 1
;;
makedepend)
"$@" || exit $?
# Remove any Libtool call
if test "$libtool" = yes; then
while test $1 != '--mode=compile'; do
shift
done
shift
fi
# X makedepend
shift
cleared=no
for arg in "$@"; do
case $cleared in
no)
set ""; shift
cleared=yes ;;
esac
case "$arg" in
-D*|-I*)
set fnord "$@" "$arg"; shift ;;
# Strip any option that makedepend may not understand. Remove
# the object too, otherwise makedepend will parse it as a source file.
-*|$object)
;;
*)
set fnord "$@" "$arg"; shift ;;
esac
done
obj_suffix="`echo $object | sed 's/^.*\././'`"
touch "$tmpdepfile"
${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
rm -f "$depfile"
cat < "$tmpdepfile" > "$depfile"
sed '1,2d' "$tmpdepfile" | tr ' ' '
' | \
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile" "$tmpdepfile".bak
;;
cpp)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test $1 != '--mode=compile'; do
shift
done
shift
fi
# Remove `-o $object'.
IFS=" "
for arg
do
case $arg in
-o)
shift
;;
$object)
shift
;;
*)
set fnord "$@" "$arg"
shift # fnord
shift # $arg
;;
esac
done
"$@" -E |
sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
-e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
sed '$ s: \\$::' > "$tmpdepfile"
rm -f "$depfile"
echo "$object : \\" > "$depfile"
cat < "$tmpdepfile" >> "$depfile"
sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
msvisualcpp)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout, regardless of -o,
# because we must use -o when running libtool.
"$@" || exit $?
IFS=" "
for arg
do
case "$arg" in
"-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
set fnord "$@"
shift
shift
;;
*)
set fnord "$@" "$arg"
shift
shift
;;
esac
done
"$@" -E |
sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile"
rm -f "$depfile"
echo "$object : \\" > "$depfile"
. "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile"
echo " " >> "$depfile"
. "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile"
rm -f "$tmpdepfile"
;;
none)
exec "$@"
;;
*)
echo "Unknown depmode $depmode" 1>&2
exit 1
;;
esac
exit 0
# Local Variables:
# mode: shell-script
# sh-indentation: 2
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-end: "$"
# End:

View File

@ -1,291 +0,0 @@
#!/bin/sh
#
# $NetBSD: install-sh,v 1.1.1.1 2007/11/12 14:50:55 jmmv Exp $
# This script now also installs multiple files, but might choke on installing
# multiple files with spaces in the file names.
#
# install - install a program, script, or datafile
# This comes from X11R5 (mit/util/scripts/install.sh).
#
# Copyright 1991 by the Massachusetts Institute of Technology
#
# Permission to use, copy, modify, distribute, and sell this software and its
# documentation for any purpose is hereby granted without fee, provided that
# the above copyright notice appear in all copies and that both that
# copyright notice and this permission notice appear in supporting
# documentation, and that the name of M.I.T. not be used in advertising or
# publicity pertaining to distribution of the software without specific,
# written prior permission. M.I.T. makes no representations about the
# suitability of this software for any purpose. It is provided "as is"
# without express or implied warranty.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# `make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch.
# set DOITPROG to echo to test this script
# Don't use :- since 4.3BSD and earlier shells don't like it.
doit="${DOITPROG-}"
# put in absolute paths if you don't have them in your path; or use env. vars.
awkprog="${AWKPROG-awk}"
mvprog="${MVPROG-mv}"
cpprog="${CPPROG-cp}"
chmodprog="${CHMODPROG-chmod}"
chownprog="${CHOWNPROG-chown}"
chgrpprog="${CHGRPPROG-chgrp}"
stripprog="${STRIPPROG-strip}"
rmprog="${RMPROG-rm}"
mkdirprog="${MKDIRPROG-mkdir}"
instcmd="$mvprog"
pathcompchmodcmd="$chmodprog 755"
chmodcmd="$chmodprog 755"
chowncmd=""
chgrpcmd=""
stripcmd=""
stripflags=""
rmcmd="$rmprog -f"
mvcmd="$mvprog"
src=""
msrc=""
dst=""
dir_arg=""
suffix=""
suffixfmt=""
while [ x"$1" != x ]; do
case $1 in
-b) suffix=".old"
shift
continue;;
-B) suffixfmt="$2"
shift
shift
continue;;
-c) instcmd="$cpprog"
shift
continue;;
-d) dir_arg=true
shift
continue;;
-m) chmodcmd="$chmodprog $2"
shift
shift
continue;;
-o) chowncmd="$chownprog $2"
shift
shift
continue;;
-g) chgrpcmd="$chgrpprog $2"
shift
shift
continue;;
-s) stripcmd="$stripprog"
shift
continue;;
-S) stripcmd="$stripprog"
stripflags="-S $2 $stripflags"
shift
shift
continue;;
*) if [ x"$msrc" = x ]
then
msrc="$dst"
else
msrc="$msrc $dst"
fi
src="$dst"
dst="$1"
shift
continue;;
esac
done
if [ x"$dir_arg" = x ]
then
dstisfile=""
if [ ! -d "$dst" ]
then
if [ x"$msrc" = x"$src" ]
then
dstisfile=true
else
echo "install: destination is not a directory"
exit 1
fi
fi
else
msrc="$msrc $dst"
fi
if [ x"$msrc" = x ]
then
echo "install: no destination specified"
exit 1
fi
for srcarg in $msrc; do
if [ x"$dir_arg" != x ]; then
dstarg="$srcarg"
else
dstarg="$dst"
# Waiting for this to be detected by the "$instcmd $srcarg $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if [ -f "$srcarg" ]
then
doinst="$instcmd"
elif [ -d "$srcarg" ]
then
echo "install: $srcarg: not a regular file"
exit 1
elif [ "$srcarg" = "/dev/null" ]
then
doinst="$cpprog"
else
echo "install: $srcarg does not exist"
exit 1
fi
# If destination is a directory, append the input filename; if your system
# does not like double slashes in filenames, you may need to add some logic
if [ -d "$dstarg" ]
then
dstarg="$dstarg"/`basename "$srcarg"`
fi
fi
## this sed command emulates the dirname command
dstdir=`echo "$dstarg" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
# Make sure that the destination directory exists.
# this part is taken from Noah Friedman's mkinstalldirs script
# Skip lots of stat calls in the usual case.
if [ ! -d "$dstdir" ]; then
defaultIFS='
'
IFS="${IFS-${defaultIFS}}"
oIFS="${IFS}"
# Some sh's can't handle IFS=/ for some reason.
IFS='%'
set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
IFS="${oIFS}"
pathcomp=''
while [ $# -ne 0 ] ; do
pathcomp="${pathcomp}${1}"
shift
if [ ! -d "${pathcomp}" ] ;
then
$doit $mkdirprog "${pathcomp}"
if [ x"$chowncmd" != x ]; then $doit $chowncmd "${pathcomp}"; else true ; fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "${pathcomp}"; else true ; fi &&
if [ x"$pathcompchmodcmd" != x ]; then $doit $pathcompchmodcmd "${pathcomp}"; else true ; fi
else
true
fi
pathcomp="${pathcomp}/"
done
fi
if [ x"$dir_arg" != x ]
then
if [ -d "$dstarg" ]; then
true
else
$doit $mkdirprog "$dstarg" &&
if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dstarg"; else true ; fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dstarg"; else true ; fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dstarg"; else true ; fi
fi
else
if [ x"$dstisfile" = x ]
then
file=$srcarg
else
file=$dst
fi
dstfile=`basename "$file"`
dstfinal="$dstdir/$dstfile"
# Make a temp file name in the proper directory.
dsttmp=$dstdir/#inst.$$#
# Make a backup file name in the proper directory.
case x$suffixfmt in
*%*) suffix=`echo x |
$awkprog -v bname="$dstfinal" -v fmt="$suffixfmt" '
{ cnt = 0;
do {
sfx = sprintf(fmt, cnt++);
name = bname sfx;
} while (system("test -f " name) == 0);
print sfx; }' -`;;
x) ;;
*) suffix="$suffixfmt";;
esac
dstbackup="$dstfinal$suffix"
# Move or copy the file name to the temp name
$doit $doinst $srcarg "$dsttmp" &&
trap "rm -f ${dsttmp}" 0 &&
# and set any options; do chmod last to preserve setuid bits
# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $instcmd $src $dsttmp" command.
if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dsttmp"; else true;fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dsttmp"; else true;fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd $stripflags "$dsttmp"; else true;fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dsttmp"; else true;fi &&
# Now rename the file to the real destination.
if [ x"$suffix" != x ] && [ -f "$dstfinal" ]
then
$doit $mvcmd "$dstfinal" "$dstbackup"
else
$doit $rmcmd -f "$dstfinal"
fi &&
$doit $mvcmd "$dsttmp" "$dstfinal"
fi
done &&
exit 0

7024
dist/atf/admin/ltmain.sh vendored

File diff suppressed because it is too large Load Diff

367
dist/atf/admin/missing vendored
View File

@ -1,367 +0,0 @@
#! /bin/sh
# Common stub for a few missing GNU programs while installing.
scriptversion=2006-05-10.23
# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006
# Free Software Foundation, Inc.
# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
if test $# -eq 0; then
echo 1>&2 "Try \`$0 --help' for more information"
exit 1
fi
run=:
sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p'
sed_minuso='s/.* -o \([^ ]*\).*/\1/p'
# In the cases where this matters, `missing' is being run in the
# srcdir already.
if test -f configure.ac; then
configure_ac=configure.ac
else
configure_ac=configure.in
fi
msg="missing on your system"
case $1 in
--run)
# Try to run requested program, and just exit if it succeeds.
run=
shift
"$@" && exit 0
# Exit code 63 means version mismatch. This often happens
# when the user try to use an ancient version of a tool on
# a file that requires a minimum version. In this case we
# we should proceed has if the program had been absent, or
# if --run hadn't been passed.
if test $? = 63; then
run=:
msg="probably too old"
fi
;;
-h|--h|--he|--hel|--help)
echo "\
$0 [OPTION]... PROGRAM [ARGUMENT]...
Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
error status if there is no known handling for PROGRAM.
Options:
-h, --help display this help and exit
-v, --version output version information and exit
--run try to run the given command, and emulate it if it fails
Supported PROGRAM values:
aclocal touch file \`aclocal.m4'
autoconf touch file \`configure'
autoheader touch file \`config.h.in'
autom4te touch the output file, or create a stub one
automake touch all \`Makefile.in' files
bison create \`y.tab.[ch]', if possible, from existing .[ch]
flex create \`lex.yy.c', if possible, from existing .c
help2man touch the output file
lex create \`lex.yy.c', if possible, from existing .c
makeinfo touch the output file
tar try tar, gnutar, gtar, then tar without non-portable flags
yacc create \`y.tab.[ch]', if possible, from existing .[ch]
Send bug reports to <bug-automake@gnu.org>."
exit $?
;;
-v|--v|--ve|--ver|--vers|--versi|--versio|--version)
echo "missing $scriptversion (GNU Automake)"
exit $?
;;
-*)
echo 1>&2 "$0: Unknown \`$1' option"
echo 1>&2 "Try \`$0 --help' for more information"
exit 1
;;
esac
# Now exit if we have it, but it failed. Also exit now if we
# don't have it and --version was passed (most likely to detect
# the program).
case $1 in
lex|yacc)
# Not GNU programs, they don't have --version.
;;
tar)
if test -n "$run"; then
echo 1>&2 "ERROR: \`tar' requires --run"
exit 1
elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
exit 1
fi
;;
*)
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
# We have it, but it failed.
exit 1
elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
# Could not run --version or --help. This is probably someone
# running `$TOOL --version' or `$TOOL --help' to check whether
# $TOOL exists and not knowing $TOOL uses missing.
exit 1
fi
;;
esac
# If it does not exist, or fails to run (possibly an outdated version),
# try to emulate it.
case $1 in
aclocal*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`acinclude.m4' or \`${configure_ac}'. You might want
to install the \`Automake' and \`Perl' packages. Grab them from
any GNU archive site."
touch aclocal.m4
;;
autoconf)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`${configure_ac}'. You might want to install the
\`Autoconf' and \`GNU m4' packages. Grab them from any GNU
archive site."
touch configure
;;
autoheader)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`acconfig.h' or \`${configure_ac}'. You might want
to install the \`Autoconf' and \`GNU m4' packages. Grab them
from any GNU archive site."
files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
test -z "$files" && files="config.h"
touch_files=
for f in $files; do
case $f in
*:*) touch_files="$touch_files "`echo "$f" |
sed -e 's/^[^:]*://' -e 's/:.*//'`;;
*) touch_files="$touch_files $f.in";;
esac
done
touch $touch_files
;;
automake*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
You might want to install the \`Automake' and \`Perl' packages.
Grab them from any GNU archive site."
find . -type f -name Makefile.am -print |
sed 's/\.am$/.in/' |
while read f; do touch "$f"; done
;;
autom4te)
echo 1>&2 "\
WARNING: \`$1' is needed, but is $msg.
You might have modified some files without having the
proper tools for further handling them.
You can get \`$1' as part of \`Autoconf' from any GNU
archive site."
file=`echo "$*" | sed -n "$sed_output"`
test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
if test -f "$file"; then
touch $file
else
test -z "$file" || exec >$file
echo "#! /bin/sh"
echo "# Created by GNU Automake missing as a replacement of"
echo "# $ $@"
echo "exit 0"
chmod +x $file
exit 1
fi
;;
bison|yacc)
echo 1>&2 "\
WARNING: \`$1' $msg. You should only need it if
you modified a \`.y' file. You may need the \`Bison' package
in order for those modifications to take effect. You can get
\`Bison' from any GNU archive site."
rm -f y.tab.c y.tab.h
if test $# -ne 1; then
eval LASTARG="\${$#}"
case $LASTARG in
*.y)
SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
if test -f "$SRCFILE"; then
cp "$SRCFILE" y.tab.c
fi
SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
if test -f "$SRCFILE"; then
cp "$SRCFILE" y.tab.h
fi
;;
esac
fi
if test ! -f y.tab.h; then
echo >y.tab.h
fi
if test ! -f y.tab.c; then
echo 'main() { return 0; }' >y.tab.c
fi
;;
lex|flex)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified a \`.l' file. You may need the \`Flex' package
in order for those modifications to take effect. You can get
\`Flex' from any GNU archive site."
rm -f lex.yy.c
if test $# -ne 1; then
eval LASTARG="\${$#}"
case $LASTARG in
*.l)
SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
if test -f "$SRCFILE"; then
cp "$SRCFILE" lex.yy.c
fi
;;
esac
fi
if test ! -f lex.yy.c; then
echo 'main() { return 0; }' >lex.yy.c
fi
;;
help2man)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified a dependency of a manual page. You may need the
\`Help2man' package in order for those modifications to take
effect. You can get \`Help2man' from any GNU archive site."
file=`echo "$*" | sed -n "$sed_output"`
test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
if test -f "$file"; then
touch $file
else
test -z "$file" || exec >$file
echo ".ab help2man is required to generate this page"
exit 1
fi
;;
makeinfo)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified a \`.texi' or \`.texinfo' file, or any other file
indirectly affecting the aspect of the manual. The spurious
call might also be the consequence of using a buggy \`make' (AIX,
DU, IRIX). You might want to install the \`Texinfo' package or
the \`GNU make' package. Grab either from any GNU archive site."
# The file to touch is that specified with -o ...
file=`echo "$*" | sed -n "$sed_output"`
test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
if test -z "$file"; then
# ... or it is the one specified with @setfilename ...
infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
file=`sed -n '
/^@setfilename/{
s/.* \([^ ]*\) *$/\1/
p
q
}' $infile`
# ... or it is derived from the source name (dir/f.texi becomes f.info)
test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info
fi
# If the file does not exist, the user really needs makeinfo;
# let's fail without touching anything.
test -f $file || exit 1
touch $file
;;
tar)
shift
# We have already tried tar in the generic part.
# Look for gnutar/gtar before invocation to avoid ugly error
# messages.
if (gnutar --version > /dev/null 2>&1); then
gnutar "$@" && exit 0
fi
if (gtar --version > /dev/null 2>&1); then
gtar "$@" && exit 0
fi
firstarg="$1"
if shift; then
case $firstarg in
*o*)
firstarg=`echo "$firstarg" | sed s/o//`
tar "$firstarg" "$@" && exit 0
;;
esac
case $firstarg in
*h*)
firstarg=`echo "$firstarg" | sed s/h//`
tar "$firstarg" "$@" && exit 0
;;
esac
fi
echo 1>&2 "\
WARNING: I can't seem to be able to run \`tar' with the given arguments.
You may want to install GNU tar or Free paxutils, or check the
command line arguments."
exit 1
;;
*)
echo 1>&2 "\
WARNING: \`$1' is needed, and is $msg.
You might have modified some files without having the
proper tools for further handling them. Check the \`README' file,
it often tells you about the needed prerequisites for installing
this package. You may also peek at any GNU archive site, in case
some other package would contain this missing \`$1' program."
exit 1
;;
esac
exit 0
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-end: "$"
# End:

View File

@ -1,2 +0,0 @@
#define PACKAGE_REVISION_BASE "0b094aecb5df00cbc8a6a1a9b2668bd586ad5938"
#define PACKAGE_REVISION_CACHED 1

35
dist/atf/atf-c++.hpp vendored
View File

@ -1,35 +0,0 @@
//
// Automated Testing Framework (atf)
//
// Copyright (c) 2007, 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
// 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_HPP_)
#define _ATF_CXX_HPP_
#include <atf-c++/macros.hpp>
#endif // !defined(_ATF_CXX_HPP_)

View File

@ -1,311 +0,0 @@
//
// Automated Testing Framework (atf)
//
// Copyright (c) 2007, 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
// 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(HAVE_CONFIG_H)
#include "bconfig.h"
#endif
extern "C" {
#include <unistd.h>
}
#include <cstdarg>
#include <cstdlib>
#include <cstring>
#include <iostream>
extern "C" {
#include "atf-c/object.h"
}
#include "atf-c++/application.hpp"
#include "atf-c++/sanity.hpp"
#include "atf-c++/ui.hpp"
#if !defined(HAVE_VSNPRINTF_IN_STD)
namespace std {
using ::vsnprintf;
}
#endif // !defined(HAVE_VSNPRINTF_IN_STD)
namespace impl = atf::application;
#define IMPL_NAME "atf::application"
// ------------------------------------------------------------------------
// The "usage_error" class.
// ------------------------------------------------------------------------
impl::usage_error::usage_error(const char *fmt, ...)
throw() :
std::runtime_error("usage_error; message unformatted")
{
va_list ap;
va_start(ap, fmt);
std::vsnprintf(m_text, sizeof(m_text), fmt, ap);
va_end(ap);
}
impl::usage_error::~usage_error(void)
throw()
{
}
const char*
impl::usage_error::what(void)
const throw()
{
return m_text;
}
// ------------------------------------------------------------------------
// The "application" class.
// ------------------------------------------------------------------------
impl::option::option(char ch,
const std::string& a,
const std::string& desc) :
m_character(ch),
m_argument(a),
m_description(desc)
{
}
bool
impl::option::operator<(const impl::option& o)
const
{
return m_character < o.m_character;
}
impl::app::app(const std::string& description,
const std::string& manpage,
const std::string& global_manpage) :
m_hflag(false),
m_argc(-1),
m_argv(NULL),
m_prog_name(NULL),
m_description(description),
m_manpage(manpage),
m_global_manpage(global_manpage)
{
atf_init_objects();
}
impl::app::~app(void)
{
}
bool
impl::app::inited(void)
{
return m_argc != -1;
}
impl::app::options_set
impl::app::options(void)
{
options_set opts = specific_options();
opts.insert(option('h', "", "Shows this help message"));
return opts;
}
std::string
impl::app::specific_args(void)
const
{
return "";
}
impl::app::options_set
impl::app::specific_options(void)
const
{
return options_set();
}
void
impl::app::process_option(int ch, const char* arg)
{
}
void
impl::app::process_options(void)
{
PRE(inited());
std::string optstr;
#if defined(HAVE_GNU_GETOPT)
optstr += '+'; // Turn on POSIX behavior.
#endif
optstr += ':';
{
options_set opts = options();
for (options_set::const_iterator iter = opts.begin();
iter != opts.end(); iter++) {
const option& opt = (*iter);
optstr += opt.m_character;
if (!opt.m_argument.empty())
optstr += ':';
}
}
int ch;
::opterr = 0;
while ((ch = ::getopt(m_argc, m_argv, optstr.c_str())) != -1) {
switch (ch) {
case 'h':
m_hflag = true;
break;
case ':':
throw usage_error("Option -%c requires an argument.",
::optopt);
case '?':
throw usage_error("Unknown option -%c.", ::optopt);
default:
process_option(ch, ::optarg);
}
}
m_argc -= ::optind;
m_argv += ::optind;
}
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) << std::endl
<< std::endl
<< ui::format_text(m_description) << std::endl
<< std::endl;
options_set opts = options();
INV(!opts.empty());
os << "Available options:" << std::endl;
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)
<< std::endl;
}
os << std::endl;
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 + ".")
<< std::endl;
}
int
impl::app::run(int argc, char* const* argv)
{
PRE(argc > 0);
PRE(argv != NULL);
m_argc = argc;
m_argv = argv;
m_prog_name = std::strrchr(m_argv[0], '/');
if (m_prog_name == NULL)
m_prog_name = m_argv[0];
else
m_prog_name++;
const std::string bug =
std::string("This is probably a bug in ") + m_prog_name +
" or one of the libraries it uses. Please report this problem to "
PACKAGE_BUGREPORT " and provide as many details as possible "
"describing how you got to this condition.";
int errcode;
try {
int oldargc = m_argc;
process_options();
if (m_hflag) {
if (oldargc != 2)
throw usage_error("-h must be given alone.");
usage(std::cout);
errcode = EXIT_SUCCESS;
} else
errcode = main();
} catch (const usage_error& e) {
std::cerr << ui::format_error(m_prog_name, e.what())
<< std::endl
<< ui::format_info(m_prog_name, std::string("Type `") +
m_prog_name + " -h' for more details.")
<< std::endl;
errcode = EXIT_FAILURE;
} catch (const std::runtime_error& e) {
std::cerr << ui::format_error(m_prog_name, std::string(e.what()))
<< std::endl;
errcode = EXIT_FAILURE;
} catch (const std::exception& e) {
std::cerr << ui::format_error(m_prog_name,
std::string("Caught unexpected error: ")
+ e.what() + "\n" + bug)
<< std::endl;
errcode = EXIT_FAILURE;
} catch (...) {
std::cerr << ui::format_error(m_prog_name,
std::string("Caught unknown error\n") +
bug)
<< std::endl;
errcode = EXIT_FAILURE;
}
return errcode;
}

View File

@ -1,112 +0,0 @@
//
// Automated Testing Framework (atf)
//
// Copyright (c) 2007, 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
// 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_APPLICATION_HPP_)
#define _ATF_CXX_APPLICATION_HPP_
#include <ostream>
#include <set>
#include <stdexcept>
#include <string>
namespace atf {
namespace application {
// ------------------------------------------------------------------------
// The "usage_error" class.
// ------------------------------------------------------------------------
class usage_error : public std::runtime_error {
char m_text[4096];
public:
usage_error(const char*, ...) throw();
~usage_error(void) throw();
const char* what(void) const throw();
};
// ------------------------------------------------------------------------
// The "option" class.
// ------------------------------------------------------------------------
class option {
char m_character;
std::string m_argument;
std::string m_description;
friend class app;
public:
option(char, const std::string&, const std::string&);
bool operator<(const option&) const;
};
// ------------------------------------------------------------------------
// The "app" class.
// ------------------------------------------------------------------------
class app {
bool m_hflag;
void process_options(void);
void usage(std::ostream&);
bool inited(void);
protected:
typedef std::set< option > options_set;
int m_argc;
char* const* m_argv;
const char* m_prog_name;
std::string m_description;
std::string m_manpage, m_global_manpage;
options_set options(void);
// To be redefined.
virtual std::string specific_args(void) const;
virtual options_set specific_options(void) const;
virtual void process_option(int, const char*);
virtual int main(void) = 0;
public:
app(const std::string&, const std::string&, const std::string&);
virtual ~app(void);
int run(int, char* const* argv);
};
} // namespace application
} // namespace atf
#endif // !defined(_ATF_CXX_APPLICATION_HPP_)

View File

@ -1,264 +0,0 @@
.\"
.\" 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
.\" 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.
.\"
.Dd April 26, 2008
.Dt ATF-C++-API 3
.Os
.Sh NAME
.Nm ATF_ADD_TEST_CASE ,
.Nm ATF_CHECK ,
.Nm ATF_CHECK_EQUAL ,
.Nm ATF_CHECK_THROW ,
.Nm ATF_FAIL ,
.Nm ATF_INIT_TEST_CASES ,
.Nm ATF_PASS ,
.Nm ATF_SKIP ,
.Nm ATF_TEST_CASE ,
.Nm ATF_TEST_CASE_BODY ,
.Nm ATF_TEST_CASE_CLEANUP ,
.Nm ATF_TEST_CASE_HEAD ,
.Nm ATF_TEST_CASE_WITH_CLEANUP
.Nd C++ API to write ATF-based test programs
.Sh SYNOPSIS
.In atf-c++.hpp
.Fn ATF_ADD_TEST_CASE "tcs" "name"
.Fn ATF_CHECK "expression"
.Fn ATF_CHECK_EQUAL "expression_1" "expression_2"
.Fn ATF_CHECK_THROW "statement_1" "expected_exception"
.Fn ATF_FAIL "reason"
.Fn ATF_INIT_TEST_CASES "tcs"
.Fn ATF_PASS
.Fn ATF_SKIP "reason"
.Fn ATF_TEST_CASE "name"
.Fn ATF_TEST_CASE_BODY "name"
.Fn ATF_TEST_CASE_CLEANUP "name"
.Fn ATF_TEST_CASE_HEAD "name"
.Fn ATF_TEST_CASE_WITH_CLEANUP "name"
.Sh DESCRIPTION
ATF provides a mostly-macro-based programming interface to implement test
programs in C or C++.
This interface is backed by a C++ implementation, but this fact is
hidden from the developer as much as possible through the use of
macros to simplify programming.
However, the use of C++ is not hidden everywhere and while you can
implement test cases without knowing anything at all about the object model
underneath the provided calls, you might need some minimum notions of the
language in very specific circumstances.
.Pp
C++-based test programs always follow this template:
.Bd -literal -offset indent
extern "C" {
.Ns ... C-specific includes go here ...
}
.Ns ... C++-specific includes go here ...
#include <atf-c++.hpp>
ATF_TEST_CASE(tc1);
ATF_TEST_CASE_HEAD(tc1)
{
... first test case's header ...
}
ATF_TEST_CASE_BODY(tc1)
{
... first test case's body ...
}
ATF_TEST_CASE_WITH_CLEANUP(tc2);
ATF_TEST_CASE_HEAD(tc2)
{
... second test case's header ...
}
ATF_TEST_CASE_BODY(tc2)
{
... second test case's body ...
}
ATF_TEST_CASE_CLEANUP(tc2)
{
... second test case's cleanup ...
}
.Ns ... additional test cases ...
ATF_INIT_TEST_CASES(tcs)
{
ATF_ADD_TEST_CASE(tcs, tc1)
ATF_ADD_TEST_CASE(tcs, tc2)
... add additional test cases ...
}
.Ed
.Ss Definition of test cases
Test cases have an identifier and are composed of three different parts:
the header, the body and an optional cleanup routine, all of which are
described in
.Xr atf-test-case 8 .
To define test cases, one can use the
.Fn ATF_TEST_CASE
or the
.Fn ATF_TEST_CASE_WITH_CLEANUP
macros, which take a single parameter specifiying the test case's
name.
The former does not allow the specification of a cleanup routine for the
test case while the latter does.
It is important to note that these
.Em do not
set the test case up for execution when the program is run.
In order to do so, a later registration is needed through the
.Fn ATF_ADD_TEST_CASE
macro detailed in
.Sx Program initialization .
.Pp
Later on, one must define the three parts of the body by means of three
functions.
Their headers are given by the
.Fn ATF_TEST_CASE_HEAD ,
.Fn ATF_TEST_CASE_BODY
and
.Fn ATF_TEST_CASE_CLEANUP
macros, all of which take the test case's name.
Following each of these, a block of code is expected, surrounded by the
opening and closing brackets.
.Ss Program initialization
The library provides a way to easily define the test program's
.Fn main
function.
You should never define one on your own, but rely on the
library to do it for you.
This is done by using the
.Fn ATF_INIT_TEST_CASES
macro, which is passed the name of the list that will hold the test cases.
This name can be whatever you want as long as it is a valid variable value.
.Pp
After the macro, you are supposed to provide the body of a function, which
should only use the
.Fn ATF_ADD_TEST_CASE
macro to register the test cases the test program will execute.
The first parameter of this macro matches the name you provided in the
former call.
.Ss Header definitions
The test case's header can define the meta-data by using the
.Fn set
method, which takes two parameters: the first one specifies the
meta-data variable to be set and the second one specifies its value.
Both of them are strings.
.Ss Configuration variables
The test case has read-only access to the current configuration variables
by means of the
.Ft bool
.Fn has_config_var
and the
.Ft std::string
.Fn get_config_var
methods, which can be called in any of the three parts of a test case.
.Ss Access to the source directory
It is possible to get the path to the test case's source directory from any
of its three components by querying the
.Sq srcdir
configuration variable.
.Ss Requiring programs
Aside from the
.Va require.progs
meta-data variable available in the header only, one can also check for
additional programs in the test case's body by using the
.Fn require_prog
function, which takes the base name or full path of a single binary.
Relative paths are forbidden.
If it is not found, the test case will be automatically skipped.
.Ss Test case finalization
The test case finalizes either when the body reaches its end, at which
point the test is assumed to have
.Em passed ,
or at any explicit call to
.Fn ATF_PASS ,
.Fn ATF_FAIL
or
.Fn ATF_SKIP .
These three macros terminate the execution of the test case immediately.
The cleanup routine will be processed afterwards in a completely automated
way, regardless of the test case's termination reason.
.Pp
.Fn ATF_PASS
does not take any parameters.
.Fn ATF_FAIL
and
.Fn ATF_SKIP
take a single string that describes why the test case failed or
was skipped, respectively.
It is very important to provide a clear error message in both cases so that
the user can quickly know why the test did not pass.
.Ss Helper macros for common checks
The library provides several macros that are very handy in multiple
situations.
These basically check some condition after executing a given statement or
processing a given expression and, if the condition is not met, they
automatically call
.Fn ATF_FAIL
with an appropriate error message.
.Pp
.Fn ATF_CHECK
takes an expression and raises a failure if it evaluates to false.
.Pp
.Fn ATF_CHECK_EQUAL
takes two expressions and raises a failure if the two do not evaluate to
the same exact value.
.Pp
.Fn ATF_CHECK_THROW
takes a statement and the name of an exception and raises a failure if
the statement did not throw the specified exception.
.Sh EXAMPLES
The following shows a complete test program with a single test case that
validates the addition operator:
.Bd -literal -offset indent
#include <atf-c++.hpp>
ATF_TEST_CASE(addition);
ATF_TEST_CASE_HEAD(addition)
{
set("descr", "Sample tests for the addition operator");
}
ATF_TEST_CASE_BODY(addition)
{
ATF_CHECK_EQUAL(0 + 0, 0);
ATF_CHECK_EQUAL(0 + 1, 1);
ATF_CHECK_EQUAL(1 + 0, 1);
ATF_CHECK_EQUAL(1 + 1, 2);
ATF_CHECK_EQUAL(100 + 200, 300);
}
ATF_INIT_TEST_CASES(tcs)
{
ATF_ADD_TEST_CASE(tcs, addition);
}
.Ed
.Sh SEE ALSO
.Xr atf-test-program 1 ,
.Xr atf 7 ,
.Xr atf-test-case 8

View File

@ -1,169 +0,0 @@
//
// Automated Testing Framework (atf)
//
// Copyright (c) 2007, 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
// 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 <fstream>
#include "atf-c++/atffile.hpp"
#include "atf-c++/exceptions.hpp"
#include "atf-c++/expand.hpp"
#include "atf-c++/formats.hpp"
// ------------------------------------------------------------------------
// The "reader" helper class.
// ------------------------------------------------------------------------
class reader : public atf::formats::atf_atffile_reader {
const atf::fs::directory& m_dir;
atf::tests::vars_map m_conf, m_props;
std::vector< std::string > m_tps;
void
got_tp(const std::string& name, bool isglob)
{
if (isglob) {
std::vector< std::string > ms =
atf::expand::expand_glob(name, m_dir.names());
// Cannot use m_tps.insert(iterator, begin, end) here because it
// does not work under Solaris.
for (std::vector< std::string >::const_iterator iter = ms.begin();
iter != ms.end(); iter++)
m_tps.push_back(*iter);
} else {
if (m_dir.find(name) == m_dir.end())
throw atf::not_found_error< atf::fs::path >
("Cannot locate the " + name + " file",
atf::fs::path(name));
m_tps.push_back(name);
}
}
void
got_prop(const std::string& name, const std::string& val)
{
m_props[name] = val;
}
void
got_conf(const std::string& var, const std::string& val)
{
m_conf[var] = val;
}
public:
reader(std::istream& is, const atf::fs::directory& dir) :
atf::formats::atf_atffile_reader(is),
m_dir(dir)
{
}
const atf::tests::vars_map&
conf(void)
const
{
return m_conf;
}
const atf::tests::vars_map&
props(void)
const
{
return m_props;
}
const std::vector< std::string >&
tps(void)
const
{
return m_tps;
}
};
// ------------------------------------------------------------------------
// The "atffile" class.
// ------------------------------------------------------------------------
atf::atffile::atffile(const atf::fs::path& filename)
{
// Scan the directory where the atffile lives in to gather a list of
// all possible test programs in it.
fs::directory dir(filename.branch_path());
dir.erase(filename.leaf_name());
fs::directory::iterator iter = dir.begin();
while (iter != dir.end()) {
const std::string& name = (*iter).first;
const fs::file_info& fi = (*iter).second;
// Discard hidden files and non-executable ones so that they are
// not candidates for glob matching.
if (name[0] == '.' || (!fi.is_owner_executable() &&
!fi.is_group_executable()))
dir.erase(iter++);
else
iter++;
}
// Parse the atffile.
std::ifstream is(filename.c_str());
if (!is)
throw atf::not_found_error< fs::path >
("Cannot open Atffile", filename);
reader r(is, dir);
r.read();
is.close();
// Update the atffile with the data accumulated in the reader.
m_conf = r.conf();
m_props = r.props();
m_tps = r.tps();
// Sanity checks.
if (m_props.find("test-suite") == m_props.end())
throw std::runtime_error("Undefined property `test-suite'");
}
const std::vector< std::string >&
atf::atffile::tps(void)
const
{
return m_tps;
}
const atf::tests::vars_map&
atf::atffile::conf(void)
const
{
return m_conf;
}
const atf::tests::vars_map&
atf::atffile::props(void)
const
{
return m_props;
}

View File

@ -1,56 +0,0 @@
//
// Automated Testing Framework (atf)
//
// Copyright (c) 2007, 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
// 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_ATFFILE_HPP_)
#define _ATF_CXX_ATFFILE_HPP_
#include <string>
#include <vector>
#include <atf-c++/fs.hpp>
#include <atf-c++/tests.hpp>
namespace atf {
class atffile {
atf::tests::vars_map m_conf;
std::vector< std::string > m_tps;
atf::tests::vars_map m_props;
public:
atffile(const fs::path&);
const atf::tests::vars_map& conf(void) const;
const std::vector< std::string >& tps(void) const;
const atf::tests::vars_map& props(void) const;
};
} // namespace atf
#endif // !defined(_ATF_CXX_ATFFILE_HPP_)

View File

@ -1,114 +0,0 @@
//
// Automated Testing Framework (atf)
//
// Copyright (c) 2007, 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
// 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 <map>
extern "C" {
#include "atf-c/config.h"
}
#include "atf-c++/config.hpp"
#include "atf-c++/env.hpp"
#include "atf-c++/sanity.hpp"
static std::map< std::string, std::string > m_variables;
//
// Adds all predefined standard build-time variables to the m_variables
// map, considering the values a user may have provided in the environment.
//
// Can only be called once during the program's lifetime.
//
static
void
init_variables(void)
{
PRE(m_variables.empty());
m_variables["atf_arch"] = atf_config_get("atf_arch");
m_variables["atf_confdir"] = atf_config_get("atf_confdir");
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");
POST(!m_variables.empty());
}
const std::string&
atf::config::get(const std::string& varname)
{
if (m_variables.empty())
init_variables();
PRE(has(varname));
return m_variables[varname];
}
const std::map< std::string, std::string >&
atf::config::get_all(void)
{
if (m_variables.empty())
init_variables();
return m_variables;
}
bool
atf::config::has(const std::string& varname)
{
if (m_variables.empty())
init_variables();
return m_variables.find(varname) != m_variables.end();
}
extern "C" {
void __atf_config_reinit(void);
}
namespace atf {
namespace config {
//
// Auxiliary function for the t_config test program so that it can
// revert the configuration's global status to an empty state and
// do new tests from there on.
//
// Ideally this shouldn't be part of the production library... but
// this is so small that it does not matter.
//
void
__reinit(void)
{
__atf_config_reinit();
m_variables.clear();
}
} // namespace config
} // namespace atf

View File

@ -1,75 +0,0 @@
//
// Automated Testing Framework (atf)
//
// Copyright (c) 2007, 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
// 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_CONFIG_HPP_)
#define _ATF_CXX_CONFIG_HPP_
#include <map>
#include <string>
namespace atf {
namespace config {
//!
//! \brief Gets a build-time configuration variable's value.
//!
//! Given the name of a build-time configuration variable, returns its
//! textual value. The user is free to override these by setting their
//! corresponding environment variables. Therefore always use this
//! interface to get the value of these variables.
//!
//! \pre The variable must exist.
//!
const std::string& get(const std::string&);
//!
//! \brief Returns all the build-time configuration variables.
//!
//! Returns a name to value map containing all build-time configuration
//! variables.
//!
const std::map< std::string, std::string >& get_all(void);
//!
//! \brief Checks whether a build-time configuration variable exists.
//!
//! Given the name of a build-time configuration variable, checks
//! whether it is defined and returns a boolean indicating this
//! condition. The program only has to use this function to sanity-check
//! a variable name provided by the user. Otherwise it can assume that
//! the variables are defined.
//!
bool has(const std::string&);
} // namespace config
} // namespace atf
#endif // !defined(_ATF_CXX_CONFIG_HPP_)

View File

@ -1,71 +0,0 @@
//
// Automated Testing Framework (atf)
//
// Copyright (c) 2007, 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
// 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 "atf-c/env.h"
}
#include "atf-c++/env.hpp"
#include "atf-c++/exceptions.hpp"
#include "atf-c++/sanity.hpp"
namespace impl = atf::env;
#define IMPL_NAME "atf::env"
// ------------------------------------------------------------------------
// Free functions.
// ------------------------------------------------------------------------
std::string
impl::get(const std::string& name)
{
return atf_env_get(name.c_str());
}
bool
impl::has(const std::string& name)
{
return atf_env_has(name.c_str());
}
void
impl::set(const std::string& name, const std::string& val)
{
atf_error_t err = atf_env_set(name.c_str(), val.c_str());
if (atf_is_error(err))
throw_atf_error(err);
}
void
impl::unset(const std::string& name)
{
atf_error_t err = atf_env_unset(name.c_str());
if (atf_is_error(err))
throw_atf_error(err);
}

View File

@ -1,84 +0,0 @@
//
// Automated Testing Framework (atf)
//
// Copyright (c) 2007, 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
// 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_ENV_HPP_)
#define _ATF_CXX_ENV_HPP_
#include <string>
namespace atf {
namespace env {
// ------------------------------------------------------------------------
// Free functions.
// ------------------------------------------------------------------------
//!
//! \brief Returns the value of an environment variable.
//!
//! Returns the value of the specified environment variable. The variable
//! must be defined.
//!
std::string get(const std::string&);
//!
//! \brief Checks if the environment has a variable.
//!
//! Checks if the environment has a given variable.
//!
bool has(const std::string&);
//!
//! \brief Sets an environment variable to a given value.
//!
//! Sets the specified environment variable to the given value. Note that
//! variables set to the empty string are different to undefined ones.
//!
//! Be aware that this alters the program's global status, which in general
//! is a bad thing to do due to the side-effects it may have. There are
//! some legitimate usages for this function, though.
//!
void set(const std::string&, const std::string&);
//!
//! \brief Unsets an environment variable.
//!
//! Unsets the specified environment variable Note that undefined
//! variables are different to those defined but set to an empty value.
//!
//! Be aware that this alters the program's global status, which in general
//! is a bad thing to do due to the side-effects it may have. There are
//! some legitimate usages for this function, though.
//!
void unset(const std::string&);
} // namespace env
} // namespace atf
#endif // !defined(_ATF_CXX_ENV_HPP_)

View File

@ -1,94 +0,0 @@
//
// Automated Testing Framework (atf)
//
// Copyright (c) 2007, 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
// 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(HAVE_CONFIG_H)
#include "bconfig.h"
#endif
#include <cstdarg>
#include <cstdio>
#include <cstring>
extern "C" {
#include "atf-c/error.h"
};
#include "atf-c++/exceptions.hpp"
#include "atf-c++/sanity.hpp"
atf::system_error::system_error(const std::string& who,
const std::string& message,
int sys_err) :
std::runtime_error(who + ": " + message),
m_sys_err(sys_err)
{
}
atf::system_error::~system_error(void)
throw()
{
}
int
atf::system_error::code(void)
const
throw()
{
return m_sys_err;
}
const char*
atf::system_error::what(void)
const
throw()
{
try {
if (m_message.length() == 0) {
m_message = std::string(std::runtime_error::what()) + ": ";
m_message += ::strerror(m_sys_err);
}
return m_message.c_str();
} catch (...) {
return "Unable to format system_error message";
}
}
void
atf::throw_atf_error(atf_error_t err)
{
static char buf[4096];
PRE(atf_is_error(err));
atf_error_format(err, buf, sizeof(buf));
atf_error_free(err);
throw std::runtime_error(buf);
}

View File

@ -1,98 +0,0 @@
//
// Automated Testing Framework (atf)
//
// Copyright (c) 2007, 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
// 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_EXCEPTIONS_HPP_)
#define _ATF_CXX_EXCEPTIONS_HPP_
#include <stdexcept>
extern "C" {
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;
public:
system_error(const std::string&, const std::string&, int);
~system_error(void) throw();
int code(void) const throw();
const char* what(void) const throw();
};
void throw_atf_error(struct atf_error *);
} // namespace atf
#endif // !defined(_ATF_CXX_EXCEPTIONS_HPP_)

View File

@ -1,62 +0,0 @@
//
// Automated Testing Framework (atf)
//
// Copyright (c) 2007, 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
// 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 "atf-c/expand.h"
}
#include "atf-c++/exceptions.hpp"
#include "atf-c++/expand.hpp"
#include "atf-c++/sanity.hpp"
namespace impl = atf::expand;
#define IMPL_NAME "atf::expand"
// ------------------------------------------------------------------------
// Free functions.
// ------------------------------------------------------------------------
bool
impl::is_glob(const std::string& glob)
{
return atf_expand_is_glob(glob.c_str());
}
bool
impl::matches_glob(const std::string& glob, const std::string& candidate)
{
bool result;
atf_error_t err;
err = atf_expand_matches_glob(glob.c_str(), candidate.c_str(), &result);
if (atf_is_error(err))
throw_atf_error(err);
return result;
}

View File

@ -1,147 +0,0 @@
//
// Automated Testing Framework (atf)
//
// Copyright (c) 2007, 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
// 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 <stdexcept>
#include <string>
#include <vector>
#include <atf-c++/utils.hpp>
namespace atf {
namespace expand {
// ------------------------------------------------------------------------
// The "pattern_error" class.
// ------------------------------------------------------------------------
//!
//! \brief An error class to hold information about bad patterns.
//!
//! The pattern_error class is used to represent an error when parsing
//! or comparing a pattern against a string.
//!
class pattern_error : public std::runtime_error {
struct shared_data {
//!
//! \brief Number of live references to this shared_data.
//!
size_t m_refs;
//!
//! \brief A pointer to the error message.
//!
//! This variable holds a pointer to the error message describing
//! why the pattern failed. This is a pointer to dynamic memory
//! allocated by the code that constructed this class.
//!
char *m_what;
};
mutable shared_data* m_sd;
//!
//! \brief Assignment operator for pattern_error.
//!
//! This assignment operator is made private to prevent its usage.
//! We cannot modify the parent's message once constructed, so we
//! cannot safely implement this method.
//!
pattern_error& operator=(const pattern_error&);
public:
//!
//! \brief Constructs a new pattern_error.
//!
//! Constructs a new pattern error, to be thrown as an exception,
//! with the given error message. The error message must be a
//! pointer to dynamically allocated memory, obtained by using the
//! 'new char[...]' construction.
//!
pattern_error(atf::utils::auto_array< char >&);
//!
//! \brief Copy-constructor for pattern_error.
//!
pattern_error(const pattern_error&);
//!
//! \brief Destroys the pattern_error.
//!
//! Destroys the object and releases the memory that was held by the
//! error message given during construction.
//!
~pattern_error(void) throw();
};
// ------------------------------------------------------------------------
// Free functions.
// ------------------------------------------------------------------------
//!
//! \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;
}
//!
//! \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&);
} // namespace expand
} // namespace atf
#endif // !defined(_ATF_CXX_EXPAND_HPP_)

File diff suppressed because it is too large Load Diff

View File

@ -1,199 +0,0 @@
//
// Automated Testing Framework (atf)
//
// Copyright (c) 2007, 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
// 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_FORMATS_HPP_)
#define _ATF_CXX_FORMATS_HPP_
#include <istream>
#include <ostream>
#include <stdexcept>
#include <string>
#include <atf-c++/io.hpp>
#include <atf-c++/tests.hpp>
namespace atf {
namespace formats {
// ------------------------------------------------------------------------
// The "format_error" class.
// ------------------------------------------------------------------------
//!
//! \brief A class to signal format errors in external data formats.
//!
//! This error class is used to signal format errors while parsing some
//! externalized representation of a data structure.
//!
class format_error : public std::runtime_error {
public:
format_error(const std::string&);
};
// ------------------------------------------------------------------------
// The "atf_atffile_reader" class.
// ------------------------------------------------------------------------
class atf_atffile_reader {
std::istream& m_is;
protected:
virtual void got_conf(const std::string&, const std::string &);
virtual void got_prop(const std::string&, const std::string &);
virtual void got_tp(const std::string&, bool);
virtual void got_eof(void);
public:
atf_atffile_reader(std::istream&);
virtual ~atf_atffile_reader(void);
void read(void);
};
// ------------------------------------------------------------------------
// The "atf_config_reader" class.
// ------------------------------------------------------------------------
class atf_config_reader {
std::istream& m_is;
protected:
virtual void got_var(const std::string&, const std::string &);
virtual void got_eof(void);
public:
atf_config_reader(std::istream&);
virtual ~atf_config_reader(void);
void read(void);
};
// ------------------------------------------------------------------------
// The "atf_tcs_reader" class.
// ------------------------------------------------------------------------
class atf_tcs_reader {
std::istream& m_is;
void read_out_err(void*,
atf::io::unbuffered_istream&,
atf::io::unbuffered_istream&);
protected:
virtual void got_ntcs(size_t);
virtual void got_tc_start(const std::string&);
virtual void got_tc_end(const atf::tests::tcr&);
virtual void got_stdout_line(const std::string&);
virtual void got_stderr_line(const std::string&);
virtual void got_eof(void);
public:
atf_tcs_reader(std::istream&);
virtual ~atf_tcs_reader(void);
void read(atf::io::unbuffered_istream&, atf::io::unbuffered_istream&);
};
// ------------------------------------------------------------------------
// The "atf_tcs_writer" class.
// ------------------------------------------------------------------------
class atf_tcs_writer {
std::ostream& m_os;
std::ostream& m_cout;
std::ostream& m_cerr;
size_t m_ntcs, m_curtc;
std::string m_tcname;
public:
atf_tcs_writer(std::ostream&, std::ostream&, std::ostream&, size_t);
void start_tc(const std::string&);
void end_tc(const atf::tests::tcr&);
};
// ------------------------------------------------------------------------
// The "atf_tps_reader" class.
// ------------------------------------------------------------------------
class atf_tps_reader {
std::istream& m_is;
void read_info(void*);
void read_tp(void*);
void read_tc(void*);
protected:
virtual void got_info(const std::string&, const std::string&);
virtual void got_ntps(size_t);
virtual void got_tp_start(const std::string&, size_t);
virtual void got_tp_end(const std::string&);
virtual void got_tc_start(const std::string&);
virtual void got_tc_stdout_line(const std::string&);
virtual void got_tc_stderr_line(const std::string&);
virtual void got_tc_end(const atf::tests::tcr&);
virtual void got_eof(void);
public:
atf_tps_reader(std::istream&);
virtual ~atf_tps_reader(void);
void read(void);
};
// ------------------------------------------------------------------------
// The "atf_tps_writer" class.
// ------------------------------------------------------------------------
class atf_tps_writer {
std::ostream& m_os;
std::string m_tpname, m_tcname;
public:
atf_tps_writer(std::ostream&);
void info(const std::string&, const std::string&);
void ntps(size_t);
void start_tp(const std::string&, size_t);
void end_tp(const std::string&);
void start_tc(const std::string&);
void stdout_tc(const std::string&);
void stderr_tc(const std::string&);
void end_tc(const atf::tests::tcr&);
};
} // namespace formats
} // namespace atf
#endif // !defined(_ATF_CXX_FORMATS_HPP_)

View File

@ -1,546 +0,0 @@
//
// Automated Testing Framework (atf)
//
// Copyright (c) 2007, 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
// 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(HAVE_CONFIG_H)
#include "bconfig.h"
#endif
extern "C" {
#include <sys/param.h>
#include <sys/types.h>
#include <sys/mount.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <dirent.h>
#include <libgen.h>
#include <unistd.h>
}
#include <cerrno>
#include <cstdlib>
#include <cstring>
#include "atf-c++/exceptions.hpp"
#include "atf-c++/env.hpp"
#include "atf-c++/fs.hpp"
#include "atf-c++/sanity.hpp"
#include "atf-c++/text.hpp"
#include "atf-c++/user.hpp"
#include "atf-c++/utils.hpp"
namespace impl = atf::fs;
#define IMPL_NAME "atf::fs"
// ------------------------------------------------------------------------
// Auxiliary functions.
// ------------------------------------------------------------------------
//!
//! \brief A controlled version of access(2).
//!
//! This function reimplements the standard access(2) system call to
//! safely control its exit status and raise an exception in case of
//! failure.
//!
static
bool
safe_access(const impl::path& p, int mode, int experr)
{
bool ok;
atf_error_t err = atf_fs_eaccess(p.c_path(), mode);
if (atf_is_error(err)) {
if (atf_error_is(err, "libc")) {
if (atf_libc_error_code(err) == experr)
ok = false;
else {
atf::throw_atf_error(err);
// XXX Silence warning; maybe throw_atf_error should be
// an exception and not a function.
ok = false;
}
} else {
atf::throw_atf_error(err);
// XXX Silence warning; maybe throw_atf_error should be
// an exception and not a function.
ok = false;
}
} else
ok = true;
return ok;
}
// ------------------------------------------------------------------------
// The "path" class.
// ------------------------------------------------------------------------
impl::path::path(const std::string& s)
{
atf_error_t err = atf_fs_path_init_fmt(&m_path, "%s", s.c_str());
if (atf_is_error(err))
throw_atf_error(err);
}
impl::path::path(const path& p)
{
atf_error_t err = atf_fs_path_copy(&m_path, &p.m_path);
if (atf_is_error(err))
throw_atf_error(err);
}
impl::path::~path(void)
{
atf_fs_path_fini(&m_path);
}
const char*
impl::path::c_str(void)
const
{
return atf_fs_path_cstring(&m_path);
}
const atf_fs_path_t*
impl::path::c_path(void)
const
{
return &m_path;
}
std::string
impl::path::str(void)
const
{
return c_str();
}
bool
impl::path::is_absolute(void)
const
{
return atf_fs_path_is_absolute(&m_path);
}
bool
impl::path::is_root(void)
const
{
return atf_fs_path_is_root(&m_path);
}
impl::path
impl::path::branch_path(void)
const
{
atf_fs_path_t bp;
atf_error_t err;
err = atf_fs_path_branch_path(&m_path, &bp);
if (atf_is_error(err))
throw_atf_error(err);
path p(atf_fs_path_cstring(&bp));
atf_fs_path_fini(&bp);
return p;
}
std::string
impl::path::leaf_name(void)
const
{
atf_dynstr_t ln;
atf_error_t err;
err = atf_fs_path_leaf_name(&m_path, &ln);
if (atf_is_error(err))
throw_atf_error(err);
std::string s(atf_dynstr_cstring(&ln));
atf_dynstr_fini(&ln);
return s;
}
impl::path
impl::path::to_absolute(void)
const
{
atf_fs_path_t pa;
atf_error_t err = atf_fs_path_to_absolute(&m_path, &pa);
if (atf_is_error(err))
throw_atf_error(err);
path p(atf_fs_path_cstring(&pa));
atf_fs_path_fini(&pa);
return p;
}
impl::path&
impl::path::operator=(const path& p)
{
atf_fs_path_t tmp;
atf_error_t err = atf_fs_path_init_fmt(&tmp, "%s", p.c_str());
if (atf_is_error(err))
throw_atf_error(err);
else {
atf_fs_path_fini(&m_path);
m_path = tmp;
}
return *this;
}
bool
impl::path::operator==(const path& p)
const
{
return atf_equal_fs_path_fs_path(&m_path, &p.m_path);
}
bool
impl::path::operator!=(const path& p)
const
{
return !atf_equal_fs_path_fs_path(&m_path, &p.m_path);
}
impl::path
impl::path::operator/(const std::string& p)
const
{
path p2 = *this;
atf_error_t err = atf_fs_path_append_fmt(&p2.m_path, "%s", p.c_str());
if (atf_is_error(err))
throw_atf_error(err);
return p2;
}
impl::path
impl::path::operator/(const path& p)
const
{
path p2 = *this;
atf_error_t err = atf_fs_path_append_fmt(&p2.m_path, "%s",
atf_fs_path_cstring(&p.m_path));
if (atf_is_error(err))
throw_atf_error(err);
return p2;
}
bool
impl::path::operator<(const path& p)
const
{
const char *s1 = atf_fs_path_cstring(&m_path);
const char *s2 = atf_fs_path_cstring(&p.m_path);
return std::strcmp(s1, s2) < 0;
}
// ------------------------------------------------------------------------
// The "file_info" class.
// ------------------------------------------------------------------------
const int impl::file_info::blk_type = atf_fs_stat_blk_type;
const int impl::file_info::chr_type = atf_fs_stat_chr_type;
const int impl::file_info::dir_type = atf_fs_stat_dir_type;
const int impl::file_info::fifo_type = atf_fs_stat_fifo_type;
const int impl::file_info::lnk_type = atf_fs_stat_lnk_type;
const int impl::file_info::reg_type = atf_fs_stat_reg_type;
const int impl::file_info::sock_type = atf_fs_stat_sock_type;
const int impl::file_info::wht_type = atf_fs_stat_wht_type;
impl::file_info::file_info(const path& p)
{
atf_error_t err;
err = atf_fs_stat_init(&m_stat, p.c_path());
if (atf_is_error(err))
throw_atf_error(err);
}
impl::file_info::file_info(const file_info& fi)
{
atf_fs_stat_copy(&m_stat, &fi.m_stat);
}
impl::file_info::~file_info(void)
{
atf_fs_stat_fini(&m_stat);
}
dev_t
impl::file_info::get_device(void)
const
{
return atf_fs_stat_get_device(&m_stat);
}
ino_t
impl::file_info::get_inode(void)
const
{
return atf_fs_stat_get_inode(&m_stat);
}
int
impl::file_info::get_type(void)
const
{
return atf_fs_stat_get_type(&m_stat);
}
bool
impl::file_info::is_owner_readable(void)
const
{
return atf_fs_stat_is_owner_readable(&m_stat);
}
bool
impl::file_info::is_owner_writable(void)
const
{
return atf_fs_stat_is_owner_writable(&m_stat);
}
bool
impl::file_info::is_owner_executable(void)
const
{
return atf_fs_stat_is_owner_executable(&m_stat);
}
bool
impl::file_info::is_group_readable(void)
const
{
return atf_fs_stat_is_group_readable(&m_stat);
}
bool
impl::file_info::is_group_writable(void)
const
{
return atf_fs_stat_is_group_writable(&m_stat);
}
bool
impl::file_info::is_group_executable(void)
const
{
return atf_fs_stat_is_group_executable(&m_stat);
}
bool
impl::file_info::is_other_readable(void)
const
{
return atf_fs_stat_is_other_readable(&m_stat);
}
bool
impl::file_info::is_other_writable(void)
const
{
return atf_fs_stat_is_other_writable(&m_stat);
}
bool
impl::file_info::is_other_executable(void)
const
{
return atf_fs_stat_is_other_executable(&m_stat);
}
// ------------------------------------------------------------------------
// The "directory" class.
// ------------------------------------------------------------------------
impl::directory::directory(const path& p)
{
DIR* dp = ::opendir(p.c_str());
if (dp == NULL)
throw system_error(IMPL_NAME "::directory::directory(" +
p.str() + ")", "opendir(3) failed", errno);
struct dirent* dep;
while ((dep = ::readdir(dp)) != NULL) {
path entryp = p / dep->d_name;
insert(value_type(dep->d_name, file_info(entryp)));
}
if (::closedir(dp) == -1)
throw system_error(IMPL_NAME "::directory::directory(" +
p.str() + ")", "closedir(3) failed", errno);
}
std::set< std::string >
impl::directory::names(void)
const
{
std::set< std::string > ns;
for (const_iterator iter = begin(); iter != end(); iter++)
ns.insert((*iter).first);
return ns;
}
// ------------------------------------------------------------------------
// The "temp_dir" class.
// ------------------------------------------------------------------------
impl::temp_dir::temp_dir(const path& p)
{
atf::utils::auto_array< char > buf(new char[p.str().length() + 1]);
std::strcpy(buf.get(), p.c_str());
if (::mkdtemp(buf.get()) == NULL)
throw system_error(IMPL_NAME "::temp_dir::temp_dir(" +
p.str() + ")", "mkdtemp(3) failed",
errno);
m_path = new path(buf.get());
}
impl::temp_dir::~temp_dir(void)
{
cleanup(*m_path);
delete m_path;
}
const impl::path&
impl::temp_dir::get_path(void)
const
{
return *m_path;
}
// ------------------------------------------------------------------------
// Free functions.
// ------------------------------------------------------------------------
impl::path
impl::change_directory(const path& dir)
{
path olddir = get_current_dir();
if (olddir != dir) {
if (::chdir(dir.c_str()) == -1)
throw system_error(IMPL_NAME "::chdir(" + dir.str() + ")",
"chdir(2) failed", errno);
}
return olddir;
}
bool
impl::exists(const path& p)
{
atf_error_t err;
bool b;
err = atf_fs_exists(p.c_path(), &b);
if (atf_is_error(err))
throw_atf_error(err);
return b;
}
bool
impl::have_prog_in_path(const std::string& prog)
{
PRE(prog.find('/') == std::string::npos);
// Do not bother to provide a default value for PATH. If it is not
// there something is broken in the user's environment.
if (!atf::env::has("PATH"))
throw std::runtime_error("PATH not defined in the environment");
std::vector< std::string > dirs = \
atf::text::split(atf::env::get("PATH"), ":");
bool found = false;
for (std::vector< std::string >::const_iterator iter = dirs.begin();
!found && iter != dirs.end(); iter++) {
const path& dir = path(*iter);
if (is_executable(dir / prog))
found = true;
}
return found;
}
impl::path
impl::get_current_dir(void)
{
atf_fs_path_t cwd;
atf_error_t err = atf_fs_getcwd(&cwd);
if (atf_is_error(err))
throw_atf_error(err);
path p(atf_fs_path_cstring(&cwd));
atf_fs_path_fini(&cwd);
return p;
}
bool
impl::is_executable(const path& p)
{
if (!exists(p))
return false;
return safe_access(p, atf_fs_access_x, EACCES);
}
void
impl::remove(const path& p)
{
if (file_info(p).get_type() == file_info::dir_type)
throw atf::system_error(IMPL_NAME "::remove(" + p.str() + ")",
"Is a directory",
EPERM);
if (::unlink(p.c_str()) == -1)
throw atf::system_error(IMPL_NAME "::remove(" + p.str() + ")",
"unlink(" + p.str() + ") failed",
errno);
}
void
impl::cleanup(const path& p)
{
atf_error_t err;
err = atf_fs_cleanup(p.c_path());
if (atf_is_error(err))
throw_atf_error(err);
}

View File

@ -1,437 +0,0 @@
//
// Automated Testing Framework (atf)
//
// Copyright (c) 2007, 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
// 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_FS_HPP_)
#define _ATF_CXX_FS_HPP_
extern "C" {
#include <sys/types.h>
}
#include <map>
#include <set>
#include <stdexcept>
#include <string>
extern "C" {
#include "atf-c/fs.h"
}
namespace atf {
namespace fs {
// ------------------------------------------------------------------------
// The "path" class.
// ------------------------------------------------------------------------
//!
//! \brief A class to represent a path to a file.
//!
//! The path class represents the route to a file or directory in the
//! file system. All file manipulation operations use this class to
//! represent their arguments as it takes care of normalizing user-provided
//! strings and ensures they are valid.
//!
//! It is important to note that the file pointed to by a path need not
//! exist.
//!
class path {
//!
//! \brief Internal representation of a path.
//!
atf_fs_path_t m_path;
public:
//! \brief Constructs a new path from a user-provided string.
//!
//! This constructor takes a string, either provided by the program's
//! code or by the user and constructs a new path object. The string
//! is normalized to not contain multiple delimiters together and to
//! remove any trailing one.
//!
//! The input string cannot be empty.
//!
explicit path(const std::string&);
//!
//! \brief Copy constructor.
//!
path(const path&);
//!
//! \brief Destructor for the path class.
//!
~path(void);
//!
//! \brief Returns a pointer to a C-style string representing this path.
//!
const char* c_str(void) const;
//!
//! \brief Returns a pointer to the implementation data.
//!
const atf_fs_path_t* c_path(void) const;
//!
//! \brief Returns a string representing this path.
//! XXX Really needed?
//!
std::string str(void) const;
//!
//! \brief Returns the branch path of this path.
//!
//! Calculates and returns the branch path of this path. In other
//! words, it returns what the standard ::dirname function would return.
//!
path branch_path(void) const;
//!
//! \brief Returns the leaf name of this path.
//!
//! Calculates and returns the leaf name of this path. In other words,
//! it returns what the standard ::basename function would return.
//!
std::string leaf_name(void) const;
//!
//! \brief Checks whether this path is absolute or not.
//!
//! Returns a boolean indicating if this is an absolute path or not;
//! i.e. if it starts with a slash.
//!
bool is_absolute(void) const;
//!
//! \brief Checks whether this path points to the root directory or not.
//!
//! Returns a boolean indicating if this is path points to the root
//! directory or not. The checks made by this are extremely simple (so
//! the results cannot always be trusted) but they are enough for our
//! modest sanity-checking needs. I.e. "/../" could return false.
//!
bool is_root(void) const;
//!
//! \brief Converts the path to be absolute.
//!
//! \pre The path was not absolute.
//!
path to_absolute(void) const;
//!
//! \brief Assignment operator.
//!
path& operator=(const path&);
//!
//! \brief Checks if two paths are equal.
//!
bool operator==(const path&) const;
//!
//! \brief Checks if two paths are different.
//!
bool operator!=(const path&) const;
//!
//! \brief Concatenates a path with a string.
//!
//! Constructs a new path object that is the concatenation of the
//! left-hand path with the right-hand string. The string is normalized
//! before the concatenation, and a path delimiter is introduced between
//! the two components if needed.
//!
path operator/(const std::string&) const;
//!
//! \brief Concatenates a path with another path.
//!
//! Constructs a new path object that is the concatenation of the
//! left-hand path with the right-hand one. A path delimiter is
//! introduced between the two components if needed.
//!
path operator/(const path&) const;
//!
//! \brief Checks if a path has to be sorted before another one
//! lexicographically.
//!
bool operator<(const path&) const;
};
// ------------------------------------------------------------------------
// The "file_info" class.
// ------------------------------------------------------------------------
class directory;
//!
//! \brief A class that contains information about a file.
//!
//! The file_info class holds information about an specific file that
//! exists in the file system.
//!
class file_info {
atf_fs_stat_t m_stat;
public:
//!
//! \brief The file's type.
//!
static const int blk_type;
static const int chr_type;
static const int dir_type;
static const int fifo_type;
static const int lnk_type;
static const int reg_type;
static const int sock_type;
static const int wht_type;
//!
//! \brief Constructs a new file_info based on a given file.
//!
//! This constructor creates a new file_info object and fills it with
//! the data returned by ::stat when run on the given file, which must
//! exist.
//!
explicit file_info(const path&);
//!
//! \brief The copy constructor.
//!
file_info(const file_info&);
//!
//! \brief The destructor.
//!
~file_info(void);
//!
//! \brief Returns the device containing the file.
//!
dev_t get_device(void) const;
//!
//! \brief Returns the file's inode.
//!
ino_t get_inode(void) const;
//!
//! \brief Returns the file's type.
//!
int get_type(void) const;
//!
//! \brief Returns whether the file is readable by its owner or not.
//!
bool is_owner_readable(void) const;
//!
//! \brief Returns whether the file is writable by its owner or not.
//!
bool is_owner_writable(void) const;
//!
//! \brief Returns whether the file is executable by its owner or not.
//!
bool is_owner_executable(void) const;
//!
//! \brief Returns whether the file is readable by the users belonging
//! to its group or not.
//!
bool is_group_readable(void) const;
//!
//! \brief Returns whether the file is writable the users belonging to
//! its group or not.
//!
bool is_group_writable(void) const;
//!
//! \brief Returns whether the file is executable by the users
//! belonging to its group or not.
//!
bool is_group_executable(void) const;
//!
//! \brief Returns whether the file is readable by people different
//! than the owner and those belonging to the group or not.
//!
bool is_other_readable(void) const;
//!
//! \brief Returns whether the file is write by people different
//! than the owner and those belonging to the group or not.
//!
bool is_other_writable(void) const;
//!
//! \brief Returns whether the file is executable by people different
//! than the owner and those belonging to the group or not.
//!
bool is_other_executable(void) const;
};
// ------------------------------------------------------------------------
// The "directory" class.
// ------------------------------------------------------------------------
//!
//! \brief A class representing a file system directory.
//!
//! The directory class represents a group of files in the file system and
//! corresponds to exactly one directory.
//!
class directory : public std::map< std::string, file_info > {
public:
//!
//! \brief Constructs a new directory.
//!
//! Constructs a new directory object representing the given path.
//! The directory must exist at creation time as the contents of the
//! class are gathered from it.
//!
directory(const path&);
//!
//! \brief Returns the file names of the files in the directory.
//!
//! Returns the leaf names of all files contained in the directory.
//! I.e. the keys of the directory map.
//!
std::set< std::string > names(void) const;
};
// ------------------------------------------------------------------------
// The "temp_dir" class.
// ------------------------------------------------------------------------
//!
//! \brief A RAII model for temporary directories.
//!
//! The temp_dir class provides a RAII model for temporary directories.
//! During construction, a safe temporary directory is created and during
//! destruction it is carefully removed by making use of the cleanup
//! function.
//!
class temp_dir {
//!
//! \brief The path to this temporary directory.
//!
path *m_path;
public:
//!
//! \brief Creates a new temporary directory.
//!
//! Creates a new temporary directory based on the provided name
//! template. The template must end with six X characters preceded
//! by a dot. These characters are replaced with a unique name on
//! the file system as described in mkdtemp(3).
//!
temp_dir(const path&);
//!
//! \brief Destroys the temporary directory.
//!
//! Destroys this temporary directory object as well as its file
//! system representation.
//!
~temp_dir(void);
//!
//! \brief Returns the path to this temporary directory.
//!
const path& get_path(void) const;
};
// ------------------------------------------------------------------------
// Free functions.
// ------------------------------------------------------------------------
//!
//! \brief Changes the current working directory.
//!
//! Changes the current working directory to the given path. Returns the
//! path to the directory just left.
//!
//! \throw system_error If ::chdir failed.
//!
path change_directory(const path&);
//!
//! \brief Checks if the given path exists.
//!
bool exists(const path&);
//!
//! \brief Looks for the given program in the PATH.
//!
//! Given a program name (without slashes) looks for it in the path and
//! returns its full path name if found, otherwise an empty path.
//!
bool have_prog_in_path(const std::string&);
//!
//! \brief Returns the path to the current working directory.
//!
//! Calculates and returns the path to the current working directory, which
//! is guessed using the ::getcwd function.
//!
//! \throw system_error If ::getcwd failed.
//!
path get_current_dir(void);
//!
//! \brief Checks if the given path exists, is accessible and is executable.
//!
bool is_executable(const path&);
//!
//! \brief Removes a given file.
//!
void remove(const path&);
//!
//! \brief Recursively cleans up a directory.
//!
//! This function cleans up a directory hierarchy. First of all, it looks
//! for any file system that may be mounted under the given path and, if
//! any is found, an attempt is made to unmount it. Later on, the
//! directory is removed alongside all of its contents.
//!
void cleanup(const path&);
} // namespace fs
} // namespace atf
#endif // !defined(_ATF_CXX_FS_HPP_)

View File

@ -1,350 +0,0 @@
//
// Automated Testing Framework (atf)
//
// Copyright (c) 2007, 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
// 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 <unistd.h>
}
#include <cerrno>
#include "atf-c++/exceptions.hpp"
#include "atf-c++/io.hpp"
#include "atf-c++/sanity.hpp"
namespace impl = atf::io;
#define IMPL_NAME "atf::io"
// ------------------------------------------------------------------------
// The "file_handle" class.
// ------------------------------------------------------------------------
impl::file_handle::file_handle(void) :
m_handle(invalid_value())
{
}
impl::file_handle::file_handle(handle_type h) :
m_handle(h)
{
PRE(m_handle != invalid_value());
}
impl::file_handle::file_handle(const file_handle& fh) :
m_handle(fh.m_handle)
{
fh.m_handle = invalid_value();
}
impl::file_handle::~file_handle(void)
{
if (is_valid())
close();
}
impl::file_handle&
impl::file_handle::operator=(const file_handle& fh)
{
m_handle = fh.m_handle;
fh.m_handle = invalid_value();
return *this;
}
bool
impl::file_handle::is_valid(void)
const
{
return m_handle != invalid_value();
}
void
impl::file_handle::close(void)
{
PRE(is_valid());
::close(m_handle);
m_handle = invalid_value();
}
impl::file_handle::handle_type
impl::file_handle::disown(void)
{
PRE(is_valid());
handle_type h = m_handle;
m_handle = invalid_value();
return h;
}
impl::file_handle::handle_type
impl::file_handle::get(void)
const
{
PRE(is_valid());
return m_handle;
}
void
impl::file_handle::posix_remap(handle_type h)
{
PRE(is_valid());
if (m_handle == h)
return;
if (::dup2(m_handle, h) == -1)
throw system_error(IMPL_NAME "::file_handle::posix_remap",
"dup2(2) failed", errno);
if (::close(m_handle) == -1) {
::close(h);
throw system_error(IMPL_NAME "::file_handle::posix_remap",
"close(2) failed", errno);
}
m_handle = h;
}
const impl::file_handle::handle_type
impl::file_handle::invalid_value(void)
{
return -1;
}
// ------------------------------------------------------------------------
// The "systembuf" class.
// ------------------------------------------------------------------------
impl::systembuf::systembuf(handle_type h, std::size_t bufsize) :
m_handle(h),
m_bufsize(bufsize),
m_read_buf(NULL),
m_write_buf(NULL)
{
PRE(m_handle >= 0);
PRE(m_bufsize > 0);
try {
m_read_buf = new char[bufsize];
m_write_buf = new char[bufsize];
} catch (...) {
if (m_read_buf != NULL)
delete [] m_read_buf;
if (m_write_buf != NULL)
delete [] m_write_buf;
throw;
}
setp(m_write_buf, m_write_buf + m_bufsize);
}
impl::systembuf::~systembuf(void)
{
sync(); // XXX Unsure if this is correct. But seems to be needed.
delete [] m_read_buf;
delete [] m_write_buf;
}
impl::systembuf::int_type
impl::systembuf::underflow(void)
{
PRE(gptr() >= egptr());
bool ok;
ssize_t cnt = ::read(m_handle, m_read_buf, m_bufsize);
ok = (cnt != -1 && cnt != 0);
if (!ok)
return traits_type::eof();
else {
setg(m_read_buf, m_read_buf, m_read_buf + cnt);
return traits_type::to_int_type(*gptr());
}
}
impl::systembuf::int_type
impl::systembuf::overflow(int c)
{
PRE(pptr() >= epptr());
if (sync() == -1)
return traits_type::eof();
if (!traits_type::eq_int_type(c, traits_type::eof())) {
traits_type::assign(*pptr(), c);
pbump(1);
}
return traits_type::not_eof(c);
}
int
impl::systembuf::sync(void)
{
ssize_t cnt = pptr() - pbase();
bool ok;
ok = ::write(m_handle, pbase(), cnt) == cnt;
if (ok)
pbump(-cnt);
return ok ? 0 : -1;
}
// ------------------------------------------------------------------------
// The "pipe" class.
// ------------------------------------------------------------------------
impl::pipe::pipe(void)
{
file_handle::handle_type hs[2];
if (::pipe(hs) == -1)
throw system_error(IMPL_NAME "::pipe::pipe",
"pipe(2) failed", errno);
m_read_end = file_handle(hs[0]);
m_write_end = file_handle(hs[1]);
}
impl::file_handle&
impl::pipe::rend(void)
{
return m_read_end;
}
impl::file_handle&
impl::pipe::wend(void)
{
return m_write_end;
}
// ------------------------------------------------------------------------
// The "pistream" class.
// ------------------------------------------------------------------------
impl::pistream::pistream(impl::file_handle& fh) :
std::istream(NULL),
m_handle(fh),
m_systembuf(m_handle.get())
{
rdbuf(&m_systembuf);
}
void
impl::pistream::close(void)
{
m_handle.close();
}
impl::file_handle&
impl::pistream::handle(void)
{
return m_handle;
}
// ------------------------------------------------------------------------
// The "postream" class.
// ------------------------------------------------------------------------
impl::postream::postream(impl::file_handle& fh) :
std::ostream(NULL),
m_handle(fh),
m_systembuf(m_handle.get())
{
rdbuf(&m_systembuf);
}
void
impl::postream::close(void)
{
m_handle.close();
}
impl::file_handle&
impl::postream::handle(void)
{
return m_handle;
}
// ------------------------------------------------------------------------
// The "pollable_istream" class.
// ------------------------------------------------------------------------
impl::unbuffered_istream::unbuffered_istream(impl::file_handle& fh) :
m_fh(fh),
m_is_good(true)
{
}
impl::file_handle&
impl::unbuffered_istream::get_fh(void)
{
return m_fh;
}
bool
impl::unbuffered_istream::good(void)
const
{
return m_is_good;
}
size_t
impl::unbuffered_istream::read(void* buf, size_t buflen)
{
if (!m_is_good)
return 0;
ssize_t res = ::read(m_fh.get(), buf, buflen);
m_is_good = res > 0;
return res > 0 ? res : 0;
}
void
impl::unbuffered_istream::close(void)
{
m_is_good = false;
m_fh.close();
}
// ------------------------------------------------------------------------
// Free functions.
// ------------------------------------------------------------------------
impl::unbuffered_istream&
impl::getline(unbuffered_istream& uis, std::string& str)
{
str.clear();
char ch;
while (uis.read(&ch, sizeof(ch)) == sizeof(ch) && ch != '\n') {
if (ch != '\r')
str += ch;
}
return uis;
}

View File

@ -1,637 +0,0 @@
//
// Automated Testing Framework (atf)
//
// Copyright (c) 2007, 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
// 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_IO_HPP_)
#define _ATF_CXX_IO_HPP_
#include <istream>
#include <ostream>
#include <streambuf>
#include <atf-c++/utils.hpp>
namespace atf {
namespace io {
// ------------------------------------------------------------------------
// The "file_handle" class.
// ------------------------------------------------------------------------
//!
//! \brief Simple RAII model for system file handles.
//!
//! The \a file_handle class is a simple RAII model for native system file
//! handles. This class wraps one of such handles grabbing its ownership,
//! and automaticaly closes it upon destruction. It is basically used
//! inside the library to avoid leaking open file handles, shall an
//! unexpected execution trace occur.
//!
//! A \a file_handle object can be copied but doing so invalidates the
//! source object. There can only be a single valid \a file_handle object
//! for a given system file handle. This is similar to std::auto_ptr\<\>'s
//! semantics.
//!
//! This class also provides some convenience methods to issue special file
//! operations under their respective platforms.
//!
class file_handle
{
public:
//!
//! \brief Opaque name for the native handle type.
//!
//! Each operating system identifies file handles using a specific type.
//! The \a handle_type type is used to transparently refer to file
//! handles regarless of the operating system in which this class is
//! used.
//!
//! If this class is used in a POSIX system, \a NativeSystemHandle is
//! an integer type while it is a \a HANDLE in a Win32 system.
//!
typedef int handle_type;
//!
//! \brief Constructs an invalid file handle.
//!
//! This constructor creates a new \a file_handle object that represents
//! an invalid file handle. An invalid file handle can be copied but
//! cannot be manipulated in any way (except checking for its validity).
//!
//! \see is_valid()
//!
file_handle(void);
//!
//! \brief Constructs a new file handle from a native file handle.
//!
//! This constructor creates a new \a file_handle object that takes
//! ownership of the given \a h native file handle. The user must not
//! close \a h on his own during the lifetime of the new object.
//! Ownership can be reclaimed using disown().
//!
//! \pre The native file handle must be valid; a close operation must
//! succeed on it.
//!
//! \see disown()
//!
file_handle(handle_type h);
//!
//! \brief Copy constructor; invalidates the source handle.
//!
//! This copy constructor creates a new file handle from a given one.
//! Ownership of the native file handle is transferred to the new
//! object, effectively invalidating the source file handle. This
//! avoids having two live \a file_handle objects referring to the
//! same native file handle. The source file handle need not be
//! valid in the name of simplicity.
//!
//! \post The source file handle is invalid.
//! \post The new file handle owns the source's native file handle.
//!
file_handle(const file_handle& fh);
//!
//! \brief Releases resources if the handle is valid.
//!
//! If the file handle is valid, the destructor closes it.
//!
//! \see is_valid()
//!
~file_handle(void);
//!
//! \brief Assignment operator; invalidates the source handle.
//!
//! This assignment operator transfers ownership of the RHS file
//! handle to the LHS one, effectively invalidating the source file
//! handle. This avoids having two live \a file_handle objects
//! referring to the same native file handle. The source file
//! handle need not be valid in the name of simplicity.
//!
//! \post The RHS file handle is invalid.
//! \post The LHS file handle owns RHS' native file handle.
//! \return A reference to the LHS file handle.
//!
file_handle& operator=(const file_handle& fh);
//!
//! \brief Checks whether the file handle is valid or not.
//!
//! Returns a boolean indicating whether the file handle is valid or
//! not. If the file handle is invalid, no other applications can be
//! executed other than the destructor.
//!
//! \return True if the file handle is valid; false otherwise.
//!
bool is_valid(void) const;
//!
//! \brief Closes the file handle.
//!
//! Explicitly closes the file handle, which must be valid. Upon
//! exit, the handle is not valid any more.
//!
//! \pre The file handle is valid.
//! \post The file handle is invalid.
//! \post The native file handle is closed.
//!
void close(void);
//!
//! \brief Reclaims ownership of the native file handle.
//!
//! Explicitly reclaims ownership of the native file handle contained
//! in the \a file_handle object, returning the native file handle.
//! The caller is responsible of closing it later on.
//!
//! \pre The file handle is valid.
//! \post The file handle is invalid.
//! \return The native file handle.
//!
handle_type disown(void);
//!
//! \brief Gets the native file handle.
//!
//! Returns the native file handle for the \a file_handle object.
//! The caller can issue any operation on it except closing it.
//! If closing is required, disown() shall be used.
//!
//! \pre The file handle is valid.
//! \return The native file handle.
//!
handle_type get(void) const;
//!
//! \brief Changes the native file handle to the given one.
//!
//! Given a new native file handle \a h, this operation assigns this
//! handle to the current object, closing its old native file handle.
//! In other words, it first calls dup2() to remap the old handle to
//! the new one and then closes the old handle.
//!
//! If \a h matches the current value of the handle, this is a no-op.
//! This is done for simplicity, to avoid the caller having to check
//! this condition on its own.
//!
//! If \a h is open, it is automatically closed by dup2().
//!
//! This operation is only available in POSIX systems.
//!
//! \pre The file handle is valid.
//! \pre The native file handle \a h is valid; i.e., it must be
//! closeable.
//! \post The file handle's native file handle is \a h.
//! \throw system_error If the internal remapping operation fails.
//!
void posix_remap(handle_type h);
private:
//!
//! \brief Internal handle value.
//!
//! This variable holds the native handle value for the file handle
//! hold by this object. It is interesting to note that this needs
//! to be mutable because the copy constructor and the assignment
//! operator invalidate the source object.
//!
mutable handle_type m_handle;
//!
//! \brief Constant function representing an invalid handle value.
//!
//! Returns the platform-specific handle value that represents an
//! invalid handle. This is a constant function rather than a regular
//! constant because, in the latter case, we cannot define it under
//! Win32 due to the value being of a complex type.
//!
static const handle_type invalid_value(void);
};
// ------------------------------------------------------------------------
// The "systembuf" class.
// ------------------------------------------------------------------------
//!
//! \brief std::streambuf implementation for system file handles.
//!
//! systembuf provides a std::streambuf implementation for system file
//! handles. Contrarywise to file_handle, this class does \b not take
//! ownership of the native file handle; this should be taken care of
//! somewhere else.
//!
//! This class follows the expected semantics of a std::streambuf object.
//! However, it is not copyable to avoid introducing inconsistences with
//! the on-disk file and the in-memory buffers.
//!
class systembuf :
public std::streambuf, utils::noncopyable
{
public:
typedef int handle_type;
//!
//! \brief Constructs a new systembuf for the given file handle.
//!
//! This constructor creates a new systembuf object that reads or
//! writes data from/to the \a h native file handle. This handle
//! is \b not owned by the created systembuf object; the code
//! should take care of it externally.
//!
//! This class buffers input and output; the buffer size may be
//! tuned through the \a bufsize parameter, which defaults to 8192
//! bytes.
//!
//! \see pistream and postream.
//!
explicit systembuf(handle_type h, std::size_t bufsize = 8192);
~systembuf(void);
private:
//!
//! \brief Native file handle used by the systembuf object.
//!
handle_type m_handle;
//!
//! \brief Internal buffer size used during read and write operations.
//!
std::size_t m_bufsize;
//!
//! \brief Internal buffer used during read operations.
//!
char* m_read_buf;
//!
//! \brief Internal buffer used during write operations.
//!
char* m_write_buf;
protected:
//!
//! \brief Reads new data from the native file handle.
//!
//! This operation is called by input methods when there are no more
//! data in the input buffer. The function fills the buffer with new
//! data, if available.
//!
//! \pre All input positions are exhausted (gptr() >= egptr()).
//! \post The input buffer has new data, if available.
//! \returns traits_type::eof() if a read error occurrs or there are
//! no more data to be read. Otherwise returns
//! traits_type::to_int_type(*gptr()).
//!
virtual int_type underflow(void);
//!
//! \brief Makes room in the write buffer for additional data.
//!
//! This operation is called by output methods when there is no more
//! space in the output buffer to hold a new element. The function
//! first flushes the buffer's contents to disk and then clears it to
//! leave room for more characters. The given \a c character is
//! stored at the beginning of the new space.
//!
//! \pre All output positions are exhausted (pptr() >= epptr()).
//! \post The output buffer has more space if no errors occurred
//! during the write to disk.
//! \post *(pptr() - 1) is \a c.
//! \returns traits_type::eof() if a write error occurrs. Otherwise
//! returns traits_type::not_eof(c).
//!
virtual int_type overflow(int c);
//!
//! \brief Flushes the output buffer to disk.
//!
//! Synchronizes the systembuf buffers with the contents of the file
//! associated to this object through the native file handle. The
//! output buffer is flushed to disk and cleared to leave new room
//! for more data.
//!
//! \returns 0 on success, -1 if an error occurred.
//!
virtual int sync(void);
};
// ------------------------------------------------------------------------
// The "pipe" class.
// ------------------------------------------------------------------------
//!
//! \brief Simple RAII model for anonymous pipes.
//!
//! The pipe class is a simple RAII model for anonymous pipes. It
//! provides a portable constructor that allocates a new %pipe and creates
//! a pipe object that owns the two file handles associated to it: the
//! read end and the write end.
//!
//! These handles can be retrieved for modification according to
//! file_handle semantics. Optionally, their ownership can be transferred
//! to external \a file_handle objects which comes handy when the two
//! ends need to be used in different places (i.e. after a POSIX fork()
//! system call).
//!
//! Pipes can be copied following the same semantics as file handles.
//! In other words, copying a %pipe object invalidates the source one.
//!
//! \see file_handle
//!
class pipe
{
//!
//! \brief The %pipe's read end file handle.
//!
file_handle m_read_end;
//!
//! \brief The %pipe's write end file handle.
//!
file_handle m_write_end;
public:
//!
//! \brief Creates a new %pipe.
//!
//! The default pipe constructor allocates a new anonymous %pipe
//! and assigns its ownership to the created pipe object.
//!
//! \throw system_error If the anonymous %pipe creation fails.
//!
pipe(void);
//!
//! \brief Returns the %pipe's read end file handle.
//!
//! Obtains a reference to the %pipe's read end file handle. Care
//! should be taken to not duplicate the returned object if ownership
//! shall remain to the %pipe.
//!
//! Duplicating the returned object invalidates its corresponding file
//! handle in the %pipe.
//!
//! \return A reference to the %pipe's read end file handle.
//!
file_handle& rend(void);
//!
//! \brief Returns the %pipe's write end file handle.
//!
//! Obtains a reference to the %pipe's write end file handle. Care
//! should be taken to not duplicate the returned object if ownership
//! shall remain to the %pipe.
//!
//! Duplicating the returned object invalidates its corresponding file
//! handle in the %pipe.
//!
//! \return A reference to the %pipe's write end file handle.
//!
file_handle& wend(void);
};
// ------------------------------------------------------------------------
// The "pistream" class.
// ------------------------------------------------------------------------
//!
//! \brief Child process' output stream.
//!
//! The pistream class represents an output communication channel with the
//! child process. The child process writes data to this stream and the
//! parent process can read it through the pistream object. In other
//! words, from the child's point of view, the communication channel is an
//! output one, but from the parent's point of view it is an input one;
//! hence the confusing pistream name.
//!
//! pistream objects cannot be copied because they own the file handle
//! they use to communicate with the child and because they buffer data
//! that flows through the communication channel.
//!
//! A pistream object behaves as a std::istream stream in all senses.
//! The class is only provided because it must provide a method to let
//! the caller explicitly close the communication channel.
//!
//! \remark <b>Blocking remarks</b>: Functions that read data from this
//! stream can block if the associated file handle blocks during the read.
//! As this class is used to communicate with child processes through
//! anonymous pipes, the most typical blocking condition happens when the
//! child has no more data to send to the pipe's system buffer. When
//! this happens, the buffer eventually empties and the system blocks
//! until the writer generates some data.
//!
class pistream :
public std::istream, utils::noncopyable
{
//!
//! \brief The file handle managed by this stream.
//!
file_handle m_handle;
//!
//! \brief The systembuf object used to manage this stream's data.
//!
systembuf m_systembuf;
public:
//!
//! \brief Creates a new process' output stream.
//!
//! Given a file handle, this constructor creates a new pistream
//! object that owns the given file handle \a fh. Ownership of
//! \a fh is transferred to the created pistream object.
//!
//! \pre \a fh is valid.
//! \post \a fh is invalid.
//! \post The new pistream object owns \a fh.
//!
explicit pistream(file_handle& fh);
//!
//! \brief Closes the file handle managed by this stream.
//!
//! Explicitly closes the file handle managed by this stream. This
//! function can be used by the user to tell the child process it's
//! not willing to receive more data.
//!
void close(void);
//!
//! \brief Returns the file descriptor attached to this stream.
//!
file_handle& handle(void);
};
// ------------------------------------------------------------------------
// The "postream" class.
// ------------------------------------------------------------------------
//!
//! \brief Child process' input stream.
//!
//! The postream class represents an input communication channel with the
//! child process. The child process reads data from this stream and the
//! parent process can write to it through the postream object. In other
//! words, from the child's point of view, the communication channel is an
//! input one, but from the parent's point of view it is an output one;
//! hence the confusing postream name.
//!
//! postream objects cannot be copied because they own the file handle
//! they use to communicate with the child and because they buffer data
//! that flows through the communication channel.
//!
//! A postream object behaves as a std::ostream stream in all senses.
//! The class is only provided because it must provide a method to let
//! the caller explicitly close the communication channel.
//!
//! \remark <b>Blocking remarks</b>: Functions that write data to this
//! stream can block if the associated file handle blocks during the write.
//! As this class is used to communicate with child processes through
//! anonymous pipes, the most typical blocking condition happens when the
//! child is not processing the data in the pipe's system buffer. When
//! this happens, the buffer eventually fills up and the system blocks
//! until the reader consumes some data, leaving some new room.
//!
class postream :
public std::ostream, utils::noncopyable
{
//!
//! \brief The file handle managed by this stream.
//!
file_handle m_handle;
//!
//! \brief The systembuf object used to manage this stream's data.
//!
systembuf m_systembuf;
public:
//!
//! \brief Creates a new process' input stream.
//!
//! Given a file handle, this constructor creates a new postream
//! object that owns the given file handle \a fh. Ownership of
//! \a fh is transferred to the created postream object.
//!
//! \pre \a fh is valid.
//! \post \a fh is invalid.
//! \post The new postream object owns \a fh.
//!
explicit postream(file_handle& fh);
//!
//! \brief Closes the file handle managed by this stream.
//!
//! Explicitly closes the file handle managed by this stream. This
//! function can be used by the user to tell the child process there
//! is no more data to send.
//!
void close(void);
//!
//! \brief Returns the file descriptor attached to this stream.
//!
file_handle& handle(void);
};
// ------------------------------------------------------------------------
// The "unbuffered_istream" class.
// ------------------------------------------------------------------------
//!
//! \brief An unbuffered input stream.
//!
//! The unbuffered_istream class somewhat mimics the interface of
//! std::istream, but it provides unbuffered access to its attached
//! file descriptor. This is required in those situations where poll(2)
//! is needed, because buffering data will mangle the events reported by
//! this system call and break algorithms mysteriously on some platforms.
//!
class unbuffered_istream {
//!
//! \brief The file descriptor attached to this stream.
//!
file_handle m_fh;
//!
//! \brief Whether the stream is good or not.
//!
bool m_is_good;
public:
//!
//! \brief Constructs a new unbuffered input stream.
//!
//! Given a file handle, constructs a new unbuffered input stream to
//! handle it and takes ownership of that handle.
//!
unbuffered_istream(file_handle& fh);
//!
//! \brief Returns a reference to this stream's file handle.
//!
file_handle& get_fh(void);
//!
//! \brief Checks whether the stream is good or not for reading.
//!
bool good(void) const;
//!
//! \brief Reads unformatted data.
//!
//! Reads data from this stream onto the buffer specified and returns
//! the amount of data read. To detect errors, check for the stream's
//! status using the good method after a call to this function.
//!
size_t read(void*, size_t);
//!
//! \brief Closes the stream.
//!
void close(void);
};
// ------------------------------------------------------------------------
// Free functions.
// ------------------------------------------------------------------------
//!
//! \brief Unbuffered getline implementation.
//!
//! Reads a text line from the given stream without buffering any data.
//! This is inefficient but is the only way to safely use poll(2)...
//!
unbuffered_istream& getline(unbuffered_istream&, std::string&);
} // namespace io
} // namespace atf
#endif // !defined(_ATF_CXX_IO_HPP_)

View File

@ -1,145 +0,0 @@
//
// Automated Testing Framework (atf)
//
// Copyright (c) 2007, 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
// 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_MACROS_HPP_)
#define _ATF_CXX_MACROS_HPP_
#include <sstream>
#include <stdexcept>
#include <vector>
#include <atf-c++/tests.hpp>
#define ATF_TEST_CASE(name) \
class atfu_tc_ ## name : public atf::tests::tc { \
void head(void); \
void body(void) const; \
public: \
atfu_tc_ ## name(void) : atf::tests::tc(#name) {} \
};
#define ATF_TEST_CASE_WITH_CLEANUP(name) \
class atfu_tc_ ## name : public atf::tests::tc { \
void head(void); \
void body(void) const; \
void cleanup(void) const; \
public: \
atfu_tc_ ## name(void) : atf::tests::tc(#name) {} \
};
#define ATF_TEST_CASE_NAME(name) atfu_tc_ ## name
#define ATF_TEST_CASE_HEAD(name) \
void \
atfu_tc_ ## name::head(void)
#define ATF_TEST_CASE_BODY(name) \
void \
atfu_tc_ ## name::body(void) \
const
#define ATF_TEST_CASE_CLEANUP(name) \
void \
atfu_tc_ ## name::cleanup(void) \
const
#define ATF_FAIL(reason) atf::tests::tc::fail(reason)
#define ATF_SKIP(reason) atf::tests::tc::skip(reason)
#define ATF_PASS() atf::tests::tc::pass()
#define ATF_CHECK(x) \
do { \
if (!(x)) { \
std::ostringstream atfu_ss; \
atfu_ss << "Line " << __LINE__ << ": " << #x << " not met"; \
atf::tests::tc::fail(atfu_ss.str()); \
} \
} while (false)
#define ATF_CHECK_EQUAL(x, y) \
do { \
if ((x) != (y)) { \
std::ostringstream atfu_ss; \
atfu_ss << "Line " << __LINE__ << ": " << #x << " != " << #y \
<< " (" << (x) << " != " << (y) << ")"; \
atf::tests::tc::fail(atfu_ss.str()); \
} \
} while (false)
#define ATF_CHECK_THROW(x, e) \
do { \
try { \
x; \
std::ostringstream atfu_ss; \
atfu_ss << "Line " << __LINE__ << ": " #x " did not throw " \
#e " as expected"; \
atf::tests::tc::fail(atfu_ss.str()); \
} catch (const e& atfu_eo) { \
} catch (const std::exception& atfu_e) { \
std::ostringstream atfu_ss; \
atfu_ss << "Line " << __LINE__ << ": " #x " threw an " \
"unexpected error (not " #e "): " << atfu_e.what(); \
atf::tests::tc::fail(atfu_ss.str()); \
} catch (...) { \
std::ostringstream atfu_ss; \
atfu_ss << "Line " << __LINE__ << ": " #x " threw an " \
"unexpected error (not " #e ")"; \
atf::tests::tc::fail(atfu_ss.str()); \
} \
} while (false)
#define ATF_INIT_TEST_CASES(tcs) \
namespace atf { \
namespace tests { \
int run_tp(int, char* const*, \
void (*)(std::vector< atf::tests::tc * >&)); \
} \
} \
\
static void atfu_init_tcs(std::vector< atf::tests::tc * >&); \
\
int \
main(int argc, char* const* argv) \
{ \
return atf::tests::run_tp(argc, argv, atfu_init_tcs); \
} \
\
static \
void \
atfu_init_tcs(std::vector< atf::tests::tc * >& tcs)
#define ATF_ADD_TEST_CASE(tcs, tcname) \
do { \
atf::tests::tc* tcptr = new atfu_tc_ ## tcname(); \
(tcs).push_back(tcptr); \
} while (0);
#endif // !defined(_ATF_CXX_MACROS_HPP_)

View File

@ -1,149 +0,0 @@
//
// Automated Testing Framework (atf)
//
// Copyright (c) 2007, 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
// 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 "atf-c++/parser.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.";
}
}
// ------------------------------------------------------------------------
// 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 {
std::ostringstream oss;
for (const_iterator iter = begin(); iter != end(); iter++) {
oss << (*iter).first << ": " << (*iter).second
<< std::endl;
}
m_msg = oss.str();
return m_msg.c_str();
} catch (...) {
return "Could not format messages for parsing errors.";
}
}
// ------------------------------------------------------------------------
// 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;
}

View File

@ -1,524 +0,0 @@
//
// Automated Testing Framework (atf)
//
// Copyright (c) 2007, 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
// 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 <map>
#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();
};
// ------------------------------------------------------------------------
// 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 "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.unget();
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.unget();
} else if (ch == '\n') {
done = true;
if (text.empty())
t = token(m_lineno, m_nl_type, "<<NEWLINE>>");
else
m_is.unget();
} 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&);
};
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;
}
} // namespace parser
} // namespace atf
#endif // !defined(_ATF_CXX_PARSER_HPP_)

View File

@ -1,37 +0,0 @@
//
// Automated Testing Framework (atf)
//
// Copyright (c) 2007, 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
// 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_SANITY_HPP_)
#define _ATF_CXX_SANITY_HPP_
extern "C" {
#include <atf-c/sanity.h>
}
#endif // !defined(_ATF_CXX_SANITY_HPP_)

View File

@ -1,74 +0,0 @@
//
// Automated Testing Framework (atf)
//
// Copyright (c) 2007, 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
// 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 "atf-c++/exceptions.hpp"
#include "atf-c++/signals.hpp"
namespace impl = atf::signals;
#define IMPL_NAME "atf::signals"
const int impl::last_signo = atf_signals_last_signo;
// ------------------------------------------------------------------------
// The "signal_holder" class.
// ------------------------------------------------------------------------
impl::signal_holder::signal_holder(int signo)
{
atf_error_t err = atf_signal_holder_init(&m_sh, signo);
if (atf_is_error(err))
throw_atf_error(err);
}
impl::signal_holder::~signal_holder(void)
{
atf_signal_holder_fini(&m_sh);
}
void
impl::signal_holder::process(void)
{
atf_signal_holder_process(&m_sh);
}
// ------------------------------------------------------------------------
// The "signal_programmer" class.
// ------------------------------------------------------------------------
impl::signal_programmer::signal_programmer(int signo, handler h)
{
atf_error_t err = atf_signal_programmer_init(&m_sp, signo, h);
if (atf_is_error(err))
throw_atf_error(err);
}
impl::signal_programmer::~signal_programmer(void)
{
atf_signal_programmer_fini(&m_sp);
}

View File

@ -1,84 +0,0 @@
//
// Automated Testing Framework (atf)
//
// Copyright (c) 2007, 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
// 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_SIGNALS_HPP_)
#define _ATF_CXX_SIGNALS_HPP_
extern "C" {
#include <signal.h>
}
#include <map>
extern "C" {
#include "atf-c/signals.h"
}
namespace atf {
namespace signals {
extern const int last_signo;
typedef atf_signal_handler_t handler;
// ------------------------------------------------------------------------
// The "signal_holder" class.
// ------------------------------------------------------------------------
//
// A RAII model to hold a signal while the object is alive.
//
class signal_holder {
atf_signal_holder_t m_sh;
public:
signal_holder(int);
~signal_holder(void);
void process(void);
};
// ------------------------------------------------------------------------
// The "signal_programmer" class.
// ------------------------------------------------------------------------
//
// A RAII model to program a signal while the object is alive.
//
class signal_programmer {
atf_signal_programmer_t m_sp;
public:
signal_programmer(int, handler);
~signal_programmer(void);
};
} // namespace signals
} // namespace atf
#endif // !defined(_ATF_CXX_SIGNALS_HPP_)

View File

@ -1,699 +0,0 @@
//
// Automated Testing Framework (atf)
//
// Copyright (c) 2007, 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
// 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/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <signal.h>
#include <unistd.h>
}
#include <algorithm>
#include <cctype>
#include <cerrno>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <iostream>
#include <map>
#include <memory>
#include <sstream>
#include <stdexcept>
#include <vector>
extern "C" {
#include "atf-c/object.h"
}
#include "atf-c++/application.hpp"
#include "atf-c++/config.hpp"
#include "atf-c++/env.hpp"
#include "atf-c++/exceptions.hpp"
#include "atf-c++/expand.hpp"
#include "atf-c++/formats.hpp"
#include "atf-c++/fs.hpp"
#include "atf-c++/io.hpp"
#include "atf-c++/sanity.hpp"
#include "atf-c++/signals.hpp"
#include "atf-c++/tests.hpp"
#include "atf-c++/text.hpp"
#include "atf-c++/ui.hpp"
#include "atf-c++/user.hpp"
namespace impl = atf::tests;
#define IMPL_NAME "atf::tests"
// ------------------------------------------------------------------------
// Auxiliary stuff for the timeout implementation.
// ------------------------------------------------------------------------
namespace timeout {
static pid_t current_body = 0;
static bool killed = false;
void
sigalrm_handler(int signo)
{
PRE(signo == SIGALRM);
if (current_body != 0) {
::killpg(current_body, SIGTERM);
killed = true;
}
}
} // namespace timeout
// ------------------------------------------------------------------------
// The "tcr" class.
// ------------------------------------------------------------------------
const impl::tcr::state impl::tcr::passed_state = atf_tcr_passed_state;
const impl::tcr::state impl::tcr::failed_state = atf_tcr_failed_state;
const impl::tcr::state impl::tcr::skipped_state = atf_tcr_skipped_state;
impl::tcr::tcr(state s)
{
PRE(s == passed_state);
atf_error_t err = atf_tcr_init(&m_tcr, s);
if (atf_is_error(err))
throw_atf_error(err);
}
impl::tcr::tcr(state s, const std::string& r)
{
PRE(s == failed_state || s == skipped_state);
PRE(!r.empty());
atf_error_t err = atf_tcr_init_reason_fmt(&m_tcr, s, "%s", r.c_str());
if (atf_is_error(err))
throw_atf_error(err);
}
impl::tcr::tcr(const tcr& o)
{
if (o.get_state() == passed_state)
atf_tcr_init(&m_tcr, o.get_state());
else
atf_tcr_init_reason_fmt(&m_tcr, o.get_state(), "%s",
o.get_reason().c_str());
}
impl::tcr::~tcr(void)
{
atf_tcr_fini(&m_tcr);
}
impl::tcr::state
impl::tcr::get_state(void)
const
{
return atf_tcr_get_state(&m_tcr);
}
const std::string
impl::tcr::get_reason(void)
const
{
const atf_dynstr_t* r = atf_tcr_get_reason(&m_tcr);
return atf_dynstr_cstring(r);
}
impl::tcr&
impl::tcr::operator=(const tcr& o)
{
if (this != &o) {
atf_tcr_fini(&m_tcr);
if (o.get_state() == passed_state)
atf_tcr_init(&m_tcr, o.get_state());
else
atf_tcr_init_reason_fmt(&m_tcr, o.get_state(), "%s",
o.get_reason().c_str());
}
return *this;
}
// ------------------------------------------------------------------------
// The "tc" class.
// ------------------------------------------------------------------------
static std::map< atf_tc_t*, impl::tc* > wraps;
static std::map< const atf_tc_t*, const impl::tc* > cwraps;
void
impl::tc::wrap_head(atf_tc_t *tc)
{
std::map< atf_tc_t*, impl::tc* >::iterator iter = wraps.find(tc);
INV(iter != wraps.end());
(*iter).second->head();
}
void
impl::tc::wrap_body(const atf_tc_t *tc)
{
std::map< const atf_tc_t*, const impl::tc* >::const_iterator iter =
cwraps.find(tc);
INV(iter != cwraps.end());
(*iter).second->body();
}
void
impl::tc::wrap_cleanup(const atf_tc_t *tc)
{
std::map< const atf_tc_t*, const impl::tc* >::const_iterator iter =
cwraps.find(tc);
INV(iter != cwraps.end());
(*iter).second->cleanup();
}
impl::tc::tc(const std::string& ident) :
m_ident(ident)
{
}
impl::tc::~tc(void)
{
cwraps.erase(&m_tc);
wraps.erase(&m_tc);
atf_tc_fini(&m_tc);
atf_map_fini(&m_config);
}
void
impl::tc::init(const vars_map& config)
{
atf_error_t err;
err = atf_map_init(&m_config);
if (atf_is_error(err))
throw_atf_error(err);
for (vars_map::const_iterator iter = config.begin();
iter != config.end(); iter++) {
const char *var = (*iter).first.c_str();
const char *val = (*iter).second.c_str();
err = atf_map_insert(&m_config, var, ::strdup(val), true);
if (atf_is_error(err)) {
atf_map_fini(&m_config);
throw_atf_error(err);
}
}
wraps[&m_tc] = this;
cwraps[&m_tc] = this;
err = atf_tc_init(&m_tc, m_ident.c_str(), wrap_head, wrap_body,
wrap_cleanup, &m_config);
if (atf_is_error(err)) {
atf_map_fini(&m_config);
throw_atf_error(err);
}
}
bool
impl::tc::has_config_var(const std::string& var)
const
{
return atf_tc_has_config_var(&m_tc, var.c_str());
}
bool
impl::tc::has_md_var(const std::string& var)
const
{
return atf_tc_has_md_var(&m_tc, var.c_str());
}
const std::string
impl::tc::get_config_var(const std::string& var)
const
{
return atf_tc_get_config_var(&m_tc, var.c_str());
}
const std::string
impl::tc::get_config_var(const std::string& var, const std::string& defval)
const
{
return atf_tc_get_config_var_wd(&m_tc, var.c_str(), defval.c_str());
}
const std::string
impl::tc::get_md_var(const std::string& var)
const
{
return atf_tc_get_md_var(&m_tc, var.c_str());
}
void
impl::tc::set_md_var(const std::string& var, const std::string& val)
{
atf_error_t err = atf_tc_set_md_var(&m_tc, var.c_str(), val.c_str());
if (atf_is_error(err))
throw_atf_error(err);
}
impl::tcr
impl::tc::run(const fs::path& workdirbase)
const
{
atf_tcr_t tcrc;
tcr tcrr(tcr::failed_state, "UNINITIALIZED");
atf_error_t err = atf_tc_run(&m_tc, &tcrc, workdirbase.c_path());
if (atf_is_error(err))
throw_atf_error(err);
if (atf_tcr_has_reason(&tcrc)) {
const atf_dynstr_t* r = atf_tcr_get_reason(&tcrc);
tcrr = tcr(atf_tcr_get_state(&tcrc), atf_dynstr_cstring(r));
} else {
tcrr = tcr(atf_tcr_get_state(&tcrc));
}
atf_tcr_fini(&tcrc);
return tcrr;
}
void
impl::tc::cleanup(void)
const
{
}
void
impl::tc::require_prog(const std::string& prog)
const
{
PRE(!prog.empty());
fs::path p(prog);
if (p.is_absolute()) {
if (!fs::is_executable(p))
skip("The required program " + prog + " could not be found");
} else {
INV(p.branch_path() == fs::path("."));
if (!fs::have_prog_in_path(prog))
skip("The required program " + prog + " could not be found in "
"the PATH");
}
}
void
impl::tc::pass(void)
{
atf_tc_pass();
}
void
impl::tc::fail(const std::string& reason)
{
atf_tc_fail("%s", reason.c_str());
}
void
impl::tc::skip(const std::string& reason)
{
atf_tc_skip("%s", reason.c_str());
}
// ------------------------------------------------------------------------
// The "tp" class.
// ------------------------------------------------------------------------
class tp : public atf::application::app {
public:
typedef std::vector< impl::tc * > tc_vector;
private:
static const char* m_description;
bool m_lflag;
int m_results_fd;
std::auto_ptr< std::ostream > m_results_os;
atf::fs::path m_srcdir;
atf::fs::path m_workdir;
std::vector< std::string > m_tcnames;
atf::tests::vars_map m_vars;
std::string specific_args(void) const;
options_set specific_options(void) const;
void process_option(int, const char*);
void (*m_add_tcs)(tc_vector&);
tc_vector m_tcs;
void parse_vflag(const std::string&);
void handle_srcdir(void);
tc_vector init_tcs(void);
static tc_vector filter_tcs(tc_vector,
const std::vector< std::string >&);
std::ostream& results_stream(void);
int list_tcs(void);
int run_tcs(void);
public:
tp(void (*)(tc_vector&));
~tp(void);
int main(void);
};
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)"),
m_lflag(false),
m_results_fd(STDOUT_FILENO),
m_srcdir("."),
m_workdir(atf::config::get("atf_workdir")),
m_add_tcs(add_tcs)
{
}
tp::~tp(void)
{
for (tc_vector::iterator iter = m_tcs.begin();
iter != m_tcs.end(); iter++) {
impl::tc* tc = *iter;
delete tc;
}
}
std::string
tp::specific_args(void)
const
{
return "[test_case1 [.. test_caseN]]";
}
tp::options_set
tp::specific_options(void)
const
{
using atf::application::option;
options_set opts;
opts.insert(option('l', "", "List test cases and their purpose"));
opts.insert(option('r', "fd", "The file descriptor to which the test "
"program will send the results of the "
"test cases"));
opts.insert(option('s', "srcdir", "Directory where the test's data "
"files are located"));
opts.insert(option('v', "var=value", "Sets the configuration variable "
"`var' to `value'"));
opts.insert(option('w', "workdir", "Directory where the test's "
"temporary files are located"));
return opts;
}
void
tp::process_option(int ch, const char* arg)
{
switch (ch) {
case 'l':
m_lflag = true;
break;
case 'r':
{
std::istringstream ss(arg);
ss >> m_results_fd;
}
break;
case 's':
m_srcdir = atf::fs::path(arg);
break;
case 'v':
parse_vflag(arg);
break;
case 'w':
m_workdir = atf::fs::path(arg);
break;
default:
UNREACHABLE;
}
}
void
tp::parse_vflag(const std::string& str)
{
if (str.empty())
throw std::runtime_error("-v requires a non-empty argument");
std::vector< std::string > ws = atf::text::split(str, "=");
if (ws.size() == 1 && str[str.length() - 1] == '=') {
m_vars[ws[0]] = "";
} else {
if (ws.size() != 2)
throw std::runtime_error("-v requires an argument of the form "
"var=value");
m_vars[ws[0]] = ws[1];
}
}
void
tp::handle_srcdir(void)
{
if (!atf::fs::exists(m_srcdir / m_prog_name))
throw std::runtime_error("Cannot find the test program in the "
"source directory `" + m_srcdir.str() + "'");
if (!m_srcdir.is_absolute())
m_srcdir = m_srcdir.to_absolute();
m_vars["srcdir"] = m_srcdir.str();
}
tp::tc_vector
tp::init_tcs(void)
{
m_add_tcs(m_tcs);
for (tc_vector::iterator iter = m_tcs.begin();
iter != m_tcs.end(); iter++) {
impl::tc* tc = *iter;
tc->init(m_vars);
}
return m_tcs;
}
//
// An auxiliary unary predicate that compares the given test case's
// identifier to the identifier stored in it.
//
class tc_equal_to_ident {
const std::string& m_ident;
public:
tc_equal_to_ident(const std::string& i) :
m_ident(i)
{
}
bool operator()(const impl::tc* tc)
{
return tc->get_md_var("ident") == m_ident;
}
};
tp::tc_vector
tp::filter_tcs(tc_vector tcs, const std::vector< std::string >& tcnames)
{
tc_vector tcso;
if (tcnames.empty()) {
// Special case: added for efficiency because this is the most
// typical situation.
tcso = tcs;
} else {
// Collect all the test cases' identifiers.
std::vector< std::string > ids;
for (tc_vector::iterator iter = tcs.begin();
iter != tcs.end(); iter++) {
impl::tc* tc = *iter;
ids.push_back(tc->get_md_var("ident"));
}
// Iterate over all names provided by the user and, for each one,
// expand it as if it were a glob pattern. Collect all expansions.
std::vector< std::string > exps;
for (std::vector< std::string >::const_iterator iter = tcnames.begin();
iter != tcnames.end(); iter++) {
const std::string& glob = *iter;
std::vector< std::string > ms =
atf::expand::expand_glob(glob, ids);
if (ms.empty())
throw std::runtime_error("Unknown test case `" + glob + "'");
exps.insert(exps.end(), ms.begin(), ms.end());
}
// For each expansion, locate its corresponding test case and add
// it to the output set.
for (std::vector< std::string >::const_iterator iter = exps.begin();
iter != exps.end(); iter++) {
const std::string& name = *iter;
tc_vector::iterator tciter =
std::find_if(tcs.begin(), tcs.end(), tc_equal_to_ident(name));
INV(tciter != tcs.end());
tcso.push_back(*tciter);
}
}
return tcso;
}
int
tp::list_tcs(void)
{
tc_vector tcs = filter_tcs(init_tcs(), m_tcnames);
std::string::size_type maxlen = 0;
for (tc_vector::const_iterator iter = tcs.begin();
iter != tcs.end(); iter++) {
const impl::tc* tc = *iter;
if (maxlen < tc->get_md_var("ident").length())
maxlen = tc->get_md_var("ident").length();
}
for (tc_vector::const_iterator iter = tcs.begin();
iter != tcs.end(); iter++) {
const impl::tc* tc = *iter;
std::cout << atf::ui::format_text_with_tag(tc->get_md_var("descr"),
tc->get_md_var("ident"),
false, maxlen + 4)
<< std::endl;
}
return EXIT_SUCCESS;
}
std::ostream&
tp::results_stream(void)
{
if (m_results_fd == STDOUT_FILENO)
return std::cout;
else if (m_results_fd == STDERR_FILENO)
return std::cerr;
else
return *m_results_os;
}
int
tp::run_tcs(void)
{
tc_vector tcs = filter_tcs(init_tcs(), m_tcnames);
if (!atf::fs::exists(m_workdir))
throw std::runtime_error("Cannot find the work directory `" +
m_workdir.str() + "'");
int errcode = EXIT_SUCCESS;
atf::signals::signal_holder sighup(SIGHUP);
atf::signals::signal_holder sigint(SIGINT);
atf::signals::signal_holder sigterm(SIGTERM);
atf::formats::atf_tcs_writer w(results_stream(), std::cout, std::cerr,
tcs.size());
for (tc_vector::iterator iter = tcs.begin();
iter != tcs.end(); iter++) {
impl::tc* tc = *iter;
w.start_tc(tc->get_md_var("ident"));
impl::tcr tcr = tc->run(m_workdir);
w.end_tc(tcr);
sighup.process();
sigint.process();
sigterm.process();
if (tcr.get_state() == impl::tcr::failed_state)
errcode = EXIT_FAILURE;
}
return errcode;
}
int
tp::main(void)
{
int errcode;
handle_srcdir();
for (int i = 0; i < m_argc; i++)
m_tcnames.push_back(m_argv[i]);
if (m_lflag)
errcode = list_tcs();
else {
if (m_results_fd != STDOUT_FILENO && m_results_fd != STDERR_FILENO) {
atf::io::file_handle fh(m_results_fd);
m_results_os =
std::auto_ptr< std::ostream >(new atf::io::postream(fh));
}
errcode = run_tcs();
}
return errcode;
}
namespace atf {
namespace tests {
int run_tp(int, char* const*, void (*)(tp::tc_vector&));
}
}
int
impl::run_tp(int argc, char* const* argv, void (*add_tcs)(tp::tc_vector&))
{
return tp(add_tcs).run(argc, argv);
}

View File

@ -1,134 +0,0 @@
//
// Automated Testing Framework (atf)
//
// Copyright (c) 2007, 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
// 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_TESTS_HPP_)
#define _ATF_CXX_TESTS_HPP_
#include <map>
#include <string>
extern "C" {
#include <atf-c/tc.h>
#include <atf-c/tcr.h>
}
#include <atf-c++/fs.hpp>
#include <atf-c++/utils.hpp>
namespace atf {
namespace tests {
// ------------------------------------------------------------------------
// The "vars_map" class.
// ------------------------------------------------------------------------
typedef std::map< std::string, std::string > vars_map;
// ------------------------------------------------------------------------
// The "tcr" class.
// ------------------------------------------------------------------------
//!
//! \brief Holds the results of a test case's execution.
//!
//! The tcr class holds the information that describes the results of a
//! test case's execution. This is composed of an exit code and a reason
//! for that exit code.
//!
//! TODO: Complete documentation for this class. Not done yet because it
//! is worth to investigate if this class could be rewritten as several
//! different classes, one for each status.
//!
class tcr {
atf_tcr_t m_tcr;
public:
typedef atf_tcr_state_t state;
static const state passed_state;
static const state failed_state;
static const state skipped_state;
tcr(state);
tcr(state, const std::string&);
tcr(const tcr&);
~tcr(void);
state get_state(void) const;
const std::string get_reason(void) const;
tcr& operator=(const tcr&);
};
// ------------------------------------------------------------------------
// The "tc" class.
// ------------------------------------------------------------------------
class tc : public atf::utils::noncopyable {
std::string m_ident;
atf_map_t m_config;
atf_tc_t m_tc;
protected:
virtual void head(void) = 0;
virtual void body(void) const = 0;
virtual void cleanup(void) const;
void require_prog(const std::string&) const;
static void wrap_head(atf_tc_t *);
static void wrap_body(const atf_tc_t *);
static void wrap_cleanup(const atf_tc_t *);
public:
tc(const std::string&);
virtual ~tc(void);
void init(const vars_map&);
const std::string get_config_var(const std::string&) const;
const std::string get_config_var(const std::string&, const std::string&)
const;
const std::string get_md_var(const std::string&) const;
bool has_config_var(const std::string&) const;
bool has_md_var(const std::string&) const;
void set_md_var(const std::string&, const std::string&);
tcr run(const fs::path&) const;
/* To be called from the child process only. */
static void pass(void);
static void fail(const std::string&);
static void skip(const std::string&);
};
} // namespace tests
} // namespace atf
#endif // !defined(_ATF_CXX_TESTS_HPP_)

View File

@ -1,94 +0,0 @@
//
// Automated Testing Framework (atf)
//
// Copyright (c) 2007, 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
// 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 <cctype>
extern "C" {
#include "atf-c/text.h"
}
#include "atf-c++/exceptions.hpp"
#include "atf-c++/text.hpp"
namespace impl = atf::text;
#define IMPL_NAME "atf::text"
std::string
impl::to_lower(const std::string& str)
{
std::string lc;
for (std::string::const_iterator iter = str.begin(); iter != str.end();
iter++)
lc += std::tolower(*iter);
return lc;
}
std::vector< std::string >
impl::split(const std::string& str, const std::string& delim)
{
std::vector< std::string > words;
std::string::size_type pos = 0, newpos = 0;
while (pos < str.length() && newpos != std::string::npos) {
newpos = str.find(delim, pos);
if (newpos != pos)
words.push_back(str.substr(pos, newpos - pos));
pos = newpos + delim.length();
}
return words;
}
std::string
impl::trim(const std::string& str)
{
std::string::size_type pos1 = str.find_first_not_of(" \t");
std::string::size_type pos2 = str.find_last_not_of(" \t");
if (pos1 == std::string::npos && pos2 == std::string::npos)
return "";
else if (pos1 == std::string::npos)
return str.substr(0, str.length() - pos2);
else if (pos2 == std::string::npos)
return str.substr(pos1);
else
return str.substr(pos1, pos2 - pos1 + 1);
}
bool
impl::to_bool(const std::string& str)
{
bool b;
atf_error_t err = atf_text_to_bool(str.c_str(), &b);
if (atf_is_error(err))
throw_atf_error(err);
return b;
}

View File

@ -1,131 +0,0 @@
//
// Automated Testing Framework (atf)
//
// Copyright (c) 2007, 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
// 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_TEXT_HPP_)
#define _ATF_CXX_TEXT_HPP_
#include <sstream>
#include <stdexcept>
#include <string>
#include <vector>
namespace atf {
namespace text {
//!
//! \brief Joins multiple words into a string.
//!
//! Joins a list of words into a string, separating them using the provided
//! separator. Empty words are not omitted.
//!
template< class T >
std::string
join(const T& words, const std::string& separator)
{
std::string str;
typename T::const_iterator iter = words.begin();
bool done = iter == words.end();
while (!done) {
str += *iter;
iter++;
if (iter != words.end())
str += separator;
else
done = true;
}
return str;
}
//!
//! \brief Splits a string into words.
//!
//! Splits the given string into multiple words, all separated by the
//! given delimiter. Multiple occurrences of the same delimiter are
//! not condensed so that rejoining the words later on using the same
//! delimiter results in the original string.
//!
std::vector< std::string > split(const std::string&, const std::string&);
//!
//! \brief Removes whitespace from the beginning and end of a string.
//!
std::string trim(const std::string&);
//!
//! \brief Converts a string to a boolean value.
//!
bool to_bool(const std::string&);
//!
//! \brief Changes the case of a string to lowercase.
//!
//! Returns a new string that is a lowercased version of the original
//! one.
//!
std::string to_lower(const std::string&);
//!
//! \brief Converts the given object to a string.
//!
//! Returns a string with the representation of the given object. There
//! must exist an operator<< method for that object.
//!
template< class T >
std::string
to_string(const T& ob)
{
std::ostringstream ss;
ss << ob;
return ss.str();
}
//!
//! \brief Converts the given string to another type.
//!
//! Attempts to convert the given string to the requested type. Throws
//! an exception if the conversion failed.
//!
template< class T >
T
to_type(const std::string& str)
{
std::istringstream ss(str);
T value;
ss >> value;
if (!ss.eof() || (!ss.eof() && !ss.good()))
throw std::runtime_error("Cannot convert string to requested type");
return value;
}
} // namespace text
} // namespace atf
#endif // !defined(_ATF_CXX_TEXT_HPP_)

View File

@ -1,94 +0,0 @@
//
// Automated Testing Framework (atf)
//
// Copyright (c) 2007, 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
// 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>
extern "C" {
#include "atf-c/dynstr.h"
#include "atf-c/ui.h"
}
#include "atf-c++/env.hpp"
#include "atf-c++/exceptions.hpp"
#include "atf-c++/text.hpp"
#include "atf-c++/sanity.hpp"
#include "atf-c++/ui.hpp"
namespace impl = atf::ui;
#define IMPL_NAME "atf::ui"
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)
{
atf_dynstr_t dest;
atf_error_t err;
err = atf_dynstr_init(&dest);
if (atf_is_error(err))
throw_atf_error(err);
try {
err = atf_ui_format_fmt(&dest, tag.c_str(), repeat, col, "%s",
text.c_str());
if (atf_is_error(err))
throw_atf_error(err);
std::string formatted(atf_dynstr_cstring(&dest));
atf_dynstr_fini(&dest);
return formatted;
} catch (...) {
atf_dynstr_fini(&dest);
throw;
}
}
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, 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
// 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,62 +0,0 @@
//
// Automated Testing Framework (atf)
//
// Copyright (c) 2007, 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
// 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 "atf-c/user.h"
}
#include "atf-c++/sanity.hpp"
#include "atf-c++/user.hpp"
namespace impl = atf::user;
#define IMPL_NAME "atf::user"
uid_t
impl::euid(void)
{
return atf_user_euid();
}
bool
impl::is_member_of_group(gid_t gid)
{
return atf_user_is_member_of_group(gid);
}
bool
impl::is_root(void)
{
return atf_user_is_root();
}
bool
impl::is_unprivileged(void)
{
return atf_user_is_unprivileged();
}

View File

@ -1,48 +0,0 @@
//
// Automated Testing Framework (atf)
//
// Copyright (c) 2007, 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
// 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_USER_HPP_)
#define _ATF_CXX_USER_HPP_
extern "C" {
#include <sys/types.h>
}
namespace atf {
namespace user {
uid_t euid(void);
bool is_member_of_group(gid_t);
bool is_root(void);
bool is_unprivileged(void);
} // namespace user
} // namespace atf
#endif // !defined(_ATF_CXX_USER_HPP_)

View File

@ -1,148 +0,0 @@
//
// Automated Testing Framework (atf)
//
// Copyright (c) 2007, 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
// 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_UTILS_HPP_)
#define _ATF_CXX_UTILS_HPP_
#include <cstddef>
namespace atf {
namespace utils {
// ------------------------------------------------------------------------
// The "auto_array" class.
// ------------------------------------------------------------------------
template< class T >
class auto_array {
T* m_ptr;
public:
auto_array(T* = NULL) throw();
auto_array(auto_array< T >&) throw();
~auto_array(void) throw();
T* get(void) throw();
T* release(void) throw();
void reset(T* = NULL) throw();
auto_array< T >& operator=(auto_array< T >&) throw();
T& operator[](int) throw();
};
template< class T >
auto_array< T >::auto_array(T* ptr)
throw() :
m_ptr(ptr)
{
}
template< class T >
auto_array< T >::auto_array(auto_array< T >& ptr)
throw() :
m_ptr(ptr.release())
{
}
template< class T >
auto_array< T >::~auto_array(void)
throw()
{
if (m_ptr != NULL)
delete [] m_ptr;
}
template< class T >
T*
auto_array< T >::get(void)
throw()
{
return m_ptr;
}
template< class T >
T*
auto_array< T >::release(void)
throw()
{
T* ptr = m_ptr;
m_ptr = NULL;
return ptr;
}
template< class T >
void
auto_array< T >::reset(T* ptr)
throw()
{
if (m_ptr != NULL)
delete [] m_ptr;
m_ptr = ptr;
}
template< class T >
auto_array< T >&
auto_array< T >::operator=(auto_array< T >& ptr)
throw()
{
reset(ptr.release());
return *this;
}
template< class T >
T&
auto_array< T >::operator[](int pos)
throw()
{
return m_ptr[pos];
}
// ------------------------------------------------------------------------
// 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 utils
} // namespace atf
#endif // !defined(_ATF_CXX_UTILS_HPP_)

35
dist/atf/atf-c.h vendored
View File

@ -1,35 +0,0 @@
/*
* 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
* 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_C_H)
#define ATF_C_H
#include <atf-c/macros.h>
#endif /* !defined(ATF_C_H) */

View File

@ -1,269 +0,0 @@
.\"
.\" 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
.\" 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.
.\"
.Dd April 26, 2008
.Dt ATF-C-API 3
.Os
.Sh NAME
.Nm ATF_CHECK ,
.Nm ATF_CHECK_EQUAL ,
.Nm ATF_TC ,
.Nm ATF_TC_BODY ,
.Nm ATF_TC_BODY_NAME ,
.Nm ATF_TC_CLEANUP ,
.Nm ATF_TC_CLEANUP_NAME ,
.Nm ATF_TC_HEAD ,
.Nm ATF_TC_HEAD_NAME ,
.Nm ATF_TC_NAME ,
.Nm ATF_TC_WITH_CLEANUP ,
.Nm ATF_TP_ADD_TC ,
.Nm ATF_TP_ADD_TCS ,
.Nm atf_no_error ,
.Nm atf_tc_fail ,
.Nm atf_tc_pass ,
.Nm atf_tc_skip
.Nd C API to write ATF-based test programs
.Sh SYNOPSIS
.In atf-c.h
.Fn ATF_CHECK "expression"
.Fn ATF_CHECK_EQUAL "expression_1" "expression_2"
.Fn ATF_TC "name"
.Fn ATF_TC_BODY "name"
.Fn ATF_TC_BODY_NAME "name"
.Fn ATF_TC_CLEANUP "name"
.Fn ATF_TC_CLEANUP_NAME "name"
.Fn ATF_TC_HEAD "name"
.Fn ATF_TC_HEAD_NAME "name"
.Fn ATF_TC_NAME "name"
.Fn ATF_TC_WITH_CLEANUP "name"
.Fn ATF_TP_ADD_TC "tp_name"
.Fn ATF_TP_ADD_TCS "tp_name" "tc_name"
.Fn atf_no_error
.Fn atf_tc_fail "reason"
.Fn atf_tc_pass
.Fn atf_tc_skip "reason"
.Sh DESCRIPTION
The ATF
.Pp
C-based test programs always follow this template:
.Bd -literal -offset indent
.Ns ... C-specific includes go here ...
#include <atf-c.h>
ATF_TC(tc1);
ATF_TC_HEAD(tc1)
{
... first test case's header ...
}
ATF_TC_BODY(tc1)
{
... first test case's body ...
}
ATF_TC_WITH_CLEANUP(tc2);
ATF_TC_HEAD(tc2)
{
... second test case's header ...
}
ATF_TC_BODY(tc2)
{
... second test case's body ...
}
ATF_TC_CLEANUP(tc2)
{
... second test case's cleanup ...
}
.Ns ... additional test cases ...
ATF_TP_ADD_TCS(tp, tcs)
{
ATF_TP_ADD_TC(tcs, tc1)
ATF_TP_ADD_TC(tcs, tc2)
... add additional test cases ...
return atf_no_error();
}
.Ed
.Ss Definition of test cases
Test cases have an identifier and are composed of three different parts:
the header, the body and an optional cleanup routine, all of which are
described in
.Xr atf-test-case 8 .
To define test cases, one can use the
.Fn ATF_TC
or the
.Fn ATF_TC_WITH_CLEANUP
macros, which take a single parameter specifiying the test case's name.
The former does not allow the specification of a cleanup routine for the
test case while the latter does.
It is important to note that these
.Em do not
set the test case up for execution when the program is run.
In order to do so, a later registration is needed with the
.Fn ATF_TP_ADD_TC
macro detailed in
.Sx Program initialization .
.Pp
Later on, one must define the three parts of the body by means of three
functions.
Their headers are given by the
.Fn ATF_TC_HEAD ,
.Fn ATF_TC_BODY
and
.Fn ATF_TC_CLEANUP
macros, all of which take the test case name provided to the
.Fn ATF_TC
or
.Fn ATF_TC_WITH_CLEANUP
macros.
Following each of these, a block of code is expected, surrounded by the
opening and closing brackets.
.Ss Program initialization
The library provides a way to easily define the test program's
.Fn main
function.
You should never define one on your own, but rely on the
library to do it for you.
This is done by using the
.Fn ATF_TP_ADD_TCS
macro, which is passed the name of the object that will hold the test
cases; i.e. the test program instance.
This name can be whatever you want as long as it is a valid variable
identifier.
.Pp
After the macro, you are supposed to provide the body of a function, which
should only use the
.Fn ATF_TP_ADD_TC
macro to register the test cases the test program will execute and return
a success error code.
The first parameter of this macro matches the name you provided in the
former call.
The success status can be returned using the
.Fn atf_no_error
function.
.Ss Header definitions
The test case's header can define the meta-data by using the
.Fn atf_tc_set_md_var
method, which takes two parameters: the first one specifies the
meta-data variable to be set and the second one specifies its value.
Both of them are strings.
.Ss Configuration variables
The test case has read-only access to the current configuration variables
by means of the
.Ft bool
.Fn atf_tc_has_config_var
and the
.Ft const char *
.Fn atf_tc_get_config_var
methods, which can be called in any of the three parts of a test case.
.Ss Access to the source directory
It is possible to get the path to the test case's source directory from any
of its three components by querying the
.Sq srcdir
configuration variable.
.Ss Requiring programs
Aside from the
.Va require.progs
meta-data variable available in the header only, one can also check for
additional programs in the test case's body by using the
.Fn atf_tc_require_prog
function, which takes the base name or full path of a single binary.
Relative paths are forbidden.
If it is not found, the test case will be automatically skipped.
.Ss Test case finalization
The test case finalizes either when the body reaches its end, at which
point the test is assumed to have
.Em passed ,
or at any explicit call to
.Fn atf_tc_pass ,
.Fn atf_tc_fail
or
.Fn atf_tc_skip .
These three functions terminate the execution of the test case immediately.
The cleanup routine will be processed afterwards in a completely automated
way, regardless of the test case's termination reason.
.Pp
.Fn atf_tc_pass
does not take any parameters.
.Fn atf_tc_fail
and
.Fn atf_tc_skip
take a single string that describes why the test case failed or
was skipped, respectively.
It is very important to provide a clear error message in both cases so that
the user can quickly know why the test did not pass.
.Ss Helper macros for common checks
The library provides several macros that are very handy in multiple
situations.
These basically check some condition after executing a given statement or
processing a given expression and, if the condition is not met, they
automatically call
.Fn atf_tc_fail
with an appropriate error message.
.Pp
.Fn ATF_CHECK
takes an expression and raises a failure if it evaluates to false.
.Pp
.Fn ATF_CHECK_EQUAL
takes two expressions and raises a failure if the two do not evaluate to
the same exact value.
.Sh EXAMPLES
The following shows a complete test program with a single test case that
validates the addition operator:
.Bd -literal -offset indent
#include <atf-c.h>
ATF_TC(addition);
ATF_TC_HEAD(addition)
{
atf_tc_set_md_var("descr", "Sample tests for the addition operator");
}
ATF_TC_BODY(addition)
{
ATF_CHECK_EQUAL(0 + 0, 0);
ATF_CHECK_EQUAL(0 + 1, 1);
ATF_CHECK_EQUAL(1 + 0, 1);
ATF_CHECK_EQUAL(1 + 1, 2);
ATF_CHECK_EQUAL(100 + 200, 300);
}
ATF_TP_ADD_TCS(tp)
{
ATF_TP_ADD_TC(tp, addition);
return atf_no_error();
}
.Ed
.Sh SEE ALSO
.Xr atf-test-program 1 ,
.Xr atf 7 ,
.Xr atf-test-case 8

View File

@ -1,135 +0,0 @@
/*
* 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
* 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 <stdbool.h>
#include <string.h>
#include "atf-c/config.h"
#include "atf-c/env.h"
#include "atf-c/sanity.h"
static bool initialized = false;
static const char *atf_arch = NULL;
static const char *atf_confdir = NULL;
static const char *atf_libexecdir = NULL;
static const char *atf_machine = NULL;
static const char *atf_pkgdatadir = NULL;
static const char *atf_shell = NULL;
static const char *atf_workdir = NULL;
/* Only used for unit testing, so this prototype is private. */
void __atf_config_reinit(void);
/* ---------------------------------------------------------------------
* Auxiliary functions.
* --------------------------------------------------------------------- */
static
void
initialize_var(char const **valptr, const char *name, const char *def)
{
PRE(*valptr == NULL);
if (atf_env_has(name)) {
const char *val = atf_env_get(name);
if (strlen(val) > 0)
*valptr = val;
else
*valptr = def;
} else
*valptr = def;
POST(*valptr != NULL);
}
static
void
initialize(void)
{
PRE(!initialized);
initialize_var(&atf_arch, "ATF_ARCH", ATF_ARCH);
initialize_var(&atf_confdir, "ATF_CONFDIR", ATF_CONFDIR);
initialize_var(&atf_libexecdir, "ATF_LIBEXECDIR", ATF_LIBEXECDIR);
initialize_var(&atf_machine, "ATF_MACHINE", ATF_MACHINE);
initialize_var(&atf_pkgdatadir, "ATF_PKGDATADIR", ATF_PKGDATADIR);
initialize_var(&atf_shell, "ATF_SHELL", ATF_SHELL);
initialize_var(&atf_workdir, "ATF_WORKDIR", ATF_WORKDIR);
initialized = true;
}
/* ---------------------------------------------------------------------
* Free functions.
* --------------------------------------------------------------------- */
const char *
atf_config_get(const char *var)
{
const char *value;
if (!initialized) {
initialize();
INV(initialized);
}
if (strcmp(var, "atf_arch") == 0)
value = atf_arch;
else if (strcmp(var, "atf_confdir") == 0)
value = atf_confdir;
else if (strcmp(var, "atf_libexecdir") == 0)
value = atf_libexecdir;
else if (strcmp(var, "atf_machine") == 0)
value = atf_machine;
else if (strcmp(var, "atf_pkgdatadir") == 0)
value = atf_pkgdatadir;
else if (strcmp(var, "atf_shell") == 0)
value = atf_shell;
else if (strcmp(var, "atf_workdir") == 0)
value = atf_workdir;
else {
UNREACHABLE;
value = NULL;
}
return value;
}
void
__atf_config_reinit(void)
{
initialized = false;
atf_arch = NULL;
atf_confdir = NULL;
atf_libexecdir = NULL;
atf_machine = NULL;
atf_pkgdatadir = NULL;
atf_shell = NULL;
atf_workdir = NULL;
}

View File

@ -1,37 +0,0 @@
/*
* 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
* 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_C_CONFIG_H)
#define ATF_C_CONFIG_H
#include <stdbool.h>
const char *atf_config_get(const char *);
#endif /* !defined(ATF_C_CONFIG_H) */

View File

@ -1,35 +0,0 @@
/*
* 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
* 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_C_DEFS_H)
#define ATF_C_DEFS_H
#define ATF_DEFS_ATTRIBUTE_NORETURN @ATTRIBUTE_NORETURN@
#endif /* !defined(ATF_C_DEFS_H) */

View File

@ -1,392 +0,0 @@
/*
* 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
* 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 <errno.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "atf-c/dynstr.h"
#include "atf-c/sanity.h"
#include "atf-c/text.h"
/* ---------------------------------------------------------------------
* Auxiliary functions.
* --------------------------------------------------------------------- */
static
atf_error_t
resize(atf_dynstr_t *ad, size_t newsize)
{
char *newdata;
atf_error_t err;
PRE(newsize > ad->m_datasize);
newdata = (char *)malloc(newsize);
if (newdata == NULL) {
err = atf_no_memory_error();
} else {
strcpy(newdata, ad->m_data);
free(ad->m_data);
ad->m_data = newdata;
ad->m_datasize = newsize;
err = atf_no_error();
}
return err;
}
static
atf_error_t
prepend_or_append(atf_dynstr_t *ad, const char *fmt, va_list ap,
bool prepend)
{
char *aux;
atf_error_t err;
size_t newlen;
va_list ap2;
va_copy(ap2, ap);
err = atf_text_format_ap(&aux, fmt, ap2);
va_end(ap2);
if (atf_is_error(err))
goto out;
newlen = ad->m_length + strlen(aux);
if (newlen + sizeof(char) > ad->m_datasize) {
err = resize(ad, newlen + sizeof(char));
if (atf_is_error(err))
goto out_free;
}
if (prepend) {
memmove(ad->m_data + strlen(aux), ad->m_data, ad->m_length + 1);
memcpy(ad->m_data, aux, strlen(aux));
} else
strcpy(ad->m_data + ad->m_length, aux);
ad->m_length = newlen;
err = atf_no_error();
out_free:
free(aux);
out:
return err;
}
/* ---------------------------------------------------------------------
* The "atf_dynstr" type.
* --------------------------------------------------------------------- */
/*
* Constants.
*/
const size_t atf_dynstr_npos = SIZE_MAX;
/*
* Constructors and destructors.
*/
atf_error_t
atf_dynstr_init(atf_dynstr_t *ad)
{
atf_error_t err;
atf_object_init(&ad->m_object);
ad->m_data = (char *)malloc(sizeof(char));
if (ad->m_data == NULL) {
err = atf_no_memory_error();
} else {
ad->m_data[0] = '\0';
ad->m_datasize = 1;
ad->m_length = 0;
err = atf_no_error();
}
return err;
}
atf_error_t
atf_dynstr_init_ap(atf_dynstr_t *ad, const char *fmt, va_list ap)
{
atf_error_t err;
atf_object_init(&ad->m_object);
ad->m_datasize = strlen(fmt) + 1;
ad->m_length = 0;
err = atf_no_error();
do {
ad->m_datasize *= 2;
ad->m_data = (char *)malloc(ad->m_datasize);
if (ad->m_data == NULL) {
err = atf_no_memory_error();
} else {
va_list ap2;
int ret;
va_copy(ap2, ap);
ret = vsnprintf(ad->m_data, ad->m_datasize, fmt, ap2);
va_end(ap2);
if (ret < 0) {
err = atf_libc_error(errno, "Cannot format string");
} else {
if (ret >= ad->m_datasize) {
free(ad->m_data);
ad->m_data = NULL;
}
ad->m_length = ret;
}
}
} while (!atf_is_error(err) && ad->m_length >= ad->m_datasize);
POST(atf_is_error(err) || ad->m_data != NULL);
return err;
}
atf_error_t
atf_dynstr_init_fmt(atf_dynstr_t *ad, const char *fmt, ...)
{
va_list ap;
atf_error_t err;
va_start(ap, fmt);
err = atf_dynstr_init_ap(ad, fmt, ap);
va_end(ap);
return err;
}
atf_error_t
atf_dynstr_init_raw(atf_dynstr_t *ad, const void *mem, size_t memlen)
{
atf_error_t err;
atf_object_init(&ad->m_object);
ad->m_data = (char *)malloc(memlen + 1);
if (ad->m_data == NULL)
err = atf_no_memory_error();
else {
ad->m_datasize = memlen + 1;
memcpy(ad->m_data, mem, memlen);
ad->m_data[memlen] = '\0';
ad->m_length = strlen(ad->m_data);
INV(ad->m_length <= memlen);
err = atf_no_error();
}
return err;
}
atf_error_t
atf_dynstr_init_rep(atf_dynstr_t *ad, size_t len, char ch)
{
atf_error_t err;
atf_object_init(&ad->m_object);
if (len == SIZE_MAX)
err = atf_no_memory_error();
else {
ad->m_datasize = len + sizeof(char);
ad->m_data = (char *)malloc(ad->m_datasize);
if (ad->m_data == NULL) {
err = atf_no_memory_error();
} else {
memset(ad->m_data, ch, len);
ad->m_data[len] = '\0';
ad->m_length = len;
err = atf_no_error();
}
}
return err;
}
atf_error_t
atf_dynstr_init_substr(atf_dynstr_t *ad, const atf_dynstr_t *src,
size_t beg, size_t end)
{
if (beg > src->m_length)
beg = src->m_length;
if (end == atf_dynstr_npos || end > src->m_length)
end = src->m_length;
return atf_dynstr_init_raw(ad, src->m_data + beg, end - beg);
}
atf_error_t
atf_dynstr_copy(atf_dynstr_t *dest, const atf_dynstr_t *src)
{
atf_error_t err;
atf_object_copy(&dest->m_object, &src->m_object);
dest->m_data = (char *)malloc(src->m_datasize);
if (dest->m_data == NULL)
err = atf_no_memory_error();
else {
memcpy(dest->m_data, src->m_data, src->m_datasize);
dest->m_datasize = src->m_datasize;
dest->m_length = src->m_length;
err = atf_no_error();
}
return err;
}
void
atf_dynstr_fini(atf_dynstr_t *ad)
{
INV(ad->m_data != NULL);
free(ad->m_data);
atf_object_fini(&ad->m_object);
}
char *
atf_dynstr_fini_disown(atf_dynstr_t *ad)
{
atf_object_fini(&ad->m_object);
INV(ad->m_data != NULL);
return ad->m_data;
}
/*
* Getters.
*/
const char *
atf_dynstr_cstring(const atf_dynstr_t *ad)
{
return ad->m_data;
}
size_t
atf_dynstr_length(atf_dynstr_t *ad)
{
return ad->m_length;
}
size_t
atf_dynstr_rfind_ch(const atf_dynstr_t *ad, char ch)
{
size_t pos;
for (pos = ad->m_length; pos > 0 && ad->m_data[pos - 1] != ch; pos--)
;
return pos == 0 ? atf_dynstr_npos : pos - 1;
}
/*
* Modifiers.
*/
atf_error_t
atf_dynstr_append_ap(atf_dynstr_t *ad, const char *fmt, va_list ap)
{
atf_error_t err;
va_list ap2;
va_copy(ap2, ap);
err = prepend_or_append(ad, fmt, ap2, false);
va_end(ap2);
return err;
}
atf_error_t
atf_dynstr_append_fmt(atf_dynstr_t *ad, const char *fmt, ...)
{
va_list ap;
atf_error_t err;
va_start(ap, fmt);
err = prepend_or_append(ad, fmt, ap, false);
va_end(ap);
return err;
}
void
atf_dynstr_clear(atf_dynstr_t *ad)
{
ad->m_data[0] = '\0';
ad->m_length = 0;
}
atf_error_t
atf_dynstr_prepend_ap(atf_dynstr_t *ad, const char *fmt, va_list ap)
{
atf_error_t err;
va_list ap2;
va_copy(ap2, ap);
err = prepend_or_append(ad, fmt, ap2, true);
va_end(ap2);
return err;
}
atf_error_t
atf_dynstr_prepend_fmt(atf_dynstr_t *ad, const char *fmt, ...)
{
va_list ap;
atf_error_t err;
va_start(ap, fmt);
err = prepend_or_append(ad, fmt, ap, true);
va_end(ap);
return err;
}
/*
* Operators.
*/
bool
atf_equal_dynstr_cstring(const atf_dynstr_t *ad, const char *str)
{
return strcmp(ad->m_data, str) == 0;
}
bool
atf_equal_dynstr_dynstr(const atf_dynstr_t *s1, const atf_dynstr_t *s2)
{
return strcmp(s1->m_data, s2->m_data) == 0;
}

View File

@ -1,82 +0,0 @@
/*
* 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
* 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_C_DYNSTR_H)
#define ATF_C_DYNSTR_H
#include <stdarg.h>
#include <atf-c/error.h>
#include <atf-c/object.h>
/* ---------------------------------------------------------------------
* The "atf_dynstr" type.
* --------------------------------------------------------------------- */
struct atf_dynstr {
atf_object_t m_object;
char *m_data;
size_t m_datasize;
size_t m_length;
};
typedef struct atf_dynstr atf_dynstr_t;
/* Constants */
extern const size_t atf_dynstr_npos;
/* Constructors and destructors */
atf_error_t atf_dynstr_init(atf_dynstr_t *);
atf_error_t atf_dynstr_init_ap(atf_dynstr_t *, const char *, va_list);
atf_error_t atf_dynstr_init_fmt(atf_dynstr_t *, const char *, ...);
atf_error_t atf_dynstr_init_raw(atf_dynstr_t *, const void *, size_t);
atf_error_t atf_dynstr_init_rep(atf_dynstr_t *, size_t, char);
atf_error_t atf_dynstr_init_substr(atf_dynstr_t *, const atf_dynstr_t *,
size_t, size_t);
atf_error_t atf_dynstr_copy(atf_dynstr_t *, const atf_dynstr_t *);
void atf_dynstr_fini(atf_dynstr_t *);
char *atf_dynstr_fini_disown(atf_dynstr_t *);
/* Getters */
const char *atf_dynstr_cstring(const atf_dynstr_t *);
size_t atf_dynstr_length(atf_dynstr_t *);
size_t atf_dynstr_rfind_ch(const atf_dynstr_t *, char);
/* Modifiers */
atf_error_t atf_dynstr_append_ap(atf_dynstr_t *, const char *, va_list);
atf_error_t atf_dynstr_append_fmt(atf_dynstr_t *, const char *, ...);
void atf_dynstr_clear(atf_dynstr_t *);
atf_error_t atf_dynstr_prepend_ap(atf_dynstr_t *, const char *, va_list);
atf_error_t atf_dynstr_prepend_fmt(atf_dynstr_t *, const char *, ...);
/* Operators */
bool atf_equal_dynstr_cstring(const atf_dynstr_t *, const char *);
bool atf_equal_dynstr_dynstr(const atf_dynstr_t *, const atf_dynstr_t *);
#endif /* ATF_C_DYNSTR_H */

106
dist/atf/atf-c/env.c vendored
View File

@ -1,106 +0,0 @@
/*
* Automated Testing Framework (atf)
*
* Copyright (c) 2007, 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
* 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(HAVE_CONFIG_H)
#include "bconfig.h"
#endif
#include <errno.h>
#include <stdlib.h>
#include "atf-c/env.h"
#include "atf-c/sanity.h"
#include "atf-c/text.h"
const char *
atf_env_get(const char *name)
{
const char* val = getenv(name);
PRE(val != NULL);
return val;
}
bool
atf_env_has(const char *name)
{
return getenv(name) != NULL;
}
atf_error_t
atf_env_set(const char *name, const char *val)
{
atf_error_t err;
#if defined(HAVE_SETENV)
if (setenv(name, val, 1) == -1)
err = atf_libc_error(errno, "Cannot set environment variable "
"'%s' to '%s'", name, val);
else
err = atf_no_error();
#elif defined(HAVE_PUTENV)
char *buf;
err = atf_text_format(&buf, "%s=%s", name, val);
if (!atf_is_error(err)) {
if (putenv(buf) == -1)
err = atf_libc_error(errno, "Cannot set environment variable "
"'%s' to '%s'", name, val);
free(buf);
}
#else
# error "Don't know how to set an environment variable."
#endif
return err;
}
atf_error_t
atf_env_unset(const char *name)
{
atf_error_t err;
#if defined(HAVE_UNSETENV)
unsetenv(name);
err = atf_no_error();
#elif defined(HAVE_PUTENV)
char *buf;
err = atf_text_format(&buf, "%s=", name);
if (!atf_is_error(err)) {
if (putenv(buf) == -1)
err = atf_libc_error(errno, "Cannot unset environment variable"
" '%s'", name);
free(buf);
}
#else
# error "Don't know how to unset an environment variable."
#endif
return err;
}

42
dist/atf/atf-c/env.h vendored
View File

@ -1,42 +0,0 @@
/*
* 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
* 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_C_ENV_H)
#define ATF_C_ENV_H
#include <stdbool.h>
#include <atf-c/error.h>
const char *atf_env_get(const char *);
bool atf_env_has(const char *);
atf_error_t atf_env_set(const char *, const char *);
atf_error_t atf_env_unset(const char *);
#endif /* !defined(ATF_C_ENV_H) */

242
dist/atf/atf-c/error.c vendored
View File

@ -1,242 +0,0 @@
/*
* 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
* 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 <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "atf-c/error.h"
#include "atf-c/sanity.h"
/* ---------------------------------------------------------------------
* Auxiliary functions.
* --------------------------------------------------------------------- */
static
void
error_format(const atf_error_t err, char *buf, size_t buflen)
{
PRE(err != NULL);
snprintf(buf, buflen, "Error '%s'", err->m_type);
}
static
bool
error_init(atf_error_t err, const char *type, void *data, size_t datalen,
void (*format)(const atf_error_t, char *, size_t))
{
bool ok;
PRE(data != NULL || datalen == 0);
PRE(datalen != 0 || data == NULL);
atf_object_init(&err->m_object);
err->m_free = false;
err->m_type = type;
err->m_format = (format == NULL) ? error_format : format;
ok = true;
if (data == NULL) {
err->m_data = NULL;
} else {
err->m_data = malloc(datalen);
if (err->m_data == NULL)
ok = false;
else
memcpy(err->m_data, data, datalen);
}
return ok;
}
/* ---------------------------------------------------------------------
* The "atf_error" type.
* --------------------------------------------------------------------- */
atf_error_t
atf_error_new(const char *type, void *data, size_t datalen,
void (*format)(const atf_error_t, char *, size_t))
{
atf_error_t err;
PRE(data != NULL || datalen == 0);
PRE(datalen != 0 || data == NULL);
err = malloc(sizeof(*err));
if (err == NULL)
err = atf_no_memory_error();
else {
if (!error_init(err, type, data, datalen, format)) {
free(err);
err = atf_no_memory_error();
} else
err->m_free = true;
}
INV(err != NULL);
return err;
}
void
atf_error_free(atf_error_t err)
{
bool freeit;
PRE(err != NULL);
freeit = err->m_free;
if (err->m_data != NULL)
free(err->m_data);
atf_object_fini(&err->m_object);
if (freeit)
free(err);
}
atf_error_t
atf_no_error(void)
{
return NULL;
}
bool
atf_is_error(const atf_error_t err)
{
return err != NULL;
}
bool
atf_error_is(const atf_error_t err, const char *type)
{
PRE(err != NULL);
return strcmp(err->m_type, type) == 0;
}
const void *
atf_error_data(const atf_error_t err)
{
PRE(err != NULL);
return err->m_data;
}
void
atf_error_format(const atf_error_t err, char *buf, size_t buflen)
{
PRE(err != NULL);
err->m_format(err, buf, buflen);
}
/* ---------------------------------------------------------------------
* Common error types.
* --------------------------------------------------------------------- */
/*
* The "libc" error.
*/
struct atf_libc_error_data {
int m_errno;
char m_what[4096];
};
typedef struct atf_libc_error_data atf_libc_error_data_t;
static
void
libc_format(const atf_error_t err, char *buf, size_t buflen)
{
const atf_libc_error_data_t *data;
PRE(atf_error_is(err, "libc"));
data = atf_error_data(err);
snprintf(buf, buflen, "%s: %s", data->m_what, strerror(data->m_errno));
}
atf_error_t
atf_libc_error(int syserrno, const char *fmt, ...)
{
atf_error_t err;
atf_libc_error_data_t data;
va_list ap;
data.m_errno = syserrno;
va_start(ap, fmt);
vsnprintf(data.m_what, sizeof(data.m_what), fmt, ap);
va_end(ap);
err = atf_error_new("libc", &data, sizeof(data), libc_format);
return err;
}
int
atf_libc_error_code(const atf_error_t err)
{
const struct atf_libc_error_data *data;
PRE(atf_error_is(err, "libc"));
data = atf_error_data(err);
return data->m_errno;
}
/*
* The "no_memory" error.
*/
static bool no_memory_error_inited = false;
static struct atf_error no_memory_error;
static
void
no_memory_format(const atf_error_t err, char *buf, size_t buflen)
{
PRE(atf_error_is(err, "no_memory"));
snprintf(buf, buflen, "Not enough memory");
}
atf_error_t
atf_no_memory_error(void)
{
if (!no_memory_error_inited) {
error_init(&no_memory_error, "no_memory", NULL, 0,
no_memory_format);
no_memory_error_inited = true;
}
return &no_memory_error;
}

View File

@ -1,70 +0,0 @@
/*
* 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
* 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_C_ERROR_H)
#define ATF_C_ERROR_H
#include <atf-c/object.h>
/* ---------------------------------------------------------------------
* The "atf_error" type.
* --------------------------------------------------------------------- */
struct atf_error {
atf_object_t m_object;
bool m_free;
const char *m_type;
void *m_data;
void (*m_format)(struct atf_error *, char *, size_t);
};
typedef struct atf_error *atf_error_t;
atf_error_t atf_error_new(const char *, void *, size_t,
void (*)(const atf_error_t, char *, size_t));
void atf_error_free(atf_error_t);
atf_error_t atf_no_error(void);
bool atf_is_error(const atf_error_t);
bool atf_error_is(const atf_error_t, const char *);
const void *atf_error_data(const atf_error_t);
void atf_error_format(const atf_error_t, char *, size_t);
/* ---------------------------------------------------------------------
* Common error types.
* --------------------------------------------------------------------- */
atf_error_t atf_libc_error(int, const char *, ...);
int atf_libc_error_code(const atf_error_t);
atf_error_t atf_no_memory_error(void);
#endif /* ATF_C_ERROR_H */

View File

@ -1,166 +0,0 @@
/*
* Automated Testing Framework (atf)
*
* Copyright (c) 2007, 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
* 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 <regex.h>
#include <stdio.h>
#include <string.h>
#include "atf-c/dynstr.h"
#include "atf-c/expand.h"
#include "atf-c/sanity.h"
/* REG_BASIC is just a synonym for 0, provided as a counterpart to
* REG_EXTENDED to improve readability. It is not provided by all
* systems. */
#if !defined(REG_BASIC)
#define REG_BASIC 0
#endif /* !defined(REG_BASIC) */
/* ---------------------------------------------------------------------
* The "pattern" error type.
* --------------------------------------------------------------------- */
struct pattern_error_data {
int m_errcode;
regex_t m_preg;
};
typedef struct pattern_error_data pattern_error_data_t;
static
void
pattern_format(const atf_error_t err, char *buf, size_t buflen)
{
const pattern_error_data_t *data;
char tmp[4096];
PRE(atf_error_is(err, "pattern"));
data = atf_error_data(err);
regerror(data->m_errcode, &data->m_preg, tmp, sizeof(tmp));
snprintf(buf, buflen, "Regular expression error: %s", tmp);
}
static
atf_error_t
pattern_error(int errcode, const regex_t* preg)
{
atf_error_t err;
pattern_error_data_t data;
data.m_errcode = errcode;
data.m_preg = *preg;
err = atf_error_new("pattern", &data, sizeof(data), pattern_format);
return err;
}
/* ---------------------------------------------------------------------
* Auxiliary functions.
* --------------------------------------------------------------------- */
static
atf_error_t
glob_to_regex(const char *glob, atf_dynstr_t *regex)
{
atf_error_t err;
err = atf_dynstr_init_fmt(regex, "^");
for (; !atf_is_error(err) && *glob != '\0'; glob++) {
if (*glob == '*')
err = atf_dynstr_append_fmt(regex, ".*");
else if (*glob == '?')
err = atf_dynstr_append_fmt(regex, ".");
else
err = atf_dynstr_append_fmt(regex, "%c", *glob);
}
if (!atf_is_error(err))
err = atf_dynstr_append_fmt(regex, "$");
if (atf_is_error(err))
atf_dynstr_fini(regex);
return err;
}
/* ---------------------------------------------------------------------
* Free functions.
* --------------------------------------------------------------------- */
bool
atf_expand_is_glob(const char *glob)
{
/* NOTE: Keep this in sync with glob_to_regex! */
return (strchr(glob, '*') != NULL) || (strchr(glob, '?') != NULL);
}
atf_error_t
atf_expand_matches_glob(const char *glob, const char *candidate,
bool *result)
{
atf_dynstr_t regex;
atf_error_t err;
int res;
regex_t preg;
/* Special case: regcomp does not like empty patterns. */
if (glob[0] == '\0') {
*result = candidate[0] == '\0';
err = atf_no_error();
goto out;
}
/* Convert the glob pattern into a regular expression. */
err = glob_to_regex(glob, &regex);
if (atf_is_error(err))
goto out;
/* Compile the regular expression. */
res = regcomp(&preg, atf_dynstr_cstring(&regex), REG_BASIC);
if (res != 0) {
err = pattern_error(res, &preg);
goto out;
}
/* Check match. */
res = regexec(&preg, candidate, 0, NULL, 0);
if (res != 0 && res != REG_NOMATCH) {
err = pattern_error(res, &preg);
goto out;
} else {
*result = (res == 0);
INV(!atf_is_error(err));
}
atf_dynstr_fini(&regex);
out:
return err;
}

View File

@ -1,44 +0,0 @@
/*
* 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
* 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_C_EXPAND_H)
#define ATF_C_EXPAND_H
#include <stdbool.h>
#include <atf-c/error.h>
/* ---------------------------------------------------------------------
* Free functions.
* --------------------------------------------------------------------- */
bool atf_expand_is_glob(const char *);
atf_error_t atf_expand_matches_glob(const char *, const char *, bool *);
#endif /* ATF_C_EXPAND_H */

828
dist/atf/atf-c/fs.c vendored
View File

@ -1,828 +0,0 @@
/*
* Automated Testing Framework (atf)
*
* Copyright (c) 2007, 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
* 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(HAVE_CONFIG_H)
#include "bconfig.h"
#endif
#include <sys/types.h>
#include <sys/param.h>
#include <sys/mount.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <dirent.h>
#include <errno.h>
#include <libgen.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "atf-c/fs.h"
#include "atf-c/sanity.h"
#include "atf-c/text.h"
#include "atf-c/user.h"
/* ---------------------------------------------------------------------
* The "child" error type.
* --------------------------------------------------------------------- */
/* XXX The need for this conditional here is extremely ugly. This
* exception should belong to another module with more process-related
* utilities. */
#if !defined(HAVE_UNMOUNT)
struct child_error_data {
char m_cmd[4096];
int m_state;
};
typedef struct child_error_data child_error_data_t;
static
void
child_format(const atf_error_t err, char *buf, size_t buflen)
{
const child_error_data_t *data;
PRE(atf_error_is(err, "child"));
data = atf_error_data(err);
snprintf(buf, buflen, "Unknown error while executing \"%s\"; "
"exit state was %d", data->m_cmd, data->m_state);
}
static
atf_error_t
child_error(const char *cmd, int state)
{
atf_error_t err;
child_error_data_t data;
snprintf(data.m_cmd, sizeof(data.m_cmd), "%s", cmd);
data.m_state = state;
err = atf_error_new("child", &data, sizeof(data), child_format);
return err;
}
#endif /* !defined(HAVE_UNMOUNT) */
/* ---------------------------------------------------------------------
* The "unknown_file_type" error type.
* --------------------------------------------------------------------- */
struct unknown_type_error_data {
const char *m_path;
int m_type;
};
typedef struct unknown_type_error_data unknown_type_error_data_t;
static
void
unknown_type_format(const atf_error_t err, char *buf, size_t buflen)
{
const unknown_type_error_data_t *data;
PRE(atf_error_is(err, "unknown_type"));
data = atf_error_data(err);
snprintf(buf, buflen, "Unknown file type %d of %s", data->m_type,
data->m_path);
}
static
atf_error_t
unknown_type_error(const char *path, int type)
{
atf_error_t err;
unknown_type_error_data_t data;
data.m_path = path;
data.m_type = type;
err = atf_error_new("unknown_type", &data, sizeof(data),
unknown_type_format);
return err;
}
/* ---------------------------------------------------------------------
* Auxiliary functions.
* --------------------------------------------------------------------- */
static atf_error_t cleanup_aux(const atf_fs_path_t *, dev_t, bool);
static atf_error_t cleanup_aux_dir(const char *, dev_t, bool);
static atf_error_t do_unmount(const atf_fs_path_t *);
static atf_error_t normalize(atf_dynstr_t *, char *);
static atf_error_t normalize_ap(atf_dynstr_t *, const char *, va_list);
/* The erase parameter in this routine is to control nested mount points.
* We want to descend into a mount point to unmount anything that is
* mounted under it, but we do not want to delete any files while doing
* this traversal. In other words, we erase files until we cross the
* first mount point, and after that point we only scan and unmount. */
static
atf_error_t
cleanup_aux(const atf_fs_path_t *p, dev_t parent_device, bool erase)
{
const char *pstr = atf_fs_path_cstring(p);
atf_error_t err;
atf_fs_stat_t st;
err = atf_fs_stat_init(&st, p);
if (atf_is_error(err))
goto out;
if (atf_fs_stat_get_type(&st) == atf_fs_stat_dir_type) {
err = cleanup_aux_dir(pstr, atf_fs_stat_get_device(&st),
atf_fs_stat_get_device(&st) == parent_device);
if (atf_is_error(err))
goto out_st;
}
if (atf_fs_stat_get_device(&st) != parent_device) {
err = do_unmount(p);
if (atf_is_error(err))
goto out_st;
}
if (erase) {
if (atf_fs_stat_get_type(&st) == atf_fs_stat_dir_type) {
if (rmdir(pstr) == -1)
err = atf_libc_error(errno, "Cannot remove directory "
"%s", pstr);
else
INV(!atf_is_error(err));
} else {
if (unlink(pstr) == -1)
err = atf_libc_error(errno, "Cannot remove file %s", pstr);
else
INV(!atf_is_error(err));
}
}
out_st:
atf_fs_stat_fini(&st);
out:
return err;
}
static
atf_error_t
cleanup_aux_dir(const char *pstr, dev_t this_device, bool erase)
{
DIR *d;
atf_error_t err;
struct dirent *de;
d = opendir(pstr);
if (d == NULL) {
err = atf_libc_error(errno, "Cannot open directory %s", pstr);
goto out;
}
err = atf_no_error();
while (!atf_is_error(err) && (de = readdir(d)) != NULL) {
atf_fs_path_t p;
err = atf_fs_path_init_fmt(&p, "%s/%s", pstr, de->d_name);
if (!atf_is_error(err)) {
if (strcmp(de->d_name, ".") != 0 &&
strcmp(de->d_name, "..") != 0)
err = cleanup_aux(&p, this_device, erase);
atf_fs_path_fini(&p);
}
}
closedir(d);
out:
return err;
}
static
atf_error_t
do_unmount(const atf_fs_path_t *p)
{
atf_error_t err;
atf_fs_path_t pa;
const char *pastr;
/* At least, FreeBSD's unmount(2) requires the path to be absolute.
* Let's make it absolute in all cases just to be safe that this does
* not affect other systems. */
if (!atf_fs_path_is_absolute(p))
err = atf_fs_path_to_absolute(p, &pa);
else
err = atf_fs_path_copy(&pa, p);
if (atf_is_error(err))
goto out;
pastr = atf_fs_path_cstring(&pa);
#if defined(HAVE_UNMOUNT)
if (unmount(pastr, 0) == -1)
err = atf_libc_error(errno, "Cannot unmount %s", pastr);
else
err = atf_no_error();
#else
{
/* We could use umount(2) instead if it was available... but
* trying to do so under, e.g. Linux, is a nightmare because we
* also have to update /etc/mtab to match what we did. It is
* simpler to just leave the system-specific umount(8) tool deal
* with it, at least for now. */
char *cmd;
err = atf_text_format(&cmd, "umount '%s'", pastr);
if (!atf_is_error(err)) {
int state = system(cmd);
if (state == -1)
err = atf_libc_error(errno, "Failed to run \"%s\"", cmd);
else if (!WIFEXITED(state) || WEXITSTATUS(state) != EXIT_SUCCESS)
err = child_error(cmd, state);
free(cmd);
}
}
#endif
atf_fs_path_fini(&pa);
out:
return err;
}
static
atf_error_t
normalize(atf_dynstr_t *d, char *p)
{
const char *ptr;
char *last;
atf_error_t err;
bool first;
PRE(strlen(p) > 0);
PRE(atf_dynstr_length(d) == 0);
if (p[0] == '/')
err = atf_dynstr_append_fmt(d, "/");
else
err = atf_no_error();
first = true;
last = NULL; /* Silence GCC warning. */
ptr = strtok_r(p, "/", &last);
while (!atf_is_error(err) && ptr != NULL) {
if (strlen(ptr) > 0) {
err = atf_dynstr_append_fmt(d, "%s%s", first ? "" : "/", ptr);
first = false;
}
ptr = strtok_r(NULL, "/", &last);
}
return err;
}
static
atf_error_t
normalize_ap(atf_dynstr_t *d, const char *p, va_list ap)
{
char *str;
atf_error_t err;
va_list ap2;
err = atf_dynstr_init(d);
if (atf_is_error(err))
goto out;
va_copy(ap2, ap);
err = atf_text_format_ap(&str, p, ap2);
va_end(ap2);
if (atf_is_error(err))
atf_dynstr_fini(d);
else {
err = normalize(d, str);
free(str);
}
out:
return err;
}
/* ---------------------------------------------------------------------
* The "atf_fs_path" type.
* --------------------------------------------------------------------- */
/*
* Constructors/destructors.
*/
atf_error_t
atf_fs_path_init_ap(atf_fs_path_t *p, const char *fmt, va_list ap)
{
atf_error_t err;
va_list ap2;
atf_object_init(&p->m_object);
va_copy(ap2, ap);
err = normalize_ap(&p->m_data, fmt, ap2);
va_end(ap2);
return err;
}
atf_error_t
atf_fs_path_init_fmt(atf_fs_path_t *p, const char *fmt, ...)
{
va_list ap;
atf_error_t err;
va_start(ap, fmt);
err = atf_fs_path_init_ap(p, fmt, ap);
va_end(ap);
return err;
}
atf_error_t
atf_fs_path_copy(atf_fs_path_t *dest, const atf_fs_path_t *src)
{
atf_object_copy(&dest->m_object, &src->m_object);
return atf_dynstr_copy(&dest->m_data, &src->m_data);
}
void
atf_fs_path_fini(atf_fs_path_t *p)
{
atf_dynstr_fini(&p->m_data);
atf_object_fini(&p->m_object);
}
/*
* Getters.
*/
atf_error_t
atf_fs_path_branch_path(const atf_fs_path_t *p, atf_fs_path_t *bp)
{
const ssize_t endpos = atf_dynstr_rfind_ch(&p->m_data, '/');
atf_error_t err;
if (endpos == atf_dynstr_npos)
err = atf_fs_path_init_fmt(bp, ".");
else if (endpos == 0)
err = atf_fs_path_init_fmt(bp, "/");
else {
atf_object_init(&bp->m_object);
err = atf_dynstr_init_substr(&bp->m_data, &p->m_data, 0, endpos);
}
#if defined(HAVE_CONST_DIRNAME)
INV(atf_equal_dynstr_cstring(&bp->m_data,
dirname(atf_dynstr_cstring(&p->m_data))));
#endif /* defined(HAVE_CONST_DIRNAME) */
return err;
}
const char *
atf_fs_path_cstring(const atf_fs_path_t *p)
{
return atf_dynstr_cstring(&p->m_data);
}
atf_error_t
atf_fs_path_leaf_name(const atf_fs_path_t *p, atf_dynstr_t *ln)
{
ssize_t begpos = atf_dynstr_rfind_ch(&p->m_data, '/');
atf_error_t err;
if (begpos == atf_dynstr_npos)
begpos = 0;
else
begpos++;
err = atf_dynstr_init_substr(ln, &p->m_data, begpos, atf_dynstr_npos);
#if defined(HAVE_CONST_BASENAME)
INV(atf_equal_dynstr_cstring(ln,
basename(atf_dynstr_cstring(&p->m_data))));
#endif /* defined(HAVE_CONST_BASENAME) */
return err;
}
bool
atf_fs_path_is_absolute(const atf_fs_path_t *p)
{
return atf_dynstr_cstring(&p->m_data)[0] == '/';
}
bool
atf_fs_path_is_root(const atf_fs_path_t *p)
{
return atf_equal_dynstr_cstring(&p->m_data, "/");
}
/*
* Modifiers.
*/
atf_error_t
atf_fs_path_append_ap(atf_fs_path_t *p, const char *fmt, va_list ap)
{
atf_dynstr_t aux;
atf_error_t err;
va_list ap2;
va_copy(ap2, ap);
err = normalize_ap(&aux, fmt, ap2);
va_end(ap2);
if (!atf_is_error(err)) {
const char *auxstr = atf_dynstr_cstring(&aux);
const bool needslash = auxstr[0] != '/';
err = atf_dynstr_append_fmt(&p->m_data, "%s%s",
needslash ? "/" : "", auxstr);
atf_dynstr_fini(&aux);
}
return err;
}
atf_error_t
atf_fs_path_append_fmt(atf_fs_path_t *p, const char *fmt, ...)
{
va_list ap;
atf_error_t err;
va_start(ap, fmt);
err = atf_fs_path_append_ap(p, fmt, ap);
va_end(ap);
return err;
}
atf_error_t
atf_fs_path_append_path(atf_fs_path_t *p, const atf_fs_path_t *p2)
{
return atf_fs_path_append_fmt(p, "%s", atf_dynstr_cstring(&p2->m_data));
}
atf_error_t
atf_fs_path_to_absolute(const atf_fs_path_t *p, atf_fs_path_t *pa)
{
atf_error_t err;
PRE(!atf_fs_path_is_absolute(p));
err = atf_fs_getcwd(pa);
if (atf_is_error(err))
goto out;
err = atf_fs_path_append_path(pa, p);
if (atf_is_error(err))
atf_fs_path_fini(pa);
out:
return err;
}
/*
* Operators.
*/
bool atf_equal_fs_path_fs_path(const atf_fs_path_t *p1,
const atf_fs_path_t *p2)
{
return atf_equal_dynstr_dynstr(&p1->m_data, &p2->m_data);
}
/* ---------------------------------------------------------------------
* The "atf_fs_path" type.
* --------------------------------------------------------------------- */
/*
* Constants.
*/
const int atf_fs_stat_blk_type = 1;
const int atf_fs_stat_chr_type = 2;
const int atf_fs_stat_dir_type = 3;
const int atf_fs_stat_fifo_type = 4;
const int atf_fs_stat_lnk_type = 5;
const int atf_fs_stat_reg_type = 6;
const int atf_fs_stat_sock_type = 7;
const int atf_fs_stat_wht_type = 8;
/*
* Constructors/destructors.
*/
atf_error_t
atf_fs_stat_init(atf_fs_stat_t *st, const atf_fs_path_t *p)
{
atf_error_t err;
const char *pstr = atf_fs_path_cstring(p);
if (lstat(pstr, &st->m_sb) == -1) {
err = atf_libc_error(errno, "Cannot get information of %s; "
"lstat(2) failed", pstr);
} else {
int type = st->m_sb.st_mode & S_IFMT;
err = atf_no_error();
switch (type) {
case S_IFBLK: st->m_type = atf_fs_stat_blk_type; break;
case S_IFCHR: st->m_type = atf_fs_stat_chr_type; break;
case S_IFDIR: st->m_type = atf_fs_stat_dir_type; break;
case S_IFIFO: st->m_type = atf_fs_stat_fifo_type; break;
case S_IFLNK: st->m_type = atf_fs_stat_lnk_type; break;
case S_IFREG: st->m_type = atf_fs_stat_reg_type; break;
case S_IFSOCK: st->m_type = atf_fs_stat_sock_type; break;
#if defined(S_IFWHT)
case S_IFWHT: st->m_type = atf_fs_stat_wht_type; break;
#endif
default:
err = unknown_type_error(pstr, type);
}
}
if (!atf_is_error(err))
atf_object_init(&st->m_object);
return err;
}
void
atf_fs_stat_copy(atf_fs_stat_t *dest, const atf_fs_stat_t *src)
{
atf_object_copy(&dest->m_object, &src->m_object);
dest->m_type = src->m_type;
dest->m_sb = src->m_sb;
}
void
atf_fs_stat_fini(atf_fs_stat_t *st)
{
atf_object_fini(&st->m_object);
}
/*
* Getters.
*/
dev_t
atf_fs_stat_get_device(const atf_fs_stat_t *st)
{
return st->m_sb.st_dev;
}
ino_t
atf_fs_stat_get_inode(const atf_fs_stat_t *st)
{
return st->m_sb.st_ino;
}
int
atf_fs_stat_get_type(const atf_fs_stat_t *st)
{
return st->m_type;
}
bool
atf_fs_stat_is_owner_readable(const atf_fs_stat_t *st)
{
return st->m_sb.st_mode & S_IRUSR;
}
bool
atf_fs_stat_is_owner_writable(const atf_fs_stat_t *st)
{
return st->m_sb.st_mode & S_IWUSR;
}
bool
atf_fs_stat_is_owner_executable(const atf_fs_stat_t *st)
{
return st->m_sb.st_mode & S_IXUSR;
}
bool
atf_fs_stat_is_group_readable(const atf_fs_stat_t *st)
{
return st->m_sb.st_mode & S_IRGRP;
}
bool
atf_fs_stat_is_group_writable(const atf_fs_stat_t *st)
{
return st->m_sb.st_mode & S_IWGRP;
}
bool
atf_fs_stat_is_group_executable(const atf_fs_stat_t *st)
{
return st->m_sb.st_mode & S_IXGRP;
}
bool
atf_fs_stat_is_other_readable(const atf_fs_stat_t *st)
{
return st->m_sb.st_mode & S_IROTH;
}
bool
atf_fs_stat_is_other_writable(const atf_fs_stat_t *st)
{
return st->m_sb.st_mode & S_IWOTH;
}
bool
atf_fs_stat_is_other_executable(const atf_fs_stat_t *st)
{
return st->m_sb.st_mode & S_IXOTH;
}
/* ---------------------------------------------------------------------
* Free functions.
* --------------------------------------------------------------------- */
const int atf_fs_access_f = 1 << 0;
const int atf_fs_access_r = 1 << 1;
const int atf_fs_access_w = 1 << 2;
const int atf_fs_access_x = 1 << 3;
atf_error_t
atf_fs_cleanup(const atf_fs_path_t *p)
{
atf_error_t err;
atf_fs_stat_t info;
err = atf_fs_stat_init(&info, p);
if (atf_is_error(err))
return err;
err = cleanup_aux(p, atf_fs_stat_get_device(&info), true);
atf_fs_stat_fini(&info);
return err;
}
/*
* An implementation of access(2) but using the effective user value
* instead of the real one. Also avoids false positives for root when
* asking for execute permissions, which appear in SunOS.
*/
atf_error_t
atf_fs_eaccess(const atf_fs_path_t *p, int mode)
{
atf_error_t err;
struct stat st;
bool ok;
PRE(mode & atf_fs_access_f || mode & atf_fs_access_r ||
mode & atf_fs_access_w || mode & atf_fs_access_x);
if (lstat(atf_fs_path_cstring(p), &st) == -1) {
err = atf_libc_error(errno, "Cannot get information from file %s",
atf_fs_path_cstring(p));
goto out;
}
err = atf_no_error();
/* Early return if we are only checking for existence and the file
* exists (stat call returned). */
if (mode & atf_fs_access_f)
goto out;
ok = false;
if (atf_user_is_root()) {
if (!ok && !(mode & atf_fs_access_x)) {
/* Allow root to read/write any file. */
ok = true;
}
if (!ok && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) {
/* Allow root to execute the file if any of its execution bits
* are set. */
ok = true;
}
} else {
if (!ok && (atf_user_euid() == st.st_uid)) {
ok = ((mode & atf_fs_access_r) && (st.st_mode & S_IRUSR)) ||
((mode & atf_fs_access_w) && (st.st_mode & S_IWUSR)) ||
((mode & atf_fs_access_x) && (st.st_mode & S_IXUSR));
}
if (!ok && atf_user_is_member_of_group(st.st_gid)) {
ok = ((mode & atf_fs_access_r) && (st.st_mode & S_IRGRP)) ||
((mode & atf_fs_access_w) && (st.st_mode & S_IWGRP)) ||
((mode & atf_fs_access_x) && (st.st_mode & S_IXGRP));
}
if (!ok && ((atf_user_euid() != st.st_uid) &&
!atf_user_is_member_of_group(st.st_gid))) {
ok = ((mode & atf_fs_access_r) && (st.st_mode & S_IROTH)) ||
((mode & atf_fs_access_w) && (st.st_mode & S_IWOTH)) ||
((mode & atf_fs_access_x) && (st.st_mode & S_IXOTH));
}
}
if (!ok)
err = atf_libc_error(EACCES, "Access check failed");
out:
return err;
}
atf_error_t
atf_fs_exists(const atf_fs_path_t *p, bool *b)
{
atf_error_t err;
err = atf_fs_eaccess(p, atf_fs_access_f);
if (atf_is_error(err)) {
if (atf_error_is(err, "libc") && atf_libc_error_code(err) == ENOENT) {
atf_error_free(err);
err = atf_no_error();
*b = false;
}
} else
*b = true;
return err;
}
atf_error_t
atf_fs_getcwd(atf_fs_path_t *p)
{
atf_error_t err;
char *cwd;
#if defined(HAVE_GETCWD_DYN)
cwd = getcwd(NULL, 0);
#else
cwd = getcwd(NULL, MAXPATHLEN);
#endif
if (cwd == NULL) {
err = atf_libc_error(errno, "Cannot determine current directory");
goto out;
}
err = atf_fs_path_init_fmt(p, "%s", cwd);
free(cwd);
out:
return err;
}
atf_error_t
atf_fs_mkdtemp(atf_fs_path_t *p)
{
atf_error_t err;
char *tmpl;
tmpl = p->m_data.m_data; /* XXX: Ugly */
PRE(strstr(tmpl, "XXXXXX") != NULL);
if (mkdtemp(tmpl) == NULL)
err = atf_libc_error(errno, "Cannot create temporary directory "
"with template '%s'", tmpl);
else
err = atf_no_error();
return err;
}

133
dist/atf/atf-c/fs.h vendored
View File

@ -1,133 +0,0 @@
/*
* 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
* 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_C_FS_H)
#define ATF_C_FS_H
#include <sys/types.h>
#include <sys/stat.h>
#include <stdarg.h>
#include <stdbool.h>
#include <atf-c/dynstr.h>
#include <atf-c/error.h>
#include <atf-c/object.h>
/* ---------------------------------------------------------------------
* The "atf_fs_path" type.
* --------------------------------------------------------------------- */
struct atf_fs_path {
atf_object_t m_object;
atf_dynstr_t m_data;
};
typedef struct atf_fs_path atf_fs_path_t;
/* Constructors/destructors. */
atf_error_t atf_fs_path_init_ap(atf_fs_path_t *, const char *, va_list);
atf_error_t atf_fs_path_init_fmt(atf_fs_path_t *, const char *, ...);
atf_error_t atf_fs_path_copy(atf_fs_path_t *, const atf_fs_path_t *);
void atf_fs_path_fini(atf_fs_path_t *);
/* Getters. */
atf_error_t atf_fs_path_branch_path(const atf_fs_path_t *, atf_fs_path_t *);
const char *atf_fs_path_cstring(const atf_fs_path_t *);
atf_error_t atf_fs_path_leaf_name(const atf_fs_path_t *, atf_dynstr_t *);
bool atf_fs_path_is_absolute(const atf_fs_path_t *);
bool atf_fs_path_is_root(const atf_fs_path_t *);
/* Modifiers. */
atf_error_t atf_fs_path_append_ap(atf_fs_path_t *, const char *, va_list);
atf_error_t atf_fs_path_append_fmt(atf_fs_path_t *, const char *, ...);
atf_error_t atf_fs_path_append_path(atf_fs_path_t *, const atf_fs_path_t *);
atf_error_t atf_fs_path_to_absolute(const atf_fs_path_t *, atf_fs_path_t *);
/* Operators. */
bool atf_equal_fs_path_fs_path(const atf_fs_path_t *,
const atf_fs_path_t *);
/* ---------------------------------------------------------------------
* The "atf_fs_stat" type.
* --------------------------------------------------------------------- */
struct atf_fs_stat {
atf_object_t m_object;
int m_type;
struct stat m_sb;
};
typedef struct atf_fs_stat atf_fs_stat_t;
/* Constants. */
extern const int atf_fs_stat_blk_type;
extern const int atf_fs_stat_chr_type;
extern const int atf_fs_stat_dir_type;
extern const int atf_fs_stat_fifo_type;
extern const int atf_fs_stat_lnk_type;
extern const int atf_fs_stat_reg_type;
extern const int atf_fs_stat_sock_type;
extern const int atf_fs_stat_wht_type;
/* Constructors/destructors. */
atf_error_t atf_fs_stat_init(atf_fs_stat_t *, const atf_fs_path_t *);
void atf_fs_stat_copy(atf_fs_stat_t *, const atf_fs_stat_t *);
void atf_fs_stat_fini(atf_fs_stat_t *);
/* Getters. */
dev_t atf_fs_stat_get_device(const atf_fs_stat_t *);
ino_t atf_fs_stat_get_inode(const atf_fs_stat_t *);
int atf_fs_stat_get_type(const atf_fs_stat_t *);
bool atf_fs_stat_is_owner_readable(const atf_fs_stat_t *);
bool atf_fs_stat_is_owner_writable(const atf_fs_stat_t *);
bool atf_fs_stat_is_owner_executable(const atf_fs_stat_t *);
bool atf_fs_stat_is_group_readable(const atf_fs_stat_t *);
bool atf_fs_stat_is_group_writable(const atf_fs_stat_t *);
bool atf_fs_stat_is_group_executable(const atf_fs_stat_t *);
bool atf_fs_stat_is_other_readable(const atf_fs_stat_t *);
bool atf_fs_stat_is_other_writable(const atf_fs_stat_t *);
bool atf_fs_stat_is_other_executable(const atf_fs_stat_t *);
/* ---------------------------------------------------------------------
* Free functions.
* --------------------------------------------------------------------- */
extern const int atf_fs_access_f;
extern const int atf_fs_access_r;
extern const int atf_fs_access_w;
extern const int atf_fs_access_x;
atf_error_t atf_fs_cleanup(const atf_fs_path_t *);
atf_error_t atf_fs_eaccess(const atf_fs_path_t *, int);
atf_error_t atf_fs_exists(const atf_fs_path_t *, bool *);
atf_error_t atf_fs_getcwd(atf_fs_path_t *);
atf_error_t atf_fs_mkdtemp(atf_fs_path_t *);
#endif /* !defined(ATF_C_FS_H) */

99
dist/atf/atf-c/io.c vendored
View File

@ -1,99 +0,0 @@
/*
* 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
* 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 <sys/types.h>
#include <errno.h>
#include <stdarg.h>
#include <unistd.h>
#include "atf-c/dynstr.h"
#include "atf-c/io.h"
#include "atf-c/sanity.h"
atf_error_t
atf_io_readline(int fd, atf_dynstr_t *dest)
{
char ch[2];
ssize_t cnt;
atf_error_t err;
ch[1] = '\0';
while ((cnt = read(fd, &ch[0], sizeof(ch[0]))) == sizeof(ch[0]) &&
ch[0] != '\n') {
atf_dynstr_append_fmt(dest, ch);
}
if (cnt == -1)
err = atf_libc_error(errno, "Failed to read line from file "
"descriptor %d", fd);
else
err = atf_no_error();
return err;
}
atf_error_t
atf_io_write_ap(int fd, const char *fmt, va_list ap)
{
atf_error_t err;
atf_dynstr_t str;
err = atf_dynstr_init_ap(&str, fmt, ap);
if (!atf_is_error(err)) {
ssize_t cnt = write(fd, atf_dynstr_cstring(&str),
atf_dynstr_length(&str));
if (cnt == -1)
err = atf_libc_error(errno, "Failed to write '%s' to file "
"descriptor %d", atf_dynstr_cstring(&str),
fd);
else {
INV(cnt == atf_dynstr_length(&str));
err = atf_no_error();
}
atf_dynstr_fini(&str);
}
return err;
}
atf_error_t
atf_io_write_fmt(int fd, const char *fmt, ...)
{
atf_error_t err;
va_list ap;
va_start(ap, fmt);
err = atf_io_write_ap(fd, fmt, ap);
va_end(ap);
return err;
}

46
dist/atf/atf-c/io.h vendored
View File

@ -1,46 +0,0 @@
/*
* 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
* 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_C_IO_H)
#define ATF_C_IO_H
#include <stdarg.h>
#include <atf-c/error.h>
struct atf_dynstr;
/* TODO: It would be nice to have an 'atf_io_file_t' type and avoid using
* raw file descriptors. */
atf_error_t atf_io_readline(int, struct atf_dynstr *);
atf_error_t atf_io_write_ap(int, const char *, va_list);
atf_error_t atf_io_write_fmt(int, const char *, ...);
#endif /* !defined(ATF_C_IO_H) */

291
dist/atf/atf-c/list.c vendored
View File

@ -1,291 +0,0 @@
/*
* 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
* 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 <stdlib.h>
#include "atf-c/list.h"
#include "atf-c/sanity.h"
/* ---------------------------------------------------------------------
* Auxiliary functions.
* --------------------------------------------------------------------- */
struct list_entry {
struct list_entry *m_prev;
struct list_entry *m_next;
void *m_object;
};
static
atf_list_citer_t
entry_to_citer(const atf_list_t *l, const struct list_entry *le)
{
atf_list_citer_t iter;
iter.m_list = l;
iter.m_entry = le;
return iter;
}
static
atf_list_iter_t
entry_to_iter(atf_list_t *l, struct list_entry *le)
{
atf_list_iter_t iter;
iter.m_list = l;
iter.m_entry = le;
return iter;
}
static
struct list_entry *
new_entry(void *object)
{
struct list_entry *le;
le = (struct list_entry *)malloc(sizeof(*le));
if (le != NULL) {
le->m_prev = le->m_next = NULL;
le->m_object = object;
}
return le;
}
static
struct list_entry *
new_entry_and_link(void *object, struct list_entry *prev,
struct list_entry *next)
{
struct list_entry *le;
le = new_entry(object);
if (le != NULL) {
le->m_prev = prev;
le->m_next = next;
prev->m_next = le;
next->m_prev = le;
}
return le;
}
/* ---------------------------------------------------------------------
* The "atf_list_citer" type.
* --------------------------------------------------------------------- */
/*
* Getters.
*/
const void *
atf_list_citer_data(const atf_list_citer_t citer)
{
const struct list_entry *le = citer.m_entry;
PRE(le != NULL);
return le->m_object;
}
atf_list_citer_t
atf_list_citer_next(const atf_list_citer_t citer)
{
const struct list_entry *le = citer.m_entry;
atf_list_citer_t newciter;
PRE(le != NULL);
newciter = citer;
newciter.m_entry = le->m_next;
return newciter;
}
bool
atf_equal_list_citer_list_citer(const atf_list_citer_t i1,
const atf_list_citer_t i2)
{
return i1.m_list == i2.m_list && i1.m_entry == i2.m_entry;
}
/* ---------------------------------------------------------------------
* The "atf_list_iter" type.
* --------------------------------------------------------------------- */
/*
* Getters.
*/
void *
atf_list_iter_data(const atf_list_iter_t iter)
{
const struct list_entry *le = iter.m_entry;
PRE(le != NULL);
return le->m_object;
}
atf_list_iter_t
atf_list_iter_next(const atf_list_iter_t iter)
{
const struct list_entry *le = iter.m_entry;
atf_list_iter_t newiter;
PRE(le != NULL);
newiter = iter;
newiter.m_entry = le->m_next;
return newiter;
}
bool
atf_equal_list_iter_list_iter(const atf_list_iter_t i1,
const atf_list_iter_t i2)
{
return i1.m_list == i2.m_list && i1.m_entry == i2.m_entry;
}
/* ---------------------------------------------------------------------
* The "atf_list" type.
* --------------------------------------------------------------------- */
/*
* Constructors and destructors.
*/
atf_error_t
atf_list_init(atf_list_t *l)
{
struct list_entry *lebeg, *leend;
lebeg = new_entry(NULL);
if (lebeg == NULL) {
return atf_no_memory_error();
}
leend = new_entry(NULL);
if (leend == NULL) {
free(lebeg);
return atf_no_memory_error();
}
lebeg->m_next = leend;
lebeg->m_prev = NULL;
leend->m_next = NULL;
leend->m_prev = lebeg;
l->m_size = 0;
l->m_begin = lebeg;
l->m_end = leend;
atf_object_init(&l->m_object);
return atf_no_error();
}
void
atf_list_fini(atf_list_t *l)
{
struct list_entry *le;
size_t freed;
le = (struct list_entry *)l->m_begin;
freed = 0;
while (le != NULL) {
struct list_entry *lenext;
lenext = le->m_next;
free(le);
le = lenext;
freed++;
}
INV(freed == l->m_size + 2);
atf_object_fini(&l->m_object);
}
/*
* Getters.
*/
atf_list_iter_t
atf_list_begin(atf_list_t *l)
{
struct list_entry *le = l->m_begin;
return entry_to_iter(l, le->m_next);
}
atf_list_citer_t
atf_list_begin_c(const atf_list_t *l)
{
const struct list_entry *le = l->m_begin;
return entry_to_citer(l, le->m_next);
}
atf_list_iter_t
atf_list_end(atf_list_t *l)
{
return entry_to_iter(l, l->m_end);
}
atf_list_citer_t
atf_list_end_c(const atf_list_t *l)
{
return entry_to_citer(l, l->m_end);
}
size_t
atf_list_size(const atf_list_t *l)
{
return l->m_size;
}
/*
* Modifiers.
*/
atf_error_t
atf_list_append(atf_list_t *l, void *data)
{
struct list_entry *le, *next, *prev;
atf_error_t err;
next = (struct list_entry *)l->m_end;
prev = next->m_prev;
le = new_entry_and_link(data, prev, next);
if (le == NULL)
err = atf_no_memory_error();
else {
l->m_size++;
err = atf_no_error();
}
return err;
}

112
dist/atf/atf-c/list.h vendored
View File

@ -1,112 +0,0 @@
/*
* 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
* 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_C_LIST_H)
#define ATF_C_LIST_H
#include <stdarg.h>
#include <atf-c/error.h>
#include <atf-c/object.h>
/* ---------------------------------------------------------------------
* The "atf_list_citer" type.
* --------------------------------------------------------------------- */
struct atf_list_citer {
const struct atf_list *m_list;
const void *m_entry;
};
typedef struct atf_list_citer atf_list_citer_t;
/* Getters. */
const void *atf_list_citer_data(const atf_list_citer_t);
atf_list_citer_t atf_list_citer_next(const atf_list_citer_t);
/* Operators. */
bool atf_equal_list_citer_list_citer(const atf_list_citer_t,
const atf_list_citer_t);
/* ---------------------------------------------------------------------
* The "atf_list_iter" type.
* --------------------------------------------------------------------- */
struct atf_list_iter {
struct atf_list *m_list;
void *m_entry;
};
typedef struct atf_list_iter atf_list_iter_t;
/* Getters. */
void *atf_list_iter_data(const atf_list_iter_t);
atf_list_iter_t atf_list_iter_next(const atf_list_iter_t);
/* Operators. */
bool atf_equal_list_iter_list_iter(const atf_list_iter_t,
const atf_list_iter_t);
/* ---------------------------------------------------------------------
* The "atf_list" type.
* --------------------------------------------------------------------- */
struct atf_list {
atf_object_t m_object;
void *m_begin;
void *m_end;
size_t m_size;
};
typedef struct atf_list atf_list_t;
/* Constructors and destructors */
atf_error_t atf_list_init(atf_list_t *);
void atf_list_fini(atf_list_t *);
/* Getters. */
atf_list_iter_t atf_list_begin(atf_list_t *);
atf_list_citer_t atf_list_begin_c(const atf_list_t *);
atf_list_iter_t atf_list_end(atf_list_t *);
atf_list_citer_t atf_list_end_c(const atf_list_t *);
size_t atf_list_size(const atf_list_t *);
/* Modifiers. */
atf_error_t atf_list_append(atf_list_t *, void *);
/* Macros. */
#define atf_list_for_each(iter, list) \
for (iter = atf_list_begin(list); \
!atf_equal_list_iter_list_iter((iter), atf_list_end(list)); \
iter = atf_list_iter_next(iter))
#define atf_list_for_each_c(iter, list) \
for (iter = atf_list_begin_c(list); \
!atf_equal_list_citer_list_citer((iter), atf_list_end_c(list)); \
iter = atf_list_citer_next(iter))
#endif /* ATF_C_LIST_H */

View File

@ -1,124 +0,0 @@
/*
* 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
* 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_C_MACROS_H)
#define ATF_C_MACROS_H
#include <atf-c/tc.h>
#include <atf-c/tp.h>
#define ATF_TC(tc) \
static void atfu_ ## tc ## _head(atf_tc_t *); \
static void atfu_ ## tc ## _body(const atf_tc_t *); \
static atf_tc_t atfu_ ## tc ## _tc; \
static atf_tc_pack_t atfu_ ## tc ## _tc_pack = { \
.m_ident = #tc, \
.m_head = atfu_ ## tc ## _head, \
.m_body = atfu_ ## tc ## _body, \
.m_cleanup = NULL, \
}
#define ATF_TC_NAME(tc) \
(atfu_ ## tc ## _tc)
#define ATF_TC_WITH_CLEANUP(tc) \
static void atfu_ ## tc ## _head(atf_tc_t *); \
static void atfu_ ## tc ## _body(const atf_tc_t *); \
static void atfu_ ## tc ## _cleanup(const atf_tc_t *); \
static atf_tc_t atfu_ ## tc ## _tc; \
static atf_tc_pack_t atfu_ ## tc ## _tc_pack = { \
.m_ident = #tc, \
.m_head = atfu_ ## tc ## _head, \
.m_body = atfu_ ## tc ## _body, \
.m_cleanup = atfu_ ## tc ## _cleanup, \
}
#define ATF_TC_HEAD(tc, tcptr) \
static \
void \
atfu_ ## tc ## _head(atf_tc_t *tcptr)
#define ATF_TC_HEAD_NAME(tc) \
(atfu_ ## tc ## _head)
#define ATF_TC_BODY(tc, tcptr) \
static \
void \
atfu_ ## tc ## _body(const atf_tc_t *tcptr)
#define ATF_TC_BODY_NAME(tc) \
(atfu_ ## tc ## _body)
#define ATF_TC_CLEANUP(tc, tcptr) \
static \
void \
atfu_ ## tc ## _cleanup(const atf_tc_t *tcptr)
#define ATF_TC_CLEANUP_NAME(tc) \
(atfu_ ## tc ## _cleanup)
#define ATF_TP_ADD_TCS(tps) \
static atf_error_t atfu_tp_add_tcs(atf_tp_t *); \
int atf_tp_main(int, char **, atf_error_t (*)(atf_tp_t *)); \
\
int \
main(int argc, char **argv) \
{ \
return atf_tp_main(argc, argv, atfu_tp_add_tcs); \
} \
static \
atf_error_t \
atfu_tp_add_tcs(atf_tp_t *tps)
#define ATF_TP_ADD_TC(tp, tc) \
do { \
atf_error_t atfu_err; \
atfu_err = atf_tc_init_pack(&atfu_ ## tc ## _tc, \
&atfu_ ## tc ## _tc_pack, \
atf_tp_get_config(tp)); \
if (atf_is_error(atfu_err)) \
return atfu_err; \
atfu_err = atf_tp_add_tc(tp, &atfu_ ## tc ## _tc); \
if (atf_is_error(atfu_err)) \
return atfu_err; \
} while (0)
#define ATF_CHECK(x) \
do { \
if (!(x)) \
atf_tc_fail("Line %d: %s not met", __LINE__, #x); \
} while (0)
#define ATF_CHECK_EQUAL(x, y) \
do { \
if ((x) != (y)) \
atf_tc_fail("Line %d: %s != %s", __LINE__, #x, #y); \
} while (0)
#endif /* !defined(ATF_C_MACROS_H) */

257
dist/atf/atf-c/map.c vendored
View File

@ -1,257 +0,0 @@
/*
* 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
* 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 <stdlib.h>
#include <string.h>
#include "atf-c/map.h"
#include "atf-c/sanity.h"
/* ---------------------------------------------------------------------
* Auxiliary functions.
* --------------------------------------------------------------------- */
struct map_entry {
char *m_key;
void *m_value;
bool m_managed;
};
static
struct map_entry *
new_entry(const char *key, void *value, bool managed)
{
struct map_entry *me;
me = (struct map_entry *)malloc(sizeof(*me));
if (me != NULL) {
me->m_key = strdup(key);
if (me->m_key == NULL) {
free(me);
me = NULL;
} else {
me->m_value = value;
me->m_managed = managed;
}
}
return me;
}
/* ---------------------------------------------------------------------
* The "atf_map_citer" type.
* --------------------------------------------------------------------- */
/*
* Getters.
*/
const void *
atf_map_citer_data(const atf_map_citer_t citer)
{
const struct map_entry *me = citer.m_entry;
PRE(me != NULL);
return me->m_value;
}
bool
atf_equal_map_citer_map_citer(const atf_map_citer_t i1,
const atf_map_citer_t i2)
{
return i1.m_map == i2.m_map && i1.m_entry == i2.m_entry;
}
/* ---------------------------------------------------------------------
* The "atf_map_iter" type.
* --------------------------------------------------------------------- */
/*
* Getters.
*/
void *
atf_map_iter_data(const atf_map_iter_t iter)
{
const struct map_entry *me = iter.m_entry;
PRE(me != NULL);
return me->m_value;
}
bool
atf_equal_map_iter_map_iter(const atf_map_iter_t i1,
const atf_map_iter_t i2)
{
return i1.m_map == i2.m_map && i1.m_entry == i2.m_entry;
}
/* ---------------------------------------------------------------------
* The "atf_map" type.
* --------------------------------------------------------------------- */
/*
* Constructors and destructors.
*/
atf_error_t
atf_map_init(atf_map_t *m)
{
atf_error_t err;
err = atf_list_init(&m->m_list);
if (atf_is_error(err))
goto out;
atf_object_init(&m->m_object);
out:
return err;
}
void
atf_map_fini(atf_map_t *m)
{
atf_list_iter_t iter;
atf_list_for_each(iter, &m->m_list) {
struct map_entry *me = atf_list_iter_data(iter);
if (me->m_managed)
free(me->m_value);
free(me->m_key);
free(me);
}
atf_list_fini(&m->m_list);
atf_object_fini(&m->m_object);
}
/*
* Getters.
*/
atf_map_iter_t
atf_map_end(atf_map_t *m)
{
atf_map_iter_t iter;
iter.m_map = m;
iter.m_entry = NULL;
return iter;
}
atf_map_citer_t
atf_map_end_c(const atf_map_t *m)
{
atf_map_citer_t iter;
iter.m_map = m;
iter.m_entry = NULL;
return iter;
}
atf_map_iter_t
atf_map_find(atf_map_t *m, const char *key)
{
atf_list_iter_t iter;
atf_list_for_each(iter, &m->m_list) {
struct map_entry *me = atf_list_iter_data(iter);
if (strcmp(me->m_key, key) == 0) {
atf_map_iter_t i;
i.m_map = m;
i.m_entry = me;
return i;
}
}
return atf_map_end(m);
}
atf_map_citer_t
atf_map_find_c(const atf_map_t *m, const char *key)
{
atf_list_citer_t iter;
atf_list_for_each_c(iter, &m->m_list) {
const struct map_entry *me = atf_list_citer_data(iter);
if (strcmp(me->m_key, key) == 0) {
atf_map_citer_t i;
i.m_map = m;
i.m_entry = me;
return i;
}
}
return atf_map_end_c(m);
}
size_t
atf_map_size(const atf_map_t *m)
{
return atf_list_size(&m->m_list);
}
/*
* Modifiers.
*/
atf_error_t
atf_map_insert(atf_map_t *m, const char *key, void *value, bool managed)
{
struct map_entry *me;
atf_error_t err;
atf_map_iter_t iter;
iter = atf_map_find(m, key);
if (atf_equal_map_iter_map_iter(iter, atf_map_end(m))) {
me = new_entry(key, value, managed);
if (me == NULL)
err = atf_no_memory_error();
else {
err = atf_list_append(&m->m_list, me);
if (atf_is_error(err)) {
if (managed)
free(value);
free(me);
}
}
} else {
me = iter.m_entry;
if (me->m_managed)
free(me->m_value);
INV(strcmp(me->m_key, key) == 0);
me->m_value = value;
me->m_managed = managed;
err = atf_no_error();
}
return err;
}

101
dist/atf/atf-c/map.h vendored
View File

@ -1,101 +0,0 @@
/*
* 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
* 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_C_MAP_H)
#define ATF_C_MAP_H
#include <stdarg.h>
#include <stdbool.h>
#include <atf-c/error.h>
#include <atf-c/list.h>
#include <atf-c/object.h>
/* ---------------------------------------------------------------------
* The "atf_map_citer" type.
* --------------------------------------------------------------------- */
struct atf_map_citer {
const struct atf_map *m_map;
const void *m_entry;
};
typedef struct atf_map_citer atf_map_citer_t;
/* Getters. */
const void *atf_map_citer_data(const atf_map_citer_t);
/* Operators. */
bool atf_equal_map_citer_map_citer(const atf_map_citer_t,
const atf_map_citer_t);
/* ---------------------------------------------------------------------
* The "atf_map_iter" type.
* --------------------------------------------------------------------- */
struct atf_map_iter {
struct atf_map *m_map;
void *m_entry;
};
typedef struct atf_map_iter atf_map_iter_t;
/* Getters. */
void *atf_map_iter_data(const atf_map_iter_t);
/* Operators. */
bool atf_equal_map_iter_map_iter(const atf_map_iter_t,
const atf_map_iter_t);
/* ---------------------------------------------------------------------
* The "atf_map" type.
* --------------------------------------------------------------------- */
/* A list-based map. Typically very inefficient, but our maps are small
* enough. */
struct atf_map {
atf_object_t m_object;
atf_list_t m_list;
};
typedef struct atf_map atf_map_t;
/* Constructors and destructors */
atf_error_t atf_map_init(atf_map_t *);
void atf_map_fini(atf_map_t *);
/* Getters. */
atf_map_iter_t atf_map_end(atf_map_t *);
atf_map_citer_t atf_map_end_c(const atf_map_t *);
atf_map_iter_t atf_map_find(atf_map_t *, const char *);
atf_map_citer_t atf_map_find_c(const atf_map_t *, const char *);
size_t atf_map_size(const atf_map_t *);
/* Modifiers. */
atf_error_t atf_map_insert(atf_map_t *, const char *, void *, bool);
#endif /* ATF_C_MAP_H */

View File

@ -1,109 +0,0 @@
/*
* 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
* 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 <err.h>
#include <stdlib.h>
#include "atf-c/object.h"
#include "atf-c/sanity.h"
static size_t balance = 0;
static bool initialized = false;
static bool exit_checks = true;
/* ---------------------------------------------------------------------
* The "atf_object" type.
* --------------------------------------------------------------------- */
static const uint32_t atf_object_magic_alive = 0xcafebabe;
static const uint32_t atf_object_magic_dead = 0xdeadbeef;
void
atf_object_init(atf_object_t *o)
{
PRE(initialized);
o->m_magic = atf_object_magic_alive;
o->m_finis = 0;
balance++;
}
void
atf_object_copy(atf_object_t *dest, const atf_object_t *src)
{
atf_object_init(dest);
}
void
atf_object_fini(atf_object_t *o)
{
PRE(initialized);
PRE(o->m_magic == atf_object_magic_alive);
PRE(o->m_finis == 0);
PRE(balance > 0);
o->m_magic = atf_object_magic_dead;
o->m_finis++;
balance--;
}
/* ---------------------------------------------------------------------
* Free functions.
* --------------------------------------------------------------------- */
static
void
check_balance(void)
{
PRE(initialized);
if (exit_checks && balance > 0) {
warnx("FATAL ERROR: Invalid balance: %zd objects were not "
"released", balance);
abort();
}
}
void
atf_init_objects(void)
{
initialized = true;
if (atexit(check_balance) == -1)
err(EXIT_FAILURE, "FATAL ERROR: Cannot initialize object system");
}
void
atf_disable_exit_checks(void)
{
exit_checks = false;
}

View File

@ -1,58 +0,0 @@
/*
* 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
* 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_C_OBJECT_H)
#define ATF_C_OBJECT_H
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
/* ---------------------------------------------------------------------
* The "atf_object" type.
* --------------------------------------------------------------------- */
struct atf_object {
uint32_t m_magic;
size_t m_finis;
};
typedef struct atf_object atf_object_t;
void atf_object_init(atf_object_t *);
void atf_object_copy(atf_object_t *, const atf_object_t *);
void atf_object_fini(atf_object_t *);
/* ---------------------------------------------------------------------
* Free functions.
* --------------------------------------------------------------------- */
void atf_init_objects(void);
void atf_disable_exit_checks(void);
#endif /* ATF_C_OBJECT_H */

View File

@ -1,78 +0,0 @@
/*
* 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
* 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(HAVE_CONFIG_H)
#include "bconfig.h"
#endif
#include <err.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include "atf-c/sanity.h"
static
void
fail(const char *fmt, ...)
{
va_list ap;
char buf[4096];
va_start(ap, fmt);
vsnprintf(buf, sizeof(buf), fmt, ap);
va_end(ap);
warnx("%s", buf);
warnx("%s", "");
warnx("This is probably a bug in this application or one of the "
"libraries it uses. If you believe this problem is caused "
"by, or is related to " PACKAGE_STRING ", please report it "
"to " PACKAGE_BUGREPORT " and provide as many detatils as "
"possible describing how you got to this condition.");
abort();
}
void
atf_sanity_inv(const char *file, int line, const char *cond)
{
fail("Invariant check failed at %s:%d: %s", file, line, cond);
}
void
atf_sanity_pre(const char *file, int line, const char *cond)
{
fail("Precondition check failed at %s:%d: %s", file, line, cond);
}
void
atf_sanity_post(const char *file, int line, const char *cond)
{
fail("Postcondition check failed at %s:%d: %s", file, line, cond);
}

View File

@ -1,73 +0,0 @@
/*
* 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
* 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_C_SANITY_H)
#define ATF_C_SANITY_H
void atf_sanity_inv(const char *, int, const char *);
void atf_sanity_pre(const char *, int, const char *);
void atf_sanity_post(const char *, int, const char *);
#if !defined(NDEBUG)
#define INV(x) \
do { \
if (!(x)) \
atf_sanity_inv(__FILE__, __LINE__, #x); \
} while (0)
#define PRE(x) \
do { \
if (!(x)) \
atf_sanity_pre(__FILE__, __LINE__, #x); \
} while (0)
#define POST(x) \
do { \
if (!(x)) \
atf_sanity_post(__FILE__, __LINE__, #x); \
} while (0)
#else /* defined(NDEBUG) */
#define INV(x) \
do { \
} while (0)
#define PRE(x) \
do { \
} while (0)
#define POST(x) \
do { \
} while (0)
#endif /* !defined(NDEBUG) */
#define UNREACHABLE INV(0)
#endif /* ATF_C_SANITY_H */

View File

@ -1,167 +0,0 @@
/*
* Automated Testing Framework (atf)
*
* Copyright (c) 2007, 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
* 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(HAVE_CONFIG_H)
#include "bconfig.h"
#endif
#include <sys/types.h>
#include <errno.h>
#include <stdbool.h>
#include <unistd.h>
#include "atf-c/sanity.h"
#include "atf-c/signals.h"
const int atf_signals_last_signo = LAST_SIGNO;
/* ---------------------------------------------------------------------
* The "atf_signal_holder" type.
* --------------------------------------------------------------------- */
static bool happened[LAST_SIGNO + 1];
static
void
holder_handler(int signo)
{
happened[signo] = true;
}
/*
* Constructors/destructors.
*/
atf_error_t
atf_signal_holder_init(atf_signal_holder_t *sh, int signo)
{
atf_error_t err;
err = atf_signal_programmer_init(&sh->m_sp, signo, holder_handler);
if (atf_is_error(err))
goto out;
atf_object_init(&sh->m_object);
sh->m_signo = signo;
happened[signo] = false;
INV(!atf_is_error(err));
out:
return err;
}
void
atf_signal_holder_fini(atf_signal_holder_t *sh)
{
atf_signal_programmer_fini(&sh->m_sp);
if (happened[sh->m_signo])
kill(getpid(), sh->m_signo);
atf_object_fini(&sh->m_object);
}
/*
* Getters.
*/
void
atf_signal_holder_process(atf_signal_holder_t *sh)
{
if (happened[sh->m_signo]) {
int ret;
atf_error_t err;
atf_signal_programmer_fini(&sh->m_sp);
happened[sh->m_signo] = false;
ret = kill(getpid(), sh->m_signo);
INV(ret != -1);
err = atf_signal_programmer_init(&sh->m_sp, sh->m_signo,
holder_handler);
INV(!atf_is_error(err));
}
}
/* ---------------------------------------------------------------------
* The "atf_signal_programmer" type.
* --------------------------------------------------------------------- */
/*
* Constructors/destructors.
*/
atf_error_t
atf_signal_programmer_init(atf_signal_programmer_t *sp, int signo,
atf_signal_handler_t handler)
{
atf_error_t err;
struct sigaction sa;
sa.sa_handler = handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
if (sigaction(signo, &sa, &sp->m_oldsa) == -1)
err = atf_libc_error(errno, "Failed to program signal %d", signo);
else {
atf_object_init(&sp->m_object);
sp->m_signo = signo;
err = atf_no_error();
}
return err;
}
void
atf_signal_programmer_fini(atf_signal_programmer_t *sp)
{
if (sigaction(sp->m_signo, &sp->m_oldsa, NULL) == -1)
UNREACHABLE;
atf_object_fini(&sp->m_object);
}
/* ---------------------------------------------------------------------
* Free functions.
* --------------------------------------------------------------------- */
void
atf_signal_reset(int signo)
{
struct sigaction sa;
sa.sa_handler = SIG_DFL;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
(void)sigaction(signo, &sa, NULL);
}

View File

@ -1,85 +0,0 @@
/*
* 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
* 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_C_SIGNALS_H)
#define ATF_C_SIGNALS_H
#include <signal.h>
#include <stdbool.h>
#include <atf-c/error.h>
#include <atf-c/object.h>
extern const int atf_signals_last_signo;
typedef void (*atf_signal_handler_t)(int);
/* ---------------------------------------------------------------------
* The "atf_signal_programmer" type.
* --------------------------------------------------------------------- */
struct atf_signal_programmer {
atf_object_t m_object;
int m_signo;
atf_signal_handler_t m_handler;
struct sigaction m_oldsa;
};
typedef struct atf_signal_programmer atf_signal_programmer_t;
/* Constructors/destructors. */
atf_error_t atf_signal_programmer_init(atf_signal_programmer_t *, int,
atf_signal_handler_t);
void atf_signal_programmer_fini(atf_signal_programmer_t *);
/* ---------------------------------------------------------------------
* The "atf_signal_holder" type.
* --------------------------------------------------------------------- */
struct atf_signal_holder {
atf_object_t m_object;
int m_signo;
atf_signal_programmer_t m_sp;
};
typedef struct atf_signal_holder atf_signal_holder_t;
/* Constructors/destructors. */
atf_error_t atf_signal_holder_init(atf_signal_holder_t *, int);
void atf_signal_holder_fini(atf_signal_holder_t *);
/* Modifiers. */
void atf_signal_holder_process(atf_signal_holder_t *);
/* ---------------------------------------------------------------------
* Free functions.
* --------------------------------------------------------------------- */
void atf_signal_reset(int);
#endif /* ATF_C_SIGNALS_H */

1040
dist/atf/atf-c/tc.c vendored

File diff suppressed because it is too large Load Diff

114
dist/atf/atf-c/tc.h vendored
View File

@ -1,114 +0,0 @@
/*
* 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
* 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_C_TC_H)
#define ATF_C_TC_H
#include <atf-c/defs.h>
#include <atf-c/error.h>
#include <atf-c/map.h>
#include <atf-c/object.h>
struct atf_dynstr;
struct atf_fs_path;
struct atf_tc;
struct atf_tcr;
typedef void (*atf_tc_head_t)(struct atf_tc *);
typedef void (*atf_tc_body_t)(const struct atf_tc *);
typedef void (*atf_tc_cleanup_t)(const struct atf_tc *);
/* ---------------------------------------------------------------------
* The "atf_tc_pack" type.
* --------------------------------------------------------------------- */
/* For static initialization only. */
struct atf_tc_pack {
const char *m_ident;
const atf_map_t *m_config;
atf_tc_head_t m_head;
atf_tc_body_t m_body;
atf_tc_cleanup_t m_cleanup;
};
typedef const struct atf_tc_pack atf_tc_pack_t;
/* ---------------------------------------------------------------------
* The "atf_tc" type.
* --------------------------------------------------------------------- */
struct atf_tc {
atf_object_t m_object;
const char *m_ident;
atf_map_t m_vars;
const atf_map_t *m_config;
atf_tc_head_t m_head;
atf_tc_body_t m_body;
atf_tc_cleanup_t m_cleanup;
};
typedef struct atf_tc atf_tc_t;
/* Constructors/destructors. */
atf_error_t atf_tc_init(atf_tc_t *, const char *, atf_tc_head_t,
atf_tc_body_t, atf_tc_cleanup_t,
const atf_map_t *);
atf_error_t atf_tc_init_pack(atf_tc_t *, atf_tc_pack_t *,
const atf_map_t *);
void atf_tc_fini(atf_tc_t *);
/* Getters. */
const char *atf_tc_get_ident(const atf_tc_t *);
const char *atf_tc_get_config_var(const atf_tc_t *, const char *);
const char *atf_tc_get_config_var_wd(const atf_tc_t *, const char *,
const char *);
const char *atf_tc_get_md_var(const atf_tc_t *, const char *);
bool atf_tc_has_config_var(const atf_tc_t *, const char *);
bool atf_tc_has_md_var(const atf_tc_t *, const char *);
/* Modifiers. */
atf_error_t atf_tc_set_md_var(atf_tc_t *, const char *, const char *, ...);
/* ---------------------------------------------------------------------
* Free functions.
* --------------------------------------------------------------------- */
atf_error_t atf_tc_run(const atf_tc_t *, struct atf_tcr *,
const struct atf_fs_path *);
/* To be run from test case bodies only. */
void atf_tc_fail(const char *, ...) ATF_DEFS_ATTRIBUTE_NORETURN;
void atf_tc_pass(void) ATF_DEFS_ATTRIBUTE_NORETURN;
void atf_tc_require_prog(const char *);
void atf_tc_skip(const char *, ...) ATF_DEFS_ATTRIBUTE_NORETURN;
#endif /* ATF_C_TC_H */

200
dist/atf/atf-c/tcr.c vendored
View File

@ -1,200 +0,0 @@
/*
* 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
* 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 <stdbool.h>
#include "atf-c/sanity.h"
#include "atf-c/tcr.h"
/* ---------------------------------------------------------------------
* Auxiliary types and functions.
* --------------------------------------------------------------------- */
static
bool
state_allows_reason(atf_tcr_state_t state)
{
return state == atf_tcr_failed_state || state == atf_tcr_skipped_state;
}
static
atf_error_t
format_reason(atf_dynstr_t *reason, const char *fmt, va_list ap)
{
atf_error_t err;
atf_dynstr_t tmp;
va_list ap2;
va_copy(ap2, ap);
err = atf_dynstr_init_ap(&tmp, fmt, ap2);
va_end(ap2);
if (atf_is_error(err))
goto out;
/* There is no reason for calling rfind instead of find other than
* find is not implemented. */
if (atf_dynstr_rfind_ch(&tmp, '\n') == atf_dynstr_npos) {
err = atf_dynstr_copy(reason, &tmp);
} else {
const char *iter;
err = atf_dynstr_init_fmt(reason, "BOGUS REASON (THE ORIGINAL "
"HAD NEWLINES): ");
if (atf_is_error(err))
goto out_tmp;
for (iter = atf_dynstr_cstring(&tmp); *iter != '\0'; iter++) {
if (*iter == '\n')
err = atf_dynstr_append_fmt(reason, "<<NEWLINE>>");
else
err = atf_dynstr_append_fmt(reason, "%c", *iter);
if (atf_is_error(err)) {
atf_dynstr_fini(reason);
break;
}
}
}
out_tmp:
atf_dynstr_fini(&tmp);
out:
return err;
}
/* ---------------------------------------------------------------------
* The "atf_tcr" type.
* --------------------------------------------------------------------- */
/*
* Constants.
*/
const atf_tcr_state_t atf_tcr_passed_state = 0;
const atf_tcr_state_t atf_tcr_failed_state = 1;
const atf_tcr_state_t atf_tcr_skipped_state = 2;
/*
* Constructors/destructors.
*/
atf_error_t
atf_tcr_init(atf_tcr_t *tcr, atf_tcr_state_t state)
{
atf_error_t err;
PRE(!state_allows_reason(state));
atf_object_init(&tcr->m_object);
tcr->m_state = state;
err = atf_dynstr_init(&tcr->m_reason);
if (atf_is_error(err))
goto err_object;
INV(!atf_is_error(err));
return err;
err_object:
atf_object_fini(&tcr->m_object);
return err;
}
atf_error_t
atf_tcr_init_reason_ap(atf_tcr_t *tcr, atf_tcr_state_t state,
const char *fmt, va_list ap)
{
va_list ap2;
atf_error_t err;
PRE(state_allows_reason(state));
atf_object_init(&tcr->m_object);
tcr->m_state = state;
va_copy(ap2, ap);
err = format_reason(&tcr->m_reason, fmt, ap2);
va_end(ap2);
if (atf_is_error(err))
goto err_object;
INV(!atf_is_error(err));
return err;
err_object:
atf_object_fini(&tcr->m_object);
return err;
}
atf_error_t
atf_tcr_init_reason_fmt(atf_tcr_t *tcr, atf_tcr_state_t state,
const char *fmt, ...)
{
va_list ap;
atf_error_t err;
va_start(ap, fmt);
err = atf_tcr_init_reason_ap(tcr, state, fmt, ap);
va_end(ap);
return err;
}
void
atf_tcr_fini(atf_tcr_t *tcr)
{
atf_dynstr_fini(&tcr->m_reason);
atf_object_fini(&tcr->m_object);
}
/*
* Getters. */
atf_tcr_state_t
atf_tcr_get_state(const atf_tcr_t *tcr)
{
return tcr->m_state;
}
const atf_dynstr_t *
atf_tcr_get_reason(const atf_tcr_t *tcr)
{
PRE(state_allows_reason(tcr->m_state));
return &tcr->m_reason;
}
bool
atf_tcr_has_reason(const atf_tcr_t *tcr)
{
return state_allows_reason(tcr->m_state);
}

72
dist/atf/atf-c/tcr.h vendored
View File

@ -1,72 +0,0 @@
/*
* 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
* 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_C_TCR_H)
#define ATF_C_TCR_H
#include <stdarg.h>
#include <stdbool.h>
#include <atf-c/dynstr.h>
#include <atf-c/error.h>
#include <atf-c/object.h>
/* ---------------------------------------------------------------------
* The "atf_tcr" type.
* --------------------------------------------------------------------- */
typedef int atf_tcr_state_t;
struct atf_tcr {
atf_object_t m_object;
atf_tcr_state_t m_state;
atf_dynstr_t m_reason;
};
typedef struct atf_tcr atf_tcr_t;
/* Constants. */
extern const atf_tcr_state_t atf_tcr_passed_state;
extern const atf_tcr_state_t atf_tcr_failed_state;
extern const atf_tcr_state_t atf_tcr_skipped_state;
/* Constructors/destructors. */
atf_error_t atf_tcr_init(atf_tcr_t *, int);
atf_error_t atf_tcr_init_reason_ap(atf_tcr_t *, atf_tcr_state_t,
const char *, va_list);
atf_error_t atf_tcr_init_reason_fmt(atf_tcr_t *, atf_tcr_state_t,
const char *, ...);
void atf_tcr_fini(atf_tcr_t *);
/* Getters. */
atf_tcr_state_t atf_tcr_get_state(const atf_tcr_t *);
const atf_dynstr_t *atf_tcr_get_reason(const atf_tcr_t *);
bool atf_tcr_has_reason(const atf_tcr_t *);
#endif /* ATF_C_TCR_H */

134
dist/atf/atf-c/text.c vendored
View File

@ -1,134 +0,0 @@
/*
* 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
* 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 <errno.h>
#include <limits.h>
#include <string.h>
#include <stdlib.h>
#include "atf-c/dynstr.h"
#include "atf-c/text.h"
atf_error_t
atf_text_for_each_word(const char *instr, const char *sep,
atf_error_t (*func)(const char *, void *),
void *data)
{
atf_error_t err;
char *str, *str2, *last;
str = strdup(instr);
if (str == NULL) {
err = atf_no_memory_error();
goto out;
}
err = atf_no_error();
str2 = strtok_r(str, sep, &last);
while (str2 != NULL && !atf_is_error(err)) {
err = func(str2, data);
str2 = strtok_r(NULL, sep, &last);
}
free(str);
out:
return err;
}
atf_error_t
atf_text_format(char **dest, const char *fmt, ...)
{
atf_error_t err;
va_list ap;
va_start(ap, fmt);
err = atf_text_format_ap(dest, fmt, ap);
va_end(ap);
return err;
}
atf_error_t
atf_text_format_ap(char **dest, const char *fmt, va_list ap)
{
atf_error_t err;
atf_dynstr_t tmp;
va_list ap2;
va_copy(ap2, ap);
err = atf_dynstr_init_ap(&tmp, fmt, ap2);
va_end(ap2);
if (!atf_is_error(err))
*dest = atf_dynstr_fini_disown(&tmp);
return err;
}
atf_error_t
atf_text_to_bool(const char *str, bool *b)
{
atf_error_t err;
if (strcasecmp(str, "yes") == 0 ||
strcasecmp(str, "true") == 0) {
*b = true;
err = atf_no_error();
} else if (strcasecmp(str, "no") == 0 ||
strcasecmp(str, "false") == 0) {
*b = false;
err = atf_no_error();
} else {
/* XXX Not really a libc error. */
err = atf_libc_error(EINVAL, "Cannot convert string '%s' "
"to boolean", str);
}
return err;
}
atf_error_t
atf_text_to_long(const char *str, long *l)
{
atf_error_t err;
char *endptr;
long tmp;
errno = 0;
tmp = strtol(str, &endptr, 10);
if (str[0] == '\0' || *endptr != '\0')
err = atf_libc_error(EINVAL, "'%s' is not a number", str);
else if (errno == ERANGE || (tmp == LONG_MAX || tmp == LONG_MIN))
err = atf_libc_error(ERANGE, "'%s' is out of range", str);
else {
*l = tmp;
err = atf_no_error();
}
return err;
}

45
dist/atf/atf-c/text.h vendored
View File

@ -1,45 +0,0 @@
/*
* 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
* 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_C_TEXT_H)
#define ATF_C_TEXT_H
#include <stdarg.h>
#include <atf-c/error.h>
atf_error_t atf_text_for_each_word(const char *, const char *,
atf_error_t (*)(const char *, void *),
void *);
atf_error_t atf_text_format(char **, const char *, ...);
atf_error_t atf_text_format_ap(char **, const char *, va_list);
atf_error_t atf_text_to_bool(const char *, bool *);
atf_error_t atf_text_to_long(const char *, long *);
#endif /* ATF_C_TEXT_H */

217
dist/atf/atf-c/tp.c vendored
View File

@ -1,217 +0,0 @@
/*
* 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
* 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 <stdio.h>
#include <string.h>
#include "atf-c/fs.h"
#include "atf-c/io.h"
#include "atf-c/sanity.h"
#include "atf-c/tc.h"
#include "atf-c/tcr.h"
#include "atf-c/tp.h"
/* ---------------------------------------------------------------------
* Auxiliary functions.
* --------------------------------------------------------------------- */
static
const atf_tc_t *
find_tc(const atf_tp_t *tp, const char *ident)
{
const atf_tc_t *tc;
atf_list_citer_t iter;
tc = NULL;
atf_list_for_each_c(iter, &tp->m_tcs) {
const atf_tc_t *tc2;
tc2 = atf_list_citer_data(iter);
if (strcmp(tc2->m_ident, ident) == 0) {
tc = tc2;
break;
}
}
return tc;
}
/* ---------------------------------------------------------------------
* The "atf_tp" type.
* --------------------------------------------------------------------- */
/*
* Constructors/destructors.
*/
atf_error_t
atf_tp_init(atf_tp_t *tp, struct atf_map *config)
{
atf_error_t err;
PRE(config != NULL);
atf_object_init(&tp->m_object);
err = atf_list_init(&tp->m_tcs);
if (atf_is_error(err))
goto err_object;
tp->m_config = config;
INV(!atf_is_error(err));
return err;
err_object:
atf_object_fini(&tp->m_object);
return err;
}
void
atf_tp_fini(atf_tp_t *tp)
{
atf_list_iter_t iter;
atf_list_for_each(iter, &tp->m_tcs) {
atf_tc_t *tc = atf_list_iter_data(iter);
atf_tc_fini(tc);
}
atf_list_fini(&tp->m_tcs);
atf_object_fini(&tp->m_object);
}
/*
* Getters.
*/
const struct atf_map *
atf_tp_get_config(const atf_tp_t *tp)
{
return tp->m_config;
}
const atf_tc_t *
atf_tp_get_tc(const atf_tp_t *tp, const char *id)
{
const atf_tc_t *tc = find_tc(tp, id);
PRE(tc != NULL);
return tc;
}
const atf_list_t *
atf_tp_get_tcs(const atf_tp_t *tp)
{
return &tp->m_tcs;
}
/*
* Modifiers.
*/
atf_error_t
atf_tp_add_tc(atf_tp_t *tp, atf_tc_t *tc)
{
atf_error_t err;
PRE(find_tc(tp, tc->m_ident) == NULL);
err = atf_list_append(&tp->m_tcs, tc);
POST(find_tc(tp, tc->m_ident) != NULL);
return err;
}
/* ---------------------------------------------------------------------
* Free functions.
* --------------------------------------------------------------------- */
atf_error_t
atf_tp_run(const atf_tp_t *tp, const atf_list_t *ids, int fd,
const atf_fs_path_t *workdir, size_t *failcount)
{
atf_error_t err;
atf_list_citer_t iter;
size_t count;
err = atf_io_write_fmt(fd, "Content-Type: application/X-atf-tcs; "
"version=\"1\"\n\n");
if (atf_is_error(err))
goto out;
err = atf_io_write_fmt(fd, "tcs-count: %d\n", atf_list_size(ids));
if (atf_is_error(err))
goto out;
*failcount = count = 0;
atf_list_for_each_c(iter, ids) {
const char *ident = atf_list_citer_data(iter);
const atf_tc_t *tc;
atf_tcr_t tcr;
int state;
err = atf_io_write_fmt(fd, "tc-start: %s\n", ident);
if (atf_is_error(err))
goto out;
tc = find_tc(tp, ident);
PRE(tc != NULL);
err = atf_tc_run(tc, &tcr, workdir);
if (atf_is_error(err))
goto out;
count++;
if (count < atf_list_size(ids)) {
fprintf(stdout, "__atf_tc_separator__\n");
fprintf(stderr, "__atf_tc_separator__\n");
}
fflush(stdout);
fflush(stderr);
state = atf_tcr_get_state(&tcr);
if (state == atf_tcr_passed_state) {
err = atf_io_write_fmt(fd, "tc-end: %s, passed\n", ident);
} else if (state == atf_tcr_failed_state) {
const atf_dynstr_t *reason = atf_tcr_get_reason(&tcr);
err = atf_io_write_fmt(fd, "tc-end: %s, failed, %s\n", ident,
atf_dynstr_cstring(reason));
(*failcount)++;
} else if (state == atf_tcr_skipped_state) {
const atf_dynstr_t *reason = atf_tcr_get_reason(&tcr);
err = atf_io_write_fmt(fd, "tc-end: %s, skipped, %s\n", ident,
atf_dynstr_cstring(reason));
} else
UNREACHABLE;
atf_tcr_fini(&tcr);
if (atf_is_error(err))
goto out;
}
out:
return err;
}

72
dist/atf/atf-c/tp.h vendored
View File

@ -1,72 +0,0 @@
/*
* 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
* 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_C_TP_H)
#define ATF_C_TP_H
#include <atf-c/error.h>
#include <atf-c/list.h>
#include <atf-c/object.h>
struct atf_fs_path;
struct atf_map;
struct atf_tc;
/* ---------------------------------------------------------------------
* The "atf_tp" type.
* --------------------------------------------------------------------- */
struct atf_tp {
atf_object_t m_object;
atf_list_t m_tcs;
const struct atf_map *m_config;
};
typedef struct atf_tp atf_tp_t;
/* Constructors/destructors. */
atf_error_t atf_tp_init(atf_tp_t *, struct atf_map *);
void atf_tp_fini(atf_tp_t *);
/* Getters. */
const struct atf_map *atf_tp_get_config(const atf_tp_t *);
const struct atf_tc *atf_tp_get_tc(const atf_tp_t *, const char *);
const atf_list_t *atf_tp_get_tcs(const atf_tp_t *);
/* Modifiers. */
atf_error_t atf_tp_add_tc(atf_tp_t *, struct atf_tc *);
/* ---------------------------------------------------------------------
* Free functions.
* --------------------------------------------------------------------- */
atf_error_t atf_tp_run(const atf_tp_t *, const atf_list_t *, int,
const struct atf_fs_path *, size_t *);
#endif /* ATF_C_TP_H */

View File

@ -1,648 +0,0 @@
/*
* 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
* 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(HAVE_CONFIG_H)
#include "bconfig.h"
#endif
#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "atf-c/config.h"
#include "atf-c/dynstr.h"
#include "atf-c/expand.h"
#include "atf-c/fs.h"
#include "atf-c/object.h"
#include "atf-c/map.h"
#include "atf-c/sanity.h"
#include "atf-c/tc.h"
#include "atf-c/tp.h"
#include "atf-c/ui.h"
#if defined(HAVE_GNU_GETOPT)
# define GETOPT_POSIX "+"
#else
# define GETOPT_POSIX ""
#endif
static const char *progname = NULL;
/* This prototype is provided by macros.h during instantiation of the test
* program, so it can be kept private. Don't know if that's the best idea
* though. */
int atf_tp_main(int, char **, atf_error_t (*)(atf_tp_t *));
/* ---------------------------------------------------------------------
* The "usage" and "user" error types.
* --------------------------------------------------------------------- */
#define FREE_FORM_ERROR(name) \
struct name ## _error_data { \
char m_what[2048]; \
}; \
\
static \
void \
name ## _format(const atf_error_t err, char *buf, size_t buflen) \
{ \
const struct name ## _error_data *data; \
\
PRE(atf_error_is(err, #name)); \
\
data = atf_error_data(err); \
snprintf(buf, buflen, "%s", data->m_what); \
} \
\
static \
atf_error_t \
name ## _error(const char *fmt, ...) \
{ \
atf_error_t err; \
struct name ## _error_data data; \
va_list ap; \
\
va_start(ap, fmt); \
vsnprintf(data.m_what, sizeof(data.m_what), fmt, ap); \
va_end(ap); \
\
err = atf_error_new(#name, &data, sizeof(data), name ## _format); \
\
return err; \
}
FREE_FORM_ERROR(usage);
FREE_FORM_ERROR(user);
/* ---------------------------------------------------------------------
* Printing functions.
* --------------------------------------------------------------------- */
/* XXX: Why are these functions here? We have got a ui module, and it
* seems the correct place to put these. Otherwise, the functions that
* currently live there only format text, so they'd be moved to the text
* module instead and kill ui completely. */
static
atf_error_t
print_tag(FILE *f, const char *tag, bool repeat, size_t col,
const char *fmt, ...)
{
atf_error_t err;
va_list ap;
atf_dynstr_t dest;
err = atf_dynstr_init(&dest);
if (atf_is_error(err))
goto out;
va_start(ap, fmt);
err = atf_ui_format_ap(&dest, tag, repeat, col, fmt, ap);
va_end(ap);
if (atf_is_error(err))
goto out_dest;
fprintf(f, "%s\n", atf_dynstr_cstring(&dest));
out_dest:
atf_dynstr_fini(&dest);
out:
return err;
}
static
void
print_error(const atf_error_t err)
{
PRE(atf_is_error(err));
if (atf_error_is(err, "no_memory")) {
char buf[1024];
atf_error_format(err, buf, sizeof(buf));
fprintf(stderr, "%s: %s\n", progname, buf);
} else {
atf_dynstr_t tag;
char buf[4096];
atf_error_format(err, buf, sizeof(buf));
atf_dynstr_init_fmt(&tag, "%s: ", progname);
print_tag(stderr, atf_dynstr_cstring(&tag), true, 0,
"ERROR: %s", buf);
if (atf_error_is(err, "usage"))
print_tag(stderr, atf_dynstr_cstring(&tag), true, 0,
"Type `%s -h' for more details.", progname);
atf_dynstr_fini(&tag);
}
}
/* ---------------------------------------------------------------------
* Options handling.
* --------------------------------------------------------------------- */
struct params {
bool m_do_list;
bool m_do_usage;
int m_fd;
const char *m_srcdir;
const char *m_workdir;
atf_list_t m_tcglobs;
atf_map_t m_config;
};
static
atf_error_t
params_init(struct params *p)
{
atf_error_t err;
p->m_do_list = false;
p->m_do_usage = false;
p->m_fd = STDOUT_FILENO;
p->m_srcdir = ".";
p->m_workdir = atf_config_get("atf_workdir");
err = atf_list_init(&p->m_tcglobs);
if (atf_is_error(err))
goto out;
err = atf_map_init(&p->m_config);
if (atf_is_error(err))
atf_list_fini(&p->m_tcglobs);
out:
return err;
}
static
void
params_fini(struct params *p)
{
atf_list_iter_t iter;
atf_map_fini(&p->m_config);
atf_list_for_each(iter, &p->m_tcglobs)
free(atf_list_iter_data(iter));
atf_list_fini(&p->m_tcglobs);
}
static
atf_error_t
parse_rflag(const char *arg, int *value)
{
atf_error_t err;
if (strlen(arg) != 1 || !isdigit((int)arg[0])) {
err = usage_error("Invalid value for -r; must be a single digit.");
goto out;
}
*value = arg[0] - '0';
INV(*value >= 0 && *value <= 9);
err = atf_no_error();
out:
return err;
}
static
atf_error_t
parse_vflag(char *arg, atf_map_t *config)
{
atf_error_t err;
char *split;
split = strchr(arg, '=');
if (split == NULL) {
err = usage_error("-v requires an argument of the form var=value");
goto out;
}
*split = '\0';
split++;
err = atf_map_insert(config, arg, split, false);
out:
return err;
}
/* ---------------------------------------------------------------------
* Test case filtering.
* --------------------------------------------------------------------- */
static
atf_error_t
match_tcs(const atf_tp_t *tp, const char *glob, atf_list_t *ids)
{
atf_error_t err;
bool found;
atf_list_citer_t iter;
err = atf_no_error();
found = false;
atf_list_for_each_c(iter, atf_tp_get_tcs(tp)) {
const atf_tc_t *tc = atf_list_citer_data(iter);
const char *ident = atf_tc_get_ident(tc);
if (atf_expand_is_glob(glob)) {
bool matches;
err = atf_expand_matches_glob(glob, ident, &matches);
if (!atf_is_error(err) && matches) {
err = atf_list_append(ids, strdup(ident));
found = true;
}
} else {
if (strcmp(glob, tc->m_ident) == 0) {
err = atf_list_append(ids, strdup(ident));
found = true;
}
}
if (atf_is_error(err))
break;
}
if (!atf_is_error(err) && !found)
err = user_error("Unknown test case `%s'", glob);
return err;
}
static
atf_error_t
filter_tcs(const atf_tp_t *tp, const atf_list_t *globs, atf_list_t *ids)
{
atf_error_t err;
atf_list_citer_t iter;
err = atf_list_init(ids);
if (atf_is_error(err))
goto out;
atf_list_for_each_c(iter, globs) {
const char *glob = atf_list_citer_data(iter);
err = match_tcs(tp, glob, ids);
if (atf_is_error(err)) {
atf_list_fini(ids);
goto out;
}
}
out:
return err;
}
static
atf_error_t
list_tcs(const atf_tp_t *tp, const atf_list_t *tcids)
{
atf_error_t err;
size_t col;
atf_list_citer_t iter;
PRE(atf_list_size(tcids) > 0);
err = atf_no_error();
/* Calculate column where to start descriptions. */
col = 0;
atf_list_for_each_c(iter, tcids) {
const char *id = atf_list_citer_data(iter);
const atf_tc_t *tc = atf_tp_get_tc(tp, id);
const size_t len = strlen(atf_tc_get_ident(tc));
if (col < len)
col = len;
}
col += 4;
/* Pretty-print test case identifiers and descriptions. */
atf_list_for_each_c(iter, tcids) {
const char *id = atf_list_citer_data(iter);
const atf_tc_t *tc = atf_tp_get_tc(tp, id);
const char *descr = atf_tc_get_md_var(tc, "descr");
err = print_tag(stdout, id, false, col, "%s", descr);
if (atf_is_error(err))
break;
}
return err;
}
/* ---------------------------------------------------------------------
* Main.
* --------------------------------------------------------------------- */
static
void
usage(void)
{
print_tag(stdout, "Usage: ", false, 0,
"%s [options] [test_case1 [.. test_caseN]]", progname);
printf("\n");
print_tag(stdout, "", false, 0, "This is an independent atf test "
"program.");
printf("\n");
print_tag(stdout, "", false, 0, "Available options:");
print_tag(stdout, " -h ", false, 0,
"Shows this help message");
print_tag(stdout, " -l ", false, 0,
"List test cases and their purpose");
print_tag(stdout, " -r fd ", false, 0,
"The file descriptor to which the test program "
"will send the results of the test cases");
print_tag(stdout, " -s srcdir ", false, 0,
"Directory where the test's data files are "
"located");
print_tag(stdout, " -v var=value ", false, 0,
"Sets the configuration variable `var' to `value'");
print_tag(stdout, " -w workdir ", false, 0,
"Directory where the test's temporary files are "
"located");
printf("\n");
print_tag(stdout, "", false, 0, "For more details please see "
"atf-test-program(1) and atf(7).");
}
static
atf_error_t
process_params(int argc, char **argv, struct params *p)
{
atf_error_t err;
int ch;
err = params_init(p);
if (atf_is_error(err))
goto out;
opterr = 0;
while (!atf_is_error(err) &&
(ch = getopt(argc, argv, GETOPT_POSIX ":hlr:s:v:w:")) != -1) {
switch (ch) {
case 'h':
p->m_do_usage = true;
break;
case 'l':
p->m_do_list = true;
break;
case 'r':
err = parse_rflag(optarg, &p->m_fd);
break;
case 's':
p->m_srcdir = optarg;
break;
case 'v':
err = parse_vflag(optarg, &p->m_config);
break;
case 'w':
p->m_workdir = optarg;
break;
case ':':
err = usage_error("Option -%c requires an argument.", optopt);
break;
case '?':
default:
err = usage_error("Unknown option -%c.", optopt);
}
}
argc -= optind;
argv += optind;
if (!atf_is_error(err)) {
char **arg;
for (arg = argv; !atf_is_error(err) && *arg != NULL; arg++)
err = atf_list_append(&p->m_tcglobs, strdup(*arg));
if (!atf_is_error(err) && atf_list_size(&p->m_tcglobs) == 0)
err = atf_list_append(&p->m_tcglobs, strdup("*"));
}
if (atf_is_error(err))
params_fini(p);
out:
return err;
}
static
atf_error_t
handle_srcdir(struct params *p)
{
atf_error_t err;
atf_fs_path_t exe, srcdir;
bool b;
err = atf_fs_path_init_fmt(&srcdir, "%s", p->m_srcdir);
if (atf_is_error(err))
goto out;
if (!atf_fs_path_is_absolute(&srcdir)) {
atf_fs_path_t srcdirabs;
err = atf_fs_path_to_absolute(&srcdir, &srcdirabs);
if (atf_is_error(err))
goto out_srcdir;
atf_fs_path_fini(&srcdir);
srcdir = srcdirabs;
}
err = atf_fs_path_copy(&exe, &srcdir);
if (atf_is_error(err))
goto out_srcdir;
err = atf_fs_path_append_fmt(&exe, "%s", progname);
if (atf_is_error(err))
goto out_exe;
err = atf_fs_exists(&exe, &b);
if (!atf_is_error(err)) {
if (b) {
err = atf_map_insert(&p->m_config, "srcdir",
strdup(atf_fs_path_cstring(&srcdir)), true);
} else {
err = user_error("Cannot find the test program in the source "
"directory `%s'", p->m_srcdir);
}
}
out_exe:
atf_fs_path_fini(&exe);
out_srcdir:
atf_fs_path_fini(&srcdir);
out:
return err;
}
static
atf_error_t
handle_workdir(struct params *p, atf_fs_path_t *workdir)
{
atf_error_t err;
bool b;
err = atf_fs_path_init_fmt(workdir, "%s", p->m_workdir);
if (atf_is_error(err))
goto out;
err = atf_fs_exists(workdir, &b);
if (atf_is_error(err)) {
atf_fs_path_fini(workdir);
goto out;
}
if (!b) {
atf_fs_path_fini(workdir);
err = user_error("Cannot find the work directory `%s'",
p->m_workdir);
} else
INV(!atf_is_error(err));
out:
return err;
}
static
atf_error_t
controlled_main(int argc, char **argv,
atf_error_t (*add_tcs_hook)(atf_tp_t *),
int *exitcode)
{
atf_error_t err;
struct params p;
atf_tp_t tp;
atf_list_t tcids;
atf_fs_path_t workdir;
err = process_params(argc, argv, &p);
if (atf_is_error(err))
goto out;
if (p.m_do_usage) {
if (argc != 2) {
err = usage_error("-h must be given alone.");
} else {
usage();
*exitcode = EXIT_SUCCESS;
}
goto out_p;
}
err = handle_srcdir(&p);
if (atf_is_error(err))
goto out_p;
err = handle_workdir(&p, &workdir);
if (atf_is_error(err))
goto out_p;
err = atf_tp_init(&tp, &p.m_config);
if (atf_is_error(err))
goto out_workdir;
err = add_tcs_hook(&tp);
if (atf_is_error(err))
goto out_tp;
err = filter_tcs(&tp, &p.m_tcglobs, &tcids);
if (atf_is_error(err))
goto out_tp;
if (p.m_do_list) {
err = list_tcs(&tp, &tcids);
if (!atf_is_error(err))
*exitcode = EXIT_SUCCESS;
} else {
size_t failed;
err = atf_tp_run(&tp, &tcids, p.m_fd, &workdir, &failed);
if (!atf_is_error(err))
*exitcode = failed > 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}
{
atf_list_iter_t iter;
atf_list_for_each(iter, &tcids)
free(atf_list_iter_data(iter));
atf_list_fini(&tcids);
}
out_tp:
atf_tp_fini(&tp);
out_workdir:
atf_fs_path_fini(&workdir);
out_p:
params_fini(&p);
out:
return err;
}
int
atf_tp_main(int argc, char **argv, atf_error_t (*add_tcs_hook)(atf_tp_t *))
{
atf_error_t err;
int exitcode;
atf_init_objects();
progname = strrchr(argv[0], '/');
if (progname == NULL)
progname = argv[0];
else
progname++;
exitcode = EXIT_FAILURE; /* Silence GCC warning. */
err = controlled_main(argc, argv, add_tcs_hook, &exitcode);
if (atf_is_error(err)) {
print_error(err);
atf_error_free(err);
exitcode = EXIT_FAILURE;
}
return exitcode;
}

212
dist/atf/atf-c/ui.c vendored
View File

@ -1,212 +0,0 @@
/*
* 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
* 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 <sys/ioctl.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include "atf-c/dynstr.h"
#include "atf-c/env.h"
#include "atf-c/sanity.h"
#include "atf-c/text.h"
#include "atf-c/ui.h"
/* ---------------------------------------------------------------------
* Auxiliary functions.
* --------------------------------------------------------------------- */
static
size_t
terminal_width(void)
{
static bool done = false;
static size_t width = 0;
if (!done) {
if (atf_env_has("COLUMNS")) {
const char *cols = atf_env_get("COLUMNS");
if (strlen(cols) > 0) {
width = atoi(cols); /* XXX No error checking */
}
} 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
atf_error_t
format_paragraph(atf_dynstr_t *dest,
const char *tag, bool repeat, size_t col, bool firstp,
char *str)
{
const size_t maxcol = terminal_width();
size_t curcol;
char *last, *str2;
atf_dynstr_t pad, fullpad;
atf_error_t err;
err = atf_dynstr_init_rep(&pad, col - strlen(tag), ' ');
if (atf_is_error(err))
goto out;
err = atf_dynstr_init_rep(&fullpad, col, ' ');
if (atf_is_error(err))
goto out_pad;
if (firstp || repeat)
err = atf_dynstr_append_fmt(dest, "%s%s", tag,
atf_dynstr_cstring(&pad));
else
err = atf_dynstr_append_fmt(dest, atf_dynstr_cstring(&fullpad));
if (atf_is_error(err))
goto out_pads;
last = NULL; /* Silence GCC warning. */
str2 = strtok_r(str, " ", &last);
curcol = col;
do {
const bool firstw = (str == str2);
if (!firstw) {
if (maxcol > 0 && curcol + strlen(str2) + 1 > maxcol) {
if (repeat)
err = atf_dynstr_append_fmt
(dest, "\n%s%s", tag, atf_dynstr_cstring(&pad));
else
err = atf_dynstr_append_fmt
(dest, "\n%s", atf_dynstr_cstring(&fullpad));
curcol = col;
} else {
err = atf_dynstr_append_fmt(dest, " ");
curcol++;
}
}
if (!atf_is_error(err)) {
err = atf_dynstr_append_fmt(dest, str2);
curcol += strlen(str2);
str2 = strtok_r(NULL, " ", &last);
}
} while (!atf_is_error(err) && str2 != NULL);
out_pads:
atf_dynstr_fini(&fullpad);
out_pad:
atf_dynstr_fini(&pad);
out:
return err;
}
static
atf_error_t
format_aux(atf_dynstr_t *dest,
const char *tag, bool repeat, size_t col, char *str)
{
char *last, *str2;
atf_error_t err;
PRE(col == 0 || col >= strlen(tag));
if (col == 0)
col = strlen(tag);
str2 = str + strlen(str);
while (str2 != str && *--str2 == '\n')
*str2 = '\0';
last = NULL; /* Silence GCC warning. */
str2 = strtok_r(str, "\n", &last);
do {
const bool first = (str2 == str);
err = format_paragraph(dest, tag, repeat, col, first, str2);
str2 = strtok_r(NULL, "\n", &last);
if (!atf_is_error(err) && str2 != NULL) {
if (repeat)
err = atf_dynstr_append_fmt(dest, "\n%s\n", tag);
else
err = atf_dynstr_append_fmt(dest, "\n\n");
}
} while (str2 != NULL && !atf_is_error(err));
return 0;
}
/* ---------------------------------------------------------------------
* Free functions.
* --------------------------------------------------------------------- */
atf_error_t
atf_ui_format_ap(atf_dynstr_t *dest,
const char *tag, bool repeat, size_t col,
const char *fmt, va_list ap)
{
char *src;
atf_error_t err;
va_list ap2;
va_copy(ap2, ap);
err = atf_text_format_ap(&src, fmt, ap2);
va_end(ap2);
if (!atf_is_error(err)) {
err = format_aux(dest, tag, repeat, col, src);
free(src);
}
return err;
}
atf_error_t
atf_ui_format_fmt(atf_dynstr_t *dest,
const char *tag, bool repeat, size_t col,
const char *fmt, ...)
{
va_list ap;
atf_error_t err;
va_start(ap, fmt);
err = atf_ui_format_ap(dest, tag, repeat, col, fmt, ap);
va_end(ap);
return err;
}

48
dist/atf/atf-c/ui.h vendored
View File

@ -1,48 +0,0 @@
/*
* 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
* 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_C_UI_H)
#define ATF_C_UI_H
#include <stdarg.h>
#include <stdbool.h>
#include <stddef.h>
#include <atf-c/error.h>
struct atf_dynstr;
atf_error_t atf_ui_format_ap(struct atf_dynstr *,
const char *, bool, size_t,
const char *, va_list);
atf_error_t atf_ui_format_fmt(struct atf_dynstr *,
const char *, bool, size_t,
const char *, ...);
#endif /* ATF_C_UI_H */

78
dist/atf/atf-c/user.c vendored
View File

@ -1,78 +0,0 @@
/*
* Automated Testing Framework (atf)
*
* Copyright (c) 2007, 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
* 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 <sys/param.h>
#include <sys/types.h>
#include <limits.h>
#include <unistd.h>
#include "atf-c/sanity.h"
#include "atf-c/user.h"
/* ---------------------------------------------------------------------
* Free functions.
* --------------------------------------------------------------------- */
uid_t
atf_user_euid(void)
{
return geteuid();
}
bool
atf_user_is_member_of_group(gid_t gid)
{
static gid_t groups[NGROUPS_MAX];
static int ngroups = -1;
bool found;
int i;
if (ngroups == -1) {
ngroups = getgroups(NGROUPS_MAX, groups);
INV(ngroups >= 0);
}
found = false;
for (i = 0; !found && i < ngroups; i++)
if (groups[i] == gid)
found = true;
return found;
}
bool
atf_user_is_root(void)
{
return geteuid() == 0;
}
bool
atf_user_is_unprivileged(void)
{
return geteuid() != 0;
}

Some files were not shown because too many files have changed in this diff Show More