1fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Protocol Buffers - Google's data interchange format 2fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Copyright 2008 Google Inc. All rights reserved. 3afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson// https://developers.google.com/protocol-buffers/ 4fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// 5fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Redistribution and use in source and binary forms, with or without 6fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// modification, are permitted provided that the following conditions are 7fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// met: 8fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// 9fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// * Redistributions of source code must retain the above copyright 10fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// notice, this list of conditions and the following disclaimer. 11fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// * Redistributions in binary form must reproduce the above 12fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// copyright notice, this list of conditions and the following disclaimer 13fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// in the documentation and/or other materials provided with the 14fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// distribution. 15fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// * Neither the name of Google Inc. nor the names of its 16fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// contributors may be used to endorse or promote products derived from 17fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// this software without specific prior written permission. 18fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// 19fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 31fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Author: kenton@google.com (Kenton Varda) 32fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// emulates google3/testing/base/public/googletest.cc 33fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 34fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/testing/googletest.h> 35fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/testing/file.h> 36fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/stubs/strutil.h> 37fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <sys/stat.h> 38fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <sys/types.h> 39fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <errno.h> 40fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <stdlib.h> 41fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#ifdef _MSC_VER 42fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <io.h> 43fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <direct.h> 44fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#else 45fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <unistd.h> 46fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#endif 47fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <stdio.h> 48fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <fcntl.h> 49d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville#include <iostream> 50d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville#include <fstream> 51fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 52fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace google { 53fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace protobuf { 54fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 55fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#ifdef _WIN32 56fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#define mkdir(name, mode) mkdir(name) 57fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#endif 58fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 59fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#ifndef O_BINARY 60fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#ifdef _O_BINARY 61fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#define O_BINARY _O_BINARY 62fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#else 63fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#define O_BINARY 0 // If this isn't defined, the platform doesn't need it. 64fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#endif 65fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#endif 66fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 67fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring TestSourceDir() { 68b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer#ifndef GOOGLE_THIRD_PARTY_PROTOBUF 69b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer#ifndef _MSC_VER 70b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer // automake sets the "srcdir" environment variable. 71b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer char* result = getenv("srcdir"); 72b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer if (result != NULL) { 73b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer return result; 74b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer } 75b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer#endif // _MSC_VER 76b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer 77fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Look for the "src" directory. 78fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string prefix = "."; 79fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 80fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville while (!File::Exists(prefix + "/src/google/protobuf")) { 81fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!File::Exists(prefix)) { 82fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_LOG(FATAL) 83fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville << "Could not find protobuf source code. Please run tests from " 84fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "somewhere within the protobuf source package."; 85fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 86fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville prefix += "/.."; 87fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 88fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return prefix + "/src"; 89fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#else 90b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer return "third_party/protobuf/src"; 91b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer#endif // GOOGLE_THIRD_PARTY_PROTOBUF 92fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 93fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 94fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace { 95fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 96fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring GetTemporaryDirectoryName() { 97b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer // Tests run under Bazel "should not" use /tmp. Bazel sets this environment 98b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer // variable for tests to use instead. 99b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer char *from_environment = getenv("TEST_TMPDIR"); 100b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer if (from_environment != NULL && from_environment[0] != '\0') { 101b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer return string(from_environment) + "/protobuf_tmpdir"; 102b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer } 103b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer 104fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // tmpnam() is generally not considered safe but we're only using it for 105fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // testing. We cannot use tmpfile() or mkstemp() since we're creating a 106fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // directory. 107d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville char b[L_tmpnam + 1]; // HPUX multithread return 0 if s is 0 108d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville string result = tmpnam(b); 109fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#ifdef _WIN32 110fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // On Win32, tmpnam() returns a file prefixed with '\', but which is supposed 111fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // to be used in the current working directory. WTF? 112fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (HasPrefixString(result, "\\")) { 113fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result.erase(0, 1); 114fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 115b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer // The Win32 API accepts forward slashes as a path delimiter even though 116b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer // backslashes are standard. Let's avoid confusion and use only forward 117b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer // slashes. 118b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer result = StringReplace(result, "\\", "/", true); 119fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#endif // _WIN32 120fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return result; 121fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 122fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 123fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Creates a temporary directory on demand and deletes it when the process 124fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// quits. 125fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleclass TempDirDeleter { 126fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville public: 127fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville TempDirDeleter() {} 128fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ~TempDirDeleter() { 129fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!name_.empty()) { 130fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville File::DeleteRecursively(name_, NULL, NULL); 131fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 132fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 133fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 134fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string GetTempDir() { 135fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (name_.empty()) { 136fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville name_ = GetTemporaryDirectoryName(); 137fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_CHECK(mkdir(name_.c_str(), 0777) == 0) << strerror(errno); 138fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 139fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Stick a file in the directory that tells people what this is, in case 140fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // we abort and don't get a chance to delete it. 141fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville File::WriteStringToFileOrDie("", name_ + "/TEMP_DIR_FOR_PROTOBUF_TESTS"); 142fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 143fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return name_; 144fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 145fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 146fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville private: 147fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string name_; 148fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}; 149fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 150fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTempDirDeleter temp_dir_deleter_; 151fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 152fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} // namespace 153fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 154fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring TestTempDir() { 155fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return temp_dir_deleter_.GetTempDir(); 156fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 157fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 158fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// TODO(kenton): Share duplicated code below. Too busy/lazy for now. 159fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 160fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestatic string stdout_capture_filename_; 161fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestatic string stderr_capture_filename_; 162fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestatic int original_stdout_ = -1; 163fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestatic int original_stderr_ = -1; 164fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 165fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid CaptureTestStdout() { 166fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_CHECK_EQ(original_stdout_, -1) << "Already capturing."; 167fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 168fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville stdout_capture_filename_ = TestTempDir() + "/captured_stdout"; 169fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 170fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int fd = open(stdout_capture_filename_.c_str(), 171fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville O_WRONLY | O_CREAT | O_EXCL | O_BINARY, 0777); 172fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_CHECK(fd >= 0) << "open: " << strerror(errno); 173fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 174fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville original_stdout_ = dup(1); 175fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville close(1); 176fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville dup2(fd, 1); 177fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville close(fd); 178fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 179fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 180fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid CaptureTestStderr() { 181fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_CHECK_EQ(original_stderr_, -1) << "Already capturing."; 182fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 183fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville stderr_capture_filename_ = TestTempDir() + "/captured_stderr"; 184fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 185fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int fd = open(stderr_capture_filename_.c_str(), 186fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville O_WRONLY | O_CREAT | O_EXCL | O_BINARY, 0777); 187fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_CHECK(fd >= 0) << "open: " << strerror(errno); 188fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 189fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville original_stderr_ = dup(2); 190fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville close(2); 191fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville dup2(fd, 2); 192fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville close(fd); 193fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 194fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 195fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring GetCapturedTestStdout() { 196fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_CHECK_NE(original_stdout_, -1) << "Not capturing."; 197fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 198fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville close(1); 199fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville dup2(original_stdout_, 1); 200fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville original_stdout_ = -1; 201fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 202fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string result; 203fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville File::ReadFileToStringOrDie(stdout_capture_filename_, &result); 204fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 205fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville remove(stdout_capture_filename_.c_str()); 206fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 207fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return result; 208fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 209fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 210fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring GetCapturedTestStderr() { 211fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_CHECK_NE(original_stderr_, -1) << "Not capturing."; 212fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 213fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville close(2); 214fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville dup2(original_stderr_, 2); 215fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville original_stderr_ = -1; 216fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 217fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string result; 218fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville File::ReadFileToStringOrDie(stderr_capture_filename_, &result); 219fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 220fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville remove(stderr_capture_filename_.c_str()); 221fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 222fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return result; 223fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 224fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 225fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleScopedMemoryLog* ScopedMemoryLog::active_log_ = NULL; 226fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 227fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleScopedMemoryLog::ScopedMemoryLog() { 228fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_CHECK(active_log_ == NULL); 229fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville active_log_ = this; 230fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville old_handler_ = SetLogHandler(&HandleLog); 231fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 232fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 233fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleScopedMemoryLog::~ScopedMemoryLog() { 234fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SetLogHandler(old_handler_); 235fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville active_log_ = NULL; 236fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 237fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 238a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonconst vector<string>& ScopedMemoryLog::GetMessages(LogLevel level) { 239a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson GOOGLE_CHECK(level == ERROR || 240a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson level == WARNING); 241a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson return messages_[level]; 242fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 243fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 244fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid ScopedMemoryLog::HandleLog(LogLevel level, const char* filename, 245fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int line, const string& message) { 246fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_CHECK(active_log_ != NULL); 247a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (level == ERROR || level == WARNING) { 248a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson active_log_->messages_[level].push_back(message); 249fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 250fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 251fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 252fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace { 253fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 254fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Force shutdown at process exit so that we can test for memory leaks. To 255fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// actually check for leaks, I suggest using the heap checker included with 256fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// google-perftools. Set it to "draconian" mode to ensure that every last 257fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// call to malloc() has a corresponding free(). 258fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestruct ForceShutdown { 259fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ~ForceShutdown() { 260fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ShutdownProtobufLibrary(); 261fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 262fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} force_shutdown; 263fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 264fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} // namespace 265fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 266fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} // namespace protobuf 267fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} // namespace google 268