From afd586a5d5c96a606773bd48422b892957419b59 Mon Sep 17 00:00:00 2001 From: Date: Fri, 19 Dec 2008 15:20:40 +0000 Subject: [PATCH] Initial windows support. Now we don't have the stacktrace and several unittests. git-svn-id: https://google-glog.googlecode.com/svn/trunk@23 eb4d4688-79bd-11dd-afb4-1d65580434c0 --- INSTALL | 60 - Makefile.am | 65 +- Makefile.in | 172 ++- configure | 1026 ++++++++++++++- configure.ac | 12 +- google-glog.sln | 29 + src/base/commandlineflags.h | 9 +- src/config.h.in | 18 + src/config_for_unittests.h | 66 + src/glog/log_severity.h | 11 +- src/glog/logging.h.in | 120 +- src/glog/raw_logging.h.in | 17 +- src/glog/vlog_is_on.h.in | 21 +- src/googletest.h | 77 +- src/logging.cc | 282 ++-- src/logging_unittest.cc | 72 +- src/raw_logging.cc | 14 +- src/utilities.cc | 21 +- src/utilities.h | 8 + src/vlog_is_on.cc | 13 +- src/windows/config.h | 136 ++ src/windows/glog/log_severity.h | 61 + src/windows/glog/logging.h | 1342 ++++++++++++++++++++ src/windows/glog/raw_logging.h | 102 ++ src/windows/glog/stl_logging.h | 132 ++ src/windows/glog/vlog_is_on.h | 104 ++ src/windows/port.cc | 64 + src/windows/port.h | 149 +++ src/windows/preprocess.sh | 118 ++ vsprojects/libglog/libglog.vcproj | 249 ++++ .../logging_unittest/logging_unittest.vcproj | 193 +++ 31 files changed, 4392 insertions(+), 371 deletions(-) create mode 100755 google-glog.sln create mode 100644 src/config_for_unittests.h create mode 100755 src/windows/config.h create mode 100644 src/windows/glog/log_severity.h create mode 100755 src/windows/glog/logging.h create mode 100755 src/windows/glog/raw_logging.h create mode 100755 src/windows/glog/stl_logging.h create mode 100755 src/windows/glog/vlog_is_on.h create mode 100755 src/windows/port.cc create mode 100755 src/windows/port.h create mode 100755 src/windows/preprocess.sh create mode 100755 vsprojects/libglog/libglog.vcproj create mode 100755 vsprojects/logging_unittest/logging_unittest.vcproj diff --git a/INSTALL b/INSTALL index 0babe24..d3c5b40 100644 --- a/INSTALL +++ b/INSTALL @@ -7,66 +7,6 @@ Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005, This file is free documentation; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. -Glog-Specific Install Notes -================================ - -*** NOTE FOR 64-BIT LINUX SYSTEMS - -The glibc built-in stack-unwinder on 64-bit systems has some problems -with the glog libraries. (In particular, if you are using -InstallFailureSignalHandler(), the signal may be raised in the middle -of malloc, holding some malloc-related locks when they invoke the -stack unwinder. The built-in stack unwinder may call malloc -recursively, which may require the thread to acquire a lock it already -holds: deadlock.) - -For that reason, if you use a 64-bit system and you need -InstallFailureSignalHandler(), we strongly recommend you install -libunwind before trying to configure or install google glog. -libunwind can be found at - - http://download.savannah.nongnu.org/releases/libunwind/libunwind-snap-070410.tar.gz - -Even if you already have libunwind installed, you will probably still -need to install from the snapshot to get the latest version. - -CAUTION: if you install libunwind from the URL above, be aware that -you may have trouble if you try to statically link your binary with -glog: that is, if you link with 'gcc -static -lgcc_eh ...'. This -is because both libunwind and libgcc implement the same C++ exception -handling APIs, but they implement them differently on some platforms. -This is not likely to be a problem on ia64, but may be on x86-64. - -Also, if you link binaries statically, make sure that you add --Wl,--eh-frame-hdr to your linker options. This is required so that -libunwind can find the information generated by the compiler required -for stack unwinding. - -Using -static is rare, though, so unless you know this will affect you -it probably won't. - -If you cannot or do not wish to install libunwind, you can still try -to use two kinds of stack-unwinder: 1. glibc built-in stack-unwinder -and 2. frame pointer based stack-unwinder. - -1. As we already mentioned, glibc's unwinder has a deadlock issue. -However, if you don't use InstallFailureSignalHandler() or you don't -worry about the rare possibilities of deadlocks, you can use this -stack-unwinder. If you specify no options and libunwind isn't -detected on your system, the configure script chooses this unwinder by -default. - -2. The frame pointer based stack unwinder requires that your -application, the glog library, and system libraries like libc, all be -compiled with a frame pointer. This is *not* the default for x86-64. - -If you are on x86-64 system, know that you have a set of system -libraries with frame-pointers enabled, and compile all your -applications with -fno-omit-frame-pointer, then you can enable the -frame pointer based stack unwinder by passing the ---enable-frame-pointers flag to configure. - - Basic Installation ================== diff --git a/Makefile.am b/Makefile.am index 5b55e0f..163f16e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -28,7 +28,11 @@ endif glogincludedir = $(includedir)/glog ## The .h files you want to install (that is, .h files that people ## who install this package can include in their own applications.) -gloginclude_HEADERS = src/glog/log_severity.h src/glog/logging.h src/glog/raw_logging.h src/glog/vlog_is_on.h src/glog/stl_logging.h +## We have to include both the .h and .h.in forms. The latter we +## put in noinst_HEADERS. +gloginclude_HEADERS = src/glog/log_severity.h +nodist_gloginclude_HEADERS = src/glog/logging.h src/glog/raw_logging.h src/glog/vlog_is_on.h src/glog/stl_logging.h +noinst_HEADERS = src/glog/logging.h.in src/glog/raw_logging.h.in src/glog/vlog_is_on.h.in src/glog/stl_logging.h.in docdir = $(prefix)/share/doc/$(PACKAGE)-$(VERSION) ## This is for HTML and other documentation you want to install. @@ -56,8 +60,10 @@ noinst_SCRIPTS = TEST_BINARIES = TESTS += logging_unittest -logging_unittest_SOURCES = $(gloginclude_HEADERS) src/config.h \ - src/logging_unittest.cc +logging_unittest_SOURCES = $(gloginclude_HEADERS) \ + src/logging_unittest.cc \ + src/config_for_unittests.h +nodist_logging_unittest_SOURCES = $(nodist_gloginclude_HEADERS) logging_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) logging_unittest_LDFLAGS = $(PTHREAD_CFLAGS) logging_unittest_LDADD = libglog.la $(COMMON_LIBS) @@ -81,64 +87,73 @@ signalhandler_unittest_sh: signalhandler_unittest $(top_srcdir)/src/signalhandler_unittest.sh TEST_BINARIES += logging_striptest0 -logging_striptest0_SOURCES = $(gloginclude_HEADERS) src/config.h \ +logging_striptest0_SOURCES = $(gloginclude_HEADERS) \ src/logging_striptest_main.cc +nodist_logging_striptest0_SOURCES = $(nodist_gloginclude_HEADERS) logging_striptest0_CXXFLAGS = $(PTHREAD_CFLAGS) logging_striptest0_LDFLAGS = $(PTHREAD_CFLAGS) logging_striptest0_LDADD = libglog.la $(COMMON_LIBS) TEST_BINARIES += logging_striptest2 -logging_striptest2_SOURCES = $(gloginclude_HEADERS) src/config.h \ +logging_striptest2_SOURCES = $(gloginclude_HEADERS) \ src/logging_striptest2.cc +nodist_logging_striptest2_SOURCES = $(nodist_gloginclude_HEADERS) logging_striptest2_CXXFLAGS = $(PTHREAD_CFLAGS) logging_striptest2_LDFLAGS = $(PTHREAD_CFLAGS) logging_striptest2_LDADD = libglog.la $(COMMON_LIBS) TEST_BINARIES += logging_striptest10 -logging_striptest10_SOURCES = $(gloginclude_HEADERS) src/config.h \ +logging_striptest10_SOURCES = $(gloginclude_HEADERS) \ src/logging_striptest10.cc +nodist_logging_striptest10_SOURCES = $(nodist_gloginclude_HEADERS) logging_striptest10_CXXFLAGS = $(PTHREAD_CFLAGS) logging_striptest10_LDFLAGS = $(PTHREAD_CFLAGS) logging_striptest10_LDADD = libglog.la $(COMMON_LIBS) TESTS += demangle_unittest -demangle_unittest_SOURCES = $(gloginclude_HEADERS) src/config.h \ +demangle_unittest_SOURCES = $(gloginclude_HEADERS) \ src/demangle_unittest.cc +nodist_demangle_unittest_SOURCES = $(nodist_gloginclude_HEADERS) demangle_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) demangle_unittest_LDFLAGS = $(PTHREAD_CFLAGS) demangle_unittest_LDADD = libglog.la $(COMMON_LIBS) TESTS += stacktrace_unittest -stacktrace_unittest_SOURCES = $(gloginclude_HEADERS) src/config.h \ +stacktrace_unittest_SOURCES = $(gloginclude_HEADERS) \ src/stacktrace_unittest.cc +nodist_stacktrace_unittest_SOURCES = $(nodist_gloginclude_HEADERS) stacktrace_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) stacktrace_unittest_LDFLAGS = $(PTHREAD_CFLAGS) stacktrace_unittest_LDADD = libglog.la $(COMMON_LIBS) TESTS += symbolize_unittest -symbolize_unittest_SOURCES = $(gloginclude_HEADERS) src/config.h \ +symbolize_unittest_SOURCES = $(gloginclude_HEADERS) \ src/symbolize_unittest.cc +nodist_symbolize_unittest_SOURCES = $(nodist_gloginclude_HEADERS) symbolize_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) symbolize_unittest_LDFLAGS = $(PTHREAD_CFLAGS) symbolize_unittest_LDADD = libglog.la $(COMMON_LIBS) TESTS += stl_logging_unittest -stl_logging_unittest_SOURCES = $(gloginclude_HEADERS) src/config.h \ +stl_logging_unittest_SOURCES = $(gloginclude_HEADERS) \ src/stl_logging_unittest.cc +nodist_stl_logging_unittest_SOURCES = $(nodist_gloginclude_HEADERS) stl_logging_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) stl_logging_unittest_LDFLAGS = $(PTHREAD_CFLAGS) stl_logging_unittest_LDADD = libglog.la $(COMMON_LIBS) TEST_BINARIES += signalhandler_unittest -signalhandler_unittest_SOURCES = $(gloginclude_HEADERS) src/config.h \ +signalhandler_unittest_SOURCES = $(gloginclude_HEADERS) \ src/signalhandler_unittest.cc +nodist_signalhandler_unittest_SOURCES = $(nodist_gloginclude_HEADERS) signalhandler_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) signalhandler_unittest_LDFLAGS = $(PTHREAD_CFLAGS) signalhandler_unittest_LDADD = libglog.la $(COMMON_LIBS) TESTS += utilities_unittest -utilities_unittest_SOURCES = $(gloginclude_HEADERS) src/config.h \ +utilities_unittest_SOURCES = $(gloginclude_HEADERS) \ src/utilities_unittest.cc +nodist_utilities_unittest_SOURCES = $(nodist_gloginclude_HEADERS) utilities_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) utilities_unittest_LDFLAGS = $(PTHREAD_CFLAGS) utilities_unittest_LDADD = libglog.la $(COMMON_LIBS) @@ -146,7 +161,7 @@ utilities_unittest_LDADD = libglog.la $(COMMON_LIBS) ## vvvv RULES TO MAKE THE LIBRARIES, BINARIES, AND UNITTESTS lib_LTLIBRARIES += libglog.la -libglog_la_SOURCES = $(gloginclude_HEADERS) src/config.h \ +libglog_la_SOURCES = $(gloginclude_HEADERS) \ src/logging.cc src/raw_logging.cc src/vlog_is_on.cc \ src/utilities.cc src/utilities.h \ src/demangle.cc src/demangle.h \ @@ -160,11 +175,17 @@ libglog_la_SOURCES = $(gloginclude_HEADERS) src/config.h \ src/signalhandler.cc \ src/base/mutex.h src/base/googleinit.h \ src/base/commandlineflags.h src/googletest.h +nodist_libglog_la_SOURCES = $(nodist_gloginclude_HEADERS) libglog_la_CXXFLAGS = $(PTRHEAD_CFLAGS) -DNDEBUG libglog_la_LDFLAGS = $(PTRHEAD_CFLAGS) libglog_la_LIBADD = $(COMMON_LIBS) +## The location of the windows project file for each binary we make +WINDOWS_PROJECTS = google-glog.sln +WINDOWS_PROJECTS += vsprojects/libglog/libglog.vcproj +WINDOWS_PROJECTS += vsprojects/logging_unittest/logging_unittest.vcproj + ## ^^^^ END OF RULES TO MAKE THE LIBRARIES, BINARIES, AND UNITTESTS @@ -178,13 +199,19 @@ rpm: dist-gzip packages/rpm.sh packages/rpm/rpm.spec deb: dist-gzip packages/deb.sh packages/deb/* @cd packages && ./deb.sh ${PACKAGE} ${VERSION} -# TODO(hamaji): We don't support Visual Studio for now. -## Windows wants write permission to .vcproj files and maybe even sln files. -#dist-hook: -# test -e "$(distdir)/vsprojects" \ -# && chmod -R u+w $(distdir)/*.sln $(distdir)/vsprojects/ +# Windows wants write permission to .vcproj files and maybe even sln files. +dist-hook: + test -e "$(distdir)/vsprojects" \ + && chmod -R u+w $(distdir)/*.sln $(distdir)/vsprojects/ libtool: $(LIBTOOL_DEPS) $(SHELL) ./config.status --recheck + EXTRA_DIST = packages/rpm.sh packages/rpm/rpm.spec packages/deb.sh packages/deb \ - $(SCRIPTS) src/logging_unittest.err src/demangle_unittest.txt + $(SCRIPTS) src/logging_unittest.err src/demangle_unittest.txt \ + src/windows/config.h src/windows/port.h src/windows/port.cc \ + src/windows/preprocess.sh \ + src/windows/glog/log_severity.h src/windows/glog/logging.h \ + src/windows/glog/raw_logging.h src/windows/glog/stl_logging.h \ + src/windows/glog/vlog_is_on.h \ + $(WINDOWS_PROJECTS) diff --git a/Makefile.in b/Makefile.in index c076f26..4b540b1 100644 --- a/Makefile.in +++ b/Makefile.in @@ -49,7 +49,7 @@ TESTS = logging_unittest$(EXEEXT) demangle_unittest$(EXEEXT) \ noinst_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) subdir = . DIST_COMMON = README $(am__configure_deps) $(dist_doc_DATA) \ - $(gloginclude_HEADERS) $(srcdir)/Makefile.am \ + $(gloginclude_HEADERS) $(noinst_HEADERS) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in $(top_srcdir)/configure \ $(top_srcdir)/src/config.h.in \ $(top_srcdir)/src/glog/logging.h.in \ @@ -82,7 +82,7 @@ am__vpath_adj = case $$p in \ esac; am__strip_dir = `echo $$p | sed -e 's|^.*/||'`; am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(docdir)" \ - "$(DESTDIR)$(glogincludedir)" + "$(DESTDIR)$(glogincludedir)" "$(DESTDIR)$(glogincludedir)" libLTLIBRARIES_INSTALL = $(INSTALL) LTLIBRARIES = $(lib_LTLIBRARIES) am__DEPENDENCIES_1 = @@ -94,7 +94,9 @@ am_libglog_la_OBJECTS = $(am__objects_1) libglog_la-logging.lo \ libglog_la-raw_logging.lo libglog_la-vlog_is_on.lo \ libglog_la-utilities.lo libglog_la-demangle.lo \ libglog_la-symbolize.lo libglog_la-signalhandler.lo -libglog_la_OBJECTS = $(am_libglog_la_OBJECTS) +nodist_libglog_la_OBJECTS = $(am__objects_1) +libglog_la_OBJECTS = $(am_libglog_la_OBJECTS) \ + $(nodist_libglog_la_OBJECTS) libglog_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(libglog_la_CXXFLAGS) \ $(CXXFLAGS) $(libglog_la_LDFLAGS) $(LDFLAGS) -o $@ @@ -106,7 +108,9 @@ am__EXEEXT_2 = logging_striptest0$(EXEEXT) logging_striptest2$(EXEEXT) \ PROGRAMS = $(noinst_PROGRAMS) am_demangle_unittest_OBJECTS = $(am__objects_1) \ demangle_unittest-demangle_unittest.$(OBJEXT) -demangle_unittest_OBJECTS = $(am_demangle_unittest_OBJECTS) +nodist_demangle_unittest_OBJECTS = $(am__objects_1) +demangle_unittest_OBJECTS = $(am_demangle_unittest_OBJECTS) \ + $(nodist_demangle_unittest_OBJECTS) demangle_unittest_DEPENDENCIES = libglog.la $(am__DEPENDENCIES_2) demangle_unittest_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ @@ -114,7 +118,9 @@ demangle_unittest_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(demangle_unittest_LDFLAGS) $(LDFLAGS) -o $@ am_logging_striptest0_OBJECTS = $(am__objects_1) \ logging_striptest0-logging_striptest_main.$(OBJEXT) -logging_striptest0_OBJECTS = $(am_logging_striptest0_OBJECTS) +nodist_logging_striptest0_OBJECTS = $(am__objects_1) +logging_striptest0_OBJECTS = $(am_logging_striptest0_OBJECTS) \ + $(nodist_logging_striptest0_OBJECTS) logging_striptest0_DEPENDENCIES = libglog.la $(am__DEPENDENCIES_2) logging_striptest0_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ @@ -122,7 +128,9 @@ logging_striptest0_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(logging_striptest0_LDFLAGS) $(LDFLAGS) -o $@ am_logging_striptest10_OBJECTS = $(am__objects_1) \ logging_striptest10-logging_striptest10.$(OBJEXT) -logging_striptest10_OBJECTS = $(am_logging_striptest10_OBJECTS) +nodist_logging_striptest10_OBJECTS = $(am__objects_1) +logging_striptest10_OBJECTS = $(am_logging_striptest10_OBJECTS) \ + $(nodist_logging_striptest10_OBJECTS) logging_striptest10_DEPENDENCIES = libglog.la $(am__DEPENDENCIES_2) logging_striptest10_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ @@ -130,7 +138,9 @@ logging_striptest10_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(logging_striptest10_LDFLAGS) $(LDFLAGS) -o $@ am_logging_striptest2_OBJECTS = $(am__objects_1) \ logging_striptest2-logging_striptest2.$(OBJEXT) -logging_striptest2_OBJECTS = $(am_logging_striptest2_OBJECTS) +nodist_logging_striptest2_OBJECTS = $(am__objects_1) +logging_striptest2_OBJECTS = $(am_logging_striptest2_OBJECTS) \ + $(nodist_logging_striptest2_OBJECTS) logging_striptest2_DEPENDENCIES = libglog.la $(am__DEPENDENCIES_2) logging_striptest2_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ @@ -138,7 +148,9 @@ logging_striptest2_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(logging_striptest2_LDFLAGS) $(LDFLAGS) -o $@ am_logging_unittest_OBJECTS = $(am__objects_1) \ logging_unittest-logging_unittest.$(OBJEXT) -logging_unittest_OBJECTS = $(am_logging_unittest_OBJECTS) +nodist_logging_unittest_OBJECTS = $(am__objects_1) +logging_unittest_OBJECTS = $(am_logging_unittest_OBJECTS) \ + $(nodist_logging_unittest_OBJECTS) logging_unittest_DEPENDENCIES = libglog.la $(am__DEPENDENCIES_2) logging_unittest_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ @@ -146,7 +158,9 @@ logging_unittest_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(logging_unittest_LDFLAGS) $(LDFLAGS) -o $@ am_signalhandler_unittest_OBJECTS = $(am__objects_1) \ signalhandler_unittest-signalhandler_unittest.$(OBJEXT) -signalhandler_unittest_OBJECTS = $(am_signalhandler_unittest_OBJECTS) +nodist_signalhandler_unittest_OBJECTS = $(am__objects_1) +signalhandler_unittest_OBJECTS = $(am_signalhandler_unittest_OBJECTS) \ + $(nodist_signalhandler_unittest_OBJECTS) signalhandler_unittest_DEPENDENCIES = libglog.la $(am__DEPENDENCIES_2) signalhandler_unittest_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ @@ -154,7 +168,9 @@ signalhandler_unittest_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(signalhandler_unittest_LDFLAGS) $(LDFLAGS) -o $@ am_stacktrace_unittest_OBJECTS = $(am__objects_1) \ stacktrace_unittest-stacktrace_unittest.$(OBJEXT) -stacktrace_unittest_OBJECTS = $(am_stacktrace_unittest_OBJECTS) +nodist_stacktrace_unittest_OBJECTS = $(am__objects_1) +stacktrace_unittest_OBJECTS = $(am_stacktrace_unittest_OBJECTS) \ + $(nodist_stacktrace_unittest_OBJECTS) stacktrace_unittest_DEPENDENCIES = libglog.la $(am__DEPENDENCIES_2) stacktrace_unittest_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ @@ -162,7 +178,9 @@ stacktrace_unittest_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(stacktrace_unittest_LDFLAGS) $(LDFLAGS) -o $@ am_stl_logging_unittest_OBJECTS = $(am__objects_1) \ stl_logging_unittest-stl_logging_unittest.$(OBJEXT) -stl_logging_unittest_OBJECTS = $(am_stl_logging_unittest_OBJECTS) +nodist_stl_logging_unittest_OBJECTS = $(am__objects_1) +stl_logging_unittest_OBJECTS = $(am_stl_logging_unittest_OBJECTS) \ + $(nodist_stl_logging_unittest_OBJECTS) stl_logging_unittest_DEPENDENCIES = libglog.la $(am__DEPENDENCIES_2) stl_logging_unittest_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ @@ -170,7 +188,9 @@ stl_logging_unittest_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(stl_logging_unittest_LDFLAGS) $(LDFLAGS) -o $@ am_symbolize_unittest_OBJECTS = $(am__objects_1) \ symbolize_unittest-symbolize_unittest.$(OBJEXT) -symbolize_unittest_OBJECTS = $(am_symbolize_unittest_OBJECTS) +nodist_symbolize_unittest_OBJECTS = $(am__objects_1) +symbolize_unittest_OBJECTS = $(am_symbolize_unittest_OBJECTS) \ + $(nodist_symbolize_unittest_OBJECTS) symbolize_unittest_DEPENDENCIES = libglog.la $(am__DEPENDENCIES_2) symbolize_unittest_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ @@ -178,7 +198,9 @@ symbolize_unittest_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(symbolize_unittest_LDFLAGS) $(LDFLAGS) -o $@ am_utilities_unittest_OBJECTS = $(am__objects_1) \ utilities_unittest-utilities_unittest.$(OBJEXT) -utilities_unittest_OBJECTS = $(am_utilities_unittest_OBJECTS) +nodist_utilities_unittest_OBJECTS = $(am__objects_1) +utilities_unittest_OBJECTS = $(am_utilities_unittest_OBJECTS) \ + $(nodist_utilities_unittest_OBJECTS) utilities_unittest_DEPENDENCIES = libglog.la $(am__DEPENDENCIES_2) utilities_unittest_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ @@ -206,12 +228,26 @@ CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ -SOURCES = $(libglog_la_SOURCES) $(demangle_unittest_SOURCES) \ - $(logging_striptest0_SOURCES) $(logging_striptest10_SOURCES) \ - $(logging_striptest2_SOURCES) $(logging_unittest_SOURCES) \ +SOURCES = $(libglog_la_SOURCES) $(nodist_libglog_la_SOURCES) \ + $(demangle_unittest_SOURCES) \ + $(nodist_demangle_unittest_SOURCES) \ + $(logging_striptest0_SOURCES) \ + $(nodist_logging_striptest0_SOURCES) \ + $(logging_striptest10_SOURCES) \ + $(nodist_logging_striptest10_SOURCES) \ + $(logging_striptest2_SOURCES) \ + $(nodist_logging_striptest2_SOURCES) \ + $(logging_unittest_SOURCES) $(nodist_logging_unittest_SOURCES) \ $(signalhandler_unittest_SOURCES) \ - $(stacktrace_unittest_SOURCES) $(stl_logging_unittest_SOURCES) \ - $(symbolize_unittest_SOURCES) $(utilities_unittest_SOURCES) + $(nodist_signalhandler_unittest_SOURCES) \ + $(stacktrace_unittest_SOURCES) \ + $(nodist_stacktrace_unittest_SOURCES) \ + $(stl_logging_unittest_SOURCES) \ + $(nodist_stl_logging_unittest_SOURCES) \ + $(symbolize_unittest_SOURCES) \ + $(nodist_symbolize_unittest_SOURCES) \ + $(utilities_unittest_SOURCES) \ + $(nodist_utilities_unittest_SOURCES) DIST_SOURCES = $(libglog_la_SOURCES) $(demangle_unittest_SOURCES) \ $(logging_striptest0_SOURCES) $(logging_striptest10_SOURCES) \ $(logging_striptest2_SOURCES) $(logging_unittest_SOURCES) \ @@ -221,7 +257,9 @@ DIST_SOURCES = $(libglog_la_SOURCES) $(demangle_unittest_SOURCES) \ dist_docDATA_INSTALL = $(INSTALL_DATA) DATA = $(dist_doc_DATA) glogincludeHEADERS_INSTALL = $(INSTALL_HEADER) -HEADERS = $(gloginclude_HEADERS) +nodist_glogincludeHEADERS_INSTALL = $(INSTALL_HEADER) +HEADERS = $(gloginclude_HEADERS) $(nodist_gloginclude_HEADERS) \ + $(noinst_HEADERS) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) @@ -316,6 +354,7 @@ ac_cv_have_stdint_h = @ac_cv_have_stdint_h@ ac_cv_have_systypes_h = @ac_cv_have_systypes_h@ ac_cv_have_u_int16_t = @ac_cv_have_u_int16_t@ ac_cv_have_uint16_t = @ac_cv_have_uint16_t@ +ac_cv_have_unistd_h = @ac_cv_have_unistd_h@ ac_google_end_namespace = @ac_google_end_namespace@ ac_google_namespace = @ac_google_namespace@ ac_google_start_namespace = @ac_google_start_namespace@ @@ -374,7 +413,9 @@ AM_CPPFLAGS = -I$(top_srcdir)/src # This is mostly based on configure options AM_CXXFLAGS = $(am__append_1) $(am__append_2) $(am__append_3) glogincludedir = $(includedir)/glog -gloginclude_HEADERS = src/glog/log_severity.h src/glog/logging.h src/glog/raw_logging.h src/glog/vlog_is_on.h src/glog/stl_logging.h +gloginclude_HEADERS = src/glog/log_severity.h +nodist_gloginclude_HEADERS = src/glog/logging.h src/glog/raw_logging.h src/glog/vlog_is_on.h src/glog/stl_logging.h +noinst_HEADERS = src/glog/logging.h.in src/glog/raw_logging.h.in src/glog/vlog_is_on.h.in src/glog/stl_logging.h.in dist_doc_DATA = AUTHORS COPYING ChangeLog INSTALL NEWS README \ doc/designstyle.css doc/glog.html @@ -391,67 +432,78 @@ noinst_SCRIPTS = src/logging_striplog_test.sh src/demangle_unittest.sh \ # Binaries used for script-based unittests. TEST_BINARIES = logging_striptest0 logging_striptest2 \ logging_striptest10 signalhandler_unittest -logging_unittest_SOURCES = $(gloginclude_HEADERS) src/config.h \ - src/logging_unittest.cc +logging_unittest_SOURCES = $(gloginclude_HEADERS) \ + src/logging_unittest.cc \ + src/config_for_unittests.h +nodist_logging_unittest_SOURCES = $(nodist_gloginclude_HEADERS) logging_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) logging_unittest_LDFLAGS = $(PTHREAD_CFLAGS) logging_unittest_LDADD = libglog.la $(COMMON_LIBS) -logging_striptest0_SOURCES = $(gloginclude_HEADERS) src/config.h \ +logging_striptest0_SOURCES = $(gloginclude_HEADERS) \ src/logging_striptest_main.cc +nodist_logging_striptest0_SOURCES = $(nodist_gloginclude_HEADERS) logging_striptest0_CXXFLAGS = $(PTHREAD_CFLAGS) logging_striptest0_LDFLAGS = $(PTHREAD_CFLAGS) logging_striptest0_LDADD = libglog.la $(COMMON_LIBS) -logging_striptest2_SOURCES = $(gloginclude_HEADERS) src/config.h \ +logging_striptest2_SOURCES = $(gloginclude_HEADERS) \ src/logging_striptest2.cc +nodist_logging_striptest2_SOURCES = $(nodist_gloginclude_HEADERS) logging_striptest2_CXXFLAGS = $(PTHREAD_CFLAGS) logging_striptest2_LDFLAGS = $(PTHREAD_CFLAGS) logging_striptest2_LDADD = libglog.la $(COMMON_LIBS) -logging_striptest10_SOURCES = $(gloginclude_HEADERS) src/config.h \ +logging_striptest10_SOURCES = $(gloginclude_HEADERS) \ src/logging_striptest10.cc +nodist_logging_striptest10_SOURCES = $(nodist_gloginclude_HEADERS) logging_striptest10_CXXFLAGS = $(PTHREAD_CFLAGS) logging_striptest10_LDFLAGS = $(PTHREAD_CFLAGS) logging_striptest10_LDADD = libglog.la $(COMMON_LIBS) -demangle_unittest_SOURCES = $(gloginclude_HEADERS) src/config.h \ +demangle_unittest_SOURCES = $(gloginclude_HEADERS) \ src/demangle_unittest.cc +nodist_demangle_unittest_SOURCES = $(nodist_gloginclude_HEADERS) demangle_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) demangle_unittest_LDFLAGS = $(PTHREAD_CFLAGS) demangle_unittest_LDADD = libglog.la $(COMMON_LIBS) -stacktrace_unittest_SOURCES = $(gloginclude_HEADERS) src/config.h \ +stacktrace_unittest_SOURCES = $(gloginclude_HEADERS) \ src/stacktrace_unittest.cc +nodist_stacktrace_unittest_SOURCES = $(nodist_gloginclude_HEADERS) stacktrace_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) stacktrace_unittest_LDFLAGS = $(PTHREAD_CFLAGS) stacktrace_unittest_LDADD = libglog.la $(COMMON_LIBS) -symbolize_unittest_SOURCES = $(gloginclude_HEADERS) src/config.h \ +symbolize_unittest_SOURCES = $(gloginclude_HEADERS) \ src/symbolize_unittest.cc +nodist_symbolize_unittest_SOURCES = $(nodist_gloginclude_HEADERS) symbolize_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) symbolize_unittest_LDFLAGS = $(PTHREAD_CFLAGS) symbolize_unittest_LDADD = libglog.la $(COMMON_LIBS) -stl_logging_unittest_SOURCES = $(gloginclude_HEADERS) src/config.h \ +stl_logging_unittest_SOURCES = $(gloginclude_HEADERS) \ src/stl_logging_unittest.cc +nodist_stl_logging_unittest_SOURCES = $(nodist_gloginclude_HEADERS) stl_logging_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) stl_logging_unittest_LDFLAGS = $(PTHREAD_CFLAGS) stl_logging_unittest_LDADD = libglog.la $(COMMON_LIBS) -signalhandler_unittest_SOURCES = $(gloginclude_HEADERS) src/config.h \ +signalhandler_unittest_SOURCES = $(gloginclude_HEADERS) \ src/signalhandler_unittest.cc +nodist_signalhandler_unittest_SOURCES = $(nodist_gloginclude_HEADERS) signalhandler_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) signalhandler_unittest_LDFLAGS = $(PTHREAD_CFLAGS) signalhandler_unittest_LDADD = libglog.la $(COMMON_LIBS) -utilities_unittest_SOURCES = $(gloginclude_HEADERS) src/config.h \ +utilities_unittest_SOURCES = $(gloginclude_HEADERS) \ src/utilities_unittest.cc +nodist_utilities_unittest_SOURCES = $(nodist_gloginclude_HEADERS) utilities_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) utilities_unittest_LDFLAGS = $(PTHREAD_CFLAGS) utilities_unittest_LDADD = libglog.la $(COMMON_LIBS) -libglog_la_SOURCES = $(gloginclude_HEADERS) src/config.h \ +libglog_la_SOURCES = $(gloginclude_HEADERS) \ src/logging.cc src/raw_logging.cc src/vlog_is_on.cc \ src/utilities.cc src/utilities.h \ src/demangle.cc src/demangle.h \ @@ -466,11 +518,20 @@ libglog_la_SOURCES = $(gloginclude_HEADERS) src/config.h \ src/base/mutex.h src/base/googleinit.h \ src/base/commandlineflags.h src/googletest.h +nodist_libglog_la_SOURCES = $(nodist_gloginclude_HEADERS) libglog_la_CXXFLAGS = $(PTRHEAD_CFLAGS) -DNDEBUG libglog_la_LDFLAGS = $(PTRHEAD_CFLAGS) libglog_la_LIBADD = $(COMMON_LIBS) +WINDOWS_PROJECTS = google-glog.sln vsprojects/libglog/libglog.vcproj \ + vsprojects/logging_unittest/logging_unittest.vcproj EXTRA_DIST = packages/rpm.sh packages/rpm/rpm.spec packages/deb.sh packages/deb \ - $(SCRIPTS) src/logging_unittest.err src/demangle_unittest.txt + $(SCRIPTS) src/logging_unittest.err src/demangle_unittest.txt \ + src/windows/config.h src/windows/port.h src/windows/port.cc \ + src/windows/preprocess.sh \ + src/windows/glog/log_severity.h src/windows/glog/logging.h \ + src/windows/glog/raw_logging.h src/windows/glog/stl_logging.h \ + src/windows/glog/vlog_is_on.h \ + $(WINDOWS_PROJECTS) all: all-am @@ -877,6 +938,23 @@ uninstall-glogincludeHEADERS: echo " rm -f '$(DESTDIR)$(glogincludedir)/$$f'"; \ rm -f "$(DESTDIR)$(glogincludedir)/$$f"; \ done +install-nodist_glogincludeHEADERS: $(nodist_gloginclude_HEADERS) + @$(NORMAL_INSTALL) + test -z "$(glogincludedir)" || $(MKDIR_P) "$(DESTDIR)$(glogincludedir)" + @list='$(nodist_gloginclude_HEADERS)'; for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + f=$(am__strip_dir) \ + echo " $(nodist_glogincludeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(glogincludedir)/$$f'"; \ + $(nodist_glogincludeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(glogincludedir)/$$f"; \ + done + +uninstall-nodist_glogincludeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(nodist_gloginclude_HEADERS)'; for p in $$list; do \ + f=$(am__strip_dir) \ + echo " rm -f '$(DESTDIR)$(glogincludedir)/$$f'"; \ + rm -f "$(DESTDIR)$(glogincludedir)/$$f"; \ + done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ @@ -1026,6 +1104,9 @@ distdir: $(DISTFILES) || exit 1; \ fi; \ done + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$(top_distdir)" distdir="$(distdir)" \ + dist-hook -find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ @@ -1136,7 +1217,7 @@ check: check-am all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(SCRIPTS) $(DATA) \ $(HEADERS) installdirs: - for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(docdir)" "$(DESTDIR)$(glogincludedir)"; do \ + for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(docdir)" "$(DESTDIR)$(glogincludedir)" "$(DESTDIR)$(glogincludedir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am @@ -1185,7 +1266,8 @@ info: info-am info-am: -install-data-am: install-dist_docDATA install-glogincludeHEADERS +install-data-am: install-dist_docDATA install-glogincludeHEADERS \ + install-nodist_glogincludeHEADERS install-dvi: install-dvi-am @@ -1224,28 +1306,30 @@ ps: ps-am ps-am: uninstall-am: uninstall-dist_docDATA uninstall-glogincludeHEADERS \ - uninstall-libLTLIBRARIES + uninstall-libLTLIBRARIES uninstall-nodist_glogincludeHEADERS .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am am--refresh check check-TESTS check-am \ clean clean-generic clean-libLTLIBRARIES clean-libtool \ clean-noinstPROGRAMS ctags dist dist-all dist-bzip2 dist-gzip \ - dist-lzma dist-shar dist-tarZ dist-zip distcheck distclean \ - distclean-compile distclean-generic distclean-hdr \ + dist-hook dist-lzma dist-shar dist-tarZ dist-zip distcheck \ + distclean distclean-compile distclean-generic distclean-hdr \ distclean-libtool distclean-tags distcleancheck distdir \ distuninstallcheck dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am \ install-dist_docDATA install-dvi install-dvi-am install-exec \ install-exec-am install-glogincludeHEADERS install-html \ install-html-am install-info install-info-am \ - install-libLTLIBRARIES install-man install-pdf install-pdf-am \ + install-libLTLIBRARIES install-man \ + install-nodist_glogincludeHEADERS install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags uninstall uninstall-am uninstall-dist_docDATA \ - uninstall-glogincludeHEADERS uninstall-libLTLIBRARIES + uninstall-glogincludeHEADERS uninstall-libLTLIBRARIES \ + uninstall-nodist_glogincludeHEADERS @ENABLE_FRAME_POINTERS_FALSE@@X86_64_TRUE@ # TODO(csilvers): check if -fomit-frame-pointer might be in $(CXXFLAGS), @ENABLE_FRAME_POINTERS_FALSE@@X86_64_TRUE@ # before setting this. @@ -1265,10 +1349,10 @@ rpm: dist-gzip packages/rpm.sh packages/rpm/rpm.spec deb: dist-gzip packages/deb.sh packages/deb/* @cd packages && ./deb.sh ${PACKAGE} ${VERSION} -# TODO(hamaji): We don't support Visual Studio for now. -#dist-hook: -# test -e "$(distdir)/vsprojects" \ -# && chmod -R u+w $(distdir)/*.sln $(distdir)/vsprojects/ +# Windows wants write permission to .vcproj files and maybe even sln files. +dist-hook: + test -e "$(distdir)/vsprojects" \ + && chmod -R u+w $(distdir)/*.sln $(distdir)/vsprojects/ libtool: $(LIBTOOL_DEPS) $(SHELL) ./config.status --recheck diff --git a/configure b/configure index 3817ce9..efc1451 100755 --- a/configure +++ b/configure @@ -895,6 +895,7 @@ ac_cv_have___builtin_expect ac_cv_have_stdint_h ac_cv_have_systypes_h ac_cv_have_inttypes_h +ac_cv_have_unistd_h ac_cv_have_uint16_t ac_cv_have_u_int16_t ac_cv_have___uint16 @@ -5063,7 +5064,7 @@ ia64-*-hpux*) ;; *-*-irix6*) # Find out which ABI we are using. - echo '#line 5066 "configure"' > conftest.$ac_ext + echo '#line 5067 "configure"' > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? @@ -7418,11 +7419,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7421: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7422: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:7425: \$? = $ac_status" >&5 + echo "$as_me:7426: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -7708,11 +7709,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7711: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7712: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:7715: \$? = $ac_status" >&5 + echo "$as_me:7716: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -7812,11 +7813,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7815: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7816: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:7819: \$? = $ac_status" >&5 + echo "$as_me:7820: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -10189,7 +10190,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext < conftest.$ac_ext <&5) + (eval echo "\"\$as_me:12694: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:12697: \$? = $ac_status" >&5 + echo "$as_me:12698: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -12794,11 +12795,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:12797: $lt_compile\"" >&5) + (eval echo "\"\$as_me:12798: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:12801: \$? = $ac_status" >&5 + echo "$as_me:12802: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -14392,11 +14393,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:14395: $lt_compile\"" >&5) + (eval echo "\"\$as_me:14396: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:14399: \$? = $ac_status" >&5 + echo "$as_me:14400: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -14496,11 +14497,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:14499: $lt_compile\"" >&5) + (eval echo "\"\$as_me:14500: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:14503: \$? = $ac_status" >&5 + echo "$as_me:14504: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -16716,11 +16717,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:16719: $lt_compile\"" >&5) + (eval echo "\"\$as_me:16720: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:16723: \$? = $ac_status" >&5 + echo "$as_me:16724: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -17006,11 +17007,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:17009: $lt_compile\"" >&5) + (eval echo "\"\$as_me:17010: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:17013: \$? = $ac_status" >&5 + echo "$as_me:17014: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -17110,11 +17111,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:17113: $lt_compile\"" >&5) + (eval echo "\"\$as_me:17114: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:17117: \$? = $ac_status" >&5 + echo "$as_me:17118: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -20391,6 +20392,153 @@ fi +for ac_header in unistd.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + { echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } + +# Is the header present? +{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( cat <<\_ASBOX +## ------------------------------------ ## +## Report this to opensource@google.com ## +## ------------------------------------ ## +_ASBOX + ) | sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + ac_cv_have_unistd_h=1 +else + ac_cv_have_unistd_h=0 +fi + +done + + for ac_header in syscall.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` @@ -20536,7 +20684,589 @@ fi done -for ac_header in sys/syscall.h +for ac_header in sys/syscall.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + { echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } + +# Is the header present? +{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( cat <<\_ASBOX +## ------------------------------------ ## +## Report this to opensource@google.com ## +## ------------------------------------ ## +_ASBOX + ) | sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + +# For backtrace with glibc. + +for ac_header in execinfo.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + { echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } + +# Is the header present? +{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( cat <<\_ASBOX +## ------------------------------------ ## +## Report this to opensource@google.com ## +## ------------------------------------ ## +_ASBOX + ) | sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + +# For backtrace with libunwind. + +for ac_header in libunwind.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + { echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } + +# Is the header present? +{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( cat <<\_ASBOX +## ------------------------------------ ## +## Report this to opensource@google.com ## +## ------------------------------------ ## +_ASBOX + ) | sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +for ac_header in ucontext.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + { echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } + +# Is the header present? +{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( cat <<\_ASBOX +## ------------------------------------ ## +## Report this to opensource@google.com ## +## ------------------------------------ ## +_ASBOX + ) | sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +for ac_header in sys/utsname.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then @@ -20680,9 +21410,8 @@ fi done -# For backtrace with glibc. -for ac_header in execinfo.h +for ac_header in pwd.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then @@ -20826,9 +21555,8 @@ fi done -# For backtrace with libunwind. -for ac_header in libunwind.h +for ac_header in syslog.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then @@ -20967,15 +21695,158 @@ if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF - ac_cv_have_libunwind_h=1 + +fi + +done + + +for ac_header in sys/time.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + { echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } + +# Is the header present? +{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( cat <<\_ASBOX +## ------------------------------------ ## +## Report this to opensource@google.com ## +## ------------------------------------ ## +_ASBOX + ) | sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else - ac_cv_have_libunwind_h=0 + eval "$as_ac_Header=\$ac_header_preproc" +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + fi done -for ac_header in ucontext.h +for ac_header in glob.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then @@ -21884,6 +22755,95 @@ _ACEOF fi +{ echo "$as_me:$LINENO: checking for fcntl" >&5 +echo $ECHO_N "checking for fcntl... $ECHO_C" >&6; } +if test "${ac_cv_func_fcntl+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define fcntl to an innocuous variant, in case declares fcntl. + For example, HP-UX 11i declares gettimeofday. */ +#define fcntl innocuous_fcntl + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char fcntl (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef fcntl + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char fcntl (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_fcntl || defined __stub___fcntl +choke me +#endif + +int +main () +{ +return fcntl (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_func_fcntl=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_func_fcntl=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_func_fcntl" >&5 +echo "${ECHO_T}$ac_cv_func_fcntl" >&6; } +if test $ac_cv_func_fcntl = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_FCNTL 1 +_ACEOF + +fi + { echo "$as_me:$LINENO: checking for __attribute__" >&5 @@ -23521,6 +24481,7 @@ fi + # Write generated configuration file ac_config_files="$ac_config_files Makefile src/glog/logging.h src/glog/raw_logging.h src/glog/vlog_is_on.h src/glog/stl_logging.h" @@ -24365,6 +25326,7 @@ ac_cv_have___builtin_expect!$ac_cv_have___builtin_expect$ac_delim ac_cv_have_stdint_h!$ac_cv_have_stdint_h$ac_delim ac_cv_have_systypes_h!$ac_cv_have_systypes_h$ac_delim ac_cv_have_inttypes_h!$ac_cv_have_inttypes_h$ac_delim +ac_cv_have_unistd_h!$ac_cv_have_unistd_h$ac_delim ac_cv_have_uint16_t!$ac_cv_have_uint16_t$ac_delim ac_cv_have_u_int16_t!$ac_cv_have_u_int16_t$ac_delim ac_cv_have___uint16!$ac_cv_have___uint16$ac_delim @@ -24374,7 +25336,7 @@ LIBOBJS!$LIBOBJS$ac_delim LTLIBOBJS!$LTLIBOBJS$ac_delim _ACEOF - if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 36; then + if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 37; then break elif $ac_last_try; then { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 diff --git a/configure.ac b/configure.ac index c49196b..dcb4cee 100644 --- a/configure.ac +++ b/configure.ac @@ -28,13 +28,19 @@ AC_HEADER_STDC AC_CHECK_HEADER(stdint.h, ac_cv_have_stdint_h=1, ac_cv_have_stdint_h=0) AC_CHECK_HEADER(sys/types.h, ac_cv_have_systypes_h=1, ac_cv_have_systypes_h=0) AC_CHECK_HEADER(inttypes.h, ac_cv_have_inttypes_h=1, ac_cv_have_inttypes_h=0) +AC_CHECK_HEADERS(unistd.h, ac_cv_have_unistd_h=1, ac_cv_have_unistd_h=0) AC_CHECK_HEADERS(syscall.h) AC_CHECK_HEADERS(sys/syscall.h) # For backtrace with glibc. AC_CHECK_HEADERS(execinfo.h) # For backtrace with libunwind. -AC_CHECK_HEADERS(libunwind.h, ac_cv_have_libunwind_h=1, ac_cv_have_libunwind_h=0) +AC_CHECK_HEADERS(libunwind.h) AC_CHECK_HEADERS(ucontext.h) +AC_CHECK_HEADERS(sys/utsname.h) +AC_CHECK_HEADERS(pwd.h) +AC_CHECK_HEADERS(syslog.h) +AC_CHECK_HEADERS(sys/time.h) +AC_CHECK_HEADERS(glob.h) AC_CHECK_SIZEOF(void *) @@ -50,6 +56,9 @@ AC_CHECK_FUNC(sigaltstack, AC_CHECK_FUNC(dladdr, AC_DEFINE(HAVE_DLADDR, 1, [Define if you have the `dladdr' function])) +AC_CHECK_FUNC(fcntl, + AC_DEFINE(HAVE_FCNTL, 1, + [Define if you have the `fcntl' function])) AX_C___ATTRIBUTE__ # We only care about these two attributes. @@ -168,6 +177,7 @@ AC_SUBST(ac_cv_have___builtin_expect) AC_SUBST(ac_cv_have_stdint_h) AC_SUBST(ac_cv_have_systypes_h) AC_SUBST(ac_cv_have_inttypes_h) +AC_SUBST(ac_cv_have_unistd_h) AC_SUBST(ac_cv_have_uint16_t) AC_SUBST(ac_cv_have_u_int16_t) AC_SUBST(ac_cv_have___uint16) diff --git a/google-glog.sln b/google-glog.sln new file mode 100755 index 0000000..2ef93e3 --- /dev/null +++ b/google-glog.sln @@ -0,0 +1,29 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual C++ Express 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libglog", "vsprojects\libglog\libglog.vcproj", "{34BD04BD-BC1D-4BFC-AAFC-ED02D9E960F1}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "logging_unittest", "vsprojects\logging_unittest\logging_unittest.vcproj", "{DD0690AA-5E09-46B5-83FD-4B28604CABA8}" + ProjectSection(ProjectDependencies) = postProject + {34BD04BD-BC1D-4BFC-AAFC-ED02D9E960F1} = {34BD04BD-BC1D-4BFC-AAFC-ED02D9E960F1} + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {34BD04BD-BC1D-4BFC-AAFC-ED02D9E960F1}.Debug|Win32.ActiveCfg = Debug|Win32 + {34BD04BD-BC1D-4BFC-AAFC-ED02D9E960F1}.Debug|Win32.Build.0 = Debug|Win32 + {34BD04BD-BC1D-4BFC-AAFC-ED02D9E960F1}.Release|Win32.ActiveCfg = Release|Win32 + {34BD04BD-BC1D-4BFC-AAFC-ED02D9E960F1}.Release|Win32.Build.0 = Release|Win32 + {DD0690AA-5E09-46B5-83FD-4B28604CABA8}.Debug|Win32.ActiveCfg = Debug|Win32 + {DD0690AA-5E09-46B5-83FD-4B28604CABA8}.Debug|Win32.Build.0 = Debug|Win32 + {DD0690AA-5E09-46B5-83FD-4B28604CABA8}.Release|Win32.ActiveCfg = Release|Win32 + {DD0690AA-5E09-46B5-83FD-4B28604CABA8}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/src/base/commandlineflags.h b/src/base/commandlineflags.h index 5c5011e..81b9e76 100644 --- a/src/base/commandlineflags.h +++ b/src/base/commandlineflags.h @@ -63,12 +63,12 @@ #define DECLARE_VARIABLE(type, name, tn) \ namespace FLAG__namespace_do_not_use_directly_use_DECLARE_##tn##_instead { \ - extern type FLAGS_##name; \ + extern GOOGLE_GLOG_DLL_DECL type FLAGS_##name; \ } \ using FLAG__namespace_do_not_use_directly_use_DECLARE_##tn##_instead::FLAGS_##name #define DEFINE_VARIABLE(type, name, value, meaning, tn) \ namespace FLAG__namespace_do_not_use_directly_use_DECLARE_##tn##_instead { \ - type FLAGS_##name(value); \ + GOOGLE_GLOG_DLL_DECL type FLAGS_##name(value); \ char FLAGS_no##name; \ } \ using FLAG__namespace_do_not_use_directly_use_DECLARE_##tn##_instead::FLAGS_##name @@ -90,12 +90,13 @@ // std::string, which doesn't play nicely with our FLAG__namespace hackery. #define DECLARE_string(name) \ namespace FLAG__namespace_do_not_use_directly_use_DECLARE_string_instead { \ - extern std::string FLAGS_##name; \ + extern GOOGLE_GLOG_DLL_DECL std::string FLAGS_##name; \ } \ using FLAG__namespace_do_not_use_directly_use_DECLARE_string_instead::FLAGS_##name #define DEFINE_string(name, value, meaning) \ namespace FLAG__namespace_do_not_use_directly_use_DECLARE_string_instead { \ - std::string FLAGS_##name(EnvToString("GLOG_" #name, value)); \ + GOOGLE_GLOG_DLL_DECL std::string \ + FLAGS_##name(EnvToString("GLOG_" #name, value)); \ char FLAGS_no##name; \ } \ using FLAG__namespace_do_not_use_directly_use_DECLARE_string_instead::FLAGS_##name diff --git a/src/config.h.in b/src/config.h.in index f613e7a..8737b9f 100644 --- a/src/config.h.in +++ b/src/config.h.in @@ -12,6 +12,12 @@ /* Define to 1 if you have the header file. */ #undef HAVE_EXECINFO_H +/* Define if you have the `fcntl' function */ +#undef HAVE_FCNTL + +/* Define to 1 if you have the header file. */ +#undef HAVE_GLOB_H + /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H @@ -36,6 +42,9 @@ /* Define if you have POSIX threads libraries and header files. */ #undef HAVE_PTHREAD +/* Define to 1 if you have the header file. */ +#undef HAVE_PWD_H + /* define if the compiler implements pthread_rwlock_* */ #undef HAVE_RWLOCK @@ -57,15 +66,24 @@ /* Define to 1 if you have the header file. */ #undef HAVE_SYSCALL_H +/* Define to 1 if you have the header file. */ +#undef HAVE_SYSLOG_H + /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SYSCALL_H +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TIME_H + /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_UTSNAME_H + /* Define to 1 if you have the header file. */ #undef HAVE_UCONTEXT_H diff --git a/src/config_for_unittests.h b/src/config_for_unittests.h new file mode 100644 index 0000000..13ea8ea --- /dev/null +++ b/src/config_for_unittests.h @@ -0,0 +1,66 @@ +// Copyright (c) 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. + +// --- +// All Rights Reserved. +// +// Author: Craig Silverstein +// Copied from google-perftools and modified by Shinichiro Hamaji +// +// This file is needed for windows -- unittests are not part of the +// glog dll, but still want to include config.h just like the +// dll does, so they can use internal tools and APIs for testing. +// +// The problem is that config.h declares GOOGLE_GLOG_DLL_DECL to be +// for exporting symbols, but the unittest needs to *import* symbols +// (since it's not the dll). +// +// The solution is to have this file, which is just like config.h but +// sets GOOGLE_GLOG_DLL_DECL to do a dllimport instead of a dllexport. +// +// The reason we need this extra GOOGLE_GLOG_DLL_DECL_FOR_UNITTESTS +// variable is in case people want to set GOOGLE_GLOG_DLL_DECL explicitly +// to something other than __declspec(dllexport). In that case, they +// may want to use something other than __declspec(dllimport) for the +// unittest case. For that, we allow folks to define both +// GOOGLE_GLOG_DLL_DECL and GOOGLE_GLOG_DLL_DECL_FOR_UNITTESTS explicitly. +// +// NOTE: This file is equivalent to config.h on non-windows systems, +// which never defined GOOGLE_GLOG_DLL_DECL_FOR_UNITTESTS and always +// define GOOGLE_GLOG_DLL_DECL to the empty string. + +#include "config.h" + +#undef GOOGLE_GLOG_DLL_DECL +#ifdef GOOGLE_GLOG_DLL_DECL_FOR_UNITTESTS +# define GOOGLE_GLOG_DLL_DECL GOOGLE_GLOG_DLL_DECL_FOR_UNITTESTS +#else +// if DLL_DECL_FOR_UNITTESTS isn't defined, use "" +# define GOOGLE_GLOG_DLL_DECL +#endif diff --git a/src/glog/log_severity.h b/src/glog/log_severity.h index 11820a3..b90d333 100644 --- a/src/glog/log_severity.h +++ b/src/glog/log_severity.h @@ -3,6 +3,15 @@ #ifndef BASE_LOG_SEVERITY_H__ #define BASE_LOG_SEVERITY_H__ +// Annoying stuff for windows -- makes sure clients can import these functions +#ifndef GOOGLE_GLOG_DLL_DECL +# ifdef _WIN32 +# define GOOGLE_GLOG_DLL_DECL __declspec(dllimport) +# else +# define GOOGLE_GLOG_DLL_DECL +# endif +#endif + // Variables of type LogSeverity are widely taken to lie in the range // [0, NUM_SEVERITIES-1]. Be careful to preserve this assumption if // you ever need to change their values or add a new severity. @@ -17,7 +26,7 @@ const int INFO = 0, WARNING = 1, ERROR = 2, FATAL = 3, NUM_SEVERITIES = 4; #define DFATAL_LEVEL FATAL #endif -extern const char* const LogSeverityNames[NUM_SEVERITIES]; +extern GOOGLE_GLOG_DLL_DECL const char* const LogSeverityNames[NUM_SEVERITIES]; // NDEBUG usage helpers related to (RAW_)DCHECK: // diff --git a/src/glog/logging.h.in b/src/glog/logging.h.in index e982553..0949432 100644 --- a/src/glog/logging.h.in +++ b/src/glog/logging.h.in @@ -14,7 +14,9 @@ #include #include #include -#include +#if @ac_cv_have_unistd_h@ +# include +#endif #ifdef __DEPRECATED // Make GCC quiet. # undef __DEPRECATED @@ -25,6 +27,15 @@ #endif #include +// Annoying stuff for windows -- makes sure clients can import these functions +#ifndef GOOGLE_GLOG_DLL_DECL +# ifdef _WIN32 +# define GOOGLE_GLOG_DLL_DECL __declspec(dllimport) +# else +# define GOOGLE_GLOG_DLL_DECL +# endif +#endif + // We care a lot about number of bits things take up. Unfortunately, // systems define their bit-specific ints in a lot of different ways. // We use our own way, and have a typedef to get there. @@ -59,9 +70,9 @@ typedef int64_t int64; typedef u_int64_t uint64; #elif @ac_cv_have___uint16@ // the windows (vc7) format typedef __int32 int32; -typedef __uint32 uint32; +typedef unsigned __int32 uint32; typedef __int64 int64; -typedef __uint64 uint64; +typedef unsigned __int64 uint64; #else #error Do not know how to define a 32-bit integer quantity on your system #endif @@ -222,7 +233,7 @@ typedef __uint64 uint64; #define MUST_UNDEF_GFLAGS_DECLARE_MACROS #define DECLARE_VARIABLE(type, name, tn) \ namespace FLAG__namespace_do_not_use_directly_use_DECLARE_##tn##_instead { \ - extern type FLAGS_##name; \ + extern GOOGLE_GLOG_DLL_DECL type FLAGS_##name; \ } \ using FLAG__namespace_do_not_use_directly_use_DECLARE_##tn##_instead::FLAGS_##name @@ -238,7 +249,7 @@ typedef __uint64 uint64; // std::string, which doesn't play nicely with our FLAG__namespace hackery. #define DECLARE_string(name) \ namespace FLAG__namespace_do_not_use_directly_use_DECLARE_string_instead { \ - extern std::string FLAGS_##name; \ + extern GOOGLE_GLOG_DLL_DECL std::string FLAGS_##name; \ } \ using FLAG__namespace_do_not_use_directly_use_DECLARE_string_instead::FLAGS_##name #endif @@ -376,10 +387,10 @@ DECLARE_bool(alsologtostderr); // Initialize google's logging library. You will see the program name // specified by argv0 in log outputs. -void InitGoogleLogging(const char* argv0); +GOOGLE_GLOG_DLL_DECL void InitGoogleLogging(const char* argv0); // Install a function which will be called after LOG(FATAL). -void InstallFailureFunction(void (*fail_func)()); +GOOGLE_GLOG_DLL_DECL void InstallFailureFunction(void (*fail_func)()); class LogSink; // defined below @@ -581,8 +592,8 @@ typedef std::string _Check_string; // Helper functions for string comparisons. // To avoid bloat, the definitions are in logging.cc. #define DECLARE_CHECK_STROP_IMPL(func, expected) \ - std::string* Check##func##expected##Impl(const char* s1, const char* s2, \ - const char* names); + GOOGLE_GLOG_DLL_DECL std::string* Check##func##expected##Impl( \ + const char* s1, const char* s2, const char* names); DECLARE_CHECK_STROP_IMPL(strcmp, true) DECLARE_CHECK_STROP_IMPL(strcmp, false) DECLARE_CHECK_STROP_IMPL(strcasecmp, true) @@ -833,7 +844,7 @@ enum PRIVATE_Counter {COUNTER}; // You shouldn't actually use LogMessage's constructor to log things, // though. You should use the LOG() macro (and variants thereof) // above. -class LogMessage { +class GOOGLE_GLOG_DLL_DECL LogMessage { public: enum { // Passing kNoLogPrefix for the line number disables the @@ -844,7 +855,19 @@ public: kNoLogPrefix = -1 }; - class LogStream : public std::ostrstream { + // LogStream inherit from non-DLL-exported class (std::ostrstream) + // and VC++ produces a warning for this situation. + // However, MSDN says "C4275 can be ignored in Microsoft Visual C++ + // 2005 if you are deriving from a type in the Standard C++ Library" + // http://msdn.microsoft.com/en-us/library/3tdb471s(VS.80).aspx + // Let's just ignore the warning. +#ifdef _MSC_VER +# pragma warning(disable: 4275) +#endif + class GOOGLE_GLOG_DLL_DECL LogStream : public std::ostrstream { +#ifdef _MSC_VER +# pragma warning(default: 4275) +#endif public: LogStream(char *buf, int len, int ctr) : ostrstream(buf, len), @@ -940,11 +963,9 @@ private: // Counts of messages sent at each priority: static int64 num_messages_[NUM_SEVERITIES]; // under log_mutex - static LogMessageData fatal_message_data_; - // We keep the data in a separate struct so that each instance of // LogMessage uses less stack space. - struct LogMessageData { + struct GOOGLE_GLOG_DLL_DECL LogMessageData { // ORDER DEPENDENCY: preserved_errno_ comes before buf_ comes before // message_text_ comes before stream_ int preserved_errno_; // preserved errno @@ -978,6 +999,8 @@ private: void operator=(const LogMessageData&); }; + static LogMessageData fatal_message_data_; + LogMessageData* allocated_; LogMessageData* data_; @@ -990,7 +1013,7 @@ private: // This class happens to be thread-hostile because all instances share // a single data buffer, but since it can only be created just before // the process dies, we don't worry so much. -class LogMessageFatal : public LogMessage { +class GOOGLE_GLOG_DLL_DECL LogMessageFatal : public LogMessage { public: LogMessageFatal(const char* file, int line); LogMessageFatal(const char* file, int line, const CheckOpString& result); @@ -1015,11 +1038,12 @@ T* CheckNotNull(const char *file, int line, const char *names, T* t) { // Allow folks to put a counter in the LOG_EVERY_X()'ed messages. This // only works if ostream is a LogStream. If the ostream is not a // LogStream you'll get an assert saying as much at runtime. -std::ostream& operator<<(std::ostream &os, const PRIVATE_Counter&); +GOOGLE_GLOG_DLL_DECL std::ostream& operator<<(std::ostream &os, + const PRIVATE_Counter&); // Derived class for PLOG*() above. -class ErrnoLogMessage : public LogMessage { +class GOOGLE_GLOG_DLL_DECL ErrnoLogMessage : public LogMessage { public: ErrnoLogMessage(const char* file, int line, LogSeverity severity, int ctr, @@ -1038,7 +1062,7 @@ class ErrnoLogMessage : public LogMessage { // logging macros. This avoids compiler warnings like "value computed // is not used" and "statement has no effect". -class LogMessageVoidify { +class GOOGLE_GLOG_DLL_DECL LogMessageVoidify { public: LogMessageVoidify() { } // This has to be an operator with a precedence lower than << but @@ -1049,19 +1073,20 @@ class LogMessageVoidify { // Flushes all log files that contains messages that are at least of // the specified severity level. Thread-safe. -void FlushLogFiles(LogSeverity min_severity); +GOOGLE_GLOG_DLL_DECL void FlushLogFiles(LogSeverity min_severity); // Flushes all log files that contains messages that are at least of // the specified severity level. Thread-hostile because it ignores // locking -- used for catastrophic failures. -void FlushLogFilesUnsafe(LogSeverity min_severity); +GOOGLE_GLOG_DLL_DECL void FlushLogFilesUnsafe(LogSeverity min_severity); // // Set the destination to which a particular severity level of log // messages is sent. If base_filename is "", it means "don't log this // severity". Thread-safe. // -void SetLogDestination(LogSeverity severity, const char* base_filename); +GOOGLE_GLOG_DLL_DECL void SetLogDestination(LogSeverity severity, + const char* base_filename); // // Set the basename of the symlink to the latest log file at a given @@ -1069,14 +1094,15 @@ void SetLogDestination(LogSeverity severity, const char* base_filename); // you don't call this function, the symlink basename is the // invocation name of the program. Thread-safe. // -void SetLogSymlink(LogSeverity severity, const char* symlink_basename); +GOOGLE_GLOG_DLL_DECL void SetLogSymlink(LogSeverity severity, + const char* symlink_basename); // // Used to send logs to some other kind of destination // Users should subclass LogSink and override send to do whatever they want. // Implementations must be thread-safe because a shared instance will // be called from whichever thread ran the LOG(XXX) line. -class LogSink { +class GOOGLE_GLOG_DLL_DECL LogSink { public: virtual ~LogSink(); @@ -1111,8 +1137,8 @@ class LogSink { }; // Add or remove a LogSink as a consumer of logging data. Thread-safe. -void AddLogSink(LogSink *destination); -void RemoveLogSink(LogSink *destination); +GOOGLE_GLOG_DLL_DECL void AddLogSink(LogSink *destination); +GOOGLE_GLOG_DLL_DECL void RemoveLogSink(LogSink *destination); // // Specify an "extension" added to the filename specified via @@ -1120,19 +1146,20 @@ void RemoveLogSink(LogSink *destination); // often used to append the port we're listening on to the logfile // name. Thread-safe. // -void SetLogFilenameExtension(const char* filename_extension); +GOOGLE_GLOG_DLL_DECL void SetLogFilenameExtension( + const char* filename_extension); // // Make it so that all log messages of at least a particular severity // are logged to stderr (in addition to logging to the usual log // file(s)). Thread-safe. // -void SetStderrLogging(LogSeverity min_severity); +GOOGLE_GLOG_DLL_DECL void SetStderrLogging(LogSeverity min_severity); // // Make it so that all log messages go only to stderr. Thread-safe. // -void LogToStderr(); +GOOGLE_GLOG_DLL_DECL void LogToStderr(); // // Make it so that all log messages of at least a particular severity are @@ -1140,13 +1167,15 @@ void LogToStderr(); // usual log file(s)). The list of addresses is just a string containing // the email addresses to send to (separated by spaces, say). Thread-safe. // -void SetEmailLogging(LogSeverity min_severity, const char* addresses); +GOOGLE_GLOG_DLL_DECL void SetEmailLogging(LogSeverity min_severity, + const char* addresses); // A simple function that sends email. dest is a commma-separated // list of addressess. Thread-safe. -bool SendEmail(const char*dest, const char *subject, const char*body); +GOOGLE_GLOG_DLL_DECL bool SendEmail(const char *dest, + const char *subject, const char *body); -const std::vector& GetLoggingDirectories(); +GOOGLE_GLOG_DLL_DECL const std::vector& GetLoggingDirectories(); // For tests only: Clear the internal [cached] list of logging directories to // force a refresh the next time GetLoggingDirectories is called. @@ -1156,12 +1185,13 @@ void TestOnly_ClearLoggingDirectoriesList(); // Returns a set of existing temporary directories, which will be a // subset of the directories returned by GetLogginDirectories(). // Thread-safe. -void GetExistingTempDirectories(std::vector* list); +GOOGLE_GLOG_DLL_DECL void GetExistingTempDirectories( + std::vector* list); // Print any fatal message again -- useful to call from signal handler // so that the last thing in the output is the fatal message. // Thread-hostile, but a race is unlikely. -void ReprintFatalMessage(); +GOOGLE_GLOG_DLL_DECL void ReprintFatalMessage(); // Truncate a log file that may be the append-only output of multiple // processes and hence can't simply be renamed/reopened (typically a @@ -1170,16 +1200,17 @@ void ReprintFatalMessage(); // be racing with other writers, this approach has the potential to // lose very small amounts of data. For security, only follow symlinks // if the path is /proc/self/fd/* -void TruncateLogFile(const char *path, int64 limit, int64 keep); +GOOGLE_GLOG_DLL_DECL void TruncateLogFile(const char *path, + int64 limit, int64 keep); // Truncate stdout and stderr if they are over the value specified by // --max_log_size; keep the final 1MB. This function has the same // race condition as TruncateLogFile. -void TruncateStdoutStderr(); +GOOGLE_GLOG_DLL_DECL void TruncateStdoutStderr(); // Return the string representation of the provided LogSeverity level. // Thread-safe. -const char* GetLogSeverityName(LogSeverity severity); +GOOGLE_GLOG_DLL_DECL const char* GetLogSeverityName(LogSeverity severity); // --------------------------------------------------------------------- // Implementation details that are not useful to most clients @@ -1194,7 +1225,7 @@ const char* GetLogSeverityName(LogSeverity severity); namespace base { -class Logger { +class GOOGLE_GLOG_DLL_DECL Logger { public: virtual ~Logger(); @@ -1223,12 +1254,12 @@ class Logger { // Get the logger for the specified severity level. The logger // remains the property of the logging module and should not be // deleted by the caller. Thread-safe. -extern Logger* GetLogger(LogSeverity level); +extern GOOGLE_GLOG_DLL_DECL Logger* GetLogger(LogSeverity level); // Set the logger for the specified severity level. The logger // becomes the property of the logging module and should not // be deleted by the caller. Thread-safe. -extern void SetLogger(LogSeverity level, Logger* logger); +extern GOOGLE_GLOG_DLL_DECL void SetLogger(LogSeverity level, Logger* logger); } @@ -1242,11 +1273,11 @@ extern void SetLogger(LogSeverity level, Logger* logger); // be set to an empty string, if this function failed. This means, in most // cases, you do not need to check the error code and you can directly // use the value of "buf". It will never have an undefined value. -int posix_strerror_r(int err, char *buf, size_t len); +GOOGLE_GLOG_DLL_DECL int posix_strerror_r(int err, char *buf, size_t len); // A class for which we define operator<<, which does nothing. -class NullStream : public LogMessage::LogStream { +class GOOGLE_GLOG_DLL_DECL NullStream : public LogMessage::LogStream { public: // Initialize the LogStream so the messages can be written somewhere // (they'll never be actually displayed). This will be needed if a @@ -1272,7 +1303,7 @@ inline NullStream& operator<<(NullStream &str, const T &value) { return str; } // Similar to NullStream, but aborts the program (without stack // trace), like LogMessageFatal. -class NullStreamFatal : public NullStream { +class GOOGLE_GLOG_DLL_DECL NullStreamFatal : public NullStream { public: @ac_cv___attribute___noreturn@ ~NullStreamFatal() { _exit(1); } }; @@ -1293,13 +1324,14 @@ class NullStreamFatal : public NullStream { // to use the failure signal handler for all threads. The stack trace // will be shown only for the thread that receives the signal. In other // words, stack traces of other threads won't be shown. -void InstallFailureSignalHandler(); +GOOGLE_GLOG_DLL_DECL void InstallFailureSignalHandler(); // Installs a function that is used for writing the failure dump. "data" // is the pointer to the beginning of a message to be written, and "size" // is the size of the message. You should not expect the data is // terminated with '\0'. -void InstallFailureWriter(void (*writer)(const char* data, int size)); +GOOGLE_GLOG_DLL_DECL void InstallFailureWriter( + void (*writer)(const char* data, int size)); @ac_google_end_namespace@ diff --git a/src/glog/raw_logging.h.in b/src/glog/raw_logging.h.in index 07e8e56..c7d92d9 100644 --- a/src/glog/raw_logging.h.in +++ b/src/glog/raw_logging.h.in @@ -13,6 +13,15 @@ #include "glog/log_severity.h" #include "glog/vlog_is_on.h" +// Annoying stuff for windows -- makes sure clients can import these functions +#ifndef GOOGLE_GLOG_DLL_DECL +# ifdef _WIN32 +# define GOOGLE_GLOG_DLL_DECL __declspec(dllimport) +# else +# define GOOGLE_GLOG_DLL_DECL +# endif +#endif + // This is similar to LOG(severity) << format... and VLOG(level) << format.., // but // * it is to be used ONLY by low-level modules that can't use normal LOG() @@ -72,15 +81,17 @@ // Logs format... at "severity" level, reporting it // as called from file:line. // This does not allocate memory or acquire locks. -void RawLog__(LogSeverity severity, const char* file, int line, - const char* format, ...) +GOOGLE_GLOG_DLL_DECL void RawLog__(LogSeverity severity, + const char* file, + int line, + const char* format, ...) @ac_cv___attribute___printf_4_5@; // Hack to propagate time information into this module so that // this module does not have to directly call localtime_r(), // which could allocate memory. extern "C" struct ::tm; -void RawLog__SetLastTime(const struct ::tm& t); +GOOGLE_GLOG_DLL_DECL void RawLog__SetLastTime(const struct ::tm& t); @ac_google_end_namespace@ diff --git a/src/glog/vlog_is_on.h.in b/src/glog/vlog_is_on.h.in index 1a78d41..ff1adb8 100644 --- a/src/glog/vlog_is_on.h.in +++ b/src/glog/vlog_is_on.h.in @@ -35,6 +35,15 @@ #include "glog/log_severity.h" +// Annoying stuff for windows -- makes sure clients can import these functions +#ifndef GOOGLE_GLOG_DLL_DECL +# ifdef _WIN32 +# define GOOGLE_GLOG_DLL_DECL __declspec(dllimport) +# else +# define GOOGLE_GLOG_DLL_DECL +# endif +#endif + #if defined(__GNUC__) // We emit an anonymous static int* variable at every VLOG_IS_ON(n) site. // (Normally) the first time every VLOG_IS_ON(n) site is hit, @@ -63,7 +72,8 @@ // one needs to supply the exact --vmodule pattern that applied to them. // (If no --vmodule pattern applied to them // the value of FLAGS_v will continue to control them.) -extern int SetVLOGLevel(const char* module_pattern, int log_level); +extern GOOGLE_GLOG_DLL_DECL int SetVLOGLevel(const char* module_pattern, + int log_level); // Various declarations needed for VLOG_IS_ON above: ========================= @@ -81,9 +91,10 @@ extern @ac_google_namespace@::int32 kLogSiteUninitialized; // verbose_level is the argument to VLOG_IS_ON // We will return the return value for VLOG_IS_ON // and if possible set *site_flag appropriately. -extern bool InitVLOG3__(@ac_google_namespace@::int32** site_flag, - @ac_google_namespace@::int32* site_default, - const char* fname, - @ac_google_namespace@::int32 verbose_level); +extern GOOGLE_GLOG_DLL_DECL bool InitVLOG3__( + @ac_google_namespace@::int32** site_flag, + @ac_google_namespace@::int32* site_default, + const char* fname, + @ac_google_namespace@::int32 verbose_level); #endif // BASE_VLOG_IS_ON_H_ diff --git a/src/googletest.h b/src/googletest.h index 503104f..d53800d 100644 --- a/src/googletest.h +++ b/src/googletest.h @@ -15,7 +15,9 @@ #include #include #include -#include +#ifdef HAVE_UNISTD_H +# include +#endif #include "base/commandlineflags.h" @@ -23,15 +25,44 @@ using std::map; using std::string; using std::vector; -DEFINE_string(test_tmpdir, "/tmp", "Dir we use for temp files"); -DEFINE_string(test_srcdir, ".", +_START_GOOGLE_NAMESPACE_ + +extern GOOGLE_GLOG_DLL_DECL void (*g_logging_fail_func)(); + +_END_GOOGLE_NAMESPACE_ + +#undef GOOGLE_GLOG_DLL_DECL +#define GOOGLE_GLOG_DLL_DECL + +static string GetTempDir() { +#ifndef OS_WINDOWS + return "/tmp"; +#else + char tmp[MAX_PATH]; + GetTempPathA(MAX_PATH, tmp); + return tmp; +#endif +} + +#ifdef OS_WINDOWS +// The test will run in glog/vsproject/ +// (e.g., glog/vsproject/logging_unittest). +static const char TEST_SRC_DIR[] = "../.."; +#else +static const char TEST_SRC_DIR[] = "."; +#endif + +DEFINE_string(test_tmpdir, GetTempDir(), "Dir we use for temp files"); +DEFINE_string(test_srcdir, TEST_SRC_DIR, "Source-dir root, needed to find glog_unittest_flagfile"); +#ifdef NDEBUG DEFINE_int32(benchmark_iters, 100000000, "Number of iterations per benchmark"); +#else +DEFINE_int32(benchmark_iters, 1000000, "Number of iterations per benchmark"); +#endif _START_GOOGLE_NAMESPACE_ -extern void (*g_logging_fail_func)(); - // The following is some bare-bones testing infrastructure #define EXPECT_TRUE(cond) \ @@ -96,6 +127,10 @@ static void CalledAbort() { longjmp(g_jmp_buf, 1); } +#ifdef OS_WINDOWS +// TODO(hamaji): Death test somehow doesn't work in Windows. +#define ASSERT_DEATH(fn, msg) +#else #define ASSERT_DEATH(fn, msg) \ do { \ g_called_abort = false; \ @@ -110,6 +145,7 @@ static void CalledAbort() { exit(1); \ } \ } while (0) +#endif #ifdef NDEBUG #define ASSERT_DEBUG_DEATH(fn, msg) @@ -307,11 +343,10 @@ static string MungeLine(const string& line) { iss >> logcode_date; while (!IsLoggingPrefix(logcode_date)) { before += " " + logcode_date; - if (iss.eof()) { + if (!(iss >> logcode_date)) { // We cannot find the header of log output. return before; } - iss >> logcode_date; } if (!before.empty()) before += " "; iss >> time; @@ -354,6 +389,8 @@ static string Munge(const string& filename) { char null_str[256]; sprintf(null_str, "%p", NULL); StringReplace(&line, "__NULLP__", null_str); + // Remove 0x prefix produced by %p. VC++ doesn't put the prefix. + StringReplace(&line, " 0x", " "); char errmsg_buf[100]; posix_strerror_r(0, errmsg_buf, sizeof(errmsg_buf)); @@ -429,16 +466,32 @@ struct FlagSaver { }; #endif -// TODO(hamaji): Make it portable. class Thread { public: void SetJoinable(bool joinable) {} +#if defined(HAVE_PTHREAD) void Start() { pthread_create(&th_, NULL, &Thread::InvokeThread, this); } void Join() { pthread_join(th_, NULL); } +#elif defined(OS_WINDOWS) + void Start() { + handle_ = CreateThread(NULL, + 0, + (LPTHREAD_START_ROUTINE)&Thread::InvokeThread, + (LPVOID)this, + 0, + &th_); + CHECK(handle_) << "CreateThread"; + } + void Join() { + WaitForSingleObject(handle_, INFINITE); + } +#else +# error No thread implementation. +#endif protected: virtual void Run() = 0; @@ -450,11 +503,17 @@ class Thread { } pthread_t th_; +#ifdef OS_WINDOWS + HANDLE handle_; +#endif }; -// TODO(hamaji): Make it portable. static void SleepForMilliseconds(int t) { +#ifndef OS_WINDOWS usleep(t * 1000); +#else + Sleep(t); +#endif } // Add hook for operator new to ensure there are no memory allocation. diff --git a/src/logging.cc b/src/logging.cc index 06516fb..c0da25e 100644 --- a/src/logging.cc +++ b/src/logging.cc @@ -3,21 +3,28 @@ #include "utilities.h" #include -#include #include #include -#include +#ifdef HAVE_UNISTD_H +# include // For _exit. +#endif #include #include #include -#include +#ifdef HAVE_SYS_UTSNAME_H +# include // For uname. +#endif #include #include #include #include #include -#include -#include +#ifdef HAVE_PWD_H +# include +#endif +#ifdef HAVE_SYSLOG_H +# include +#endif #include #include // for errno #include @@ -101,6 +108,28 @@ DEFINE_bool(stop_logging_if_full_disk, false, // TODO(hamaji): consider windows #define PATH_SEPARATOR '/' +static void GetHostName(string* hostname) { +#if defined(HAVE_SYS_UTSNAME_H) + struct utsname buf; + if (0 != uname(&buf)) { + // ensure null termination on failure + *buf.nodename = '\0'; + } + *hostname = buf.nodename; +#elif defined(OS_WINDOWS) + char buf[256]; + DWORD len; + if (GetComputerNameA(buf, &len)) { + *hostname = buf; + } else { + hostname->clear(); + } +#else +# warning There is no way to retrieve the host name. + *hostname = "(unknown)"; +#endif +} + _START_GOOGLE_NAMESPACE_ // A mutex that allows only one thread to log at a time, to keep things from @@ -130,6 +159,8 @@ static bool SendEmailInternal(const char*dest, const char *subject, base::Logger::~Logger() { } +namespace { + // Encapsulates all file-system related state class LogFileObject : public base::Logger { public: @@ -182,61 +213,7 @@ class LogFileObject : public base::Logger { bool CreateLogfile(const char* time_pid_string); }; -LogFileObject::LogFileObject(LogSeverity severity, - const char* base_filename) - : base_filename_selected_(base_filename != NULL), - base_filename_((base_filename != NULL) ? base_filename : ""), - symlink_basename_(ProgramInvocationShortName()), - filename_extension_(), - file_(NULL), - severity_(severity), - bytes_since_flush_(0), - file_length_(0), - rollover_attempt_(kRolloverAttemptFrequency-1), - next_flush_time_(0) { - assert(severity >= 0); - assert(severity < NUM_SEVERITIES); -} - -LogFileObject::~LogFileObject() { - MutexLock l(&lock_); - if (file_ != NULL) { - fclose(file_); - file_ = NULL; - } -} - -void LogFileObject::SetBasename(const char* basename) { - MutexLock l(&lock_); - base_filename_selected_ = true; - if (base_filename_ != basename) { - // Get rid of old log file since we are changing names - if (file_ != NULL) { - fclose(file_); - file_ = NULL; - rollover_attempt_ = kRolloverAttemptFrequency-1; - } - base_filename_ = basename; - } -} - -void LogFileObject::SetExtension(const char* ext) { - MutexLock l(&lock_); - if (filename_extension_ != ext) { - // Get rid of old log file since we are changing names - if (file_ != NULL) { - fclose(file_); - file_ = NULL; - rollover_attempt_ = kRolloverAttemptFrequency-1; - } - filename_extension_ = ext; - } -} - -void LogFileObject::SetSymlinkBasename(const char* symlink_basename) { - MutexLock l(&lock_); - symlink_basename_ = symlink_basename; -} +} // namespace class LogDestination { public: @@ -339,10 +316,8 @@ Mutex LogDestination::sink_mutex_; /* static */ const string& LogDestination::hostname() { if (hostname_.empty()) { - struct utsname buf; - if (0 == uname(&buf)) { - hostname_ = buf.nodename; - } else { + GetHostName(&hostname_); + if (hostname_.empty()) { hostname_ = "(unknown)"; } } @@ -355,22 +330,6 @@ LogDestination::LogDestination(LogSeverity severity, logger_(&fileobject_) { } -void LogFileObject::Flush() { - MutexLock l(&lock_); - FlushUnlocked(); -} - -void LogFileObject::FlushUnlocked(){ - if (file_ != NULL) { - fflush(file_); - bytes_since_flush_ = 0; - } - // Figure out when we are due for another flush. - const int64 next = (FLAGS_logbufsecs - * static_cast(1000000)); // in usec - next_flush_time_ = CycleClock_Now() + UsecToCycles(next); -} - inline void LogDestination::FlushLogFilesUnsafe(int min_severity) { // assume we have the log_mutex or we simply don't care // about it @@ -476,7 +435,7 @@ inline void LogDestination::SetEmailLogging(LogSeverity min_severity, static void WriteToStderr(const char* message, size_t len) { // Avoid using cerr from this module since we may get called during // exit code, and cerr may be partially or fully destroyed by then. - fwrite(message, len, 1, stderr); + write(STDERR_FILENO, message, len); } inline void LogDestination::MaybeLogToStderr(LogSeverity severity, @@ -568,14 +527,100 @@ inline void LogDestination::WaitForSinks(LogMessage::LogMessageData* data) { } } +LogDestination* LogDestination::log_destinations_[NUM_SEVERITIES]; + +inline LogDestination* LogDestination::log_destination(LogSeverity severity) { + assert(severity >=0 && severity < NUM_SEVERITIES); + if (!log_destinations_[severity]) { + log_destinations_[severity] = new LogDestination(severity, NULL); + } + return log_destinations_[severity]; +} + +namespace { + +LogFileObject::LogFileObject(LogSeverity severity, + const char* base_filename) + : base_filename_selected_(base_filename != NULL), + base_filename_((base_filename != NULL) ? base_filename : ""), + symlink_basename_(ProgramInvocationShortName()), + filename_extension_(), + file_(NULL), + severity_(severity), + bytes_since_flush_(0), + file_length_(0), + rollover_attempt_(kRolloverAttemptFrequency-1), + next_flush_time_(0) { + assert(severity >= 0); + assert(severity < NUM_SEVERITIES); +} + +LogFileObject::~LogFileObject() { + MutexLock l(&lock_); + if (file_ != NULL) { + fclose(file_); + file_ = NULL; + } +} + +void LogFileObject::SetBasename(const char* basename) { + MutexLock l(&lock_); + base_filename_selected_ = true; + if (base_filename_ != basename) { + // Get rid of old log file since we are changing names + if (file_ != NULL) { + fclose(file_); + file_ = NULL; + rollover_attempt_ = kRolloverAttemptFrequency-1; + } + base_filename_ = basename; + } +} + +void LogFileObject::SetExtension(const char* ext) { + MutexLock l(&lock_); + if (filename_extension_ != ext) { + // Get rid of old log file since we are changing names + if (file_ != NULL) { + fclose(file_); + file_ = NULL; + rollover_attempt_ = kRolloverAttemptFrequency-1; + } + filename_extension_ = ext; + } +} + +void LogFileObject::SetSymlinkBasename(const char* symlink_basename) { + MutexLock l(&lock_); + symlink_basename_ = symlink_basename; +} + +void LogFileObject::Flush() { + MutexLock l(&lock_); + FlushUnlocked(); +} + +void LogFileObject::FlushUnlocked(){ + if (file_ != NULL) { + fflush(file_); + bytes_since_flush_ = 0; + } + // Figure out when we are due for another flush. + const int64 next = (FLAGS_logbufsecs + * static_cast(1000000)); // in usec + next_flush_time_ = CycleClock_Now() + UsecToCycles(next); +} + bool LogFileObject::CreateLogfile(const char* time_pid_string) { string string_filename = base_filename_+filename_extension_+ time_pid_string; const char* filename = string_filename.c_str(); int fd = open(filename, O_WRONLY | O_CREAT | O_EXCL, 0664); if (fd == -1) return false; +#ifdef HAVE_FCNTL // Mark the file close-on-exec. We don't really care if this fails fcntl(fd, F_SETFD, FD_CLOEXEC); +#endif file_ = fdopen(fd, "a"); // Make a FILE*. if (file_ == NULL) { // Man, we're screwed! @@ -599,6 +644,8 @@ bool LogFileObject::CreateLogfile(const char* time_pid_string) { linkpath += linkname; unlink(linkpath.c_str()); // delete old one if it exists + // We must have unistd.h. +#ifdef HAVE_UNISTD_H // Make the symlink be relative (in the same dir) so that if the // entire log directory gets relocated the link is still valid. const char *linkdest = slash ? (slash + 1) : filename; @@ -611,6 +658,7 @@ bool LogFileObject::CreateLogfile(const char* time_pid_string) { unlink(linkpath.c_str()); // delete old one if it exists symlink(filename, linkpath.c_str()); // silently ignore failures } +#endif } return true; // Everything worked @@ -627,7 +675,7 @@ void LogFileObject::Write(bool force_flush, return; } - if ((file_length_ >> 20) >= FLAGS_max_log_size) { + if (static_cast(file_length_ >> 20) >= FLAGS_max_log_size) { fclose(file_); file_ = NULL; file_length_ = bytes_since_flush_ = 0; @@ -679,10 +727,8 @@ void LogFileObject::Write(bool force_flush, // Where does the file get put? Successively try the directories // "/tmp", and "." string stripped_filename(ProgramInvocationShortName()); // in cmdlineflag - struct utsname buf; - if (0 != uname(&buf)) { - *buf.nodename = '\0'; // ensure null termination on failure - } + string hostname; + GetHostName(&hostname); string uidname = MyUserName(); // We should not call CHECK() here because this function can be @@ -691,7 +737,7 @@ void LogFileObject::Write(bool force_flush, // deadlock. Simply use a name like invalid-user. if (uidname.empty()) uidname = "invalid-user"; - stripped_filename = stripped_filename+'.'+buf.nodename+'.' + stripped_filename = stripped_filename+'.'+hostname+'.' +uidname+".log." +LogSeverityNames[severity_]+'.'; // We're going to (potentially) try to put logs in several different dirs @@ -771,26 +817,7 @@ void LogFileObject::Write(bool force_flush, } } -LogDestination* LogDestination::log_destinations_[NUM_SEVERITIES]; - -inline LogDestination* LogDestination::log_destination(LogSeverity severity) { - assert(severity >=0 && severity < NUM_SEVERITIES); - if (!log_destinations_[severity]) { - log_destinations_[severity] = new LogDestination(severity, NULL); - } - return log_destinations_[severity]; -} - -// Get the part of filepath after the last path separator. -// (Doesn't modify filepath, contrary to basename() in libgen.h.) -static const char* const_basename(const char* filepath) { - const char* base = strrchr(filepath, '/'); -#ifdef OS_WINDOWS // Look for either path separator in Windows - if (!base) - base = strrchr(filepath, '\\'); -#endif - return base ? (base+1) : filepath; -} +} // namespace // // LogMessage's constructor starts each message with a string like: @@ -1098,7 +1125,7 @@ void LogMessage::SendToLog() { } static void logging_fail() { -#if defined _DEBUG && defined COMPILER_MSVC +#if defined(_DEBUG) && defined(_MSC_VER) // When debugging on windows, avoid the obnoxious dialog and make // it possible to continue past a LOG(FATAL) in the debugger _asm int 3 @@ -1108,9 +1135,10 @@ static void logging_fail() { } #ifdef HAVE___ATTRIBUTE__ +GOOGLE_GLOG_DLL_DECL void (*g_logging_fail_func)() __attribute__((noreturn)) = &logging_fail; #else -void (*g_logging_fail_func)() = &logging_fail; +GOOGLE_GLOG_DLL_DECL void (*g_logging_fail_func)() = &logging_fail; #endif void InstallFailureFunction(void (*fail_func)()) { @@ -1151,6 +1179,7 @@ void LogMessage::SaveOrSendToLog() { // L >= log_mutex (callers must hold the log_mutex). void LogMessage::SendToSyslogAndLog() { +#ifdef HAVE_SYSLOG_H // Before any calls to syslog(), make a single call to openlog() static bool openlog_already_called = false; if (!openlog_already_called) { @@ -1165,6 +1194,9 @@ void LogMessage::SendToSyslogAndLog() { int(data_->num_chars_to_syslog_), data_->message_text_ + data_->num_prefix_chars_); SendToLog(); +#else + LOG(ERROR) << "No syslog support: message=" << data_->message_text_; +#endif } base::Logger* base::GetLogger(LogSeverity severity) { @@ -1333,7 +1365,7 @@ bool SendEmail(const char*dest, const char *subject, const char*body){ return SendEmailInternal(dest, subject, body, true); } -void GetTempDirectories(vector* list) { +static void GetTempDirectories(vector* list) { list->clear(); #ifdef OS_WINDOWS // On windows we'll try to find a directory in this order: @@ -1429,7 +1461,7 @@ void GetExistingTempDirectories(vector* list) { } void TruncateLogFile(const char *path, int64 limit, int64 keep) { - +#ifdef HAVE_UNISTD_H struct stat statbuf; const int kCopyBlockSize = 8 << 10; char copybuf[kCopyBlockSize]; @@ -1498,28 +1530,36 @@ void TruncateLogFile(const char *path, int64 limit, int64 keep) { out_close_fd: close(fd); - +#else + LOG(ERROR) << "No log truncation support."; +#endif } void TruncateStdoutStderr() { +#ifdef HAVE_UNISTD_H int64 limit = FLAGS_max_log_size << 20; int64 keep = 1 << 20; TruncateLogFile("/proc/self/fd/1", limit, keep); TruncateLogFile("/proc/self/fd/2", limit, keep); +#else + LOG(ERROR) << "No log truncation support."; +#endif } // Helper functions for string comparisons. -#define DEFINE_CHECK_STROP_IMPL(name, func, expected) \ - string* Check##func##expected##Impl(const char* s1, const char* s2, \ - const char* names) { \ - bool equal = s1 == s2 || (s1 && s2 && !func(s1, s2)); \ - if (equal == expected) return NULL; \ - else { \ - strstream ss; \ +#define DEFINE_CHECK_STROP_IMPL(name, func, expected) \ + string* Check##func##expected##Impl(const char* s1, const char* s2, \ + const char* names) { \ + bool equal = s1 == s2 || (s1 && s2 && !func(s1, s2)); \ + if (equal == expected) return NULL; \ + else { \ + strstream ss; \ + if (!s1) s1 = ""; \ + if (!s2) s2 = ""; \ ss << #name " failed: " << names << " (" << s1 << " vs. " << s2 << ")"; \ - return new string(ss.str(), ss.pcount()); \ - } \ + return new string(ss.str(), ss.pcount()); \ + } \ } DEFINE_CHECK_STROP_IMPL(CHECK_STREQ, strcmp, true) DEFINE_CHECK_STROP_IMPL(CHECK_STRNE, strcmp, false) diff --git a/src/logging_unittest.cc b/src/logging_unittest.cc index ddd6ef0..48d2d60 100644 --- a/src/logging_unittest.cc +++ b/src/logging_unittest.cc @@ -4,12 +4,17 @@ // // Author: Ray Sidney +#include "config_for_unittests.h" #include "utilities.h" #include -#include +#ifdef HAVE_GLOB_H +# include +#endif #include -#include +#ifdef HAVE_UNISTD_H +# include +#endif #include #include @@ -356,7 +361,7 @@ void TestLogString() { LOG_STRING(WARNING, no_errors) << "LOG_STRING: " << "reported warning"; LOG_STRING(ERROR, NULL) << "LOG_STRING: " << "reported error"; - for (int i = 0; i < errors.size(); ++i) { + for (size_t i = 0; i < errors.size(); ++i) { LOG(INFO) << "Captured by LOG_STRING: " << errors[i]; } } @@ -386,7 +391,7 @@ void TestLogSink() { LOG_TO_SINK(NULL, ERROR) << "LOG_TO_SINK: " << "reported error"; LOG(INFO) << "Captured by LOG_TO_SINK:"; - for (int i = 0; i < sink.errors.size(); ++i) { + for (size_t i = 0; i < sink.errors.size(); ++i) { LogMessage("foo", LogMessage::kNoLogPrefix, INFO).stream() << sink.errors[i]; } @@ -481,6 +486,7 @@ TEST(DeathCheckNN, Simple) { // Get list of file names that match pattern static void GetFiles(const string& pattern, vector* files) { files->clear(); +#if defined(HAVE_GLOB_H) glob_t g; const int r = glob(pattern.c_str(), 0, NULL, &g); CHECK((r == 0) || (r == GLOB_NOMATCH)) << ": error matching " << pattern; @@ -488,13 +494,32 @@ static void GetFiles(const string& pattern, vector* files) { files->push_back(string(g.gl_pathv[i])); } globfree(&g); +#elif defined(OS_WINDOWS) + WIN32_FIND_DATAA data; + HANDLE handle = FindFirstFileA(pattern.c_str(), &data); + size_t index = pattern.rfind('\\'); + if (index == string::npos) { + LOG(FATAL) << "No directory separator."; + } + const string dirname = pattern.substr(0, index + 1); + if (FAILED(handle)) { + // Finding no files is OK. + return; + } + do { + files->push_back(dirname + data.cFileName); + } while (FindNextFileA(handle, &data)); + LOG_SYSRESULT(FindClose(handle)); +#else +# error There is no way to do glob. +#endif } // Delete files patching pattern static void DeleteFiles(const string& pattern) { vector files; GetFiles(pattern, &files); - for (int i = 0; i < files.size(); i++) { + for (size_t i = 0; i < files.size(); i++) { CHECK(unlink(files[i].c_str()) == 0) << ": " << strerror(errno); } } @@ -519,18 +544,22 @@ static void CheckFile(const string& name, const string& expected_string) { static void TestBasename() { fprintf(stderr, "==== Test setting log file basename\n"); - string dest = FLAGS_test_tmpdir + "/logging_test_basename"; + const string dest = FLAGS_test_tmpdir + "/logging_test_basename"; DeleteFiles(dest + "*"); SetLogDestination(INFO, dest.c_str()); LOG(INFO) << "message to new base"; FlushLogFiles(INFO); + CheckFile(dest, "message to new base"); + // Release file handle for the destination file to unlock the file in Windows. + LogToStderr(); DeleteFiles(dest + "*"); } static void TestSymlink() { +#ifndef OS_WINDOWS fprintf(stderr, "==== Test setting log file symlink\n"); string dest = FLAGS_test_tmpdir + "/logging_test_symlink"; string sym = FLAGS_test_tmpdir + "/symlinkbase"; @@ -545,6 +574,7 @@ static void TestSymlink() { DeleteFiles(dest + "*"); DeleteFiles(sym + "*"); +#endif } static void TestExtension() { @@ -564,6 +594,8 @@ static void TestExtension() { CHECK_EQ(filenames.size(), 1); CHECK(strstr(filenames[0].c_str(), "specialextension") != NULL); + // Release file handle for the destination file to unlock the file in Windows. + LogToStderr(); DeleteFiles(dest + "*"); } @@ -633,9 +665,10 @@ static void TestOneTruncate(const char *path, int64 limit, int64 keep, CHECK_ERR(lseek(fd, 0, SEEK_SET)); // File should contain the suffix of the original file - char buf[statbuf.st_size + 1]; + int buf_size = statbuf.st_size + 1; + char* buf = new char[buf_size]; memset(buf, 0, sizeof(buf)); - CHECK_ERR(read(fd, buf, sizeof(buf))); + CHECK_ERR(read(fd, buf, buf_size)); const char *p = buf; int64 checked = 0; @@ -645,9 +678,11 @@ static void TestOneTruncate(const char *path, int64 limit, int64 keep, checked += bytes; } close(fd); + delete[] buf; } static void TestTruncate() { +#ifdef HAVE_UNISTD_H fprintf(stderr, "==== Test log truncation\n"); string path = FLAGS_test_tmpdir + "/truncatefile"; @@ -663,8 +698,10 @@ static void TestTruncate() { TestOneTruncate(path.c_str(), 10, 50, 0, 10, 10); TestOneTruncate(path.c_str(), 50, 100, 0, 30, 30); - // MacOSX 10.4 doesn't fail in this case. Let's just ignore this test. -#if !defined(OS_MACOSX) + // MacOSX 10.4 doesn't fail in this case. + // Windows doesn't have symlink. + // Let's just ignore this test for these cases. +#if !defined(OS_MACOSX) && !defined(OS_WINDOWS) // Through a symlink should fail to truncate string linkname = path + ".link"; unlink(linkname.c_str()); @@ -681,12 +718,17 @@ static void TestTruncate() { snprintf(fdpath, sizeof(fdpath), "/proc/self/fd/%d", fd); TestOneTruncate(fdpath, 10, 10, 10, 10, 10); #endif + +#endif } _START_GOOGLE_NAMESPACE_ +namespace glog_internal_namespace_ { extern // in logging.cc bool SafeFNMatch_(const char* pattern, size_t patt_len, const char* str, size_t str_len); +} // namespace glog_internal_namespace_ +using glog_internal_namespace_::SafeFNMatch_; _END_GOOGLE_NAMESPACE_ static bool WrapSafeFNMatch(string pattern, string str) { @@ -865,7 +907,7 @@ static void TestLogSinkWaitTillSent() { LOG(WARNING) << "Message 3"; SleepForMilliseconds(60); } - for (int i = 0; i < global_messages.size(); ++i) { + for (size_t i = 0; i < global_messages.size(); ++i) { LOG(INFO) << "Sink capture: " << global_messages[i]; } CHECK_EQ(global_messages.size(), 3); @@ -874,12 +916,13 @@ static void TestLogSinkWaitTillSent() { TEST(Strerror, logging) { int errcode = EINTR; char *msg = strdup(strerror(errcode)); - char buf[strlen(msg) + 1]; + int buf_size = strlen(msg) + 1; + char *buf = new char[buf_size]; CHECK_EQ(posix_strerror_r(errcode, NULL, 0), -1); buf[0] = 'A'; CHECK_EQ(posix_strerror_r(errcode, buf, 0), -1); CHECK_EQ(buf[0], 'A'); - CHECK_EQ(posix_strerror_r(errcode, NULL, sizeof(buf)), -1); + CHECK_EQ(posix_strerror_r(errcode, NULL, buf_size), -1); #if defined(OS_MACOSX) || defined(OS_FREEBSD) // MacOSX or FreeBSD considers this case is an error since there is // no enough space. @@ -888,9 +931,10 @@ TEST(Strerror, logging) { CHECK_EQ(posix_strerror_r(errcode, buf, 1), 0); #endif CHECK_STREQ(buf, ""); - CHECK_EQ(posix_strerror_r(errcode, buf, sizeof(buf)), 0); + CHECK_EQ(posix_strerror_r(errcode, buf, buf_size), 0); CHECK_STREQ(buf, msg); free(msg); + delete[] buf; } // Simple routines to look at the sizes of generated code for LOG(FATAL) and diff --git a/src/raw_logging.cc b/src/raw_logging.cc index f9e44df..70aa807 100644 --- a/src/raw_logging.cc +++ b/src/raw_logging.cc @@ -17,15 +17,9 @@ #elif defined(HAVE_SYS_SYSCALL_H) #include // for syscall() #endif -#include - -#if defined(OS_MACOSX) -#ifndef __DARWIN_UNIX03 -#define __DARWIN_UNIX03 // tells libgen.h to define basename() +#ifdef HAVE_UNISTD_H +# include #endif -#endif // OS_MACOSX - -#include // basename() _START_GOOGLE_NAMESPACE_ @@ -82,13 +76,13 @@ void RawLog__(LogSeverity severity, const char* file, int line, DoRawLog(&buf, &size, "%c%02d%02d %02d%02d%02d %s:%d] RAW: ", LogSeverityNames[severity][0], 1 + t.tm_mon, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec, - basename(const_cast(file)), line); + const_basename(const_cast(file)), line); } else { DoRawLog(&buf, &size, "%c%02d%02d %02d%02d%02d %08x %s:%d] RAW: ", LogSeverityNames[severity][0], 1 + t.tm_mon, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec, int(pthread_self()), - basename(const_cast(file)), line); + const_basename(const_cast(file)), line); } va_list ap; va_start(ap, format); diff --git a/src/utilities.cc b/src/utilities.cc index 1c4d52f..6f47085 100644 --- a/src/utilities.cc +++ b/src/utilities.cc @@ -4,7 +4,9 @@ #include "utilities.h" #include -#include +#ifdef HAVE_SYS_TIME_H +# include +#endif #include #include "base/googleinit.h" @@ -138,9 +140,17 @@ bool is_default_thread() { int64 CycleClock_Now() { // TODO(hamaji): temporary impementation - it might be too slow. +#ifdef OS_WINDOWS + SYSTEMTIME now; + GetSystemTime(&now); + return (static_cast(now.wSecond) * 1000000 + + static_cast(now.wMilliseconds) * 1000); +#else + // TODO(hamaji): temporary impementation - it might be too slow. struct timeval tv; gettimeofday(&tv, NULL); return static_cast(tv.tv_sec) * 1000000 + tv.tv_usec; +#endif } int64 UsecToCycles(int64 usec) { @@ -152,6 +162,15 @@ int32 GetMainThreadPid() { return g_main_thread_pid; } +const char* const_basename(const char* filepath) { + const char* base = strrchr(filepath, '/'); +#ifdef OS_WINDOWS // Look for either path separator in Windows + if (!base) + base = strrchr(filepath, '\\'); +#endif + return base ? (base+1) : filepath; +} + static string g_my_user_name; const string& MyUserName() { return g_my_user_name; diff --git a/src/utilities.h b/src/utilities.h index 1236fbe..0da2625 100644 --- a/src/utilities.h +++ b/src/utilities.h @@ -40,6 +40,10 @@ #include +#ifdef OS_WINDOWS +# include "port.h" +#endif + #include "config.h" #include "glog/logging.h" @@ -116,6 +120,10 @@ int32 GetMainThreadPid(); const std::string& MyUserName(); +// Get the part of filepath after the last path separator. +// (Doesn't modify filepath, contrary to basename() in libgen.h.) +const char* const_basename(const char* filepath); + // Wrapper of __sync_val_compare_and_swap. If the GCC extension isn't // defined, we try the CPU specific logics (we only support x86 and // x86_64 for now) first, then use a naive implementation, which has a diff --git a/src/vlog_is_on.cc b/src/vlog_is_on.cc index 877751d..833212a 100644 --- a/src/vlog_is_on.cc +++ b/src/vlog_is_on.cc @@ -8,7 +8,6 @@ #include #include #include -#include // fnmatch() is used in obsolete _InitVLOG #include #include #include "base/commandlineflags.h" @@ -32,12 +31,16 @@ DEFINE_string(vmodule, "", "per-module verbose level." _START_GOOGLE_NAMESPACE_ +namespace glog_internal_namespace_ { + // Implementation of fnmatch that does not need 0-termination // of arguments and does not allocate any memory, // but we only support "*" and "?" wildcards, not the "[...]" patterns. // It's not a static function for the unittest. -bool SafeFNMatch_(const char* pattern, size_t patt_len, - const char* str, size_t str_len) { +GOOGLE_GLOG_DLL_DECL bool SafeFNMatch_(const char* pattern, + size_t patt_len, + const char* str, + size_t str_len) { int p = 0; int s = 0; while (1) { @@ -63,6 +66,10 @@ bool SafeFNMatch_(const char* pattern, size_t patt_len, } } +} // namespace glog_internal_namespace_ + +using glog_internal_namespace_::SafeFNMatch_; + int32 kLogSiteUninitialized = 1000; // List of per-module log levels from FLAGS_vmodule. diff --git a/src/windows/config.h b/src/windows/config.h new file mode 100755 index 0000000..114762e --- /dev/null +++ b/src/windows/config.h @@ -0,0 +1,136 @@ +/* src/config.h.in. Generated from configure.ac by autoheader. */ + +/* Namespace for Google classes */ +#define GOOGLE_NAMESPACE google + +/* Define if you have the `dladdr' function */ +#undef HAVE_DLADDR + +/* Define to 1 if you have the header file. */ +#undef HAVE_DLFCN_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_EXECINFO_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_LIBUNWIND_H + +/* define if you have google gflags library */ +#undef HAVE_LIB_GFLAGS + +/* define if you have libunwind */ +#undef HAVE_LIB_UNWIND + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* define if the compiler implements namespaces */ +#undef HAVE_NAMESPACES + +/* Define if you have POSIX threads libraries and header files. */ +#undef HAVE_PTHREAD + +/* define if the compiler implements pthread_rwlock_* */ +#undef HAVE_RWLOCK + +/* Define if you have the `sigaltstack' function */ +#undef HAVE_SIGALTSTACK + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYSCALL_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SYSCALL_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UCONTEXT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* define if the compiler supports using expression for operator */ +#undef HAVE_USING_OPERATOR + +/* define if your compiler has __attribute__ */ +#undef HAVE___ATTRIBUTE__ + +/* define if your compiler has __builtin_expect */ +#undef HAVE___BUILTIN_EXPECT + +/* define if your compiler has __sync_val_compare_and_swap */ +#undef HAVE___SYNC_VAL_COMPARE_AND_SWAP + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* How to access the PC from a struct ucontext */ +#undef PC_FROM_UCONTEXT + +/* Define to necessary symbol if this constant uses a non-standard name on + your system. */ +#undef PTHREAD_CREATE_JOINABLE + +/* The size of `void *', as computed by sizeof. */ +#undef SIZEOF_VOID_P + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* the namespace where STL code like vector<> is defined */ +#undef STL_NAMESPACE + +/* Version number of package */ +#undef VERSION + +/* Stops putting the code inside the Google namespace */ +#define _END_GOOGLE_NAMESPACE_ } + +/* Puts following code inside the Google namespace */ +#define _START_GOOGLE_NAMESPACE_ namespace google { + +/* Always the empty-string on non-windows systems. On windows, should be + "__declspec(dllexport)". This way, when we compile the dll, we export our + functions/classes. It's safe to define this here because config.h is only + used internally, to compile the DLL, and every DLL source file #includes + "config.h" before anything else. */ +#ifndef GOOGLE_GLOG_DLL_DECL +# define GOOGLE_GLOG_IS_A_DLL 1 /* not set if you're statically linking */ +# define GOOGLE_GLOG_DLL_DECL __declspec(dllexport) +# define GOOGLE_GLOG_DLL_DECL_FOR_UNITTESTS __declspec(dllimport) +#endif diff --git a/src/windows/glog/log_severity.h b/src/windows/glog/log_severity.h new file mode 100644 index 0000000..d113015 --- /dev/null +++ b/src/windows/glog/log_severity.h @@ -0,0 +1,61 @@ +// This file is automatically generated from src/glog/log_severity.h +// using src/windows/preprocess.sh. +// DO NOT EDIT! + +// Copyright 2007 Google Inc. All Rights Reserved. + +#ifndef BASE_LOG_SEVERITY_H__ +#define BASE_LOG_SEVERITY_H__ + +// Annoying stuff for windows -- makes sure clients can import these functions +#ifndef GOOGLE_GLOG_DLL_DECL +# ifdef _WIN32 +# define GOOGLE_GLOG_DLL_DECL __declspec(dllimport) +# else +# define GOOGLE_GLOG_DLL_DECL +# endif +#endif + +// Variables of type LogSeverity are widely taken to lie in the range +// [0, NUM_SEVERITIES-1]. Be careful to preserve this assumption if +// you ever need to change their values or add a new severity. +typedef int LogSeverity; + +const int INFO = 0, WARNING = 1, ERROR = 2, FATAL = 3, NUM_SEVERITIES = 4; + +// DFATAL is FATAL in debug mode, ERROR in normal mode +#ifdef NDEBUG +#define DFATAL_LEVEL ERROR +#else +#define DFATAL_LEVEL FATAL +#endif + +extern GOOGLE_GLOG_DLL_DECL const char* const LogSeverityNames[NUM_SEVERITIES]; + +// NDEBUG usage helpers related to (RAW_)DCHECK: +// +// DEBUG_MODE is for small !NDEBUG uses like +// if (DEBUG_MODE) foo.CheckThatFoo(); +// instead of substantially more verbose +// #ifndef NDEBUG +// foo.CheckThatFoo(); +// #endif +// +// IF_DEBUG_MODE is for small !NDEBUG uses like +// IF_DEBUG_MODE( string error; ) +// DCHECK(Foo(&error)) << error; +// instead of substantially more verbose +// #ifndef NDEBUG +// string error; +// DCHECK(Foo(&error)) << error; +// #endif +// +#ifdef NDEBUG +enum { DEBUG_MODE = 0 }; +#define IF_DEBUG_MODE(x) +#else +enum { DEBUG_MODE = 1 }; +#define IF_DEBUG_MODE(x) x +#endif + +#endif // BASE_LOG_SEVERITY_H__ diff --git a/src/windows/glog/logging.h b/src/windows/glog/logging.h new file mode 100755 index 0000000..d6e8a3a --- /dev/null +++ b/src/windows/glog/logging.h @@ -0,0 +1,1342 @@ +// This file is automatically generated from src/glog/logging.h.in +// using src/windows/preprocess.sh. +// DO NOT EDIT! + +// +// Copyright (C) 1999 and onwards Google, Inc. +// +// Author: Ray Sidney +// +// This file contains #include information about logging-related stuff. +// Pretty much everybody needs to #include this file so that they can +// log various happenings. +// +#ifndef _LOGGING_H_ +#define _LOGGING_H_ + +#include +#include +#include +#include +#if 0 +# include +#endif +#ifdef __DEPRECATED +// Make GCC quiet. +# undef __DEPRECATED +# include +# define __DEPRECATED +#else +# include +#endif +#include + +// Annoying stuff for windows -- makes sure clients can import these functions +#ifndef GOOGLE_GLOG_DLL_DECL +# ifdef _WIN32 +# define GOOGLE_GLOG_DLL_DECL __declspec(dllimport) +# else +# define GOOGLE_GLOG_DLL_DECL +# endif +#endif + +// We care a lot about number of bits things take up. Unfortunately, +// systems define their bit-specific ints in a lot of different ways. +// We use our own way, and have a typedef to get there. +// Note: these commands below may look like "#if 1" or "#if 0", but +// that's because they were constructed that way at ./configure time. +// Look at logging.h.in to see how they're calculated (based on your config). +#if 0 +#include // the normal place uint16_t is defined +#endif +#if 0 +#include // the normal place u_int16_t is defined +#endif +#if 0 +#include // a third place for uint16_t or u_int16_t +#endif + +#if 0 +#include +#endif + +namespace google { + +#if 0 // the C99 format +typedef int32_t int32; +typedef uint32_t uint32; +typedef int64_t int64; +typedef uint64_t uint64; +#elif 0 // the BSD format +typedef int32_t int32; +typedef u_int32_t uint32; +typedef int64_t int64; +typedef u_int64_t uint64; +#elif 1 // the windows (vc7) format +typedef __int32 int32; +typedef unsigned __int32 uint32; +typedef __int64 int64; +typedef unsigned __int64 uint64; +#else +#error Do not know how to define a 32-bit integer quantity on your system +#endif + +} + +// The global value of GOOGLE_STRIP_LOG. All the messages logged to +// LOG(XXX) with severity less than GOOGLE_STRIP_LOG will not be displayed. +// If it can be determined at compile time that the message will not be +// printed, the statement will be compiled out. +// +// Example: to strip out all INFO and WARNING messages, use the value +// of 2 below. To make an exception for WARNING messages from a single +// file, add "#define GOOGLE_STRIP_LOG 1" to that file _before_ including +// base/logging.h +#ifndef GOOGLE_STRIP_LOG +#define GOOGLE_STRIP_LOG 0 +#endif + +// GCC can be told that a certain branch is not likely to be taken (for +// instance, a CHECK failure), and use that information in static analysis. +// Giving it this information can help it optimize for the common case in +// the absence of better information (ie. -fprofile-arcs). +// +#ifndef GOOGLE_PREDICT_BRANCH_NOT_TAKEN +#if 0 +#define GOOGLE_PREDICT_BRANCH_NOT_TAKEN(x) (__builtin_expect(x, 0)) +#else +#define GOOGLE_PREDICT_BRANCH_NOT_TAKEN(x) x +#endif +#endif + +// Make a bunch of macros for logging. The way to log things is to stream +// things to LOG(). E.g., +// +// LOG(INFO) << "Found " << num_cookies << " cookies"; +// +// You can capture log messages in a string, rather than reporting them +// immediately: +// +// vector errors; +// LOG_STRING(ERROR, &errors) << "Couldn't parse cookie #" << cookie_num; +// +// This pushes back the new error onto 'errors'; if given a NULL pointer, +// it reports the error via LOG(ERROR). +// +// You can also do conditional logging: +// +// LOG_IF(INFO, num_cookies > 10) << "Got lots of cookies"; +// +// You can also do occasional logging (log every n'th occurrence of an +// event): +// +// LOG_EVERY_N(INFO, 10) << "Got the " << COUNTER << "th cookie"; +// +// The above will cause log messages to be output on the 1st, 11th, 21st, ... +// times it is executed. Note that the special COUNTER value is used to +// identify which repetition is happening. +// +// You can also do occasional conditional logging (log every n'th +// occurrence of an event, when condition is satisfied): +// +// LOG_IF_EVERY_N(INFO, (size > 1024), 10) << "Got the " << COUNTER +// << "th big cookie"; +// +// You can log messages the first N times your code executes a line. E.g. +// +// LOG_FIRST_N(INFO, 20) << "Got the " << COUNTER << "th cookie"; +// +// Outputs log messages for the first 20 times it is executed. +// +// Analogous SYSLOG, SYSLOG_IF, and SYSLOG_EVERY_N macros are available. +// These log to syslog as well as to the normal logs. If you use these at +// all, you need to be aware that syslog can drastically reduce performance, +// especially if it is configured for remote logging! Don't use these +// unless you fully understand this and have a concrete need to use them. +// Even then, try to minimize your use of them. +// +// There are also "debug mode" logging macros like the ones above: +// +// DLOG(INFO) << "Found cookies"; +// +// DLOG_IF(INFO, num_cookies > 10) << "Got lots of cookies"; +// +// DLOG_EVERY_N(INFO, 10) << "Got the " << COUNTER << "th cookie"; +// +// All "debug mode" logging is compiled away to nothing for non-debug mode +// compiles. +// +// We also have +// +// LOG_ASSERT(assertion); +// DLOG_ASSERT(assertion); +// +// which is syntactic sugar for {,D}LOG_IF(FATAL, assert fails) << assertion; +// +// There are "verbose level" logging macros. They look like +// +// VLOG(1) << "I'm printed when you run the program with --v=1 or more"; +// VLOG(2) << "I'm printed when you run the program with --v=2 or more"; +// +// These always log at the INFO log level (when they log at all). +// The verbose logging can also be turned on module-by-module. For instance, +// --vmodule=mapreduce=2,file=1,gfs*=3 --v=0 +// will cause: +// a. VLOG(2) and lower messages to be printed from mapreduce.{h,cc} +// b. VLOG(1) and lower messages to be printed from file.{h,cc} +// c. VLOG(3) and lower messages to be printed from files prefixed with "gfs" +// d. VLOG(0) and lower messages to be printed from elsewhere +// +// The wildcarding functionality shown by (c) supports both '*' (match +// 0 or more characters) and '?' (match any single character) wildcards. +// +// There's also VLOG_IS_ON(n) "verbose level" condition macro. To be used as +// +// if (VLOG_IS_ON(2)) { +// // do some logging preparation and logging +// // that can't be accomplished with just VLOG(2) << ...; +// } +// +// There are also VLOG_IF, VLOG_EVERY_N and VLOG_IF_EVERY_N "verbose level" +// condition macros for sample cases, when some extra computation and +// preparation for logs is not needed. +// VLOG_IF(1, (size > 1024)) +// << "I'm printed when size is more than 1024 and when you run the " +// "program with --v=1 or more"; +// VLOG_EVERY_N(1, 10) +// << "I'm printed every 10th occurrence, and when you run the program " +// "with --v=1 or more. Present occurence is " << COUNTER; +// VLOG_IF_EVERY_N(1, (size > 1024), 10) +// << "I'm printed on every 10th occurence of case when size is more " +// " than 1024, when you run the program with --v=1 or more. "; +// "Present occurence is " << COUNTER; +// +// The supported severity levels for macros that allow you to specify one +// are (in increasing order of severity) INFO, WARNING, ERROR, and FATAL. +// Note that messages of a given severity are logged not only in the +// logfile for that severity, but also in all logfiles of lower severity. +// E.g., a message of severity FATAL will be logged to the logfiles of +// severity FATAL, ERROR, WARNING, and INFO. +// +// There is also the special severity of DFATAL, which logs FATAL in +// debug mode, ERROR in normal mode. +// +// Very important: logging a message at the FATAL severity level causes +// the program to terminate (after the message is logged). +// +// Unless otherwise specified, logs will be written to the filename +// "...log..", followed +// by the date, time, and pid (you can't prevent the date, time, and pid +// from being in the filename). +// +// The logging code takes two flags: +// --v=# set the verbose level +// --logtostderr log all the messages to stderr instead of to logfiles + +#ifndef DECLARE_VARIABLE +#define MUST_UNDEF_GFLAGS_DECLARE_MACROS +#define DECLARE_VARIABLE(type, name, tn) \ + namespace FLAG__namespace_do_not_use_directly_use_DECLARE_##tn##_instead { \ + extern GOOGLE_GLOG_DLL_DECL type FLAGS_##name; \ + } \ + using FLAG__namespace_do_not_use_directly_use_DECLARE_##tn##_instead::FLAGS_##name + +// bool specialization +#define DECLARE_bool(name) \ + DECLARE_VARIABLE(bool, name, bool) + +// int32 specialization +#define DECLARE_int32(name) \ + DECLARE_VARIABLE(google::int32, name, int32) + +// Special case for string, because we have to specify the namespace +// std::string, which doesn't play nicely with our FLAG__namespace hackery. +#define DECLARE_string(name) \ + namespace FLAG__namespace_do_not_use_directly_use_DECLARE_string_instead { \ + extern GOOGLE_GLOG_DLL_DECL std::string FLAGS_##name; \ + } \ + using FLAG__namespace_do_not_use_directly_use_DECLARE_string_instead::FLAGS_##name +#endif + +// Set whether log messages go to stderr instead of logfiles +DECLARE_bool(logtostderr); + +// Set how important a log message should be to avoid buffering +DECLARE_int32(logbuflevel); + +// Log suppression level: messages logged at a lower level than this +// are suppressed. +DECLARE_int32(minloglevel); + +// If specified, logfiles are written into this directory instead of the +// default logging directory. +DECLARE_string(log_dir); + +DECLARE_int32(v); // in vlog_is_on.cc + +DECLARE_int32(stderrthreshold); +DECLARE_bool(alsologtostderr); + +#ifdef MUST_UNDEF_GFLAGS_DECLARE_MACROS +#undef MUST_UNDEF_GFLAGS_DECLARE_MACROS +#undef DECLARE_VARIABLE +#undef DECLARE_bool +#undef DECLARE_int32 +#undef DECLARE_string +#endif + +// Log messages below the GOOGLE_STRIP_LOG level will be compiled away for +// security reasons. See LOG(severtiy) below. + +// A few definitions of macros that don't generate much code. Since +// LOG(INFO) and its ilk are used all over our code, it's +// better to have compact code for these operations. + +#if 0 >= GOOGLE_STRIP_LOG +#define COMPACT_GOOGLE_LOG_INFO google::LogMessage(__FILE__, __LINE__) +#else +#define COMPACT_GOOGLE_LOG_INFO google::NullStream() +#endif + +#if 1 >= GOOGLE_STRIP_LOG +#define COMPACT_GOOGLE_LOG_WARNING google::LogMessage(__FILE__, __LINE__, google::WARNING) +#else +#define COMPACT_GOOGLE_LOG_WARNING google::NullStream() +#endif + +#if 2 >= GOOGLE_STRIP_LOG +#define COMPACT_GOOGLE_LOG_ERROR google::LogMessage(__FILE__, __LINE__, google::ERROR) +#else +#define COMPACT_GOOGLE_LOG_ERROR google::NullStream() +#endif + +#if 3 >= GOOGLE_STRIP_LOG +#define COMPACT_GOOGLE_LOG_FATAL google::LogMessageFatal(__FILE__, __LINE__) +#else +#define COMPACT_GOOGLE_LOG_FATAL google::NullStreamFatal() +#endif + +// For DFATAL, we want to use LogMessage (as opposed to +// LogMessageFatal), to be consistent with the original behavior. +#ifdef NDEBUG +#define COMPACT_GOOGLE_LOG_DFATAL COMPACT_GOOGLE_LOG_ERROR +#elif 3 >= GOOGLE_STRIP_LOG +#define COMPACT_GOOGLE_LOG_DFATAL google::LogMessage(__FILE__, __LINE__, google::FATAL) +#else +#define COMPACT_GOOGLE_LOG_DFATAL google::NullStreamFatal() +#endif + +#define GOOGLE_LOG_INFO(counter) google::LogMessage(__FILE__, __LINE__, google::INFO, counter, &google::LogMessage::SendToLog) +#define SYSLOG_INFO(counter) \ + google::LogMessage(__FILE__, __LINE__, google::INFO, counter, \ + &google::LogMessage::SendToSyslogAndLog) +#define GOOGLE_LOG_WARNING(counter) \ + google::LogMessage(__FILE__, __LINE__, google::WARNING, counter, \ + &google::LogMessage::SendToLog) +#define SYSLOG_WARNING(counter) \ + google::LogMessage(__FILE__, __LINE__, google::WARNING, counter, \ + &google::LogMessage::SendToSyslogAndLog) +#define GOOGLE_LOG_ERROR(counter) \ + google::LogMessage(__FILE__, __LINE__, google::ERROR, counter, \ + &google::LogMessage::SendToLog) +#define SYSLOG_ERROR(counter) \ + google::LogMessage(__FILE__, __LINE__, google::ERROR, counter, \ + &google::LogMessage::SendToSyslogAndLog) +#define GOOGLE_LOG_FATAL(counter) \ + google::LogMessage(__FILE__, __LINE__, google::FATAL, counter, \ + &google::LogMessage::SendToLog) +#define SYSLOG_FATAL(counter) \ + google::LogMessage(__FILE__, __LINE__, google::FATAL, counter, \ + &google::LogMessage::SendToSyslogAndLog) +#define GOOGLE_LOG_DFATAL(counter) \ + google::LogMessage(__FILE__, __LINE__, google::DFATAL_LEVEL, counter, \ + &google::LogMessage::SendToLog) +#define SYSLOG_DFATAL(counter) \ + google::LogMessage(__FILE__, __LINE__, google::DFATAL_LEVEL, counter, \ + &google::LogMessage::SendToSyslogAndLog) + +#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) || defined(__CYGWIN32__) +// A very useful logging macro to log windows errors: +#define LOG_SYSRESULT(result) \ + if (FAILED(result)) { \ + LPTSTR message = NULL; \ + LPTSTR msg = reinterpret_cast(&message); \ + DWORD message_length = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | \ + FORMAT_MESSAGE_FROM_SYSTEM, \ + 0, result, 0, msg, 100, NULL); \ + if (message_length > 0) { \ + google::LogMessage(__FILE__, __LINE__, ERROR, 0, \ + &google::LogMessage::SendToLog).stream() << message; \ + LocalFree(message); \ + } \ + } +#endif + +// We use the preprocessor's merging operator, "##", so that, e.g., +// LOG(INFO) becomes the token GOOGLE_LOG_INFO. There's some funny +// subtle difference between ostream member streaming functions (e.g., +// ostream::operator<<(int) and ostream non-member streaming functions +// (e.g., ::operator<<(ostream&, string&): it turns out that it's +// impossible to stream something like a string directly to an unnamed +// ostream. We employ a neat hack by calling the stream() member +// function of LogMessage which seems to avoid the problem. +#define LOG(severity) COMPACT_GOOGLE_LOG_ ## severity.stream() +#define SYSLOG(severity) SYSLOG_ ## severity(0).stream() + +namespace google { + +// They need the definitions of integer types. +#include "glog/log_severity.h" +#include "glog/vlog_is_on.h" + +// Initialize google's logging library. You will see the program name +// specified by argv0 in log outputs. +GOOGLE_GLOG_DLL_DECL void InitGoogleLogging(const char* argv0); + +// Install a function which will be called after LOG(FATAL). +GOOGLE_GLOG_DLL_DECL void InstallFailureFunction(void (*fail_func)()); + +class LogSink; // defined below + +// If a non-NULL sink pointer is given, we push this message to that sink. +// We then do normal LOG(severity) logging as well. +// This is useful for capturing messages and passing/storing them +// somewhere more specific than the global log of the process. +// Argument types: +// LogSink* sink; +// LogSeverity severity; +// The cast is to disambiguate NULL arguments. +#define LOG_TO_SINK(sink, severity) \ + google::LogMessage(__FILE__, __LINE__, google::severity, \ + static_cast(sink)).stream() + +// If a non-NULL pointer is given, we push the message onto the end +// of a vector of strings; otherwise, we report it with LOG(severity). +// This is handy for capturing messages and perhaps passing them back +// to the caller, rather than reporting them immediately. +// Argument types: +// LogSeverity severity; +// vector *outvec; +// The cast is to disambiguate NULL arguments. +#define LOG_STRING(severity, outvec) \ + google::LogMessage(__FILE__, __LINE__, google::severity, \ + static_cast*>(outvec)).stream() + +#define LOG_IF(severity, condition) \ + !(condition) ? (void) 0 : google::LogMessageVoidify() & LOG(severity) +#define SYSLOG_IF(severity, condition) \ + !(condition) ? (void) 0 : google::LogMessageVoidify() & SYSLOG(severity) + +#define LOG_ASSERT(condition) \ + LOG_IF(FATAL, !(condition)) << "Assert failed: " #condition +#define SYSLOG_ASSERT(condition) \ + SYSLOG_IF(FATAL, !(condition)) << "Assert failed: " #condition + +// CHECK dies with a fatal error if condition is not true. It is *not* +// controlled by NDEBUG, so the check will be executed regardless of +// compilation mode. Therefore, it is safe to do things like: +// CHECK(fp->Write(x) == 4) +#define CHECK(condition) \ + LOG_IF(FATAL, GOOGLE_PREDICT_BRANCH_NOT_TAKEN(!(condition))) \ + << "Check failed: " #condition " " + +// A container for a string pointer which can be evaluated to a bool - +// true iff the pointer is NULL. +struct CheckOpString { + CheckOpString(std::string* str) : str_(str) { } + // No destructor: if str_ is non-NULL, we're about to LOG(FATAL), + // so there's no point in cleaning up str_. + operator bool() const { + return GOOGLE_PREDICT_BRANCH_NOT_TAKEN(str_ != NULL); + } + std::string* str_; +}; + +// Function is overloaded for integral types to allow static const +// integrals declared in classes and not defined to be used as arguments to +// CHECK* macros. It's not encouraged though. +template +inline const T& GetReferenceableValue(const T& t) { return t; } +inline char GetReferenceableValue(char t) { return t; } +inline unsigned char GetReferenceableValue(unsigned char t) { return t; } +inline signed char GetReferenceableValue(signed char t) { return t; } +inline short GetReferenceableValue(short t) { return t; } +inline unsigned short GetReferenceableValue(unsigned short t) { return t; } +inline int GetReferenceableValue(int t) { return t; } +inline unsigned int GetReferenceableValue(unsigned int t) { return t; } +inline long GetReferenceableValue(long t) { return t; } +inline unsigned long GetReferenceableValue(unsigned long t) { return t; } +inline long long GetReferenceableValue(long long t) { return t; } +inline unsigned long long GetReferenceableValue(unsigned long long t) { + return t; +} + +// This is a dummy class to define the following operator. +struct DummyClassToDefineOperator {}; + +} + +// Define global operator<< to declare using ::operator<<. +// This declaration will allow use to use CHECK macros for user +// defined classes which have operator<< (e.g., stl_logging.h). +inline std::ostream& operator<<( + std::ostream& out, const google::DummyClassToDefineOperator& dummy) { + return out; +} + +namespace google { + +// Build the error message string. +template +std::string* MakeCheckOpString(const t1& v1, const t2& v2, const char* names) { + // It means that we cannot use stl_logging if compiler doesn't + // support using expression for operator. + // TODO(hamaji): Figure out a way to fix. +#if 1 + using ::operator<<; +#endif + std::strstream ss; + ss << names << " (" << v1 << " vs. " << v2 << ")"; + return new std::string(ss.str(), ss.pcount()); +} + +// Helper functions for CHECK_OP macro. +// The (int, int) specialization works around the issue that the compiler +// will not instantiate the template version of the function on values of +// unnamed enum type - see comment below. +#define DEFINE_CHECK_OP_IMPL(name, op) \ + template \ + inline std::string* Check##name##Impl(const t1& v1, const t2& v2, \ + const char* names) { \ + if (v1 op v2) return NULL; \ + else return MakeCheckOpString(v1, v2, names); \ + } \ + inline std::string* Check##name##Impl(int v1, int v2, const char* names) { \ + return Check##name##Impl(v1, v2, names); \ + } + +// Use _EQ, _NE, _LE, etc. in case the file including base/logging.h +// provides its own #defines for the simpler names EQ, NE, LE, etc. +// This happens if, for example, those are used as token names in a +// yacc grammar. +DEFINE_CHECK_OP_IMPL(_EQ, ==) +DEFINE_CHECK_OP_IMPL(_NE, !=) +DEFINE_CHECK_OP_IMPL(_LE, <=) +DEFINE_CHECK_OP_IMPL(_LT, < ) +DEFINE_CHECK_OP_IMPL(_GE, >=) +DEFINE_CHECK_OP_IMPL(_GT, > ) +#undef DEFINE_CHECK_OP_IMPL + +// Helper macro for binary operators. +// Don't use this macro directly in your code, use CHECK_EQ et al below. + +#if defined(STATIC_ANALYSIS) +// Only for static analysis tool to know that it is equivalent to assert +#define CHECK_OP_LOG(name, op, val1, val2, log) CHECK((val1) op (val2)) +#elif !defined(NDEBUG) +// In debug mode, avoid constructing CheckOpStrings if possible, +// to reduce the overhead of CHECK statments by 2x. +// Real DCHECK-heavy tests have seen 1.5x speedups. + +// The meaning of "string" might be different between now and +// when this macro gets invoked (e.g., if someone is experimenting +// with other string implementations that get defined after this +// file is included). Save the current meaning now and use it +// in the macro. +typedef std::string _Check_string; +#define CHECK_OP_LOG(name, op, val1, val2, log) \ + while (google::_Check_string* _result = \ + google::Check##name##Impl((val1), (val2), #val1 " " #op " " #val2)) \ + log(__FILE__, __LINE__, google::CheckOpString(_result)).stream() +#else +// In optimized mode, use CheckOpString to hint to compiler that +// the while condition is unlikely. +#define CHECK_OP_LOG(name, op, val1, val2, log) \ + while (google::CheckOpString _result = \ + google::Check##name##Impl(GetReferenceableValue(val1), \ + GetReferenceableValue(val2), \ + #val1 " " #op " " #val2)) \ + log(__FILE__, __LINE__, _result).stream() +#endif // STATIC_ANALYSIS, !NDEBUG + +#define CHECK_OP(name, op, val1, val2) \ + CHECK_OP_LOG(name, op, val1, val2, google::LogMessageFatal) + +// Equality/Inequality checks - compare two values, and log a FATAL message +// including the two values when the result is not as expected. The values +// must have operator<<(ostream, ...) defined. +// +// You may append to the error message like so: +// CHECK_NE(1, 2) << ": The world must be ending!"; +// +// We are very careful to ensure that each argument is evaluated exactly +// once, and that anything which is legal to pass as a function argument is +// legal here. In particular, the arguments may be temporary expressions +// which will end up being destroyed at the end of the apparent statement, +// for example: +// CHECK_EQ(string("abc")[1], 'b'); +// +// WARNING: These don't compile correctly if one of the arguments is a pointer +// and the other is NULL. To work around this, simply static_cast NULL to the +// type of the desired pointer. + +#define CHECK_EQ(val1, val2) CHECK_OP(_EQ, ==, val1, val2) +#define CHECK_NE(val1, val2) CHECK_OP(_NE, !=, val1, val2) +#define CHECK_LE(val1, val2) CHECK_OP(_LE, <=, val1, val2) +#define CHECK_LT(val1, val2) CHECK_OP(_LT, < , val1, val2) +#define CHECK_GE(val1, val2) CHECK_OP(_GE, >=, val1, val2) +#define CHECK_GT(val1, val2) CHECK_OP(_GT, > , val1, val2) + +// Check that the input is non NULL. This very useful in constructor +// initializer lists. + +#define CHECK_NOTNULL(val) \ + google::CheckNotNull(__FILE__, __LINE__, "'" #val "' Must be non NULL", (val)) + +// Helper functions for string comparisons. +// To avoid bloat, the definitions are in logging.cc. +#define DECLARE_CHECK_STROP_IMPL(func, expected) \ + GOOGLE_GLOG_DLL_DECL std::string* Check##func##expected##Impl( \ + const char* s1, const char* s2, const char* names); +DECLARE_CHECK_STROP_IMPL(strcmp, true) +DECLARE_CHECK_STROP_IMPL(strcmp, false) +DECLARE_CHECK_STROP_IMPL(strcasecmp, true) +DECLARE_CHECK_STROP_IMPL(strcasecmp, false) +#undef DECLARE_CHECK_STROP_IMPL + +// Helper macro for string comparisons. +// Don't use this macro directly in your code, use CHECK_STREQ et al below. +#define CHECK_STROP(func, op, expected, s1, s2) \ + while (google::CheckOpString _result = \ + google::Check##func##expected##Impl((s1), (s2), \ + #s1 " " #op " " #s2)) \ + LOG(FATAL) << *_result.str_ + + +// String (char*) equality/inequality checks. +// CASE versions are case-insensitive. +// +// Note that "s1" and "s2" may be temporary strings which are destroyed +// by the compiler at the end of the current "full expression" +// (e.g. CHECK_STREQ(Foo().c_str(), Bar().c_str())). + +#define CHECK_STREQ(s1, s2) CHECK_STROP(strcmp, ==, true, s1, s2) +#define CHECK_STRNE(s1, s2) CHECK_STROP(strcmp, !=, false, s1, s2) +#define CHECK_STRCASEEQ(s1, s2) CHECK_STROP(strcasecmp, ==, true, s1, s2) +#define CHECK_STRCASENE(s1, s2) CHECK_STROP(strcasecmp, !=, false, s1, s2) + +#define CHECK_INDEX(I,A) CHECK(I < (sizeof(A)/sizeof(A[0]))) +#define CHECK_BOUND(B,A) CHECK(B <= (sizeof(A)/sizeof(A[0]))) + +#define CHECK_DOUBLE_EQ(val1, val2) \ + do { \ + CHECK_LE((val1), (val2)+0.000000000000001L); \ + CHECK_GE((val1), (val2)-0.000000000000001L); \ + } while (0) + +#define CHECK_NEAR(val1, val2, margin) \ + do { \ + CHECK_LE((val1), (val2)+(margin)); \ + CHECK_GE((val1), (val2)-(margin)); \ + } while (0) + +// perror()..googly style! +// +// PLOG() and PLOG_IF() and PCHECK() behave exactly like their LOG* and +// CHECK equivalents with the addition that they postpend a description +// of the current state of errno to their output lines. + +#define PLOG(severity) GOOGLE_PLOG(severity, 0).stream() + +#define GOOGLE_PLOG(severity, counter) \ + google::ErrnoLogMessage( \ + __FILE__, __LINE__, google::severity, counter, \ + &google::LogMessage::SendToLog) + +#define PLOG_IF(severity, condition) \ + !(condition) ? (void) 0 : google::LogMessageVoidify() & PLOG(severity) + +// A CHECK() macro that postpends errno if the condition is false. E.g. +// +// if (poll(fds, nfds, timeout) == -1) { PCHECK(errno == EINTR); ... } +#define PCHECK(condition) \ + PLOG_IF(FATAL, GOOGLE_PREDICT_BRANCH_NOT_TAKEN(!(condition))) \ + << "Check failed: " #condition " " + +// A CHECK() macro that lets you assert the success of a function that +// returns -1 and sets errno in case of an error. E.g. +// +// CHECK_ERR(mkdir(path, 0700)); +// +// or +// +// int fd = open(filename, flags); CHECK_ERR(fd) << ": open " << filename; +#define CHECK_ERR(invocation) \ +PLOG_IF(FATAL, GOOGLE_PREDICT_BRANCH_NOT_TAKEN((invocation) == -1)) \ + << #invocation + +// Use macro expansion to create, for each use of LOG_EVERY_N(), static +// variables with the __LINE__ expansion as part of the variable name. +#define LOG_EVERY_N_VARNAME(base, line) LOG_EVERY_N_VARNAME_CONCAT(base, line) +#define LOG_EVERY_N_VARNAME_CONCAT(base, line) base ## line + +#define LOG_OCCURRENCES LOG_EVERY_N_VARNAME(occurrences_, __LINE__) +#define LOG_OCCURRENCES_MOD_N LOG_EVERY_N_VARNAME(occurrences_mod_n_, __LINE__) + +#define SOME_KIND_OF_LOG_EVERY_N(severity, n, what_to_do) \ + static int LOG_OCCURRENCES = 0, LOG_OCCURRENCES_MOD_N = 0; \ + ++LOG_OCCURRENCES; \ + if (++LOG_OCCURRENCES_MOD_N > n) LOG_OCCURRENCES_MOD_N -= n; \ + if (LOG_OCCURRENCES_MOD_N == 1) \ + google::LogMessage( \ + __FILE__, __LINE__, google::severity, LOG_OCCURRENCES, \ + &what_to_do).stream() + +#define SOME_KIND_OF_LOG_IF_EVERY_N(severity, condition, n, what_to_do) \ + static int LOG_OCCURRENCES = 0, LOG_OCCURRENCES_MOD_N = 0; \ + ++LOG_OCCURRENCES; \ + if (condition && \ + ((LOG_OCCURRENCES_MOD_N=(LOG_OCCURRENCES_MOD_N + 1) % n) == (1 % n))) \ + google::LogMessage( \ + __FILE__, __LINE__, google::severity, LOG_OCCURRENCES, \ + &what_to_do).stream() + +#define SOME_KIND_OF_PLOG_EVERY_N(severity, n, what_to_do) \ + static int LOG_OCCURRENCES = 0, LOG_OCCURRENCES_MOD_N = 0; \ + ++LOG_OCCURRENCES; \ + if (++LOG_OCCURRENCES_MOD_N > n) LOG_OCCURRENCES_MOD_N -= n; \ + if (LOG_OCCURRENCES_MOD_N == 1) \ + google::ErrnoLogMessage( \ + __FILE__, __LINE__, google::severity, LOG_OCCURRENCES, \ + &what_to_do).stream() + +#define SOME_KIND_OF_LOG_FIRST_N(severity, n, what_to_do) \ + static int LOG_OCCURRENCES = 0; \ + if (LOG_OCCURRENCES <= n) \ + ++LOG_OCCURRENCES; \ + if (LOG_OCCURRENCES <= n) \ + google::LogMessage( \ + __FILE__, __LINE__, google::severity, LOG_OCCURRENCES, \ + &what_to_do).stream() + +#define LOG_EVERY_N(severity, n) \ + SOME_KIND_OF_LOG_EVERY_N(severity, (n), google::LogMessage::SendToLog) + +#define SYSLOG_EVERY_N(severity, n) \ + SOME_KIND_OF_LOG_EVERY_N(severity, (n), google::LogMessage::SendToSyslogAndLog) + +#define PLOG_EVERY_N(severity, n) \ + SOME_KIND_OF_PLOG_EVERY_N(severity, (n), google::LogMessage::SendToLog) + +#define LOG_FIRST_N(severity, n) \ + SOME_KIND_OF_LOG_FIRST_N(severity, (n), google::LogMessage::SendToLog) + +#define LOG_IF_EVERY_N(severity, condition, n) \ + SOME_KIND_OF_LOG_IF_EVERY_N(severity, (condition), (n), google::LogMessage::SendToLog) + +// We want the special COUNTER value available for LOG_EVERY_X()'ed messages +enum PRIVATE_Counter {COUNTER}; + + +// Plus some debug-logging macros that get compiled to nothing for production + +#ifndef NDEBUG + +#define DLOG(severity) LOG(severity) +#define DLOG_IF(severity, condition) LOG_IF(severity, condition) +#define DLOG_EVERY_N(severity, n) LOG_EVERY_N(severity, n) +#define DLOG_IF_EVERY_N(severity, condition, n) \ + LOG_IF_EVERY_N(severity, condition, n) +#define DLOG_ASSERT(condition) LOG_ASSERT(condition) + +// debug-only checking. not executed in NDEBUG mode. +#define DCHECK(condition) CHECK(condition) +#define DCHECK_EQ(val1, val2) CHECK_EQ(val1, val2) +#define DCHECK_NE(val1, val2) CHECK_NE(val1, val2) +#define DCHECK_LE(val1, val2) CHECK_LE(val1, val2) +#define DCHECK_LT(val1, val2) CHECK_LT(val1, val2) +#define DCHECK_GE(val1, val2) CHECK_GE(val1, val2) +#define DCHECK_GT(val1, val2) CHECK_GT(val1, val2) +#define DCHECK_STREQ(str1, str2) CHECK_STREQ(str1, str2) +#define DCHECK_STRCASEEQ(str1, str2) CHECK_STRCASEEQ(str1, str2) +#define DCHECK_STRNE(str1, str2) CHECK_STRNE(str1, str2) +#define DCHECK_STRCASENE(str1, str2) CHECK_STRCASENE(str1, str2) + +#else // NDEBUG + +#define DLOG(severity) \ + true ? (void) 0 : google::LogMessageVoidify() & LOG(severity) + +#define DLOG_IF(severity, condition) \ + (true || !(condition)) ? (void) 0 : google::LogMessageVoidify() & LOG(severity) + +#define DLOG_EVERY_N(severity, n) \ + true ? (void) 0 : google::LogMessageVoidify() & LOG(severity) + +#define DLOG_IF_EVERY_N(severity, condition, n) \ + (true || !(condition))? (void) 0 : google::LogMessageVoidify() & LOG(severity) + +#define DLOG_ASSERT(condition) \ + true ? (void) 0 : LOG_ASSERT(condition) + +#define DCHECK(condition) \ + while (false) \ + CHECK(condition) + +#define DCHECK_EQ(val1, val2) \ + while (false) \ + CHECK_EQ(val1, val2) + +#define DCHECK_NE(val1, val2) \ + while (false) \ + CHECK_NE(val1, val2) + +#define DCHECK_LE(val1, val2) \ + while (false) \ + CHECK_LE(val1, val2) + +#define DCHECK_LT(val1, val2) \ + while (false) \ + CHECK_LT(val1, val2) + +#define DCHECK_GE(val1, val2) \ + while (false) \ + CHECK_GE(val1, val2) + +#define DCHECK_GT(val1, val2) \ + while (false) \ + CHECK_GT(val1, val2) + +#define DCHECK_STREQ(str1, str2) \ + while (false) \ + CHECK_STREQ(str1, str2) + +#define DCHECK_STRCASEEQ(str1, str2) \ + while (false) \ + CHECK_STRCASEEQ(str1, str2) + +#define DCHECK_STRNE(str1, str2) \ + while (false) \ + CHECK_STRNE(str1, str2) + +#define DCHECK_STRCASENE(str1, str2) \ + while (false) \ + CHECK_STRCASENE(str1, str2) + + +#endif // NDEBUG + +// Log only in verbose mode. + +#define VLOG(verboselevel) LOG_IF(INFO, VLOG_IS_ON(verboselevel)) + +#define VLOG_IF(verboselevel, condition) \ + LOG_IF(INFO, (condition) && VLOG_IS_ON(verboselevel)) + +#define VLOG_EVERY_N(verboselevel, n) \ + LOG_IF_EVERY_N(INFO, VLOG_IS_ON(verboselevel), n) + +#define VLOG_IF_EVERY_N(verboselevel, condition, n) \ + LOG_IF_EVERY_N(INFO, (condition) && VLOG_IS_ON(verboselevel), n) + +// +// This class more or less represents a particular log message. You +// create an instance of LogMessage and then stream stuff to it. +// When you finish streaming to it, ~LogMessage is called and the +// full message gets streamed to the appropriate destination. +// +// You shouldn't actually use LogMessage's constructor to log things, +// though. You should use the LOG() macro (and variants thereof) +// above. +class GOOGLE_GLOG_DLL_DECL LogMessage { +public: + enum { + // Passing kNoLogPrefix for the line number disables the + // log-message prefix. Useful for using the LogMessage + // infrastructure as a printing utility. See also the --log_prefix + // flag for controlling the log-message prefix on an + // application-wide basis. + kNoLogPrefix = -1 + }; + + // LogStream inherit from non-DLL-exported class (std::ostrstream) + // and VC++ produces a warning for this situation. + // However, MSDN says "C4275 can be ignored in Microsoft Visual C++ + // 2005 if you are deriving from a type in the Standard C++ Library" + // http://msdn.microsoft.com/en-us/library/3tdb471s(VS.80).aspx + // Let's just ignore the warning. +#ifdef _MSC_VER +# pragma warning(disable: 4275) +#endif + class GOOGLE_GLOG_DLL_DECL LogStream : public std::ostrstream { +#ifdef _MSC_VER +# pragma warning(default: 4275) +#endif + public: + LogStream(char *buf, int len, int ctr) + : ostrstream(buf, len), + ctr_(ctr) { + self_ = this; + } + + int ctr() const { return ctr_; } + void set_ctr(int ctr) { ctr_ = ctr; } + LogStream* self() const { return self_; } + + private: + int ctr_; // Counter hack (for the LOG_EVERY_X() macro) + LogStream *self_; // Consistency check hack + }; + +public: + // icc 8 requires this typedef to avoid an internal compiler error. + typedef void (LogMessage::*SendMethod)(); + + LogMessage(const char* file, int line, LogSeverity severity, int ctr, + SendMethod send_method); + + // Two special constructors that generate reduced amounts of code at + // LOG call sites for common cases. + + // Used for LOG(INFO): Implied are: + // severity = INFO, ctr = 0, send_method = &LogMessage::SendToLog. + // + // Using this constructor instead of the more complex constructor above + // saves 19 bytes per call site. + LogMessage(const char* file, int line); + + // Used for LOG(severity) where severity != INFO. Implied + // are: ctr = 0, send_method = &LogMessage::SendToLog + // + // Using this constructor instead of the more complex constructor above + // saves 17 bytes per call site. + LogMessage(const char* file, int line, LogSeverity severity); + + // Constructor to also log this message to a specified sink (if not NULL). + // Implied are: ctr = 0, send_method = &LogMessage::SendToSinkAndLog. + LogMessage(const char* file, int line, LogSeverity severity, LogSink* sink); + + // Constructor where we also give a vector pointer + // for storing the messages (if the pointer is not NULL). + // Implied are: ctr = 0, send_method = &LogMessage::SaveOrSendToLog. + LogMessage(const char* file, int line, LogSeverity severity, + std::vector* outvec); + + // A special constructor used for check failures + LogMessage(const char* file, int line, const CheckOpString& result); + + ~LogMessage(); + + // Flush a buffered message to the sink set in the constructor. Always + // called by the destructor, it may also be called from elsewhere if + // needed. Only the first call is actioned; any later ones are ignored. + void Flush(); + + // An arbitrary limit on the length of a single log message. This + // is so that streaming can be done more efficiently. + static const size_t kMaxLogMessageLen; + + // Theses should not be called directly outside of logging.*, + // only passed as SendMethod arguments to other LogMessage methods: + void SendToLog(); // Actually dispatch to the logs + void SendToSyslogAndLog(); // Actually dispatch to syslog and the logs + + // Call abort() or similar to perform LOG(FATAL) crash. + static void Fail() ; + + std::ostream& stream() { return data_->stream_; } + + int preserved_errno() const { return data_->preserved_errno_; } + + // Must be called without the log_mutex held. (L < log_mutex) + static int64 num_messages(int severity); + +private: + + // Fully internal SendMethod cases: + void SendToSinkAndLog(); // Send to sink if provided and dispatch to the logs + void SaveOrSendToLog(); // Save to stringvec if provided, else to logs + + struct LogMessageData; + + void Init(const char* file, int line, LogSeverity severity, + void (LogMessage::*send_method)()); + + LogMessageData* GetMessageData(int preserved_errno, LogSeverity, int ctr); + + // Counts of messages sent at each priority: + static int64 num_messages_[NUM_SEVERITIES]; // under log_mutex + + // We keep the data in a separate struct so that each instance of + // LogMessage uses less stack space. + struct GOOGLE_GLOG_DLL_DECL LogMessageData { + // ORDER DEPENDENCY: preserved_errno_ comes before buf_ comes before + // message_text_ comes before stream_ + int preserved_errno_; // preserved errno + char* buf_; + char* message_text_; // Complete message text (points to selected buffer) + LogStream stream_; + const char severity_; // What level is this LogMessage logged at? + int line_; // line number where logging call is. + void (LogMessage::*send_method_)(); // Call this in destructor to send + union { // At most one of these is used: union to keep the size low. + LogSink* sink_; // NULL or sink to send message to + std::vector* outvec_; // NULL or vector to push message onto + }; + time_t timestamp_; // Time of creation of LogMessage + struct ::tm tm_time_; // Time of creation of LogMessage + size_t num_prefix_chars_; // How many chars of "prefix" for this message? + size_t num_chars_to_log_; // How many chars of msg to send to log? + size_t num_chars_to_syslog_; // How many chars of msg to send to syslog? + + const char* basename_; // basename of the file which called LOG. + const char* fullname_; // full name (including directory) + // of the file which called LOG. + + bool has_been_flushed_; // False if data has not yet been flushed. + + LogMessageData(int preserved_errno, LogSeverity severity, int ctr); + ~LogMessageData(); + + private: + LogMessageData(const LogMessageData&); + void operator=(const LogMessageData&); + }; + + static LogMessageData fatal_message_data_; + + LogMessageData* allocated_; + LogMessageData* data_; + + friend class LogDestination; + + LogMessage(const LogMessage&); + void operator=(const LogMessage&); +}; + +// This class happens to be thread-hostile because all instances share +// a single data buffer, but since it can only be created just before +// the process dies, we don't worry so much. +class GOOGLE_GLOG_DLL_DECL LogMessageFatal : public LogMessage { + public: + LogMessageFatal(const char* file, int line); + LogMessageFatal(const char* file, int line, const CheckOpString& result); + ~LogMessageFatal() ; +}; + +// A non-macro interface to the log facility; (useful +// when the logging level is not a compile-time constant). +inline void LogAtLevel(int const log_level, std::string const &msg) { + LogMessage(__FILE__, __LINE__, log_level).stream() << msg; +} + +// A small helper for CHECK_NOTNULL(). +template +T* CheckNotNull(const char *file, int line, const char *names, T* t) { + if (t == NULL) { + LogMessageFatal(file, line, new std::string(names)); + } + return t; +} + +// Allow folks to put a counter in the LOG_EVERY_X()'ed messages. This +// only works if ostream is a LogStream. If the ostream is not a +// LogStream you'll get an assert saying as much at runtime. +GOOGLE_GLOG_DLL_DECL std::ostream& operator<<(std::ostream &os, + const PRIVATE_Counter&); + + +// Derived class for PLOG*() above. +class GOOGLE_GLOG_DLL_DECL ErrnoLogMessage : public LogMessage { + public: + + ErrnoLogMessage(const char* file, int line, LogSeverity severity, int ctr, + void (LogMessage::*send_method)()); + + // Postpends ": strerror(errno) [errno]". + ~ErrnoLogMessage(); + + private: + ErrnoLogMessage(const ErrnoLogMessage&); + void operator=(const ErrnoLogMessage&); +}; + + +// This class is used to explicitly ignore values in the conditional +// logging macros. This avoids compiler warnings like "value computed +// is not used" and "statement has no effect". + +class GOOGLE_GLOG_DLL_DECL LogMessageVoidify { + public: + LogMessageVoidify() { } + // This has to be an operator with a precedence lower than << but + // higher than ?: + void operator&(std::ostream&) { } +}; + + +// Flushes all log files that contains messages that are at least of +// the specified severity level. Thread-safe. +GOOGLE_GLOG_DLL_DECL void FlushLogFiles(LogSeverity min_severity); + +// Flushes all log files that contains messages that are at least of +// the specified severity level. Thread-hostile because it ignores +// locking -- used for catastrophic failures. +GOOGLE_GLOG_DLL_DECL void FlushLogFilesUnsafe(LogSeverity min_severity); + +// +// Set the destination to which a particular severity level of log +// messages is sent. If base_filename is "", it means "don't log this +// severity". Thread-safe. +// +GOOGLE_GLOG_DLL_DECL void SetLogDestination(LogSeverity severity, + const char* base_filename); + +// +// Set the basename of the symlink to the latest log file at a given +// severity. If symlink_basename is empty, do not make a symlink. If +// you don't call this function, the symlink basename is the +// invocation name of the program. Thread-safe. +// +GOOGLE_GLOG_DLL_DECL void SetLogSymlink(LogSeverity severity, + const char* symlink_basename); + +// +// Used to send logs to some other kind of destination +// Users should subclass LogSink and override send to do whatever they want. +// Implementations must be thread-safe because a shared instance will +// be called from whichever thread ran the LOG(XXX) line. +class GOOGLE_GLOG_DLL_DECL LogSink { + public: + virtual ~LogSink(); + + // Sink's logging logic (message_len is such as to exclude '\n' at the end). + // This method can't use LOG() or CHECK() as logging system mutex(s) are held + // during this call. + virtual void send(LogSeverity severity, const char* full_filename, + const char* base_filename, int line, + const struct ::tm* tm_time, + const char* message, size_t message_len) = 0; + + // Redefine this to implement waiting for + // the sink's logging logic to complete. + // It will be called after each send() returns, + // but before that LogMessage exits or crashes. + // By default this function does nothing. + // Using this function one can implement complex logic for send() + // that itself involves logging; and do all this w/o causing deadlocks and + // inconsistent rearrangement of log messages. + // E.g. if a LogSink has thread-specific actions, the send() method + // can simply add the message to a queue and wake up another thread that + // handles real logging while itself making some LOG() calls; + // WaitTillSent() can be implemented to wait for that logic to complete. + // See our unittest for an example. + virtual void WaitTillSent(); + + // Returns the normal text output of the log message. + // Can be useful to implement send(). + static std::string ToString(LogSeverity severity, const char* file, int line, + const struct ::tm* tm_time, + const char* message, size_t message_len); +}; + +// Add or remove a LogSink as a consumer of logging data. Thread-safe. +GOOGLE_GLOG_DLL_DECL void AddLogSink(LogSink *destination); +GOOGLE_GLOG_DLL_DECL void RemoveLogSink(LogSink *destination); + +// +// Specify an "extension" added to the filename specified via +// SetLogDestination. This applies to all severity levels. It's +// often used to append the port we're listening on to the logfile +// name. Thread-safe. +// +GOOGLE_GLOG_DLL_DECL void SetLogFilenameExtension( + const char* filename_extension); + +// +// Make it so that all log messages of at least a particular severity +// are logged to stderr (in addition to logging to the usual log +// file(s)). Thread-safe. +// +GOOGLE_GLOG_DLL_DECL void SetStderrLogging(LogSeverity min_severity); + +// +// Make it so that all log messages go only to stderr. Thread-safe. +// +GOOGLE_GLOG_DLL_DECL void LogToStderr(); + +// +// Make it so that all log messages of at least a particular severity are +// logged via email to a list of addresses (in addition to logging to the +// usual log file(s)). The list of addresses is just a string containing +// the email addresses to send to (separated by spaces, say). Thread-safe. +// +GOOGLE_GLOG_DLL_DECL void SetEmailLogging(LogSeverity min_severity, + const char* addresses); + +// A simple function that sends email. dest is a commma-separated +// list of addressess. Thread-safe. +GOOGLE_GLOG_DLL_DECL bool SendEmail(const char *dest, + const char *subject, const char *body); + +GOOGLE_GLOG_DLL_DECL const std::vector& GetLoggingDirectories(); + +// For tests only: Clear the internal [cached] list of logging directories to +// force a refresh the next time GetLoggingDirectories is called. +// Thread-hostile. +void TestOnly_ClearLoggingDirectoriesList(); + +// Returns a set of existing temporary directories, which will be a +// subset of the directories returned by GetLogginDirectories(). +// Thread-safe. +GOOGLE_GLOG_DLL_DECL void GetExistingTempDirectories( + std::vector* list); + +// Print any fatal message again -- useful to call from signal handler +// so that the last thing in the output is the fatal message. +// Thread-hostile, but a race is unlikely. +GOOGLE_GLOG_DLL_DECL void ReprintFatalMessage(); + +// Truncate a log file that may be the append-only output of multiple +// processes and hence can't simply be renamed/reopened (typically a +// stdout/stderr). If the file "path" is > "limit" bytes, copy the +// last "keep" bytes to offset 0 and truncate the rest. Since we could +// be racing with other writers, this approach has the potential to +// lose very small amounts of data. For security, only follow symlinks +// if the path is /proc/self/fd/* +GOOGLE_GLOG_DLL_DECL void TruncateLogFile(const char *path, + int64 limit, int64 keep); + +// Truncate stdout and stderr if they are over the value specified by +// --max_log_size; keep the final 1MB. This function has the same +// race condition as TruncateLogFile. +GOOGLE_GLOG_DLL_DECL void TruncateStdoutStderr(); + +// Return the string representation of the provided LogSeverity level. +// Thread-safe. +GOOGLE_GLOG_DLL_DECL const char* GetLogSeverityName(LogSeverity severity); + +// --------------------------------------------------------------------- +// Implementation details that are not useful to most clients +// --------------------------------------------------------------------- + +// A Logger is the interface used by logging modules to emit entries +// to a log. A typical implementation will dump formatted data to a +// sequence of files. We also provide interfaces that will forward +// the data to another thread so that the invoker never blocks. +// Implementations should be thread-safe since the logging system +// will write to them from multiple threads. + +namespace base { + +class GOOGLE_GLOG_DLL_DECL Logger { + public: + virtual ~Logger(); + + // Writes "message[0,message_len-1]" corresponding to an event that + // occurred at "timestamp". If "force_flush" is true, the log file + // is flushed immediately. + // + // The input message has already been formatted as deemed + // appropriate by the higher level logging facility. For example, + // textual log messages already contain timestamps, and the + // file:linenumber header. + virtual void Write(bool force_flush, + time_t timestamp, + const char* message, + int message_len) = 0; + + // Flush any buffered messages + virtual void Flush() = 0; + + // Get the current LOG file size. + // The returned value is approximate since some + // logged data may not have been flushed to disk yet. + virtual uint32 LogSize() = 0; +}; + +// Get the logger for the specified severity level. The logger +// remains the property of the logging module and should not be +// deleted by the caller. Thread-safe. +extern GOOGLE_GLOG_DLL_DECL Logger* GetLogger(LogSeverity level); + +// Set the logger for the specified severity level. The logger +// becomes the property of the logging module and should not +// be deleted by the caller. Thread-safe. +extern GOOGLE_GLOG_DLL_DECL void SetLogger(LogSeverity level, Logger* logger); + +} + +// glibc has traditionally implemented two incompatible versions of +// strerror_r(). There is a poorly defined convention for picking the +// version that we want, but it is not clear whether it even works with +// all versions of glibc. +// So, instead, we provide this wrapper that automatically detects the +// version that is in use, and then implements POSIX semantics. +// N.B. In addition to what POSIX says, we also guarantee that "buf" will +// be set to an empty string, if this function failed. This means, in most +// cases, you do not need to check the error code and you can directly +// use the value of "buf". It will never have an undefined value. +GOOGLE_GLOG_DLL_DECL int posix_strerror_r(int err, char *buf, size_t len); + + +// A class for which we define operator<<, which does nothing. +class GOOGLE_GLOG_DLL_DECL NullStream : public LogMessage::LogStream { + public: + // Initialize the LogStream so the messages can be written somewhere + // (they'll never be actually displayed). This will be needed if a + // NullStream& is implicitly converted to LogStream&, in which case + // the overloaded NullStream::operator<< will not be invoked. + NullStream() : LogMessage::LogStream(message_buffer_, 1, 0) { } + NullStream &stream() { return *this; } + private: + // A very short buffer for messages (which we discard anyway). This + // will be needed if NullStream& converted to LogStream& (e.g. as a + // result of a conditional expression). + char message_buffer_[2]; +}; + +// Do nothing. This operator is inline, allowing the message to be +// compiled away. The message will not be compiled away if we do +// something like (flag ? LOG(INFO) : LOG(ERROR)) << message; when +// SKIP_LOG=WARNING. In those cases, NullStream will be implicitly +// converted to LogStream and the message will be computed and then +// quietly discarded. +template +inline NullStream& operator<<(NullStream &str, const T &value) { return str; } + +// Similar to NullStream, but aborts the program (without stack +// trace), like LogMessageFatal. +class GOOGLE_GLOG_DLL_DECL NullStreamFatal : public NullStream { + public: + ~NullStreamFatal() { _exit(1); } +}; + +// Install a signal handler that will dump signal information and a stack +// trace when the program crashes on certain signals. We'll install the +// signal handler for the following signals. +// +// SIGSEGV, SIGILL, SIGFPE, SIGABRT, SIGBUS, and SIGTERM. +// +// By default, the signal handler will write the failure dump to the +// standard error. You can customize the destination by installing your +// own writer function by InstallFailureWriter() below. +// +// Note on threading: +// +// The function should be called before threads are created, if you want +// to use the failure signal handler for all threads. The stack trace +// will be shown only for the thread that receives the signal. In other +// words, stack traces of other threads won't be shown. +GOOGLE_GLOG_DLL_DECL void InstallFailureSignalHandler(); + +// Installs a function that is used for writing the failure dump. "data" +// is the pointer to the beginning of a message to be written, and "size" +// is the size of the message. You should not expect the data is +// terminated with '\0'. +GOOGLE_GLOG_DLL_DECL void InstallFailureWriter( + void (*writer)(const char* data, int size)); + +} + +#endif // _LOGGING_H_ diff --git a/src/windows/glog/raw_logging.h b/src/windows/glog/raw_logging.h new file mode 100755 index 0000000..5d2d7bf --- /dev/null +++ b/src/windows/glog/raw_logging.h @@ -0,0 +1,102 @@ +// This file is automatically generated from src/glog/raw_logging.h.in +// using src/windows/preprocess.sh. +// DO NOT EDIT! + +// Copyright 2006 Google Inc. All Rights Reserved. +// Author: Maxim Lifantsev +// +// Logging routines that do not allocate any memory and acquire any +// locks, and can therefore be used by low-level memory allocation +// and synchronization code. + +#ifndef BASE_RAW_LOGGING_H__ +#define BASE_RAW_LOGGING_H__ + +namespace google { + +#include "glog/log_severity.h" +#include "glog/vlog_is_on.h" + +// Annoying stuff for windows -- makes sure clients can import these functions +#ifndef GOOGLE_GLOG_DLL_DECL +# ifdef _WIN32 +# define GOOGLE_GLOG_DLL_DECL __declspec(dllimport) +# else +# define GOOGLE_GLOG_DLL_DECL +# endif +#endif + +// This is similar to LOG(severity) << format... and VLOG(level) << format.., +// but +// * it is to be used ONLY by low-level modules that can't use normal LOG() +// * it is desiged to be a low-level logger that does not allocate any +// memory and does not need any locks, hence: +// * it logs straight and ONLY to STDERR w/o buffering +// * it uses an explicit format and arguments list +// * it will silently chop off really long message strings +// Usage example: +// RAW_LOG(ERROR, "Failed foo with %i: %s", status, error); +// RAW_VLOG(3, "status is %i", status); +// These will print an almost standard log lines like this to stderr only: +// E0821 211317 file.cc:123] RAW: Failed foo with 22: bad_file +// I0821 211317 file.cc:142] RAW: status is 20 +#define RAW_LOG(severity, ...) \ + do { \ + google::RawLog__(google::severity, __FILE__, __LINE__, __VA_ARGS__); \ + } while (0) + +#define RAW_VLOG(verboselevel, ...) \ + do { \ + if (VLOG_IS_ON(verboselevel)) { \ + google::RawLog__(google::INFO, __FILE__, __LINE__, __VA_ARGS__); \ + } \ + } while (0) + +// Similar to CHECK(condition) << message, +// but for low-level modules: we use only RAW_LOG that does not allocate memory. +// We do not want to provide args list here to encourage this usage: +// if (!cond) RAW_LOG(FATAL, "foo ...", hard_to_compute_args); +// so that the args are not computed when not needed. +#define RAW_CHECK(condition, message) \ + do { \ + if (!(condition)) { \ + RAW_LOG(FATAL, "Check %s failed: %s", #condition, message); \ + } \ + } while (0) + +// Debug versions of RAW_LOG and RAW_CHECK +#ifndef NDEBUG + +#define RAW_DLOG(severity, ...) RAW_LOG(severity, __VA_ARGS__) +#define RAW_DCHECK(condition, message) RAW_CHECK(condition, message) + +#else // NDEBUG + +#define RAW_DLOG(severity, ...) \ + while (false) \ + RAW_LOG(severity, __VA_ARGS__) +#define RAW_DCHECK(condition, message) \ + while (false) \ + RAW_CHECK(condition, message) + +#endif // NDEBUG + +// Helper function to implement RAW_LOG and RAW_VLOG +// Logs format... at "severity" level, reporting it +// as called from file:line. +// This does not allocate memory or acquire locks. +GOOGLE_GLOG_DLL_DECL void RawLog__(LogSeverity severity, + const char* file, + int line, + const char* format, ...) + ; + +// Hack to propagate time information into this module so that +// this module does not have to directly call localtime_r(), +// which could allocate memory. +extern "C" struct ::tm; +GOOGLE_GLOG_DLL_DECL void RawLog__SetLastTime(const struct ::tm& t); + +} + +#endif // BASE_RAW_LOGGING_H__ diff --git a/src/windows/glog/stl_logging.h b/src/windows/glog/stl_logging.h new file mode 100755 index 0000000..a3c6b99 --- /dev/null +++ b/src/windows/glog/stl_logging.h @@ -0,0 +1,132 @@ +// This file is automatically generated from src/glog/stl_logging.h.in +// using src/windows/preprocess.sh. +// DO NOT EDIT! + +// Copyright 2003 Google, Inc. +// All Rights Reserved. +// +// Stream output operators for STL containers; to be used for logging *only*. +// Inclusion of this file lets you do: +// +// list x; +// LOG(INFO) << "data: " << x; +// vector v1, v2; +// CHECK_EQ(v1, v2); +// +// Note that if you want to use these operators from the non-global namespace, +// you may get an error since they are not in namespace std (and they are not +// in namespace std since that would result in undefined behavior). You may +// need to write +// +// using ::operator<<; +// +// to fix these errors. + +#ifndef UTIL_GTL_STL_LOGGING_INL_H_ +#define UTIL_GTL_STL_LOGGING_INL_H_ + +#if !1 +# error We do not support stl_logging for this compiler +#endif + +#include +#include +#include +#include +#include +#include +#include + +#ifdef __GNUC__ +# include +# include +# include +#endif + +template +inline std::ostream& operator<<(std::ostream& out, + const std::pair& p) { + out << '(' << p.first << ", " << p.second << ')'; + return out; +} + +namespace google { + +template +inline void PrintSequence(std::ostream& out, Iter begin, Iter end) { + using ::operator<<; + // Output at most 100 elements -- appropriate if used for logging. + for (int i = 0; begin != end && i < 100; ++i, ++begin) { + if (i > 0) out << ' '; + out << *begin; + } + if (begin != end) { + out << " ..."; + } +} + +} + +#define OUTPUT_TWO_ARG_CONTAINER(Sequence) \ +template \ +inline std::ostream& operator<<(std::ostream& out, \ + const Sequence& seq) { \ + google::PrintSequence(out, seq.begin(), seq.end()); \ + return out; \ +} + +OUTPUT_TWO_ARG_CONTAINER(std::vector) +OUTPUT_TWO_ARG_CONTAINER(std::deque) +OUTPUT_TWO_ARG_CONTAINER(std::list) +#ifdef __GNUC__ +OUTPUT_TWO_ARG_CONTAINER(__gnu_cxx::slist) +#endif + +#undef OUTPUT_TWO_ARG_CONTAINER + +#define OUTPUT_THREE_ARG_CONTAINER(Sequence) \ +template \ +inline std::ostream& operator<<(std::ostream& out, \ + const Sequence& seq) { \ + google::PrintSequence(out, seq.begin(), seq.end()); \ + return out; \ +} + +OUTPUT_THREE_ARG_CONTAINER(std::set) +OUTPUT_THREE_ARG_CONTAINER(std::multiset) + +#undef OUTPUT_THREE_ARG_CONTAINER + +#define OUTPUT_FOUR_ARG_CONTAINER(Sequence) \ +template \ +inline std::ostream& operator<<(std::ostream& out, \ + const Sequence& seq) { \ + google::PrintSequence(out, seq.begin(), seq.end()); \ + return out; \ +} + +OUTPUT_FOUR_ARG_CONTAINER(std::map) +OUTPUT_FOUR_ARG_CONTAINER(std::multimap) +#ifdef __GNUC__ +OUTPUT_FOUR_ARG_CONTAINER(__gnu_cxx::hash_set) +OUTPUT_FOUR_ARG_CONTAINER(__gnu_cxx::hash_multiset) +#endif + +#undef OUTPUT_FOUR_ARG_CONTAINER + +#define OUTPUT_FIVE_ARG_CONTAINER(Sequence) \ +template \ +inline std::ostream& operator<<(std::ostream& out, \ + const Sequence& seq) { \ + google::PrintSequence(out, seq.begin(), seq.end()); \ + return out; \ +} + +#ifdef __GNUC__ +OUTPUT_FIVE_ARG_CONTAINER(__gnu_cxx::hash_map) +OUTPUT_FIVE_ARG_CONTAINER(__gnu_cxx::hash_multimap) +#endif + +#undef OUTPUT_FIVE_ARG_CONTAINER + +#endif // UTIL_GTL_STL_LOGGING_INL_H_ diff --git a/src/windows/glog/vlog_is_on.h b/src/windows/glog/vlog_is_on.h new file mode 100755 index 0000000..ffbbf20 --- /dev/null +++ b/src/windows/glog/vlog_is_on.h @@ -0,0 +1,104 @@ +// This file is automatically generated from src/glog/vlog_is_on.h.in +// using src/windows/preprocess.sh. +// DO NOT EDIT! + +// Copyright 1999, 2007 Google Inc. All Rights Reserved. +// Author: Ray Sidney and many others +// +// Defines the VLOG_IS_ON macro that controls the variable-verbosity +// conditional logging. +// +// It's used by VLOG and VLOG_IF in logging.h +// and by RAW_VLOG in raw_logging.h to trigger the logging. +// +// It can also be used directly e.g. like this: +// if (VLOG_IS_ON(2)) { +// // do some logging preparation and logging +// // that can't be accomplished e.g. via just VLOG(2) << ...; +// } +// +// The truth value that VLOG_IS_ON(level) returns is determined by +// the three verbosity level flags: +// --v= Gives the default maximal active V-logging level; +// 0 is the default. +// Normally positive values are used for V-logging levels. +// --vmodule= Gives the per-module maximal V-logging levels to override +// the value given by --v. +// E.g. "my_module=2,foo*=3" would change the logging level +// for all code in source files "my_module.*" and "foo*.*" +// ("-inl" suffixes are also disregarded for this matching). +// +// SetVLOGLevel helper function is provided to do limited dynamic control over +// V-logging by overriding the per-module settings given via --vmodule flag. +// +// CAVEAT: --vmodule functionality is not available in non gcc compilers. +// + +#ifndef BASE_VLOG_IS_ON_H_ +#define BASE_VLOG_IS_ON_H_ + +#include "glog/log_severity.h" + +// Annoying stuff for windows -- makes sure clients can import these functions +#ifndef GOOGLE_GLOG_DLL_DECL +# ifdef _WIN32 +# define GOOGLE_GLOG_DLL_DECL __declspec(dllimport) +# else +# define GOOGLE_GLOG_DLL_DECL +# endif +#endif + +#if defined(__GNUC__) +// We emit an anonymous static int* variable at every VLOG_IS_ON(n) site. +// (Normally) the first time every VLOG_IS_ON(n) site is hit, +// we determine what variable will dynamically control logging at this site: +// it's either FLAGS_v or an appropriate internal variable +// matching the current source file that represents results of +// parsing of --vmodule flag and/or SetVLOGLevel calls. +#define VLOG_IS_ON(verboselevel) \ + ({ static google::int32* vlocal__ = &google::kLogSiteUninitialized; \ + google::int32 verbose_level__ = (verboselevel); \ + (*vlocal__ >= verbose_level__) && \ + ((vlocal__ != &google::kLogSiteUninitialized) || \ + (google::InitVLOG3__(&vlocal__, &FLAGS_v, \ + __FILE__, verbose_level__))); }) +#else +// GNU extensions not available, so we do not support --vmodule. +// Dynamic value of FLAGS_v always controls the logging level. +#define VLOG_IS_ON(verboselevel) (FLAGS_v >= (verboselevel)) +#endif + +// Set VLOG(_IS_ON) level for module_pattern to log_level. +// This lets us dynamically control what is normally set by the --vmodule flag. +// Returns the level that previously applied to module_pattern. +// NOTE: To change the log level for VLOG(_IS_ON) sites +// that have already executed after/during InitGoogleLogging, +// one needs to supply the exact --vmodule pattern that applied to them. +// (If no --vmodule pattern applied to them +// the value of FLAGS_v will continue to control them.) +extern GOOGLE_GLOG_DLL_DECL int SetVLOGLevel(const char* module_pattern, + int log_level); + +// Various declarations needed for VLOG_IS_ON above: ========================= + +// Special value used to indicate that a VLOG_IS_ON site has not been +// initialized. We make this a large value, so the common-case check +// of "*vlocal__ >= verbose_level__" in VLOG_IS_ON definition +// passes in such cases and InitVLOG3__ is then triggered. +extern google::int32 kLogSiteUninitialized; + +// Helper routine which determines the logging info for a particalur VLOG site. +// site_flag is the address of the site-local pointer to the controlling +// verbosity level +// site_default is the default to use for *site_flag +// fname is the current source file name +// verbose_level is the argument to VLOG_IS_ON +// We will return the return value for VLOG_IS_ON +// and if possible set *site_flag appropriately. +extern GOOGLE_GLOG_DLL_DECL bool InitVLOG3__( + google::int32** site_flag, + google::int32* site_default, + const char* fname, + google::int32 verbose_level); + +#endif // BASE_VLOG_IS_ON_H_ diff --git a/src/windows/port.cc b/src/windows/port.cc new file mode 100755 index 0000000..bfa6e70 --- /dev/null +++ b/src/windows/port.cc @@ -0,0 +1,64 @@ +/* Copyright (c) 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. + * + * --- + * Author: Craig Silverstein + * Copied from google-perftools and modified by Shinichiro Hamaji + */ + +#ifndef _WIN32 +# error You should only be including windows/port.cc in a windows environment! +#endif + +#include "config.h" +#include // for va_list, va_start, va_end +#include // for strstr() +#include +#include +#include +#include "port.h" + +using std::string; +using std::vector; + +// These call the windows _vsnprintf, but always NUL-terminate. +int safe_vsnprintf(char *str, size_t size, const char *format, va_list ap) { + if (size == 0) // not even room for a \0? + return -1; // not what C99 says to do, but what windows does + str[size-1] = '\0'; + return _vsnprintf(str, size-1, format, ap); +} + +int snprintf(char *str, size_t size, const char *format, ...) { + va_list ap; + va_start(ap, format); + const int r = vsnprintf(str, size, format, ap); + va_end(ap); + return r; +} diff --git a/src/windows/port.h b/src/windows/port.h new file mode 100755 index 0000000..d093bf5 --- /dev/null +++ b/src/windows/port.h @@ -0,0 +1,149 @@ +/* Copyright (c) 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. + * + * --- + * Author: Craig Silverstein + * Copied from google-perftools and modified by Shinichiro Hamaji + * + * These are some portability typedefs and defines to make it a bit + * easier to compile this code under VC++. + * + * Several of these are taken from glib: + * http://developer.gnome.org/doc/API/glib/glib-windows-compatability-functions.html + */ + +#ifndef CTEMPLATE_WINDOWS_PORT_H_ +#define CTEMPLATE_WINDOWS_PORT_H_ + +#include "config.h" + +#ifdef _WIN32 + +#define WIN32_LEAN_AND_MEAN /* We always want minimal includes */ +#include +#include /* for gethostname */ +#include /* because we so often use open/close/etc */ +#include /* for _getcwd() */ +#include /* for _getpid() */ +#include /* read in vsnprintf decl. before redifining it */ +#include /* template_dictionary.cc uses va_copy */ +#include /* for _strnicmp(), strerror_s() */ +#include /* for localtime_s() */ +/* Note: the C++ #includes are all together at the bottom. This file is + * used by both C and C++ code, so we put all the C++ together. + */ + +/* 4244: otherwise we get problems when substracting two size_t's to an int + * 4251: it's complaining about a private struct I've chosen not to dllexport + * 4355: we use this in a constructor, but we do it safely + * 4715: for some reason VC++ stopped realizing you can't return after abort() + * 4800: we know we're casting ints/char*'s to bools, and we're ok with that + * 4996: Yes, we're ok using "unsafe" functions like fopen() and strerror() + */ +#pragma warning(disable:4244 4251 4355 4715 4800 4996) + +/* file I/O */ +#define PATH_MAX 1024 +#define access _access +#define getcwd _getcwd +#define open _open +#define read _read +#define write _write +#define lseek _lseek +#define close _close +#define popen _popen +#define pclose _pclose +#define R_OK 04 /* read-only (for access()) */ +#define S_ISDIR(m) (((m) & _S_IFMT) == _S_IFDIR) +#ifndef __MINGW32__ +enum { STDIN_FILENO = 0, STDOUT_FILENO = 1, STDERR_FILENO = 2 }; +#endif +#define S_IRUSR S_IREAD +#define S_IWUSR S_IWRITE + +/* Not quite as lightweight as a hard-link, but more than good enough for us. */ +#define link(oldpath, newpath) CopyFileA(oldpath, newpath, false) + +#define strcasecmp _stricmp +#define strncasecmp _strnicmp + +/* In windows-land, hash<> is called hash_compare<> (from xhash.h) */ +#define hash hash_compare + +/* Sleep is in ms, on windows */ +#define sleep(secs) Sleep((secs) * 1000) + +/* We can't just use _vsnprintf and _snprintf as drop-in-replacements, + * because they don't always NUL-terminate. :-( We also can't use the + * name vsnprintf, since windows defines that (but not snprintf (!)). + */ +extern int snprintf(char *str, size_t size, + const char *format, ...); +extern int safe_vsnprintf(char *str, size_t size, + const char *format, va_list ap); +#define vsnprintf(str, size, format, ap) safe_vsnprintf(str, size, format, ap) +#define va_copy(dst, src) (dst) = (src) + +/* Windows doesn't support specifying the number of buckets as a + * hash_map constructor arg, so we leave this blank. + */ +#define CTEMPLATE_SMALL_HASHTABLE + +#define DEFAULT_TEMPLATE_ROOTDIR ".." + +// ----------------------------------- SYSTEM/PROCESS +typedef int pid_t; +#define getpid _getpid + +// ----------------------------------- THREADS +typedef DWORD pthread_t; +typedef DWORD pthread_key_t; +typedef LONG pthread_once_t; +enum { PTHREAD_ONCE_INIT = 0 }; // important that this be 0! for SpinLock +#define pthread_self GetCurrentThreadId +#define pthread_equal(pthread_t_1, pthread_t_2) ((pthread_t_1)==(pthread_t_2)) + +inline struct tm* localtime_r(const time_t* timep, struct tm* result) { + localtime_s(result, timep); + return result; +} + +inline char* strerror_r(int errnum, char* buf, size_t buflen) { + strerror_s(buf, buflen, errnum); + return buf; +} + +#ifndef __cplusplus +/* I don't see how to get inlining for C code in MSVC. Ah well. */ +#define inline +#endif + +#endif /* _WIN32 */ + +#endif /* CTEMPLATE_WINDOWS_PORT_H_ */ diff --git a/src/windows/preprocess.sh b/src/windows/preprocess.sh new file mode 100755 index 0000000..ea4352e --- /dev/null +++ b/src/windows/preprocess.sh @@ -0,0 +1,118 @@ +#!/bin/sh + +# Copyright (c) 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. + +# --- +# Author: Craig Silverstein +# Copied from google-perftools and modified by Shinichiro Hamaji +# +# This script is meant to be run at distribution-generation time, for +# instance by autogen.sh. It does some of the work configure would +# normally do, for windows systems. In particular, it expands all the +# @...@ variables found in .in files, and puts them here, in the windows +# directory. +# +# This script should be run before any new release. + +if [ -z "$1" ]; then + echo "USAGE: $0 " + exit 1 +fi + +DLLDEF_MACRO_NAME="GLOG_DLL_DECL" + +# The text we put in every .h files we create. As a courtesy, we'll +# include a helpful comment for windows users as to how to use +# GLOG_DLL_DECL. Apparently sed expands \n into a newline. Good! +DLLDEF_DEFINES="\ +// NOTE: if you are statically linking the template library into your binary\n\ +// (rather than using the template .dll), set '/D $DLLDEF_MACRO_NAME='\n\ +// as a compiler flag in your project file to turn off the dllimports.\n\ +#ifndef $DLLDEF_MACRO_NAME\n\ +# define $DLLDEF_MACRO_NAME __declspec(dllimport)\n\ +#endif" + +# Read all the windows config info into variables +# In order for the 'set' to take, this requires putting all in a subshell. +( + while read define varname value; do + [ "$define" != "#define" ] && continue + eval "$varname='$value'" + done + + # Process all the .in files in the "glog" subdirectory + mkdir -p "$1/windows/glog" + for file in `echo "$1"/glog/*.in`; do + echo "Processing $file" + outfile="$1/windows/glog/`basename $file .in`" + + echo "\ +// This file is automatically generated from $file +// using src/windows/preprocess.sh. +// DO NOT EDIT! +" > "$outfile" + # Besides replacing @...@, we also need to turn on dllimport + # We also need to replace hash by hash_compare (annoying we hard-code :-( ) + sed -e "s!@ac_windows_dllexport@!$DLLDEF_MACRO_NAME!g" \ + -e "s!@ac_windows_dllexport_defines@!$DLLDEF_DEFINES!g" \ + -e "s!@ac_cv_cxx_hash_map@!$HASH_MAP_H!g" \ + -e "s!@ac_cv_cxx_hash_namespace@!$HASH_NAMESPACE!g" \ + -e "s!@ac_cv_cxx_hash_set@!$HASH_SET_H!g" \ + -e "s!@ac_cv_have_stdint_h@!0!g" \ + -e "s!@ac_cv_have_systypes_h@!0!g" \ + -e "s!@ac_cv_have_inttypes_h@!0!g" \ + -e "s!@ac_cv_have_unistd_h@!0!g" \ + -e "s!@ac_cv_have_uint16_t@!0!g" \ + -e "s!@ac_cv_have_u_int16_t@!0!g" \ + -e "s!@ac_cv_have___uint16@!1!g" \ + -e "s!@ac_cv_have_libgflags@!0!g" \ + -e "s!@ac_cv_have___builtin_expect@!0!g" \ + -e "s!@ac_cv_cxx_using_operator@!1!g" \ + -e "s!@ac_cv___attribute___noreturn@!!g" \ + -e "s!@ac_cv___attribute___printf_4_5@!!g" \ + -e "s!@ac_google_attribute@!${HAVE___ATTRIBUTE__:-0}!g" \ + -e "s!@ac_google_end_namespace@!$_END_GOOGLE_NAMESPACE_!g" \ + -e "s!@ac_google_namespace@!$GOOGLE_NAMESPACE!g" \ + -e "s!@ac_google_start_namespace@!$_START_GOOGLE_NAMESPACE_!g" \ + -e "s!@ac_htmlparser_namespace@!$HTMLPARSER_NAMESPACE!g" \ + -e "s!\\bhash\\b!hash_compare!g" \ + "$file" >> "$outfile" + done +) < "$1/windows/config.h" + +# log_severity.h isn't a .in file. +echo "\ +// This file is automatically generated from $1/glog/log_severity.h +// using src/windows/preprocess.sh. +// DO NOT EDIT! +" > "$1/windows/glog/log_severity.h" +cat "$1/glog/log_severity.h" >> "$1/windows/glog/log_severity.h" + +echo "DONE" diff --git a/vsprojects/libglog/libglog.vcproj b/vsprojects/libglog/libglog.vcproj new file mode 100755 index 0000000..67aeaac --- /dev/null +++ b/vsprojects/libglog/libglog.vcproj @@ -0,0 +1,249 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vsprojects/logging_unittest/logging_unittest.vcproj b/vsprojects/logging_unittest/logging_unittest.vcproj new file mode 100755 index 0000000..649a234 --- /dev/null +++ b/vsprojects/logging_unittest/logging_unittest.vcproj @@ -0,0 +1,193 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- 2.7.4