Fuchsia is looking to remove the ZX_WAIT_ASYNC_ONCE constant, and our copy of GoogleTest still has it. As usually with GoogleTest updates, our old local patch is no longer necessary, but now we need a new one. Change-Id: I8d226f01cf0951fd278605688684bf1ce3e17898 Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/44884 Reviewed-by: Adam Langley <agl@google.com> Commit-Queue: David Benjamin <davidben@google.com>chromium-5359
parent
4f75b76ef2
commit
4df05c5235
125 changed files with 5383 additions and 13238 deletions
@ -1,338 +0,0 @@ |
||||
# Automake file
|
||||
|
||||
ACLOCAL_AMFLAGS = -I m4
|
||||
|
||||
# Nonstandard package files for distribution
|
||||
EXTRA_DIST = \
|
||||
CONTRIBUTORS \
|
||||
LICENSE \
|
||||
include/gtest/internal/gtest-type-util.h.pump \
|
||||
make/Makefile \
|
||||
scripts/fuse_gtest_files.py \
|
||||
scripts/gen_gtest_pred_impl.py \
|
||||
scripts/pump.py \
|
||||
scripts/test/Makefile
|
||||
|
||||
# gtest source files that we don't compile directly. They are
|
||||
# #included by gtest-all.cc.
|
||||
GTEST_SRC = \
|
||||
src/gtest-death-test.cc \
|
||||
src/gtest-filepath.cc \
|
||||
src/gtest-internal-inl.h \
|
||||
src/gtest-matchers.cc \
|
||||
src/gtest-port.cc \
|
||||
src/gtest-printers.cc \
|
||||
src/gtest-test-part.cc \
|
||||
src/gtest-typed-test.cc \
|
||||
src/gtest.cc
|
||||
|
||||
EXTRA_DIST += $(GTEST_SRC)
|
||||
|
||||
# Sample files that we don't compile.
|
||||
EXTRA_DIST += \
|
||||
samples/prime_tables.h \
|
||||
samples/sample1_unittest.cc \
|
||||
samples/sample2_unittest.cc \
|
||||
samples/sample3_unittest.cc \
|
||||
samples/sample4_unittest.cc \
|
||||
samples/sample5_unittest.cc \
|
||||
samples/sample6_unittest.cc \
|
||||
samples/sample7_unittest.cc \
|
||||
samples/sample8_unittest.cc \
|
||||
samples/sample9_unittest.cc
|
||||
|
||||
# C++ test files that we don't compile directly.
|
||||
EXTRA_DIST += \
|
||||
test/googletest-death-test_ex_test.cc \
|
||||
test/googletest-death-test-test.cc \
|
||||
test/googletest-filepath-test.cc \
|
||||
test/googletest-listener-test.cc \
|
||||
test/googletest-message-test.cc \
|
||||
test/googletest-options-test.cc \
|
||||
test/googletest-param-test2-test.cc \
|
||||
test/googletest-param-test2-test.cc \
|
||||
test/googletest-param-test-test.cc \
|
||||
test/googletest-param-test-test.cc \
|
||||
test/googletest-param-test-test.h \
|
||||
test/googletest-port-test.cc \
|
||||
test/gtest_premature_exit_test.cc \
|
||||
test/googletest-printers-test.cc \
|
||||
test/googletest-test-part-test.cc \
|
||||
test/gtest-typed-test2_test.cc \
|
||||
test/gtest-typed-test_test.cc \
|
||||
test/gtest-typed-test_test.h \
|
||||
test/gtest-unittest-api_test.cc \
|
||||
test/googletest-break-on-failure-unittest_.cc \
|
||||
test/googletest-catch-exceptions-test_.cc \
|
||||
test/googletest-color-test_.cc \
|
||||
test/googletest-env-var-test_.cc \
|
||||
test/gtest_environment_test.cc \
|
||||
test/googletest-filter-unittest_.cc \
|
||||
test/gtest_help_test_.cc \
|
||||
test/googletest-list-tests-unittest_.cc \
|
||||
test/gtest_main_unittest.cc \
|
||||
test/gtest_no_test_unittest.cc \
|
||||
test/googletest-output-test_.cc \
|
||||
test/gtest_pred_impl_unittest.cc \
|
||||
test/gtest_prod_test.cc \
|
||||
test/gtest_repeat_test.cc \
|
||||
test/googletest-shuffle-test_.cc \
|
||||
test/gtest_sole_header_test.cc \
|
||||
test/gtest_stress_test.cc \
|
||||
test/gtest_throw_on_failure_ex_test.cc \
|
||||
test/googletest-throw-on-failure-test_.cc \
|
||||
test/googletest-uninitialized-test_.cc \
|
||||
test/gtest_unittest.cc \
|
||||
test/gtest_unittest.cc \
|
||||
test/gtest_xml_outfile1_test_.cc \
|
||||
test/gtest_xml_outfile2_test_.cc \
|
||||
test/gtest_xml_output_unittest_.cc \
|
||||
test/production.cc \
|
||||
test/production.h
|
||||
|
||||
# Python tests that we don't run.
|
||||
EXTRA_DIST += \
|
||||
test/googletest-break-on-failure-unittest.py \
|
||||
test/googletest-catch-exceptions-test.py \
|
||||
test/googletest-color-test.py \
|
||||
test/googletest-env-var-test.py \
|
||||
test/googletest-filter-unittest.py \
|
||||
test/gtest_help_test.py \
|
||||
test/googletest-list-tests-unittest.py \
|
||||
test/googletest-output-test.py \
|
||||
test/googletest-output-test-golden-lin.txt \
|
||||
test/googletest-shuffle-test.py \
|
||||
test/gtest_test_utils.py \
|
||||
test/googletest-throw-on-failure-test.py \
|
||||
test/googletest-uninitialized-test.py \
|
||||
test/gtest_xml_outfiles_test.py \
|
||||
test/gtest_xml_output_unittest.py \
|
||||
test/gtest_xml_test_utils.py
|
||||
|
||||
# CMake script
|
||||
EXTRA_DIST += \
|
||||
CMakeLists.txt \
|
||||
cmake/internal_utils.cmake
|
||||
|
||||
# MSVC project files
|
||||
EXTRA_DIST += \
|
||||
msvc/2010/gtest-md.sln \
|
||||
msvc/2010/gtest-md.vcxproj \
|
||||
msvc/2010/gtest.sln \
|
||||
msvc/2010/gtest.vcxproj \
|
||||
msvc/2010/gtest_main-md.vcxproj \
|
||||
msvc/2010/gtest_main.vcxproj \
|
||||
msvc/2010/gtest_prod_test-md.vcxproj \
|
||||
msvc/2010/gtest_prod_test.vcxproj \
|
||||
msvc/2010/gtest_unittest-md.vcxproj \
|
||||
msvc/2010/gtest_unittest.vcxproj
|
||||
|
||||
# xcode project files
|
||||
EXTRA_DIST += \
|
||||
xcode/Config/DebugProject.xcconfig \
|
||||
xcode/Config/FrameworkTarget.xcconfig \
|
||||
xcode/Config/General.xcconfig \
|
||||
xcode/Config/ReleaseProject.xcconfig \
|
||||
xcode/Config/StaticLibraryTarget.xcconfig \
|
||||
xcode/Config/TestTarget.xcconfig \
|
||||
xcode/Resources/Info.plist \
|
||||
xcode/Scripts/runtests.sh \
|
||||
xcode/Scripts/versiongenerate.py \
|
||||
xcode/gtest.xcodeproj/project.pbxproj
|
||||
|
||||
# xcode sample files
|
||||
EXTRA_DIST += \
|
||||
xcode/Samples/FrameworkSample/Info.plist \
|
||||
xcode/Samples/FrameworkSample/WidgetFramework.xcodeproj/project.pbxproj \
|
||||
xcode/Samples/FrameworkSample/runtests.sh \
|
||||
xcode/Samples/FrameworkSample/widget.cc \
|
||||
xcode/Samples/FrameworkSample/widget.h \
|
||||
xcode/Samples/FrameworkSample/widget_test.cc
|
||||
|
||||
# C++Builder project files
|
||||
EXTRA_DIST += \
|
||||
codegear/gtest.cbproj \
|
||||
codegear/gtest.groupproj \
|
||||
codegear/gtest_all.cc \
|
||||
codegear/gtest_link.cc \
|
||||
codegear/gtest_main.cbproj \
|
||||
codegear/gtest_unittest.cbproj
|
||||
|
||||
# Distribute and install M4 macro
|
||||
m4datadir = $(datadir)/aclocal
|
||||
m4data_DATA = m4/gtest.m4
|
||||
EXTRA_DIST += $(m4data_DATA)
|
||||
|
||||
# We define the global AM_CPPFLAGS as everything we compile includes from these
|
||||
# directories.
|
||||
AM_CPPFLAGS = -I$(srcdir) -I$(srcdir)/include
|
||||
|
||||
# Modifies compiler and linker flags for pthreads compatibility.
|
||||
if HAVE_PTHREADS |
||||
AM_CXXFLAGS = @PTHREAD_CFLAGS@ -DGTEST_HAS_PTHREAD=1
|
||||
AM_LIBS = @PTHREAD_LIBS@
|
||||
else |
||||
AM_CXXFLAGS = -DGTEST_HAS_PTHREAD=0
|
||||
endif |
||||
|
||||
# Build rules for libraries.
|
||||
lib_LTLIBRARIES = lib/libgtest.la lib/libgtest_main.la
|
||||
|
||||
lib_libgtest_la_SOURCES = src/gtest-all.cc
|
||||
|
||||
pkginclude_HEADERS = \
|
||||
include/gtest/gtest-death-test.h \
|
||||
include/gtest/gtest-matchers.h \
|
||||
include/gtest/gtest-message.h \
|
||||
include/gtest/gtest-param-test.h \
|
||||
include/gtest/gtest-printers.h \
|
||||
include/gtest/gtest-spi.h \
|
||||
include/gtest/gtest-test-part.h \
|
||||
include/gtest/gtest-typed-test.h \
|
||||
include/gtest/gtest.h \
|
||||
include/gtest/gtest_pred_impl.h \
|
||||
include/gtest/gtest_prod.h
|
||||
|
||||
pkginclude_internaldir = $(pkgincludedir)/internal
|
||||
pkginclude_internal_HEADERS = \
|
||||
include/gtest/internal/gtest-death-test-internal.h \
|
||||
include/gtest/internal/gtest-filepath.h \
|
||||
include/gtest/internal/gtest-internal.h \
|
||||
include/gtest/internal/gtest-param-util.h \
|
||||
include/gtest/internal/gtest-port.h \
|
||||
include/gtest/internal/gtest-port-arch.h \
|
||||
include/gtest/internal/gtest-string.h \
|
||||
include/gtest/internal/gtest-type-util.h \
|
||||
include/gtest/internal/custom/gtest.h \
|
||||
include/gtest/internal/custom/gtest-port.h \
|
||||
include/gtest/internal/custom/gtest-printers.h
|
||||
|
||||
lib_libgtest_main_la_SOURCES = src/gtest_main.cc
|
||||
lib_libgtest_main_la_LIBADD = lib/libgtest.la
|
||||
|
||||
# Build rules for samples and tests. Automake's naming for some of
|
||||
# these variables isn't terribly obvious, so this is a brief
|
||||
# reference:
|
||||
#
|
||||
# TESTS -- Programs run automatically by "make check"
|
||||
# check_PROGRAMS -- Programs built by "make check" but not necessarily run
|
||||
|
||||
TESTS=
|
||||
TESTS_ENVIRONMENT = GTEST_SOURCE_DIR="$(srcdir)/test" \
|
||||
GTEST_BUILD_DIR="$(top_builddir)/test"
|
||||
check_PROGRAMS=
|
||||
|
||||
# A simple sample on using gtest.
|
||||
TESTS += samples/sample1_unittest \
|
||||
samples/sample2_unittest \
|
||||
samples/sample3_unittest \
|
||||
samples/sample4_unittest \
|
||||
samples/sample5_unittest \
|
||||
samples/sample6_unittest \
|
||||
samples/sample7_unittest \
|
||||
samples/sample8_unittest \
|
||||
samples/sample9_unittest \
|
||||
samples/sample10_unittest
|
||||
check_PROGRAMS += samples/sample1_unittest \
|
||||
samples/sample2_unittest \
|
||||
samples/sample3_unittest \
|
||||
samples/sample4_unittest \
|
||||
samples/sample5_unittest \
|
||||
samples/sample6_unittest \
|
||||
samples/sample7_unittest \
|
||||
samples/sample8_unittest \
|
||||
samples/sample9_unittest \
|
||||
samples/sample10_unittest
|
||||
|
||||
samples_sample1_unittest_SOURCES = samples/sample1_unittest.cc samples/sample1.cc
|
||||
samples_sample1_unittest_LDADD = lib/libgtest_main.la \
|
||||
lib/libgtest.la
|
||||
samples_sample2_unittest_SOURCES = samples/sample2_unittest.cc samples/sample2.cc
|
||||
samples_sample2_unittest_LDADD = lib/libgtest_main.la \
|
||||
lib/libgtest.la
|
||||
samples_sample3_unittest_SOURCES = samples/sample3_unittest.cc
|
||||
samples_sample3_unittest_LDADD = lib/libgtest_main.la \
|
||||
lib/libgtest.la
|
||||
samples_sample4_unittest_SOURCES = samples/sample4_unittest.cc samples/sample4.cc
|
||||
samples_sample4_unittest_LDADD = lib/libgtest_main.la \
|
||||
lib/libgtest.la
|
||||
samples_sample5_unittest_SOURCES = samples/sample5_unittest.cc samples/sample1.cc
|
||||
samples_sample5_unittest_LDADD = lib/libgtest_main.la \
|
||||
lib/libgtest.la
|
||||
samples_sample6_unittest_SOURCES = samples/sample6_unittest.cc
|
||||
samples_sample6_unittest_LDADD = lib/libgtest_main.la \
|
||||
lib/libgtest.la
|
||||
samples_sample7_unittest_SOURCES = samples/sample7_unittest.cc
|
||||
samples_sample7_unittest_LDADD = lib/libgtest_main.la \
|
||||
lib/libgtest.la
|
||||
samples_sample8_unittest_SOURCES = samples/sample8_unittest.cc
|
||||
samples_sample8_unittest_LDADD = lib/libgtest_main.la \
|
||||
lib/libgtest.la
|
||||
|
||||
# Also verify that libgtest works by itself.
|
||||
samples_sample9_unittest_SOURCES = samples/sample9_unittest.cc
|
||||
samples_sample9_unittest_LDADD = lib/libgtest.la
|
||||
samples_sample10_unittest_SOURCES = samples/sample10_unittest.cc
|
||||
samples_sample10_unittest_LDADD = lib/libgtest.la
|
||||
|
||||
# This tests most constructs of gtest and verifies that libgtest_main
|
||||
# and libgtest work.
|
||||
TESTS += test/gtest_all_test
|
||||
check_PROGRAMS += test/gtest_all_test
|
||||
test_gtest_all_test_SOURCES = test/gtest_all_test.cc
|
||||
test_gtest_all_test_LDADD = lib/libgtest_main.la \
|
||||
lib/libgtest.la
|
||||
|
||||
TESTS += test/gtest_skip_in_environment_setup_test
|
||||
check_PROGRAMS += test/gtest_skip_in_environment_setup_test
|
||||
test_gtest_skip_in_environment_setup_test_SOURCES = test/gtest_skip_in_environment_setup_test.cc
|
||||
test_gtest_skip_in_environment_setup_test_LDADD= lib/libgtest_main.la \
|
||||
lib/libgtest.la
|
||||
|
||||
# Tests that fused gtest files compile and work.
|
||||
FUSED_GTEST_SRC = \
|
||||
fused-src/gtest/gtest-all.cc \
|
||||
fused-src/gtest/gtest.h \
|
||||
fused-src/gtest/gtest_main.cc
|
||||
|
||||
if HAVE_PYTHON |
||||
TESTS += test/fused_gtest_test
|
||||
check_PROGRAMS += test/fused_gtest_test
|
||||
test_fused_gtest_test_SOURCES = $(FUSED_GTEST_SRC) \
|
||||
samples/sample1.cc samples/sample1_unittest.cc
|
||||
test_fused_gtest_test_CPPFLAGS = -I"$(srcdir)/fused-src"
|
||||
|
||||
# Build rules for putting fused Google Test files into the distribution
|
||||
# package. The user can also create those files by manually running
|
||||
# scripts/fuse_gtest_files.py.
|
||||
$(test_fused_gtest_test_SOURCES): fused-gtest |
||||
|
||||
fused-gtest: $(pkginclude_HEADERS) $(pkginclude_internal_HEADERS) \
|
||||
$(GTEST_SRC) src/gtest-all.cc src/gtest_main.cc \
|
||||
scripts/fuse_gtest_files.py
|
||||
mkdir -p "$(srcdir)/fused-src"
|
||||
chmod -R u+w "$(srcdir)/fused-src"
|
||||
rm -f "$(srcdir)/fused-src/gtest/gtest-all.cc"
|
||||
rm -f "$(srcdir)/fused-src/gtest/gtest.h"
|
||||
"$(srcdir)/scripts/fuse_gtest_files.py" "$(srcdir)/fused-src"
|
||||
cp -f "$(srcdir)/src/gtest_main.cc" "$(srcdir)/fused-src/gtest/"
|
||||
|
||||
maintainer-clean-local: |
||||
rm -rf "$(srcdir)/fused-src"
|
||||
endif |
||||
|
||||
# Death tests may produce core dumps in the build directory. In case
|
||||
# this happens, clean them to keep distcleancheck happy.
|
||||
CLEANFILES = core
|
||||
|
||||
# Disables 'make install' as installing a compiled version of Google
|
||||
# Test can lead to undefined behavior due to violation of the
|
||||
# One-Definition Rule.
|
||||
|
||||
install-exec-local: |
||||
echo "'make install' is dangerous and not supported. Instead, see README for how to integrate Google Test into your build system."
|
||||
false
|
||||
|
||||
install-data-local: |
||||
echo "'make install' is dangerous and not supported. Instead, see README for how to integrate Google Test into your build system."
|
||||
false
|
@ -1,10 +1,9 @@ |
||||
prefix=${pcfiledir}/../.. |
||||
libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@ |
||||
includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@ |
||||
libdir=@CMAKE_INSTALL_FULL_LIBDIR@ |
||||
includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@ |
||||
|
||||
Name: gtest |
||||
Description: GoogleTest (without main() function) |
||||
Version: @PROJECT_VERSION@ |
||||
URL: https://github.com/google/googletest |
||||
Libs: -L${libdir} -lgtest @CMAKE_THREAD_LIBS_INIT@ |
||||
Cflags: -I${includedir} @GTEST_HAS_PTHREAD_MACRO@ @CMAKE_THREAD_LIBS_INIT@ |
||||
Cflags: -I${includedir} @GTEST_HAS_PTHREAD_MACRO@ |
||||
|
@ -1,11 +1,10 @@ |
||||
prefix=${pcfiledir}/../.. |
||||
libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@ |
||||
includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@ |
||||
libdir=@CMAKE_INSTALL_FULL_LIBDIR@ |
||||
includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@ |
||||
|
||||
Name: gtest_main |
||||
Description: GoogleTest (with main() function) |
||||
Version: @PROJECT_VERSION@ |
||||
URL: https://github.com/google/googletest |
||||
Requires: gtest |
||||
Requires: gtest = @PROJECT_VERSION@ |
||||
Libs: -L${libdir} -lgtest_main @CMAKE_THREAD_LIBS_INIT@ |
||||
Cflags: -I${includedir} @GTEST_HAS_PTHREAD_MACRO@ @CMAKE_THREAD_LIBS_INIT@ |
||||
Cflags: -I${includedir} @GTEST_HAS_PTHREAD_MACRO@ |
||||
|
@ -1,38 +0,0 @@ |
||||
// Copyright 2009, 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.
|
||||
//
|
||||
// Author: Josh Kelley (joshkel@gmail.com)
|
||||
//
|
||||
// Google C++ Testing Framework (Google Test)
|
||||
//
|
||||
// C++Builder's IDE cannot build a static library from files with hyphens
|
||||
// in their name. See http://qc.codegear.com/wc/qcmain.aspx?d=70977 .
|
||||
// This file serves as a workaround.
|
||||
|
||||
#include "src/gtest-all.cc" |
@ -1,40 +0,0 @@ |
||||
// Copyright 2009, 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.
|
||||
//
|
||||
// Author: Josh Kelley (joshkel@gmail.com)
|
||||
//
|
||||
// Google C++ Testing Framework (Google Test)
|
||||
//
|
||||
// Links gtest.lib and gtest_main.lib into the current project in C++Builder.
|
||||
// This means that these libraries can't be renamed, but it's the only way to
|
||||
// ensure that Debug versus Release test builds are linked against the
|
||||
// appropriate Debug or Release build of the libraries.
|
||||
|
||||
#pragma link "gtest.lib" |
||||
#pragma link "gtest_main.lib" |
@ -1,68 +0,0 @@ |
||||
m4_include(m4/acx_pthread.m4) |
||||
|
||||
# At this point, the Xcode project assumes the version string will be three |
||||
# integers separated by periods and surrounded by square brackets (e.g. |
||||
# "[1.0.1]"). It also asumes that there won't be any closing parenthesis |
||||
# between "AC_INIT(" and the closing ")" including comments and strings. |
||||
AC_INIT([Google C++ Testing Framework], |
||||
[1.8.0], |
||||
[googletestframework@googlegroups.com], |
||||
[gtest]) |
||||
|
||||
# Provide various options to initialize the Autoconf and configure processes. |
||||
AC_PREREQ([2.59]) |
||||
AC_CONFIG_SRCDIR([./LICENSE]) |
||||
AC_CONFIG_MACRO_DIRS([m4]) |
||||
AC_CONFIG_AUX_DIR([build-aux]) |
||||
AC_CONFIG_HEADERS([build-aux/config.h]) |
||||
AC_CONFIG_FILES([Makefile]) |
||||
AC_CONFIG_FILES([scripts/gtest-config], [chmod +x scripts/gtest-config]) |
||||
|
||||
# Initialize Automake with various options. We require at least v1.9, prevent |
||||
# pedantic complaints about package files, and enable various distribution |
||||
# targets. |
||||
AM_INIT_AUTOMAKE([1.9 dist-bzip2 dist-zip foreign subdir-objects]) |
||||
|
||||
# Check for programs used in building Google Test. |
||||
AC_PROG_CC |
||||
AC_PROG_CXX |
||||
AC_LANG([C++]) |
||||
AC_PROG_LIBTOOL |
||||
|
||||
# TODO(chandlerc@google.com): Currently we aren't running the Python tests |
||||
# against the interpreter detected by AM_PATH_PYTHON, and so we condition |
||||
# HAVE_PYTHON by requiring "python" to be in the PATH, and that interpreter's |
||||
# version to be >= 2.3. This will allow the scripts to use a "/usr/bin/env" |
||||
# hashbang. |
||||
PYTHON= # We *do not* allow the user to specify a python interpreter |
||||
AC_PATH_PROG([PYTHON],[python],[:]) |
||||
AS_IF([test "$PYTHON" != ":"], |
||||
[AM_PYTHON_CHECK_VERSION([$PYTHON],[2.3],[:],[PYTHON=":"])]) |
||||
AM_CONDITIONAL([HAVE_PYTHON],[test "$PYTHON" != ":"]) |
||||
|
||||
# Configure pthreads. |
||||
AC_ARG_WITH([pthreads], |
||||
[AS_HELP_STRING([--with-pthreads], |
||||
[use pthreads (default is yes)])], |
||||
[with_pthreads=$withval], |
||||
[with_pthreads=check]) |
||||
|
||||
have_pthreads=no |
||||
AS_IF([test "x$with_pthreads" != "xno"], |
||||
[ACX_PTHREAD( |
||||
[], |
||||
[AS_IF([test "x$with_pthreads" != "xcheck"], |
||||
[AC_MSG_FAILURE( |
||||
[--with-pthreads was specified, but unable to be used])])]) |
||||
have_pthreads="$acx_pthread_ok"]) |
||||
AM_CONDITIONAL([HAVE_PTHREADS],[test "x$have_pthreads" = "xyes"]) |
||||
AC_SUBST(PTHREAD_CFLAGS) |
||||
AC_SUBST(PTHREAD_LIBS) |
||||
|
||||
# TODO(chandlerc@google.com) Check for the necessary system headers. |
||||
|
||||
# TODO(chandlerc@google.com) Check the types, structures, and other compiler |
||||
# and architecture characteristics. |
||||
|
||||
# Output the generated files. No further autoconf macros may be used. |
||||
AC_OUTPUT |
@ -1,177 +0,0 @@ |
||||
|
||||
|
||||
<b>P</b>ump is <b>U</b>seful for <b>M</b>eta <b>P</b>rogramming. |
||||
|
||||
# The Problem # |
||||
|
||||
Template and macro libraries often need to define many classes, |
||||
functions, or macros that vary only (or almost only) in the number of |
||||
arguments they take. It's a lot of repetitive, mechanical, and |
||||
error-prone work. |
||||
|
||||
Variadic templates and variadic macros can alleviate the problem. |
||||
However, while both are being considered by the C++ committee, neither |
||||
is in the standard yet or widely supported by compilers. Thus they |
||||
are often not a good choice, especially when your code needs to be |
||||
portable. And their capabilities are still limited. |
||||
|
||||
As a result, authors of such libraries often have to write scripts to |
||||
generate their implementation. However, our experience is that it's |
||||
tedious to write such scripts, which tend to reflect the structure of |
||||
the generated code poorly and are often hard to read and edit. For |
||||
example, a small change needed in the generated code may require some |
||||
non-intuitive, non-trivial changes in the script. This is especially |
||||
painful when experimenting with the code. |
||||
|
||||
# Our Solution # |
||||
|
||||
Pump (for Pump is Useful for Meta Programming, Pretty Useful for Meta |
||||
Programming, or Practical Utility for Meta Programming, whichever you |
||||
prefer) is a simple meta-programming tool for C++. The idea is that a |
||||
programmer writes a `foo.pump` file which contains C++ code plus meta |
||||
code that manipulates the C++ code. The meta code can handle |
||||
iterations over a range, nested iterations, local meta variable |
||||
definitions, simple arithmetic, and conditional expressions. You can |
||||
view it as a small Domain-Specific Language. The meta language is |
||||
designed to be non-intrusive (s.t. it won't confuse Emacs' C++ mode, |
||||
for example) and concise, making Pump code intuitive and easy to |
||||
maintain. |
||||
|
||||
## Highlights ## |
||||
|
||||
* The implementation is in a single Python script and thus ultra portable: no build or installation is needed and it works cross platforms. |
||||
* Pump tries to be smart with respect to [Google's style guide](https://github.com/google/styleguide): it breaks long lines (easy to have when they are generated) at acceptable places to fit within 80 columns and indent the continuation lines correctly. |
||||
* The format is human-readable and more concise than XML. |
||||
* The format works relatively well with Emacs' C++ mode. |
||||
|
||||
## Examples ## |
||||
|
||||
The following Pump code (where meta keywords start with `$`, `[[` and `]]` are meta brackets, and `$$` starts a meta comment that ends with the line): |
||||
|
||||
``` |
||||
$var n = 3 $$ Defines a meta variable n. |
||||
$range i 0..n $$ Declares the range of meta iterator i (inclusive). |
||||
$for i [[ |
||||
$$ Meta loop. |
||||
// Foo$i does blah for $i-ary predicates. |
||||
$range j 1..i |
||||
template <size_t N $for j [[, typename A$j]]> |
||||
class Foo$i { |
||||
$if i == 0 [[ |
||||
blah a; |
||||
]] $elif i <= 2 [[ |
||||
blah b; |
||||
]] $else [[ |
||||
blah c; |
||||
]] |
||||
}; |
||||
|
||||
]] |
||||
``` |
||||
|
||||
will be translated by the Pump compiler to: |
||||
|
||||
``` cpp |
||||
// Foo0 does blah for 0-ary predicates. |
||||
template <size_t N> |
||||
class Foo0 { |
||||
blah a; |
||||
}; |
||||
|
||||
// Foo1 does blah for 1-ary predicates. |
||||
template <size_t N, typename A1> |
||||
class Foo1 { |
||||
blah b; |
||||
}; |
||||
|
||||
// Foo2 does blah for 2-ary predicates. |
||||
template <size_t N, typename A1, typename A2> |
||||
class Foo2 { |
||||
blah b; |
||||
}; |
||||
|
||||
// Foo3 does blah for 3-ary predicates. |
||||
template <size_t N, typename A1, typename A2, typename A3> |
||||
class Foo3 { |
||||
blah c; |
||||
}; |
||||
``` |
||||
|
||||
In another example, |
||||
|
||||
``` |
||||
$range i 1..n |
||||
Func($for i + [[a$i]]); |
||||
$$ The text between i and [[ is the separator between iterations. |
||||
``` |
||||
|
||||
will generate one of the following lines (without the comments), depending on the value of `n`: |
||||
|
||||
``` cpp |
||||
Func(); // If n is 0. |
||||
Func(a1); // If n is 1. |
||||
Func(a1 + a2); // If n is 2. |
||||
Func(a1 + a2 + a3); // If n is 3. |
||||
// And so on... |
||||
``` |
||||
|
||||
## Constructs ## |
||||
|
||||
We support the following meta programming constructs: |
||||
|
||||
| `$var id = exp` | Defines a named constant value. `$id` is valid util the end of the current meta lexical block. | |
||||
|:----------------|:-----------------------------------------------------------------------------------------------| |
||||
| `$range id exp..exp` | Sets the range of an iteration variable, which can be reused in multiple loops later. | |
||||
| `$for id sep [[ code ]]` | Iteration. The range of `id` must have been defined earlier. `$id` is valid in `code`. | |
||||
| `$($)` | Generates a single `$` character. | |
||||
| `$id` | Value of the named constant or iteration variable. | |
||||
| `$(exp)` | Value of the expression. | |
||||
| `$if exp [[ code ]] else_branch` | Conditional. | |
||||
| `[[ code ]]` | Meta lexical block. | |
||||
| `cpp_code` | Raw C++ code. | |
||||
| `$$ comment` | Meta comment. | |
||||
|
||||
**Note:** To give the user some freedom in formatting the Pump source |
||||
code, Pump ignores a new-line character if it's right after `$for foo` |
||||
or next to `[[` or `]]`. Without this rule you'll often be forced to write |
||||
very long lines to get the desired output. Therefore sometimes you may |
||||
need to insert an extra new-line in such places for a new-line to show |
||||
up in your output. |
||||
|
||||
## Grammar ## |
||||
|
||||
``` ebnf |
||||
code ::= atomic_code* |
||||
atomic_code ::= $var id = exp |
||||
| $var id = [[ code ]] |
||||
| $range id exp..exp |
||||
| $for id sep [[ code ]] |
||||
| $($) |
||||
| $id |
||||
| $(exp) |
||||
| $if exp [[ code ]] else_branch |
||||
| [[ code ]] |
||||
| cpp_code |
||||
sep ::= cpp_code | empty_string |
||||
else_branch ::= $else [[ code ]] |
||||
| $elif exp [[ code ]] else_branch |
||||
| empty_string |
||||
exp ::= simple_expression_in_Python_syntax |
||||
``` |
||||
|
||||
## Code ## |
||||
|
||||
You can find the source code of Pump in [scripts/pump.py](../scripts/pump.py). It is still |
||||
very unpolished and lacks automated tests, although it has been |
||||
successfully used many times. If you find a chance to use it in your |
||||
project, please let us know what you think! We also welcome help on |
||||
improving Pump. |
||||
|
||||
## Real Examples ## |
||||
|
||||
You can find real-world applications of Pump in [Google Test](https://github.com/google/googletest/tree/master/googletest) and [Google Mock](https://github.com/google/googletest/tree/master/googlemock). The source file `foo.h.pump` generates `foo.h`. |
||||
|
||||
## Tips ## |
||||
|
||||
* If a meta variable is followed by a letter or digit, you can separate them using `[[]]`, which inserts an empty string. For example `Foo$j[[]]Helper` generate `Foo1Helper` when `j` is 1. |
||||
* To avoid extra-long Pump source lines, you can break a line anywhere you want by inserting `[[]]` followed by a new line. Since any new-line character next to `[[` or `]]` is ignored, the generated code won't contain this new line. |
@ -1,93 +0,0 @@ |
||||
|
||||
|
||||
This guide will explain how to use the Google Testing Framework in your Xcode projects on Mac OS X. This tutorial begins by quickly explaining what to do for experienced users. After the quick start, the guide goes provides additional explanation about each step. |
||||
|
||||
# Quick Start # |
||||
|
||||
Here is the quick guide for using Google Test in your Xcode project. |
||||
|
||||
1. Download the source from the [website](https://github.com/google/googletest) using this command: `svn checkout http://googletest.googlecode.com/svn/trunk/ googletest-read-only`. |
||||
1. Open up the `gtest.xcodeproj` in the `googletest-read-only/xcode/` directory and build the gtest.framework. |
||||
1. Create a new "Shell Tool" target in your Xcode project called something like "UnitTests". |
||||
1. Add the gtest.framework to your project and add it to the "Link Binary with Libraries" build phase of "UnitTests". |
||||
1. Add your unit test source code to the "Compile Sources" build phase of "UnitTests". |
||||
1. Edit the "UnitTests" executable and add an environment variable named "DYLD\_FRAMEWORK\_PATH" with a value equal to the path to the framework containing the gtest.framework relative to the compiled executable. |
||||
1. Build and Go. |
||||
|
||||
The following sections further explain each of the steps listed above in depth, describing in more detail how to complete it including some variations. |
||||
|
||||
# Get the Source # |
||||
|
||||
Currently, the gtest.framework discussed here isn't available in a tagged release of Google Test, it is only available in the trunk. As explained at the Google Test [site](https://github.com/google/googletest), you can get the code from anonymous SVN with this command: |
||||
|
||||
``` |
||||
svn checkout http://googletest.googlecode.com/svn/trunk/ googletest-read-only |
||||
``` |
||||
|
||||
Alternatively, if you are working with Subversion in your own code base, you can add Google Test as an external dependency to your own Subversion repository. By following this approach, everyone that checks out your svn repository will also receive a copy of Google Test (a specific version, if you wish) without having to check it out explicitly. This makes the set up of your project simpler and reduces the copied code in the repository. |
||||
|
||||
To use `svn:externals`, decide where you would like to have the external source reside. You might choose to put the external source inside the trunk, because you want it to be part of the branch when you make a release. However, keeping it outside the trunk in a version-tagged directory called something like `third-party/googletest/1.0.1`, is another option. Once the location is established, use `svn propedit svn:externals _directory_` to set the svn:externals property on a directory in your repository. This directory won't contain the code, but be its versioned parent directory. |
||||
|
||||
The command `svn propedit` will bring up your Subversion editor, making editing the long, (potentially multi-line) property simpler. This same method can be used to check out a tagged branch, by using the appropriate URL (e.g. `https://github.com/google/googletest/releases/tag/release-1.0.1`). Additionally, the svn:externals property allows the specification of a particular revision of the trunk with the `-r_##_` option (e.g. `externals/src/googletest -r60 http://googletest.googlecode.com/svn/trunk`). |
||||
|
||||
Here is an example of using the svn:externals properties on a trunk (read via `svn propget`) of a project. This value checks out a copy of Google Test into the `trunk/externals/src/googletest/` directory. |
||||
|
||||
``` |
||||
[Computer:svn] user$ svn propget svn:externals trunk |
||||
externals/src/googletest http://googletest.googlecode.com/svn/trunk |
||||
``` |
||||
|
||||
# Add the Framework to Your Project # |
||||
|
||||
The next step is to build and add the gtest.framework to your own project. This guide describes two common ways below. |
||||
|
||||
* **Option 1** --- The simplest way to add Google Test to your own project, is to open gtest.xcodeproj (found in the xcode/ directory of the Google Test trunk) and build the framework manually. Then, add the built framework into your project using the "Add->Existing Framework..." from the context menu or "Project->Add..." from the main menu. The gtest.framework is relocatable and contains the headers and object code that you'll need to make tests. This method requires rebuilding every time you upgrade Google Test in your project. |
||||
* **Option 2** --- If you are going to be living off the trunk of Google Test, incorporating its latest features into your unit tests (or are a Google Test developer yourself). You'll want to rebuild the framework every time the source updates. to do this, you'll need to add the gtest.xcodeproj file, not the framework itself, to your own Xcode project. Then, from the build products that are revealed by the project's disclosure triangle, you can find the gtest.framework, which can be added to your targets (discussed below). |
||||
|
||||
# Make a Test Target # |
||||
|
||||
To start writing tests, make a new "Shell Tool" target. This target template is available under BSD, Cocoa, or Carbon. Add your unit test source code to the "Compile Sources" build phase of the target. |
||||
|
||||
Next, you'll want to add gtest.framework in two different ways, depending upon which option you chose above. |
||||
|
||||
* **Option 1** --- During compilation, Xcode will need to know that you are linking against the gtest.framework. Add the gtest.framework to the "Link Binary with Libraries" build phase of your test target. This will include the Google Test headers in your header search path, and will tell the linker where to find the library. |
||||
* **Option 2** --- If your working out of the trunk, you'll also want to add gtest.framework to your "Link Binary with Libraries" build phase of your test target. In addition, you'll want to add the gtest.framework as a dependency to your unit test target. This way, Xcode will make sure that gtest.framework is up to date, every time your build your target. Finally, if you don't share build directories with Google Test, you'll have to copy the gtest.framework into your own build products directory using a "Run Script" build phase. |
||||
|
||||
# Set Up the Executable Run Environment # |
||||
|
||||
Since the unit test executable is a shell tool, it doesn't have a bundle with a `Contents/Frameworks` directory, in which to place gtest.framework. Instead, the dynamic linker must be told at runtime to search for the framework in another location. This can be accomplished by setting the "DYLD\_FRAMEWORK\_PATH" environment variable in the "Edit Active Executable ..." Arguments tab, under "Variables to be set in the environment:". The path for this value is the path (relative or absolute) of the directory containing the gtest.framework. |
||||
|
||||
If you haven't set up the DYLD\_FRAMEWORK\_PATH, correctly, you might get a message like this: |
||||
|
||||
``` |
||||
[Session started at 2008-08-15 06:23:57 -0600.] |
||||
dyld: Library not loaded: @loader_path/../Frameworks/gtest.framework/Versions/A/gtest |
||||
Referenced from: /Users/username/Documents/Sandbox/gtestSample/build/Debug/WidgetFrameworkTest |
||||
Reason: image not found |
||||
``` |
||||
|
||||
To correct this problem, go to to the directory containing the executable named in "Referenced from:" value in the error message above. Then, with the terminal in this location, find the relative path to the directory containing the gtest.framework. That is the value you'll need to set as the DYLD\_FRAMEWORK\_PATH. |
||||
|
||||
# Build and Go # |
||||
|
||||
Now, when you click "Build and Go", the test will be executed. Dumping out something like this: |
||||
|
||||
``` |
||||
[Session started at 2008-08-06 06:36:13 -0600.] |
||||
[==========] Running 2 tests from 1 test case. |
||||
[----------] Global test environment set-up. |
||||
[----------] 2 tests from WidgetInitializerTest |
||||
[ RUN ] WidgetInitializerTest.TestConstructor |
||||
[ OK ] WidgetInitializerTest.TestConstructor |
||||
[ RUN ] WidgetInitializerTest.TestConversion |
||||
[ OK ] WidgetInitializerTest.TestConversion |
||||
[----------] Global test environment tear-down |
||||
[==========] 2 tests from 1 test case ran. |
||||
[ PASSED ] 2 tests. |
||||
|
||||
The Debugger has exited with status 0. |
||||
``` |
||||
|
||||
# Summary # |
||||
|
||||
Unit testing is a valuable way to ensure your data model stays valid even during rapid development or refactoring. The Google Testing Framework is a great unit testing framework for C and C++ which integrates well with an Xcode development environment. |
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,314 +0,0 @@ |
||||
$$ -*- mode: c++; -*- |
||||
$var n = 50 $$ Maximum length of type lists we want to support. |
||||
// Copyright 2008 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. |
||||
|
||||
|
||||
// Type utilities needed for implementing typed and type-parameterized |
||||
// tests. This file is generated by a SCRIPT. DO NOT EDIT BY HAND! |
||||
// |
||||
// Currently we support at most $n types in a list, and at most $n |
||||
// type-parameterized tests in one type-parameterized test suite. |
||||
// Please contact googletestframework@googlegroups.com if you need |
||||
// more. |
||||
|
||||
// GOOGLETEST_CM0001 DO NOT DELETE |
||||
|
||||
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ |
||||
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ |
||||
|
||||
#include "gtest/internal/gtest-port.h" |
||||
|
||||
// #ifdef __GNUC__ is too general here. It is possible to use gcc without using |
||||
// libstdc++ (which is where cxxabi.h comes from). |
||||
# if GTEST_HAS_CXXABI_H_ |
||||
# include <cxxabi.h> |
||||
# elif defined(__HP_aCC) |
||||
# include <acxx_demangle.h> |
||||
# endif // GTEST_HASH_CXXABI_H_ |
||||
|
||||
namespace testing { |
||||
namespace internal { |
||||
|
||||
// Canonicalizes a given name with respect to the Standard C++ Library. |
||||
// This handles removing the inline namespace within `std` that is |
||||
// used by various standard libraries (e.g., `std::__1`). Names outside |
||||
// of namespace std are returned unmodified. |
||||
inline std::string CanonicalizeForStdLibVersioning(std::string s) { |
||||
static const char prefix[] = "std::__"; |
||||
if (s.compare(0, strlen(prefix), prefix) == 0) { |
||||
std::string::size_type end = s.find("::", strlen(prefix)); |
||||
if (end != s.npos) { |
||||
// Erase everything between the initial `std` and the second `::`. |
||||
s.erase(strlen("std"), end - strlen("std")); |
||||
} |
||||
} |
||||
return s; |
||||
} |
||||
|
||||
// GetTypeName<T>() returns a human-readable name of type T. |
||||
// NB: This function is also used in Google Mock, so don't move it inside of |
||||
// the typed-test-only section below. |
||||
template <typename T> |
||||
std::string GetTypeName() { |
||||
# if GTEST_HAS_RTTI |
||||
|
||||
const char* const name = typeid(T).name(); |
||||
# if GTEST_HAS_CXXABI_H_ || defined(__HP_aCC) |
||||
int status = 0; |
||||
// gcc's implementation of typeid(T).name() mangles the type name, |
||||
// so we have to demangle it. |
||||
# if GTEST_HAS_CXXABI_H_ |
||||
using abi::__cxa_demangle; |
||||
# endif // GTEST_HAS_CXXABI_H_ |
||||
char* const readable_name = __cxa_demangle(name, nullptr, nullptr, &status); |
||||
const std::string name_str(status == 0 ? readable_name : name); |
||||
free(readable_name); |
||||
return CanonicalizeForStdLibVersioning(name_str); |
||||
# else |
||||
return name; |
||||
# endif // GTEST_HAS_CXXABI_H_ || __HP_aCC |
||||
|
||||
# else |
||||
|
||||
return "<type>"; |
||||
|
||||
# endif // GTEST_HAS_RTTI |
||||
} |
||||
|
||||
#if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P |
||||
|
||||
// AssertyTypeEq<T1, T2>::type is defined iff T1 and T2 are the same |
||||
// type. This can be used as a compile-time assertion to ensure that |
||||
// two types are equal. |
||||
|
||||
template <typename T1, typename T2> |
||||
struct AssertTypeEq; |
||||
|
||||
template <typename T> |
||||
struct AssertTypeEq<T, T> { |
||||
typedef bool type; |
||||
}; |
||||
|
||||
// A unique type used as the default value for the arguments of class |
||||
// template Types. This allows us to simulate variadic templates |
||||
// (e.g. Types<int>, Type<int, double>, and etc), which C++ doesn't |
||||
// support directly. |
||||
struct None {}; |
||||
|
||||
// The following family of struct and struct templates are used to |
||||
// represent type lists. In particular, TypesN<T1, T2, ..., TN> |
||||
// represents a type list with N types (T1, T2, ..., and TN) in it. |
||||
// Except for Types0, every struct in the family has two member types: |
||||
// Head for the first type in the list, and Tail for the rest of the |
||||
// list. |
||||
|
||||
// The empty type list. |
||||
struct Types0 {}; |
||||
|
||||
// Type lists of length 1, 2, 3, and so on. |
||||
|
||||
template <typename T1> |
||||
struct Types1 { |
||||
typedef T1 Head; |
||||
typedef Types0 Tail; |
||||
}; |
||||
|
||||
$range i 2..n |
||||
|
||||
$for i [[ |
||||
$range j 1..i |
||||
$range k 2..i |
||||
template <$for j, [[typename T$j]]> |
||||
struct Types$i { |
||||
typedef T1 Head; |
||||
typedef Types$(i-1)<$for k, [[T$k]]> Tail; |
||||
}; |
||||
|
||||
|
||||
]] |
||||
|
||||
} // namespace internal |
||||
|
||||
// We don't want to require the users to write TypesN<...> directly, |
||||
// as that would require them to count the length. Types<...> is much |
||||
// easier to write, but generates horrible messages when there is a |
||||
// compiler error, as gcc insists on printing out each template |
||||
// argument, even if it has the default value (this means Types<int> |
||||
// will appear as Types<int, None, None, ..., None> in the compiler |
||||
// errors). |
||||
// |
||||
// Our solution is to combine the best part of the two approaches: a |
||||
// user would write Types<T1, ..., TN>, and Google Test will translate |
||||
// that to TypesN<T1, ..., TN> internally to make error messages |
||||
// readable. The translation is done by the 'type' member of the |
||||
// Types template. |
||||
|
||||
$range i 1..n |
||||
template <$for i, [[typename T$i = internal::None]]> |
||||
struct Types { |
||||
typedef internal::Types$n<$for i, [[T$i]]> type; |
||||
}; |
||||
|
||||
template <> |
||||
struct Types<$for i, [[internal::None]]> { |
||||
typedef internal::Types0 type; |
||||
}; |
||||
|
||||
$range i 1..n-1 |
||||
$for i [[ |
||||
$range j 1..i |
||||
$range k i+1..n |
||||
template <$for j, [[typename T$j]]> |
||||
struct Types<$for j, [[T$j]]$for k[[, internal::None]]> { |
||||
typedef internal::Types$i<$for j, [[T$j]]> type; |
||||
}; |
||||
|
||||
]] |
||||
|
||||
namespace internal { |
||||
|
||||
# define GTEST_TEMPLATE_ template <typename T> class |
||||
|
||||
// The template "selector" struct TemplateSel<Tmpl> is used to |
||||
// represent Tmpl, which must be a class template with one type |
||||
// parameter, as a type. TemplateSel<Tmpl>::Bind<T>::type is defined |
||||
// as the type Tmpl<T>. This allows us to actually instantiate the |
||||
// template "selected" by TemplateSel<Tmpl>. |
||||
// |
||||
// This trick is necessary for simulating typedef for class templates, |
||||
// which C++ doesn't support directly. |
||||
template <GTEST_TEMPLATE_ Tmpl> |
||||
struct TemplateSel { |
||||
template <typename T> |
||||
struct Bind { |
||||
typedef Tmpl<T> type; |
||||
}; |
||||
}; |
||||
|
||||
# define GTEST_BIND_(TmplSel, T) \ |
||||
TmplSel::template Bind<T>::type |
||||
|
||||
// A unique struct template used as the default value for the |
||||
// arguments of class template Templates. This allows us to simulate |
||||
// variadic templates (e.g. Templates<int>, Templates<int, double>, |
||||
// and etc), which C++ doesn't support directly. |
||||
template <typename T> |
||||
struct NoneT {}; |
||||
|
||||
// The following family of struct and struct templates are used to |
||||
// represent template lists. In particular, TemplatesN<T1, T2, ..., |
||||
// TN> represents a list of N templates (T1, T2, ..., and TN). Except |
||||
// for Templates0, every struct in the family has two member types: |
||||
// Head for the selector of the first template in the list, and Tail |
||||
// for the rest of the list. |
||||
|
||||
// The empty template list. |
||||
struct Templates0 {}; |
||||
|
||||
// Template lists of length 1, 2, 3, and so on. |
||||
|
||||
template <GTEST_TEMPLATE_ T1> |
||||
struct Templates1 { |
||||
typedef TemplateSel<T1> Head; |
||||
typedef Templates0 Tail; |
||||
}; |
||||
|
||||
$range i 2..n |
||||
|
||||
$for i [[ |
||||
$range j 1..i |
||||
$range k 2..i |
||||
template <$for j, [[GTEST_TEMPLATE_ T$j]]> |
||||
struct Templates$i { |
||||
typedef TemplateSel<T1> Head; |
||||
typedef Templates$(i-1)<$for k, [[T$k]]> Tail; |
||||
}; |
||||
|
||||
|
||||
]] |
||||
|
||||
// We don't want to require the users to write TemplatesN<...> directly, |
||||
// as that would require them to count the length. Templates<...> is much |
||||
// easier to write, but generates horrible messages when there is a |
||||
// compiler error, as gcc insists on printing out each template |
||||
// argument, even if it has the default value (this means Templates<list> |
||||
// will appear as Templates<list, NoneT, NoneT, ..., NoneT> in the compiler |
||||
// errors). |
||||
// |
||||
// Our solution is to combine the best part of the two approaches: a |
||||
// user would write Templates<T1, ..., TN>, and Google Test will translate |
||||
// that to TemplatesN<T1, ..., TN> internally to make error messages |
||||
// readable. The translation is done by the 'type' member of the |
||||
// Templates template. |
||||
|
||||
$range i 1..n |
||||
template <$for i, [[GTEST_TEMPLATE_ T$i = NoneT]]> |
||||
struct Templates { |
||||
typedef Templates$n<$for i, [[T$i]]> type; |
||||
}; |
||||
|
||||
template <> |
||||
struct Templates<$for i, [[NoneT]]> { |
||||
typedef Templates0 type; |
||||
}; |
||||
|
||||
$range i 1..n-1 |
||||
$for i [[ |
||||
$range j 1..i |
||||
$range k i+1..n |
||||
template <$for j, [[GTEST_TEMPLATE_ T$j]]> |
||||
struct Templates<$for j, [[T$j]]$for k[[, NoneT]]> { |
||||
typedef Templates$i<$for j, [[T$j]]> type; |
||||
}; |
||||
|
||||
]] |
||||
|
||||
// The TypeList template makes it possible to use either a single type |
||||
// or a Types<...> list in TYPED_TEST_SUITE() and |
||||
// INSTANTIATE_TYPED_TEST_SUITE_P(). |
||||
|
||||
template <typename T> |
||||
struct TypeList { |
||||
typedef Types1<T> type; |
||||
}; |
||||
|
||||
|
||||
$range i 1..n |
||||
template <$for i, [[typename T$i]]> |
||||
struct TypeList<Types<$for i, [[T$i]]> > { |
||||
typedef typename Types<$for i, [[T$i]]>::type type; |
||||
}; |
||||
|
||||
#endif // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P |
||||
|
||||
} // namespace internal |
||||
} // namespace testing |
||||
|
||||
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ |
@ -1,363 +0,0 @@ |
||||
# This was retrieved from |
||||
# http://svn.0pointer.de/viewvc/trunk/common/acx_pthread.m4?revision=1277&root=avahi |
||||
# See also (perhaps for new versions?) |
||||
# http://svn.0pointer.de/viewvc/trunk/common/acx_pthread.m4?root=avahi |
||||
# |
||||
# We've rewritten the inconsistency check code (from avahi), to work |
||||
# more broadly. In particular, it no longer assumes ld accepts -zdefs. |
||||
# This caused a restructing of the code, but the functionality has only |
||||
# changed a little. |
||||
|
||||
dnl @synopsis ACX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) |
||||
dnl |
||||
dnl @summary figure out how to build C programs using POSIX threads |
||||
dnl |
||||
dnl This macro figures out how to build C programs using POSIX threads. |
||||
dnl It sets the PTHREAD_LIBS output variable to the threads library and |
||||
dnl linker flags, and the PTHREAD_CFLAGS output variable to any special |
||||
dnl C compiler flags that are needed. (The user can also force certain |
||||
dnl compiler flags/libs to be tested by setting these environment |
||||
dnl variables.) |
||||
dnl |
||||
dnl Also sets PTHREAD_CC to any special C compiler that is needed for |
||||
dnl multi-threaded programs (defaults to the value of CC otherwise). |
||||
dnl (This is necessary on AIX to use the special cc_r compiler alias.) |
||||
dnl |
||||
dnl NOTE: You are assumed to not only compile your program with these |
||||
dnl flags, but also link it with them as well. e.g. you should link |
||||
dnl with $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS |
||||
dnl $LIBS |
||||
dnl |
||||
dnl If you are only building threads programs, you may wish to use |
||||
dnl these variables in your default LIBS, CFLAGS, and CC: |
||||
dnl |
||||
dnl LIBS="$PTHREAD_LIBS $LIBS" |
||||
dnl CFLAGS="$CFLAGS $PTHREAD_CFLAGS" |
||||
dnl CC="$PTHREAD_CC" |
||||
dnl |
||||
dnl In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute |
||||
dnl constant has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to |
||||
dnl that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX). |
||||
dnl |
||||
dnl ACTION-IF-FOUND is a list of shell commands to run if a threads |
||||
dnl library is found, and ACTION-IF-NOT-FOUND is a list of commands to |
||||
dnl run it if it is not found. If ACTION-IF-FOUND is not specified, the |
||||
dnl default action will define HAVE_PTHREAD. |
||||
dnl |
||||
dnl Please let the authors know if this macro fails on any platform, or |
||||
dnl if you have any other suggestions or comments. This macro was based |
||||
dnl on work by SGJ on autoconf scripts for FFTW (www.fftw.org) (with |
||||
dnl help from M. Frigo), as well as ac_pthread and hb_pthread macros |
||||
dnl posted by Alejandro Forero Cuervo to the autoconf macro repository. |
||||
dnl We are also grateful for the helpful feedback of numerous users. |
||||
dnl |
||||
dnl @category InstalledPackages |
||||
dnl @author Steven G. Johnson <stevenj@alum.mit.edu> |
||||
dnl @version 2006-05-29 |
||||
dnl @license GPLWithACException |
||||
dnl |
||||
dnl Checks for GCC shared/pthread inconsistency based on work by |
||||
dnl Marcin Owsiany <marcin@owsiany.pl> |
||||
|
||||
|
||||
AC_DEFUN([ACX_PTHREAD], [ |
||||
AC_REQUIRE([AC_CANONICAL_HOST]) |
||||
AC_LANG_SAVE |
||||
AC_LANG_C |
||||
acx_pthread_ok=no |
||||
|
||||
# We used to check for pthread.h first, but this fails if pthread.h |
||||
# requires special compiler flags (e.g. on True64 or Sequent). |
||||
# It gets checked for in the link test anyway. |
||||
|
||||
# First of all, check if the user has set any of the PTHREAD_LIBS, |
||||
# etcetera environment variables, and if threads linking works using |
||||
# them: |
||||
if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then |
||||
save_CFLAGS="$CFLAGS" |
||||
CFLAGS="$CFLAGS $PTHREAD_CFLAGS" |
||||
save_LIBS="$LIBS" |
||||
LIBS="$PTHREAD_LIBS $LIBS" |
||||
AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS]) |
||||
AC_TRY_LINK_FUNC(pthread_join, acx_pthread_ok=yes) |
||||
AC_MSG_RESULT($acx_pthread_ok) |
||||
if test x"$acx_pthread_ok" = xno; then |
||||
PTHREAD_LIBS="" |
||||
PTHREAD_CFLAGS="" |
||||
fi |
||||
LIBS="$save_LIBS" |
||||
CFLAGS="$save_CFLAGS" |
||||
fi |
||||
|
||||
# We must check for the threads library under a number of different |
||||
# names; the ordering is very important because some systems |
||||
# (e.g. DEC) have both -lpthread and -lpthreads, where one of the |
||||
# libraries is broken (non-POSIX). |
||||
|
||||
# Create a list of thread flags to try. Items starting with a "-" are |
||||
# C compiler flags, and other items are library names, except for "none" |
||||
# which indicates that we try without any flags at all, and "pthread-config" |
||||
# which is a program returning the flags for the Pth emulation library. |
||||
|
||||
acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" |
||||
|
||||
# The ordering *is* (sometimes) important. Some notes on the |
||||
# individual items follow: |
||||
|
||||
# pthreads: AIX (must check this before -lpthread) |
||||
# none: in case threads are in libc; should be tried before -Kthread and |
||||
# other compiler flags to prevent continual compiler warnings |
||||
# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) |
||||
# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) |
||||
# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) |
||||
# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads) |
||||
# -pthreads: Solaris/gcc |
||||
# -mthreads: Mingw32/gcc, Lynx/gcc |
||||
# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it |
||||
# doesn't hurt to check since this sometimes defines pthreads too; |
||||
# also defines -D_REENTRANT) |
||||
# ... -mt is also the pthreads flag for HP/aCC |
||||
# pthread: Linux, etcetera |
||||
# --thread-safe: KAI C++ |
||||
# pthread-config: use pthread-config program (for GNU Pth library) |
||||
|
||||
case "${host_cpu}-${host_os}" in |
||||
*solaris*) |
||||
|
||||
# On Solaris (at least, for some versions), libc contains stubbed |
||||
# (non-functional) versions of the pthreads routines, so link-based |
||||
# tests will erroneously succeed. (We need to link with -pthreads/-mt/ |
||||
# -lpthread.) (The stubs are missing pthread_cleanup_push, or rather |
||||
# a function called by this macro, so we could check for that, but |
||||
# who knows whether they'll stub that too in a future libc.) So, |
||||
# we'll just look for -pthreads and -lpthread first: |
||||
|
||||
acx_pthread_flags="-pthreads pthread -mt -pthread $acx_pthread_flags" |
||||
;; |
||||
esac |
||||
|
||||
if test x"$acx_pthread_ok" = xno; then |
||||
for flag in $acx_pthread_flags; do |
||||
|
||||
case $flag in |
||||
none) |
||||
AC_MSG_CHECKING([whether pthreads work without any flags]) |
||||
;; |
||||
|
||||
-*) |
||||
AC_MSG_CHECKING([whether pthreads work with $flag]) |
||||
PTHREAD_CFLAGS="$flag" |
||||
;; |
||||
|
||||
pthread-config) |
||||
AC_CHECK_PROG(acx_pthread_config, pthread-config, yes, no) |
||||
if test x"$acx_pthread_config" = xno; then continue; fi |
||||
PTHREAD_CFLAGS="`pthread-config --cflags`" |
||||
PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" |
||||
;; |
||||
|
||||
*) |
||||
AC_MSG_CHECKING([for the pthreads library -l$flag]) |
||||
PTHREAD_LIBS="-l$flag" |
||||
;; |
||||
esac |
||||
|
||||
save_LIBS="$LIBS" |
||||
save_CFLAGS="$CFLAGS" |
||||
LIBS="$PTHREAD_LIBS $LIBS" |
||||
CFLAGS="$CFLAGS $PTHREAD_CFLAGS" |
||||
|
||||
# Check for various functions. We must include pthread.h, |
||||
# since some functions may be macros. (On the Sequent, we |
||||
# need a special flag -Kthread to make this header compile.) |
||||
# We check for pthread_join because it is in -lpthread on IRIX |
||||
# while pthread_create is in libc. We check for pthread_attr_init |
||||
# due to DEC craziness with -lpthreads. We check for |
||||
# pthread_cleanup_push because it is one of the few pthread |
||||
# functions on Solaris that doesn't have a non-functional libc stub. |
||||
# We try pthread_create on general principles. |
||||
AC_TRY_LINK([#include <pthread.h>], |
||||
[pthread_t th; pthread_join(th, 0); |
||||
pthread_attr_init(0); pthread_cleanup_push(0, 0); |
||||
pthread_create(0,0,0,0); pthread_cleanup_pop(0); ], |
||||
[acx_pthread_ok=yes]) |
||||
|
||||
LIBS="$save_LIBS" |
||||
CFLAGS="$save_CFLAGS" |
||||
|
||||
AC_MSG_RESULT($acx_pthread_ok) |
||||
if test "x$acx_pthread_ok" = xyes; then |
||||
break; |
||||
fi |
||||
|
||||
PTHREAD_LIBS="" |
||||
PTHREAD_CFLAGS="" |
||||
done |
||||
fi |
||||
|
||||
# Various other checks: |
||||
if test "x$acx_pthread_ok" = xyes; then |
||||
save_LIBS="$LIBS" |
||||
LIBS="$PTHREAD_LIBS $LIBS" |
||||
save_CFLAGS="$CFLAGS" |
||||
CFLAGS="$CFLAGS $PTHREAD_CFLAGS" |
||||
|
||||
# Detect AIX lossage: JOINABLE attribute is called UNDETACHED. |
||||
AC_MSG_CHECKING([for joinable pthread attribute]) |
||||
attr_name=unknown |
||||
for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do |
||||
AC_TRY_LINK([#include <pthread.h>], [int attr=$attr; return attr;], |
||||
[attr_name=$attr; break]) |
||||
done |
||||
AC_MSG_RESULT($attr_name) |
||||
if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then |
||||
AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name, |
||||
[Define to necessary symbol if this constant |
||||
uses a non-standard name on your system.]) |
||||
fi |
||||
|
||||
AC_MSG_CHECKING([if more special flags are required for pthreads]) |
||||
flag=no |
||||
case "${host_cpu}-${host_os}" in |
||||
*-aix* | *-freebsd* | *-darwin*) flag="-D_THREAD_SAFE";; |
||||
*solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";; |
||||
esac |
||||
AC_MSG_RESULT(${flag}) |
||||
if test "x$flag" != xno; then |
||||
PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS" |
||||
fi |
||||
|
||||
LIBS="$save_LIBS" |
||||
CFLAGS="$save_CFLAGS" |
||||
# More AIX lossage: must compile with xlc_r or cc_r |
||||
if test x"$GCC" != xyes; then |
||||
AC_CHECK_PROGS(PTHREAD_CC, xlc_r cc_r, ${CC}) |
||||
else |
||||
PTHREAD_CC=$CC |
||||
fi |
||||
|
||||
# The next part tries to detect GCC inconsistency with -shared on some |
||||
# architectures and systems. The problem is that in certain |
||||
# configurations, when -shared is specified, GCC "forgets" to |
||||
# internally use various flags which are still necessary. |
||||
|
||||
# |
||||
# Prepare the flags |
||||
# |
||||
save_CFLAGS="$CFLAGS" |
||||
save_LIBS="$LIBS" |
||||
save_CC="$CC" |
||||
|
||||
# Try with the flags determined by the earlier checks. |
||||
# |
||||
# -Wl,-z,defs forces link-time symbol resolution, so that the |
||||
# linking checks with -shared actually have any value |
||||
# |
||||
# FIXME: -fPIC is required for -shared on many architectures, |
||||
# so we specify it here, but the right way would probably be to |
||||
# properly detect whether it is actually required. |
||||
CFLAGS="-shared -fPIC -Wl,-z,defs $CFLAGS $PTHREAD_CFLAGS" |
||||
LIBS="$PTHREAD_LIBS $LIBS" |
||||
CC="$PTHREAD_CC" |
||||
|
||||
# In order not to create several levels of indentation, we test |
||||
# the value of "$done" until we find the cure or run out of ideas. |
||||
done="no" |
||||
|
||||
# First, make sure the CFLAGS we added are actually accepted by our |
||||
# compiler. If not (and OS X's ld, for instance, does not accept -z), |
||||
# then we can't do this test. |
||||
if test x"$done" = xno; then |
||||
AC_MSG_CHECKING([whether to check for GCC pthread/shared inconsistencies]) |
||||
AC_TRY_LINK(,, , [done=yes]) |
||||
|
||||
if test "x$done" = xyes ; then |
||||
AC_MSG_RESULT([no]) |
||||
else |
||||
AC_MSG_RESULT([yes]) |
||||
fi |
||||
fi |
||||
|
||||
if test x"$done" = xno; then |
||||
AC_MSG_CHECKING([whether -pthread is sufficient with -shared]) |
||||
AC_TRY_LINK([#include <pthread.h>], |
||||
[pthread_t th; pthread_join(th, 0); |
||||
pthread_attr_init(0); pthread_cleanup_push(0, 0); |
||||
pthread_create(0,0,0,0); pthread_cleanup_pop(0); ], |
||||
[done=yes]) |
||||
|
||||
if test "x$done" = xyes; then |
||||
AC_MSG_RESULT([yes]) |
||||
else |
||||
AC_MSG_RESULT([no]) |
||||
fi |
||||
fi |
||||
|
||||
# |
||||
# Linux gcc on some architectures such as mips/mipsel forgets |
||||
# about -lpthread |
||||
# |
||||
if test x"$done" = xno; then |
||||
AC_MSG_CHECKING([whether -lpthread fixes that]) |
||||
LIBS="-lpthread $PTHREAD_LIBS $save_LIBS" |
||||
AC_TRY_LINK([#include <pthread.h>], |
||||
[pthread_t th; pthread_join(th, 0); |
||||
pthread_attr_init(0); pthread_cleanup_push(0, 0); |
||||
pthread_create(0,0,0,0); pthread_cleanup_pop(0); ], |
||||
[done=yes]) |
||||
|
||||
if test "x$done" = xyes; then |
||||
AC_MSG_RESULT([yes]) |
||||
PTHREAD_LIBS="-lpthread $PTHREAD_LIBS" |
||||
else |
||||
AC_MSG_RESULT([no]) |
||||
fi |
||||
fi |
||||
# |
||||
# FreeBSD 4.10 gcc forgets to use -lc_r instead of -lc |
||||
# |
||||
if test x"$done" = xno; then |
||||
AC_MSG_CHECKING([whether -lc_r fixes that]) |
||||
LIBS="-lc_r $PTHREAD_LIBS $save_LIBS" |
||||
AC_TRY_LINK([#include <pthread.h>], |
||||
[pthread_t th; pthread_join(th, 0); |
||||
pthread_attr_init(0); pthread_cleanup_push(0, 0); |
||||
pthread_create(0,0,0,0); pthread_cleanup_pop(0); ], |
||||
[done=yes]) |
||||
|
||||
if test "x$done" = xyes; then |
||||
AC_MSG_RESULT([yes]) |
||||
PTHREAD_LIBS="-lc_r $PTHREAD_LIBS" |
||||
else |
||||
AC_MSG_RESULT([no]) |
||||
fi |
||||
fi |
||||
if test x"$done" = xno; then |
||||
# OK, we have run out of ideas |
||||
AC_MSG_WARN([Impossible to determine how to use pthreads with shared libraries]) |
||||
|
||||
# so it's not safe to assume that we may use pthreads |
||||
acx_pthread_ok=no |
||||
fi |
||||
|
||||
CFLAGS="$save_CFLAGS" |
||||
LIBS="$save_LIBS" |
||||
CC="$save_CC" |
||||
else |
||||
PTHREAD_CC="$CC" |
||||
fi |
||||
|
||||
AC_SUBST(PTHREAD_LIBS) |
||||
AC_SUBST(PTHREAD_CFLAGS) |
||||
AC_SUBST(PTHREAD_CC) |
||||
|
||||
# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: |
||||
if test x"$acx_pthread_ok" = xyes; then |
||||
ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1]) |
||||
: |
||||
else |
||||
acx_pthread_ok=no |
||||
$2 |
||||
fi |
||||
AC_LANG_RESTORE |
||||
])dnl ACX_PTHREAD |
@ -1,74 +0,0 @@ |
||||
dnl GTEST_LIB_CHECK([minimum version [, |
||||
dnl action if found [,action if not found]]]) |
||||
dnl |
||||
dnl Check for the presence of the Google Test library, optionally at a minimum |
||||
dnl version, and indicate a viable version with the HAVE_GTEST flag. It defines |
||||
dnl standard variables for substitution including GTEST_CPPFLAGS, |
||||
dnl GTEST_CXXFLAGS, GTEST_LDFLAGS, and GTEST_LIBS. It also defines |
||||
dnl GTEST_VERSION as the version of Google Test found. Finally, it provides |
||||
dnl optional custom action slots in the event GTEST is found or not. |
||||
AC_DEFUN([GTEST_LIB_CHECK], |
||||
[ |
||||
dnl Provide a flag to enable or disable Google Test usage. |
||||
AC_ARG_ENABLE([gtest], |
||||
[AS_HELP_STRING([--enable-gtest], |
||||
[Enable tests using the Google C++ Testing Framework. |
||||
(Default is enabled.)])], |
||||
[], |
||||
[enable_gtest=]) |
||||
AC_ARG_VAR([GTEST_CONFIG], |
||||
[The exact path of Google Test's 'gtest-config' script.]) |
||||
AC_ARG_VAR([GTEST_CPPFLAGS], |
||||
[C-like preprocessor flags for Google Test.]) |
||||
AC_ARG_VAR([GTEST_CXXFLAGS], |
||||
[C++ compile flags for Google Test.]) |
||||
AC_ARG_VAR([GTEST_LDFLAGS], |
||||
[Linker path and option flags for Google Test.]) |
||||
AC_ARG_VAR([GTEST_LIBS], |
||||
[Library linking flags for Google Test.]) |
||||
AC_ARG_VAR([GTEST_VERSION], |
||||
[The version of Google Test available.]) |
||||
HAVE_GTEST="no" |
||||
AS_IF([test "x${enable_gtest}" != "xno"], |
||||
[AC_MSG_CHECKING([for 'gtest-config']) |
||||
AS_IF([test "x${enable_gtest}" != "xyes"], |
||||
[AS_IF([test -x "${enable_gtest}/scripts/gtest-config"], |
||||
[GTEST_CONFIG="${enable_gtest}/scripts/gtest-config"], |
||||
[GTEST_CONFIG="${enable_gtest}/bin/gtest-config"]) |
||||
AS_IF([test -x "${GTEST_CONFIG}"], [], |
||||
[AC_MSG_RESULT([no]) |
||||
AC_MSG_ERROR([dnl |
||||
Unable to locate either a built or installed Google Test. |
||||
The specific location '${enable_gtest}' was provided for a built or installed |
||||
Google Test, but no 'gtest-config' script could be found at this location.]) |
||||
])], |
||||
[AC_PATH_PROG([GTEST_CONFIG], [gtest-config])]) |
||||
AS_IF([test -x "${GTEST_CONFIG}"], |
||||
[AC_MSG_RESULT([${GTEST_CONFIG}]) |
||||
m4_ifval([$1], |
||||
[_gtest_min_version="--min-version=$1" |
||||
AC_MSG_CHECKING([for Google Test at least version >= $1])], |
||||
[_gtest_min_version="--min-version=0" |
||||
AC_MSG_CHECKING([for Google Test])]) |
||||
AS_IF([${GTEST_CONFIG} ${_gtest_min_version}], |
||||
[AC_MSG_RESULT([yes]) |
||||
HAVE_GTEST='yes'], |
||||
[AC_MSG_RESULT([no])])], |
||||
[AC_MSG_RESULT([no])]) |
||||
AS_IF([test "x${HAVE_GTEST}" = "xyes"], |
||||
[GTEST_CPPFLAGS=`${GTEST_CONFIG} --cppflags` |
||||
GTEST_CXXFLAGS=`${GTEST_CONFIG} --cxxflags` |
||||
GTEST_LDFLAGS=`${GTEST_CONFIG} --ldflags` |
||||
GTEST_LIBS=`${GTEST_CONFIG} --libs` |
||||
GTEST_VERSION=`${GTEST_CONFIG} --version` |
||||
AC_DEFINE([HAVE_GTEST],[1],[Defined when Google Test is available.])], |
||||
[AS_IF([test "x${enable_gtest}" = "xyes"], |
||||
[AC_MSG_ERROR([dnl |
||||
Google Test was enabled, but no viable version could be found.]) |
||||
])])]) |
||||
AC_SUBST([HAVE_GTEST]) |
||||
AM_CONDITIONAL([HAVE_GTEST],[test "x$HAVE_GTEST" = "xyes"]) |
||||
AS_IF([test "x$HAVE_GTEST" = "xyes"], |
||||
[m4_ifval([$2], [$2])], |
||||
[m4_ifval([$3], [$3])]) |
||||
]) |
@ -1,88 +0,0 @@ |
||||
# A sample Makefile for building Google Test and using it in user
|
||||
# tests. Please tweak it to suit your environment and project. You
|
||||
# may want to move it to your project's root directory.
|
||||
#
|
||||
# SYNOPSIS:
|
||||
#
|
||||
# make [all] - makes everything.
|
||||
# make TARGET - makes the given target.
|
||||
# make clean - removes all files generated by make.
|
||||
|
||||
# Please tweak the following variable definitions as needed by your
|
||||
# project, except GTEST_HEADERS, which you can use in your own targets
|
||||
# but shouldn't modify.
|
||||
|
||||
# Points to the root of Google Test, relative to where this file is.
|
||||
# Remember to tweak this if you move this file.
|
||||
GTEST_DIR = ..
|
||||
|
||||
# Points to the location of the Google Test libraries
|
||||
GTEST_LIB_DIR = .
|
||||
|
||||
# Where to find user code.
|
||||
USER_DIR = ../samples
|
||||
|
||||
# Flags passed to the preprocessor.
|
||||
# Set Google Test's header directory as a system directory, such that
|
||||
# the compiler doesn't generate warnings in Google Test headers.
|
||||
CPPFLAGS += -isystem $(GTEST_DIR)/include
|
||||
|
||||
# Flags passed to the C++ compiler.
|
||||
CXXFLAGS += -g -Wall -Wextra -pthread -std=c++11
|
||||
|
||||
# Google Test libraries
|
||||
GTEST_LIBS = libgtest.a libgtest_main.a
|
||||
|
||||
# All tests produced by this Makefile. Remember to add new tests you
|
||||
# created to the list.
|
||||
TESTS = sample1_unittest
|
||||
|
||||
# All Google Test headers. Usually you shouldn't change this
|
||||
# definition.
|
||||
GTEST_HEADERS = $(GTEST_DIR)/include/gtest/*.h \
|
||||
$(GTEST_DIR)/include/gtest/internal/*.h
|
||||
|
||||
# House-keeping build targets.
|
||||
|
||||
all : $(GTEST_LIBS) $(TESTS) |
||||
|
||||
clean : |
||||
rm -f $(GTEST_LIBS) $(TESTS) *.o
|
||||
|
||||
# Builds gtest.a and gtest_main.a.
|
||||
|
||||
# Usually you shouldn't tweak such internal variables, indicated by a
|
||||
# trailing _.
|
||||
GTEST_SRCS_ = $(GTEST_DIR)/src/*.cc $(GTEST_DIR)/src/*.h $(GTEST_HEADERS)
|
||||
|
||||
# For simplicity and to avoid depending on Google Test's
|
||||
# implementation details, the dependencies specified below are
|
||||
# conservative and not optimized. This is fine as Google Test
|
||||
# compiles fast and for ordinary users its source rarely changes.
|
||||
gtest-all.o : $(GTEST_SRCS_) |
||||
$(CXX) $(CPPFLAGS) -I$(GTEST_DIR) $(CXXFLAGS) -c \
|
||||
$(GTEST_DIR)/src/gtest-all.cc
|
||||
|
||||
gtest_main.o : $(GTEST_SRCS_) |
||||
$(CXX) $(CPPFLAGS) -I$(GTEST_DIR) $(CXXFLAGS) -c \
|
||||
$(GTEST_DIR)/src/gtest_main.cc
|
||||
|
||||
libgtest.a : gtest-all.o |
||||
$(AR) $(ARFLAGS) $@ $^
|
||||
|
||||
libgtest_main.a : gtest-all.o gtest_main.o |
||||
$(AR) $(ARFLAGS) $@ $^
|
||||
|
||||
# Builds a sample test. A test should link with either gtest.a or
|
||||
# gtest_main.a, depending on whether it defines its own main()
|
||||
# function.
|
||||
|
||||
sample1.o : $(USER_DIR)/sample1.cc $(USER_DIR)/sample1.h $(GTEST_HEADERS) |
||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/sample1.cc
|
||||
|
||||
sample1_unittest.o : $(USER_DIR)/sample1_unittest.cc \
|
||||
$(USER_DIR)/sample1.h $(GTEST_HEADERS)
|
||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/sample1_unittest.cc
|
||||
|
||||
sample1_unittest : sample1.o sample1_unittest.o $(GTEST_LIBS) |
||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -L$(GTEST_LIB_DIR) -lgtest_main -lpthread $^ -o $@
|
@ -1,55 +0,0 @@ |
||||
Microsoft Visual Studio Solution File, Format Version 11.00 |
||||
# Visual C++ Express 2010 |
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest-md", "gtest-md.vcxproj", "{C8F6C172-56F2-4E76-B5FA-C3B423B31BE8}" |
||||
EndProject |
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest_main-md", "gtest_main-md.vcxproj", "{3AF54C8A-10BF-4332-9147-F68ED9862033}" |
||||
EndProject |
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest_prod_test-md", "gtest_prod_test-md.vcxproj", "{24848551-EF4F-47E8-9A9D-EA4D49BC3ECB}" |
||||
EndProject |
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest_unittest-md", "gtest_unittest-md.vcxproj", "{4D9FDFB5-986A-4139-823C-F4EE0ED481A2}" |
||||
EndProject |
||||
Global |
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution |
||||
Debug|Win32 = Debug|Win32 |
||||
Debug|x64 = Debug|x64 |
||||
Release|Win32 = Release|Win32 |
||||
Release|x64 = Release|x64 |
||||
EndGlobalSection |
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution |
||||
{C8F6C172-56F2-4E76-B5FA-C3B423B31BE8}.Debug|Win32.ActiveCfg = Debug|Win32 |
||||
{C8F6C172-56F2-4E76-B5FA-C3B423B31BE8}.Debug|Win32.Build.0 = Debug|Win32 |
||||
{C8F6C172-56F2-4E76-B5FA-C3B423B31BE8}.Debug|x64.ActiveCfg = Debug|x64 |
||||
{C8F6C172-56F2-4E76-B5FA-C3B423B31BE8}.Debug|x64.Build.0 = Debug|x64 |
||||
{C8F6C172-56F2-4E76-B5FA-C3B423B31BE8}.Release|Win32.ActiveCfg = Release|Win32 |
||||
{C8F6C172-56F2-4E76-B5FA-C3B423B31BE8}.Release|Win32.Build.0 = Release|Win32 |
||||
{C8F6C172-56F2-4E76-B5FA-C3B423B31BE8}.Release|x64.ActiveCfg = Release|x64 |
||||
{C8F6C172-56F2-4E76-B5FA-C3B423B31BE8}.Release|x64.Build.0 = Release|x64 |
||||
{3AF54C8A-10BF-4332-9147-F68ED9862033}.Debug|Win32.ActiveCfg = Debug|Win32 |
||||
{3AF54C8A-10BF-4332-9147-F68ED9862033}.Debug|Win32.Build.0 = Debug|Win32 |
||||
{3AF54C8A-10BF-4332-9147-F68ED9862033}.Debug|x64.ActiveCfg = Debug|x64 |
||||
{3AF54C8A-10BF-4332-9147-F68ED9862033}.Debug|x64.Build.0 = Debug|x64 |
||||
{3AF54C8A-10BF-4332-9147-F68ED9862033}.Release|Win32.ActiveCfg = Release|Win32 |
||||
{3AF54C8A-10BF-4332-9147-F68ED9862033}.Release|Win32.Build.0 = Release|Win32 |
||||
{3AF54C8A-10BF-4332-9147-F68ED9862033}.Release|x64.ActiveCfg = Release|x64 |
||||
{3AF54C8A-10BF-4332-9147-F68ED9862033}.Release|x64.Build.0 = Release|x64 |
||||
{24848551-EF4F-47E8-9A9D-EA4D49BC3ECB}.Debug|Win32.ActiveCfg = Debug|Win32 |
||||
{24848551-EF4F-47E8-9A9D-EA4D49BC3ECB}.Debug|Win32.Build.0 = Debug|Win32 |
||||
{24848551-EF4F-47E8-9A9D-EA4D49BC3ECB}.Debug|x64.ActiveCfg = Debug|x64 |
||||
{24848551-EF4F-47E8-9A9D-EA4D49BC3ECB}.Debug|x64.Build.0 = Debug|x64 |
||||
{24848551-EF4F-47E8-9A9D-EA4D49BC3ECB}.Release|Win32.ActiveCfg = Release|Win32 |
||||
{24848551-EF4F-47E8-9A9D-EA4D49BC3ECB}.Release|Win32.Build.0 = Release|Win32 |
||||
{24848551-EF4F-47E8-9A9D-EA4D49BC3ECB}.Release|x64.ActiveCfg = Release|x64 |
||||
{24848551-EF4F-47E8-9A9D-EA4D49BC3ECB}.Release|x64.Build.0 = Release|x64 |
||||
{4D9FDFB5-986A-4139-823C-F4EE0ED481A2}.Debug|Win32.ActiveCfg = Debug|Win32 |
||||
{4D9FDFB5-986A-4139-823C-F4EE0ED481A2}.Debug|Win32.Build.0 = Debug|Win32 |
||||
{4D9FDFB5-986A-4139-823C-F4EE0ED481A2}.Debug|x64.ActiveCfg = Debug|x64 |
||||
{4D9FDFB5-986A-4139-823C-F4EE0ED481A2}.Debug|x64.Build.0 = Debug|x64 |
||||
{4D9FDFB5-986A-4139-823C-F4EE0ED481A2}.Release|Win32.ActiveCfg = Release|Win32 |
||||
{4D9FDFB5-986A-4139-823C-F4EE0ED481A2}.Release|Win32.Build.0 = Release|Win32 |
||||
{4D9FDFB5-986A-4139-823C-F4EE0ED481A2}.Release|x64.ActiveCfg = Release|x64 |
||||
{4D9FDFB5-986A-4139-823C-F4EE0ED481A2}.Release|x64.Build.0 = Release|x64 |
||||
EndGlobalSection |
||||
GlobalSection(SolutionProperties) = preSolution |
||||
HideSolutionNode = FALSE |
||||
EndGlobalSection |
||||
EndGlobal |
@ -1,55 +0,0 @@ |
||||
Microsoft Visual Studio Solution File, Format Version 11.00 |
||||
# Visual C++ Express 2010 |
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest", "gtest.vcxproj", "{C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}" |
||||
EndProject |
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest_main", "gtest_main.vcxproj", "{3AF54C8A-10BF-4332-9147-F68ED9862032}" |
||||
EndProject |
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest_unittest", "gtest_unittest.vcxproj", "{4D9FDFB5-986A-4139-823C-F4EE0ED481A1}" |
||||
EndProject |
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest_prod_test", "gtest_prod_test.vcxproj", "{24848551-EF4F-47E8-9A9D-EA4D49BC3ECA}" |
||||
EndProject |
||||
Global |
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution |
||||
Debug|Win32 = Debug|Win32 |
||||
Debug|x64 = Debug|x64 |
||||
Release|Win32 = Release|Win32 |
||||
Release|x64 = Release|x64 |
||||
EndGlobalSection |
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution |
||||
{C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Debug|Win32.ActiveCfg = Debug|Win32 |
||||
{C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Debug|Win32.Build.0 = Debug|Win32 |
||||
{C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Debug|x64.ActiveCfg = Debug|x64 |
||||
{C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Debug|x64.Build.0 = Debug|x64 |
||||
{C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Release|Win32.ActiveCfg = Release|Win32 |
||||
{C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Release|Win32.Build.0 = Release|Win32 |
||||
{C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Release|x64.ActiveCfg = Release|x64 |
||||
{C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Release|x64.Build.0 = Release|x64 |
||||
{3AF54C8A-10BF-4332-9147-F68ED9862032}.Debug|Win32.ActiveCfg = Debug|Win32 |
||||
{3AF54C8A-10BF-4332-9147-F68ED9862032}.Debug|Win32.Build.0 = Debug|Win32 |
||||
{3AF54C8A-10BF-4332-9147-F68ED9862032}.Debug|x64.ActiveCfg = Debug|x64 |
||||
{3AF54C8A-10BF-4332-9147-F68ED9862032}.Debug|x64.Build.0 = Debug|x64 |
||||
{3AF54C8A-10BF-4332-9147-F68ED9862032}.Release|Win32.ActiveCfg = Release|Win32 |
||||
{3AF54C8A-10BF-4332-9147-F68ED9862032}.Release|Win32.Build.0 = Release|Win32 |
||||
{3AF54C8A-10BF-4332-9147-F68ED9862032}.Release|x64.ActiveCfg = Release|x64 |
||||
{3AF54C8A-10BF-4332-9147-F68ED9862032}.Release|x64.Build.0 = Release|x64 |
||||
{4D9FDFB5-986A-4139-823C-F4EE0ED481A1}.Debug|Win32.ActiveCfg = Debug|Win32 |
||||
{4D9FDFB5-986A-4139-823C-F4EE0ED481A1}.Debug|Win32.Build.0 = Debug|Win32 |
||||
{4D9FDFB5-986A-4139-823C-F4EE0ED481A1}.Debug|x64.ActiveCfg = Debug|x64 |
||||
{4D9FDFB5-986A-4139-823C-F4EE0ED481A1}.Debug|x64.Build.0 = Debug|x64 |
||||
{4D9FDFB5-986A-4139-823C-F4EE0ED481A1}.Release|Win32.ActiveCfg = Release|Win32 |
||||
{4D9FDFB5-986A-4139-823C-F4EE0ED481A1}.Release|Win32.Build.0 = Release|Win32 |
||||
{4D9FDFB5-986A-4139-823C-F4EE0ED481A1}.Release|x64.ActiveCfg = Release|x64 |
||||
{4D9FDFB5-986A-4139-823C-F4EE0ED481A1}.Release|x64.Build.0 = Release|x64 |
||||
{24848551-EF4F-47E8-9A9D-EA4D49BC3ECA}.Debug|Win32.ActiveCfg = Debug|Win32 |
||||
{24848551-EF4F-47E8-9A9D-EA4D49BC3ECA}.Debug|Win32.Build.0 = Debug|Win32 |
||||
{24848551-EF4F-47E8-9A9D-EA4D49BC3ECA}.Debug|x64.ActiveCfg = Debug|x64 |
||||
{24848551-EF4F-47E8-9A9D-EA4D49BC3ECA}.Debug|x64.Build.0 = Debug|x64 |
||||
{24848551-EF4F-47E8-9A9D-EA4D49BC3ECA}.Release|Win32.ActiveCfg = Release|Win32 |
||||
{24848551-EF4F-47E8-9A9D-EA4D49BC3ECA}.Release|Win32.Build.0 = Release|Win32 |
||||
{24848551-EF4F-47E8-9A9D-EA4D49BC3ECA}.Release|x64.ActiveCfg = Release|x64 |
||||
{24848551-EF4F-47E8-9A9D-EA4D49BC3ECA}.Release|x64.Build.0 = Release|x64 |
||||
EndGlobalSection |
||||
GlobalSection(SolutionProperties) = preSolution |
||||
HideSolutionNode = FALSE |
||||
EndGlobalSection |
||||
EndGlobal |
@ -1,855 +0,0 @@ |
||||
#!/usr/bin/env python |
||||
# |
||||
# Copyright 2008, 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. |
||||
|
||||
"""pump v0.2.0 - Pretty Useful for Meta Programming. |
||||
|
||||
A tool for preprocessor meta programming. Useful for generating |
||||
repetitive boilerplate code. Especially useful for writing C++ |
||||
classes, functions, macros, and templates that need to work with |
||||
various number of arguments. |
||||
|
||||
USAGE: |
||||
pump.py SOURCE_FILE |
||||
|
||||
EXAMPLES: |
||||
pump.py foo.cc.pump |
||||
Converts foo.cc.pump to foo.cc. |
||||
|
||||
GRAMMAR: |
||||
CODE ::= ATOMIC_CODE* |
||||
ATOMIC_CODE ::= $var ID = EXPRESSION |
||||
| $var ID = [[ CODE ]] |
||||
| $range ID EXPRESSION..EXPRESSION |
||||
| $for ID SEPARATOR [[ CODE ]] |
||||
| $($) |
||||
| $ID |
||||
| $(EXPRESSION) |
||||
| $if EXPRESSION [[ CODE ]] ELSE_BRANCH |
||||
| [[ CODE ]] |
||||
| RAW_CODE |
||||
SEPARATOR ::= RAW_CODE | EMPTY |
||||
ELSE_BRANCH ::= $else [[ CODE ]] |
||||
| $elif EXPRESSION [[ CODE ]] ELSE_BRANCH |
||||
| EMPTY |
||||
EXPRESSION has Python syntax. |
||||
""" |
||||
|
||||
__author__ = 'wan@google.com (Zhanyong Wan)' |
||||
|
||||
import os |
||||
import re |
||||
import sys |
||||
|
||||
|
||||
TOKEN_TABLE = [ |
||||
(re.compile(r'\$var\s+'), '$var'), |
||||
(re.compile(r'\$elif\s+'), '$elif'), |
||||
(re.compile(r'\$else\s+'), '$else'), |
||||
(re.compile(r'\$for\s+'), '$for'), |
||||
(re.compile(r'\$if\s+'), '$if'), |
||||
(re.compile(r'\$range\s+'), '$range'), |
||||
(re.compile(r'\$[_A-Za-z]\w*'), '$id'), |
||||
(re.compile(r'\$\(\$\)'), '$($)'), |
||||
(re.compile(r'\$'), '$'), |
||||
(re.compile(r'\[\[\n?'), '[['), |
||||
(re.compile(r'\]\]\n?'), ']]'), |
||||
] |
||||
|
||||
|
||||
class Cursor: |
||||
"""Represents a position (line and column) in a text file.""" |
||||
|
||||
def __init__(self, line=-1, column=-1): |
||||
self.line = line |
||||
self.column = column |
||||
|
||||
def __eq__(self, rhs): |
||||
return self.line == rhs.line and self.column == rhs.column |
||||
|
||||
def __ne__(self, rhs): |
||||
return not self == rhs |
||||
|
||||
def __lt__(self, rhs): |
||||
return self.line < rhs.line or ( |
||||
self.line == rhs.line and self.column < rhs.column) |
||||
|
||||
def __le__(self, rhs): |
||||
return self < rhs or self == rhs |
||||
|
||||
def __gt__(self, rhs): |
||||
return rhs < self |
||||
|
||||
def __ge__(self, rhs): |
||||
return rhs <= self |
||||
|
||||
def __str__(self): |
||||
if self == Eof(): |
||||
return 'EOF' |
||||
else: |
||||
return '%s(%s)' % (self.line + 1, self.column) |
||||
|
||||
def __add__(self, offset): |
||||
return Cursor(self.line, self.column + offset) |
||||
|
||||
def __sub__(self, offset): |
||||
return Cursor(self.line, self.column - offset) |
||||
|
||||
def Clone(self): |
||||
"""Returns a copy of self.""" |
||||
|
||||
return Cursor(self.line, self.column) |
||||
|
||||
|
||||
# Special cursor to indicate the end-of-file. |
||||
def Eof(): |
||||
"""Returns the special cursor to denote the end-of-file.""" |
||||
return Cursor(-1, -1) |
||||
|
||||
|
||||
class Token: |
||||
"""Represents a token in a Pump source file.""" |
||||
|
||||
def __init__(self, start=None, end=None, value=None, token_type=None): |
||||
if start is None: |
||||
self.start = Eof() |
||||
else: |
||||
self.start = start |
||||
if end is None: |
||||
self.end = Eof() |
||||
else: |
||||
self.end = end |
||||
self.value = value |
||||
self.token_type = token_type |
||||
|
||||
def __str__(self): |
||||
return 'Token @%s: \'%s\' type=%s' % ( |
||||
self.start, self.value, self.token_type) |
||||
|
||||
def Clone(self): |
||||
"""Returns a copy of self.""" |
||||
|
||||
return Token(self.start.Clone(), self.end.Clone(), self.value, |
||||
self.token_type) |
||||
|
||||
|
||||
def StartsWith(lines, pos, string): |
||||
"""Returns True iff the given position in lines starts with 'string'.""" |
||||
|
||||
return lines[pos.line][pos.column:].startswith(string) |
||||
|
||||
|
||||
def FindFirstInLine(line, token_table): |
||||
best_match_start = -1 |
||||
for (regex, token_type) in token_table: |
||||
m = regex.search(line) |
||||
if m: |
||||
# We found regex in lines |
||||
if best_match_start < 0 or m.start() < best_match_start: |
||||
best_match_start = m.start() |
||||
best_match_length = m.end() - m.start() |
||||
best_match_token_type = token_type |
||||
|
||||
if best_match_start < 0: |
||||
return None |
||||
|
||||
return (best_match_start, best_match_length, best_match_token_type) |
||||
|
||||
|
||||
def FindFirst(lines, token_table, cursor): |
||||
"""Finds the first occurrence of any string in strings in lines.""" |
||||
|
||||
start = cursor.Clone() |
||||
cur_line_number = cursor.line |
||||
for line in lines[start.line:]: |
||||
if cur_line_number == start.line: |
||||
line = line[start.column:] |
||||
m = FindFirstInLine(line, token_table) |
||||
if m: |
||||
# We found a regex in line. |
||||
(start_column, length, token_type) = m |
||||
if cur_line_number == start.line: |
||||
start_column += start.column |
||||
found_start = Cursor(cur_line_number, start_column) |
||||
found_end = found_start + length |
||||
return MakeToken(lines, found_start, found_end, token_type) |
||||
cur_line_number += 1 |
||||
# We failed to find str in lines |
||||
return None |
||||
|
||||
|
||||
def SubString(lines, start, end): |
||||
"""Returns a substring in lines.""" |
||||
|
||||
if end == Eof(): |
||||
end = Cursor(len(lines) - 1, len(lines[-1])) |
||||
|
||||
if start >= end: |
||||
return '' |
||||
|
||||
if start.line == end.line: |
||||
return lines[start.line][start.column:end.column] |
||||
|
||||
result_lines = ([lines[start.line][start.column:]] + |
||||
lines[start.line + 1:end.line] + |
||||
[lines[end.line][:end.column]]) |
||||
return ''.join(result_lines) |
||||
|
||||
|
||||
def StripMetaComments(str): |
||||
"""Strip meta comments from each line in the given string.""" |
||||
|
||||
# First, completely remove lines containing nothing but a meta |
||||
# comment, including the trailing \n. |
||||
str = re.sub(r'^\s*\$\$.*\n', '', str) |
||||
|
||||
# Then, remove meta comments from contentful lines. |
||||
return re.sub(r'\s*\$\$.*', '', str) |
||||
|
||||
|
||||
def MakeToken(lines, start, end, token_type): |
||||
"""Creates a new instance of Token.""" |
||||
|
||||
return Token(start, end, SubString(lines, start, end), token_type) |
||||
|
||||
|
||||
def ParseToken(lines, pos, regex, token_type): |
||||
line = lines[pos.line][pos.column:] |
||||
m = regex.search(line) |
||||
if m and not m.start(): |
||||
return MakeToken(lines, pos, pos + m.end(), token_type) |
||||
else: |
||||
print 'ERROR: %s expected at %s.' % (token_type, pos) |
||||
sys.exit(1) |
||||
|
||||
|
||||
ID_REGEX = re.compile(r'[_A-Za-z]\w*') |
||||
EQ_REGEX = re.compile(r'=') |
||||
REST_OF_LINE_REGEX = re.compile(r'.*?(?=$|\$\$)') |
||||
OPTIONAL_WHITE_SPACES_REGEX = re.compile(r'\s*') |
||||
WHITE_SPACE_REGEX = re.compile(r'\s') |
||||
DOT_DOT_REGEX = re.compile(r'\.\.') |
||||
|
||||
|
||||
def Skip(lines, pos, regex): |
||||
line = lines[pos.line][pos.column:] |
||||
m = re.search(regex, line) |
||||
if m and not m.start(): |
||||
return pos + m.end() |
||||
else: |
||||
return pos |
||||
|
||||
|
||||
def SkipUntil(lines, pos, regex, token_type): |
||||
line = lines[pos.line][pos.column:] |
||||
m = re.search(regex, line) |
||||
if m: |
||||
return pos + m.start() |
||||
else: |
||||
print ('ERROR: %s expected on line %s after column %s.' % |
||||
(token_type, pos.line + 1, pos.column)) |
||||
sys.exit(1) |
||||
|
||||
|
||||
def ParseExpTokenInParens(lines, pos): |
||||
def ParseInParens(pos): |
||||
pos = Skip(lines, pos, OPTIONAL_WHITE_SPACES_REGEX) |
||||
pos = Skip(lines, pos, r'\(') |
||||
pos = Parse(pos) |
||||
pos = Skip(lines, pos, r'\)') |
||||
return pos |
||||
|
||||
def Parse(pos): |
||||
pos = SkipUntil(lines, pos, r'\(|\)', ')') |
||||
if SubString(lines, pos, pos + 1) == '(': |
||||
pos = Parse(pos + 1) |
||||
pos = Skip(lines, pos, r'\)') |
||||
return Parse(pos) |
||||
else: |
||||
return pos |
||||
|
||||
start = pos.Clone() |
||||
pos = ParseInParens(pos) |
||||
return MakeToken(lines, start, pos, 'exp') |
||||
|
||||
|
||||
def RStripNewLineFromToken(token): |
||||
if token.value.endswith('\n'): |
||||
return Token(token.start, token.end, token.value[:-1], token.token_type) |
||||
else: |
||||
return token |
||||
|
||||
|
||||
def TokenizeLines(lines, pos): |
||||
while True: |
||||
found = FindFirst(lines, TOKEN_TABLE, pos) |
||||
if not found: |
||||
yield MakeToken(lines, pos, Eof(), 'code') |
||||
return |
||||
|
||||
if found.start == pos: |
||||
prev_token = None |
||||
prev_token_rstripped = None |
||||
else: |
||||
prev_token = MakeToken(lines, pos, found.start, 'code') |
||||
prev_token_rstripped = RStripNewLineFromToken(prev_token) |
||||
|
||||
if found.token_type == '$var': |
||||
if prev_token_rstripped: |
||||
yield prev_token_rstripped |
||||
yield found |
||||
id_token = ParseToken(lines, found.end, ID_REGEX, 'id') |
||||
yield id_token |
||||
pos = Skip(lines, id_token.end, OPTIONAL_WHITE_SPACES_REGEX) |
||||
|
||||
eq_token = ParseToken(lines, pos, EQ_REGEX, '=') |
||||
yield eq_token |
||||
pos = Skip(lines, eq_token.end, r'\s*') |
||||
|
||||
if SubString(lines, pos, pos + 2) != '[[': |
||||
exp_token = ParseToken(lines, pos, REST_OF_LINE_REGEX, 'exp') |
||||
yield exp_token |
||||
pos = Cursor(exp_token.end.line + 1, 0) |
||||
elif found.token_type == '$for': |
||||
if prev_token_rstripped: |
||||
yield prev_token_rstripped |
||||
yield found |
||||
id_token = ParseToken(lines, found.end, ID_REGEX, 'id') |
||||
yield id_token |
||||
pos = Skip(lines, id_token.end, WHITE_SPACE_REGEX) |
||||
elif found.token_type == '$range': |
||||
if prev_token_rstripped: |
||||
yield prev_token_rstripped |
||||
yield found |
||||
id_token = ParseToken(lines, found.end, ID_REGEX, 'id') |
||||
yield id_token |
||||
pos = Skip(lines, id_token.end, OPTIONAL_WHITE_SPACES_REGEX) |
||||
|
||||
dots_pos = SkipUntil(lines, pos, DOT_DOT_REGEX, '..') |
||||
yield MakeToken(lines, pos, dots_pos, 'exp') |
||||
yield MakeToken(lines, dots_pos, dots_pos + 2, '..') |
||||
pos = dots_pos + 2 |
||||
new_pos = Cursor(pos.line + 1, 0) |
||||
yield MakeToken(lines, pos, new_pos, 'exp') |
||||
pos = new_pos |
||||
elif found.token_type == '$': |
||||
if prev_token: |
||||
yield prev_token |
||||
yield found |
||||
exp_token = ParseExpTokenInParens(lines, found.end) |
||||
yield exp_token |
||||
pos = exp_token.end |
||||
elif (found.token_type == ']]' or found.token_type == '$if' or |
||||
found.token_type == '$elif' or found.token_type == '$else'): |
||||
if prev_token_rstripped: |
||||
yield prev_token_rstripped |
||||
yield found |
||||
pos = found.end |
||||
else: |
||||
if prev_token: |
||||
yield prev_token |
||||
yield found |
||||
pos = found.end |
||||
|
||||
|
||||
def Tokenize(s): |
||||
"""A generator that yields the tokens in the given string.""" |
||||
if s != '': |
||||
lines = s.splitlines(True) |
||||
for token in TokenizeLines(lines, Cursor(0, 0)): |
||||
yield token |
||||
|
||||
|
||||
class CodeNode: |
||||
def __init__(self, atomic_code_list=None): |
||||
self.atomic_code = atomic_code_list |
||||
|
||||
|
||||
class VarNode: |
||||
def __init__(self, identifier=None, atomic_code=None): |
||||
self.identifier = identifier |
||||
self.atomic_code = atomic_code |
||||
|
||||
|
||||
class RangeNode: |
||||
def __init__(self, identifier=None, exp1=None, exp2=None): |
||||
self.identifier = identifier |
||||
self.exp1 = exp1 |
||||
self.exp2 = exp2 |
||||
|
||||
|
||||
class ForNode: |
||||
def __init__(self, identifier=None, sep=None, code=None): |
||||
self.identifier = identifier |
||||
self.sep = sep |
||||
self.code = code |
||||
|
||||
|
||||
class ElseNode: |
||||
def __init__(self, else_branch=None): |
||||
self.else_branch = else_branch |
||||
|
||||
|
||||
class IfNode: |
||||
def __init__(self, exp=None, then_branch=None, else_branch=None): |
||||
self.exp = exp |
||||
self.then_branch = then_branch |
||||
self.else_branch = else_branch |
||||
|
||||
|
||||
class RawCodeNode: |
||||
def __init__(self, token=None): |
||||
self.raw_code = token |
||||
|
||||
|
||||
class LiteralDollarNode: |
||||
def __init__(self, token): |
||||
self.token = token |
||||
|
||||
|
||||
class ExpNode: |
||||
def __init__(self, token, python_exp): |
||||
self.token = token |
||||
self.python_exp = python_exp |
||||
|
||||
|
||||
def PopFront(a_list): |
||||
head = a_list[0] |
||||
a_list[:1] = [] |
||||
return head |
||||
|
||||
|
||||
def PushFront(a_list, elem): |
||||
a_list[:0] = [elem] |
||||
|
||||
|
||||
def PopToken(a_list, token_type=None): |
||||
token = PopFront(a_list) |
||||
if token_type is not None and token.token_type != token_type: |
||||
print 'ERROR: %s expected at %s' % (token_type, token.start) |
||||
print 'ERROR: %s found instead' % (token,) |
||||
sys.exit(1) |
||||
|
||||
return token |
||||
|
||||
|
||||
def PeekToken(a_list): |
||||
if not a_list: |
||||
return None |
||||
|
||||
return a_list[0] |
||||
|
||||
|
||||
def ParseExpNode(token): |
||||
python_exp = re.sub(r'([_A-Za-z]\w*)', r'self.GetValue("\1")', token.value) |
||||
return ExpNode(token, python_exp) |
||||
|
||||
|
||||
def ParseElseNode(tokens): |
||||
def Pop(token_type=None): |
||||
return PopToken(tokens, token_type) |
||||
|
||||
next = PeekToken(tokens) |
||||
if not next: |
||||
return None |
||||
if next.token_type == '$else': |
||||
Pop('$else') |
||||
Pop('[[') |
||||
code_node = ParseCodeNode(tokens) |
||||
Pop(']]') |
||||
return code_node |
||||
elif next.token_type == '$elif': |
||||
Pop('$elif') |
||||
exp = Pop('code') |
||||
Pop('[[') |
||||
code_node = ParseCodeNode(tokens) |
||||
Pop(']]') |
||||
inner_else_node = ParseElseNode(tokens) |
||||
return CodeNode([IfNode(ParseExpNode(exp), code_node, inner_else_node)]) |
||||
elif not next.value.strip(): |
||||
Pop('code') |
||||
return ParseElseNode(tokens) |
||||
else: |
||||
return None |
||||
|
||||
|
||||
def ParseAtomicCodeNode(tokens): |
||||
def Pop(token_type=None): |
||||
return PopToken(tokens, token_type) |
||||
|
||||
head = PopFront(tokens) |
||||
t = head.token_type |
||||
if t == 'code': |
||||
return RawCodeNode(head) |
||||
elif t == '$var': |
||||
id_token = Pop('id') |
||||
Pop('=') |
||||
next = PeekToken(tokens) |
||||
if next.token_type == 'exp': |
||||
exp_token = Pop() |
||||
return VarNode(id_token, ParseExpNode(exp_token)) |
||||
Pop('[[') |
||||
code_node = ParseCodeNode(tokens) |
||||
Pop(']]') |
||||
return VarNode(id_token, code_node) |
||||
elif t == '$for': |
||||
id_token = Pop('id') |
||||
next_token = PeekToken(tokens) |
||||
if next_token.token_type == 'code': |
||||
sep_token = next_token |
||||
Pop('code') |
||||
else: |
||||
sep_token = None |
||||
Pop('[[') |
||||
code_node = ParseCodeNode(tokens) |
||||
Pop(']]') |
||||
return ForNode(id_token, sep_token, code_node) |
||||
elif t == '$if': |
||||
exp_token = Pop('code') |
||||
Pop('[[') |
||||
code_node = ParseCodeNode(tokens) |
||||
Pop(']]') |
||||
else_node = ParseElseNode(tokens) |
||||
return IfNode(ParseExpNode(exp_token), code_node, else_node) |
||||
elif t == '$range': |
||||
id_token = Pop('id') |
||||
exp1_token = Pop('exp') |
||||
Pop('..') |
||||
exp2_token = Pop('exp') |
||||
return RangeNode(id_token, ParseExpNode(exp1_token), |
||||
ParseExpNode(exp2_token)) |
||||
elif t == '$id': |
||||
return ParseExpNode(Token(head.start + 1, head.end, head.value[1:], 'id')) |
||||
elif t == '$($)': |
||||
return LiteralDollarNode(head) |
||||
elif t == '$': |
||||
exp_token = Pop('exp') |
||||
return ParseExpNode(exp_token) |
||||
elif t == '[[': |
||||
code_node = ParseCodeNode(tokens) |
||||
Pop(']]') |
||||
return code_node |
||||
else: |
||||
PushFront(tokens, head) |
||||
return None |
||||
|
||||
|
||||
def ParseCodeNode(tokens): |
||||
atomic_code_list = [] |
||||
while True: |
||||
if not tokens: |
||||
break |
||||
atomic_code_node = ParseAtomicCodeNode(tokens) |
||||
if atomic_code_node: |
||||
atomic_code_list.append(atomic_code_node) |
||||
else: |
||||
break |
||||
return CodeNode(atomic_code_list) |
||||
|
||||
|
||||
def ParseToAST(pump_src_text): |
||||
"""Convert the given Pump source text into an AST.""" |
||||
tokens = list(Tokenize(pump_src_text)) |
||||
code_node = ParseCodeNode(tokens) |
||||
return code_node |
||||
|
||||
|
||||
class Env: |
||||
def __init__(self): |
||||
self.variables = [] |
||||
self.ranges = [] |
||||
|
||||
def Clone(self): |
||||
clone = Env() |
||||
clone.variables = self.variables[:] |
||||
clone.ranges = self.ranges[:] |
||||
return clone |
||||
|
||||
def PushVariable(self, var, value): |
||||
# If value looks like an int, store it as an int. |
||||
try: |
||||
int_value = int(value) |
||||
if ('%s' % int_value) == value: |
||||
value = int_value |
||||
except Exception: |
||||
pass |
||||
self.variables[:0] = [(var, value)] |
||||
|
||||
def PopVariable(self): |
||||
self.variables[:1] = [] |
||||
|
||||
def PushRange(self, var, lower, upper): |
||||
self.ranges[:0] = [(var, lower, upper)] |
||||
|
||||
def PopRange(self): |
||||
self.ranges[:1] = [] |
||||
|
||||
def GetValue(self, identifier): |
||||
for (var, value) in self.variables: |
||||
if identifier == var: |
||||
return value |
||||
|
||||
print 'ERROR: meta variable %s is undefined.' % (identifier,) |
||||
sys.exit(1) |
||||
|
||||
def EvalExp(self, exp): |
||||
try: |
||||
result = eval(exp.python_exp) |
||||
except Exception, e: |
||||
print 'ERROR: caught exception %s: %s' % (e.__class__.__name__, e) |
||||
print ('ERROR: failed to evaluate meta expression %s at %s' % |
||||
(exp.python_exp, exp.token.start)) |
||||
sys.exit(1) |
||||
return result |
||||
|
||||
def GetRange(self, identifier): |
||||
for (var, lower, upper) in self.ranges: |
||||
if identifier == var: |
||||
return (lower, upper) |
||||
|
||||
print 'ERROR: range %s is undefined.' % (identifier,) |
||||
sys.exit(1) |
||||
|
||||
|
||||
class Output: |
||||
def __init__(self): |
||||
self.string = '' |
||||
|
||||
def GetLastLine(self): |
||||
index = self.string.rfind('\n') |
||||
if index < 0: |
||||
return '' |
||||
|
||||
return self.string[index + 1:] |
||||
|
||||
def Append(self, s): |
||||
self.string += s |
||||
|
||||
|
||||
def RunAtomicCode(env, node, output): |
||||
if isinstance(node, VarNode): |
||||
identifier = node.identifier.value.strip() |
||||
result = Output() |
||||
RunAtomicCode(env.Clone(), node.atomic_code, result) |
||||
value = result.string |
||||
env.PushVariable(identifier, value) |
||||
elif isinstance(node, RangeNode): |
||||
identifier = node.identifier.value.strip() |
||||
lower = int(env.EvalExp(node.exp1)) |
||||
upper = int(env.EvalExp(node.exp2)) |
||||
env.PushRange(identifier, lower, upper) |
||||
elif isinstance(node, ForNode): |
||||
identifier = node.identifier.value.strip() |
||||
if node.sep is None: |
||||
sep = '' |
||||
else: |
||||
sep = node.sep.value |
||||
(lower, upper) = env.GetRange(identifier) |
||||
for i in range(lower, upper + 1): |
||||
new_env = env.Clone() |
||||
new_env.PushVariable(identifier, i) |
||||
RunCode(new_env, node.code, output) |
||||
if i != upper: |
||||
output.Append(sep) |
||||
elif isinstance(node, RawCodeNode): |
||||
output.Append(node.raw_code.value) |
||||
elif isinstance(node, IfNode): |
||||
cond = env.EvalExp(node.exp) |
||||
if cond: |
||||
RunCode(env.Clone(), node.then_branch, output) |
||||
elif node.else_branch is not None: |
||||
RunCode(env.Clone(), node.else_branch, output) |
||||
elif isinstance(node, ExpNode): |
||||
value = env.EvalExp(node) |
||||
output.Append('%s' % (value,)) |
||||
elif isinstance(node, LiteralDollarNode): |
||||
output.Append('$') |
||||
elif isinstance(node, CodeNode): |
||||
RunCode(env.Clone(), node, output) |
||||
else: |
||||
print 'BAD' |
||||
print node |
||||
sys.exit(1) |
||||
|
||||
|
||||
def RunCode(env, code_node, output): |
||||
for atomic_code in code_node.atomic_code: |
||||
RunAtomicCode(env, atomic_code, output) |
||||
|
||||
|
||||
def IsSingleLineComment(cur_line): |
||||
return '//' in cur_line |
||||
|
||||
|
||||
def IsInPreprocessorDirective(prev_lines, cur_line): |
||||
if cur_line.lstrip().startswith('#'): |
||||
return True |
||||
return prev_lines and prev_lines[-1].endswith('\\') |
||||
|
||||
|
||||
def WrapComment(line, output): |
||||
loc = line.find('//') |
||||
before_comment = line[:loc].rstrip() |
||||
if before_comment == '': |
||||
indent = loc |
||||
else: |
||||
output.append(before_comment) |
||||
indent = len(before_comment) - len(before_comment.lstrip()) |
||||
prefix = indent*' ' + '// ' |
||||
max_len = 80 - len(prefix) |
||||
comment = line[loc + 2:].strip() |
||||
segs = [seg for seg in re.split(r'(\w+\W*)', comment) if seg != ''] |
||||
cur_line = '' |
||||
for seg in segs: |
||||
if len((cur_line + seg).rstrip()) < max_len: |
||||
cur_line += seg |
||||
else: |
||||
if cur_line.strip() != '': |
||||
output.append(prefix + cur_line.rstrip()) |
||||
cur_line = seg.lstrip() |
||||
if cur_line.strip() != '': |
||||
output.append(prefix + cur_line.strip()) |
||||
|
||||
|
||||
def WrapCode(line, line_concat, output): |
||||
indent = len(line) - len(line.lstrip()) |
||||
prefix = indent*' ' # Prefix of the current line |
||||
max_len = 80 - indent - len(line_concat) # Maximum length of the current line |
||||
new_prefix = prefix + 4*' ' # Prefix of a continuation line |
||||
new_max_len = max_len - 4 # Maximum length of a continuation line |
||||
# Prefers to wrap a line after a ',' or ';'. |
||||
segs = [seg for seg in re.split(r'([^,;]+[,;]?)', line.strip()) if seg != ''] |
||||
cur_line = '' # The current line without leading spaces. |
||||
for seg in segs: |
||||
# If the line is still too long, wrap at a space. |
||||
while cur_line == '' and len(seg.strip()) > max_len: |
||||
seg = seg.lstrip() |
||||
split_at = seg.rfind(' ', 0, max_len) |
||||
output.append(prefix + seg[:split_at].strip() + line_concat) |
||||
seg = seg[split_at + 1:] |
||||
prefix = new_prefix |
||||
max_len = new_max_len |
||||
|
||||
if len((cur_line + seg).rstrip()) < max_len: |
||||
cur_line = (cur_line + seg).lstrip() |
||||
else: |
||||
output.append(prefix + cur_line.rstrip() + line_concat) |
||||
prefix = new_prefix |
||||
max_len = new_max_len |
||||
cur_line = seg.lstrip() |
||||
if cur_line.strip() != '': |
||||
output.append(prefix + cur_line.strip()) |
||||
|
||||
|
||||
def WrapPreprocessorDirective(line, output): |
||||
WrapCode(line, ' \\', output) |
||||
|
||||
|
||||
def WrapPlainCode(line, output): |
||||
WrapCode(line, '', output) |
||||
|
||||
|
||||
def IsMultiLineIWYUPragma(line): |
||||
return re.search(r'/\* IWYU pragma: ', line) |
||||
|
||||
|
||||
def IsHeaderGuardIncludeOrOneLineIWYUPragma(line): |
||||
return (re.match(r'^#(ifndef|define|endif\s*//)\s*[\w_]+\s*$', line) or |
||||
re.match(r'^#include\s', line) or |
||||
# Don't break IWYU pragmas, either; that causes iwyu.py problems. |
||||
re.search(r'// IWYU pragma: ', line)) |
||||
|
||||
|
||||
def WrapLongLine(line, output): |
||||
line = line.rstrip() |
||||
if len(line) <= 80: |
||||
output.append(line) |
||||
elif IsSingleLineComment(line): |
||||
if IsHeaderGuardIncludeOrOneLineIWYUPragma(line): |
||||
# The style guide made an exception to allow long header guard lines, |
||||
# includes and IWYU pragmas. |
||||
output.append(line) |
||||
else: |
||||
WrapComment(line, output) |
||||
elif IsInPreprocessorDirective(output, line): |
||||
if IsHeaderGuardIncludeOrOneLineIWYUPragma(line): |
||||
# The style guide made an exception to allow long header guard lines, |
||||
# includes and IWYU pragmas. |
||||
output.append(line) |
||||
else: |
||||
WrapPreprocessorDirective(line, output) |
||||
elif IsMultiLineIWYUPragma(line): |
||||
output.append(line) |
||||
else: |
||||
WrapPlainCode(line, output) |
||||
|
||||
|
||||
def BeautifyCode(string): |
||||
lines = string.splitlines() |
||||
output = [] |
||||
for line in lines: |
||||
WrapLongLine(line, output) |
||||
output2 = [line.rstrip() for line in output] |
||||
return '\n'.join(output2) + '\n' |
||||
|
||||
|
||||
def ConvertFromPumpSource(src_text): |
||||
"""Return the text generated from the given Pump source text.""" |
||||
ast = ParseToAST(StripMetaComments(src_text)) |
||||
output = Output() |
||||
RunCode(Env(), ast, output) |
||||
return BeautifyCode(output.string) |
||||
|
||||
|
||||
def main(argv): |
||||
if len(argv) == 1: |
||||
print __doc__ |
||||
sys.exit(1) |
||||
|
||||
file_path = argv[-1] |
||||
output_str = ConvertFromPumpSource(file(file_path, 'r').read()) |
||||
if file_path.endswith('.pump'): |
||||
output_file_path = file_path[:-5] |
||||
else: |
||||
output_file_path = '-' |
||||
if output_file_path == '-': |
||||
print output_str, |
||||
else: |
||||
output_file = file(output_file_path, 'w') |
||||
output_file.write('// This file was GENERATED by command:\n') |
||||
output_file.write('// %s %s\n' % |
||||
(os.path.basename(__file__), os.path.basename(file_path))) |
||||
output_file.write('// DO NOT EDIT BY HAND!!!\n\n') |
||||
output_file.write(output_str) |
||||
output_file.close() |
||||
|
||||
|
||||
if __name__ == '__main__': |
||||
main(sys.argv) |
File diff suppressed because it is too large
Load Diff
@ -1,61 +0,0 @@ |
||||
// Copyright 2008, 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.
|
||||
|
||||
//
|
||||
// Tests for Google Test itself. This verifies that the basic constructs of
|
||||
// Google Test work.
|
||||
|
||||
#include "gtest/gtest.h" |
||||
#include "googletest-param-test-test.h" |
||||
|
||||
using ::testing::Values; |
||||
using ::testing::internal::ParamGenerator; |
||||
|
||||
// Tests that generators defined in a different translation unit
|
||||
// are functional. The test using extern_gen_2 is defined
|
||||
// in googletest-param-test-test.cc.
|
||||
ParamGenerator<int> extern_gen_2 = Values(33); |
||||
|
||||
// Tests that a parameterized test case can be defined in one translation unit
|
||||
// and instantiated in another. The test is defined in
|
||||
// googletest-param-test-test.cc and ExternalInstantiationTest fixture class is
|
||||
// defined in gtest-param-test_test.h.
|
||||
INSTANTIATE_TEST_SUITE_P(MultiplesOf33, |
||||
ExternalInstantiationTest, |
||||
Values(33, 66)); |
||||
|
||||
// Tests that a parameterized test case can be instantiated
|
||||
// in multiple translation units. Another instantiation is defined
|
||||
// in googletest-param-test-test.cc and
|
||||
// InstantiationInMultipleTranslationUnitsTest fixture is defined in
|
||||
// gtest-param-test_test.h
|
||||
INSTANTIATE_TEST_SUITE_P(Sequence2, |
||||
InstantiationInMultipleTranslationUnitsTest, |
||||
Values(42*3, 42*4, 42*5)); |
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue