remove ATF source code and Atffiles

(cherry picked from commit 8c4d50c6bc)
This commit is contained in:
Evan Hunt 2018-11-14 22:33:00 +00:00
parent 4f3073de7c
commit 33f428efda
334 changed files with 2 additions and 123144 deletions

View file

@ -1,5 +0,0 @@
Content-Type: application/X-atf-atffile; version="1"
prop: test-suite = bind9
tp: lib

View file

@ -14,7 +14,7 @@ top_builddir = @top_builddir@
VERSION=@BIND9_VERSION@
SUBDIRS = make unit lib bin doc
SUBDIRS = make lib bin doc
TARGETS =
PREREQS = bind.keys.h

3
configure vendored
View file

@ -24851,7 +24851,7 @@ ac_config_commands="$ac_config_commands chmod"
# elsewhere if there's a good reason for doing so.
#
ac_config_files="$ac_config_files make/Makefile make/mkdep Makefile bin/Makefile bin/check/Makefile bin/confgen/Makefile bin/confgen/unix/Makefile bin/delv/Makefile bin/dig/Makefile bin/dnssec/Makefile bin/named/Makefile bin/named/unix/Makefile bin/nsupdate/Makefile bin/pkcs11/Makefile bin/python/Makefile bin/python/isc/Makefile bin/python/isc/utils.py bin/python/isc/tests/Makefile bin/python/dnssec-checkds.py bin/python/dnssec-coverage.py bin/python/dnssec-keymgr.py bin/python/isc/__init__.py bin/python/isc/checkds.py bin/python/isc/coverage.py bin/python/isc/dnskey.py bin/python/isc/eventlist.py bin/python/isc/keydict.py bin/python/isc/keyevent.py bin/python/isc/keymgr.py bin/python/isc/keyseries.py bin/python/isc/keyzone.py bin/python/isc/policy.py bin/python/isc/rndc.py bin/python/isc/tests/dnskey_test.py bin/python/isc/tests/policy_test.py bin/rndc/Makefile bin/tests/Makefile bin/tests/headerdep_test.sh bin/tests/optional/Makefile bin/tests/pkcs11/Makefile bin/tests/pkcs11/benchmarks/Makefile bin/tests/system/Makefile bin/tests/system/conf.sh bin/tests/system/dlz/prereq.sh bin/tests/system/dlzexternal/Makefile bin/tests/system/dlzexternal/ns1/dlzs.conf bin/tests/system/dyndb/Makefile bin/tests/system/dyndb/driver/Makefile bin/tests/system/inline/checkdsa.sh bin/tests/system/pipelined/Makefile bin/tests/system/rndc/Makefile bin/tests/system/rpz/Makefile bin/tests/system/rsabigexponent/Makefile bin/tests/system/tkey/Makefile bin/tests/virtual-time/Makefile bin/tests/virtual-time/conf.sh bin/tools/Makefile contrib/scripts/check-secure-delegation.pl contrib/scripts/zone-edit.sh doc/Makefile doc/arm/Makefile doc/arm/noteversion.xml doc/arm/pkgversion.xml doc/arm/releaseinfo.xml doc/doxygen/Doxyfile doc/doxygen/Makefile doc/doxygen/doxygen-input-filter doc/misc/Makefile doc/tex/Makefile doc/tex/armstyle.sty doc/xsl/Makefile doc/xsl/isc-docbook-chunk.xsl doc/xsl/isc-docbook-html.xsl doc/xsl/isc-manpage.xsl doc/xsl/isc-notes-html.xsl isc-config.sh lib/Makefile lib/bind9/Makefile lib/bind9/include/Makefile lib/bind9/include/bind9/Makefile lib/dns/Makefile lib/dns/include/Makefile lib/dns/include/dns/Makefile lib/dns/include/dst/Makefile lib/dns/tests/Makefile lib/irs/Makefile lib/irs/include/Makefile lib/irs/include/irs/Makefile lib/irs/include/irs/netdb.h lib/irs/include/irs/platform.h lib/irs/tests/Makefile lib/isc/$arch/Makefile lib/isc/$arch/include/Makefile lib/isc/$arch/include/isc/Makefile lib/isc/$thread_dir/Makefile lib/isc/$thread_dir/include/Makefile lib/isc/$thread_dir/include/isc/Makefile lib/isc/Makefile lib/isc/include/Makefile lib/isc/include/isc/Makefile lib/isc/include/isc/platform.h lib/isc/include/pk11/Makefile lib/isc/include/pkcs11/Makefile lib/isc/tests/Makefile lib/isc/nls/Makefile lib/isc/unix/Makefile lib/isc/unix/include/Makefile lib/isc/unix/include/isc/Makefile lib/isc/unix/include/pkcs11/Makefile lib/isccc/Makefile lib/isccc/include/Makefile lib/isccc/include/isccc/Makefile lib/isccc/tests/Makefile lib/isccfg/Makefile lib/isccfg/include/Makefile lib/isccfg/include/isccfg/Makefile lib/isccfg/tests/Makefile lib/ns/Makefile lib/ns/include/Makefile lib/ns/include/ns/Makefile lib/ns/tests/Makefile lib/samples/Makefile lib/samples/Makefile-postinstall unit/Makefile unit/unittest.sh"
ac_config_files="$ac_config_files make/Makefile make/mkdep Makefile bin/Makefile bin/check/Makefile bin/confgen/Makefile bin/confgen/unix/Makefile bin/delv/Makefile bin/dig/Makefile bin/dnssec/Makefile bin/named/Makefile bin/named/unix/Makefile bin/nsupdate/Makefile bin/pkcs11/Makefile bin/python/Makefile bin/python/isc/Makefile bin/python/isc/utils.py bin/python/isc/tests/Makefile bin/python/dnssec-checkds.py bin/python/dnssec-coverage.py bin/python/dnssec-keymgr.py bin/python/isc/__init__.py bin/python/isc/checkds.py bin/python/isc/coverage.py bin/python/isc/dnskey.py bin/python/isc/eventlist.py bin/python/isc/keydict.py bin/python/isc/keyevent.py bin/python/isc/keymgr.py bin/python/isc/keyseries.py bin/python/isc/keyzone.py bin/python/isc/policy.py bin/python/isc/rndc.py bin/python/isc/tests/dnskey_test.py bin/python/isc/tests/policy_test.py bin/rndc/Makefile bin/tests/Makefile bin/tests/headerdep_test.sh bin/tests/optional/Makefile bin/tests/pkcs11/Makefile bin/tests/pkcs11/benchmarks/Makefile bin/tests/system/Makefile bin/tests/system/conf.sh bin/tests/system/dlz/prereq.sh bin/tests/system/dlzexternal/Makefile bin/tests/system/dlzexternal/ns1/dlzs.conf bin/tests/system/dyndb/Makefile bin/tests/system/dyndb/driver/Makefile bin/tests/system/inline/checkdsa.sh bin/tests/system/pipelined/Makefile bin/tests/system/rndc/Makefile bin/tests/system/rpz/Makefile bin/tests/system/rsabigexponent/Makefile bin/tests/system/tkey/Makefile bin/tests/virtual-time/Makefile bin/tests/virtual-time/conf.sh bin/tools/Makefile contrib/scripts/check-secure-delegation.pl contrib/scripts/zone-edit.sh doc/Makefile doc/arm/Makefile doc/arm/noteversion.xml doc/arm/pkgversion.xml doc/arm/releaseinfo.xml doc/doxygen/Doxyfile doc/doxygen/Makefile doc/doxygen/doxygen-input-filter doc/misc/Makefile doc/tex/Makefile doc/tex/armstyle.sty doc/xsl/Makefile doc/xsl/isc-docbook-chunk.xsl doc/xsl/isc-docbook-html.xsl doc/xsl/isc-manpage.xsl doc/xsl/isc-notes-html.xsl isc-config.sh lib/Makefile lib/bind9/Makefile lib/bind9/include/Makefile lib/bind9/include/bind9/Makefile lib/dns/Makefile lib/dns/include/Makefile lib/dns/include/dns/Makefile lib/dns/include/dst/Makefile lib/dns/tests/Makefile lib/irs/Makefile lib/irs/include/Makefile lib/irs/include/irs/Makefile lib/irs/include/irs/netdb.h lib/irs/include/irs/platform.h lib/irs/tests/Makefile lib/isc/$arch/Makefile lib/isc/$arch/include/Makefile lib/isc/$arch/include/isc/Makefile lib/isc/$thread_dir/Makefile lib/isc/$thread_dir/include/Makefile lib/isc/$thread_dir/include/isc/Makefile lib/isc/Makefile lib/isc/include/Makefile lib/isc/include/isc/Makefile lib/isc/include/isc/platform.h lib/isc/include/pk11/Makefile lib/isc/include/pkcs11/Makefile lib/isc/tests/Makefile lib/isc/nls/Makefile lib/isc/unix/Makefile lib/isc/unix/include/Makefile lib/isc/unix/include/isc/Makefile lib/isc/unix/include/pkcs11/Makefile lib/isccc/Makefile lib/isccc/include/Makefile lib/isccc/include/isccc/Makefile lib/isccc/tests/Makefile lib/isccfg/Makefile lib/isccfg/include/Makefile lib/isccfg/include/isccfg/Makefile lib/isccfg/tests/Makefile lib/ns/Makefile lib/ns/include/Makefile lib/ns/include/ns/Makefile lib/ns/tests/Makefile lib/samples/Makefile lib/samples/Makefile-postinstall unit/unittest.sh"
#
@ -25974,7 +25974,6 @@ do
"lib/ns/tests/Makefile") CONFIG_FILES="$CONFIG_FILES lib/ns/tests/Makefile" ;;
"lib/samples/Makefile") CONFIG_FILES="$CONFIG_FILES lib/samples/Makefile" ;;
"lib/samples/Makefile-postinstall") CONFIG_FILES="$CONFIG_FILES lib/samples/Makefile-postinstall" ;;
"unit/Makefile") CONFIG_FILES="$CONFIG_FILES unit/Makefile" ;;
"unit/unittest.sh") CONFIG_FILES="$CONFIG_FILES unit/unittest.sh" ;;
*) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;

View file

@ -5436,7 +5436,6 @@ AC_CONFIG_FILES([
lib/ns/tests/Makefile
lib/samples/Makefile
lib/samples/Makefile-postinstall
unit/Makefile
unit/unittest.sh
])

View file

@ -1,9 +0,0 @@
Content-Type: application/X-atf-atffile; version="1"
prop: test-suite = bind9
tp: dns
tp: irs
tp: isc
tp: isccfg
tp: ns

View file

@ -1,5 +0,0 @@
Content-Type: application/X-atf-atffile; version="1"
prop: test-suite = bind9
tp: tests

View file

@ -1,35 +0,0 @@
Content-Type: application/X-atf-atffile; version="1"
prop: test-suite = bind9
tp: acl_test
tp: db_test
tp: dbdiff_test
tp: dbiterator_test
tp: dbversion_test
tp: dh_test
tp: dispatch_test
tp: dnstap_test
tp: dst_test
tp: dstrandom_test
tp: geoip_test
tp: gost_test
tp: keytable_test
tp: master_test
tp: name_test
tp: nsec3_test
tp: peer_test
tp: private_test
tp: rbt_serialize_test
tp: rbt_test
tp: rdata_test
tp: rdataset_test
tp: rdatasetstats_test
tp: resolver_test
tp: rsa_test
tp: sigs_test
tp: time_test
tp: tsig_test
tp: update_test
tp: zonemgr_test
tp: zt_test

View file

@ -1,5 +0,0 @@
Content-Type: application/X-atf-atffile; version="1"
prop: test-suite = bind9
tp: tests

View file

@ -1,5 +0,0 @@
Content-Type: application/X-atf-atffile; version="1"
prop: test-suite = bind9
tp: resconf_test

View file

@ -1,5 +0,0 @@
Content-Type: application/X-atf-atffile; version="1"
prop: test-suite = bind9
tp: tests

View file

@ -1,32 +0,0 @@
Content-Type: application/X-atf-atffile; version="1"
prop: test-suite = bind9
tp: aes_test
tp: atomic_test
tp: buffer_test
tp: counter_test
tp: errno_test
tp: file_test
tp: hash_test
tp: heap_test
tp: ht_test
tp: inet_ntop_test
tp: lex_test
tp: mem_test
tp: netaddr_test
tp: parse_test
tp: pool_test
tp: print_test
tp: queue_test
tp: radix_test
tp: random_test
tp: regex_test
tp: safe_test
tp: sockaddr_test
tp: socket_test
tp: symtab_test
tp: task_test
tp: taskpool_test
tp: time_test
tp: timer_test

View file

@ -1,5 +0,0 @@
Content-Type: application/X-atf-atffile; version="1"
prop: test-suite = bind9
tp: tests

View file

@ -1,5 +0,0 @@
Content-Type: application/X-atf-atffile; version="1"
prop: test-suite = bind9
tp: parser_test

View file

@ -1,5 +0,0 @@
Content-Type: application/X-atf-atffile; version="1"
prop: test-suite = bind9
tp: tests

View file

@ -1,7 +0,0 @@
Content-Type: application/X-atf-atffile; version="1"
prop: test-suite = bind9
tp: listenlist_test
tp: notify_test
tp: query_test

View file

@ -1,36 +0,0 @@
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
# See the COPYRIGHT file distributed with this work for additional
# information regarding copyright ownership.
srcdir = @srcdir@
VPATH = @srcdir@
top_srcdir = @top_srcdir@
# Attempt to disable parallel processing.
.NOTPARALLEL:
.NO_PARALLEL:
SUBDIRS = @ATFBUILD@
TARGETS = atf
@BIND9_MAKE_RULES@
#
# install ATF libraries, if configured with --with-atf
#
atf:
@for i in ${ALL_SUBDIRS}; do \
if [ "$$i" != "nulldir" -a -d $$i ]; then \
(cd $$i; ${MAKE} ${MAKEDEFS} install) || exit 1; \
fi; \
done
clean distclean::
rm -rf ./atf
distclean::
rm unittest.sh

View file

@ -1,19 +0,0 @@
language: cpp
compiler:
- gcc
- clang
before_install:
- ./admin/travis-install-deps.sh
env:
- AS_ROOT=no
- AS_ROOT=yes
script:
- ./admin/travis-build.sh
notifications:
email:
- atf-log@googlegroups.com

View file

@ -1,30 +0,0 @@
Authors and contributors Automated Testing Framework
===========================================================================
* Julio Merino <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.
* Lukasz Strzygowski <qx89l4@gmail.com>
Participant of the Google Summer of Code 2008 program. Mentored by The
NetBSD Foundation, he worked on the atfify NetBSD-SoC project and, as a
side-effect, he contributed to the ATF source code. He developed the
initial version of the atf-check utility and started the addition of the
ATF_REQUIRE family of macros in the C interface.
* Paul Goyette <pgoyette@NetBSD.org>
Implemented timestamping of test programs and test cases so that
atf-report can provide timings for their execution.
===========================================================================
vim: filetype=text:textwidth=75:expandtab:shiftwidth=2:softtabstop=2

View file

@ -1,10 +0,0 @@
Content-Type: application/X-atf-atffile; version="1"
prop: test-suite = atf
tp: atf-c
tp: atf-c++
tp: atf-sh
tp: test-programs
tp-glob: tools*

View file

@ -1,100 +0,0 @@
Redistribution terms Automated Testing Framework
===========================================================================
License
*******
Copyright (c) 2007, 2008, 2009, 2010, 2011, 2012 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.
Copyright 2011, 2012 Google Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Google Inc. nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
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 Merino <jmmv@users.sourceforge.net>
* atf-c/ui.c: The format_paragraph and format_text functions were
derived form the ones in the Monotone project, revision
3a0982da308228d796df35f98d787c5cff2bb5b6.
Author: Julio Merino <jmmv@NetBSD.org>
* atf-c++/detail/io.hpp, atf-c++/detail/io.cpp, atf-c++/detail/io_test.cpp:
These files were derived from the file_handle, systembuf, pipe and pistream
classes and tests found in the Boost.Process library.
Author: Julio Merino <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 Merino <jmmv84@gmail.com>
===========================================================================
vim: filetype=text:textwidth=75:expandtab:shiftwidth=2:softtabstop=2

View file

@ -1,223 +0,0 @@
Installation instructions Automated Testing Framework
===========================================================================
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
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 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
to have GNU autoconf, automake and libtool installed.
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 configure.ac, Makefile.am or any of the other build
system files. To do this, simply run:
$ autoreconf -i -s
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. Install the program by running 'make install'. You may need to become
root to issue this step.
4. Issue any manual installation steps that may be required. These are
described later in their own section.
5. 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:
* --prefix=directory
Possible values: Any path
Default: /usr/local
Specifies where the program (binaries and all associated files) will
be installed.
* --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.
* --help
Shows information about all available flags and exits immediately,
without running any configuration tasks.
The following environment variables are specific to ATF's 'configure'
script:
* ATF_BUILD_CC
Possible values: empty, a absolute or relative path to a C compiler.
Default: the value of CC as detected by the configure script.
Specifies the C compiler that ATF will use at run time whenever the
build-time-specific checks are used.
* ATF_BUILD_CFLAGS
Possible values: empty, a list of valid C compiler flags.
Default: the value of CFLAGS as detected by the configure script.
Specifies the C compiler flags that ATF will use at run time whenever the
build-time-specific checks are used.
* ATF_BUILD_CPP
Possible values: empty, a absolute or relative path to a C/C++
preprocessor.
Default: the value of CPP as detected by the configure script.
Specifies the C/C++ preprocessor that ATF will use at run time whenever
the build-time-specific checks are used.
* ATF_BUILD_CPPFLAGS
Possible values: empty, a list of valid C/C++ preprocessor flags.
Default: the value of CPPFLAGS as detected by the configure script.
Specifies the C/C++ preprocessor flags that ATF will use at run time
whenever the build-time-specific checks are used.
* ATF_BUILD_CXX
Possible values: empty, a absolute or relative path to a C++ compiler.
Default: the value of CXX as detected by the configure script.
Specifies the C++ compiler that ATF will use at run time whenever the
build-time-specific checks are used.
* ATF_BUILD_CXXFLAGS
Possible values: empty, a list of valid C++ compiler flags.
Default: the value of CXXFLAGS as detected by the configure script.
Specifies the C++ compiler flags that ATF will use at run time whenever
the build-time-specific checks are used.
* 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.
* ATF_SHELL
Possible values: empty, absolute path to a POSIX shell interpreter.
Default: empty.
Specifies the POSIX shell interpreter that ATF will use at run time to
execute its scripts and the test programs written using the atf-sh
library. If empty, the configure script will try to find a suitable
interpreter for you.
* 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.
* GDB
Possible values: empty, absolute path to GNU GDB.
Default: empty.
Specifies the path to the GNU GDB binary that atf-run will use to gather
a stack trace of a crashing test program. If empty, the configure script
will try to find a suitable binary for you.
The following flags are specific to ATF's 'configure' script:
* --enable-developer
Possible values: yes, no
Default: 'yes' in Git HEAD builds; 'no' in formal releases.
Enables several features useful for development, such as the inclusion
of debugging symbols in all objects or the enforcement of compilation
warnings.
The compiler will be executed with an exhaustive collection of warning
detection features regardless of the value of this flag. However, such
warnings are only fatal when --enable-developer is 'yes'.
* --enable-tools
Possible values: yes, no
Default: no.
Enables the build of the deprecated atf-config, atf-report, atf-run
and atf-version tools. atf-report and atf-run have been superseded by
Kyua, and atf-config and atf-version are unnecessary.
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.
===========================================================================
vim: filetype=text:textwidth=75:expandtab:shiftwidth=2:softtabstop=2

View file

@ -1,12 +0,0 @@
syntax("kyuafile", 1)
test_suite("atf")
include("atf-c/Kyuafile")
include("atf-c++/Kyuafile")
include("atf-sh/Kyuafile")
include("test-programs/Kyuafile")
if fs.exists("tools/Kyuafile") then
include("tools/Kyuafile")
end

View file

@ -1,159 +0,0 @@
# Copyright (c) 2007 The NetBSD Foundation, Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
# CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
atf_aclocal_DATA =
BUILT_SOURCES =
CLEANFILES =
DIST_HOOKS =
EXTRA_DIST =
bin_PROGRAMS =
dist_man_MANS =
include_HEADERS =
lib_LTLIBRARIES =
libexec_PROGRAMS =
man_MANS =
noinst_DATA =
noinst_LTLIBRARIES =
INSTALLCHECK_TARGETS =
PHONY_TARGETS =
ACLOCAL_AMFLAGS = -I m4
AM_DISTCHECK_CONFIGURE_FLAGS = --enable-tools
include admin/Makefile.am.inc
include atf-c/Makefile.am.inc
include atf-c++/Makefile.am.inc
include atf-sh/Makefile.am.inc
include bootstrap/Makefile.am.inc
include doc/Makefile.am.inc
include test-programs/Makefile.am.inc
if ENABLE_TOOLS
include tools/Makefile.am.inc
endif
#
# Top-level distfile documents.
#
doc_DATA = AUTHORS COPYING NEWS README
noinst_DATA += INSTALL README
EXTRA_DIST += $(doc_DATA) INSTALL README
#
# Supporting logic to run our custom testsuite.
#
TESTS_ENVIRONMENT = PATH=$(prefix)/bin:$${PATH} \
PKG_CONFIG_PATH=$(prefix)/lib/pkgconfig
# Allow the caller to override the configuration file to passed to our
# test runs below.
KYUA_TEST_CONFIG_FILE = none
testsdir = $(exec_prefix)/tests
pkgtestsdir = $(testsdir)/$(PACKAGE)
if ENABLE_TOOLS
INSTALLCHECK_TARGETS += installcheck-atf
PHONY_TARGETS += installcheck-atf
installcheck-atf:
logfile=$$(pwd)/installcheck.log; \
fifofile=$$(pwd)/installcheck.fifo; \
cd $(pkgtestsdir); \
rm -f $${fifofile}; \
mkfifo $${fifofile}; \
cat $${fifofile} | tee $${logfile} | $(TESTS_ENVIRONMENT) atf-report & \
$(TESTS_ENVIRONMENT) atf-run >>$${fifofile}; \
res=$${?}; \
wait; \
rm $${fifofile}; \
echo; \
echo "The verbatim output of atf-run has been saved to" \
"installcheck.log; exit was $${res}"; \
test $${res} -eq 0
CLEANFILES += installcheck.fifo installcheck.log
endif
PHONY_TARGETS += installcheck-kyua
if HAVE_KYUA
if !ENABLE_TOOLS
INSTALLCHECK_TARGETS += installcheck-kyua
endif
installcheck-kyua:
cd $(pkgtestsdir) && $(TESTS_ENVIRONMENT) \
$(KYUA) --config='$(KYUA_TEST_CONFIG_FILE)' test
endif
installcheck-local: $(INSTALLCHECK_TARGETS)
pkgtests_DATA = Kyuafile
if ENABLE_TOOLS
pkgtests_DATA += Atffile
endif
EXTRA_DIST += $(pkgtests_DATA)
BUILD_SH_TP = \
test -d "$$(dirname "$${dst}")" || mkdir -p "$$(dirname "$${dst}")"; \
echo "\#! $(bindir)/atf-sh" >"$${dst}"; \
if [ -n "$${substs}" ]; then \
cat $${src} | sed $${substs} >>"$${dst}"; \
else \
cat $${src} >>"$${dst}"; \
fi; \
chmod +x "$${dst}"
#
# Custom targets.
#
DIST_HOOKS += forbid-dist
if ENABLE_TOOLS
forbid-dist:
@true
else
forbid-dist:
@echo "Sorry; cannot make dist without the tools enabled."
@echo "Please reconfigure with --enable-tools."
@false
endif
PHONY_TARGETS += clean-all
clean-all:
GIT="$(GIT)" $(SH) $(srcdir)/admin/clean-all.sh
.PHONY: $(PHONY_TARGETS)
# TODO(jmmv): Remove after atf 0.22.
install-data-hook:
cd $(DESTDIR)$(man3dir) && \
for binding in c c++ sh; do \
rm -f "atf-$${binding}-api.3"; \
$(LN_S) "atf-$${binding}.3" "atf-$${binding}-api.3"; \
done
dist-hook: $(DIST_HOOKS)
# vim: syntax=make:noexpandtab:shiftwidth=8:softtabstop=8

File diff suppressed because it is too large Load diff

View file

@ -1,710 +0,0 @@
Major changes between releases Automated Testing Framework
===========================================================================
Changes in version 0.21
***********************
Released on October 23rd, 2014.
* Restored the atf(7) manual page to serve as a reference to all the other
manual pages shipped by ATF.
* Added the -s flag to atf-sh to support specifying the shell interpreter
to be used.
* Removed ATF_WORKDIR. The only remaining consumers have been converted to
use the standard TMPDIR environment variable. As a benefit, and because
Kyua forces the TMPDIR to live within the test case's work directory,
any stale files left behind by ATF will be automatically cleaned up.
* Documented the environment variables recognized by each component in the
relevant manual pages. This information was lost with the atf-config(1)
removal.
* Added a new "require.diskspace" metadata property to test cases so that
they can specify the minimum amount of disk space required for the test
to run.
* Renamed the atf-{c,c++,sh}-api(3) manual pages to atf-{c,c++,sh}(3) for
discoverability purposes. Symbolic links are provided for the time
being to still make the old names visible.
* Issue #5: Recommend the (expected, actual) idiom for calls to the test
macros in the manual pages.
* Issue #7: Stopped catching unhandled exceptions in atf-c++ tests. This
propagates the crash to the caller, which in turn allows it to obtain
proper debugging information. In particular, Kyua should now be able to
extract a stacktrace pinpointing the problem.
* Issue #8: Fixed atf-c/macros_test:use test failures spotted by the clang
that ships with FreeBSD 11.0-CURRENT.
* Issue #12: Improved documentation of atf-sh(3) and atf-check(1) by better
explaining how they relate to each other.
* Issue #14: Stopped setting 'set -e' in atf-sh. This setting was
initially added as a way to enable a "strict" mode in the library and to
make test cases fail fast when they run unprotected commands. However,
doing so in the library is surprising as the responsibility of enabling
'set -e' should be on the user's code. Also, 'set -e' introduces
inconsistent behavior on subshells and users do not expect that.
* Issue #15: Fixed atf_utils_{fork,wait} to support nested calls.
* Issue #16: Fixed test failures (by removing a long-standing hack) on
systems that lack \e support in printf(1).
* Issue #19: Removed stale references to atf-config and atf-run.
Changes in version 0.19
***********************
Experimental version released on February 7th, 2014.
This is the last release to bundle the code for the deprecated tools.
The next release will drop their code and will stop worrying about
backwards compatibility between the ATF libraries and what the old tools
may or may not support.
If you still require the old tools for some reason, grab a copy of the
'tools' directory now. The code in this directory is standalone and
does not depend on any internal details of atf-c++ any longer.
* Various fixes and improvements to support running as part of the FreeBSD
test suite.
* Project hosting moved from Google Code (as a subproject of Kyua) to
GitHub (as a first-class project). The main reason for the change is
the suppression of binary downloads in Google Code on Jan 15th, 2014.
See https://github.com/jmmv/atf/
* Removed builtin help from atf-sh(1) and atf-check(1) for simplicity
reasons. In other words, their -h option is gone.
* Moved the code of the deprecated tools into a 'tools' directory and
completely decoupled their code from the internals of atf-c++. The
reason for this is to painlessly allow a third-party to maintain a
copy of these tools after we delete them because upcoming changes to
atf-c++ would break the stale tools.
Changes in version 0.18
***********************
Experimental version released on November 16th, 2013.
* Issue 45: Added require.memory support in atf-run for FreeBSD.
* Fixed an issue with the handling of cin with libc++.
* Issue 64: Fixed various mandoc formatting warnings.
* NetBSD PR bin/48284: Made atf-check flush its progress message to
stdout so that an interrupted test case always shows the last message
being executed.
* NetBSD PR bin/48285: Fixed atf_check examples in atf-sh-api(3).
Changes in version 0.17
***********************
Experimental version released on February 14th, 2013.
* Added the atf_utils_cat_file, atf_utils_compare_file,
atf_utils_copy_file, atf_utils_create_file, atf_utils_file_exists,
atf_utils_fork, atf_utils_grep_file, atf_utils_grep_string,
atf_utils_readline, atf_utils_redirect and atf_utils_wait utility
functions to atf-c-api. Documented the already-public
atf_utils_free_charpp function.
* Added the cat_file, compare_file, copy_file, create_file, file_exists,
fork, grep_collection, grep_file, grep_string, redirect and wait
functions to the atf::utils namespace of atf-c++-api. These are
wrappers around the same functions added to the atf-c-api library.
* Added the ATF_CHECK_MATCH, ATF_CHECK_MATCH_MSG, ATF_REQUIRE_MATCH and
ATF_REQUIRE_MATCH_MSG macros to atf-c to simplify the validation of a
string against a regular expression.
* Miscellaneous fixes for manpage typos and compilation problems with
clang.
* Added caching of the results of those configure tests that rely on
executing a test program. This should help crossbuild systems by
providing a mechanism to pre-specify what the results should be.
* PR bin/45690: Make atf-report convert any non-printable characters to
a plain-text representation (matching their corresponding hexadecimal
entities) in XML output files. This is to prevent the output of test
cases from breaking xsltproc later.
Changes in version 0.16
***********************
Experimental version released on July 10th, 2012.
* Added a --enable-tools flag to configure to request the build of the
deprecated ATF tools, whose build is now disabled by default. In order
to continue running tests, you should migrate to Kyua instead of enabling
the build of the deprecated tools. The kyua-atf-compat package provides
transitional compatibility versions of atf-run and atf-report built on
top of Kyua.
* Tweaked the ATF_TEST_CASE macro of atf-c++ so that the compiler can
detect defined but unused test cases.
* PR bin/45859: Fixed some XSLT bugs that resulted in the tc-time and
tp-time XML tags leaking into the generated HTML file. Also improved
the CSS file slightly to correct alignment and color issues with the
timestamps column.
* Optimized atf-c++/macros.hpp so that GNU G++ consumes less memory during
compilation with GNU G++.
* Flipped the default to building shared libraries for atf-c and atf-c++,
and started versioning them. As a side-effect, this removes the
--enable-unstable-shared flag from configure that appears to not work any
more (under NetBSD). Additionally, some distributions require the use of
shared libraries for proper dependency tracking (e.g. Fedora), so it is
better if we do the right versioning upstream.
* Project hosting moved from an adhoc solution (custom web site and
Monotone repository) to Google Code (standard wiki and Git). ATF now
lives in a subcomponent of the Kyua project.
Changes in version 0.15
***********************
Experimental version released on January 16th, 2012.
* Respect stdin in atf-check. The previous release silenced stdin for any
processes spawned by atf, not only test programs, which caused breakage
in tests that pipe data through atf-check.
* Performance improvements to atf-sh.
* Enabled detection of unused parameters and variables in the code and
fixed all warnings.
* Changed the behavior of "developer mode". Compiler warnings are now
enabled unconditionally regardless of whether we are in developer mode or
not; developer mode is now only used to perform strict warning checks and
to enable assertions. Additionally, developer mode is now only
automatically enabled when building from the repository, not for formal
releases.
* Added new Autoconf M4 macros (ATF_ARG_WITH, ATF_CHECK_C and
ATF_CHECK_CXX) to provide a consistent way of defining a --with-arg flag
in configure scripts and detecting the presence of any of the ATF
bindings. Note that ATF_CHECK_SH was already introduced in 0.14, but it
has now been modified to also honor --with-atf if instantiated.
* Added timing support to atf-run / atf-report.
* Added support for a 'require.memory' property, to specify the minimum
amount of physical memory needed by the test case to yield valid results.
* PR bin/45690: Force an ISO-8859-1 encoding in the XML files generated by
atf-report so that invalid data in the output of test cases does not
mangle our report.
Changes in version 0.14
***********************
Experimental version released on June 14th, 2011.
* Added a pkg-config file for atf-sh and an aclocal file to ease the
detection of atf-sh from autoconf scripts.
* Made the default test case body defined by atf_sh fail. This is to
ensure that test cases are properly defined in test programs and helps
in catching typos in the names of the body functions.
* PR bin/44882: Made atf-run connect the stdin of test cases to /dev/zero.
This provides more consistent results with "normal" execution (in
particular, when tests are executed detached from a terminal).
* Made atf-run hardcode TZ=UTC for test cases. It used to undefine TZ, but
that does not take into account that libc determines the current timezone
from a configuration file.
* All test programs will now print a warning when they are not run through
atf-run(1) stating that this is unsupported and may deliver incorrect
results.
* Added support for the 'require.files' test-case property. This allows
test cases to specify installed files that must be present for the test
case to run.
Changes in version 0.13
***********************
Experimental version released on March 31st, 2011.
This is the first release after the creation of the Kyua project, a more
modular and reliable replacement for ATF. From now on, ATF will change to
accomodate the transition to this new codebase, but ATF will still continue
to see development in the short/medium term. Check out the project page at
http://code.google.com/p/kyua/ for more details.
The changes in this release are:
* Added support to run the tests with the Kyua runtime engine (kyua-cli), a
new package that aims to replace atf-run and atf-report. The ATF tests
can be run with the new system by issuing a 'make installcheck-kyua' from
the top-level directory of the project (assuming the 'kyua' binary is
available during the configuration stage of ATF).
* atf-run and atf-report are now in maintenance mode (but *not* deprecated
yet!). Kyua already implements a new, much more reliable runtime engine
that provides similar features to these tools. That said, it is not
complete yet so all development efforts should go towards it.
* If GDB is installed, atf-run dumps the stack trace of crashing test
programs in an attempt to aid debugging. Contributed by Antti Kantee.
* Reverted default timeout change in previous release and reset its value
to 5 minutes. This was causing several issues, specially when running
the existing NetBSD test suite in qemu.
* Fixed the 'match' output checker in atf-check to properly validate the
last line of a file even if it does not have a newline.
* Added the ATF_REQUIRE_IN and ATF_REQUIRE_NOT_IN macros to atf-c++ to
check for the presence (or lack thereof) of an element in a collection.
* PR bin/44176: Fixed a race condition in atf-run that would crash atf-run
when the cleanup of a test case triggered asynchronous modifications to
its work directory (e.g. killing a daemon process that cleans up a pid
file in the work directory).
* PR bin/44301: Fixed the sample XSLT file to report bogus test programs
instead of just listing them as having 0 test cases.
Changes in version 0.12
***********************
Experimental version released on November 7th, 2010.
* Added the ATF_REQUIRE_THROW_RE to atf-c++, which is the same as
ATF_REQUIRE_THROW but allows checking for the validity of the exception's
error message by means of a regular expression.
* Added the ATF_REQUIRE_MATCH to atf-c++, which allows checking for a
regular expression match in a string.
* Changed the default timeout for test cases from 5 minutes to 30 seconds.
30 seconds is long enough for virtually all tests to complete, and 5
minutes is a way too long pause in a test suite where a single test case
stalls.
* Deprecated the use.fs property. While this seemed like a good idea in
the first place to impose more control on what test cases can do, it
turns out to be bad. First, use.fs=false prevents bogus test cases
from dumping core so after-the-fact debugging is harder. Second,
supporting use.fs adds a lot of unnecessary complexity. atf-run will
now ignore any value provided to use.fs and will allow test cases to
freely access the file system if they wish to.
* Added the atf_tc_get_config_var_as_{bool,long}{,_wd} functions to the atf-c
library. The 'text' module became private in 0.11 but was being used
externally to simplify the parsing of configuration variables.
* Made atf-run recognize the 'unprivileged-user' configuration variable
and automatically drop root privileges when a test case sets
require.user=unprivileged. Note that this is, by no means, done for
security purposes; this is just for user convenience; tests should, in
general, not be blindly run as root in the first place.
Changes in version 0.11
***********************
Experimental version released on October 20th, 2010.
* The ATF_CHECK* macros in atf-c++ were renamed to ATF_REQUIRE* to match
their counterparts in atf-c.
* Clearly separated the modules in atf-c that are supposed to be public
from those that are implementation details. The header files for the
internal modules are not installed any more.
* Made the atf-check tool private. It is only required by atf-sh and being
public has the danger of causing confusion. Also, making it private
simplifies the public API of atf.
* Changed atf-sh to enable per-command error checking (set -e) by default.
This catches many cases in which a test case is broken but it is not
reported as such because execution continues.
* Fixed the XSTL and CSS stylesheets to support expected failures.
Changes in version 0.10
***********************
Experimental version released on July 2nd, 2010.
Miscellaneous features
* Added expected failures support to test cases and atf-run. These
include, for example, expected clean exits, expected reception of fatal
signals, expected timeouts and expected errors in condition checks.
These statuses can be used to denote test cases that are known to fail
due to a bug in the code they are testing. atf-report reports these
tests separately but they do not count towards the failed test cases
amount.
* Added the ATF_CHECK_ERRNO and ATF_REQUIRE_ERRNO to the C library to
allow easy checking of call failures that update errno.
* Added the has.cleanup meta-data property to test caes that specifies
whether the test case has a cleanup routine or not; its value is
automatically set. This property is read by atf-run to know if it has to
run the cleanup routine; skipping this run for every test case
significantly speeds up the run time of test suites.
* Reversed the order of the ATF_CHECK_THROW macro in the C++ binding to
take the expected exception as the first argument and the statement to
execute as the second argument.
Changes in atf-check
* Changed atf-check to support negating the status and output checks by
prefixing them with not- and added support to specify multiple checkers
for stdout and stderr, not only one.
* Added the match output checker to atf-check to look for regular
expressions in the stdout and stderr of commands.
* Modified the exit checks in atf-check to support checking for the
reception of signals.
Code simplifications and cleanups
* Removed usage messages from test programs to simplify the
implementation of every binding by a significant amount. They just now
refer the user to the appropriate manual page and do not attempt to wrap
lines on terminal boundaries. Test programs are not supposed to be run
by users directly so this minor interface regression is not important.
* Removed the atf-format internal utility, which is unused after the
change documented above.
* Removed the atf-cleanup internal utility. It has been unused since the
test case isolation was moved to atf-run in 0.8
* Splitted the Makefile.am into smaller files for easier maintenance and
dropped the use of M4. Only affects users building from the repository
sources.
* Intermixed tests with the source files in the source tree to provide
them more visibility and easier access. The tests directory is gone from
the source tree and tests are now suffixed by _test, not prefixed by t_.
* Simplifications to the atf-c library: removed the io, tcr and ui
modules as they had become unnecessary after all simplifications
introduced since the 0.8 release.
* Removed the application/X-atf-tcr format introduced in 0.8 release.
Tests now print a much simplified format that is easy to parse and nicer
to read by end users. As a side effect, the default for test cases is
now to print their results to stdout unless otherwise stated by providing
the -r flag.
* Removed XML distribution documents and replaced them with plain-text
documents. They provided little value and introduced a lot of complexity
to the build system.
* Simplified the output of atf-version by not attempting to print a
revision number when building form a distfile. Makes the build system
easier to maintain.
Changes in version 0.9
**********************
Experimental version released on June 3rd, 2010.
* Added atf-sh, an interpreter to process test programs written using
the shell API. This is not really a shell interpreter by itself though:
it is just a wrapper around the system shell that eases the loading of
the necessary ATF libraries.
* Removed atf-compile in favour of atf-sh.
* Added the use.fs metadata property to test case, which is used to
specify which test cases require file system access. This is to
highlight dependencies on external resources more clearly and to speed up
the execution of test suites by skipping the creation of many unnecessary
work directories.
* Fixed test programs to get a sane default value for their source
directory. This means that it should not be necessary any more to pass
-s when running test programs that do not live in the current directory.
* Defining test case headers became optional. This is trivial to achieve
in shell-based tests but a bit ugly in C and C++. In C, use the new
ATF_TC_WITHOUT_HEAD macro to define the test case, and in C++ use
ATF_TEST_CASE_WITHOUT_HEAD.
Changes in version 0.8
**********************
Experimental version released on May 7th, 2010.
* Test programs no longer run several test cases in a row. The execution
of a test program now requires a test case name, and that single test
case is executed. To execute several test cases, use the atf-run utility
as usual.
* Test programs no longer fork a subprocess to isolate the execution of
test cases. They run the test case code in-process, and a crash of the
test case will result in a crash of the test program. This is to ease
debugging of faulty test cases.
* Test programs no longer isolate their test cases. This means that they
will not create temporary directories nor sanitize the environment any
more. Yes: running a test case that depends on system state by hand will
most likely yield different results depending on where (machine,
directory, user environment, etc.) it is run. Isolation has been moved
to atf-run.
* Test programs no longer print a cryptic format (application/X-atf-tcs)
on a special file channel. They can now print whatever they want on the
screen. Because test programs can now only run one test case every time,
providing controlled output is not necessary any more.
* Test programs no longer write their status into a special file
descriptor. Instead, they create a file with the results, which is later
parsed by atf-run. This changes the semantics of the -r flag.
* atf-run has been adjusted to perform the test case isolation. As a
result, there is now a single canonical place that implements the
isolation of test caes. In previous releases, the three language
bindings (C, C++ and shell) had to be kept in sync with each other (read:
not a nice thing to do at all). As a side effect of this change, writing
bindings for other languages will be much, much easier from now on.
* atf-run forks test programs on a test case basis, instead of on a test
program basis as it did before. This is to provide the test case
isolation that was before implemented by the test programs themselves.
* Removed the atf-exec tool. This was used to implement test case
isolation in atf-sh, but it is now unnecessary.
* It is now optional to define the descr meta-data property. It has been
proven to be mostly useless, because test cases often carry a descriptive
name of their own.
Changes in version 0.7
**********************
Experimental version released on December 22nd, 2009.
* Added build-time checks to atf-c and atf-c++. A binding for atf-sh
will come later.
* Migrated all build-time checks for header files to proper ATF tests.
This demonstrates the use of the new feature described above.
* Added an internal API for child process management.
* Converted all plain-text distribution documents to a Docbook canonical
version, and include pre-generated plain text and HTML copies in the
distribution file.
* Simplified the contents of the Makefile.am by regenerating it from a
canonical Makefile.am.m4 source. As a side-effect, some dependency
specifications were fixed.
* Migrated all checks from the check target to installcheck, as these
require ATF to be installed.
* Fixed sign comparison mismatches triggered by the now-enabled
-Wsign-compare.
* Fixed many memory and object leaks.
Changes in version 0.6
**********************
Experimental version released on January 18th, 2009.
* Make atf-exec be able to kill its child process after a certain period
of time; this is controlled through the new -t option.
* Change atf-sh to use atf-exec's -t option to control the test case's
timeouts, instead of doing it internally. Same behavior as before, but
noticeably faster.
* atf-exec's -g option and atf-killpg are gone due to the previous
change.
* Added the atf-check(1) tool, a program that executes a given command
and checks its exit code against a known value and allows the management
of stdout and stderr in multiple ways. This replaces the previous
atf_check function in the atf-sh library and exposes this functionality
to both atf-c and atf-c++.
* Added the ATF_REQUIRE family of macros to the C interface. These help
in checking for fatal test conditions. The old ATF_CHECK macros now
perform non-fatal checks only. I.e. by using ATF_CHECK, the test case
can now continue its execution and the failures will not be reported
until the end of the whole run.
* Extended the amount of ATF_CHECK_* C macros with new ones to provide
more features to the developer. These also have their corresponding
counterparts in the ATF_REQUIRE_* family. The new macros (listing the
suffixes only) are: _EQ (replaces _EQUAL), _EQ_MSG, _STREQ and
_STREQ_MSG.
Changes in version 0.5
**********************
Experimental version released on May 1st, 2008.
* 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.
Changes in version 0.4
**********************
Experimental version released on February 4th, 2008.
* 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.
Changes in version 0.3
**********************
Experimental version released on November 11th, 2007.
* 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.
Changes in version 0.2
**********************
Experimental version released on September 20th, 2007.
* 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.
Changes in version 0.1
**********************
Experimental version released on August 20th, 2007.
* First public version. This was released coinciding with the end of the
Google Summer of Code 2007 program.
===========================================================================
vim: filetype=text:textwidth=75:expandtab:shiftwidth=2:softtabstop=2

View file

@ -1,40 +0,0 @@
Introductory information Automated Testing Framework
===========================================================================
Introduction
************
The Automated Testing Framework (ATF) is a collection of libraries and
utilities designed to ease unattended application testing in the hands of
developers and end users of a specific piece of software.
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.
* 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.
===========================================================================
vim: filetype=text:textwidth=75:expandtab:shiftwidth=2:softtabstop=2

View file

@ -1,45 +0,0 @@
# Welcome to the ATF project!
ATF, or Automated Testing Framework, is a **collection of libraries** to
write test programs in **C, C++ and POSIX shell**.
The ATF libraries offer a simple API. The API is orthogonal through the
various bindings, allowing developers to quickly learn how to write test
programs in different languages.
ATF-based test programs offer a **consistent end-user command-line
interface** to allow both humans and automation to run the tests.
ATF-based test programs **rely on an execution engine** to be run and
this execution engine is *not* shipped with ATF.
**[Kyua](https://github.com/jmmv/kyua/) is the engine of choice.**
## Download
Formal releases for source files are available for download from GitHub:
* [atf 0.20](../../releases/tag/atf-0.20), released on February 7th, 2014.
## Installation
You are encouraged to install binary packages for your operating system
wherever available:
* Fedora 20 and above: install the `atf` package with `yum install atf`.
* FreeBSD 10.0 and above: install the `atf` package with `pkg install atf`.
* NetBSD with pkgsrc: install the `pkgsrc/devel/atf` package.
Should you want to build and install ATF from the source tree provided
here, follow the instructions in the [INSTALL file](INSTALL).
## Support
Please use the
[atf-discuss mailing list](https://groups.google.com/forum/#!forum/atf-discuss)
for any support inquiries related to `atf-c`, `atf-c++` or `atf-sh`.
If you have any questions on Kyua proper, please use the
[kyua-discuss mailing list](https://groups.google.com/forum/#!forum/kyua-discuss)
instead.

1226
unit/atf-src/aclocal.m4 vendored

File diff suppressed because it is too large Load diff

View file

@ -1,38 +0,0 @@
# Copyright (c) 2007 The NetBSD Foundation, Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
# CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
dist-hook: check-style
PHONY_TARGETS += check-style
check-style:
$(srcdir)/admin/check-style.sh
EXTRA_DIST += admin/check-style-common.awk \
admin/check-style-c.awk \
admin/check-style-cpp.awk \
admin/check-style-man.awk \
admin/check-style-shell.awk \
admin/check-style.sh
# vim: syntax=make:noexpandtab:shiftwidth=8:softtabstop=8

View file

@ -1,270 +0,0 @@
#! /bin/sh
# Wrapper for Microsoft lib.exe
me=ar-lib
scriptversion=2012-03-01.08; # UTC
# Copyright (C) 2010-2017 Free Software Foundation, Inc.
# Written by Peter Rosin <peda@lysator.liu.se>.
#
# 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, see <http://www.gnu.org/licenses/>.
# 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>.
# func_error message
func_error ()
{
echo "$me: $1" 1>&2
exit 1
}
file_conv=
# func_file_conv build_file
# Convert a $build file to $host form and store it in $file
# Currently only supports Windows hosts.
func_file_conv ()
{
file=$1
case $file in
/ | /[!/]*) # absolute file, and not a UNC file
if test -z "$file_conv"; then
# lazily determine how to convert abs files
case `uname -s` in
MINGW*)
file_conv=mingw
;;
CYGWIN*)
file_conv=cygwin
;;
*)
file_conv=wine
;;
esac
fi
case $file_conv in
mingw)
file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
;;
cygwin)
file=`cygpath -m "$file" || echo "$file"`
;;
wine)
file=`winepath -w "$file" || echo "$file"`
;;
esac
;;
esac
}
# func_at_file at_file operation archive
# Iterate over all members in AT_FILE performing OPERATION on ARCHIVE
# for each of them.
# When interpreting the content of the @FILE, do NOT use func_file_conv,
# since the user would need to supply preconverted file names to
# binutils ar, at least for MinGW.
func_at_file ()
{
operation=$2
archive=$3
at_file_contents=`cat "$1"`
eval set x "$at_file_contents"
shift
for member
do
$AR -NOLOGO $operation:"$member" "$archive" || exit $?
done
}
case $1 in
'')
func_error "no command. Try '$0 --help' for more information."
;;
-h | --h*)
cat <<EOF
Usage: $me [--help] [--version] PROGRAM ACTION ARCHIVE [MEMBER...]
Members may be specified in a file named with @FILE.
EOF
exit $?
;;
-v | --v*)
echo "$me, version $scriptversion"
exit $?
;;
esac
if test $# -lt 3; then
func_error "you must specify a program, an action and an archive"
fi
AR=$1
shift
while :
do
if test $# -lt 2; then
func_error "you must specify a program, an action and an archive"
fi
case $1 in
-lib | -LIB \
| -ltcg | -LTCG \
| -machine* | -MACHINE* \
| -subsystem* | -SUBSYSTEM* \
| -verbose | -VERBOSE \
| -wx* | -WX* )
AR="$AR $1"
shift
;;
*)
action=$1
shift
break
;;
esac
done
orig_archive=$1
shift
func_file_conv "$orig_archive"
archive=$file
# strip leading dash in $action
action=${action#-}
delete=
extract=
list=
quick=
replace=
index=
create=
while test -n "$action"
do
case $action in
d*) delete=yes ;;
x*) extract=yes ;;
t*) list=yes ;;
q*) quick=yes ;;
r*) replace=yes ;;
s*) index=yes ;;
S*) ;; # the index is always updated implicitly
c*) create=yes ;;
u*) ;; # TODO: don't ignore the update modifier
v*) ;; # TODO: don't ignore the verbose modifier
*)
func_error "unknown action specified"
;;
esac
action=${action#?}
done
case $delete$extract$list$quick$replace,$index in
yes,* | ,yes)
;;
yesyes*)
func_error "more than one action specified"
;;
*)
func_error "no action specified"
;;
esac
if test -n "$delete"; then
if test ! -f "$orig_archive"; then
func_error "archive not found"
fi
for member
do
case $1 in
@*)
func_at_file "${1#@}" -REMOVE "$archive"
;;
*)
func_file_conv "$1"
$AR -NOLOGO -REMOVE:"$file" "$archive" || exit $?
;;
esac
done
elif test -n "$extract"; then
if test ! -f "$orig_archive"; then
func_error "archive not found"
fi
if test $# -gt 0; then
for member
do
case $1 in
@*)
func_at_file "${1#@}" -EXTRACT "$archive"
;;
*)
func_file_conv "$1"
$AR -NOLOGO -EXTRACT:"$file" "$archive" || exit $?
;;
esac
done
else
$AR -NOLOGO -LIST "$archive" | sed -e 's/\\/\\\\/g' | while read member
do
$AR -NOLOGO -EXTRACT:"$member" "$archive" || exit $?
done
fi
elif test -n "$quick$replace"; then
if test ! -f "$orig_archive"; then
if test -z "$create"; then
echo "$me: creating $orig_archive"
fi
orig_archive=
else
orig_archive=$archive
fi
for member
do
case $1 in
@*)
func_file_conv "${1#@}"
set x "$@" "@$file"
;;
*)
func_file_conv "$1"
set x "$@" "$file"
;;
esac
shift
shift
done
if test -n "$orig_archive"; then
$AR -NOLOGO -OUT:"$archive" "$orig_archive" "$@" || exit $?
else
$AR -NOLOGO -OUT:"$archive" "$@" || exit $?
fi
elif test -n "$list"; then
if test ! -f "$orig_archive"; then
func_error "archive not found"
fi
$AR -NOLOGO -LIST "$archive" || exit $?
fi

View file

@ -1,90 +0,0 @@
# Copyright (c) 2007 The NetBSD Foundation, Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
# CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
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,78 +0,0 @@
# Copyright (c) 2007 The NetBSD Foundation, Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
# CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
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 > 80)
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,86 +0,0 @@
# Copyright (c) 2007 The NetBSD Foundation, Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
# CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
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");
}
/std::endl/ {
warn("Use \\n instead of std::endl");
}
/\/\*/ {
warn("Do not use C-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,74 +0,0 @@
# Copyright (c) 2007 The NetBSD Foundation, Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
# CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
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,102 +0,0 @@
# Copyright (c) 2007 The NetBSD Foundation, Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
# CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
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");
}
/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,186 +0,0 @@
#! /bin/sh
# Copyright (c) 2007 The NetBSD Foundation, Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
# CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# 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 "*.at" -o \
-name "*.awk" -o \
-name "*.c" -o \
-name "*.cpp" -o \
-name "*.h" -o \
-name "*.h.in" -o \
-name "*.hpp" -o \
-name "*.m4" -o \
-name "*.sh" \
\) -a \( \
\! -path "*/atf-[0-9]*" -a \
\! -path "*autom4te*" -a \
-type f -a \
\! -name "aclocal.m4" \
\! -name "config.h" \
\! -name "defs.h" \
\! -name "defs.hpp" \
\! -name "libtool.m4" \
\! -name "ltoptions.m4" \
\! -name "ltsugar.m4" \
\! -name "lt~obsolete.m4" \
\! -name "*.so.*" \
\) | grep -v tools/
}
#
# 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

View file

@ -1,348 +0,0 @@
#! /bin/sh
# Wrapper for compilers which do not understand '-c -o'.
scriptversion=2016-01-11.22; # UTC
# Copyright (C) 1999-2017 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, see <http://www.gnu.org/licenses/>.
# 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>.
nl='
'
# We need space, tab and new line, in precisely that order. Quoting is
# there to prevent tools from complaining about whitespace usage.
IFS=" "" $nl"
file_conv=
# func_file_conv build_file lazy
# Convert a $build file to $host form and store it in $file
# Currently only supports Windows hosts. If the determined conversion
# type is listed in (the comma separated) LAZY, no conversion will
# take place.
func_file_conv ()
{
file=$1
case $file in
/ | /[!/]*) # absolute file, and not a UNC file
if test -z "$file_conv"; then
# lazily determine how to convert abs files
case `uname -s` in
MINGW*)
file_conv=mingw
;;
CYGWIN*)
file_conv=cygwin
;;
*)
file_conv=wine
;;
esac
fi
case $file_conv/,$2, in
*,$file_conv,*)
;;
mingw/*)
file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
;;
cygwin/*)
file=`cygpath -m "$file" || echo "$file"`
;;
wine/*)
file=`winepath -w "$file" || echo "$file"`
;;
esac
;;
esac
}
# func_cl_dashL linkdir
# Make cl look for libraries in LINKDIR
func_cl_dashL ()
{
func_file_conv "$1"
if test -z "$lib_path"; then
lib_path=$file
else
lib_path="$lib_path;$file"
fi
linker_opts="$linker_opts -LIBPATH:$file"
}
# func_cl_dashl library
# Do a library search-path lookup for cl
func_cl_dashl ()
{
lib=$1
found=no
save_IFS=$IFS
IFS=';'
for dir in $lib_path $LIB
do
IFS=$save_IFS
if $shared && test -f "$dir/$lib.dll.lib"; then
found=yes
lib=$dir/$lib.dll.lib
break
fi
if test -f "$dir/$lib.lib"; then
found=yes
lib=$dir/$lib.lib
break
fi
if test -f "$dir/lib$lib.a"; then
found=yes
lib=$dir/lib$lib.a
break
fi
done
IFS=$save_IFS
if test "$found" != yes; then
lib=$lib.lib
fi
}
# func_cl_wrapper cl arg...
# Adjust compile command to suit cl
func_cl_wrapper ()
{
# Assume a capable shell
lib_path=
shared=:
linker_opts=
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'.
eat=1
case $2 in
*.o | *.[oO][bB][jJ])
func_file_conv "$2"
set x "$@" -Fo"$file"
shift
;;
*)
func_file_conv "$2"
set x "$@" -Fe"$file"
shift
;;
esac
;;
-I)
eat=1
func_file_conv "$2" mingw
set x "$@" -I"$file"
shift
;;
-I*)
func_file_conv "${1#-I}" mingw
set x "$@" -I"$file"
shift
;;
-l)
eat=1
func_cl_dashl "$2"
set x "$@" "$lib"
shift
;;
-l*)
func_cl_dashl "${1#-l}"
set x "$@" "$lib"
shift
;;
-L)
eat=1
func_cl_dashL "$2"
;;
-L*)
func_cl_dashL "${1#-L}"
;;
-static)
shared=false
;;
-Wl,*)
arg=${1#-Wl,}
save_ifs="$IFS"; IFS=','
for flag in $arg; do
IFS="$save_ifs"
linker_opts="$linker_opts $flag"
done
IFS="$save_ifs"
;;
-Xlinker)
eat=1
linker_opts="$linker_opts $2"
;;
-*)
set x "$@" "$1"
shift
;;
*.cc | *.CC | *.cxx | *.CXX | *.[cC]++)
func_file_conv "$1"
set x "$@" -Tp"$file"
shift
;;
*.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO])
func_file_conv "$1" mingw
set x "$@" "$file"
shift
;;
*)
set x "$@" "$1"
shift
;;
esac
fi
shift
done
if test -n "$linker_opts"; then
linker_opts="-link$linker_opts"
fi
exec "$@" $linker_opts
exit 1
}
eat=
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 $?
;;
cl | *[/\\]cl | cl.exe | *[/\\]cl.exe | \
icl | *[/\\]icl | icl.exe | *[/\\]icl.exe )
func_cl_wrapper "$@" # Doesn't return...
;;
esac
ofile=
cfile=
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 's|^.*[\\/]||; s|^[a-zA-Z]:||; 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
test "$cofile" = "$ofile" || mv "$cofile" "$ofile"
elif test -f "${cofile}bj"; then
test "${cofile}bj" = "$ofile" || 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-time-zone: "UTC0"
# time-stamp-end: "; # UTC"
# End:

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,791 +0,0 @@
#! /bin/sh
# depcomp - compile a program generating dependencies as side-effects
scriptversion=2016-01-11.22; # UTC
# Copyright (C) 1999-2017 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, see <http://www.gnu.org/licenses/>.
# 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 outputting dependencies.
libtool Whether libtool is used (yes/no).
Report bugs to <bug-automake@gnu.org>.
EOF
exit $?
;;
-v | --v*)
echo "depcomp $scriptversion"
exit $?
;;
esac
# Get the directory component of the given path, and save it in the
# global variables '$dir'. Note that this directory component will
# be either empty or ending with a '/' character. This is deliberate.
set_dir_from ()
{
case $1 in
*/*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;;
*) dir=;;
esac
}
# Get the suffix-stripped basename of the given path, and save it the
# global variable '$base'.
set_base_from ()
{
base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'`
}
# If no dependency file was actually created by the compiler invocation,
# we still have to create a dummy depfile, to avoid errors with the
# Makefile "include basename.Plo" scheme.
make_dummy_depfile ()
{
echo "#dummy" > "$depfile"
}
# Factor out some common post-processing of the generated depfile.
# Requires the auxiliary global variable '$tmpdepfile' to be set.
aix_post_process_depfile ()
{
# If the compiler actually managed to produce a dependency file,
# post-process it.
if test -f "$tmpdepfile"; then
# Each line is of the form 'foo.o: dependency.h'.
# Do two passes, one to just change these to
# $object: dependency.h
# and one to simply output
# dependency.h:
# which is needed to avoid the deleted-header problem.
{ sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile"
sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile"
} > "$depfile"
rm -f "$tmpdepfile"
else
make_dummy_depfile
fi
}
# A tabulation character.
tab=' '
# A newline character.
nl='
'
# Character ranges might be problematic outside the C locale.
# These definitions help.
upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ
lower=abcdefghijklmnopqrstuvwxyz
digits=0123456789
alpha=${upper}${lower}
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"
# Avoid interferences from the environment.
gccflag= dashmflag=
# 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
cygpath_u="cygpath -u -f -"
if test "$depmode" = msvcmsys; then
# This is just like msvisualcpp but w/o cygpath translation.
# Just convert the backslash-escaped backslashes to single forward
# slashes to satisfy depend.m4
cygpath_u='sed s,\\\\,/,g'
depmode=msvisualcpp
fi
if test "$depmode" = msvc7msys; then
# This is just like msvc7 but w/o cygpath translation.
# Just convert the backslash-escaped backslashes to single forward
# slashes to satisfy depend.m4
cygpath_u='sed s,\\\\,/,g'
depmode=msvc7
fi
if test "$depmode" = xlc; then
# IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information.
gccflag=-qmakedep=gcc,-MF
depmode=gcc
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 -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
mv "$tmpdepfile" "$depfile"
;;
gcc)
## Note that this doesn't just cater to obsosete pre-3.x GCC compilers.
## but also to in-use compilers like IMB xlc/xlC and the HP C compiler.
## (see the conditional assignment to $gccflag above).
## 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). Also, it might not be
## supported by the other compilers which use the 'gcc' depmode.
## - 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 -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
echo "$object : \\" > "$depfile"
# 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.
## 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. hp depmode also adds that space, but also prefixes the VPATH
## to the object. Take care to not repeat it in the output.
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
tr ' ' "$nl" < "$tmpdepfile" \
| sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -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 -ne 0; then
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 ' ' "$nl" < "$tmpdepfile" \
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \
| tr "$nl" ' ' >> "$depfile"
echo >> "$depfile"
# The second pass generates a dummy entry for each header file.
tr ' ' "$nl" < "$tmpdepfile" \
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
>> "$depfile"
else
make_dummy_depfile
fi
rm -f "$tmpdepfile"
;;
xlc)
# 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
;;
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.
set_dir_from "$object"
set_base_from "$object"
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 -ne 0; then
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
exit $stat
fi
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
do
test -f "$tmpdepfile" && break
done
aix_post_process_depfile
;;
tcc)
# tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26
# FIXME: That version still under development at the moment of writing.
# Make that this statement remains true also for stable, released
# versions.
# It will wrap lines (doesn't matter whether long or short) with a
# trailing '\', as in:
#
# foo.o : \
# foo.c \
# foo.h \
#
# It will put a trailing '\' even on the last line, and will use leading
# spaces rather than leading tabs (at least since its commit 0394caf7
# "Emit spaces for -MD").
"$@" -MD -MF "$tmpdepfile"
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
# Each non-empty line is of the form 'foo.o : \' or ' dep.h \'.
# We have to change lines of the first kind to '$object: \'.
sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile"
# And for each line of the second kind, we have to emit a 'dep.h:'
# dummy dependency, to avoid the deleted-header problem.
sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile"
rm -f "$tmpdepfile"
;;
## The order of this option in the case statement is important, since the
## shell code in configure will try each of these formats in the order
## listed in this file. A plain '-MD' option would be understood by many
## compilers, so we must ensure this comes after the gcc and icc options.
pgcc)
# Portland's C compiler understands '-MD'.
# Will always output deps to 'file.d' where file is the root name of the
# source file under compilation, even if file resides in a subdirectory.
# The object file name does not affect the name of the '.d' file.
# pgcc 10.2 will output
# foo.o: sub/foo.c sub/foo.h
# and will wrap long lines using '\' :
# foo.o: sub/foo.c ... \
# sub/foo.h ... \
# ...
set_dir_from "$object"
# Use the source, not the object, to determine the base name, since
# that's sadly what pgcc will do too.
set_base_from "$source"
tmpdepfile=$base.d
# For projects that build the same source file twice into different object
# files, the pgcc approach of using the *source* file root name can cause
# problems in parallel builds. Use a locking strategy to avoid stomping on
# the same $tmpdepfile.
lockdir=$base.d-lock
trap "
echo '$0: caught signal, cleaning up...' >&2
rmdir '$lockdir'
exit 1
" 1 2 13 15
numtries=100
i=$numtries
while test $i -gt 0; do
# mkdir is a portable test-and-set.
if mkdir "$lockdir" 2>/dev/null; then
# This process acquired the lock.
"$@" -MD
stat=$?
# Release the lock.
rmdir "$lockdir"
break
else
# If the lock is being held by a different process, wait
# until the winning process is done or we timeout.
while test -d "$lockdir" && test $i -gt 0; do
sleep 1
i=`expr $i - 1`
done
fi
i=`expr $i - 1`
done
trap - 1 2 13 15
if test $i -le 0; then
echo "$0: failed to acquire lock after $numtries attempts" >&2
echo "$0: check lockdir '$lockdir'" >&2
exit 1
fi
if test $stat -ne 0; then
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.
set_dir_from "$object"
set_base_from "$object"
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 -ne 0; then
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,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile"
# Add 'dependent.h:' lines.
sed -ne '2,${
s/^ *//
s/ \\*$//
s/$/:/
p
}' "$tmpdepfile" >> "$depfile"
else
make_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.
set_dir_from "$object"
set_base_from "$object"
if test "$libtool" = yes; then
# Libtool 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$base.o.d # libtool 1.5
tmpdepfile2=$dir.libs/$base.o.d # Likewise.
tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504
"$@" -Wc,-MD
else
tmpdepfile1=$dir$base.d
tmpdepfile2=$dir$base.d
tmpdepfile3=$dir$base.d
"$@" -MD
fi
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
exit $stat
fi
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
do
test -f "$tmpdepfile" && break
done
# Same post-processing that is required for AIX mode.
aix_post_process_depfile
;;
msvc7)
if test "$libtool" = yes; then
showIncludes=-Wc,-showIncludes
else
showIncludes=-showIncludes
fi
"$@" $showIncludes > "$tmpdepfile"
stat=$?
grep -v '^Note: including file: ' "$tmpdepfile"
if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
echo "$object : \\" > "$depfile"
# The first sed program below extracts the file names and escapes
# backslashes for cygpath. The second sed program outputs the file
# name when reading, but also accumulates all include files in the
# hold buffer in order to output them again at the end. This only
# works with sed implementations that can handle large buffers.
sed < "$tmpdepfile" -n '
/^Note: including file: *\(.*\)/ {
s//\1/
s/\\/\\\\/g
p
}' | $cygpath_u | sort -u | sed -n '
s/ /\\ /g
s/\(.*\)/'"$tab"'\1 \\/p
s/.\(.*\) \\/\1:/
H
$ {
s/.*/'"$tab"'/
G
p
}' >> "$depfile"
echo >> "$depfile" # make sure the fragment doesn't end with a backslash
rm -f "$tmpdepfile"
;;
msvc7msys)
# 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
;;
#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 "X$1" != 'X--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|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile"
rm -f "$depfile"
cat < "$tmpdepfile" > "$depfile"
# Some versions of the HPUX 10.20 sed can't process this sed invocation
# correctly. Breaking it into two sed invocations is a workaround.
tr ' ' "$nl" < "$tmpdepfile" \
| 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 "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
# X makedepend
shift
cleared=no eat=no
for arg
do
case $cleared in
no)
set ""; shift
cleared=yes ;;
esac
if test $eat = yes; then
eat=no
continue
fi
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.
-arch)
eat=yes ;;
-*|$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"
# makedepend may prepend the VPATH from the source file name to the object.
# No need to regex-escape $object, excess matching of '.' is harmless.
sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile"
# Some versions of the HPUX 10.20 sed can't process the last invocation
# correctly. Breaking it into two sed invocations is a workaround.
sed '1,2d' "$tmpdepfile" \
| tr ' ' "$nl" \
| 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 "X$1" != 'X--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.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
IFS=" "
for arg
do
case "$arg" in
-o)
shift
;;
$object)
shift
;;
"-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
set fnord "$@"
shift
shift
;;
*)
set fnord "$@" "$arg"
shift
shift
;;
esac
done
"$@" -E 2>/dev/null |
sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile"
rm -f "$depfile"
echo "$object : \\" > "$depfile"
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile"
echo "$tab" >> "$depfile"
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile"
rm -f "$tmpdepfile"
;;
msvcmsys)
# 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
;;
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-time-zone: "UTC0"
# time-stamp-end: "; # UTC"
# End:

View file

@ -1,501 +0,0 @@
#!/bin/sh
# install - install a program, script, or datafile
scriptversion=2016-01-11.22; # UTC
# This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the
# following copyright and license.
#
# Copyright (C) 1994 X Consortium
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name of the X Consortium shall not
# be used in advertising or otherwise to promote the sale, use or other deal-
# ings in this Software without prior written authorization from the X Consor-
# tium.
#
#
# FSF changes to this file are in the public domain.
#
# 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.
tab=' '
nl='
'
IFS=" $tab$nl"
# Set DOITPROG to "echo" to test this script.
doit=${DOITPROG-}
doit_exec=${doit:-exec}
# Put in absolute file names if you don't have them in your path;
# or use environment vars.
chgrpprog=${CHGRPPROG-chgrp}
chmodprog=${CHMODPROG-chmod}
chownprog=${CHOWNPROG-chown}
cmpprog=${CMPPROG-cmp}
cpprog=${CPPROG-cp}
mkdirprog=${MKDIRPROG-mkdir}
mvprog=${MVPROG-mv}
rmprog=${RMPROG-rm}
stripprog=${STRIPPROG-strip}
posix_mkdir=
# Desired mode of installed file.
mode=0755
chgrpcmd=
chmodcmd=$chmodprog
chowncmd=
mvcmd=$mvprog
rmcmd="$rmprog -f"
stripcmd=
src=
dst=
dir_arg=
dst_arg=
copy_on_change=false
is_target_a_directory=possibly
usage="\
Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
or: $0 [OPTION]... SRCFILES... DIRECTORY
or: $0 [OPTION]... -t DIRECTORY SRCFILES...
or: $0 [OPTION]... -d DIRECTORIES...
In the 1st form, copy SRCFILE to DSTFILE.
In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
In the 4th, create DIRECTORIES.
Options:
--help display this help and exit.
--version display version info and exit.
-c (ignored)
-C install only if different (preserve the last data modification time)
-d create directories instead of installing files.
-g GROUP $chgrpprog installed files to GROUP.
-m MODE $chmodprog installed files to MODE.
-o USER $chownprog installed files to USER.
-s $stripprog installed files.
-t DIRECTORY install into DIRECTORY.
-T report an error if DSTFILE is a directory.
Environment variables override the default commands:
CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
RMPROG STRIPPROG
"
while test $# -ne 0; do
case $1 in
-c) ;;
-C) copy_on_change=true;;
-d) dir_arg=true;;
-g) chgrpcmd="$chgrpprog $2"
shift;;
--help) echo "$usage"; exit $?;;
-m) mode=$2
case $mode in
*' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*)
echo "$0: invalid mode: $mode" >&2
exit 1;;
esac
shift;;
-o) chowncmd="$chownprog $2"
shift;;
-s) stripcmd=$stripprog;;
-t)
is_target_a_directory=always
dst_arg=$2
# Protect names problematic for 'test' and other utilities.
case $dst_arg in
-* | [=\(\)!]) dst_arg=./$dst_arg;;
esac
shift;;
-T) is_target_a_directory=never;;
--version) echo "$0 $scriptversion"; exit $?;;
--) shift
break;;
-*) echo "$0: invalid option: $1" >&2
exit 1;;
*) break;;
esac
shift
done
# We allow the use of options -d and -T together, by making -d
# take the precedence; this is for compatibility with GNU install.
if test -n "$dir_arg"; then
if test -n "$dst_arg"; then
echo "$0: target directory not allowed when installing a directory." >&2
exit 1
fi
fi
if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
# When -d is used, all remaining arguments are directories to create.
# When -t is used, the destination is already specified.
# Otherwise, the last argument is the destination. Remove it from $@.
for arg
do
if test -n "$dst_arg"; then
# $@ is not empty: it contains at least $arg.
set fnord "$@" "$dst_arg"
shift # fnord
fi
shift # arg
dst_arg=$arg
# Protect names problematic for 'test' and other utilities.
case $dst_arg in
-* | [=\(\)!]) dst_arg=./$dst_arg;;
esac
done
fi
if test $# -eq 0; then
if test -z "$dir_arg"; then
echo "$0: no input file specified." >&2
exit 1
fi
# It's OK to call 'install-sh -d' without argument.
# This can happen when creating conditional directories.
exit 0
fi
if test -z "$dir_arg"; then
if test $# -gt 1 || test "$is_target_a_directory" = always; then
if test ! -d "$dst_arg"; then
echo "$0: $dst_arg: Is not a directory." >&2
exit 1
fi
fi
fi
if test -z "$dir_arg"; then
do_exit='(exit $ret); exit $ret'
trap "ret=129; $do_exit" 1
trap "ret=130; $do_exit" 2
trap "ret=141; $do_exit" 13
trap "ret=143; $do_exit" 15
# Set umask so as not to create temps with too-generous modes.
# However, 'strip' requires both read and write access to temps.
case $mode in
# Optimize common cases.
*644) cp_umask=133;;
*755) cp_umask=22;;
*[0-7])
if test -z "$stripcmd"; then
u_plus_rw=
else
u_plus_rw='% 200'
fi
cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
*)
if test -z "$stripcmd"; then
u_plus_rw=
else
u_plus_rw=,u+rw
fi
cp_umask=$mode$u_plus_rw;;
esac
fi
for src
do
# Protect names problematic for 'test' and other utilities.
case $src in
-* | [=\(\)!]) src=./$src;;
esac
if test -n "$dir_arg"; then
dst=$src
dstdir=$dst
test -d "$dstdir"
dstdir_status=$?
else
# Waiting for this to be detected by the "$cpprog $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if test ! -f "$src" && test ! -d "$src"; then
echo "$0: $src does not exist." >&2
exit 1
fi
if test -z "$dst_arg"; then
echo "$0: no destination specified." >&2
exit 1
fi
dst=$dst_arg
# If destination is a directory, append the input filename; won't work
# if double slashes aren't ignored.
if test -d "$dst"; then
if test "$is_target_a_directory" = never; then
echo "$0: $dst_arg: Is a directory" >&2
exit 1
fi
dstdir=$dst
dst=$dstdir/`basename "$src"`
dstdir_status=0
else
dstdir=`dirname "$dst"`
test -d "$dstdir"
dstdir_status=$?
fi
fi
obsolete_mkdir_used=false
if test $dstdir_status != 0; then
case $posix_mkdir in
'')
# Create intermediate dirs using mode 755 as modified by the umask.
# This is like FreeBSD 'install' as of 1997-10-28.
umask=`umask`
case $stripcmd.$umask in
# Optimize common cases.
*[2367][2367]) mkdir_umask=$umask;;
.*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
*[0-7])
mkdir_umask=`expr $umask + 22 \
- $umask % 100 % 40 + $umask % 20 \
- $umask % 10 % 4 + $umask % 2
`;;
*) mkdir_umask=$umask,go-w;;
esac
# With -d, create the new directory with the user-specified mode.
# Otherwise, rely on $mkdir_umask.
if test -n "$dir_arg"; then
mkdir_mode=-m$mode
else
mkdir_mode=
fi
posix_mkdir=false
case $umask in
*[123567][0-7][0-7])
# POSIX mkdir -p sets u+wx bits regardless of umask, which
# is incompatible with FreeBSD 'install' when (umask & 300) != 0.
;;
*)
tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
if (umask $mkdir_umask &&
exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
then
if test -z "$dir_arg" || {
# Check for POSIX incompatibilities with -m.
# HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
# other-writable bit of parent directory when it shouldn't.
# FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
ls_ld_tmpdir=`ls -ld "$tmpdir"`
case $ls_ld_tmpdir in
d????-?r-*) different_mode=700;;
d????-?--*) different_mode=755;;
*) false;;
esac &&
$mkdirprog -m$different_mode -p -- "$tmpdir" && {
ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
}
}
then posix_mkdir=:
fi
rmdir "$tmpdir/d" "$tmpdir"
else
# Remove any dirs left behind by ancient mkdir implementations.
rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
fi
trap '' 0;;
esac;;
esac
if
$posix_mkdir && (
umask $mkdir_umask &&
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
)
then :
else
# The umask is ridiculous, or mkdir does not conform to POSIX,
# or it failed possibly due to a race condition. Create the
# directory the slow way, step by step, checking for races as we go.
case $dstdir in
/*) prefix='/';;
[-=\(\)!]*) prefix='./';;
*) prefix='';;
esac
oIFS=$IFS
IFS=/
set -f
set fnord $dstdir
shift
set +f
IFS=$oIFS
prefixes=
for d
do
test X"$d" = X && continue
prefix=$prefix$d
if test -d "$prefix"; then
prefixes=
else
if $posix_mkdir; then
(umask=$mkdir_umask &&
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
# Don't fail if two instances are running concurrently.
test -d "$prefix" || exit 1
else
case $prefix in
*\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
*) qprefix=$prefix;;
esac
prefixes="$prefixes '$qprefix'"
fi
fi
prefix=$prefix/
done
if test -n "$prefixes"; then
# Don't fail if two instances are running concurrently.
(umask $mkdir_umask &&
eval "\$doit_exec \$mkdirprog $prefixes") ||
test -d "$dstdir" || exit 1
obsolete_mkdir_used=true
fi
fi
fi
if test -n "$dir_arg"; then
{ test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
{ test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
else
# Make a couple of temp file names in the proper directory.
dsttmp=$dstdir/_inst.$$_
rmtmp=$dstdir/_rm.$$_
# Trap to clean up those temp files at exit.
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
# Copy the file name to the temp name.
(umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
# 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 $cpprog $src $dsttmp" command.
#
{ test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
{ test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
{ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
# If -C, don't bother to copy if it wouldn't change the file.
if $copy_on_change &&
old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
set -f &&
set X $old && old=:$2:$4:$5:$6 &&
set X $new && new=:$2:$4:$5:$6 &&
set +f &&
test "$old" = "$new" &&
$cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
then
rm -f "$dsttmp"
else
# Rename the file to the real destination.
$doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
# The rename failed, perhaps because mv can't rename something else
# to itself, or perhaps because mv is so ancient that it does not
# support -f.
{
# Now remove or move aside any old file at destination location.
# We try this two ways since rm can't unlink itself on some
# systems and the destination file might be busy for other
# reasons. In this case, the final cleanup might fail but the new
# file should still install successfully.
{
test ! -f "$dst" ||
$doit $rmcmd -f "$dst" 2>/dev/null ||
{ $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
{ $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
} ||
{ echo "$0: cannot unlink or rename $dst" >&2
(exit 1); exit 1
}
} &&
# Now rename the file to the real destination.
$doit $mvcmd "$dsttmp" "$dst"
}
fi || exit 1
trap '' 0
fi
done
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC0"
# time-stamp-end: "; # UTC"
# End:

File diff suppressed because it is too large Load diff

View file

@ -1,215 +0,0 @@
#! /bin/sh
# Common wrapper for a few potentially missing GNU programs.
scriptversion=2016-01-11.22; # UTC
# Copyright (C) 1996-2017 Free Software Foundation, Inc.
# Originally written 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, see <http://www.gnu.org/licenses/>.
# 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
case $1 in
--is-lightweight)
# Used by our autoconf macros to check whether the available missing
# script is modern enough.
exit 0
;;
--run)
# Back-compat with the calling convention used by older automake.
shift
;;
-h|--h|--he|--hel|--help)
echo "\
$0 [OPTION]... PROGRAM [ARGUMENT]...
Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due
to PROGRAM being missing or too old.
Options:
-h, --help display this help and exit
-v, --version output version information and exit
Supported PROGRAM values:
aclocal autoconf autoheader autom4te automake makeinfo
bison yacc flex lex help2man
Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and
'g' are ignored when checking the name.
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
# Run the given program, remember its exit status.
"$@"; st=$?
# If it succeeded, we are done.
test $st -eq 0 && exit 0
# Also exit now if we it failed (or wasn't found), and '--version' was
# passed; such an option is passed most likely to detect whether the
# program is present and works.
case $2 in --version|--help) exit $st;; esac
# Exit code 63 means version mismatch. This often happens when the user
# tries to use an ancient version of a tool on a file that requires a
# minimum version.
if test $st -eq 63; then
msg="probably too old"
elif test $st -eq 127; then
# Program was missing.
msg="missing on your system"
else
# Program was found and executed, but failed. Give up.
exit $st
fi
perl_URL=http://www.perl.org/
flex_URL=http://flex.sourceforge.net/
gnu_software_URL=http://www.gnu.org/software
program_details ()
{
case $1 in
aclocal|automake)
echo "The '$1' program is part of the GNU Automake package:"
echo "<$gnu_software_URL/automake>"
echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:"
echo "<$gnu_software_URL/autoconf>"
echo "<$gnu_software_URL/m4/>"
echo "<$perl_URL>"
;;
autoconf|autom4te|autoheader)
echo "The '$1' program is part of the GNU Autoconf package:"
echo "<$gnu_software_URL/autoconf/>"
echo "It also requires GNU m4 and Perl in order to run:"
echo "<$gnu_software_URL/m4/>"
echo "<$perl_URL>"
;;
esac
}
give_advice ()
{
# Normalize program name to check for.
normalized_program=`echo "$1" | sed '
s/^gnu-//; t
s/^gnu//; t
s/^g//; t'`
printf '%s\n' "'$1' is $msg."
configure_deps="'configure.ac' or m4 files included by 'configure.ac'"
case $normalized_program in
autoconf*)
echo "You should only need it if you modified 'configure.ac',"
echo "or m4 files included by it."
program_details 'autoconf'
;;
autoheader*)
echo "You should only need it if you modified 'acconfig.h' or"
echo "$configure_deps."
program_details 'autoheader'
;;
automake*)
echo "You should only need it if you modified 'Makefile.am' or"
echo "$configure_deps."
program_details 'automake'
;;
aclocal*)
echo "You should only need it if you modified 'acinclude.m4' or"
echo "$configure_deps."
program_details 'aclocal'
;;
autom4te*)
echo "You might have modified some maintainer files that require"
echo "the 'autom4te' program to be rebuilt."
program_details 'autom4te'
;;
bison*|yacc*)
echo "You should only need it if you modified a '.y' file."
echo "You may want to install the GNU Bison package:"
echo "<$gnu_software_URL/bison/>"
;;
lex*|flex*)
echo "You should only need it if you modified a '.l' file."
echo "You may want to install the Fast Lexical Analyzer package:"
echo "<$flex_URL>"
;;
help2man*)
echo "You should only need it if you modified a dependency" \
"of a man page."
echo "You may want to install the GNU Help2man package:"
echo "<$gnu_software_URL/help2man/>"
;;
makeinfo*)
echo "You should only need it if you modified a '.texi' file, or"
echo "any other file indirectly affecting the aspect of the manual."
echo "You might want to install the Texinfo package:"
echo "<$gnu_software_URL/texinfo/>"
echo "The spurious makeinfo call might also be the consequence of"
echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might"
echo "want to install GNU make:"
echo "<$gnu_software_URL/make/>"
;;
*)
echo "You might have modified some files without having the proper"
echo "tools for further handling them. Check the 'README' file, it"
echo "often tells you about the needed prerequisites for installing"
echo "this package. You may also peek at any GNU archive site, in"
echo "case some other package contains this missing '$1' program."
;;
esac
}
give_advice "$1" | sed -e '1s/^/WARNING: /' \
-e '2,$s/^/ /' >&2
# Propagate the correct exit status (expected to be 127 for a program
# not found, 63 for a program that failed due to version mismatch).
exit $st
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC0"
# time-stamp-end: "; # UTC"
# End:

View file

@ -1,50 +0,0 @@
#! /bin/sh
# Copyright 2014 Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of Google Inc. nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
set -e -x
if [ -d /usr/local/share/aclocal ]; then
autoreconf -isv -I/usr/local/share/aclocal
else
autoreconf -isv
fi
./configure
if [ "${AS_ROOT:-no}" = yes ]; then
cat >root-kyua.conf <<EOF
syntax(2)
unprivileged_user = 'nobody'
EOF
sudo -H make distcheck DISTCHECK_CONFIGURE_FLAGS="${f}" \
KYUA_TEST_CONFIG_FILE="$(pwd)/root-kyua.conf"
else
make distcheck
fi
# vim: syntax=sh:expandtab:shiftwidth=4:softtabstop=4

View file

@ -1,77 +0,0 @@
#! /bin/sh
# Copyright 2014 Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of Google Inc. nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
set -e -x
sudo apt-get update -qq
sudo apt-get install -y liblua5.2-0 liblua5.2-dev \
libsqlite3-0 libsqlite3-dev pkg-config sqlite3
install_from_github() {
local project="${1}"; shift
local name="${1}"; shift
local release="${1}"; shift
local distname="${name}-${release}"
local baseurl="https://github.com/jmmv/${project}"
wget --no-check-certificate \
"${baseurl}/releases/download/${distname}/${distname}.tar.gz"
tar -xzvf "${distname}.tar.gz"
cd "${distname}"
./configure \
--disable-developer \
--without-atf \
--without-doxygen \
CPPFLAGS="-I/usr/local/include" \
LDFLAGS="-L/usr/local/lib -Wl,-R/usr/local/lib" \
PKG_CONFIG_PATH="/usr/local/lib/pkgconfig"
make
sudo make install
cd -
rm -rf "${distname}" "${distname}.tar.gz"
}
install_from_bintray() {
local name="20140803-usr-local-kyua-ubuntu-12-04-amd64-${CC:-gcc}.tar.gz"
wget "http://dl.bintray.com/jmmv/kyua/${name}" || return 1
sudo tar -xzvp -C / -f "${name}"
rm -f "${name}"
}
if ! install_from_bintray; then
install_from_github atf atf 0.20
install_from_github lutok lutok 0.4
install_from_github kyua kyua-testers 0.2
install_from_github kyua kyua-cli 0.8
fi
# vim: syntax=sh:expandtab:shiftwidth=4:softtabstop=4

View file

@ -1,32 +0,0 @@
// Copyright (c) 2007 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#if !defined(ATF_CXX_HPP)
#define ATF_CXX_HPP
#include <atf-c++/macros.hpp>
#include <atf-c++/utils.hpp>
#endif // !defined(ATF_CXX_HPP)

View file

@ -1,13 +0,0 @@
Content-Type: application/X-atf-atffile; version="1"
prop: test-suite = atf
tp: detail
tp: atf_c++_test
tp: build_test
tp: check_test
tp: macros_test
tp: pkg_config_test
tp: tests_test
tp: utils_test

View file

@ -1,13 +0,0 @@
syntax("kyuafile", 1)
test_suite("atf")
atf_test_program{name="atf_c++_test"}
atf_test_program{name="build_test"}
atf_test_program{name="check_test"}
atf_test_program{name="macros_test"}
atf_test_program{name="pkg_config_test"}
atf_test_program{name="tests_test"}
atf_test_program{name="utils_test"}
include("detail/Kyuafile")

View file

@ -1,101 +0,0 @@
# Copyright (c) 2007 The NetBSD Foundation, Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
# CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
ATF_CXX_LIBS = libatf-c++.la libatf-c.la
lib_LTLIBRARIES += libatf-c++.la
libatf_c___la_LIBADD = libatf-c.la
libatf_c___la_SOURCES = atf-c++/build.cpp \
atf-c++/build.hpp \
atf-c++/check.cpp \
atf-c++/check.hpp \
atf-c++/macros.hpp \
atf-c++/tests.cpp \
atf-c++/tests.hpp \
atf-c++/utils.cpp \
atf-c++/utils.hpp
libatf_c___la_LDFLAGS = -version-info 2:0:0
include_HEADERS += atf-c++.hpp
atf_c___HEADERS = atf-c++/build.hpp \
atf-c++/check.hpp \
atf-c++/macros.hpp \
atf-c++/tests.hpp \
atf-c++/utils.hpp
atf_c__dir = $(includedir)/atf-c++
dist_man_MANS += atf-c++/atf-c++.3
atf_aclocal_DATA += atf-c++/atf-c++.m4
EXTRA_DIST += atf-c++/atf-c++.m4
atf_c__dirpkgconfigdir = $(atf_pkgconfigdir)
atf_c__dirpkgconfig_DATA = atf-c++/atf-c++.pc
CLEANFILES += atf-c++/atf-c++.pc
EXTRA_DIST += atf-c++/atf-c++.pc.in
atf-c++/atf-c++.pc: $(srcdir)/atf-c++/atf-c++.pc.in Makefile
$(AM_V_GEN)test -d atf-c++ || mkdir -p atf-c++; \
sed -e 's#__ATF_VERSION__#$(PACKAGE_VERSION)#g' \
-e 's#__CXX__#$(CXX)#g' \
-e 's#__INCLUDEDIR__#$(includedir)#g' \
-e 's#__LIBDIR__#$(libdir)#g' \
<$(srcdir)/atf-c++/atf-c++.pc.in >atf-c++/atf-c++.pc.tmp; \
mv atf-c++/atf-c++.pc.tmp atf-c++/atf-c++.pc
tests_atf_c___DATA = atf-c++/Atffile \
atf-c++/Kyuafile \
atf-c++/macros_hpp_test.cpp \
atf-c++/unused_test.cpp
tests_atf_c__dir = $(pkgtestsdir)/atf-c++
EXTRA_DIST += $(tests_atf_c___DATA)
tests_atf_c___PROGRAMS = atf-c++/atf_c++_test
atf_c___atf_c___test_SOURCES = atf-c++/atf_c++_test.cpp
atf_c___atf_c___test_LDADD = atf-c++/detail/libtest_helpers.la $(ATF_CXX_LIBS)
tests_atf_c___PROGRAMS += atf-c++/build_test
atf_c___build_test_SOURCES = atf-c++/build_test.cpp atf-c/h_build.h
atf_c___build_test_LDADD = atf-c++/detail/libtest_helpers.la $(ATF_CXX_LIBS)
tests_atf_c___PROGRAMS += atf-c++/check_test
atf_c___check_test_SOURCES = atf-c++/check_test.cpp
atf_c___check_test_LDADD = atf-c++/detail/libtest_helpers.la $(ATF_CXX_LIBS)
tests_atf_c___PROGRAMS += atf-c++/macros_test
atf_c___macros_test_SOURCES = atf-c++/macros_test.cpp
atf_c___macros_test_LDADD = atf-c++/detail/libtest_helpers.la $(ATF_CXX_LIBS)
tests_atf_c___SCRIPTS = atf-c++/pkg_config_test
CLEANFILES += atf-c++/pkg_config_test
EXTRA_DIST += atf-c++/pkg_config_test.sh
atf-c++/pkg_config_test: $(srcdir)/atf-c++/pkg_config_test.sh
$(AM_V_GEN)src="$(srcdir)/atf-c++/pkg_config_test.sh"; \
dst="atf-c++/pkg_config_test"; $(BUILD_SH_TP)
tests_atf_c___PROGRAMS += atf-c++/tests_test
atf_c___tests_test_SOURCES = atf-c++/tests_test.cpp
atf_c___tests_test_LDADD = atf-c++/detail/libtest_helpers.la $(ATF_CXX_LIBS)
tests_atf_c___PROGRAMS += atf-c++/utils_test
atf_c___utils_test_SOURCES = atf-c++/utils_test.cpp
atf_c___utils_test_LDADD = atf-c++/detail/libtest_helpers.la $(ATF_CXX_LIBS)
include atf-c++/detail/Makefile.am.inc
# vim: syntax=make:noexpandtab:shiftwidth=8:softtabstop=8

View file

@ -1,649 +0,0 @@
.\" 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 October 13, 2014
.Dt ATF-C++ 3
.Os
.Sh NAME
.Nm atf-c++ ,
.Nm ATF_ADD_TEST_CASE ,
.Nm ATF_CHECK_ERRNO ,
.Nm ATF_FAIL ,
.Nm ATF_INIT_TEST_CASES ,
.Nm ATF_PASS ,
.Nm ATF_REQUIRE ,
.Nm ATF_REQUIRE_EQ ,
.Nm ATF_REQUIRE_ERRNO ,
.Nm ATF_REQUIRE_IN ,
.Nm ATF_REQUIRE_MATCH ,
.Nm ATF_REQUIRE_NOT_IN ,
.Nm ATF_REQUIRE_THROW ,
.Nm ATF_REQUIRE_THROW_RE ,
.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_NAME ,
.Nm ATF_TEST_CASE_USE ,
.Nm ATF_TEST_CASE_WITH_CLEANUP ,
.Nm ATF_TEST_CASE_WITHOUT_HEAD ,
.Nm atf::utils::cat_file ,
.Nm atf::utils::compare_file ,
.Nm atf::utils::copy_file ,
.Nm atf::utils::create_file ,
.Nm atf::utils::file_exists ,
.Nm atf::utils::fork ,
.Nm atf::utils::grep_collection ,
.Nm atf::utils::grep_file ,
.Nm atf::utils::grep_string ,
.Nm atf::utils::redirect ,
.Nm atf::utils::wait
.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_ERRNO "expected_errno" "bool_expression"
.Fn ATF_FAIL "reason"
.Fn ATF_INIT_TEST_CASES "tcs"
.Fn ATF_PASS
.Fn ATF_REQUIRE "expression"
.Fn ATF_REQUIRE_EQ "expected_expression" "actual_expression"
.Fn ATF_REQUIRE_ERRNO "expected_errno" "bool_expression"
.Fn ATF_REQUIRE_IN "element" "collection"
.Fn ATF_REQUIRE_MATCH "regexp" "string_expression"
.Fn ATF_REQUIRE_NOT_IN "element" "collection"
.Fn ATF_REQUIRE_THROW "expected_exception" "statement"
.Fn ATF_REQUIRE_THROW_RE "expected_exception" "regexp" "statement"
.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_NAME "name"
.Fn ATF_TEST_CASE_USE "name"
.Fn ATF_TEST_CASE_WITH_CLEANUP "name"
.Fn ATF_TEST_CASE_WITHOUT_HEAD "name"
.Ft void
.Fo atf::utils::cat_file
.Fa "const std::string& path"
.Fa "const std::string& prefix"
.Fc
.Ft bool
.Fo atf::utils::compare_file
.Fa "const std::string& path"
.Fa "const std::string& contents"
.Fc
.Ft void
.Fo atf::utils::copy_file
.Fa "const std::string& source"
.Fa "const std::string& destination"
.Fc
.Ft void
.Fo atf::utils::create_file
.Fa "const std::string& path"
.Fa "const std::string& contents"
.Fc
.Ft void
.Fo atf::utils::file_exists
.Fa "const std::string& path"
.Fc
.Ft pid_t
.Fo atf::utils::fork
.Fa "void"
.Fc
.Ft bool
.Fo atf::utils::grep_collection
.Fa "const std::string& regexp"
.Fa "const Collection& collection"
.Fc
.Ft bool
.Fo atf::utils::grep_file
.Fa "const std::string& regexp"
.Fa "const std::string& path"
.Fc
.Ft bool
.Fo atf::utils::grep_string
.Fa "const std::string& regexp"
.Fa "const std::string& path"
.Fc
.Ft void
.Fo atf::utils::redirect
.Fa "const int fd"
.Fa "const std::string& path"
.Fc
.Ft void
.Fo atf::utils::wait
.Fa "const pid_t pid"
.Fa "const int expected_exit_status"
.Fa "const std::string& expected_stdout"
.Fa "const std::string& expected_stderr"
.Fc
.Sh DESCRIPTION
ATF provides a C++ programming interface to implement test programs.
C++-based test programs 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 ...
}
ATF_TEST_CASE(tc3);
ATF_TEST_CASE_BODY(tc3)
{
... third test case's body ...
}
.Ns ... additional test cases ...
ATF_INIT_TEST_CASES(tcs)
{
ATF_ADD_TEST_CASE(tcs, tc1);
ATF_ADD_TEST_CASE(tcs, tc2);
ATF_ADD_TEST_CASE(tcs, tc3);
... 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 4 .
To define test cases, one can use the
.Fn ATF_TEST_CASE ,
.Fn ATF_TEST_CASE_WITH_CLEANUP
or the
.Fn ATF_TEST_CASE_WITHOUT_HEAD
macros, which take a single parameter specifiying the test case's
name.
.Fn ATF_TEST_CASE ,
requires to define a head and a body for the test case,
.Fn ATF_TEST_CASE_WITH_CLEANUP
requires to define a head, a body and a cleanup for the test case and
.Fn ATF_TEST_CASE_WITHOUT_HEAD
requires only a body for the test case.
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.
.Pp
Additionally, the
.Fn ATF_TEST_CASE_NAME
macro can be used to obtain the name of the class corresponding to a
particular test case, as the name is internally manged by the library to
prevent clashes with other user identifiers.
Similarly, the
.Fn ATF_TEST_CASE_USE
macro can be executed on a particular test case to mark it as "used" and
thus prevent compiler warnings regarding unused symbols.
Note that
.Em you should never have to use these macros during regular operation.
.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_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 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 Expectations
Everything explained in the previous section changes when the test case
expectations are redefined by the programmer.
.Pp
Each test case has an internal state called
.Sq expect
that describes what the test case expectations are at any point in time.
The value of this property can change during execution by any of:
.Bl -tag -width indent
.It Fn expect_death "reason"
Expects the test case to exit prematurely regardless of the nature of the
exit.
.It Fn expect_exit "exitcode" "reason"
Expects the test case to exit cleanly.
If
.Va exitcode
is not
.Sq -1 ,
the runtime engine will validate that the exit code of the test case
matches the one provided in this call.
Otherwise, the exact value will be ignored.
.It Fn expect_fail "reason"
Any failure (be it fatal or non-fatal) raised in this mode is recorded.
However, such failures do not report the test case as failed; instead, the
test case finalizes cleanly and is reported as
.Sq expected failure ;
this report includes the provided
.Fa reason
as part of it.
If no error is raised while running in this mode, then the test case is
reported as
.Sq failed .
.Pp
This mode is useful to reproduce actual known bugs in tests.
Whenever the developer fixes the bug later on, the test case will start
reporting a failure, signaling the developer that the test case must be
adjusted to the new conditions.
In this situation, it is useful, for example, to set
.Fa reason
as the bug number for tracking purposes.
.It Fn expect_pass
This is the normal mode of execution.
In this mode, any failure is reported as such to the user and the test case
is marked as
.Sq failed .
.It Fn expect_race "reason"
Any failure or timeout during the execution of the test case will be
considered as if a race condition has been triggered and reported as such.
If no problems arise, the test will continue execution as usual.
.It Fn expect_signal "signo" "reason"
Expects the test case to terminate due to the reception of a signal.
If
.Va signo
is not
.Sq -1 ,
the runtime engine will validate that the signal that terminated the test
case matches the one provided in this call.
Otherwise, the exact value will be ignored.
.It Fn expect_timeout "reason"
Expects the test case to execute for longer than its timeout.
.El
.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_REQUIRE
takes an expression and raises a failure if it evaluates to false.
.Pp
.Fn ATF_REQUIRE_EQ
takes two expressions and raises a failure if the two do not evaluate to
the same exact value.
The common style is to put the expected value in the first parameter and the
actual value in the second parameter.
.Pp
.Fn ATF_REQUIRE_IN
takes an element and a collection and validates that the element is present in
the collection.
.Pp
.Fn ATF_REQUIRE_MATCH
takes a regular expression and a string and raises a failure if the regular
expression does not match the string.
.Pp
.Fn ATF_REQUIRE_NOT_IN
takes an element and a collection and validates that the element is not present
in the collection.
.Pp
.Fn ATF_REQUIRE_THROW
takes the name of an exception and a statement and raises a failure if
the statement does not throw the specified exception.
.Fn ATF_REQUIRE_THROW_RE
takes the name of an exception, a regular expresion and a statement and raises a
failure if the statement does not throw the specified exception and if the
message of the exception does not match the regular expression.
.Pp
.Fn ATF_CHECK_ERRNO
and
.Fn ATF_REQUIRE_ERRNO
take, first, the error code that the check is expecting to find in the
.Va errno
variable and, second, a boolean expression that, if evaluates to true,
means that a call failed and
.Va errno
has to be checked against the first value.
.Ss Utility functions
The following functions are provided as part of the
.Nm
API to simplify the creation of a variety of tests.
In particular, these are useful to write tests for command-line interfaces.
.Pp
.Ft void
.Fo atf::utils::cat_file
.Fa "const std::string& path"
.Fa "const std::string& prefix"
.Fc
.Bd -ragged -offset indent
Prints the contents of
.Fa path
to the standard output, prefixing every line with the string in
.Fa prefix .
.Ed
.Pp
.Ft bool
.Fo atf::utils::compare_file
.Fa "const std::string& path"
.Fa "const std::string& contents"
.Fc
.Bd -ragged -offset indent
Returns true if the given
.Fa path
matches exactly the expected inlined
.Fa contents .
.Ed
.Pp
.Ft void
.Fo atf::utils::copy_file
.Fa "const std::string& source"
.Fa "const std::string& destination"
.Fc
.Bd -ragged -offset indent
Copies the file
.Fa source
to
.Fa destination .
The permissions of the file are preserved during the code.
.Ed
.Pp
.Ft void
.Fo atf::utils::create_file
.Fa "const std::string& path"
.Fa "const std::string& contents"
.Fc
.Bd -ragged -offset indent
Creates
.Fa file
with the text given in
.Fa contents .
.Ed
.Pp
.Ft void
.Fo atf::utils::file_exists
.Fa "const std::string& path"
.Fc
.Bd -ragged -offset indent
Checks if
.Fa path
exists.
.Ed
.Pp
.Ft pid_t
.Fo atf::utils::fork
.Fa "void"
.Fc
.Bd -ragged -offset indent
Forks a process and redirects the standard output and standard error of the
child to files for later validation with
.Fn atf::utils::wait .
Fails the test case if the fork fails, so this does not return an error.
.Ed
.Pp
.Ft bool
.Fo atf::utils::grep_collection
.Fa "const std::string& regexp"
.Fa "const Collection& collection"
.Fc
.Bd -ragged -offset indent
Searches for the regular expression
.Fa regexp
in any of the strings contained in the
.Fa collection .
This is a template that accepts any one-dimensional container of strings.
.Ed
.Pp
.Ft bool
.Fo atf::utils::grep_file
.Fa "const std::string& regexp"
.Fa "const std::string& path"
.Fc
.Bd -ragged -offset indent
Searches for the regular expression
.Fa regexp
in the file
.Fa path .
The variable arguments are used to construct the regular expression.
.Ed
.Pp
.Ft bool
.Fo atf::utils::grep_string
.Fa "const std::string& regexp"
.Fa "const std::string& str"
.Fc
.Bd -ragged -offset indent
Searches for the regular expression
.Fa regexp
in the string
.Fa str .
.Ed
.Ft void
.Fo atf::utils::redirect
.Fa "const int fd"
.Fa "const std::string& path"
.Fc
.Bd -ragged -offset indent
Redirects the given file descriptor
.Fa fd
to the file
.Fa path .
This function exits the process in case of an error and does not properly mark
the test case as failed.
As a result, it should only be used in subprocesses of the test case; specially
those spawned by
.Fn atf::utils::fork .
.Ed
.Pp
.Ft void
.Fo atf::utils::wait
.Fa "const pid_t pid"
.Fa "const int expected_exit_status"
.Fa "const std::string& expected_stdout"
.Fa "const std::string& expected_stderr"
.Fc
.Bd -ragged -offset indent
Waits and validates the result of a subprocess spawned with
.Fn atf::utils::wait .
The validation involves checking that the subprocess exited cleanly and returned
the code specified in
.Fa expected_exit_status
and that its standard output and standard error match the strings given in
.Fa expected_stdout
and
.Fa expected_stderr .
.Pp
If any of the
.Fa expected_stdout
or
.Fa expected_stderr
strings are prefixed with
.Sq save: ,
then they specify the name of the file into which to store the stdout or stderr
of the subprocess, and no comparison is performed.
.Ed
.Sh ENVIRONMENT
The following variables are recognized by
.Nm
but should not be overridden other than for testing purposes:
.Pp
.Bl -tag -width ATFXBUILDXCXXFLAGSXX -compact
.It Va ATF_BUILD_CC
Path to the C compiler.
.It Va ATF_BUILD_CFLAGS
C compiler flags.
.It Va ATF_BUILD_CPP
Path to the C/C++ preprocessor.
.It Va ATF_BUILD_CPPFLAGS
C/C++ preprocessor flags.
.It Va ATF_BUILD_CXX
Path to the C++ compiler.
.It Va ATF_BUILD_CXXFLAGS
C++ compiler flags.
.El
.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_md_var("descr", "Sample tests for the addition operator");
}
ATF_TEST_CASE_BODY(addition)
{
ATF_REQUIRE_EQ(0, 0 + 0);
ATF_REQUIRE_EQ(1, 0 + 1);
ATF_REQUIRE_EQ(1, 1 + 0);
ATF_REQUIRE_EQ(2, 1 + 1);
ATF_REQUIRE_EQ(300, 100 + 200);
}
ATF_TEST_CASE(open_failure);
ATF_TEST_CASE_HEAD(open_failure)
{
set_md_var("descr", "Sample tests for the open function");
}
ATF_TEST_CASE_BODY(open_failure)
{
ATF_REQUIRE_ERRNO(ENOENT, open("non-existent", O_RDONLY) == -1);
}
ATF_TEST_CASE(known_bug);
ATF_TEST_CASE_HEAD(known_bug)
{
set_md_var("descr", "Reproduces a known bug");
}
ATF_TEST_CASE_BODY(known_bug)
{
expect_fail("See bug number foo/bar");
ATF_REQUIRE_EQ(3, 1 + 1);
expect_pass();
ATF_REQUIRE_EQ(3, 1 + 2);
}
ATF_INIT_TEST_CASES(tcs)
{
ATF_ADD_TEST_CASE(tcs, addition);
ATF_ADD_TEST_CASE(tcs, open_failure);
ATF_ADD_TEST_CASE(tcs, known_bug);
}
.Ed
.Sh SEE ALSO
.Xr atf-test-program 1 ,
.Xr atf-test-case 4

View file

@ -1,44 +0,0 @@
dnl Copyright 2011 Google Inc.
dnl All rights reserved.
dnl
dnl Redistribution and use in source and binary forms, with or without
dnl modification, are permitted provided that the following conditions are
dnl met:
dnl
dnl * Redistributions of source code must retain the above copyright
dnl notice, this list of conditions and the following disclaimer.
dnl * Redistributions in binary form must reproduce the above copyright
dnl notice, this list of conditions and the following disclaimer in the
dnl documentation and/or other materials provided with the distribution.
dnl * Neither the name of Google Inc. nor the names of its contributors
dnl may be used to endorse or promote products derived from this software
dnl without specific prior written permission.
dnl
dnl THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
dnl "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
dnl LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
dnl A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
dnl OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
dnl SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
dnl LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
dnl DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
dnl THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
dnl (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
dnl OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
dnl ATF_CHECK_CXX([version-spec])
dnl
dnl Checks if atf-c++ is present. If version-spec is provided, ensures that
dnl the installed version of atf-sh matches the required version. This
dnl argument must be something like '>= 0.14' and accepts any version
dnl specification supported by pkg-config.
dnl
dnl Defines and substitutes ATF_CXX_CFLAGS and ATF_CXX_LIBS with the compiler
dnl and linker flags need to build against atf-c++.
AC_DEFUN([ATF_CHECK_CXX], [
spec="atf-c++[]m4_default_nblank([ $1], [])"
_ATF_CHECK_ARG_WITH(
[PKG_CHECK_MODULES([ATF_CXX], [${spec}],
[found=yes found_atf_cxx=yes], [found=no])],
[required ${spec} not found])
])

View file

@ -1,11 +0,0 @@
# ATF pkg-config file
cxx=__CXX__
includedir=__INCLUDEDIR__
libdir=__LIBDIR__
Name: atf-c++
Description: Automated Testing Framework (C++ binding)
Version: __ATF_VERSION__
Cflags: -I${includedir}
Libs: -L${libdir} -latf-c++ -latf-c

View file

@ -1,44 +0,0 @@
// Copyright (c) 2009 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <atf-c++.hpp>
#include "atf-c++/detail/test_helpers.hpp"
// ------------------------------------------------------------------------
// Tests cases for the header file.
// ------------------------------------------------------------------------
HEADER_TC(include, "atf-c++.hpp");
// ------------------------------------------------------------------------
// Main.
// ------------------------------------------------------------------------
ATF_INIT_TEST_CASES(tcs)
{
// Add the test cases for the header file.
ATF_ADD_TEST_CASE(tcs, include);
}

View file

@ -1,115 +0,0 @@
// Copyright (c) 2009 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "atf-c++/build.hpp"
extern "C" {
#include "atf-c/build.h"
#include "atf-c/error.h"
#include "atf-c/utils.h"
}
#include "atf-c++/detail/exceptions.hpp"
#include "atf-c++/detail/process.hpp"
namespace impl = atf::build;
#define IMPL_NAME "atf::build"
// ------------------------------------------------------------------------
// Auxiliary functions.
// ------------------------------------------------------------------------
inline
atf::process::argv_array
cargv_to_argv(const atf_list_t* l)
{
std::vector< const char* > aux;
atf_list_citer_t iter;
atf_list_for_each_c(iter, l)
aux.push_back(static_cast< const char* >(atf_list_citer_data(iter)));
return atf::process::argv_array(aux);
}
inline
atf::process::argv_array
cargv_to_argv_and_free(char** l)
{
try {
atf::process::argv_array argv((const char* const*)l);
atf_utils_free_charpp(l);
return argv;
} catch (...) {
atf_utils_free_charpp(l);
throw;
}
}
// ------------------------------------------------------------------------
// Free functions.
// ------------------------------------------------------------------------
atf::process::argv_array
impl::c_o(const std::string& sfile, const std::string& ofile,
const atf::process::argv_array& optargs)
{
char** l;
atf_error_t err = atf_build_c_o(sfile.c_str(), ofile.c_str(),
optargs.exec_argv(), &l);
if (atf_is_error(err))
throw_atf_error(err);
return cargv_to_argv_and_free(l);
}
atf::process::argv_array
impl::cpp(const std::string& sfile, const std::string& ofile,
const atf::process::argv_array& optargs)
{
char** l;
atf_error_t err = atf_build_cpp(sfile.c_str(), ofile.c_str(),
optargs.exec_argv(), &l);
if (atf_is_error(err))
throw_atf_error(err);
return cargv_to_argv_and_free(l);
}
atf::process::argv_array
impl::cxx_o(const std::string& sfile, const std::string& ofile,
const atf::process::argv_array& optargs)
{
char** l;
atf_error_t err = atf_build_cxx_o(sfile.c_str(), ofile.c_str(),
optargs.exec_argv(), &l);
if (atf_is_error(err))
throw_atf_error(err);
return cargv_to_argv_and_free(l);
}

View file

@ -1,53 +0,0 @@
// Copyright (c) 2009 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#if !defined(ATF_CXX_BUILD_HPP)
#define ATF_CXX_BUILD_HPP
#include <string>
namespace atf {
namespace process {
class argv_array;
} // namespace process
namespace build {
// ------------------------------------------------------------------------
// Free functions.
// ------------------------------------------------------------------------
process::argv_array c_o(const std::string&, const std::string&,
const process::argv_array&);
process::argv_array cpp(const std::string&, const std::string&,
const process::argv_array&);
process::argv_array cxx_o(const std::string&, const std::string&,
const process::argv_array&);
} // namespace build
} // namespace atf
#endif // !defined(ATF_CXX_BUILD_HPP)

View file

@ -1,226 +0,0 @@
// Copyright (c) 2009 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "atf-c++/build.hpp"
#include <cstring>
#include <iostream>
#include <atf-c++.hpp>
extern "C" {
#include "atf-c/h_build.h"
}
#include "atf-c++/detail/env.hpp"
#include "atf-c++/detail/process.hpp"
// ------------------------------------------------------------------------
// Auxiliary functions.
// ------------------------------------------------------------------------
template< class C >
void
print_col(const char* prefix, const C& c)
{
std::cout << prefix << ":";
for (typename C::const_iterator iter = c.begin(); iter != c.end();
iter++)
std::cout << " '" << *iter << "'";
std::cout << "\n";
}
static
void
print_array(const char* prefix, const char* const* a)
{
std::cout << prefix << ":";
for (; *a != NULL; a++)
std::cout << " '" << *a << "'";
std::cout << "\n";
}
static
void
verbose_set_env(const char *var, const char *val)
{
std::cout << "Setting " << var << " to '" << val << "'\n";
atf::env::set(var, val);
}
static
bool
equal_argvs(const atf::process::argv_array& aa, const char* const* array)
{
bool equal = true;
atf::process::argv_array::size_type i = 0;
while (equal && (i < aa.size() && array[i] != NULL)) {
if (std::strcmp(aa[i], array[i]) != 0)
equal = false;
else
i++;
}
if (equal && (i < aa.size() || array[i] != NULL))
equal = false;
return equal;
}
static
void
check_equal_argvs(const atf::process::argv_array& aa, const char* const* array)
{
print_array("Expected arguments", array);
print_col("Arguments returned", aa);
if (!equal_argvs(aa, array))
ATF_FAIL("The constructed argv differs from the expected values");
}
// ------------------------------------------------------------------------
// Internal test cases.
// ------------------------------------------------------------------------
ATF_TEST_CASE(equal_argvs);
ATF_TEST_CASE_HEAD(equal_argvs)
{
set_md_var("descr", "Tests the test case internal equal_argvs function");
}
ATF_TEST_CASE_BODY(equal_argvs)
{
{
const char* const array[] = { NULL };
const char* const argv[] = { NULL };
ATF_REQUIRE(equal_argvs(atf::process::argv_array(argv), array));
}
{
const char* const array[] = { NULL };
const char* const argv[] = { "foo", NULL };
ATF_REQUIRE(!equal_argvs(atf::process::argv_array(argv), array));
}
{
const char* const array[] = { "foo", NULL };
const char* const argv[] = { NULL };
ATF_REQUIRE(!equal_argvs(atf::process::argv_array(argv), array));
}
{
const char* const array[] = { "foo", NULL };
const char* const argv[] = { "foo", NULL };
ATF_REQUIRE(equal_argvs(atf::process::argv_array(argv), array));
}
}
// ------------------------------------------------------------------------
// Test cases for the free functions.
// ------------------------------------------------------------------------
ATF_TEST_CASE(c_o);
ATF_TEST_CASE_HEAD(c_o)
{
set_md_var("descr", "Tests the c_o function");
}
ATF_TEST_CASE_BODY(c_o)
{
for (struct c_o_test* test = c_o_tests; test->expargv[0] != NULL;
test++) {
std::cout << "> Test: " << test->msg << "\n";
verbose_set_env("ATF_BUILD_CC", test->cc);
verbose_set_env("ATF_BUILD_CFLAGS", test->cflags);
verbose_set_env("ATF_BUILD_CPPFLAGS", test->cppflags);
atf::process::argv_array argv =
atf::build::c_o(test->sfile, test->ofile,
atf::process::argv_array(test->optargs));
check_equal_argvs(argv, test->expargv);
}
}
ATF_TEST_CASE(cpp);
ATF_TEST_CASE_HEAD(cpp)
{
set_md_var("descr", "Tests the cpp function");
}
ATF_TEST_CASE_BODY(cpp)
{
for (struct cpp_test* test = cpp_tests; test->expargv[0] != NULL;
test++) {
std::cout << "> Test: " << test->msg << "\n";
verbose_set_env("ATF_BUILD_CPP", test->cpp);
verbose_set_env("ATF_BUILD_CPPFLAGS", test->cppflags);
atf::process::argv_array argv =
atf::build::cpp(test->sfile, test->ofile,
atf::process::argv_array(test->optargs));
check_equal_argvs(argv, test->expargv);
}
}
ATF_TEST_CASE(cxx_o);
ATF_TEST_CASE_HEAD(cxx_o)
{
set_md_var("descr", "Tests the cxx_o function");
}
ATF_TEST_CASE_BODY(cxx_o)
{
for (struct cxx_o_test* test = cxx_o_tests; test->expargv[0] != NULL;
test++) {
std::cout << "> Test: " << test->msg << "\n";
verbose_set_env("ATF_BUILD_CXX", test->cxx);
verbose_set_env("ATF_BUILD_CXXFLAGS", test->cxxflags);
verbose_set_env("ATF_BUILD_CPPFLAGS", test->cppflags);
atf::process::argv_array argv =
atf::build::cxx_o(test->sfile, test->ofile,
atf::process::argv_array(test->optargs));
check_equal_argvs(argv, test->expargv);
}
}
// ------------------------------------------------------------------------
// Main.
// ------------------------------------------------------------------------
ATF_INIT_TEST_CASES(tcs)
{
// Add the internal test cases.
ATF_ADD_TEST_CASE(tcs, equal_argvs);
// Add the test cases for the free functions.
ATF_ADD_TEST_CASE(tcs, c_o);
ATF_ADD_TEST_CASE(tcs, cpp);
ATF_ADD_TEST_CASE(tcs, cxx_o);
}

View file

@ -1,154 +0,0 @@
// Copyright (c) 2007 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "atf-c++/check.hpp"
#include <cstring>
extern "C" {
#include "atf-c/build.h"
#include "atf-c/error.h"
}
#include "atf-c++/detail/exceptions.hpp"
#include "atf-c++/detail/process.hpp"
#include "atf-c++/detail/sanity.hpp"
namespace impl = atf::check;
#define IMPL_NAME "atf::check"
// ------------------------------------------------------------------------
// The "check_result" class.
// ------------------------------------------------------------------------
impl::check_result::check_result(const atf_check_result_t* result)
{
std::memcpy(&m_result, result, sizeof(m_result));
}
impl::check_result::~check_result(void)
{
atf_check_result_fini(&m_result);
}
bool
impl::check_result::exited(void)
const
{
return atf_check_result_exited(&m_result);
}
int
impl::check_result::exitcode(void)
const
{
PRE(exited());
return atf_check_result_exitcode(&m_result);
}
bool
impl::check_result::signaled(void)
const
{
return atf_check_result_signaled(&m_result);
}
int
impl::check_result::termsig(void)
const
{
PRE(signaled());
return atf_check_result_termsig(&m_result);
}
const std::string
impl::check_result::stdout_path(void) const
{
return atf_check_result_stdout(&m_result);
}
const std::string
impl::check_result::stderr_path(void) const
{
return atf_check_result_stderr(&m_result);
}
// ------------------------------------------------------------------------
// Free functions.
// ------------------------------------------------------------------------
bool
impl::build_c_o(const std::string& sfile, const std::string& ofile,
const atf::process::argv_array& optargs)
{
bool success;
atf_error_t err = atf_check_build_c_o(sfile.c_str(), ofile.c_str(),
optargs.exec_argv(), &success);
if (atf_is_error(err))
throw_atf_error(err);
return success;
}
bool
impl::build_cpp(const std::string& sfile, const std::string& ofile,
const atf::process::argv_array& optargs)
{
bool success;
atf_error_t err = atf_check_build_cpp(sfile.c_str(), ofile.c_str(),
optargs.exec_argv(), &success);
if (atf_is_error(err))
throw_atf_error(err);
return success;
}
bool
impl::build_cxx_o(const std::string& sfile, const std::string& ofile,
const atf::process::argv_array& optargs)
{
bool success;
atf_error_t err = atf_check_build_cxx_o(sfile.c_str(), ofile.c_str(),
optargs.exec_argv(), &success);
if (atf_is_error(err))
throw_atf_error(err);
return success;
}
std::auto_ptr< impl::check_result >
impl::exec(const atf::process::argv_array& argva)
{
atf_check_result_t result;
atf_error_t err = atf_check_exec_array(argva.exec_argv(), &result);
if (atf_is_error(err))
throw_atf_error(err);
return std::auto_ptr< impl::check_result >(new impl::check_result(&result));
}

View file

@ -1,131 +0,0 @@
// Copyright (c) 2007 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#if !defined(ATF_CXX_CHECK_HPP)
#define ATF_CXX_CHECK_HPP
extern "C" {
#include <atf-c/check.h>
}
#include <cstddef>
#include <memory>
#include <string>
#include <vector>
namespace atf {
namespace process {
class argv_array;
} // namespace process
namespace check {
// ------------------------------------------------------------------------
// The "check_result" class.
// ------------------------------------------------------------------------
//!
//! \brief A class that contains results of executed command.
//!
//! The check_result class holds information about results
//! of executing arbitrary command and manages files containing
//! its output.
//!
class check_result {
// Non-copyable.
check_result(const check_result&);
check_result& operator=(const check_result&);
//!
//! \brief Internal representation of a result.
//!
atf_check_result_t m_result;
//!
//! \brief Constructs a results object and grabs ownership of the
//! parameter passed in.
//!
check_result(const atf_check_result_t* result);
friend check_result test_constructor(const char* const*);
friend std::auto_ptr< check_result > exec(const atf::process::argv_array&);
public:
//!
//! \brief Destroys object and removes all managed files.
//!
~check_result(void);
//!
//! \brief Returns whether the command exited correctly or not.
//!
bool exited(void) const;
//!
//! \brief Returns command's exit status.
//!
int exitcode(void) const;
//!
//! \brief Returns whether the command received a signal or not.
//!
bool signaled(void) const;
//!
//! \brief Returns the signal that terminated the command.
//!
int termsig(void) const;
//!
//! \brief Returns the path to file contaning command's stdout.
//!
const std::string stdout_path(void) const;
//!
//! \brief Returns the path to file contaning command's stderr.
//!
const std::string stderr_path(void) const;
};
// ------------------------------------------------------------------------
// Free functions.
// ------------------------------------------------------------------------
bool build_c_o(const std::string&, const std::string&,
const atf::process::argv_array&);
bool build_cpp(const std::string&, const std::string&,
const atf::process::argv_array&);
bool build_cxx_o(const std::string&, const std::string&,
const atf::process::argv_array&);
std::auto_ptr< check_result > exec(const atf::process::argv_array&);
// Useful for testing only.
check_result test_constructor(void);
} // namespace check
} // namespace atf
#endif // !defined(ATF_CXX_CHECK_HPP)

View file

@ -1,394 +0,0 @@
// Copyright (c) 2007 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "atf-c++/check.hpp"
extern "C" {
#include <fcntl.h>
#include <signal.h>
#include <unistd.h>
}
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <iostream>
#include <list>
#include <memory>
#include <vector>
#include <atf-c++.hpp>
#include "atf-c++/detail/fs.hpp"
#include "atf-c++/detail/process.hpp"
#include "atf-c++/detail/test_helpers.hpp"
#include "atf-c++/detail/text.hpp"
#include "atf-c++/utils.hpp"
// ------------------------------------------------------------------------
// Auxiliary functions.
// ------------------------------------------------------------------------
static
std::auto_ptr< atf::check::check_result >
do_exec(const atf::tests::tc* tc, const char* helper_name)
{
std::vector< std::string > argv;
argv.push_back(get_process_helpers_path(*tc, false).str());
argv.push_back(helper_name);
std::cout << "Executing " << argv[0] << " " << argv[1] << "\n";
atf::process::argv_array argva(argv);
return atf::check::exec(argva);
}
static
std::auto_ptr< atf::check::check_result >
do_exec(const atf::tests::tc* tc, const char* helper_name, const char *carg2)
{
std::vector< std::string > argv;
argv.push_back(get_process_helpers_path(*tc, false).str());
argv.push_back(helper_name);
argv.push_back(carg2);
std::cout << "Executing " << argv[0] << " " << argv[1] << " "
<< argv[2] << "\n";
atf::process::argv_array argva(argv);
return atf::check::exec(argva);
}
// ------------------------------------------------------------------------
// Helper test cases for the free functions.
// ------------------------------------------------------------------------
ATF_TEST_CASE(h_build_c_o_ok);
ATF_TEST_CASE_HEAD(h_build_c_o_ok)
{
set_md_var("descr", "Helper test case for build_c_o");
}
ATF_TEST_CASE_BODY(h_build_c_o_ok)
{
std::ofstream sfile("test.c");
sfile << "#include <stdio.h>\n";
sfile.close();
ATF_REQUIRE(atf::check::build_c_o("test.c", "test.o",
atf::process::argv_array()));
}
ATF_TEST_CASE(h_build_c_o_fail);
ATF_TEST_CASE_HEAD(h_build_c_o_fail)
{
set_md_var("descr", "Helper test case for build_c_o");
}
ATF_TEST_CASE_BODY(h_build_c_o_fail)
{
std::ofstream sfile("test.c");
sfile << "void foo(void) { int a = UNDEFINED_SYMBOL; }\n";
sfile.close();
ATF_REQUIRE(!atf::check::build_c_o("test.c", "test.o",
atf::process::argv_array()));
}
ATF_TEST_CASE(h_build_cpp_ok);
ATF_TEST_CASE_HEAD(h_build_cpp_ok)
{
set_md_var("descr", "Helper test case for build_cpp");
}
ATF_TEST_CASE_BODY(h_build_cpp_ok)
{
std::ofstream sfile("test.c");
sfile << "#define A foo\n";
sfile << "#define B bar\n";
sfile << "A B\n";
sfile.close();
ATF_REQUIRE(atf::check::build_cpp("test.c", "test.p",
atf::process::argv_array()));
}
ATF_TEST_CASE(h_build_cpp_fail);
ATF_TEST_CASE_HEAD(h_build_cpp_fail)
{
set_md_var("descr", "Helper test case for build_cpp");
}
ATF_TEST_CASE_BODY(h_build_cpp_fail)
{
std::ofstream sfile("test.c");
sfile << "#include \"./non-existent.h\"\n";
sfile.close();
ATF_REQUIRE(!atf::check::build_cpp("test.c", "test.p",
atf::process::argv_array()));
}
ATF_TEST_CASE(h_build_cxx_o_ok);
ATF_TEST_CASE_HEAD(h_build_cxx_o_ok)
{
set_md_var("descr", "Helper test case for build_cxx_o");
}
ATF_TEST_CASE_BODY(h_build_cxx_o_ok)
{
std::ofstream sfile("test.cpp");
sfile << "#include <iostream>\n";
sfile.close();
ATF_REQUIRE(atf::check::build_cxx_o("test.cpp", "test.o",
atf::process::argv_array()));
}
ATF_TEST_CASE(h_build_cxx_o_fail);
ATF_TEST_CASE_HEAD(h_build_cxx_o_fail)
{
set_md_var("descr", "Helper test case for build_cxx_o");
}
ATF_TEST_CASE_BODY(h_build_cxx_o_fail)
{
std::ofstream sfile("test.cpp");
sfile << "void foo(void) { int a = UNDEFINED_SYMBOL; }\n";
sfile.close();
ATF_REQUIRE(!atf::check::build_cxx_o("test.cpp", "test.o",
atf::process::argv_array()));
}
// ------------------------------------------------------------------------
// Test cases for the free functions.
// ------------------------------------------------------------------------
ATF_TEST_CASE(build_c_o);
ATF_TEST_CASE_HEAD(build_c_o)
{
set_md_var("descr", "Tests the build_c_o function");
}
ATF_TEST_CASE_BODY(build_c_o)
{
ATF_TEST_CASE_USE(h_build_c_o_ok);
run_h_tc< ATF_TEST_CASE_NAME(h_build_c_o_ok) >();
ATF_REQUIRE(atf::utils::grep_file("-o test.o", "stdout"));
ATF_REQUIRE(atf::utils::grep_file("-c test.c", "stdout"));
ATF_TEST_CASE_USE(h_build_c_o_fail);
run_h_tc< ATF_TEST_CASE_NAME(h_build_c_o_fail) >();
ATF_REQUIRE(atf::utils::grep_file("-o test.o", "stdout"));
ATF_REQUIRE(atf::utils::grep_file("-c test.c", "stdout"));
ATF_REQUIRE(atf::utils::grep_file("test.c", "stderr"));
ATF_REQUIRE(atf::utils::grep_file("UNDEFINED_SYMBOL", "stderr"));
}
ATF_TEST_CASE(build_cpp);
ATF_TEST_CASE_HEAD(build_cpp)
{
set_md_var("descr", "Tests the build_cpp function");
}
ATF_TEST_CASE_BODY(build_cpp)
{
ATF_TEST_CASE_USE(h_build_cpp_ok);
run_h_tc< ATF_TEST_CASE_NAME(h_build_cpp_ok) >();
ATF_REQUIRE(atf::utils::grep_file("-o.*test.p", "stdout"));
ATF_REQUIRE(atf::utils::grep_file("test.c", "stdout"));
ATF_REQUIRE(atf::utils::grep_file("foo bar", "test.p"));
ATF_TEST_CASE_USE(h_build_cpp_fail);
run_h_tc< ATF_TEST_CASE_NAME(h_build_cpp_fail) >();
ATF_REQUIRE(atf::utils::grep_file("-o test.p", "stdout"));
ATF_REQUIRE(atf::utils::grep_file("test.c", "stdout"));
ATF_REQUIRE(atf::utils::grep_file("test.c", "stderr"));
ATF_REQUIRE(atf::utils::grep_file("non-existent.h", "stderr"));
}
ATF_TEST_CASE(build_cxx_o);
ATF_TEST_CASE_HEAD(build_cxx_o)
{
set_md_var("descr", "Tests the build_cxx_o function");
}
ATF_TEST_CASE_BODY(build_cxx_o)
{
ATF_TEST_CASE_USE(h_build_cxx_o_ok);
run_h_tc< ATF_TEST_CASE_NAME(h_build_cxx_o_ok) >();
ATF_REQUIRE(atf::utils::grep_file("-o test.o", "stdout"));
ATF_REQUIRE(atf::utils::grep_file("-c test.cpp", "stdout"));
ATF_TEST_CASE_USE(h_build_cxx_o_fail);
run_h_tc< ATF_TEST_CASE_NAME(h_build_cxx_o_fail) >();
ATF_REQUIRE(atf::utils::grep_file("-o test.o", "stdout"));
ATF_REQUIRE(atf::utils::grep_file("-c test.cpp", "stdout"));
ATF_REQUIRE(atf::utils::grep_file("test.cpp", "stderr"));
ATF_REQUIRE(atf::utils::grep_file("UNDEFINED_SYMBOL", "stderr"));
}
ATF_TEST_CASE(exec_cleanup);
ATF_TEST_CASE_HEAD(exec_cleanup)
{
set_md_var("descr", "Tests that exec properly cleans up the temporary "
"files it creates");
}
ATF_TEST_CASE_BODY(exec_cleanup)
{
std::auto_ptr< atf::fs::path > out;
std::auto_ptr< atf::fs::path > err;
{
std::auto_ptr< atf::check::check_result > r =
do_exec(this, "exit-success");
out.reset(new atf::fs::path(r->stdout_path()));
err.reset(new atf::fs::path(r->stderr_path()));
ATF_REQUIRE(atf::fs::exists(*out.get()));
ATF_REQUIRE(atf::fs::exists(*err.get()));
}
ATF_REQUIRE(!atf::fs::exists(*out.get()));
ATF_REQUIRE(!atf::fs::exists(*err.get()));
}
ATF_TEST_CASE(exec_exitstatus);
ATF_TEST_CASE_HEAD(exec_exitstatus)
{
set_md_var("descr", "Tests that exec properly captures the exit "
"status of the executed command");
}
ATF_TEST_CASE_BODY(exec_exitstatus)
{
{
std::auto_ptr< atf::check::check_result > r =
do_exec(this, "exit-success");
ATF_REQUIRE(r->exited());
ATF_REQUIRE(!r->signaled());
ATF_REQUIRE_EQ(r->exitcode(), EXIT_SUCCESS);
}
{
std::auto_ptr< atf::check::check_result > r =
do_exec(this, "exit-failure");
ATF_REQUIRE(r->exited());
ATF_REQUIRE(!r->signaled());
ATF_REQUIRE_EQ(r->exitcode(), EXIT_FAILURE);
}
{
std::auto_ptr< atf::check::check_result > r =
do_exec(this, "exit-signal");
ATF_REQUIRE(!r->exited());
ATF_REQUIRE(r->signaled());
ATF_REQUIRE_EQ(r->termsig(), SIGKILL);
}
}
static
void
check_lines(const std::string& path, const char* outname,
const char* resname)
{
std::ifstream f(path.c_str());
ATF_REQUIRE(f);
std::string line;
std::getline(f, line);
ATF_REQUIRE_EQ(line, std::string("Line 1 to ") + outname + " for " +
resname);
std::getline(f, line);
ATF_REQUIRE_EQ(line, std::string("Line 2 to ") + outname + " for " +
resname);
}
ATF_TEST_CASE(exec_stdout_stderr);
ATF_TEST_CASE_HEAD(exec_stdout_stderr)
{
set_md_var("descr", "Tests that exec properly captures the stdout "
"and stderr streams of the child process");
}
ATF_TEST_CASE_BODY(exec_stdout_stderr)
{
std::auto_ptr< atf::check::check_result > r1 =
do_exec(this, "stdout-stderr", "result1");
ATF_REQUIRE(r1->exited());
ATF_REQUIRE_EQ(r1->exitcode(), EXIT_SUCCESS);
std::auto_ptr< atf::check::check_result > r2 =
do_exec(this, "stdout-stderr", "result2");
ATF_REQUIRE(r2->exited());
ATF_REQUIRE_EQ(r2->exitcode(), EXIT_SUCCESS);
const std::string out1 = r1->stdout_path();
const std::string out2 = r2->stdout_path();
const std::string err1 = r1->stderr_path();
const std::string err2 = r2->stderr_path();
ATF_REQUIRE(out1.find("check.XXXXXX") == std::string::npos);
ATF_REQUIRE(out2.find("check.XXXXXX") == std::string::npos);
ATF_REQUIRE(err1.find("check.XXXXXX") == std::string::npos);
ATF_REQUIRE(err2.find("check.XXXXXX") == std::string::npos);
ATF_REQUIRE(out1.find("/check") != std::string::npos);
ATF_REQUIRE(out2.find("/check") != std::string::npos);
ATF_REQUIRE(err1.find("/check") != std::string::npos);
ATF_REQUIRE(err2.find("/check") != std::string::npos);
ATF_REQUIRE(out1.find("/stdout") != std::string::npos);
ATF_REQUIRE(out2.find("/stdout") != std::string::npos);
ATF_REQUIRE(err1.find("/stderr") != std::string::npos);
ATF_REQUIRE(err2.find("/stderr") != std::string::npos);
ATF_REQUIRE(out1 != out2);
ATF_REQUIRE(err1 != err2);
check_lines(out1, "stdout", "result1");
check_lines(out2, "stdout", "result2");
check_lines(err1, "stderr", "result1");
check_lines(err2, "stderr", "result2");
}
ATF_TEST_CASE(exec_unknown);
ATF_TEST_CASE_HEAD(exec_unknown)
{
set_md_var("descr", "Tests that running a non-existing binary "
"is handled correctly");
}
ATF_TEST_CASE_BODY(exec_unknown)
{
std::vector< std::string > argv;
argv.push_back("/foo/bar/non-existent");
atf::process::argv_array argva(argv);
std::auto_ptr< atf::check::check_result > r = atf::check::exec(argva);
ATF_REQUIRE(r->exited());
ATF_REQUIRE_EQ(r->exitcode(), 127);
}
// ------------------------------------------------------------------------
// Main.
// ------------------------------------------------------------------------
ATF_INIT_TEST_CASES(tcs)
{
// Add the test cases for the free functions.
ATF_ADD_TEST_CASE(tcs, build_c_o);
ATF_ADD_TEST_CASE(tcs, build_cpp);
ATF_ADD_TEST_CASE(tcs, build_cxx_o);
ATF_ADD_TEST_CASE(tcs, exec_cleanup);
ATF_ADD_TEST_CASE(tcs, exec_exitstatus);
ATF_ADD_TEST_CASE(tcs, exec_stdout_stderr);
ATF_ADD_TEST_CASE(tcs, exec_unknown);
}

View file

@ -1,10 +0,0 @@
Content-Type: application/X-atf-atffile; version="1"
prop: test-suite = atf
tp: application_test
tp: auto_array_test
tp: env_test
tp: exceptions_test
tp: fs_test
tp: text_test

View file

@ -1,11 +0,0 @@
syntax("kyuafile", 1)
test_suite("atf")
atf_test_program{name="application_test"}
atf_test_program{name="auto_array_test"}
atf_test_program{name="env_test"}
atf_test_program{name="exceptions_test"}
atf_test_program{name="fs_test"}
atf_test_program{name="process_test"}
atf_test_program{name="text_test"}

View file

@ -1,82 +0,0 @@
# Copyright (c) 2007 The NetBSD Foundation, Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
# CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
libatf_c___la_SOURCES += atf-c++/detail/application.cpp \
atf-c++/detail/application.hpp \
atf-c++/detail/auto_array.hpp \
atf-c++/detail/env.cpp \
atf-c++/detail/env.hpp \
atf-c++/detail/exceptions.cpp \
atf-c++/detail/exceptions.hpp \
atf-c++/detail/fs.cpp \
atf-c++/detail/fs.hpp \
atf-c++/detail/process.cpp \
atf-c++/detail/process.hpp \
atf-c++/detail/sanity.hpp \
atf-c++/detail/text.cpp \
atf-c++/detail/text.hpp
tests_atf_c___detail_DATA = atf-c++/detail/Atffile \
atf-c++/detail/Kyuafile
tests_atf_c___detaildir = $(pkgtestsdir)/atf-c++/detail
EXTRA_DIST += $(tests_atf_c___detail_DATA)
noinst_LTLIBRARIES += atf-c++/detail/libtest_helpers.la
atf_c___detail_libtest_helpers_la_SOURCES = atf-c++/detail/test_helpers.cpp \
atf-c++/detail/test_helpers.hpp
atf_c___detail_libtest_helpers_la_CPPFLAGS = -DATF_INCLUDEDIR=\"$(includedir)\"
tests_atf_c___detail_PROGRAMS = atf-c++/detail/application_test
atf_c___detail_application_test_SOURCES = atf-c++/detail/application_test.cpp
atf_c___detail_application_test_LDADD = atf-c++/detail/libtest_helpers.la $(ATF_CXX_LIBS)
tests_atf_c___detail_PROGRAMS += atf-c++/detail/auto_array_test
atf_c___detail_auto_array_test_SOURCES = atf-c++/detail/auto_array_test.cpp
atf_c___detail_auto_array_test_LDADD = atf-c++/detail/libtest_helpers.la $(ATF_CXX_LIBS)
tests_atf_c___detail_PROGRAMS += atf-c++/detail/env_test
atf_c___detail_env_test_SOURCES = atf-c++/detail/env_test.cpp
atf_c___detail_env_test_LDADD = atf-c++/detail/libtest_helpers.la $(ATF_CXX_LIBS)
tests_atf_c___detail_PROGRAMS += atf-c++/detail/exceptions_test
atf_c___detail_exceptions_test_SOURCES = atf-c++/detail/exceptions_test.cpp
atf_c___detail_exceptions_test_LDADD = atf-c++/detail/libtest_helpers.la $(ATF_CXX_LIBS)
tests_atf_c___detail_PROGRAMS += atf-c++/detail/fs_test
atf_c___detail_fs_test_SOURCES = atf-c++/detail/fs_test.cpp
atf_c___detail_fs_test_LDADD = atf-c++/detail/libtest_helpers.la $(ATF_CXX_LIBS)
tests_atf_c___detail_PROGRAMS += atf-c++/detail/process_test
atf_c___detail_process_test_SOURCES = atf-c++/detail/process_test.cpp
atf_c___detail_process_test_LDADD = atf-c++/detail/libtest_helpers.la $(ATF_CXX_LIBS)
tests_atf_c___detail_PROGRAMS += atf-c++/detail/text_test
atf_c___detail_text_test_SOURCES = atf-c++/detail/text_test.cpp
atf_c___detail_text_test_LDADD = atf-c++/detail/libtest_helpers.la $(ATF_CXX_LIBS)
tests_atf_c___detail_PROGRAMS += atf-c++/detail/version_helper
atf_c___detail_version_helper_SOURCES = atf-c++/detail/version_helper.cpp
# vim: syntax=make:noexpandtab:shiftwidth=8:softtabstop=8

View file

@ -1,249 +0,0 @@
// Copyright (c) 2007 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "atf-c++/detail/application.hpp"
#if defined(HAVE_CONFIG_H)
#include "config.h"
#endif
extern "C" {
#include <unistd.h>
}
#include <cstdarg>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
extern "C" {
#include "atf-c/defs.h"
}
#include "atf-c++/detail/sanity.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) :
m_argc(-1),
m_argv(NULL),
m_prog_name(NULL),
m_description(description),
m_manpage(manpage)
{
}
impl::app::~app(void)
{
}
bool
impl::app::inited(void)
{
return m_argc != -1;
}
impl::app::options_set
impl::app::options(void)
{
return specific_options();
}
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 ATF_DEFS_ATTRIBUTE_UNUSED,
const char* arg ATF_DEFS_ATTRIBUTE_UNUSED)
{
}
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;
const int old_opterr = ::opterr;
::opterr = 0;
while ((ch = ::getopt(m_argc, m_argv, optstr.c_str())) != -1) {
switch (ch) {
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;
// Clear getopt state just in case the test wants to use it.
opterr = old_opterr;
optind = 1;
#if defined(HAVE_OPTRESET)
optreset = 1;
#endif
}
int
impl::app::run(int argc, char* const* argv)
{
PRE(argc > 0);
PRE(argv != NULL);
m_argc = argc;
m_argv = argv;
m_argv0 = m_argv[0];
m_prog_name = std::strrchr(m_argv[0], '/');
if (m_prog_name == NULL)
m_prog_name = m_argv[0];
else
m_prog_name++;
// Libtool workaround: if running from within the source tree (binaries
// that are not installed yet), skip the "lt-" prefix added to files in
// the ".libs" directory to show the real (not temporary) name.
if (std::strncmp(m_prog_name, "lt-", 3) == 0)
m_prog_name += 3;
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 {
process_options();
errcode = main();
} catch (const usage_error& e) {
std::cerr << m_prog_name << ": ERROR: " << e.what() << "\n";
std::cerr << m_prog_name << ": See " << m_manpage << " for usage "
"details.\n";
errcode = EXIT_FAILURE;
} catch (const std::runtime_error& e) {
std::cerr << m_prog_name << ": ERROR: " << e.what() << "\n";
errcode = EXIT_FAILURE;
} catch (const std::exception& e) {
std::cerr << m_prog_name << ": ERROR: Caught unexpected error: "
<< e.what() << "\n";
errcode = EXIT_FAILURE;
} catch (...) {
std::cerr << m_prog_name << ": ERROR: Caught unknown error\n";
errcode = EXIT_FAILURE;
}
return errcode;
}

View file

@ -1,107 +0,0 @@
// Copyright (c) 2007 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#if !defined(ATF_CXX_DETAIL_APPLICATION_HPP)
#define ATF_CXX_DETAIL_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 {
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_argv0;
const char* m_prog_name;
std::string m_description;
std::string m_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&);
virtual ~app(void);
int run(int, char* const*);
};
} // namespace application
} // namespace atf
#endif // !defined(ATF_CXX_DETAIL_APPLICATION_HPP)

View file

@ -1,90 +0,0 @@
// Copyright (c) 2009 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "atf-c++/detail/application.hpp"
extern "C" {
#include <unistd.h>
}
#include <atf-c++.hpp>
class getopt_app : public atf::application::app {
public:
getopt_app(void) : app("description", "manpage") {}
int main(void)
{
// Provide an option that is unknown to the application driver and
// one that is, together with an argument that would be swallowed by
// the test program option if it were recognized.
int argc = 4;
char arg1[] = "progname";
char arg2[] = "-Z";
char arg3[] = "-s";
char arg4[] = "foo";
char *const argv[] = { arg1, arg2, arg3, arg4, NULL };
int ch;
bool zflag;
// Given that this obviously is an application, and that we used the
// same driver to start, we can test getopt(3) right here without doing
// any fancy stuff.
zflag = false;
while ((ch = ::getopt(argc, argv, ":Z")) != -1) {
switch (ch) {
case 'Z':
zflag = true;
break;
case '?':
default:
if (optopt != 's')
ATF_FAIL("Unexpected unknown option found");
}
}
ATF_REQUIRE(zflag);
ATF_REQUIRE_EQ(1, argc - optind);
ATF_REQUIRE_EQ(std::string("foo"), argv[optind]);
return 0;
}
};
ATF_TEST_CASE_WITHOUT_HEAD(getopt);
ATF_TEST_CASE_BODY(getopt)
{
int argc = 1;
char arg1[] = "progname";
char *const argv[] = { arg1, NULL };
ATF_REQUIRE_EQ(0, getopt_app().run(argc, argv));
}
ATF_INIT_TEST_CASES(tcs)
{
ATF_ADD_TEST_CASE(tcs, getopt);
}

View file

@ -1,175 +0,0 @@
// Copyright (c) 2007 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#if !defined(ATF_CXX_DETAIL_AUTO_ARRAY_HPP)
#define ATF_CXX_DETAIL_AUTO_ARRAY_HPP
#include <cstddef>
namespace atf {
// ------------------------------------------------------------------------
// The "auto_array" class.
// ------------------------------------------------------------------------
template< class T >
struct auto_array_ref {
T* m_ptr;
explicit auto_array_ref(T*);
};
template< class T >
auto_array_ref< T >::auto_array_ref(T* ptr) :
m_ptr(ptr)
{
}
template< class T >
class auto_array {
T* m_ptr;
public:
auto_array(T* = NULL) throw();
auto_array(auto_array< T >&) throw();
auto_array(auto_array_ref< T >) throw();
~auto_array(void) throw();
T* get(void) throw();
const T* get(void) const throw();
T* release(void) throw();
void reset(T* = NULL) throw();
auto_array< T >& operator=(auto_array< T >&) throw();
auto_array< T >& operator=(auto_array_ref< T >) throw();
T& operator[](int) throw();
operator auto_array_ref< T >(void) 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(auto_array_ref< T > ref)
throw() :
m_ptr(ref.m_ptr)
{
}
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 >
const T*
auto_array< T >::get(void)
const 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 >
auto_array< T >&
auto_array< T >::operator=(auto_array_ref< T > ref)
throw()
{
if (m_ptr != ref.m_ptr) {
delete [] m_ptr;
m_ptr = ref.m_ptr;
}
return *this;
}
template< class T >
T&
auto_array< T >::operator[](int pos)
throw()
{
return m_ptr[pos];
}
template< class T >
auto_array< T >::operator auto_array_ref< T >(void)
throw()
{
return auto_array_ref< T >(release());
}
} // namespace atf
#endif // !defined(ATF_CXX_DETAIL_AUTO_ARRAY_HPP)

View file

@ -1,302 +0,0 @@
// Copyright (c) 2007 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "atf-c++/detail/auto_array.hpp"
extern "C" {
#include <sys/types.h>
}
#include <iostream>
#include <atf-c++.hpp>
extern "C" {
#include "atf-c/defs.h"
}
// ------------------------------------------------------------------------
// Tests for the "auto_array" class.
// ------------------------------------------------------------------------
class test_array {
public:
int m_value;
static ssize_t m_nblocks;
static
atf::auto_array< test_array >
do_copy(atf::auto_array< test_array >& ta)
{
return atf::auto_array< test_array >(ta);
}
void* operator new(size_t size ATF_DEFS_ATTRIBUTE_UNUSED)
{
ATF_FAIL("New called but should have been new[]");
return new int(5);
}
void* operator new[](size_t size)
{
m_nblocks++;
void* mem = ::operator new(size);
std::cout << "Allocated 'test_array' object " << mem << "\n";
return mem;
}
void operator delete(void* mem ATF_DEFS_ATTRIBUTE_UNUSED)
{
ATF_FAIL("Delete called but should have been delete[]");
}
void operator delete[](void* mem)
{
std::cout << "Releasing 'test_array' object " << mem << "\n";
if (m_nblocks == 0)
ATF_FAIL("Unbalanced delete[]");
m_nblocks--;
::operator delete(mem);
}
};
ssize_t test_array::m_nblocks = 0;
ATF_TEST_CASE(auto_array_scope);
ATF_TEST_CASE_HEAD(auto_array_scope)
{
set_md_var("descr", "Tests the automatic scope handling in the "
"auto_array smart pointer class");
}
ATF_TEST_CASE_BODY(auto_array_scope)
{
using atf::auto_array;
ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
{
auto_array< test_array > t(new test_array[10]);
ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
}
ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
}
ATF_TEST_CASE(auto_array_copy);
ATF_TEST_CASE_HEAD(auto_array_copy)
{
set_md_var("descr", "Tests the auto_array smart pointer class' copy "
"constructor");
}
ATF_TEST_CASE_BODY(auto_array_copy)
{
using atf::auto_array;
ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
{
auto_array< test_array > t1(new test_array[10]);
ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
{
auto_array< test_array > t2(t1);
ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
}
ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
}
ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
}
ATF_TEST_CASE(auto_array_copy_ref);
ATF_TEST_CASE_HEAD(auto_array_copy_ref)
{
set_md_var("descr", "Tests the auto_array smart pointer class' copy "
"constructor through the auxiliary auto_array_ref object");
}
ATF_TEST_CASE_BODY(auto_array_copy_ref)
{
using atf::auto_array;
ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
{
auto_array< test_array > t1(new test_array[10]);
ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
{
auto_array< test_array > t2 = test_array::do_copy(t1);
ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
}
ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
}
ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
}
ATF_TEST_CASE(auto_array_get);
ATF_TEST_CASE_HEAD(auto_array_get)
{
set_md_var("descr", "Tests the auto_array smart pointer class' get "
"method");
}
ATF_TEST_CASE_BODY(auto_array_get)
{
using atf::auto_array;
test_array* ta = new test_array[10];
auto_array< test_array > t(ta);
ATF_REQUIRE_EQ(t.get(), ta);
}
ATF_TEST_CASE(auto_array_release);
ATF_TEST_CASE_HEAD(auto_array_release)
{
set_md_var("descr", "Tests the auto_array smart pointer class' release "
"method");
}
ATF_TEST_CASE_BODY(auto_array_release)
{
using atf::auto_array;
test_array* ta1 = new test_array[10];
{
auto_array< test_array > t(ta1);
ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
test_array* ta2 = t.release();
ATF_REQUIRE_EQ(ta2, ta1);
ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
}
ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
delete [] ta1;
}
ATF_TEST_CASE(auto_array_reset);
ATF_TEST_CASE_HEAD(auto_array_reset)
{
set_md_var("descr", "Tests the auto_array smart pointer class' reset "
"method");
}
ATF_TEST_CASE_BODY(auto_array_reset)
{
using atf::auto_array;
test_array* ta1 = new test_array[10];
test_array* ta2 = new test_array[10];
ATF_REQUIRE_EQ(test_array::m_nblocks, 2);
{
auto_array< test_array > t(ta1);
ATF_REQUIRE_EQ(test_array::m_nblocks, 2);
t.reset(ta2);
ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
t.reset();
ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
}
ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
}
ATF_TEST_CASE(auto_array_assign);
ATF_TEST_CASE_HEAD(auto_array_assign)
{
set_md_var("descr", "Tests the auto_array smart pointer class' "
"assignment operator");
}
ATF_TEST_CASE_BODY(auto_array_assign)
{
using atf::auto_array;
ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
{
auto_array< test_array > t1(new test_array[10]);
ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
{
auto_array< test_array > t2;
t2 = t1;
ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
}
ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
}
ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
}
ATF_TEST_CASE(auto_array_assign_ref);
ATF_TEST_CASE_HEAD(auto_array_assign_ref)
{
set_md_var("descr", "Tests the auto_array smart pointer class' "
"assignment operator through the auxiliary auto_array_ref "
"object");
}
ATF_TEST_CASE_BODY(auto_array_assign_ref)
{
using atf::auto_array;
ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
{
auto_array< test_array > t1(new test_array[10]);
ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
{
auto_array< test_array > t2;
t2 = test_array::do_copy(t1);
ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
}
ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
}
ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
}
ATF_TEST_CASE(auto_array_access);
ATF_TEST_CASE_HEAD(auto_array_access)
{
set_md_var("descr", "Tests the auto_array smart pointer class' access "
"operator");
}
ATF_TEST_CASE_BODY(auto_array_access)
{
using atf::auto_array;
auto_array< test_array > t(new test_array[10]);
for (int i = 0; i < 10; i++)
t[i].m_value = i * 2;
for (int i = 0; i < 10; i++)
ATF_REQUIRE_EQ(t[i].m_value, i * 2);
}
// ------------------------------------------------------------------------
// Main.
// ------------------------------------------------------------------------
ATF_INIT_TEST_CASES(tcs)
{
// Add the test for the "auto_array" class.
ATF_ADD_TEST_CASE(tcs, auto_array_scope);
ATF_ADD_TEST_CASE(tcs, auto_array_copy);
ATF_ADD_TEST_CASE(tcs, auto_array_copy_ref);
ATF_ADD_TEST_CASE(tcs, auto_array_get);
ATF_ADD_TEST_CASE(tcs, auto_array_release);
ATF_ADD_TEST_CASE(tcs, auto_array_reset);
ATF_ADD_TEST_CASE(tcs, auto_array_assign);
ATF_ADD_TEST_CASE(tcs, auto_array_assign_ref);
ATF_ADD_TEST_CASE(tcs, auto_array_access);
}

View file

@ -1,75 +0,0 @@
// Copyright (c) 2007 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "atf-c++/detail/env.hpp"
extern "C" {
#include "atf-c/detail/env.h"
#include "atf-c/error.h"
}
#include "atf-c++/detail/exceptions.hpp"
#include "atf-c++/detail/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());
}
std::string
impl::get(const std::string& name, const std::string& default_value)
{
return atf_env_get_with_default(name.c_str(), default_value.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,85 +0,0 @@
// Copyright (c) 2007 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#if !defined(ATF_CXX_DETAIL_ENV_HPP)
#define ATF_CXX_DETAIL_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 Returns the value of an environment variable with a default.
//!
std::string get(const std::string&, 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_DETAIL_ENV_HPP)

View file

@ -1,101 +0,0 @@
// Copyright (c) 2007 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "atf-c++/detail/env.hpp"
#include <atf-c++.hpp>
// ------------------------------------------------------------------------
// Test cases for the free functions.
// ------------------------------------------------------------------------
ATF_TEST_CASE(has_get);
ATF_TEST_CASE_HEAD(has_get)
{
set_md_var("descr", "Tests the has and get functions");
}
ATF_TEST_CASE_BODY(has_get)
{
ATF_REQUIRE(atf::env::has("PATH"));
ATF_REQUIRE(!atf::env::get("PATH").empty());
ATF_REQUIRE(!atf::env::has("_UNDEFINED_VARIABLE_"));
}
ATF_TEST_CASE(get_with_default);
ATF_TEST_CASE_HEAD(get_with_default)
{
set_md_var("descr", "Tests the get function with a default value");
}
ATF_TEST_CASE_BODY(get_with_default)
{
ATF_REQUIRE(atf::env::has("PATH"));
ATF_REQUIRE(atf::env::get("PATH", "default value") != "default value");
ATF_REQUIRE_EQ(atf::env::get("_UNDEFINED_VARIABLE_", "foo bar"), "foo bar");
}
ATF_TEST_CASE(set);
ATF_TEST_CASE_HEAD(set)
{
set_md_var("descr", "Tests the set function");
}
ATF_TEST_CASE_BODY(set)
{
ATF_REQUIRE(atf::env::has("PATH"));
const std::string& oldval = atf::env::get("PATH");
atf::env::set("PATH", "foo-bar");
ATF_REQUIRE(atf::env::get("PATH") != oldval);
ATF_REQUIRE_EQ(atf::env::get("PATH"), "foo-bar");
ATF_REQUIRE(!atf::env::has("_UNDEFINED_VARIABLE_"));
atf::env::set("_UNDEFINED_VARIABLE_", "foo2-bar2");
ATF_REQUIRE_EQ(atf::env::get("_UNDEFINED_VARIABLE_"), "foo2-bar2");
}
ATF_TEST_CASE(unset);
ATF_TEST_CASE_HEAD(unset)
{
set_md_var("descr", "Tests the unset function");
}
ATF_TEST_CASE_BODY(unset)
{
ATF_REQUIRE(atf::env::has("PATH"));
atf::env::unset("PATH");
ATF_REQUIRE(!atf::env::has("PATH"));
}
// ------------------------------------------------------------------------
// Main.
// ------------------------------------------------------------------------
ATF_INIT_TEST_CASES(tcs)
{
// Add the test cases for the free functions.
ATF_ADD_TEST_CASE(tcs, has_get);
ATF_ADD_TEST_CASE(tcs, get_with_default);
ATF_ADD_TEST_CASE(tcs, set);
ATF_ADD_TEST_CASE(tcs, unset);
}

View file

@ -1,154 +0,0 @@
// Copyright (c) 2007 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "atf-c++/detail/exceptions.hpp"
#if defined(HAVE_CONFIG_H)
#include "config.h"
#endif
#include <cstdarg>
#include <cstdio>
#include <cstring>
#include <new>
extern "C" {
#include "atf-c/error.h"
}
#include "atf-c++/detail/sanity.hpp"
// ------------------------------------------------------------------------
// The "system_error" type.
// ------------------------------------------------------------------------
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";
}
}
// ------------------------------------------------------------------------
// Free functions.
// ------------------------------------------------------------------------
static
void
throw_libc_error(atf_error_t err)
{
PRE(atf_error_is(err, "libc"));
const int ecode = atf_libc_error_code(err);
const std::string msg = atf_libc_error_msg(err);
atf_error_free(err);
throw atf::system_error("XXX", msg, ecode);
}
static
void
throw_no_memory_error(atf_error_t err)
{
PRE(atf_error_is(err, "no_memory"));
atf_error_free(err);
throw std::bad_alloc();
}
static
void
throw_unknown_error(atf_error_t err)
{
PRE(atf_is_error(err));
static char buf[4096];
atf_error_format(err, buf, sizeof(buf));
atf_error_free(err);
throw std::runtime_error(buf);
}
void
atf::throw_atf_error(atf_error_t err)
{
static struct handler {
const char* m_name;
void (*m_func)(atf_error_t);
} handlers[] = {
{ "libc", throw_libc_error },
{ "no_memory", throw_no_memory_error },
{ NULL, throw_unknown_error },
};
PRE(atf_is_error(err));
handler* h = handlers;
while (h->m_name != NULL) {
if (atf_error_is(err, h->m_name)) {
h->m_func(err);
UNREACHABLE;
} else
h++;
}
// XXX: I'm not sure that raising an "unknown" error is a wise thing
// to do here. The C++ binding is supposed to have feature parity
// with the C one, so all possible errors raised by the C library
// should have their counterpart in the C++ library. Still, removing
// this will require some code auditing that I can't afford at the
// moment.
INV(h->m_name == NULL && h->m_func != NULL);
h->m_func(err);
UNREACHABLE;
}

View file

@ -1,54 +0,0 @@
// Copyright (c) 2007 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#if !defined(ATF_CXX_DETAIL_EXCEPTIONS_HPP)
#define ATF_CXX_DETAIL_EXCEPTIONS_HPP
#include <stdexcept>
#include <string>
extern "C" {
struct atf_error;
}
namespace atf {
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_DETAIL_EXCEPTIONS_HPP)

View file

@ -1,145 +0,0 @@
// Copyright (c) 2009 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "atf-c++/detail/exceptions.hpp"
extern "C" {
#include "atf-c/error.h"
}
#include <cstdio>
#include <new>
#include <atf-c++.hpp>
#include "atf-c++/detail/sanity.hpp"
// ------------------------------------------------------------------------
// The "test" error.
// ------------------------------------------------------------------------
extern "C" {
struct test_error_data {
const char* m_msg;
};
typedef struct test_error_data test_error_data_t;
static
void
test_format(const atf_error_t err, char *buf, size_t buflen)
{
const test_error_data_t* data;
PRE(atf_error_is(err, "test"));
data = static_cast< const test_error_data_t * >(atf_error_data(err));
snprintf(buf, buflen, "Message: %s", data->m_msg);
}
static
atf_error_t
test_error(const char* msg)
{
atf_error_t err;
test_error_data_t data;
data.m_msg = msg;
err = atf_error_new("test", &data, sizeof(data), test_format);
return err;
}
} // extern
// ------------------------------------------------------------------------
// Tests cases for the free functions.
// ------------------------------------------------------------------------
ATF_TEST_CASE(throw_atf_error_libc);
ATF_TEST_CASE_HEAD(throw_atf_error_libc)
{
set_md_var("descr", "Tests the throw_atf_error function when raising "
"a libc error");
}
ATF_TEST_CASE_BODY(throw_atf_error_libc)
{
try {
atf::throw_atf_error(atf_libc_error(1, "System error 1"));
} catch (const atf::system_error& e) {
ATF_REQUIRE(e.code() == 1);
ATF_REQUIRE(std::string(e.what()).find("System error 1") !=
std::string::npos);
} catch (const std::exception& e) {
ATF_FAIL(std::string("Got unexpected exception: ") + e.what());
}
}
ATF_TEST_CASE(throw_atf_error_no_memory);
ATF_TEST_CASE_HEAD(throw_atf_error_no_memory)
{
set_md_var("descr", "Tests the throw_atf_error function when raising "
"a no_memory error");
}
ATF_TEST_CASE_BODY(throw_atf_error_no_memory)
{
try {
atf::throw_atf_error(atf_no_memory_error());
} catch (const std::bad_alloc&) {
} catch (const std::exception& e) {
ATF_FAIL(std::string("Got unexpected exception: ") + e.what());
}
}
ATF_TEST_CASE(throw_atf_error_unknown);
ATF_TEST_CASE_HEAD(throw_atf_error_unknown)
{
set_md_var("descr", "Tests the throw_atf_error function when raising "
"an unknown error");
}
ATF_TEST_CASE_BODY(throw_atf_error_unknown)
{
try {
atf::throw_atf_error(test_error("The message"));
} catch (const std::runtime_error& e) {
const std::string msg = e.what();
ATF_REQUIRE(msg.find("The message") != std::string::npos);
} catch (const std::exception& e) {
ATF_FAIL(std::string("Got unexpected exception: ") + e.what());
}
}
// ------------------------------------------------------------------------
// Main.
// ------------------------------------------------------------------------
ATF_INIT_TEST_CASES(tcs)
{
// Add the test cases for the free functions.
ATF_ADD_TEST_CASE(tcs, throw_atf_error_libc);
ATF_ADD_TEST_CASE(tcs, throw_atf_error_no_memory);
ATF_ADD_TEST_CASE(tcs, throw_atf_error_unknown);
}

View file

@ -1,513 +0,0 @@
// Copyright (c) 2007 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "atf-c++/detail/fs.hpp"
#if defined(HAVE_CONFIG_H)
#include "config.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>
extern "C" {
#include "atf-c/error.h"
}
#include "atf-c++/detail/env.hpp"
#include "atf-c++/detail/exceptions.hpp"
#include "atf-c++/detail/process.hpp"
#include "atf-c++/detail/sanity.hpp"
#include "atf-c++/detail/text.hpp"
#include "atf-c++/utils.hpp"
namespace impl = atf::fs;
#define IMPL_NAME "atf::fs"
// ------------------------------------------------------------------------
// Auxiliary functions.
// ------------------------------------------------------------------------
static bool safe_access(const impl::path&, int, int);
//!
//! \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) {
atf_error_free(err);
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(const atf_fs_path_t *p)
{
atf_error_t err = atf_fs_path_copy(&m_path, p);
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);
}
mode_t
impl::file_info::get_mode(void)
const
{
return atf_fs_stat_get_mode(&m_stat);
}
off_t
impl::file_info::get_size(void)
const
{
return atf_fs_stat_get_size(&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;
}
// ------------------------------------------------------------------------
// Free functions.
// ------------------------------------------------------------------------
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;
}
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::rmdir(const path& p)
{
atf_error_t err = atf_fs_rmdir(p.c_path());
if (atf_is_error(err))
throw_atf_error(err);
}

View file

@ -1,387 +0,0 @@
// Copyright (c) 2007 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#if !defined(ATF_CXX_DETAIL_FS_HPP)
#define ATF_CXX_DETAIL_FS_HPP
extern "C" {
#include <sys/types.h>
}
#include <map>
#include <memory>
#include <ostream>
#include <set>
#include <stdexcept>
#include <string>
extern "C" {
#include "atf-c/detail/fs.h"
}
namespace atf {
namespace io {
class systembuf;
} // namespace io
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 Copy constructor.
//!
path(const atf_fs_path_t *);
//!
//! \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 permissions.
//!
mode_t get_mode(void) const;
//!
//! \brief Returns the file's size.
//!
off_t get_size(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;
};
// ------------------------------------------------------------------------
// Free functions.
// ------------------------------------------------------------------------
//!
//! \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 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 Removes an empty directory.
//!
void rmdir(const path&);
} // namespace fs
} // namespace atf
#endif // !defined(ATF_CXX_DETAIL_FS_HPP)

View file

@ -1,542 +0,0 @@
// Copyright (c) 2007 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "atf-c++/detail/fs.hpp"
extern "C" {
#include <sys/types.h>
#include <sys/stat.h>
}
#include <fstream>
#include <cerrno>
#include <cstdio>
#include <atf-c++.hpp>
#include "atf-c++/detail/exceptions.hpp"
// ------------------------------------------------------------------------
// Auxiliary functions.
// ------------------------------------------------------------------------
static
void
create_files(void)
{
::mkdir("files", 0755);
::mkdir("files/dir", 0755);
std::ofstream os("files/reg");
os.close();
// TODO: Should create all other file types (blk, chr, fifo, lnk, sock)
// and test for them... but the underlying file system may not support
// most of these. Specially as we are working on /tmp, which can be
// mounted with flags such as "nodev". See how to deal with this
// situation.
}
// ------------------------------------------------------------------------
// Test cases for the "path" class.
// ------------------------------------------------------------------------
ATF_TEST_CASE(path_normalize);
ATF_TEST_CASE_HEAD(path_normalize)
{
set_md_var("descr", "Tests the path's normalization");
}
ATF_TEST_CASE_BODY(path_normalize)
{
using atf::fs::path;
ATF_REQUIRE_EQ(path(".").str(), ".");
ATF_REQUIRE_EQ(path("..").str(), "..");
ATF_REQUIRE_EQ(path("foo").str(), "foo");
ATF_REQUIRE_EQ(path("foo/bar").str(), "foo/bar");
ATF_REQUIRE_EQ(path("foo/bar/").str(), "foo/bar");
ATF_REQUIRE_EQ(path("/foo").str(), "/foo");
ATF_REQUIRE_EQ(path("/foo/bar").str(), "/foo/bar");
ATF_REQUIRE_EQ(path("/foo/bar/").str(), "/foo/bar");
ATF_REQUIRE_EQ(path("///foo").str(), "/foo");
ATF_REQUIRE_EQ(path("///foo///bar").str(), "/foo/bar");
ATF_REQUIRE_EQ(path("///foo///bar///").str(), "/foo/bar");
}
ATF_TEST_CASE(path_is_absolute);
ATF_TEST_CASE_HEAD(path_is_absolute)
{
set_md_var("descr", "Tests the path::is_absolute function");
}
ATF_TEST_CASE_BODY(path_is_absolute)
{
using atf::fs::path;
ATF_REQUIRE( path("/").is_absolute());
ATF_REQUIRE( path("////").is_absolute());
ATF_REQUIRE( path("////a").is_absolute());
ATF_REQUIRE( path("//a//").is_absolute());
ATF_REQUIRE(!path("a////").is_absolute());
ATF_REQUIRE(!path("../foo").is_absolute());
}
ATF_TEST_CASE(path_is_root);
ATF_TEST_CASE_HEAD(path_is_root)
{
set_md_var("descr", "Tests the path::is_root function");
}
ATF_TEST_CASE_BODY(path_is_root)
{
using atf::fs::path;
ATF_REQUIRE( path("/").is_root());
ATF_REQUIRE( path("////").is_root());
ATF_REQUIRE(!path("////a").is_root());
ATF_REQUIRE(!path("//a//").is_root());
ATF_REQUIRE(!path("a////").is_root());
ATF_REQUIRE(!path("../foo").is_root());
}
ATF_TEST_CASE(path_branch_path);
ATF_TEST_CASE_HEAD(path_branch_path)
{
set_md_var("descr", "Tests the path::branch_path function");
}
ATF_TEST_CASE_BODY(path_branch_path)
{
using atf::fs::path;
ATF_REQUIRE_EQ(path(".").branch_path().str(), ".");
ATF_REQUIRE_EQ(path("foo").branch_path().str(), ".");
ATF_REQUIRE_EQ(path("foo/bar").branch_path().str(), "foo");
ATF_REQUIRE_EQ(path("/foo").branch_path().str(), "/");
ATF_REQUIRE_EQ(path("/foo/bar").branch_path().str(), "/foo");
}
ATF_TEST_CASE(path_leaf_name);
ATF_TEST_CASE_HEAD(path_leaf_name)
{
set_md_var("descr", "Tests the path::leaf_name function");
}
ATF_TEST_CASE_BODY(path_leaf_name)
{
using atf::fs::path;
ATF_REQUIRE_EQ(path(".").leaf_name(), ".");
ATF_REQUIRE_EQ(path("foo").leaf_name(), "foo");
ATF_REQUIRE_EQ(path("foo/bar").leaf_name(), "bar");
ATF_REQUIRE_EQ(path("/foo").leaf_name(), "foo");
ATF_REQUIRE_EQ(path("/foo/bar").leaf_name(), "bar");
}
ATF_TEST_CASE(path_compare_equal);
ATF_TEST_CASE_HEAD(path_compare_equal)
{
set_md_var("descr", "Tests the comparison for equality between paths");
}
ATF_TEST_CASE_BODY(path_compare_equal)
{
using atf::fs::path;
ATF_REQUIRE(path("/") == path("///"));
ATF_REQUIRE(path("/a") == path("///a"));
ATF_REQUIRE(path("/a") == path("///a///"));
ATF_REQUIRE(path("a/b/c") == path("a//b//c"));
ATF_REQUIRE(path("a/b/c") == path("a//b//c///"));
}
ATF_TEST_CASE(path_compare_different);
ATF_TEST_CASE_HEAD(path_compare_different)
{
set_md_var("descr", "Tests the comparison for difference between paths");
}
ATF_TEST_CASE_BODY(path_compare_different)
{
using atf::fs::path;
ATF_REQUIRE(path("/") != path("//a/"));
ATF_REQUIRE(path("/a") != path("a///"));
ATF_REQUIRE(path("a/b/c") != path("a/b"));
ATF_REQUIRE(path("a/b/c") != path("a//b"));
ATF_REQUIRE(path("a/b/c") != path("/a/b/c"));
ATF_REQUIRE(path("a/b/c") != path("/a//b//c"));
}
ATF_TEST_CASE(path_concat);
ATF_TEST_CASE_HEAD(path_concat)
{
set_md_var("descr", "Tests the concatenation of multiple paths");
}
ATF_TEST_CASE_BODY(path_concat)
{
using atf::fs::path;
ATF_REQUIRE_EQ((path("foo") / "bar").str(), "foo/bar");
ATF_REQUIRE_EQ((path("foo/") / "/bar").str(), "foo/bar");
ATF_REQUIRE_EQ((path("foo/") / "/bar/baz").str(), "foo/bar/baz");
ATF_REQUIRE_EQ((path("foo/") / "///bar///baz").str(), "foo/bar/baz");
}
ATF_TEST_CASE(path_to_absolute);
ATF_TEST_CASE_HEAD(path_to_absolute)
{
set_md_var("descr", "Tests the conversion of a relative path to an "
"absolute one");
}
ATF_TEST_CASE_BODY(path_to_absolute)
{
using atf::fs::file_info;
using atf::fs::path;
create_files();
{
const path p(".");
path pa = p.to_absolute();
ATF_REQUIRE(pa.is_absolute());
file_info fi(p);
file_info fia(pa);
ATF_REQUIRE_EQ(fi.get_device(), fia.get_device());
ATF_REQUIRE_EQ(fi.get_inode(), fia.get_inode());
}
{
const path p("files/reg");
path pa = p.to_absolute();
ATF_REQUIRE(pa.is_absolute());
file_info fi(p);
file_info fia(pa);
ATF_REQUIRE_EQ(fi.get_device(), fia.get_device());
ATF_REQUIRE_EQ(fi.get_inode(), fia.get_inode());
}
}
ATF_TEST_CASE(path_op_less);
ATF_TEST_CASE_HEAD(path_op_less)
{
set_md_var("descr", "Tests that the path's less-than operator works");
}
ATF_TEST_CASE_BODY(path_op_less)
{
using atf::fs::path;
create_files();
ATF_REQUIRE(!(path("aaa") < path("aaa")));
ATF_REQUIRE( path("aab") < path("abc"));
ATF_REQUIRE(!(path("abc") < path("aab")));
}
// ------------------------------------------------------------------------
// Test cases for the "directory" class.
// ------------------------------------------------------------------------
ATF_TEST_CASE(directory_read);
ATF_TEST_CASE_HEAD(directory_read)
{
set_md_var("descr", "Tests the directory class creation, which reads "
"the contents of a directory");
}
ATF_TEST_CASE_BODY(directory_read)
{
using atf::fs::directory;
using atf::fs::path;
create_files();
directory d(path("files"));
ATF_REQUIRE_EQ(d.size(), 4);
ATF_REQUIRE(d.find(".") != d.end());
ATF_REQUIRE(d.find("..") != d.end());
ATF_REQUIRE(d.find("dir") != d.end());
ATF_REQUIRE(d.find("reg") != d.end());
}
ATF_TEST_CASE(directory_file_info);
ATF_TEST_CASE_HEAD(directory_file_info)
{
set_md_var("descr", "Tests that the file_info objects attached to the "
"directory are valid");
}
ATF_TEST_CASE_BODY(directory_file_info)
{
using atf::fs::directory;
using atf::fs::file_info;
using atf::fs::path;
create_files();
directory d(path("files"));
{
directory::const_iterator iter = d.find("dir");
ATF_REQUIRE(iter != d.end());
const file_info& fi = (*iter).second;
ATF_REQUIRE(fi.get_type() == file_info::dir_type);
}
{
directory::const_iterator iter = d.find("reg");
ATF_REQUIRE(iter != d.end());
const file_info& fi = (*iter).second;
ATF_REQUIRE(fi.get_type() == file_info::reg_type);
}
}
ATF_TEST_CASE(directory_names);
ATF_TEST_CASE_HEAD(directory_names)
{
set_md_var("descr", "Tests the directory's names method");
}
ATF_TEST_CASE_BODY(directory_names)
{
using atf::fs::directory;
using atf::fs::path;
create_files();
directory d(path("files"));
std::set< std::string > ns = d.names();
ATF_REQUIRE_EQ(ns.size(), 4);
ATF_REQUIRE(ns.find(".") != ns.end());
ATF_REQUIRE(ns.find("..") != ns.end());
ATF_REQUIRE(ns.find("dir") != ns.end());
ATF_REQUIRE(ns.find("reg") != ns.end());
}
// ------------------------------------------------------------------------
// Test cases for the "file_info" class.
// ------------------------------------------------------------------------
ATF_TEST_CASE(file_info_stat);
ATF_TEST_CASE_HEAD(file_info_stat)
{
set_md_var("descr", "Tests the file_info creation and its basic contents");
}
ATF_TEST_CASE_BODY(file_info_stat)
{
using atf::fs::file_info;
using atf::fs::path;
create_files();
{
path p("files/dir");
file_info fi(p);
ATF_REQUIRE(fi.get_type() == file_info::dir_type);
}
{
path p("files/reg");
file_info fi(p);
ATF_REQUIRE(fi.get_type() == file_info::reg_type);
}
}
ATF_TEST_CASE(file_info_perms);
ATF_TEST_CASE_HEAD(file_info_perms)
{
set_md_var("descr", "Tests the file_info methods to get the file's "
"permissions");
}
ATF_TEST_CASE_BODY(file_info_perms)
{
using atf::fs::file_info;
using atf::fs::path;
path p("file");
std::ofstream os(p.c_str());
os.close();
#define perms(ur, uw, ux, gr, gw, gx, othr, othw, othx) \
{ \
file_info fi(p); \
ATF_REQUIRE(fi.is_owner_readable() == ur); \
ATF_REQUIRE(fi.is_owner_writable() == uw); \
ATF_REQUIRE(fi.is_owner_executable() == ux); \
ATF_REQUIRE(fi.is_group_readable() == gr); \
ATF_REQUIRE(fi.is_group_writable() == gw); \
ATF_REQUIRE(fi.is_group_executable() == gx); \
ATF_REQUIRE(fi.is_other_readable() == othr); \
ATF_REQUIRE(fi.is_other_writable() == othw); \
ATF_REQUIRE(fi.is_other_executable() == othx); \
}
::chmod(p.c_str(), 0000);
perms(false, false, false, false, false, false, false, false, false);
::chmod(p.c_str(), 0001);
perms(false, false, false, false, false, false, false, false, true);
::chmod(p.c_str(), 0010);
perms(false, false, false, false, false, true, false, false, false);
::chmod(p.c_str(), 0100);
perms(false, false, true, false, false, false, false, false, false);
::chmod(p.c_str(), 0002);
perms(false, false, false, false, false, false, false, true, false);
::chmod(p.c_str(), 0020);
perms(false, false, false, false, true, false, false, false, false);
::chmod(p.c_str(), 0200);
perms(false, true, false, false, false, false, false, false, false);
::chmod(p.c_str(), 0004);
perms(false, false, false, false, false, false, true, false, false);
::chmod(p.c_str(), 0040);
perms(false, false, false, true, false, false, false, false, false);
::chmod(p.c_str(), 0400);
perms(true, false, false, false, false, false, false, false, false);
::chmod(p.c_str(), 0644);
perms(true, true, false, true, false, false, true, false, false);
::chmod(p.c_str(), 0755);
perms(true, true, true, true, false, true, true, false, true);
::chmod(p.c_str(), 0777);
perms(true, true, true, true, true, true, true, true, true);
#undef perms
}
// ------------------------------------------------------------------------
// Test cases for the free functions.
// ------------------------------------------------------------------------
ATF_TEST_CASE(exists);
ATF_TEST_CASE_HEAD(exists)
{
set_md_var("descr", "Tests the exists function");
}
ATF_TEST_CASE_BODY(exists)
{
using atf::fs::exists;
using atf::fs::path;
create_files();
ATF_REQUIRE( exists(path("files")));
ATF_REQUIRE(!exists(path("file")));
ATF_REQUIRE(!exists(path("files2")));
ATF_REQUIRE( exists(path("files/.")));
ATF_REQUIRE( exists(path("files/..")));
ATF_REQUIRE( exists(path("files/dir")));
ATF_REQUIRE( exists(path("files/reg")));
ATF_REQUIRE(!exists(path("files/foo")));
}
ATF_TEST_CASE(is_executable);
ATF_TEST_CASE_HEAD(is_executable)
{
set_md_var("descr", "Tests the is_executable function");
}
ATF_TEST_CASE_BODY(is_executable)
{
using atf::fs::is_executable;
using atf::fs::path;
create_files();
ATF_REQUIRE( is_executable(path("files")));
ATF_REQUIRE( is_executable(path("files/.")));
ATF_REQUIRE( is_executable(path("files/..")));
ATF_REQUIRE( is_executable(path("files/dir")));
ATF_REQUIRE(!is_executable(path("non-existent")));
ATF_REQUIRE(!is_executable(path("files/reg")));
ATF_REQUIRE(::chmod("files/reg", 0755) != -1);
ATF_REQUIRE( is_executable(path("files/reg")));
}
ATF_TEST_CASE(remove);
ATF_TEST_CASE_HEAD(remove)
{
set_md_var("descr", "Tests the remove function");
}
ATF_TEST_CASE_BODY(remove)
{
using atf::fs::exists;
using atf::fs::path;
using atf::fs::remove;
create_files();
ATF_REQUIRE( exists(path("files/reg")));
remove(path("files/reg"));
ATF_REQUIRE(!exists(path("files/reg")));
ATF_REQUIRE( exists(path("files/dir")));
ATF_REQUIRE_THROW(atf::system_error, remove(path("files/dir")));
ATF_REQUIRE( exists(path("files/dir")));
}
// ------------------------------------------------------------------------
// Main.
// ------------------------------------------------------------------------
ATF_INIT_TEST_CASES(tcs)
{
// Add the tests for the "path" class.
ATF_ADD_TEST_CASE(tcs, path_normalize);
ATF_ADD_TEST_CASE(tcs, path_is_absolute);
ATF_ADD_TEST_CASE(tcs, path_is_root);
ATF_ADD_TEST_CASE(tcs, path_branch_path);
ATF_ADD_TEST_CASE(tcs, path_leaf_name);
ATF_ADD_TEST_CASE(tcs, path_compare_equal);
ATF_ADD_TEST_CASE(tcs, path_compare_different);
ATF_ADD_TEST_CASE(tcs, path_concat);
ATF_ADD_TEST_CASE(tcs, path_to_absolute);
ATF_ADD_TEST_CASE(tcs, path_op_less);
// Add the tests for the "file_info" class.
ATF_ADD_TEST_CASE(tcs, file_info_stat);
ATF_ADD_TEST_CASE(tcs, file_info_perms);
// Add the tests for the "directory" class.
ATF_ADD_TEST_CASE(tcs, directory_read);
ATF_ADD_TEST_CASE(tcs, directory_names);
ATF_ADD_TEST_CASE(tcs, directory_file_info);
// Add the tests for the free functions.
ATF_ADD_TEST_CASE(tcs, exists);
ATF_ADD_TEST_CASE(tcs, is_executable);
ATF_ADD_TEST_CASE(tcs, remove);
}

View file

@ -1,346 +0,0 @@
// 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 "atf-c++/detail/process.hpp"
extern "C" {
#include <signal.h>
#include "atf-c/detail/process.h"
#include "atf-c/error.h"
}
#include <iostream>
#include "atf-c++/detail/exceptions.hpp"
#include "atf-c++/detail/sanity.hpp"
namespace detail = atf::process::detail;
namespace impl = atf::process;
#define IMPL_NAME "atf::process"
// ------------------------------------------------------------------------
// Auxiliary functions.
// ------------------------------------------------------------------------
template< class C >
atf::auto_array< const char* >
collection_to_argv(const C& c)
{
atf::auto_array< const char* > argv(new const char*[c.size() + 1]);
std::size_t pos = 0;
for (typename C::const_iterator iter = c.begin(); iter != c.end();
iter++) {
argv[pos] = (*iter).c_str();
pos++;
}
INV(pos == c.size());
argv[pos] = NULL;
return argv;
}
template< class C >
C
argv_to_collection(const char* const* argv)
{
C c;
for (const char* const* iter = argv; *iter != NULL; iter++)
c.push_back(std::string(*iter));
return c;
}
// ------------------------------------------------------------------------
// The "argv_array" type.
// ------------------------------------------------------------------------
impl::argv_array::argv_array(void) :
m_exec_argv(collection_to_argv(m_args))
{
}
impl::argv_array::argv_array(const char* arg1, ...)
{
m_args.push_back(arg1);
{
va_list ap;
const char* nextarg;
va_start(ap, arg1);
while ((nextarg = va_arg(ap, const char*)) != NULL)
m_args.push_back(nextarg);
va_end(ap);
}
ctor_init_exec_argv();
}
impl::argv_array::argv_array(const char* const* ca) :
m_args(argv_to_collection< args_vector >(ca)),
m_exec_argv(collection_to_argv(m_args))
{
}
impl::argv_array::argv_array(const argv_array& a) :
m_args(a.m_args),
m_exec_argv(collection_to_argv(m_args))
{
}
void
impl::argv_array::ctor_init_exec_argv(void)
{
m_exec_argv = collection_to_argv(m_args);
}
const char* const*
impl::argv_array::exec_argv(void)
const
{
return m_exec_argv.get();
}
impl::argv_array::size_type
impl::argv_array::size(void)
const
{
return m_args.size();
}
const char*
impl::argv_array::operator[](int idx)
const
{
return m_args[idx].c_str();
}
impl::argv_array::const_iterator
impl::argv_array::begin(void)
const
{
return m_args.begin();
}
impl::argv_array::const_iterator
impl::argv_array::end(void)
const
{
return m_args.end();
}
impl::argv_array&
impl::argv_array::operator=(const argv_array& a)
{
if (this != &a) {
m_args = a.m_args;
m_exec_argv = collection_to_argv(m_args);
}
return *this;
}
// ------------------------------------------------------------------------
// The "stream" types.
// ------------------------------------------------------------------------
impl::basic_stream::basic_stream(void) :
m_inited(false)
{
}
impl::basic_stream::~basic_stream(void)
{
if (m_inited)
atf_process_stream_fini(&m_sb);
}
const atf_process_stream_t*
impl::basic_stream::get_sb(void)
const
{
INV(m_inited);
return &m_sb;
}
impl::stream_capture::stream_capture(void)
{
atf_error_t err = atf_process_stream_init_capture(&m_sb);
if (atf_is_error(err))
throw_atf_error(err);
m_inited = true;
}
impl::stream_connect::stream_connect(const int src_fd, const int tgt_fd)
{
atf_error_t err = atf_process_stream_init_connect(&m_sb, src_fd, tgt_fd);
if (atf_is_error(err))
throw_atf_error(err);
m_inited = true;
}
impl::stream_inherit::stream_inherit(void)
{
atf_error_t err = atf_process_stream_init_inherit(&m_sb);
if (atf_is_error(err))
throw_atf_error(err);
m_inited = true;
}
impl::stream_redirect_fd::stream_redirect_fd(const int fd)
{
atf_error_t err = atf_process_stream_init_redirect_fd(&m_sb, fd);
if (atf_is_error(err))
throw_atf_error(err);
m_inited = true;
}
impl::stream_redirect_path::stream_redirect_path(const fs::path& p)
{
atf_error_t err = atf_process_stream_init_redirect_path(&m_sb, p.c_path());
if (atf_is_error(err))
throw_atf_error(err);
m_inited = true;
}
// ------------------------------------------------------------------------
// The "status" type.
// ------------------------------------------------------------------------
impl::status::status(atf_process_status_t& s) :
m_status(s)
{
}
impl::status::~status(void)
{
atf_process_status_fini(&m_status);
}
bool
impl::status::exited(void)
const
{
return atf_process_status_exited(&m_status);
}
int
impl::status::exitstatus(void)
const
{
return atf_process_status_exitstatus(&m_status);
}
bool
impl::status::signaled(void)
const
{
return atf_process_status_signaled(&m_status);
}
int
impl::status::termsig(void)
const
{
return atf_process_status_termsig(&m_status);
}
bool
impl::status::coredump(void)
const
{
return atf_process_status_coredump(&m_status);
}
// ------------------------------------------------------------------------
// The "child" type.
// ------------------------------------------------------------------------
impl::child::child(atf_process_child_t& c) :
m_child(c),
m_waited(false)
{
}
impl::child::~child(void)
{
if (!m_waited) {
::kill(atf_process_child_pid(&m_child), SIGTERM);
atf_process_status_t s;
atf_error_t err = atf_process_child_wait(&m_child, &s);
INV(!atf_is_error(err));
atf_process_status_fini(&s);
}
}
impl::status
impl::child::wait(void)
{
atf_process_status_t s;
atf_error_t err = atf_process_child_wait(&m_child, &s);
if (atf_is_error(err))
throw_atf_error(err);
m_waited = true;
return status(s);
}
pid_t
impl::child::pid(void)
const
{
return atf_process_child_pid(&m_child);
}
int
impl::child::stdout_fd(void)
{
return atf_process_child_stdout(&m_child);
}
int
impl::child::stderr_fd(void)
{
return atf_process_child_stderr(&m_child);
}
// ------------------------------------------------------------------------
// Free functions.
// ------------------------------------------------------------------------
void
detail::flush_streams(void)
{
// TODO: This should only be executed when inheriting the stdout or
// stderr file descriptors. However, the flushing is specific to the
// iostreams, so we cannot do it from the C library where all the process
// logic is performed. Come up with a better design.
std::cout.flush();
std::cerr.flush();
}

View file

@ -1,274 +0,0 @@
// 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_CXX_DETAIL_PROCESS_HPP)
#define ATF_CXX_DETAIL_PROCESS_HPP
extern "C" {
#include <sys/types.h>
#include <atf-c/detail/process.h>
#include <atf-c/error.h>
}
#include <string>
#include <vector>
#include <atf-c++/detail/auto_array.hpp>
#include <atf-c++/detail/exceptions.hpp>
#include <atf-c++/detail/fs.hpp>
namespace atf {
namespace process {
class child;
class status;
// ------------------------------------------------------------------------
// The "argv_array" type.
// ------------------------------------------------------------------------
class argv_array {
typedef std::vector< std::string > args_vector;
args_vector m_args;
// TODO: This is immutable, so we should be able to use
// std::tr1::shared_array instead when it becomes widely available.
// The reason would be to remove all copy constructors and assignment
// operators from this class.
auto_array< const char* > m_exec_argv;
void ctor_init_exec_argv(void);
public:
typedef args_vector::const_iterator const_iterator;
typedef args_vector::size_type size_type;
argv_array(void);
argv_array(const char*, ...);
explicit argv_array(const char* const*);
template< class C > explicit argv_array(const C&);
argv_array(const argv_array&);
const char* const* exec_argv(void) const;
size_type size(void) const;
const char* operator[](int) const;
const_iterator begin(void) const;
const_iterator end(void) const;
argv_array& operator=(const argv_array&);
};
template< class C >
argv_array::argv_array(const C& c)
{
for (typename C::const_iterator iter = c.begin(); iter != c.end();
iter++)
m_args.push_back(*iter);
ctor_init_exec_argv();
}
// ------------------------------------------------------------------------
// The "stream" types.
// ------------------------------------------------------------------------
class basic_stream {
protected:
atf_process_stream_t m_sb;
bool m_inited;
const atf_process_stream_t* get_sb(void) const;
public:
basic_stream(void);
~basic_stream(void);
};
class stream_capture : basic_stream {
// Allow access to the getters.
template< class OutStream, class ErrStream > friend
child fork(void (*)(void*), const OutStream&, const ErrStream&, void*);
template< class OutStream, class ErrStream > friend
status exec(const atf::fs::path&, const argv_array&,
const OutStream&, const ErrStream&, void (*)(void));
public:
stream_capture(void);
};
class stream_connect : basic_stream {
// Allow access to the getters.
template< class OutStream, class ErrStream > friend
child fork(void (*)(void*), const OutStream&, const ErrStream&, void*);
template< class OutStream, class ErrStream > friend
status exec(const atf::fs::path&, const argv_array&,
const OutStream&, const ErrStream&, void (*)(void));
public:
stream_connect(const int, const int);
};
class stream_inherit : basic_stream {
// Allow access to the getters.
template< class OutStream, class ErrStream > friend
child fork(void (*)(void*), const OutStream&, const ErrStream&, void*);
template< class OutStream, class ErrStream > friend
status exec(const atf::fs::path&, const argv_array&,
const OutStream&, const ErrStream&, void (*)(void));
public:
stream_inherit(void);
};
class stream_redirect_fd : basic_stream {
// Allow access to the getters.
template< class OutStream, class ErrStream > friend
child fork(void (*)(void*), const OutStream&, const ErrStream&, void*);
template< class OutStream, class ErrStream > friend
status exec(const atf::fs::path&, const argv_array&,
const OutStream&, const ErrStream&, void (*)(void));
public:
stream_redirect_fd(const int);
};
class stream_redirect_path : basic_stream {
// Allow access to the getters.
template< class OutStream, class ErrStream > friend
child fork(void (*)(void*), const OutStream&, const ErrStream&, void*);
template< class OutStream, class ErrStream > friend
status exec(const atf::fs::path&, const argv_array&,
const OutStream&, const ErrStream&, void (*)(void));
public:
stream_redirect_path(const fs::path&);
};
// ------------------------------------------------------------------------
// The "status" type.
// ------------------------------------------------------------------------
class status {
atf_process_status_t m_status;
friend class child;
template< class OutStream, class ErrStream > friend
status exec(const atf::fs::path&, const argv_array&,
const OutStream&, const ErrStream&, void (*)(void));
status(atf_process_status_t&);
public:
~status(void);
bool exited(void) const;
int exitstatus(void) const;
bool signaled(void) const;
int termsig(void) const;
bool coredump(void) const;
};
// ------------------------------------------------------------------------
// The "child" type.
// ------------------------------------------------------------------------
class child {
atf_process_child_t m_child;
bool m_waited;
template< class OutStream, class ErrStream > friend
child fork(void (*)(void*), const OutStream&, const ErrStream&, void*);
child(atf_process_child_t& c);
public:
~child(void);
status wait(void);
pid_t pid(void) const;
int stdout_fd(void);
int stderr_fd(void);
};
// ------------------------------------------------------------------------
// Free functions.
// ------------------------------------------------------------------------
namespace detail {
void flush_streams(void);
} // namespace detail
// TODO: The void* cookie can probably be templatized, thus also allowing
// const data structures.
template< class OutStream, class ErrStream >
child
fork(void (*start)(void*), const OutStream& outsb,
const ErrStream& errsb, void* v)
{
atf_process_child_t c;
detail::flush_streams();
atf_error_t err = atf_process_fork(&c, start, outsb.get_sb(),
errsb.get_sb(), v);
if (atf_is_error(err))
throw_atf_error(err);
return child(c);
}
template< class OutStream, class ErrStream >
status
exec(const atf::fs::path& prog, const argv_array& argv,
const OutStream& outsb, const ErrStream& errsb,
void (*prehook)(void))
{
atf_process_status_t s;
detail::flush_streams();
atf_error_t err = atf_process_exec_array(&s, prog.c_path(),
argv.exec_argv(),
outsb.get_sb(),
errsb.get_sb(),
prehook);
if (atf_is_error(err))
throw_atf_error(err);
return status(s);
}
template< class OutStream, class ErrStream >
status
exec(const atf::fs::path& prog, const argv_array& argv,
const OutStream& outsb, const ErrStream& errsb)
{
return exec(prog, argv, outsb, errsb, NULL);
}
} // namespace process
} // namespace atf
#endif // !defined(ATF_CXX_DETAIL_PROCESS_HPP)

View file

@ -1,354 +0,0 @@
// 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 "atf-c++/detail/process.hpp"
#include <cstdlib>
#include <cstring>
#include <atf-c++.hpp>
#include "atf-c++/detail/test_helpers.hpp"
// TODO: Testing the fork function is a huge task and I'm afraid of
// copy/pasting tons of stuff from the C version. I'd rather not do that
// until some code can be shared, which cannot happen until the C++ binding
// is cleaned by a fair amount. Instead... just rely (at the moment) on
// the system tests for the tools using this module.
// ------------------------------------------------------------------------
// Auxiliary functions.
// ------------------------------------------------------------------------
static
std::size_t
array_size(const char* const* array)
{
std::size_t size = 0;
for (const char* const* ptr = array; *ptr != NULL; ptr++)
size++;
return size;
}
static
atf::process::status
exec_process_helpers(const atf::tests::tc& tc, const char* helper_name)
{
using atf::process::exec;
std::vector< std::string > argv;
argv.push_back(get_process_helpers_path(tc, true).leaf_name());
argv.push_back(helper_name);
return exec(get_process_helpers_path(tc, true),
atf::process::argv_array(argv),
atf::process::stream_inherit(),
atf::process::stream_inherit());
}
// ------------------------------------------------------------------------
// Tests for the "argv_array" type.
// ------------------------------------------------------------------------
ATF_TEST_CASE(argv_array_init_carray);
ATF_TEST_CASE_HEAD(argv_array_init_carray)
{
set_md_var("descr", "Tests that argv_array is correctly constructed "
"from a C-style array of strings");
}
ATF_TEST_CASE_BODY(argv_array_init_carray)
{
{
const char* const carray[] = { NULL };
atf::process::argv_array argv(carray);
ATF_REQUIRE_EQ(argv.size(), 0);
}
{
const char* const carray[] = { "arg0", NULL };
atf::process::argv_array argv(carray);
ATF_REQUIRE_EQ(argv.size(), 1);
ATF_REQUIRE(std::strcmp(argv[0], carray[0]) == 0);
}
{
const char* const carray[] = { "arg0", "arg1", "arg2", NULL };
atf::process::argv_array argv(carray);
ATF_REQUIRE_EQ(argv.size(), 3);
ATF_REQUIRE(std::strcmp(argv[0], carray[0]) == 0);
ATF_REQUIRE(std::strcmp(argv[1], carray[1]) == 0);
ATF_REQUIRE(std::strcmp(argv[2], carray[2]) == 0);
}
}
ATF_TEST_CASE(argv_array_init_col);
ATF_TEST_CASE_HEAD(argv_array_init_col)
{
set_md_var("descr", "Tests that argv_array is correctly constructed "
"from a string collection");
}
ATF_TEST_CASE_BODY(argv_array_init_col)
{
{
std::vector< std::string > col;
atf::process::argv_array argv(col);
ATF_REQUIRE_EQ(argv.size(), 0);
}
{
std::vector< std::string > col;
col.push_back("arg0");
atf::process::argv_array argv(col);
ATF_REQUIRE_EQ(argv.size(), 1);
ATF_REQUIRE_EQ(argv[0], col[0]);
}
{
std::vector< std::string > col;
col.push_back("arg0");
col.push_back("arg1");
col.push_back("arg2");
atf::process::argv_array argv(col);
ATF_REQUIRE_EQ(argv.size(), 3);
ATF_REQUIRE_EQ(argv[0], col[0]);
ATF_REQUIRE_EQ(argv[1], col[1]);
ATF_REQUIRE_EQ(argv[2], col[2]);
}
}
ATF_TEST_CASE(argv_array_init_empty);
ATF_TEST_CASE_HEAD(argv_array_init_empty)
{
set_md_var("descr", "Tests that argv_array is correctly constructed "
"by the default constructor");
}
ATF_TEST_CASE_BODY(argv_array_init_empty)
{
atf::process::argv_array argv;
ATF_REQUIRE_EQ(argv.size(), 0);
}
ATF_TEST_CASE(argv_array_init_varargs);
ATF_TEST_CASE_HEAD(argv_array_init_varargs)
{
set_md_var("descr", "Tests that argv_array is correctly constructed "
"from a variable list of arguments");
}
ATF_TEST_CASE_BODY(argv_array_init_varargs)
{
{
atf::process::argv_array argv("arg0", NULL);
ATF_REQUIRE_EQ(argv.size(), 1);
ATF_REQUIRE_EQ(argv[0], std::string("arg0"));
}
{
atf::process::argv_array argv("arg0", "arg1", "arg2", NULL);
ATF_REQUIRE_EQ(argv.size(), 3);
ATF_REQUIRE_EQ(argv[0], std::string("arg0"));
ATF_REQUIRE_EQ(argv[1], std::string("arg1"));
ATF_REQUIRE_EQ(argv[2], std::string("arg2"));
}
}
ATF_TEST_CASE(argv_array_assign);
ATF_TEST_CASE_HEAD(argv_array_assign)
{
set_md_var("descr", "Tests that assigning an argv_array works");
}
ATF_TEST_CASE_BODY(argv_array_assign)
{
using atf::process::argv_array;
const char* const carray1[] = { "arg1", NULL };
const char* const carray2[] = { "arg1", "arg2", NULL };
std::auto_ptr< argv_array > argv1(new argv_array(carray1));
std::auto_ptr< argv_array > argv2(new argv_array(carray2));
*argv2 = *argv1;
ATF_REQUIRE_EQ(argv2->size(), argv1->size());
ATF_REQUIRE(std::strcmp((*argv2)[0], (*argv1)[0]) == 0);
ATF_REQUIRE(argv2->exec_argv() != argv1->exec_argv());
argv1.release();
{
const char* const* eargv2 = argv2->exec_argv();
ATF_REQUIRE(std::strcmp(eargv2[0], carray1[0]) == 0);
ATF_REQUIRE_EQ(eargv2[1], static_cast< const char* >(NULL));
}
argv2.release();
}
ATF_TEST_CASE(argv_array_copy);
ATF_TEST_CASE_HEAD(argv_array_copy)
{
set_md_var("descr", "Tests that copying an argv_array constructed from "
"a C-style array of strings works");
}
ATF_TEST_CASE_BODY(argv_array_copy)
{
using atf::process::argv_array;
const char* const carray[] = { "arg0", NULL };
std::auto_ptr< argv_array > argv1(new argv_array(carray));
std::auto_ptr< argv_array > argv2(new argv_array(*argv1));
ATF_REQUIRE_EQ(argv2->size(), argv1->size());
ATF_REQUIRE(std::strcmp((*argv2)[0], (*argv1)[0]) == 0);
ATF_REQUIRE(argv2->exec_argv() != argv1->exec_argv());
argv1.release();
{
const char* const* eargv2 = argv2->exec_argv();
ATF_REQUIRE(std::strcmp(eargv2[0], carray[0]) == 0);
ATF_REQUIRE_EQ(eargv2[1], static_cast< const char* >(NULL));
}
argv2.release();
}
ATF_TEST_CASE(argv_array_exec_argv);
ATF_TEST_CASE_HEAD(argv_array_exec_argv)
{
set_md_var("descr", "Tests that the exec argv provided by an argv_array "
"is correct");
}
ATF_TEST_CASE_BODY(argv_array_exec_argv)
{
using atf::process::argv_array;
{
argv_array argv;
const char* const* eargv = argv.exec_argv();
ATF_REQUIRE_EQ(array_size(eargv), 0);
ATF_REQUIRE_EQ(eargv[0], static_cast< const char* >(NULL));
}
{
const char* const carray[] = { "arg0", NULL };
argv_array argv(carray);
const char* const* eargv = argv.exec_argv();
ATF_REQUIRE_EQ(array_size(eargv), 1);
ATF_REQUIRE(std::strcmp(eargv[0], "arg0") == 0);
ATF_REQUIRE_EQ(eargv[1], static_cast< const char* >(NULL));
}
{
std::vector< std::string > col;
col.push_back("arg0");
argv_array argv(col);
const char* const* eargv = argv.exec_argv();
ATF_REQUIRE_EQ(array_size(eargv), 1);
ATF_REQUIRE(std::strcmp(eargv[0], "arg0") == 0);
ATF_REQUIRE_EQ(eargv[1], static_cast< const char* >(NULL));
}
}
ATF_TEST_CASE(argv_array_iter);
ATF_TEST_CASE_HEAD(argv_array_iter)
{
set_md_var("descr", "Tests that an argv_array can be iterated");
}
ATF_TEST_CASE_BODY(argv_array_iter)
{
using atf::process::argv_array;
std::vector< std::string > vector;
vector.push_back("arg0");
vector.push_back("arg1");
vector.push_back("arg2");
argv_array argv(vector);
ATF_REQUIRE_EQ(argv.size(), 3);
std::vector< std::string >::size_type pos = 0;
for (argv_array::const_iterator iter = argv.begin(); iter != argv.end();
iter++) {
ATF_REQUIRE_EQ(*iter, vector[pos]);
pos++;
}
}
// ------------------------------------------------------------------------
// Tests cases for the free functions.
// ------------------------------------------------------------------------
ATF_TEST_CASE(exec_failure);
ATF_TEST_CASE_HEAD(exec_failure)
{
set_md_var("descr", "Tests execing a command that reports failure");
}
ATF_TEST_CASE_BODY(exec_failure)
{
const atf::process::status s = exec_process_helpers(*this, "exit-failure");
ATF_REQUIRE(s.exited());
ATF_REQUIRE_EQ(s.exitstatus(), EXIT_FAILURE);
}
ATF_TEST_CASE(exec_success);
ATF_TEST_CASE_HEAD(exec_success)
{
set_md_var("descr", "Tests execing a command that reports success");
}
ATF_TEST_CASE_BODY(exec_success)
{
const atf::process::status s = exec_process_helpers(*this, "exit-success");
ATF_REQUIRE(s.exited());
ATF_REQUIRE_EQ(s.exitstatus(), EXIT_SUCCESS);
}
// ------------------------------------------------------------------------
// Main.
// ------------------------------------------------------------------------
ATF_INIT_TEST_CASES(tcs)
{
// Add the test cases for the "argv_array" type.
ATF_ADD_TEST_CASE(tcs, argv_array_assign);
ATF_ADD_TEST_CASE(tcs, argv_array_copy);
ATF_ADD_TEST_CASE(tcs, argv_array_exec_argv);
ATF_ADD_TEST_CASE(tcs, argv_array_init_carray);
ATF_ADD_TEST_CASE(tcs, argv_array_init_col);
ATF_ADD_TEST_CASE(tcs, argv_array_init_empty);
ATF_ADD_TEST_CASE(tcs, argv_array_init_varargs);
ATF_ADD_TEST_CASE(tcs, argv_array_iter);
// Add the test cases for the free functions.
ATF_ADD_TEST_CASE(tcs, exec_failure);
ATF_ADD_TEST_CASE(tcs, exec_success);
}

View file

@ -1,33 +0,0 @@
// Copyright (c) 2007 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#if !defined(ATF_CXX_DETAIL_SANITY_HPP)
#define ATF_CXX_DETAIL_SANITY_HPP
extern "C" {
#include <atf-c/detail/sanity.h>
}
#endif // !defined(ATF_CXX_DETAIL_SANITY_HPP)

View file

@ -1,100 +0,0 @@
// Copyright (c) 2009 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "atf-c++/detail/test_helpers.hpp"
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
#include <atf-c++.hpp>
#include "atf-c++/check.hpp"
#include "atf-c++/detail/env.hpp"
#include "atf-c++/detail/fs.hpp"
#include "atf-c++/detail/process.hpp"
// Path to the directory containing the libatf-c tests, used to locate the
// process_helpers program. If NULL (the default), the code will use a
// relative path. Otherwise, the provided path will be used; this is so
// that we can locate the helpers binary if the installation uses a
// different layout than the one we provide (as is the case in FreeBSD).
#if defined(ATF_C_TESTS_BASE)
static const char* atf_c_tests_base = ATF_C_TESTS_BASE;
#else
static const char* atf_c_tests_base = NULL;
#endif
#undef ATF_C_TESTS_BASE
bool
build_check_cxx_o(const char* sfile)
{
std::vector< std::string > optargs;
optargs.push_back("-I" + atf::env::get("ATF_INCLUDEDIR", ATF_INCLUDEDIR));
optargs.push_back("-Wall");
optargs.push_back("-Werror");
return atf::check::build_cxx_o(sfile, "test.o",
atf::process::argv_array(optargs));
}
bool
build_check_cxx_o_srcdir(const atf::tests::tc& tc, const char* sfile)
{
const atf::fs::path sfilepath =
atf::fs::path(tc.get_config_var("srcdir")) / sfile;
return build_check_cxx_o(sfilepath.c_str());
}
void
header_check(const char *hdrname)
{
std::ofstream srcfile("test.cpp");
ATF_REQUIRE(srcfile);
srcfile << "#include <" << hdrname << ">\n";
srcfile.close();
const std::string failmsg = std::string("Header check failed; ") +
hdrname + " is not self-contained";
if (!build_check_cxx_o("test.cpp"))
ATF_FAIL(failmsg);
}
atf::fs::path
get_process_helpers_path(const atf::tests::tc& tc, bool is_detail)
{
const char* helper = "detail/process_helpers";
if (atf_c_tests_base == NULL) {
if (is_detail)
return atf::fs::path(tc.get_config_var("srcdir")) /
".." / ".." / "atf-c" / helper;
else
return atf::fs::path(tc.get_config_var("srcdir")) /
".." / "atf-c" / helper;
} else {
return atf::fs::path(atf_c_tests_base) / helper;
}
}

View file

@ -1,107 +0,0 @@
// Copyright (c) 2009 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#if defined(ATF_CXX_DETAIL_TEST_HELPERS_H)
# error "Cannot include test_helpers.hpp more than once."
#else
# define ATF_CXX_DETAIL_TEST_HELPERS_H
#endif
#include <cstdlib>
#include <iostream>
#include <sstream>
#include <utility>
#include <atf-c++.hpp>
#include <atf-c++/detail/process.hpp>
#define HEADER_TC(name, hdrname) \
ATF_TEST_CASE(name); \
ATF_TEST_CASE_HEAD(name) \
{ \
set_md_var("descr", "Tests that the " hdrname " file can be " \
"included on its own, without any prerequisites"); \
} \
ATF_TEST_CASE_BODY(name) \
{ \
header_check(hdrname); \
}
#define BUILD_TC(name, sfile, descr, failmsg) \
ATF_TEST_CASE(name); \
ATF_TEST_CASE_HEAD(name) \
{ \
set_md_var("descr", descr); \
} \
ATF_TEST_CASE_BODY(name) \
{ \
if (!build_check_cxx_o_srcdir(*this, sfile)) \
ATF_FAIL(failmsg); \
}
namespace atf {
namespace tests {
class tc;
}
}
void header_check(const char*);
bool build_check_cxx_o(const char*);
bool build_check_cxx_o_srcdir(const atf::tests::tc&, const char*);
atf::fs::path get_process_helpers_path(const atf::tests::tc&, bool);
struct run_h_tc_data {
const atf::tests::vars_map& m_config;
run_h_tc_data(const atf::tests::vars_map& config) :
m_config(config) {}
};
template< class TestCase >
void
run_h_tc_child(void* v)
{
run_h_tc_data* data = static_cast< run_h_tc_data* >(v);
TestCase tc;
tc.init(data->m_config);
tc.run("result");
std::exit(EXIT_SUCCESS);
}
template< class TestCase >
void
run_h_tc(atf::tests::vars_map config = atf::tests::vars_map())
{
run_h_tc_data data(config);
atf::process::child c = atf::process::fork(
run_h_tc_child< TestCase >,
atf::process::stream_redirect_path(atf::fs::path("stdout")),
atf::process::stream_redirect_path(atf::fs::path("stderr")),
&data);
const atf::process::status s = c.wait();
ATF_REQUIRE(s.exited());
}

View file

@ -1,156 +0,0 @@
// Copyright (c) 2007 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "atf-c++/detail/text.hpp"
extern "C" {
#include <regex.h>
}
#include <cctype>
#include <cstring>
extern "C" {
#include "atf-c/detail/text.h"
#include "atf-c/error.h"
}
#include "atf-c++/detail/exceptions.hpp"
namespace impl = atf::text;
#define IMPL_NAME "atf::text"
char*
impl::duplicate(const char* str)
{
char* copy = new char[std::strlen(str) + 1];
std::strcpy(copy, str);
return copy;
}
bool
impl::match(const std::string& str, const std::string& regex)
{
bool found;
// Special case: regcomp does not like empty regular expressions.
if (regex.empty()) {
found = str.empty();
} else {
::regex_t preg;
if (::regcomp(&preg, regex.c_str(), REG_EXTENDED) != 0)
throw std::runtime_error("Invalid regular expression '" + regex +
"'");
const int res = ::regexec(&preg, str.c_str(), 0, NULL, 0);
regfree(&preg);
if (res != 0 && res != REG_NOMATCH)
throw std::runtime_error("Invalid regular expression " + regex);
found = res == 0;
}
return found;
}
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;
}
int64_t
impl::to_bytes(std::string str)
{
if (str.empty())
throw std::runtime_error("Empty value");
const char unit = str[str.length() - 1];
int64_t multiplier;
switch (unit) {
case 'k': case 'K': multiplier = 1 << 10; break;
case 'm': case 'M': multiplier = 1 << 20; break;
case 'g': case 'G': multiplier = 1 << 30; break;
case 't': case 'T': multiplier = int64_t(1) << 40; break;
default:
if (!std::isdigit(unit))
throw std::runtime_error(std::string("Unknown size unit '") + unit
+ "'");
multiplier = 1;
}
if (multiplier != 1)
str.erase(str.length() - 1);
return to_type< int64_t >(str) * multiplier;
}

View file

@ -1,149 +0,0 @@
// Copyright (c) 2007 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#if !defined(ATF_CXX_DETAIL_TEXT_HPP)
#define ATF_CXX_DETAIL_TEXT_HPP
extern "C" {
#include <stdint.h>
}
#include <sstream>
#include <stdexcept>
#include <string>
#include <vector>
namespace atf {
namespace text {
//!
//! \brief Duplicates a C string using the new[] allocator.
//!
//! Replaces the functionality of strdup by using the new[] allocator and
//! thus allowing the resulting memory to be managed by utils::auto_array.
//!
char* duplicate(const char*);
//!
//! \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 Checks if the string matches a regular expression.
//!
bool match(const std::string&, const std::string&);
//!
//! \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 Converts the given string to a bytes size.
//!
int64_t to_bytes(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.fail() || ss.bad())))
throw std::runtime_error("Cannot convert string to requested type");
return value;
}
} // namespace text
} // namespace atf
#endif // !defined(ATF_CXX_DETAIL_TEXT_HPP)

View file

@ -1,386 +0,0 @@
// Copyright (c) 2007 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "atf-c++/detail/text.hpp"
#include <cstring>
#include <set>
#include <vector>
#include <atf-c++.hpp>
// ------------------------------------------------------------------------
// Test cases for the free functions.
// ------------------------------------------------------------------------
ATF_TEST_CASE(duplicate);
ATF_TEST_CASE_HEAD(duplicate)
{
set_md_var("descr", "Tests the duplicate function");
}
ATF_TEST_CASE_BODY(duplicate)
{
using atf::text::duplicate;
const char* orig = "foo";
char* copy = duplicate(orig);
ATF_REQUIRE_EQ(std::strlen(copy), 3);
ATF_REQUIRE(std::strcmp(copy, "foo") == 0);
std::strcpy(copy, "bar");
ATF_REQUIRE(std::strcmp(copy, "bar") == 0);
ATF_REQUIRE(std::strcmp(orig, "foo") == 0);
}
ATF_TEST_CASE(join);
ATF_TEST_CASE_HEAD(join)
{
set_md_var("descr", "Tests the join function");
}
ATF_TEST_CASE_BODY(join)
{
using atf::text::join;
// First set of tests using a non-sorted collection, std::vector.
{
std::vector< std::string > words;
std::string str;
words.clear();
str = join(words, ",");
ATF_REQUIRE_EQ(str, "");
words.clear();
words.push_back("");
str = join(words, ",");
ATF_REQUIRE_EQ(str, "");
words.clear();
words.push_back("");
words.push_back("");
str = join(words, ",");
ATF_REQUIRE_EQ(str, ",");
words.clear();
words.push_back("foo");
words.push_back("");
words.push_back("baz");
str = join(words, ",");
ATF_REQUIRE_EQ(str, "foo,,baz");
words.clear();
words.push_back("foo");
words.push_back("bar");
words.push_back("baz");
str = join(words, ",");
ATF_REQUIRE_EQ(str, "foo,bar,baz");
}
// Second set of tests using a sorted collection, std::set.
{
std::set< std::string > words;
std::string str;
words.clear();
str = join(words, ",");
ATF_REQUIRE_EQ(str, "");
words.clear();
words.insert("");
str = join(words, ",");
ATF_REQUIRE_EQ(str, "");
words.clear();
words.insert("foo");
words.insert("");
words.insert("baz");
str = join(words, ",");
ATF_REQUIRE_EQ(str, ",baz,foo");
words.clear();
words.insert("foo");
words.insert("bar");
words.insert("baz");
str = join(words, ",");
ATF_REQUIRE_EQ(str, "bar,baz,foo");
}
}
ATF_TEST_CASE(match);
ATF_TEST_CASE_HEAD(match)
{
set_md_var("descr", "Tests the match function");
}
ATF_TEST_CASE_BODY(match)
{
using atf::text::match;
ATF_REQUIRE_THROW(std::runtime_error, match("", "["));
ATF_REQUIRE(match("", ""));
ATF_REQUIRE(!match("foo", ""));
ATF_REQUIRE(match("", ".*"));
ATF_REQUIRE(match("", "[a-z]*"));
ATF_REQUIRE(match("hello", "hello"));
ATF_REQUIRE(match("hello", "[a-z]+"));
ATF_REQUIRE(match("hello", "^[a-z]+$"));
ATF_REQUIRE(!match("hello", "helooo"));
ATF_REQUIRE(!match("hello", "[a-z]+5"));
ATF_REQUIRE(!match("hello", "^ [a-z]+$"));
}
ATF_TEST_CASE(split);
ATF_TEST_CASE_HEAD(split)
{
set_md_var("descr", "Tests the split function");
}
ATF_TEST_CASE_BODY(split)
{
using atf::text::split;
std::vector< std::string > words;
words = split("", " ");
ATF_REQUIRE_EQ(words.size(), 0);
words = split(" ", " ");
ATF_REQUIRE_EQ(words.size(), 0);
words = split(" ", " ");
ATF_REQUIRE_EQ(words.size(), 0);
words = split("a b", " ");
ATF_REQUIRE_EQ(words.size(), 2);
ATF_REQUIRE_EQ(words[0], "a");
ATF_REQUIRE_EQ(words[1], "b");
words = split("a b c d", " ");
ATF_REQUIRE_EQ(words.size(), 4);
ATF_REQUIRE_EQ(words[0], "a");
ATF_REQUIRE_EQ(words[1], "b");
ATF_REQUIRE_EQ(words[2], "c");
ATF_REQUIRE_EQ(words[3], "d");
words = split("foo bar", " ");
ATF_REQUIRE_EQ(words.size(), 2);
ATF_REQUIRE_EQ(words[0], "foo");
ATF_REQUIRE_EQ(words[1], "bar");
words = split("foo bar baz foobar", " ");
ATF_REQUIRE_EQ(words.size(), 4);
ATF_REQUIRE_EQ(words[0], "foo");
ATF_REQUIRE_EQ(words[1], "bar");
ATF_REQUIRE_EQ(words[2], "baz");
ATF_REQUIRE_EQ(words[3], "foobar");
words = split(" foo bar", " ");
ATF_REQUIRE_EQ(words.size(), 2);
ATF_REQUIRE_EQ(words[0], "foo");
ATF_REQUIRE_EQ(words[1], "bar");
words = split("foo bar", " ");
ATF_REQUIRE_EQ(words.size(), 2);
ATF_REQUIRE_EQ(words[0], "foo");
ATF_REQUIRE_EQ(words[1], "bar");
words = split("foo bar ", " ");
ATF_REQUIRE_EQ(words.size(), 2);
ATF_REQUIRE_EQ(words[0], "foo");
ATF_REQUIRE_EQ(words[1], "bar");
words = split(" foo bar ", " ");
ATF_REQUIRE_EQ(words.size(), 2);
ATF_REQUIRE_EQ(words[0], "foo");
ATF_REQUIRE_EQ(words[1], "bar");
}
ATF_TEST_CASE(split_delims);
ATF_TEST_CASE_HEAD(split_delims)
{
set_md_var("descr", "Tests the split function using different delimiters");
}
ATF_TEST_CASE_BODY(split_delims)
{
using atf::text::split;
std::vector< std::string > words;
words = split("", "/");
ATF_REQUIRE_EQ(words.size(), 0);
words = split(" ", "/");
ATF_REQUIRE_EQ(words.size(), 1);
ATF_REQUIRE_EQ(words[0], " ");
words = split(" ", "/");
ATF_REQUIRE_EQ(words.size(), 1);
ATF_REQUIRE_EQ(words[0], " ");
words = split("a/b", "/");
ATF_REQUIRE_EQ(words.size(), 2);
ATF_REQUIRE_EQ(words[0], "a");
ATF_REQUIRE_EQ(words[1], "b");
words = split("aLONGDELIMbcdLONGDELIMef", "LONGDELIM");
ATF_REQUIRE_EQ(words.size(), 3);
ATF_REQUIRE_EQ(words[0], "a");
ATF_REQUIRE_EQ(words[1], "bcd");
ATF_REQUIRE_EQ(words[2], "ef");
}
ATF_TEST_CASE(trim);
ATF_TEST_CASE_HEAD(trim)
{
set_md_var("descr", "Tests the trim function");
}
ATF_TEST_CASE_BODY(trim)
{
using atf::text::trim;
ATF_REQUIRE_EQ(trim(""), "");
ATF_REQUIRE_EQ(trim(" "), "");
ATF_REQUIRE_EQ(trim("\t"), "");
ATF_REQUIRE_EQ(trim(" foo"), "foo");
ATF_REQUIRE_EQ(trim("\t foo"), "foo");
ATF_REQUIRE_EQ(trim(" \tfoo"), "foo");
ATF_REQUIRE_EQ(trim("foo\t "), "foo");
ATF_REQUIRE_EQ(trim("foo \t"), "foo");
ATF_REQUIRE_EQ(trim("foo bar"), "foo bar");
ATF_REQUIRE_EQ(trim("\t foo bar"), "foo bar");
ATF_REQUIRE_EQ(trim(" \tfoo bar"), "foo bar");
ATF_REQUIRE_EQ(trim("foo bar\t "), "foo bar");
ATF_REQUIRE_EQ(trim("foo bar \t"), "foo bar");
}
ATF_TEST_CASE(to_bool);
ATF_TEST_CASE_HEAD(to_bool)
{
set_md_var("descr", "Tests the to_string function");
}
ATF_TEST_CASE_BODY(to_bool)
{
using atf::text::to_bool;
ATF_REQUIRE(to_bool("true"));
ATF_REQUIRE(to_bool("TRUE"));
ATF_REQUIRE(to_bool("yes"));
ATF_REQUIRE(to_bool("YES"));
ATF_REQUIRE(!to_bool("false"));
ATF_REQUIRE(!to_bool("FALSE"));
ATF_REQUIRE(!to_bool("no"));
ATF_REQUIRE(!to_bool("NO"));
ATF_REQUIRE_THROW(std::runtime_error, to_bool(""));
ATF_REQUIRE_THROW(std::runtime_error, to_bool("tru"));
ATF_REQUIRE_THROW(std::runtime_error, to_bool("true2"));
ATF_REQUIRE_THROW(std::runtime_error, to_bool("fals"));
ATF_REQUIRE_THROW(std::runtime_error, to_bool("false2"));
}
ATF_TEST_CASE(to_bytes);
ATF_TEST_CASE_HEAD(to_bytes)
{
set_md_var("descr", "Tests the to_bytes function");
}
ATF_TEST_CASE_BODY(to_bytes)
{
using atf::text::to_bytes;
ATF_REQUIRE_EQ(0, to_bytes("0"));
ATF_REQUIRE_EQ(12345, to_bytes("12345"));
ATF_REQUIRE_EQ(2 * 1024, to_bytes("2k"));
ATF_REQUIRE_EQ(4 * 1024 * 1024, to_bytes("4m"));
ATF_REQUIRE_EQ(int64_t(8) * 1024 * 1024 * 1024, to_bytes("8g"));
ATF_REQUIRE_EQ(int64_t(16) * 1024 * 1024 * 1024 * 1024, to_bytes("16t"));
ATF_REQUIRE_THROW_RE(std::runtime_error, "Empty", to_bytes(""));
ATF_REQUIRE_THROW_RE(std::runtime_error, "Unknown size unit 'd'",
to_bytes("12d"));
ATF_REQUIRE_THROW(std::runtime_error, to_bytes(" "));
ATF_REQUIRE_THROW(std::runtime_error, to_bytes(" k"));
}
ATF_TEST_CASE(to_string);
ATF_TEST_CASE_HEAD(to_string)
{
set_md_var("descr", "Tests the to_string function");
}
ATF_TEST_CASE_BODY(to_string)
{
using atf::text::to_string;
ATF_REQUIRE_EQ(to_string('a'), "a");
ATF_REQUIRE_EQ(to_string("a"), "a");
ATF_REQUIRE_EQ(to_string(5), "5");
}
ATF_TEST_CASE(to_type);
ATF_TEST_CASE_HEAD(to_type)
{
set_md_var("descr", "Tests the to_type function");
}
ATF_TEST_CASE_BODY(to_type)
{
using atf::text::to_type;
ATF_REQUIRE_EQ(to_type< int >("0"), 0);
ATF_REQUIRE_EQ(to_type< int >("1234"), 1234);
ATF_REQUIRE_THROW(std::runtime_error, to_type< int >(" "));
ATF_REQUIRE_THROW(std::runtime_error, to_type< int >("0 a"));
ATF_REQUIRE_THROW(std::runtime_error, to_type< int >("a"));
ATF_REQUIRE_EQ(to_type< float >("0.5"), 0.5);
ATF_REQUIRE_EQ(to_type< float >("1234.5"), 1234.5);
ATF_REQUIRE_THROW(std::runtime_error, to_type< float >("0.5 a"));
ATF_REQUIRE_THROW(std::runtime_error, to_type< float >("a"));
ATF_REQUIRE_EQ(to_type< std::string >("a"), "a");
}
// ------------------------------------------------------------------------
// Main.
// ------------------------------------------------------------------------
ATF_INIT_TEST_CASES(tcs)
{
// Add the test cases for the free functions.
ATF_ADD_TEST_CASE(tcs, duplicate);
ATF_ADD_TEST_CASE(tcs, join);
ATF_ADD_TEST_CASE(tcs, match);
ATF_ADD_TEST_CASE(tcs, split);
ATF_ADD_TEST_CASE(tcs, split_delims);
ATF_ADD_TEST_CASE(tcs, trim);
ATF_ADD_TEST_CASE(tcs, to_bool);
ATF_ADD_TEST_CASE(tcs, to_bytes);
ATF_ADD_TEST_CASE(tcs, to_string);
ATF_ADD_TEST_CASE(tcs, to_type);
}

View file

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

View file

@ -1,225 +0,0 @@
// Copyright (c) 2007 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#if !defined(ATF_CXX_MACROS_HPP)
#define ATF_CXX_MACROS_HPP
#include <sstream>
#include <stdexcept>
#include <vector>
#include <atf-c++/tests.hpp>
// Do not define inline methods for the test case classes. Doing so
// significantly increases the memory requirements of GNU G++ during
// compilation.
#define ATF_TEST_CASE_WITHOUT_HEAD(name) \
namespace { \
class atfu_tc_ ## name : public atf::tests::tc { \
void body(void) const; \
public: \
atfu_tc_ ## name(void); \
}; \
static atfu_tc_ ## name* atfu_tcptr_ ## name; \
atfu_tc_ ## name::atfu_tc_ ## name(void) : atf::tests::tc(#name, false) {} \
}
#define ATF_TEST_CASE(name) \
namespace { \
class atfu_tc_ ## name : public atf::tests::tc { \
void head(void); \
void body(void) const; \
public: \
atfu_tc_ ## name(void); \
}; \
static atfu_tc_ ## name* atfu_tcptr_ ## name; \
atfu_tc_ ## name::atfu_tc_ ## name(void) : atf::tests::tc(#name, false) {} \
}
#define ATF_TEST_CASE_WITH_CLEANUP(name) \
namespace { \
class atfu_tc_ ## name : public atf::tests::tc { \
void head(void); \
void body(void) const; \
void cleanup(void) const; \
public: \
atfu_tc_ ## name(void); \
}; \
static atfu_tc_ ## name* atfu_tcptr_ ## name; \
atfu_tc_ ## name::atfu_tc_ ## name(void) : atf::tests::tc(#name, true) {} \
}
#define ATF_TEST_CASE_NAME(name) atfu_tc_ ## name
#define ATF_TEST_CASE_USE(name) (atfu_tcptr_ ## name) = NULL
#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_REQUIRE(expression) \
do { \
if (!(expression)) { \
std::ostringstream atfu_ss; \
atfu_ss << "Line " << __LINE__ << ": " << #expression \
<< " not met"; \
atf::tests::tc::fail(atfu_ss.str()); \
} \
} while (false)
#define ATF_REQUIRE_EQ(expected, actual) \
do { \
if ((expected) != (actual)) { \
std::ostringstream atfu_ss; \
atfu_ss << "Line " << __LINE__ << ": " \
<< #expected << " != " << #actual \
<< " (" << (expected) << " != " << (actual) << ")"; \
atf::tests::tc::fail(atfu_ss.str()); \
} \
} while (false)
#define ATF_REQUIRE_IN(element, collection) \
ATF_REQUIRE((collection).find(element) != (collection).end())
#define ATF_REQUIRE_NOT_IN(element, collection) \
ATF_REQUIRE((collection).find(element) == (collection).end())
#define ATF_REQUIRE_MATCH(regexp, string) \
do { \
if (!atf::tests::detail::match(regexp, string)) { \
std::ostringstream atfu_ss; \
atfu_ss << "Line " << __LINE__ << ": '" << string << "' does not " \
<< "match regexp '" << regexp << "'"; \
atf::tests::tc::fail(atfu_ss.str()); \
} \
} while (false)
#define ATF_REQUIRE_THROW(expected_exception, statement) \
do { \
try { \
statement; \
std::ostringstream atfu_ss; \
atfu_ss << "Line " << __LINE__ \
<< ": " #statement " did not throw " #expected_exception \
" as expected"; \
atf::tests::tc::fail(atfu_ss.str()); \
} catch (const expected_exception&) { \
} catch (const std::exception& atfu_e) { \
std::ostringstream atfu_ss; \
atfu_ss << "Line " << __LINE__ << ": " #statement " threw an " \
"unexpected error (not " #expected_exception "): " \
<< atfu_e.what(); \
atf::tests::tc::fail(atfu_ss.str()); \
} catch (...) { \
std::ostringstream atfu_ss; \
atfu_ss << "Line " << __LINE__ << ": " #statement " threw an " \
"unexpected error (not " #expected_exception ")"; \
atf::tests::tc::fail(atfu_ss.str()); \
} \
} while (false)
#define ATF_REQUIRE_THROW_RE(expected_exception, regexp, statement) \
do { \
try { \
statement; \
std::ostringstream atfu_ss; \
atfu_ss << "Line " << __LINE__ \
<< ": " #statement " did not throw " #expected_exception \
" as expected"; \
atf::tests::tc::fail(atfu_ss.str()); \
} catch (const expected_exception& e) { \
if (!atf::tests::detail::match(regexp, e.what())) { \
std::ostringstream atfu_ss; \
atfu_ss << "Line " << __LINE__ \
<< ": " #statement " threw " #expected_exception "(" \
<< e.what() << "), but does not match '" << regexp \
<< "'"; \
atf::tests::tc::fail(atfu_ss.str()); \
} \
} catch (const std::exception& atfu_e) { \
std::ostringstream atfu_ss; \
atfu_ss << "Line " << __LINE__ << ": " #statement " threw an " \
"unexpected error (not " #expected_exception "): " \
<< atfu_e.what(); \
atf::tests::tc::fail(atfu_ss.str()); \
} catch (...) { \
std::ostringstream atfu_ss; \
atfu_ss << "Line " << __LINE__ << ": " #statement " threw an " \
"unexpected error (not " #expected_exception ")"; \
atf::tests::tc::fail(atfu_ss.str()); \
} \
} while (false)
#define ATF_CHECK_ERRNO(expected_errno, bool_expr) \
atf::tests::tc::check_errno(__FILE__, __LINE__, expected_errno, \
#bool_expr, bool_expr)
#define ATF_REQUIRE_ERRNO(expected_errno, bool_expr) \
atf::tests::tc::require_errno(__FILE__, __LINE__, expected_errno, \
#bool_expr, bool_expr)
#define ATF_INIT_TEST_CASES(tcs) \
namespace atf { \
namespace tests { \
int run_tp(int, char**, \
void (*)(std::vector< atf::tests::tc * >&)); \
} \
} \
\
static void atfu_init_tcs(std::vector< atf::tests::tc * >&); \
\
int \
main(int argc, char** 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 { \
atfu_tcptr_ ## tcname = new atfu_tc_ ## tcname(); \
(tcs).push_back(atfu_tcptr_ ## tcname); \
} while (0);
#endif // !defined(ATF_CXX_MACROS_HPP)

View file

@ -1,126 +0,0 @@
// 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 <atf-c++/macros.hpp>
#include <stdexcept>
void
atf_check_errno_semicolons(void)
{
// Check that ATF_CHECK_ERRNO does not contain a semicolon that would
// cause an empty-statement that confuses some compilers.
ATF_CHECK_ERRNO(1, 1 == 1);
ATF_CHECK_ERRNO(2, 2 == 2);
}
void
atf_require_inside_if(void)
{
// Make sure that ATF_REQUIRE can be used inside an if statement that
// does not have braces. Earlier versions of it generated an error
// if there was an else clause because they confused the compiler
// by defining an unprotected nested if.
if (true)
ATF_REQUIRE(true);
else
ATF_REQUIRE(true);
}
void
atf_require_eq_inside_if(void)
{
// Make sure that ATF_REQUIRE_EQ can be used inside an if statement
// that does not have braces. Earlier versions of it generated an
// error if there was an else clause because they confused the
// compiler by defining an unprotected nested if.
if (true)
ATF_REQUIRE_EQ(true, true);
else
ATF_REQUIRE_EQ(true, true);
}
void
atf_require_throw_runtime_error(void)
{
// Check that we can pass std::runtime_error to ATF_REQUIRE_THROW.
// Earlier versions generated a warning because the macro's code also
// attempted to capture this exception, and thus we had a duplicate
// catch clause.
ATF_REQUIRE_THROW(std::runtime_error, (void)0);
}
void
atf_require_throw_inside_if(void)
{
// Make sure that ATF_REQUIRE_THROW can be used inside an if statement
// that does not have braces. Earlier versions of it generated an
// error because a trailing ; after a catch block was not allowed.
if (true)
ATF_REQUIRE_THROW(std::runtime_error, (void)0);
else
ATF_REQUIRE_THROW(std::runtime_error, (void)1);
}
void
atf_require_errno_semicolons(void)
{
// Check that ATF_REQUIRE_ERRNO does not contain a semicolon that would
// cause an empty-statement that confuses some compilers.
ATF_REQUIRE_ERRNO(1, 1 == 1);
ATF_REQUIRE_ERRNO(2, 2 == 2);
}
// Test case names should not be expanded during instatiation so that they
// can have the exact same name as macros.
#define TEST_MACRO_1 invalid + name
#define TEST_MACRO_2 invalid + name
#define TEST_MACRO_3 invalid + name
ATF_TEST_CASE(TEST_MACRO_1);
ATF_TEST_CASE_HEAD(TEST_MACRO_1) { }
ATF_TEST_CASE_BODY(TEST_MACRO_1) { }
void instantiate_1(void) {
ATF_TEST_CASE_USE(TEST_MACRO_1);
atf::tests::tc* the_test = new ATF_TEST_CASE_NAME(TEST_MACRO_1)();
delete the_test;
}
ATF_TEST_CASE_WITH_CLEANUP(TEST_MACRO_2);
ATF_TEST_CASE_HEAD(TEST_MACRO_2) { }
ATF_TEST_CASE_BODY(TEST_MACRO_2) { }
ATF_TEST_CASE_CLEANUP(TEST_MACRO_2) { }
void instatiate_2(void) {
ATF_TEST_CASE_USE(TEST_MACRO_2);
atf::tests::tc* the_test = new ATF_TEST_CASE_NAME(TEST_MACRO_2)();
delete the_test;
}
ATF_TEST_CASE_WITH_CLEANUP(TEST_MACRO_3);
ATF_TEST_CASE_HEAD(TEST_MACRO_3) { }
ATF_TEST_CASE_BODY(TEST_MACRO_3) { }
ATF_TEST_CASE_CLEANUP(TEST_MACRO_3) { }
void instatiate_3(void) {
ATF_TEST_CASE_USE(TEST_MACRO_3);
atf::tests::tc* the_test = new ATF_TEST_CASE_NAME(TEST_MACRO_3)();
delete the_test;
}

View file

@ -1,811 +0,0 @@
// 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 "atf-c++/macros.hpp"
extern "C" {
#include <fcntl.h>
#include <unistd.h>
}
#include <cerrno>
#include <cstdlib>
#include <iostream>
#include <stdexcept>
#include <atf-c++.hpp>
#include "atf-c++/detail/fs.hpp"
#include "atf-c++/detail/process.hpp"
#include "atf-c++/detail/sanity.hpp"
#include "atf-c++/detail/test_helpers.hpp"
#include "atf-c++/detail/text.hpp"
#include "atf-c++/utils.hpp"
// ------------------------------------------------------------------------
// Auxiliary functions.
// ------------------------------------------------------------------------
static
void
create_ctl_file(const char *name)
{
ATF_REQUIRE(open(name, O_CREAT | O_WRONLY | O_TRUNC, 0644) != -1);
}
// ------------------------------------------------------------------------
// Auxiliary test cases.
// ------------------------------------------------------------------------
ATF_TEST_CASE(h_pass);
ATF_TEST_CASE_HEAD(h_pass)
{
set_md_var("descr", "Helper test case");
}
ATF_TEST_CASE_BODY(h_pass)
{
create_ctl_file("before");
ATF_PASS();
create_ctl_file("after");
}
ATF_TEST_CASE(h_fail);
ATF_TEST_CASE_HEAD(h_fail)
{
set_md_var("descr", "Helper test case");
}
ATF_TEST_CASE_BODY(h_fail)
{
create_ctl_file("before");
ATF_FAIL("Failed on purpose");
create_ctl_file("after");
}
ATF_TEST_CASE(h_skip);
ATF_TEST_CASE_HEAD(h_skip)
{
set_md_var("descr", "Helper test case");
}
ATF_TEST_CASE_BODY(h_skip)
{
create_ctl_file("before");
ATF_SKIP("Skipped on purpose");
create_ctl_file("after");
}
ATF_TEST_CASE(h_require);
ATF_TEST_CASE_HEAD(h_require)
{
set_md_var("descr", "Helper test case");
}
ATF_TEST_CASE_BODY(h_require)
{
bool condition = atf::text::to_bool(get_config_var("condition"));
create_ctl_file("before");
ATF_REQUIRE(condition);
create_ctl_file("after");
}
ATF_TEST_CASE(h_require_eq);
ATF_TEST_CASE_HEAD(h_require_eq)
{
set_md_var("descr", "Helper test case");
}
ATF_TEST_CASE_BODY(h_require_eq)
{
long v1 = atf::text::to_type< long >(get_config_var("v1"));
long v2 = atf::text::to_type< long >(get_config_var("v2"));
create_ctl_file("before");
ATF_REQUIRE_EQ(v1, v2);
create_ctl_file("after");
}
ATF_TEST_CASE(h_require_in);
ATF_TEST_CASE_HEAD(h_require_in)
{
set_md_var("descr", "Helper test case");
}
ATF_TEST_CASE_BODY(h_require_in)
{
const std::string element = get_config_var("value");
std::set< std::string > collection;
collection.insert("foo");
collection.insert("bar");
collection.insert("baz");
create_ctl_file("before");
ATF_REQUIRE_IN(element, collection);
create_ctl_file("after");
}
ATF_TEST_CASE(h_require_match);
ATF_TEST_CASE_HEAD(h_require_match)
{
set_md_var("descr", "Helper test case");
}
ATF_TEST_CASE_BODY(h_require_match)
{
const std::string regexp = get_config_var("regexp");
const std::string string = get_config_var("string");
create_ctl_file("before");
ATF_REQUIRE_MATCH(regexp, string);
create_ctl_file("after");
}
ATF_TEST_CASE(h_require_not_in);
ATF_TEST_CASE_HEAD(h_require_not_in)
{
set_md_var("descr", "Helper test case");
}
ATF_TEST_CASE_BODY(h_require_not_in)
{
const std::string element = get_config_var("value");
std::set< std::string > collection;
collection.insert("foo");
collection.insert("bar");
collection.insert("baz");
create_ctl_file("before");
ATF_REQUIRE_NOT_IN(element, collection);
create_ctl_file("after");
}
ATF_TEST_CASE(h_require_throw);
ATF_TEST_CASE_HEAD(h_require_throw)
{
set_md_var("descr", "Helper test case");
}
ATF_TEST_CASE_BODY(h_require_throw)
{
create_ctl_file("before");
if (get_config_var("what") == "throw_int")
ATF_REQUIRE_THROW(std::runtime_error, if (1) throw int(5));
else if (get_config_var("what") == "throw_rt")
ATF_REQUIRE_THROW(std::runtime_error,
if (1) throw std::runtime_error("e"));
else if (get_config_var("what") == "no_throw_rt")
ATF_REQUIRE_THROW(std::runtime_error,
if (0) throw std::runtime_error("e"));
create_ctl_file("after");
}
ATF_TEST_CASE(h_require_throw_re);
ATF_TEST_CASE_HEAD(h_require_throw_re)
{
set_md_var("descr", "Helper test case");
}
ATF_TEST_CASE_BODY(h_require_throw_re)
{
create_ctl_file("before");
if (get_config_var("what") == "throw_int")
ATF_REQUIRE_THROW_RE(std::runtime_error, "5", if (1) throw int(5));
else if (get_config_var("what") == "throw_rt_match")
ATF_REQUIRE_THROW_RE(std::runtime_error, "foo.*baz",
if (1) throw std::runtime_error("a foo bar baz"));
else if (get_config_var("what") == "throw_rt_no_match")
ATF_REQUIRE_THROW_RE(std::runtime_error, "foo.*baz",
if (1) throw std::runtime_error("baz foo bar a"));
else if (get_config_var("what") == "no_throw_rt")
ATF_REQUIRE_THROW_RE(std::runtime_error, "e",
if (0) throw std::runtime_error("e"));
create_ctl_file("after");
}
static int
errno_fail_stub(const int raised_errno)
{
errno = raised_errno;
return -1;
}
static int
errno_ok_stub(void)
{
return 0;
}
ATF_TEST_CASE(h_check_errno);
ATF_TEST_CASE_HEAD(h_check_errno)
{
set_md_var("descr", "Helper test case");
}
ATF_TEST_CASE_BODY(h_check_errno)
{
create_ctl_file("before");
if (get_config_var("what") == "no_error")
ATF_CHECK_ERRNO(-1, errno_ok_stub() == -1);
else if (get_config_var("what") == "errno_ok")
ATF_CHECK_ERRNO(2, errno_fail_stub(2) == -1);
else if (get_config_var("what") == "errno_fail")
ATF_CHECK_ERRNO(3, errno_fail_stub(4) == -1);
else
UNREACHABLE;
create_ctl_file("after");
}
ATF_TEST_CASE(h_require_errno);
ATF_TEST_CASE_HEAD(h_require_errno)
{
set_md_var("descr", "Helper test case");
}
ATF_TEST_CASE_BODY(h_require_errno)
{
create_ctl_file("before");
if (get_config_var("what") == "no_error")
ATF_REQUIRE_ERRNO(-1, errno_ok_stub() == -1);
else if (get_config_var("what") == "errno_ok")
ATF_REQUIRE_ERRNO(2, errno_fail_stub(2) == -1);
else if (get_config_var("what") == "errno_fail")
ATF_REQUIRE_ERRNO(3, errno_fail_stub(4) == -1);
else
UNREACHABLE;
create_ctl_file("after");
}
// ------------------------------------------------------------------------
// Test cases for the macros.
// ------------------------------------------------------------------------
ATF_TEST_CASE(pass);
ATF_TEST_CASE_HEAD(pass)
{
set_md_var("descr", "Tests the ATF_PASS macro");
}
ATF_TEST_CASE_BODY(pass)
{
ATF_TEST_CASE_USE(h_pass);
run_h_tc< ATF_TEST_CASE_NAME(h_pass) >();
ATF_REQUIRE(atf::utils::grep_file("^passed", "result"));
ATF_REQUIRE(atf::fs::exists(atf::fs::path("before")));
ATF_REQUIRE(!atf::fs::exists(atf::fs::path("after")));
}
ATF_TEST_CASE(fail);
ATF_TEST_CASE_HEAD(fail)
{
set_md_var("descr", "Tests the ATF_FAIL macro");
}
ATF_TEST_CASE_BODY(fail)
{
ATF_TEST_CASE_USE(h_fail);
run_h_tc< ATF_TEST_CASE_NAME(h_fail) >();
ATF_REQUIRE(atf::utils::grep_file("^failed: Failed on purpose", "result"));
ATF_REQUIRE(atf::fs::exists(atf::fs::path("before")));
ATF_REQUIRE(!atf::fs::exists(atf::fs::path("after")));
}
ATF_TEST_CASE(skip);
ATF_TEST_CASE_HEAD(skip)
{
set_md_var("descr", "Tests the ATF_SKIP macro");
}
ATF_TEST_CASE_BODY(skip)
{
ATF_TEST_CASE_USE(h_skip);
run_h_tc< ATF_TEST_CASE_NAME(h_skip) >();
ATF_REQUIRE(atf::utils::grep_file("^skipped: Skipped on purpose",
"result"));
ATF_REQUIRE(atf::fs::exists(atf::fs::path("before")));
ATF_REQUIRE(!atf::fs::exists(atf::fs::path("after")));
}
ATF_TEST_CASE(require);
ATF_TEST_CASE_HEAD(require)
{
set_md_var("descr", "Tests the ATF_REQUIRE macro");
}
ATF_TEST_CASE_BODY(require)
{
struct test {
const char *cond;
bool ok;
} *t, tests[] = {
{ "false", false },
{ "true", true },
{ NULL, false }
};
const atf::fs::path before("before");
const atf::fs::path after("after");
for (t = &tests[0]; t->cond != NULL; t++) {
atf::tests::vars_map config;
config["condition"] = t->cond;
std::cout << "Checking with a " << t->cond << " value\n";
ATF_TEST_CASE_USE(h_require);
run_h_tc< ATF_TEST_CASE_NAME(h_require) >(config);
ATF_REQUIRE(atf::fs::exists(before));
if (t->ok) {
ATF_REQUIRE(atf::utils::grep_file("^passed", "result"));
ATF_REQUIRE(atf::fs::exists(after));
} else {
ATF_REQUIRE(atf::utils::grep_file(
"^failed: .*condition not met", "result"));
ATF_REQUIRE(!atf::fs::exists(after));
}
atf::fs::remove(before);
if (t->ok)
atf::fs::remove(after);
}
}
ATF_TEST_CASE(require_eq);
ATF_TEST_CASE_HEAD(require_eq)
{
set_md_var("descr", "Tests the ATF_REQUIRE_EQ macro");
}
ATF_TEST_CASE_BODY(require_eq)
{
struct test {
const char *v1;
const char *v2;
bool ok;
} *t, tests[] = {
{ "1", "1", true },
{ "1", "2", false },
{ "2", "1", false },
{ "2", "2", true },
{ NULL, NULL, false }
};
const atf::fs::path before("before");
const atf::fs::path after("after");
for (t = &tests[0]; t->v1 != NULL; t++) {
atf::tests::vars_map config;
config["v1"] = t->v1;
config["v2"] = t->v2;
std::cout << "Checking with " << t->v1 << ", " << t->v2
<< " and expecting " << (t->ok ? "true" : "false")
<< "\n";
ATF_TEST_CASE_USE(h_require_eq);
run_h_tc< ATF_TEST_CASE_NAME(h_require_eq) >(config);
ATF_REQUIRE(atf::fs::exists(before));
if (t->ok) {
ATF_REQUIRE(atf::utils::grep_file("^passed", "result"));
ATF_REQUIRE(atf::fs::exists(after));
} else {
ATF_REQUIRE(atf::utils::grep_file("^failed: .*v1 != v2", "result"));
ATF_REQUIRE(!atf::fs::exists(after));
}
atf::fs::remove(before);
if (t->ok)
atf::fs::remove(after);
}
}
ATF_TEST_CASE(require_in);
ATF_TEST_CASE_HEAD(require_in)
{
set_md_var("descr", "Tests the ATF_REQUIRE_IN macro");
}
ATF_TEST_CASE_BODY(require_in)
{
struct test {
const char *value;
bool ok;
} *t, tests[] = {
{ "foo", true },
{ "bar", true },
{ "baz", true },
{ "xxx", false },
{ "fooa", false },
{ "foo ", false },
{ NULL, false }
};
const atf::fs::path before("before");
const atf::fs::path after("after");
for (t = &tests[0]; t->value != NULL; t++) {
atf::tests::vars_map config;
config["value"] = t->value;
ATF_TEST_CASE_USE(h_require_in);
run_h_tc< ATF_TEST_CASE_NAME(h_require_in) >(config);
ATF_REQUIRE(atf::fs::exists(before));
if (t->ok) {
ATF_REQUIRE(atf::utils::grep_file("^passed", "result"));
ATF_REQUIRE(atf::fs::exists(after));
} else {
ATF_REQUIRE(atf::utils::grep_file("^failed: ", "result"));
ATF_REQUIRE(!atf::fs::exists(after));
}
atf::fs::remove(before);
if (t->ok)
atf::fs::remove(after);
}
}
ATF_TEST_CASE(require_match);
ATF_TEST_CASE_HEAD(require_match)
{
set_md_var("descr", "Tests the ATF_REQUIRE_MATCH macro");
}
ATF_TEST_CASE_BODY(require_match)
{
struct test {
const char *regexp;
const char *string;
bool ok;
} *t, tests[] = {
{ "foo.*bar", "this is a foo, bar, baz", true },
{ "bar.*baz", "this is a baz, bar, foo", false },
{ NULL, NULL, false }
};
const atf::fs::path before("before");
const atf::fs::path after("after");
for (t = &tests[0]; t->regexp != NULL; t++) {
atf::tests::vars_map config;
config["regexp"] = t->regexp;
config["string"] = t->string;
std::cout << "Checking with " << t->regexp << ", " << t->string
<< " and expecting " << (t->ok ? "true" : "false")
<< "\n";
ATF_TEST_CASE_USE(h_require_match);
run_h_tc< ATF_TEST_CASE_NAME(h_require_match) >(config);
ATF_REQUIRE(atf::fs::exists(before));
if (t->ok) {
ATF_REQUIRE(atf::utils::grep_file("^passed", "result"));
ATF_REQUIRE(atf::fs::exists(after));
} else {
ATF_REQUIRE(atf::utils::grep_file("^failed: ", "result"));
ATF_REQUIRE(!atf::fs::exists(after));
}
atf::fs::remove(before);
if (t->ok)
atf::fs::remove(after);
}
}
ATF_TEST_CASE(require_not_in);
ATF_TEST_CASE_HEAD(require_not_in)
{
set_md_var("descr", "Tests the ATF_REQUIRE_NOT_IN macro");
}
ATF_TEST_CASE_BODY(require_not_in)
{
struct test {
const char *value;
bool ok;
} *t, tests[] = {
{ "foo", false },
{ "bar", false },
{ "baz", false },
{ "xxx", true },
{ "fooa", true },
{ "foo ", true },
{ NULL, false }
};
const atf::fs::path before("before");
const atf::fs::path after("after");
for (t = &tests[0]; t->value != NULL; t++) {
atf::tests::vars_map config;
config["value"] = t->value;
ATF_TEST_CASE_USE(h_require_not_in);
run_h_tc< ATF_TEST_CASE_NAME(h_require_not_in) >(config);
ATF_REQUIRE(atf::fs::exists(before));
if (t->ok) {
ATF_REQUIRE(atf::utils::grep_file("^passed", "result"));
ATF_REQUIRE(atf::fs::exists(after));
} else {
ATF_REQUIRE(atf::utils::grep_file("^failed: ", "result"));
ATF_REQUIRE(!atf::fs::exists(after));
}
atf::fs::remove(before);
if (t->ok)
atf::fs::remove(after);
}
}
ATF_TEST_CASE(require_throw);
ATF_TEST_CASE_HEAD(require_throw)
{
set_md_var("descr", "Tests the ATF_REQUIRE_THROW macro");
}
ATF_TEST_CASE_BODY(require_throw)
{
struct test {
const char *what;
bool ok;
const char *msg;
} *t, tests[] = {
{ "throw_int", false, "unexpected error" },
{ "throw_rt", true, NULL },
{ "no_throw_rt", false, "did not throw" },
{ NULL, false, NULL }
};
const atf::fs::path before("before");
const atf::fs::path after("after");
for (t = &tests[0]; t->what != NULL; t++) {
atf::tests::vars_map config;
config["what"] = t->what;
std::cout << "Checking with " << t->what << " and expecting "
<< (t->ok ? "true" : "false") << "\n";
ATF_TEST_CASE_USE(h_require_throw);
run_h_tc< ATF_TEST_CASE_NAME(h_require_throw) >(config);
ATF_REQUIRE(atf::fs::exists(before));
if (t->ok) {
ATF_REQUIRE(atf::utils::grep_file("^passed", "result"));
ATF_REQUIRE(atf::fs::exists(after));
} else {
std::cout << "Checking that message contains '" << t->msg
<< "'\n";
std::string exp_result = std::string("^failed: .*") + t->msg;
ATF_REQUIRE(atf::utils::grep_file(exp_result.c_str(), "result"));
ATF_REQUIRE(!atf::fs::exists(after));
}
atf::fs::remove(before);
if (t->ok)
atf::fs::remove(after);
}
}
ATF_TEST_CASE(require_throw_re);
ATF_TEST_CASE_HEAD(require_throw_re)
{
set_md_var("descr", "Tests the ATF_REQUIRE_THROW_RE macro");
}
ATF_TEST_CASE_BODY(require_throw_re)
{
struct test {
const char *what;
bool ok;
const char *msg;
} *t, tests[] = {
{ "throw_int", false, "unexpected error" },
{ "throw_rt_match", true, NULL },
{ "throw_rt_no_match", false,
"threw.*runtime_error\\(baz foo bar a\\).*"
"does not match 'foo\\.\\*baz'" },
{ "no_throw_rt", false, "did not throw" },
{ NULL, false, NULL }
};
const atf::fs::path before("before");
const atf::fs::path after("after");
for (t = &tests[0]; t->what != NULL; t++) {
atf::tests::vars_map config;
config["what"] = t->what;
std::cout << "Checking with " << t->what << " and expecting "
<< (t->ok ? "true" : "false") << "\n";
ATF_TEST_CASE_USE(h_require_throw_re);
run_h_tc< ATF_TEST_CASE_NAME(h_require_throw_re) >(config);
ATF_REQUIRE(atf::fs::exists(before));
if (t->ok) {
ATF_REQUIRE(atf::utils::grep_file("^passed", "result"));
ATF_REQUIRE(atf::fs::exists(after));
} else {
std::cout << "Checking that message contains '" << t->msg
<< "'\n";
std::string exp_result = std::string("^failed: .*") + t->msg;
ATF_REQUIRE(atf::utils::grep_file(exp_result.c_str(), "result"));
ATF_REQUIRE(!atf::fs::exists(after));
}
atf::fs::remove(before);
if (t->ok)
atf::fs::remove(after);
}
}
ATF_TEST_CASE(check_errno);
ATF_TEST_CASE_HEAD(check_errno)
{
set_md_var("descr", "Tests the ATF_CHECK_ERRNO macro");
}
ATF_TEST_CASE_BODY(check_errno)
{
struct test {
const char *what;
bool ok;
const char *msg;
} *t, tests[] = {
{ "no_error", false,
"Expected true value in errno_ok_stub\\(\\) == -1" },
{ "errno_ok", true, NULL },
{ "errno_fail", false,
"Expected errno 3, got 4, in errno_fail_stub\\(4\\) == -1" },
{ NULL, false, NULL }
};
const atf::fs::path before("before");
const atf::fs::path after("after");
for (t = &tests[0]; t->what != NULL; t++) {
atf::tests::vars_map config;
config["what"] = t->what;
ATF_TEST_CASE_USE(h_check_errno);
run_h_tc< ATF_TEST_CASE_NAME(h_check_errno) >(config);
ATF_REQUIRE(atf::fs::exists(before));
ATF_REQUIRE(atf::fs::exists(after));
if (t->ok) {
ATF_REQUIRE(atf::utils::grep_file("^passed", "result"));
} else {
ATF_REQUIRE(atf::utils::grep_file("^failed", "result"));
std::string exp_result = "macros_test.cpp:[0-9]+: " +
std::string(t->msg) + "$";
ATF_REQUIRE(atf::utils::grep_file(exp_result.c_str(), "stderr"));
}
atf::fs::remove(before);
atf::fs::remove(after);
}
}
ATF_TEST_CASE(require_errno);
ATF_TEST_CASE_HEAD(require_errno)
{
set_md_var("descr", "Tests the ATF_REQUIRE_ERRNO macro");
}
ATF_TEST_CASE_BODY(require_errno)
{
struct test {
const char *what;
bool ok;
const char *msg;
} *t, tests[] = {
{ "no_error", false,
"Expected true value in errno_ok_stub\\(\\) == -1" },
{ "errno_ok", true, NULL },
{ "errno_fail", false,
"Expected errno 3, got 4, in errno_fail_stub\\(4\\) == -1" },
{ NULL, false, NULL }
};
const atf::fs::path before("before");
const atf::fs::path after("after");
for (t = &tests[0]; t->what != NULL; t++) {
atf::tests::vars_map config;
config["what"] = t->what;
ATF_TEST_CASE_USE(h_require_errno);
run_h_tc< ATF_TEST_CASE_NAME(h_require_errno) >(config);
ATF_REQUIRE(atf::fs::exists(before));
if (t->ok) {
ATF_REQUIRE(atf::utils::grep_file("^passed", "result"));
ATF_REQUIRE(atf::fs::exists(after));
} else {
std::string exp_result = "^failed: .*macros_test.cpp:[0-9]+: " +
std::string(t->msg) + "$";
ATF_REQUIRE(atf::utils::grep_file(exp_result.c_str(), "result"));
ATF_REQUIRE(!atf::fs::exists(after));
}
atf::fs::remove(before);
if (t->ok)
atf::fs::remove(after);
}
}
// ------------------------------------------------------------------------
// Tests cases for the header file.
// ------------------------------------------------------------------------
BUILD_TC(use, "macros_hpp_test.cpp",
"Tests that the macros provided by the atf-c++/macros.hpp file "
"do not cause syntax errors when used",
"Build of macros_hpp_test.cpp failed; some macros in "
"atf-c++/macros.hpp are broken");
ATF_TEST_CASE(detect_unused_tests);
ATF_TEST_CASE_HEAD(detect_unused_tests)
{
set_md_var("descr",
"Tests that defining an unused test case raises a warning (and "
"thus an error)");
}
ATF_TEST_CASE_BODY(detect_unused_tests)
{
const char* validate_compiler =
"class test_class { public: int dummy; };\n"
"#define define_unused static test_class unused\n"
"define_unused;\n";
atf::utils::create_file("compiler_test.cpp", validate_compiler);
if (build_check_cxx_o("compiler_test.cpp"))
expect_fail("Compiler does not raise a warning on an unused "
"static global variable declared by a macro");
if (build_check_cxx_o_srcdir(*this, "unused_test.cpp"))
ATF_FAIL("Build of unused_test.cpp passed; unused test cases are "
"not properly detected");
}
// ------------------------------------------------------------------------
// Main.
// ------------------------------------------------------------------------
ATF_INIT_TEST_CASES(tcs)
{
// Add the test cases for the macros.
ATF_ADD_TEST_CASE(tcs, pass);
ATF_ADD_TEST_CASE(tcs, fail);
ATF_ADD_TEST_CASE(tcs, skip);
ATF_ADD_TEST_CASE(tcs, check_errno);
ATF_ADD_TEST_CASE(tcs, require);
ATF_ADD_TEST_CASE(tcs, require_eq);
ATF_ADD_TEST_CASE(tcs, require_in);
ATF_ADD_TEST_CASE(tcs, require_match);
ATF_ADD_TEST_CASE(tcs, require_not_in);
ATF_ADD_TEST_CASE(tcs, require_throw);
ATF_ADD_TEST_CASE(tcs, require_throw_re);
ATF_ADD_TEST_CASE(tcs, require_errno);
// Add the test cases for the header file.
ATF_ADD_TEST_CASE(tcs, use);
ATF_ADD_TEST_CASE(tcs, detect_unused_tests);
}

View file

@ -1,143 +0,0 @@
# 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.
# The following tests assume that the atfc++.pc file is installed in a
# directory that is known by pkg-config. Otherwise they will fail,
# and you will be required to adjust PKG_CONFIG_PATH accordingly.
#
# It would be possible to bypass this requirement by setting the path
# explicitly during the tests, but then this would not do a real check
# to ensure that the installation is working.
require_pc()
{
pkg-config ${1} || atf_fail "pkg-config could not locate ${1}.pc;" \
"maybe need to set PKG_CONFIG_PATH?"
}
check_version()
{
ver1=$($(atf_get_srcdir)/detail/version_helper)
echo "Version reported by builtin PACKAGE_VERSION: ${ver1}"
atf_check -s eq:0 -o save:stdout -e empty pkg-config --modversion "${1}"
ver2=$(cat stdout)
echo "Version reported by pkg-config: ${ver2}"
atf_check_equal ${ver1} ${ver2}
}
atf_test_case version
version_head()
{
atf_set "descr" "Checks that the version in atf-c++ is correct"
atf_set "require.progs" "pkg-config"
}
version_body()
{
require_pc "atf-c++"
check_version "atf-c++"
}
atf_test_case build
build_head()
{
atf_set "descr" "Checks that a test program can be built against" \
"the C++ library based on the pkg-config information"
atf_set "require.progs" "pkg-config"
}
build_body()
{
require_pc "atf-c++"
atf_check -s eq:0 -o save:stdout -e empty \
pkg-config --variable=cxx atf-c++
cxx=$(cat stdout)
echo "Compiler is: ${cxx}"
atf_require_prog ${cxx}
cat >tp.cpp <<EOF
#include <iostream>
#include <atf-c++.hpp>
ATF_TEST_CASE(tc);
ATF_TEST_CASE_HEAD(tc) {
set_md_var("descr", "A test case");
}
ATF_TEST_CASE_BODY(tc) {
std::cout << "Running\n";
}
ATF_INIT_TEST_CASES(tcs) {
ATF_ADD_TEST_CASE(tcs, tc);
}
EOF
atf_check -s eq:0 -o save:stdout -e empty pkg-config --cflags atf-c++
cxxflags=$(cat stdout)
echo "CXXFLAGS are: ${cxxflags}"
atf_check -s eq:0 -o save:stdout -e empty \
pkg-config --libs-only-L --libs-only-other atf-c++
ldflags=$(cat stdout)
atf_check -s eq:0 -o save:stdout -e empty \
pkg-config --libs-only-l atf-c++
libs=$(cat stdout)
echo "LDFLAGS are: ${ldflags}"
echo "LIBS are: ${libs}"
atf_check -s eq:0 -o empty -e empty ${cxx} ${cxxflags} -o tp.o -c tp.cpp
atf_check -s eq:0 -o empty -e empty ${cxx} ${ldflags} -o tp tp.o ${libs}
libpath=
for f in ${ldflags}; do
case ${f} in
-L*)
dir=$(echo ${f} | sed -e 's,^-L,,')
if [ -z "${libpath}" ]; then
libpath="${dir}"
else
libpath="${libpath}:${dir}"
fi
;;
*)
;;
esac
done
atf_check -s eq:0 -o empty -e empty test -x tp
atf_check -s eq:0 -o match:'Running' -e empty -x \
"LD_LIBRARY_PATH=${libpath} ./tp tc"
}
atf_init_test_cases()
{
atf_add_test_case version
atf_add_test_case build
}
# vim: syntax=sh:expandtab:shiftwidth=4:softtabstop=4

View file

@ -1,658 +0,0 @@
// Copyright (c) 2007 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "atf-c++/tests.hpp"
#if defined(HAVE_CONFIG_H)
#include "config.h"
#endif
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/error.h"
#include "atf-c/tc.h"
#include "atf-c/utils.h"
}
#include "atf-c++/detail/application.hpp"
#include "atf-c++/detail/auto_array.hpp"
#include "atf-c++/detail/env.hpp"
#include "atf-c++/detail/exceptions.hpp"
#include "atf-c++/detail/fs.hpp"
#include "atf-c++/detail/sanity.hpp"
#include "atf-c++/detail/text.hpp"
#if defined(HAVE_GNU_GETOPT)
# define GETOPT_POSIX "+"
#else
# define GETOPT_POSIX ""
#endif
namespace impl = atf::tests;
namespace detail = atf::tests::detail;
#define IMPL_NAME "atf::tests"
using atf::application::usage_error;
// ------------------------------------------------------------------------
// The "atf_tp_writer" class.
// ------------------------------------------------------------------------
detail::atf_tp_writer::atf_tp_writer(std::ostream& os) :
m_os(os),
m_is_first(true)
{
m_os << "Content-Type: application/X-atf-tp; version=\"1\"\n\n";
}
void
detail::atf_tp_writer::start_tc(const std::string& ident)
{
if (!m_is_first)
m_os << "\n";
m_os << "ident: " << ident << "\n";
m_os.flush();
}
void
detail::atf_tp_writer::end_tc(void)
{
if (m_is_first)
m_is_first = false;
}
void
detail::atf_tp_writer::tc_meta_data(const std::string& name,
const std::string& value)
{
PRE(name != "ident");
m_os << name << ": " << value << "\n";
m_os.flush();
}
// ------------------------------------------------------------------------
// Free helper functions.
// ------------------------------------------------------------------------
std::string Program_Name;
static void
set_program_name(const char* argv0)
{
const std::string program_name = atf::fs::path(argv0).leaf_name();
// Libtool workaround: if running from within the source tree (binaries
// that are not installed yet), skip the "lt-" prefix added to files in
// the ".libs" directory to show the real (not temporary) name.
if (program_name.substr(0, 3) == "lt-")
Program_Name = program_name.substr(3);
else
Program_Name = program_name;
}
bool
detail::match(const std::string& regexp, const std::string& str)
{
return atf::text::match(str, regexp);
}
// ------------------------------------------------------------------------
// The "tc" class.
// ------------------------------------------------------------------------
static std::map< atf_tc_t*, impl::tc* > wraps;
static std::map< const atf_tc_t*, const impl::tc* > cwraps;
struct impl::tc_impl {
private:
// Non-copyable.
tc_impl(const tc_impl&);
tc_impl& operator=(const tc_impl&);
public:
std::string m_ident;
atf_tc_t m_tc;
bool m_has_cleanup;
tc_impl(const std::string& ident, const bool has_cleanup) :
m_ident(ident),
m_has_cleanup(has_cleanup)
{
}
static void
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();
}
static void
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();
}
static void
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, const bool has_cleanup) :
pimpl(new tc_impl(ident, has_cleanup))
{
}
impl::tc::~tc(void)
{
cwraps.erase(&pimpl->m_tc);
wraps.erase(&pimpl->m_tc);
atf_tc_fini(&pimpl->m_tc);
}
void
impl::tc::init(const vars_map& config)
{
atf_error_t err;
auto_array< const char * > array(new const char*[(config.size() * 2) + 1]);
const char **ptr = array.get();
for (vars_map::const_iterator iter = config.begin();
iter != config.end(); iter++) {
*ptr = (*iter).first.c_str();
*(ptr + 1) = (*iter).second.c_str();
ptr += 2;
}
*ptr = NULL;
wraps[&pimpl->m_tc] = this;
cwraps[&pimpl->m_tc] = this;
err = atf_tc_init(&pimpl->m_tc, pimpl->m_ident.c_str(), pimpl->wrap_head,
pimpl->wrap_body, pimpl->m_has_cleanup ? pimpl->wrap_cleanup : NULL,
array.get());
if (atf_is_error(err))
throw_atf_error(err);
}
bool
impl::tc::has_config_var(const std::string& var)
const
{
return atf_tc_has_config_var(&pimpl->m_tc, var.c_str());
}
bool
impl::tc::has_md_var(const std::string& var)
const
{
return atf_tc_has_md_var(&pimpl->m_tc, var.c_str());
}
const std::string
impl::tc::get_config_var(const std::string& var)
const
{
return atf_tc_get_config_var(&pimpl->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(&pimpl->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(&pimpl->m_tc, var.c_str());
}
const impl::vars_map
impl::tc::get_md_vars(void)
const
{
vars_map vars;
char **array = atf_tc_get_md_vars(&pimpl->m_tc);
try {
char **ptr;
for (ptr = array; *ptr != NULL; ptr += 2)
vars[*ptr] = *(ptr + 1);
} catch (...) {
atf_utils_free_charpp(array);
throw;
}
return vars;
}
void
impl::tc::set_md_var(const std::string& var, const std::string& val)
{
atf_error_t err = atf_tc_set_md_var(&pimpl->m_tc, var.c_str(), val.c_str());
if (atf_is_error(err))
throw_atf_error(err);
}
void
impl::tc::run(const std::string& resfile)
const
{
atf_error_t err = atf_tc_run(&pimpl->m_tc, resfile.c_str());
if (atf_is_error(err))
throw_atf_error(err);
}
void
impl::tc::run_cleanup(void)
const
{
atf_error_t err = atf_tc_cleanup(&pimpl->m_tc);
if (atf_is_error(err))
throw_atf_error(err);
}
void
impl::tc::head(void)
{
}
void
impl::tc::cleanup(void)
const
{
}
void
impl::tc::require_prog(const std::string& prog)
const
{
atf_tc_require_prog(prog.c_str());
}
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::fail_nonfatal(const std::string& reason)
{
atf_tc_fail_nonfatal("%s", reason.c_str());
}
void
impl::tc::skip(const std::string& reason)
{
atf_tc_skip("%s", reason.c_str());
}
void
impl::tc::check_errno(const char* file, const int line, const int exp_errno,
const char* expr_str, const bool result)
{
atf_tc_check_errno(file, line, exp_errno, expr_str, result);
}
void
impl::tc::require_errno(const char* file, const int line, const int exp_errno,
const char* expr_str, const bool result)
{
atf_tc_require_errno(file, line, exp_errno, expr_str, result);
}
void
impl::tc::expect_pass(void)
{
atf_tc_expect_pass();
}
void
impl::tc::expect_fail(const std::string& reason)
{
atf_tc_expect_fail("%s", reason.c_str());
}
void
impl::tc::expect_exit(const int exitcode, const std::string& reason)
{
atf_tc_expect_exit(exitcode, "%s", reason.c_str());
}
void
impl::tc::expect_signal(const int signo, const std::string& reason)
{
atf_tc_expect_signal(signo, "%s", reason.c_str());
}
void
impl::tc::expect_death(const std::string& reason)
{
atf_tc_expect_death("%s", reason.c_str());
}
void
impl::tc::expect_timeout(const std::string& reason)
{
atf_tc_expect_timeout("%s", reason.c_str());
}
// ------------------------------------------------------------------------
// Test program main code.
// ------------------------------------------------------------------------
namespace {
typedef std::vector< impl::tc * > tc_vector;
enum tc_part { BODY, CLEANUP };
static void
parse_vflag(const std::string& str, atf::tests::vars_map& vars)
{
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] == '=') {
vars[ws[0]] = "";
} else {
if (ws.size() != 2)
throw std::runtime_error("-v requires an argument of the form "
"var=value");
vars[ws[0]] = ws[1];
}
}
static atf::fs::path
handle_srcdir(const char* argv0, const std::string& srcdir_arg)
{
atf::fs::path srcdir(".");
if (srcdir_arg.empty()) {
srcdir = atf::fs::path(argv0).branch_path();
if (srcdir.leaf_name() == ".libs")
srcdir = srcdir.branch_path();
} else
srcdir = atf::fs::path(srcdir_arg);
if (!atf::fs::exists(srcdir / Program_Name))
throw usage_error("Cannot find the test program in the source "
"directory `%s'", srcdir.c_str());
if (!srcdir.is_absolute())
srcdir = srcdir.to_absolute();
return srcdir;
}
static void
init_tcs(void (*add_tcs)(tc_vector&), tc_vector& tcs,
const atf::tests::vars_map& vars)
{
add_tcs(tcs);
for (tc_vector::iterator iter = tcs.begin(); iter != tcs.end(); iter++) {
impl::tc* tc = *iter;
tc->init(vars);
}
}
static int
list_tcs(const tc_vector& tcs)
{
detail::atf_tp_writer writer(std::cout);
for (tc_vector::const_iterator iter = tcs.begin();
iter != tcs.end(); iter++) {
const impl::vars_map vars = (*iter)->get_md_vars();
{
impl::vars_map::const_iterator iter2 = vars.find("ident");
INV(iter2 != vars.end());
writer.start_tc((*iter2).second);
}
for (impl::vars_map::const_iterator iter2 = vars.begin();
iter2 != vars.end(); iter2++) {
const std::string& key = (*iter2).first;
if (key != "ident")
writer.tc_meta_data(key, (*iter2).second);
}
writer.end_tc();
}
return EXIT_SUCCESS;
}
static impl::tc*
find_tc(tc_vector tcs, const std::string& name)
{
std::vector< std::string > ids;
for (tc_vector::iterator iter = tcs.begin();
iter != tcs.end(); iter++) {
impl::tc* tc = *iter;
if (tc->get_md_var("ident") == name)
return tc;
}
throw usage_error("Unknown test case `%s'", name.c_str());
}
static std::pair< std::string, tc_part >
process_tcarg(const std::string& tcarg)
{
const std::string::size_type pos = tcarg.find(':');
if (pos == std::string::npos) {
return std::make_pair(tcarg, BODY);
} else {
const std::string tcname = tcarg.substr(0, pos);
const std::string partname = tcarg.substr(pos + 1);
if (partname == "body")
return std::make_pair(tcname, BODY);
else if (partname == "cleanup")
return std::make_pair(tcname, CLEANUP);
else {
throw usage_error("Invalid test case part `%s'", partname.c_str());
}
}
}
static int
run_tc(tc_vector& tcs, const std::string& tcarg, const atf::fs::path& resfile)
{
const std::pair< std::string, tc_part > fields = process_tcarg(tcarg);
impl::tc* tc = find_tc(tcs, fields.first);
if (!atf::env::has("__RUNNING_INSIDE_ATF_RUN") || atf::env::get(
"__RUNNING_INSIDE_ATF_RUN") != "internal-yes-value")
{
std::cerr << Program_Name << ": WARNING: Running test cases outside "
"of kyua(1) is unsupported\n";
std::cerr << Program_Name << ": WARNING: No isolation nor timeout "
"control is being applied; you may get unexpected failures; see "
"atf-test-case(4)\n";
}
switch (fields.second) {
case BODY:
tc->run(resfile.str());
break;
case CLEANUP:
tc->run_cleanup();
break;
default:
UNREACHABLE;
}
return EXIT_SUCCESS;
}
static int
safe_main(int argc, char** argv, void (*add_tcs)(tc_vector&))
{
const char* argv0 = argv[0];
bool lflag = false;
atf::fs::path resfile("/dev/stdout");
std::string srcdir_arg;
atf::tests::vars_map vars;
int ch;
int old_opterr;
old_opterr = opterr;
::opterr = 0;
while ((ch = ::getopt(argc, argv, GETOPT_POSIX ":lr:s:v:")) != -1) {
switch (ch) {
case 'l':
lflag = true;
break;
case 'r':
resfile = atf::fs::path(::optarg);
break;
case 's':
srcdir_arg = ::optarg;
break;
case 'v':
parse_vflag(::optarg, vars);
break;
case ':':
throw usage_error("Option -%c requires an argument.", ::optopt);
break;
case '?':
default:
throw usage_error("Unknown option -%c.", ::optopt);
}
}
argc -= optind;
argv += optind;
// Clear getopt state just in case the test wants to use it.
::opterr = old_opterr;
::optind = 1;
#if defined(HAVE_OPTRESET)
::optreset = 1;
#endif
vars["srcdir"] = handle_srcdir(argv0, srcdir_arg).str();
int errcode;
tc_vector tcs;
if (lflag) {
if (argc > 0)
throw usage_error("Cannot provide test case names with -l");
init_tcs(add_tcs, tcs, vars);
errcode = list_tcs(tcs);
} else {
if (argc == 0)
throw usage_error("Must provide a test case name");
else if (argc > 1)
throw usage_error("Cannot provide more than one test case name");
INV(argc == 1);
init_tcs(add_tcs, tcs, vars);
errcode = run_tc(tcs, argv[0], resfile);
}
for (tc_vector::iterator iter = tcs.begin(); iter != tcs.end(); iter++) {
impl::tc* tc = *iter;
delete tc;
}
return errcode;
}
} // anonymous namespace
namespace atf {
namespace tests {
int run_tp(int, char**, void (*)(tc_vector&));
}
}
int
impl::run_tp(int argc, char** argv, void (*add_tcs)(tc_vector&))
{
try {
set_program_name(argv[0]);
return ::safe_main(argc, argv, add_tcs);
} catch (const usage_error& e) {
std::cerr
<< Program_Name << ": ERROR: " << e.what() << '\n'
<< Program_Name << ": See atf-test-program(1) for usage details.\n";
return EXIT_FAILURE;
}
}

View file

@ -1,125 +0,0 @@
// Copyright (c) 2007 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#if !defined(ATF_CXX_TESTS_HPP)
#define ATF_CXX_TESTS_HPP
#include <map>
#include <memory>
#include <string>
extern "C" {
#include <atf-c/defs.h>
}
namespace atf {
namespace tests {
namespace detail {
class atf_tp_writer {
std::ostream& m_os;
bool m_is_first;
public:
atf_tp_writer(std::ostream&);
void start_tc(const std::string&);
void end_tc(void);
void tc_meta_data(const std::string&, const std::string&);
};
bool match(const std::string&, const std::string&);
} // namespace
// ------------------------------------------------------------------------
// The "vars_map" class.
// ------------------------------------------------------------------------
typedef std::map< std::string, std::string > vars_map;
// ------------------------------------------------------------------------
// The "tc" class.
// ------------------------------------------------------------------------
struct tc_impl;
class tc {
// Non-copyable.
tc(const tc&);
tc& operator=(const tc&);
std::auto_ptr< tc_impl > pimpl;
protected:
virtual void head(void);
virtual void body(void) const = 0;
virtual void cleanup(void) const;
void require_prog(const std::string&) const;
friend struct tc_impl;
public:
tc(const std::string&, const bool);
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;
const vars_map get_md_vars(void) 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&);
void run(const std::string&) const;
void run_cleanup(void) const;
// To be called from the child process only.
static void pass(void) ATF_DEFS_ATTRIBUTE_NORETURN;
static void fail(const std::string&) ATF_DEFS_ATTRIBUTE_NORETURN;
static void fail_nonfatal(const std::string&);
static void skip(const std::string&) ATF_DEFS_ATTRIBUTE_NORETURN;
static void check_errno(const char*, const int, const int, const char*,
const bool);
static void require_errno(const char*, const int, const int, const char*,
const bool);
static void expect_pass(void);
static void expect_fail(const std::string&);
static void expect_exit(const int, const std::string&);
static void expect_signal(const int, const std::string&);
static void expect_death(const std::string&);
static void expect_timeout(const std::string&);
};
} // namespace tests
} // namespace atf
#endif // !defined(ATF_CXX_TESTS_HPP)

View file

@ -1,190 +0,0 @@
// Copyright (c) 2007 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "atf-c++/tests.hpp"
extern "C" {
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
}
#include <fstream>
#include <iostream>
#include <sstream>
#include <atf-c++.hpp>
#include "atf-c++/detail/text.hpp"
// ------------------------------------------------------------------------
// Tests for the "atf_tp_writer" class.
// ------------------------------------------------------------------------
static
void
print_indented(const std::string& str)
{
std::vector< std::string > ws = atf::text::split(str, "\n");
for (std::vector< std::string >::const_iterator iter = ws.begin();
iter != ws.end(); iter++)
std::cout << ">>" << *iter << "<<\n";
}
// XXX Should this string handling and verbosity level be part of the
// ATF_REQUIRE_EQ macro? It may be hard to predict sometimes that a
// string can have newlines in it, and so the error message generated
// at the moment will be bogus if there are some.
static
void
check_equal(const atf::tests::tc& tc, const std::string& str,
const std::string& exp)
{
if (str != exp) {
std::cout << "String equality check failed.\n"
"Adding >> and << to delimit the string boundaries below.\n";
std::cout << "GOT:\n";
print_indented(str);
std::cout << "EXPECTED:\n";
print_indented(exp);
tc.fail("Constructed string differs from the expected one");
}
}
ATF_TEST_CASE(atf_tp_writer);
ATF_TEST_CASE_HEAD(atf_tp_writer)
{
set_md_var("descr", "Verifies the application/X-atf-tp writer");
}
ATF_TEST_CASE_BODY(atf_tp_writer)
{
std::ostringstream expss;
std::ostringstream ss;
#define RESET \
expss.str(""); \
ss.str("")
#define CHECK \
check_equal(*this, ss.str(), expss.str())
{
RESET;
atf::tests::detail::atf_tp_writer w(ss);
expss << "Content-Type: application/X-atf-tp; version=\"1\"\n\n";
CHECK;
}
{
RESET;
atf::tests::detail::atf_tp_writer w(ss);
expss << "Content-Type: application/X-atf-tp; version=\"1\"\n\n";
CHECK;
w.start_tc("test1");
expss << "ident: test1\n";
CHECK;
w.end_tc();
CHECK;
}
{
RESET;
atf::tests::detail::atf_tp_writer w(ss);
expss << "Content-Type: application/X-atf-tp; version=\"1\"\n\n";
CHECK;
w.start_tc("test1");
expss << "ident: test1\n";
CHECK;
w.end_tc();
CHECK;
w.start_tc("test2");
expss << "\nident: test2\n";
CHECK;
w.end_tc();
CHECK;
}
{
RESET;
atf::tests::detail::atf_tp_writer w(ss);
expss << "Content-Type: application/X-atf-tp; version=\"1\"\n\n";
CHECK;
w.start_tc("test1");
expss << "ident: test1\n";
CHECK;
w.tc_meta_data("descr", "the description");
expss << "descr: the description\n";
CHECK;
w.end_tc();
CHECK;
w.start_tc("test2");
expss << "\nident: test2\n";
CHECK;
w.tc_meta_data("descr", "second test case");
expss << "descr: second test case\n";
CHECK;
w.tc_meta_data("require.progs", "/bin/cp");
expss << "require.progs: /bin/cp\n";
CHECK;
w.tc_meta_data("X-custom", "foo bar baz");
expss << "X-custom: foo bar baz\n";
CHECK;
w.end_tc();
CHECK;
}
#undef CHECK
#undef RESET
}
// ------------------------------------------------------------------------
// Main.
// ------------------------------------------------------------------------
ATF_INIT_TEST_CASES(tcs)
{
// Add tests for the "atf_tp_writer" class.
ATF_ADD_TEST_CASE(tcs, atf_tp_writer);
}

View file

@ -1,48 +0,0 @@
// Copyright (c) 2012 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++.hpp>
ATF_TEST_CASE(this_is_used);
ATF_TEST_CASE_HEAD(this_is_used)
{
}
ATF_TEST_CASE_BODY(this_is_used)
{
}
ATF_TEST_CASE(this_is_unused);
ATF_TEST_CASE_HEAD(this_is_unused)
{
}
ATF_TEST_CASE_BODY(this_is_unused)
{
}
ATF_INIT_TEST_CASES(tcs)
{
ATF_ADD_TEST_CASE(tcs, this_is_used);
//ATF_ADD_TEST_CASE(tcs, this_is_unused);
}

View file

@ -1,100 +0,0 @@
// Copyright (c) 2007 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "atf-c++/utils.hpp"
extern "C" {
#include "atf-c/utils.h"
}
#include <cstdlib>
#include <iostream>
void
atf::utils::cat_file(const std::string& path, const std::string& prefix)
{
atf_utils_cat_file(path.c_str(), prefix.c_str());
}
void
atf::utils::copy_file(const std::string& source, const std::string& destination)
{
atf_utils_copy_file(source.c_str(), destination.c_str());
}
bool
atf::utils::compare_file(const std::string& path, const std::string& contents)
{
return atf_utils_compare_file(path.c_str(), contents.c_str());
}
void
atf::utils::create_file(const std::string& path, const std::string& contents)
{
atf_utils_create_file(path.c_str(), "%s", contents.c_str());
}
bool
atf::utils::file_exists(const std::string& path)
{
return atf_utils_file_exists(path.c_str());
}
pid_t
atf::utils::fork(void)
{
std::cout.flush();
std::cerr.flush();
return atf_utils_fork();
}
bool
atf::utils::grep_file(const std::string& regex, const std::string& path)
{
return atf_utils_grep_file("%s", path.c_str(), regex.c_str());
}
bool
atf::utils::grep_string(const std::string& regex, const std::string& str)
{
return atf_utils_grep_string("%s", str.c_str(), regex.c_str());
}
void
atf::utils::redirect(const int fd, const std::string& path)
{
if (fd == STDOUT_FILENO)
std::cout.flush();
else if (fd == STDERR_FILENO)
std::cerr.flush();
atf_utils_redirect(fd, path.c_str());
}
void
atf::utils::wait(const pid_t pid, const int exitstatus,
const std::string& expout, const std::string& experr)
{
atf_utils_wait(pid, exitstatus, expout.c_str(), experr.c_str());
}

View file

@ -1,64 +0,0 @@
// Copyright (c) 2007 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#if !defined(ATF_CXX_UTILS_HPP)
#define ATF_CXX_UTILS_HPP
extern "C" {
#include <unistd.h>
}
#include <string>
namespace atf {
namespace utils {
void cat_file(const std::string&, const std::string&);
bool compare_file(const std::string&, const std::string&);
void copy_file(const std::string&, const std::string&);
void create_file(const std::string&, const std::string&);
bool file_exists(const std::string&);
pid_t fork(void);
bool grep_file(const std::string&, const std::string&);
bool grep_string(const std::string&, const std::string&);
void redirect(const int, const std::string&);
void wait(const pid_t, const int, const std::string&, const std::string&);
template< typename Collection >
bool
grep_collection(const std::string& regexp, const Collection& collection)
{
for (typename Collection::const_iterator iter = collection.begin();
iter != collection.end(); ++iter) {
if (grep_string(regexp, *iter))
return true;
}
return false;
}
} // namespace utils
} // namespace atf
#endif // !defined(ATF_CXX_UTILS_HPP)

View file

@ -1,509 +0,0 @@
// Copyright (c) 2007 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "atf-c++/utils.hpp"
extern "C" {
#include <sys/stat.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <unistd.h>
}
#include <cstdlib>
#include <iostream>
#include <set>
#include <sstream>
#include <string>
#include <vector>
#include <atf-c++.hpp>
static std::string
read_file(const std::string& path)
{
char buffer[1024];
const int fd = open(path.c_str(), O_RDONLY);
if (fd == -1)
ATF_FAIL("Cannot open " + path);
const ssize_t length = read(fd, buffer, sizeof(buffer) - 1);
close(fd);
ATF_REQUIRE(length != -1);
if (length == sizeof(buffer) - 1)
ATF_FAIL("Internal buffer not long enough to read temporary file");
((char *)buffer)[length] = '\0';
return buffer;
}
// ------------------------------------------------------------------------
// Tests cases for the free functions.
// ------------------------------------------------------------------------
ATF_TEST_CASE_WITHOUT_HEAD(cat_file__empty);
ATF_TEST_CASE_BODY(cat_file__empty)
{
atf::utils::create_file("file.txt", "");
atf::utils::redirect(STDOUT_FILENO, "captured.txt");
atf::utils::cat_file("file.txt", "PREFIX");
std::cout.flush();
close(STDOUT_FILENO);
ATF_REQUIRE_EQ("", read_file("captured.txt"));
}
ATF_TEST_CASE_WITHOUT_HEAD(cat_file__one_line);
ATF_TEST_CASE_BODY(cat_file__one_line)
{
atf::utils::create_file("file.txt", "This is a single line\n");
atf::utils::redirect(STDOUT_FILENO, "captured.txt");
atf::utils::cat_file("file.txt", "PREFIX");
std::cout.flush();
close(STDOUT_FILENO);
ATF_REQUIRE_EQ("PREFIXThis is a single line\n", read_file("captured.txt"));
}
ATF_TEST_CASE_WITHOUT_HEAD(cat_file__several_lines);
ATF_TEST_CASE_BODY(cat_file__several_lines)
{
atf::utils::create_file("file.txt", "First\nSecond line\nAnd third\n");
atf::utils::redirect(STDOUT_FILENO, "captured.txt");
atf::utils::cat_file("file.txt", ">");
std::cout.flush();
close(STDOUT_FILENO);
ATF_REQUIRE_EQ(">First\n>Second line\n>And third\n",
read_file("captured.txt"));
}
ATF_TEST_CASE_WITHOUT_HEAD(cat_file__no_newline_eof);
ATF_TEST_CASE_BODY(cat_file__no_newline_eof)
{
atf::utils::create_file("file.txt", "Foo\n bar baz");
atf::utils::redirect(STDOUT_FILENO, "captured.txt");
atf::utils::cat_file("file.txt", "PREFIX");
std::cout.flush();
close(STDOUT_FILENO);
ATF_REQUIRE_EQ("PREFIXFoo\nPREFIX bar baz", read_file("captured.txt"));
}
ATF_TEST_CASE_WITHOUT_HEAD(compare_file__empty__match);
ATF_TEST_CASE_BODY(compare_file__empty__match)
{
atf::utils::create_file("test.txt", "");
ATF_REQUIRE(atf::utils::compare_file("test.txt", ""));
}
ATF_TEST_CASE_WITHOUT_HEAD(compare_file__empty__not_match);
ATF_TEST_CASE_BODY(compare_file__empty__not_match)
{
atf::utils::create_file("test.txt", "");
ATF_REQUIRE(!atf::utils::compare_file("test.txt", "\n"));
ATF_REQUIRE(!atf::utils::compare_file("test.txt", "foo"));
ATF_REQUIRE(!atf::utils::compare_file("test.txt", " "));
}
ATF_TEST_CASE_WITHOUT_HEAD(compare_file__short__match);
ATF_TEST_CASE_BODY(compare_file__short__match)
{
atf::utils::create_file("test.txt", "this is a short file");
ATF_REQUIRE(atf::utils::compare_file("test.txt", "this is a short file"));
}
ATF_TEST_CASE_WITHOUT_HEAD(compare_file__short__not_match);
ATF_TEST_CASE_BODY(compare_file__short__not_match)
{
atf::utils::create_file("test.txt", "this is a short file");
ATF_REQUIRE(!atf::utils::compare_file("test.txt", ""));
ATF_REQUIRE(!atf::utils::compare_file("test.txt", "\n"));
ATF_REQUIRE(!atf::utils::compare_file("test.txt", "this is a Short file"));
ATF_REQUIRE(!atf::utils::compare_file("test.txt", "this is a short fil"));
ATF_REQUIRE(!atf::utils::compare_file("test.txt", "this is a short file "));
}
ATF_TEST_CASE_WITHOUT_HEAD(compare_file__long__match);
ATF_TEST_CASE_BODY(compare_file__long__match)
{
char long_contents[3456];
size_t i = 0;
for (; i < sizeof(long_contents) - 1; i++)
long_contents[i] = '0' + (i % 10);
long_contents[i] = '\0';
atf::utils::create_file("test.txt", long_contents);
ATF_REQUIRE(atf::utils::compare_file("test.txt", long_contents));
}
ATF_TEST_CASE_WITHOUT_HEAD(compare_file__long__not_match);
ATF_TEST_CASE_BODY(compare_file__long__not_match)
{
char long_contents[3456];
size_t i = 0;
for (; i < sizeof(long_contents) - 1; i++)
long_contents[i] = '0' + (i % 10);
long_contents[i] = '\0';
atf::utils::create_file("test.txt", long_contents);
ATF_REQUIRE(!atf::utils::compare_file("test.txt", ""));
ATF_REQUIRE(!atf::utils::compare_file("test.txt", "\n"));
ATF_REQUIRE(!atf::utils::compare_file("test.txt", "0123456789"));
long_contents[i - 1] = 'Z';
ATF_REQUIRE(!atf::utils::compare_file("test.txt", long_contents));
}
ATF_TEST_CASE_WITHOUT_HEAD(copy_file__empty);
ATF_TEST_CASE_BODY(copy_file__empty)
{
atf::utils::create_file("src.txt", "");
ATF_REQUIRE(chmod("src.txt", 0520) != -1);
atf::utils::copy_file("src.txt", "dest.txt");
ATF_REQUIRE(atf::utils::compare_file("dest.txt", ""));
struct stat sb;
ATF_REQUIRE(stat("dest.txt", &sb) != -1);
ATF_REQUIRE_EQ(0520, sb.st_mode & 0xfff);
}
ATF_TEST_CASE_WITHOUT_HEAD(copy_file__some_contents);
ATF_TEST_CASE_BODY(copy_file__some_contents)
{
atf::utils::create_file("src.txt", "This is a\ntest file\n");
atf::utils::copy_file("src.txt", "dest.txt");
ATF_REQUIRE(atf::utils::compare_file("dest.txt", "This is a\ntest file\n"));
}
ATF_TEST_CASE_WITHOUT_HEAD(create_file);
ATF_TEST_CASE_BODY(create_file)
{
atf::utils::create_file("test.txt", "This is a %d test");
ATF_REQUIRE_EQ("This is a %d test", read_file("test.txt"));
}
ATF_TEST_CASE_WITHOUT_HEAD(file_exists);
ATF_TEST_CASE_BODY(file_exists)
{
atf::utils::create_file("test.txt", "foo");
ATF_REQUIRE( atf::utils::file_exists("test.txt"));
ATF_REQUIRE( atf::utils::file_exists("./test.txt"));
ATF_REQUIRE(!atf::utils::file_exists("./test.tx"));
ATF_REQUIRE(!atf::utils::file_exists("test.txt2"));
}
ATF_TEST_CASE_WITHOUT_HEAD(fork);
ATF_TEST_CASE_BODY(fork)
{
std::cout << "Should not get into child\n";
std::cerr << "Should not get into child\n";
pid_t pid = atf::utils::fork();
if (pid == 0) {
std::cout << "Child stdout\n";
std::cerr << "Child stderr\n";
exit(EXIT_SUCCESS);
}
int status;
ATF_REQUIRE(waitpid(pid, &status, 0) != -1);
ATF_REQUIRE(WIFEXITED(status));
ATF_REQUIRE_EQ(EXIT_SUCCESS, WEXITSTATUS(status));
std::ostringstream out_name;
out_name << "atf_utils_fork_" << pid << "_out.txt";
std::ostringstream err_name;
err_name << "atf_utils_fork_" << pid << "_err.txt";
ATF_REQUIRE_EQ("Child stdout\n", read_file(out_name.str()));
ATF_REQUIRE_EQ("Child stderr\n", read_file(err_name.str()));
}
ATF_TEST_CASE_WITHOUT_HEAD(grep_collection__set);
ATF_TEST_CASE_BODY(grep_collection__set)
{
std::set< std::string > strings;
strings.insert("First");
strings.insert("Second");
ATF_REQUIRE( atf::utils::grep_collection("irs", strings));
ATF_REQUIRE( atf::utils::grep_collection("cond", strings));
ATF_REQUIRE(!atf::utils::grep_collection("Third", strings));
}
ATF_TEST_CASE_WITHOUT_HEAD(grep_collection__vector);
ATF_TEST_CASE_BODY(grep_collection__vector)
{
std::vector< std::string > strings;
strings.push_back("First");
strings.push_back("Second");
ATF_REQUIRE( atf::utils::grep_collection("irs", strings));
ATF_REQUIRE( atf::utils::grep_collection("cond", strings));
ATF_REQUIRE(!atf::utils::grep_collection("Third", strings));
}
ATF_TEST_CASE_WITHOUT_HEAD(grep_file);
ATF_TEST_CASE_BODY(grep_file)
{
atf::utils::create_file("test.txt", "line1\nthe second line\naaaabbbb\n");
ATF_REQUIRE(atf::utils::grep_file("line1", "test.txt"));
ATF_REQUIRE(atf::utils::grep_file("second line", "test.txt"));
ATF_REQUIRE(atf::utils::grep_file("aa.*bb", "test.txt"));
ATF_REQUIRE(!atf::utils::grep_file("foo", "test.txt"));
ATF_REQUIRE(!atf::utils::grep_file("bar", "test.txt"));
ATF_REQUIRE(!atf::utils::grep_file("aaaaa", "test.txt"));
}
ATF_TEST_CASE_WITHOUT_HEAD(grep_string);
ATF_TEST_CASE_BODY(grep_string)
{
const char *str = "a string - aaaabbbb";
ATF_REQUIRE(atf::utils::grep_string("a string", str));
ATF_REQUIRE(atf::utils::grep_string("^a string", str));
ATF_REQUIRE(atf::utils::grep_string("aaaabbbb$", str));
ATF_REQUIRE(atf::utils::grep_string("aa.*bb", str));
ATF_REQUIRE(!atf::utils::grep_string("foo", str));
ATF_REQUIRE(!atf::utils::grep_string("bar", str));
ATF_REQUIRE(!atf::utils::grep_string("aaaaa", str));
}
ATF_TEST_CASE_WITHOUT_HEAD(redirect__stdout);
ATF_TEST_CASE_BODY(redirect__stdout)
{
std::cout << "Buffer this";
atf::utils::redirect(STDOUT_FILENO, "captured.txt");
std::cout << "The printed message";
std::cout.flush();
ATF_REQUIRE_EQ("The printed message", read_file("captured.txt"));
}
ATF_TEST_CASE_WITHOUT_HEAD(redirect__stderr);
ATF_TEST_CASE_BODY(redirect__stderr)
{
std::cerr << "Buffer this";
atf::utils::redirect(STDERR_FILENO, "captured.txt");
std::cerr << "The printed message";
std::cerr.flush();
ATF_REQUIRE_EQ("The printed message", read_file("captured.txt"));
}
ATF_TEST_CASE_WITHOUT_HEAD(redirect__other);
ATF_TEST_CASE_BODY(redirect__other)
{
const std::string message = "Foo bar\nbaz\n";
atf::utils::redirect(15, "captured.txt");
ATF_REQUIRE(write(15, message.c_str(), message.length()) != -1);
close(15);
ATF_REQUIRE_EQ(message, read_file("captured.txt"));
}
static void
fork_and_wait(const int exitstatus, const char* expout, const char* experr)
{
const pid_t pid = atf::utils::fork();
if (pid == 0) {
std::cout << "Some output\n";
std::cerr << "Some error\n";
exit(123);
}
atf::utils::wait(pid, exitstatus, expout, experr);
exit(EXIT_SUCCESS);
}
ATF_TEST_CASE_WITHOUT_HEAD(wait__ok);
ATF_TEST_CASE_BODY(wait__ok)
{
const pid_t control = fork();
ATF_REQUIRE(control != -1);
if (control == 0)
fork_and_wait(123, "Some output\n", "Some error\n");
else {
int status;
ATF_REQUIRE(waitpid(control, &status, 0) != -1);
ATF_REQUIRE(WIFEXITED(status));
ATF_REQUIRE_EQ(EXIT_SUCCESS, WEXITSTATUS(status));
}
}
ATF_TEST_CASE_WITHOUT_HEAD(wait__ok_nested);
ATF_TEST_CASE_BODY(wait__ok_nested)
{
const pid_t parent = atf::utils::fork();
ATF_REQUIRE(parent != -1);
if (parent == 0) {
const pid_t child = atf::utils::fork();
ATF_REQUIRE(child != -1);
if (child == 0) {
std::cerr.flush();
std::cout << "Child output\n";
std::cout.flush();
std::cerr << "Child error\n";
std::exit(50);
} else {
std::cout << "Parent output\n";
std::cerr << "Parent error\n";
atf::utils::wait(child, 50, "Child output\n", "Child error\n");
std::exit(40);
}
} else {
atf::utils::wait(parent, 40,
"Parent output\n"
"subprocess stdout: Child output\n"
"subprocess stderr: Child error\n",
"Parent error\n");
}
}
ATF_TEST_CASE_WITHOUT_HEAD(wait__invalid_exitstatus);
ATF_TEST_CASE_BODY(wait__invalid_exitstatus)
{
const pid_t control = fork();
ATF_REQUIRE(control != -1);
if (control == 0)
fork_and_wait(120, "Some output\n", "Some error\n");
else {
int status;
ATF_REQUIRE(waitpid(control, &status, 0) != -1);
ATF_REQUIRE(WIFEXITED(status));
ATF_REQUIRE_EQ(EXIT_FAILURE, WEXITSTATUS(status));
}
}
ATF_TEST_CASE_WITHOUT_HEAD(wait__invalid_stdout);
ATF_TEST_CASE_BODY(wait__invalid_stdout)
{
const pid_t control = fork();
ATF_REQUIRE(control != -1);
if (control == 0)
fork_and_wait(123, "Some output foo\n", "Some error\n");
else {
int status;
ATF_REQUIRE(waitpid(control, &status, 0) != -1);
ATF_REQUIRE(WIFEXITED(status));
ATF_REQUIRE_EQ(EXIT_FAILURE, WEXITSTATUS(status));
}
}
ATF_TEST_CASE_WITHOUT_HEAD(wait__invalid_stderr);
ATF_TEST_CASE_BODY(wait__invalid_stderr)
{
const pid_t control = fork();
ATF_REQUIRE(control != -1);
if (control == 0)
fork_and_wait(123, "Some output\n", "Some error foo\n");
else {
int status;
ATF_REQUIRE(waitpid(control, &status, 0) != -1);
ATF_REQUIRE(WIFEXITED(status));
ATF_REQUIRE_EQ(EXIT_FAILURE, WEXITSTATUS(status));
}
}
ATF_TEST_CASE_WITHOUT_HEAD(wait__save_stdout);
ATF_TEST_CASE_BODY(wait__save_stdout)
{
const pid_t control = fork();
ATF_REQUIRE(control != -1);
if (control == 0)
fork_and_wait(123, "save:my-output.txt", "Some error\n");
else {
int status;
ATF_REQUIRE(waitpid(control, &status, 0) != -1);
ATF_REQUIRE(WIFEXITED(status));
ATF_REQUIRE_EQ(EXIT_SUCCESS, WEXITSTATUS(status));
ATF_REQUIRE(atf::utils::compare_file("my-output.txt", "Some output\n"));
}
}
ATF_TEST_CASE_WITHOUT_HEAD(wait__save_stderr);
ATF_TEST_CASE_BODY(wait__save_stderr)
{
const pid_t control = fork();
ATF_REQUIRE(control != -1);
if (control == 0)
fork_and_wait(123, "Some output\n", "save:my-output.txt");
else {
int status;
ATF_REQUIRE(waitpid(control, &status, 0) != -1);
ATF_REQUIRE(WIFEXITED(status));
ATF_REQUIRE_EQ(EXIT_SUCCESS, WEXITSTATUS(status));
ATF_REQUIRE(atf::utils::compare_file("my-output.txt", "Some error\n"));
}
}
// ------------------------------------------------------------------------
// Main.
// ------------------------------------------------------------------------
ATF_INIT_TEST_CASES(tcs)
{
// Add the test for the free functions.
ATF_ADD_TEST_CASE(tcs, cat_file__empty);
ATF_ADD_TEST_CASE(tcs, cat_file__one_line);
ATF_ADD_TEST_CASE(tcs, cat_file__several_lines);
ATF_ADD_TEST_CASE(tcs, cat_file__no_newline_eof);
ATF_ADD_TEST_CASE(tcs, compare_file__empty__match);
ATF_ADD_TEST_CASE(tcs, compare_file__empty__not_match);
ATF_ADD_TEST_CASE(tcs, compare_file__short__match);
ATF_ADD_TEST_CASE(tcs, compare_file__short__not_match);
ATF_ADD_TEST_CASE(tcs, compare_file__long__match);
ATF_ADD_TEST_CASE(tcs, compare_file__long__not_match);
ATF_ADD_TEST_CASE(tcs, copy_file__empty);
ATF_ADD_TEST_CASE(tcs, copy_file__some_contents);
ATF_ADD_TEST_CASE(tcs, create_file);
ATF_ADD_TEST_CASE(tcs, file_exists);
ATF_ADD_TEST_CASE(tcs, fork);
ATF_ADD_TEST_CASE(tcs, grep_collection__set);
ATF_ADD_TEST_CASE(tcs, grep_collection__vector);
ATF_ADD_TEST_CASE(tcs, grep_file);
ATF_ADD_TEST_CASE(tcs, grep_string);
ATF_ADD_TEST_CASE(tcs, redirect__stdout);
ATF_ADD_TEST_CASE(tcs, redirect__stderr);
ATF_ADD_TEST_CASE(tcs, redirect__other);
ATF_ADD_TEST_CASE(tcs, wait__ok);
ATF_ADD_TEST_CASE(tcs, wait__ok_nested);
ATF_ADD_TEST_CASE(tcs, wait__invalid_exitstatus);
ATF_ADD_TEST_CASE(tcs, wait__invalid_stdout);
ATF_ADD_TEST_CASE(tcs, wait__invalid_stderr);
ATF_ADD_TEST_CASE(tcs, wait__save_stdout);
ATF_ADD_TEST_CASE(tcs, wait__save_stderr);
}

View file

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

View file

@ -1,15 +0,0 @@
Content-Type: application/X-atf-atffile; version="1"
prop: test-suite = atf
tp: detail
tp: atf_c_test
tp: build_test
tp: check_test
tp: error_test
tp: macros_test
tp: pkg_config_test
tp: tc_test
tp: tp_test
tp: utils_test

View file

@ -1,15 +0,0 @@
syntax("kyuafile", 1)
test_suite("atf")
atf_test_program{name="atf_c_test"}
atf_test_program{name="build_test"}
atf_test_program{name="check_test"}
atf_test_program{name="error_test"}
atf_test_program{name="macros_test"}
atf_test_program{name="pkg_config_test"}
atf_test_program{name="tc_test"}
atf_test_program{name="tp_test"}
atf_test_program{name="utils_test"}
include("detail/Kyuafile")

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