15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Protocol Buffers - Google's data interchange format 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright 2008 Google Inc. All rights reserved. 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// http://code.google.com/p/protobuf/ 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Redistribution and use in source and binary forms, with or without 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// modification, are permitted provided that the following conditions are 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// met: 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// * Redistributions of source code must retain the above copyright 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// notice, this list of conditions and the following disclaimer. 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// * Redistributions in binary form must reproduce the above 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// copyright notice, this list of conditions and the following disclaimer 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// in the documentation and/or other materials provided with the 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// distribution. 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// * Neither the name of Google Inc. nor the names of its 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// contributors may be used to endorse or promote products derived from 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// this software without specific prior written permission. 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Author: kenton@google.com (Kenton Varda) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// emulates google3/testing/base/public/googletest.cc 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/testing/googletest.h> 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/testing/file.h> 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/stubs/strutil.h> 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/stat.h> 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/types.h> 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <errno.h> 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdlib.h> 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef _MSC_VER 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <io.h> 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <direct.h> 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <unistd.h> 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdio.h> 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <fcntl.h> 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <iostream> 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <fstream> 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace google { 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace protobuf { 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef _WIN32 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define mkdir(name, mode) mkdir(name) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef O_BINARY 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef _O_BINARY 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define O_BINARY _O_BINARY 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define O_BINARY 0 // If this isn't defined, the platform doesn't need it. 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string TestSourceDir() { 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef _MSC_VER 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Look for the "src" directory. 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string prefix = "."; 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (!File::Exists(prefix + "/src/google/protobuf")) { 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!File::Exists(prefix)) { 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GOOGLE_LOG(FATAL) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "Could not find protobuf source code. Please run tests from " 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "somewhere within the protobuf source package."; 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prefix += "/.."; 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return prefix + "/src"; 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // automake sets the "srcdir" environment variable. 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* result = getenv("srcdir"); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result == NULL) { 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Otherwise, the test must be run from the source directory. 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "."; 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string GetTemporaryDirectoryName() { 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // tmpnam() is generally not considered safe but we're only using it for 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // testing. We cannot use tmpfile() or mkstemp() since we're creating a 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // directory. 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char b[L_tmpnam + 1]; // HPUX multithread return 0 if s is 0 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string result = tmpnam(b); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef _WIN32 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // On Win32, tmpnam() returns a file prefixed with '\', but which is supposed 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to be used in the current working directory. WTF? 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (HasPrefixString(result, "\\")) { 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result.erase(0, 1); 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // _WIN32 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Creates a temporary directory on demand and deletes it when the process 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// quits. 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TempDirDeleter { 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TempDirDeleter() {} 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~TempDirDeleter() { 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!name_.empty()) { 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) File::DeleteRecursively(name_, NULL, NULL); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string GetTempDir() { 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (name_.empty()) { 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) name_ = GetTemporaryDirectoryName(); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GOOGLE_CHECK(mkdir(name_.c_str(), 0777) == 0) << strerror(errno); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Stick a file in the directory that tells people what this is, in case 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we abort and don't get a chance to delete it. 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) File::WriteStringToFileOrDie("", name_ + "/TEMP_DIR_FOR_PROTOBUF_TESTS"); 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return name_; 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string name_; 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TempDirDeleter temp_dir_deleter_; 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string TestTempDir() { 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return temp_dir_deleter_.GetTempDir(); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(kenton): Share duplicated code below. Too busy/lazy for now. 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static string stdout_capture_filename_; 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static string stderr_capture_filename_; 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int original_stdout_ = -1; 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int original_stderr_ = -1; 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CaptureTestStdout() { 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GOOGLE_CHECK_EQ(original_stdout_, -1) << "Already capturing."; 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stdout_capture_filename_ = TestTempDir() + "/captured_stdout"; 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int fd = open(stdout_capture_filename_.c_str(), 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) O_WRONLY | O_CREAT | O_EXCL | O_BINARY, 0777); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GOOGLE_CHECK(fd >= 0) << "open: " << strerror(errno); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) original_stdout_ = dup(1); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) close(1); 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dup2(fd, 1); 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) close(fd); 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CaptureTestStderr() { 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GOOGLE_CHECK_EQ(original_stderr_, -1) << "Already capturing."; 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stderr_capture_filename_ = TestTempDir() + "/captured_stderr"; 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int fd = open(stderr_capture_filename_.c_str(), 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) O_WRONLY | O_CREAT | O_EXCL | O_BINARY, 0777); 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GOOGLE_CHECK(fd >= 0) << "open: " << strerror(errno); 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) original_stderr_ = dup(2); 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) close(2); 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dup2(fd, 2); 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) close(fd); 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string GetCapturedTestStdout() { 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GOOGLE_CHECK_NE(original_stdout_, -1) << "Not capturing."; 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) close(1); 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dup2(original_stdout_, 1); 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) original_stdout_ = -1; 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string result; 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) File::ReadFileToStringOrDie(stdout_capture_filename_, &result); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) remove(stdout_capture_filename_.c_str()); 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string GetCapturedTestStderr() { 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GOOGLE_CHECK_NE(original_stderr_, -1) << "Not capturing."; 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) close(2); 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dup2(original_stderr_, 2); 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) original_stderr_ = -1; 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string result; 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) File::ReadFileToStringOrDie(stderr_capture_filename_, &result); 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) remove(stderr_capture_filename_.c_str()); 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ScopedMemoryLog* ScopedMemoryLog::active_log_ = NULL; 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ScopedMemoryLog::ScopedMemoryLog() { 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GOOGLE_CHECK(active_log_ == NULL); 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) active_log_ = this; 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) old_handler_ = SetLogHandler(&HandleLog); 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ScopedMemoryLog::~ScopedMemoryLog() { 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetLogHandler(old_handler_); 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) active_log_ = NULL; 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 226ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochconst vector<string>& ScopedMemoryLog::GetMessages(LogLevel level) { 227ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch GOOGLE_CHECK(level == ERROR || 228ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch level == WARNING); 229ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return messages_[level]; 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ScopedMemoryLog::HandleLog(LogLevel level, const char* filename, 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int line, const string& message) { 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GOOGLE_CHECK(active_log_ != NULL); 235ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (level == ERROR || level == WARNING) { 236ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch active_log_->messages_[level].push_back(message); 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Force shutdown at process exit so that we can test for memory leaks. To 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// actually check for leaks, I suggest using the heap checker included with 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// google-perftools. Set it to "draconian" mode to ensure that every last 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// call to malloc() has a corresponding free(). 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ForceShutdown { 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~ForceShutdown() { 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ShutdownProtobufLibrary(); 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} force_shutdown; 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace protobuf 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace google 256