1*08ab5237SOystein Eftevaag // Copyright (c) 2011, Google Inc. 2*08ab5237SOystein Eftevaag // All rights reserved. 3*08ab5237SOystein Eftevaag // 4*08ab5237SOystein Eftevaag // Redistribution and use in source and binary forms, with or without 5*08ab5237SOystein Eftevaag // modification, are permitted provided that the following conditions are 6*08ab5237SOystein Eftevaag // met: 7*08ab5237SOystein Eftevaag // 8*08ab5237SOystein Eftevaag // * Redistributions of source code must retain the above copyright 9*08ab5237SOystein Eftevaag // notice, this list of conditions and the following disclaimer. 10*08ab5237SOystein Eftevaag // * Redistributions in binary form must reproduce the above 11*08ab5237SOystein Eftevaag // copyright notice, this list of conditions and the following disclaimer 12*08ab5237SOystein Eftevaag // in the documentation and/or other materials provided with the 13*08ab5237SOystein Eftevaag // distribution. 14*08ab5237SOystein Eftevaag // * Neither the name of Google Inc. nor the names of its 15*08ab5237SOystein Eftevaag // contributors may be used to endorse or promote products derived from 16*08ab5237SOystein Eftevaag // this software without specific prior written permission. 17*08ab5237SOystein Eftevaag // 18*08ab5237SOystein Eftevaag // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19*08ab5237SOystein Eftevaag // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20*08ab5237SOystein Eftevaag // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21*08ab5237SOystein Eftevaag // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22*08ab5237SOystein Eftevaag // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23*08ab5237SOystein Eftevaag // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24*08ab5237SOystein Eftevaag // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25*08ab5237SOystein Eftevaag // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26*08ab5237SOystein Eftevaag // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27*08ab5237SOystein Eftevaag // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28*08ab5237SOystein Eftevaag // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29*08ab5237SOystein Eftevaag // --- 30*08ab5237SOystein Eftevaag // 31*08ab5237SOystein Eftevaag // Some generically useful utility routines that in google-land would 32*08ab5237SOystein Eftevaag // be their own projects. We make a shortened version here. 33*08ab5237SOystein Eftevaag 34*08ab5237SOystein Eftevaag #ifndef GFLAGS_UTIL_H_ 35*08ab5237SOystein Eftevaag #define GFLAGS_UTIL_H_ 36*08ab5237SOystein Eftevaag 37*08ab5237SOystein Eftevaag #include "config.h" 38*08ab5237SOystein Eftevaag 39*08ab5237SOystein Eftevaag #include <assert.h> 40*08ab5237SOystein Eftevaag #ifdef HAVE_INTTYPES_H 41*08ab5237SOystein Eftevaag # include <inttypes.h> 42*08ab5237SOystein Eftevaag #endif 43*08ab5237SOystein Eftevaag #include <stdarg.h> // for va_* 44*08ab5237SOystein Eftevaag #include <stdlib.h> 45*08ab5237SOystein Eftevaag #include <stdio.h> 46*08ab5237SOystein Eftevaag #include <iostream> 47*08ab5237SOystein Eftevaag #include <string> 48*08ab5237SOystein Eftevaag #include <errno.h> 49*08ab5237SOystein Eftevaag #ifdef HAVE_SYS_STAT_H 50*08ab5237SOystein Eftevaag # include <sys/stat.h> // for mkdir 51*08ab5237SOystein Eftevaag #endif 52*08ab5237SOystein Eftevaag 53*08ab5237SOystein Eftevaag 54*08ab5237SOystein Eftevaag namespace GFLAGS_NAMESPACE { 55*08ab5237SOystein Eftevaag 56*08ab5237SOystein Eftevaag 57*08ab5237SOystein Eftevaag // This is used for unittests for death-testing. It is defined in gflags.cc. 58*08ab5237SOystein Eftevaag extern GFLAGS_DLL_DECL void (*gflags_exitfunc)(int); 59*08ab5237SOystein Eftevaag 60*08ab5237SOystein Eftevaag // Work properly if either strtoll or strtoq is on this system. 61*08ab5237SOystein Eftevaag #if defined(strtoll) || defined(HAVE_STRTOLL) 62*08ab5237SOystein Eftevaag # define strto64 strtoll 63*08ab5237SOystein Eftevaag # define strtou64 strtoull 64*08ab5237SOystein Eftevaag #elif defined(HAVE_STRTOQ) 65*08ab5237SOystein Eftevaag # define strto64 strtoq 66*08ab5237SOystein Eftevaag # define strtou64 strtouq 67*08ab5237SOystein Eftevaag // Neither strtoll nor strtoq are defined. I hope strtol works! 68*08ab5237SOystein Eftevaag #else 69*08ab5237SOystein Eftevaag # define strto64 strtol 70*08ab5237SOystein Eftevaag # define strtou64 strtoul 71*08ab5237SOystein Eftevaag #endif 72*08ab5237SOystein Eftevaag 73*08ab5237SOystein Eftevaag // If we have inttypes.h, it will have defined PRId32/etc for us. 74*08ab5237SOystein Eftevaag // If not, take our best guess. 75*08ab5237SOystein Eftevaag #ifndef PRId32 76*08ab5237SOystein Eftevaag # define PRId32 "d" 77*08ab5237SOystein Eftevaag #endif 78*08ab5237SOystein Eftevaag #ifndef PRId64 79*08ab5237SOystein Eftevaag # define PRId64 "lld" 80*08ab5237SOystein Eftevaag #endif 81*08ab5237SOystein Eftevaag #ifndef PRIu64 82*08ab5237SOystein Eftevaag # define PRIu64 "llu" 83*08ab5237SOystein Eftevaag #endif 84*08ab5237SOystein Eftevaag 85*08ab5237SOystein Eftevaag typedef signed char int8; 86*08ab5237SOystein Eftevaag typedef unsigned char uint8; 87*08ab5237SOystein Eftevaag 88*08ab5237SOystein Eftevaag // -- utility macros --------------------------------------------------------- 89*08ab5237SOystein Eftevaag 90*08ab5237SOystein Eftevaag template <bool b> struct CompileAssert; 91*08ab5237SOystein Eftevaag template <> struct CompileAssert<true> {}; 92*08ab5237SOystein Eftevaag #define COMPILE_ASSERT(expr, msg) \ 93*08ab5237SOystein Eftevaag enum { assert_##msg = sizeof(CompileAssert<bool(expr)>) } 94*08ab5237SOystein Eftevaag 95*08ab5237SOystein Eftevaag // Returns the number of elements in an array. 96*08ab5237SOystein Eftevaag #define arraysize(arr) (sizeof(arr)/sizeof(*(arr))) 97*08ab5237SOystein Eftevaag 98*08ab5237SOystein Eftevaag 99*08ab5237SOystein Eftevaag // -- logging and testing --------------------------------------------------- 100*08ab5237SOystein Eftevaag 101*08ab5237SOystein Eftevaag // For now, we ignore the level for logging, and don't show *VLOG's at 102*08ab5237SOystein Eftevaag // all, except by hand-editing the lines below 103*08ab5237SOystein Eftevaag #define LOG(level) std::cerr 104*08ab5237SOystein Eftevaag #define VLOG(level) if (true) {} else std::cerr 105*08ab5237SOystein Eftevaag #define DVLOG(level) if (true) {} else std::cerr 106*08ab5237SOystein Eftevaag 107*08ab5237SOystein Eftevaag // CHECK dies with a fatal error if condition is not true. It is *not* 108*08ab5237SOystein Eftevaag // controlled by NDEBUG, so the check will be executed regardless of 109*08ab5237SOystein Eftevaag // compilation mode. Therefore, it is safe to do things like: 110*08ab5237SOystein Eftevaag // CHECK(fp->Write(x) == 4) 111*08ab5237SOystein Eftevaag // We allow stream-like objects after this for debugging, but they're ignored. 112*08ab5237SOystein Eftevaag #define EXPECT_TRUE(condition) \ 113*08ab5237SOystein Eftevaag if (true) { \ 114*08ab5237SOystein Eftevaag if (!(condition)) { \ 115*08ab5237SOystein Eftevaag fprintf(stderr, "Check failed: %s\n", #condition); \ 116*08ab5237SOystein Eftevaag exit(1); \ 117*08ab5237SOystein Eftevaag } \ 118*08ab5237SOystein Eftevaag } else std::cerr << "" 119*08ab5237SOystein Eftevaag 120*08ab5237SOystein Eftevaag #define EXPECT_OP(op, val1, val2) \ 121*08ab5237SOystein Eftevaag if (true) { \ 122*08ab5237SOystein Eftevaag if (!((val1) op (val2))) { \ 123*08ab5237SOystein Eftevaag fprintf(stderr, "Check failed: %s %s %s\n", #val1, #op, #val2); \ 124*08ab5237SOystein Eftevaag exit(1); \ 125*08ab5237SOystein Eftevaag } \ 126*08ab5237SOystein Eftevaag } else std::cerr << "" 127*08ab5237SOystein Eftevaag 128*08ab5237SOystein Eftevaag #define EXPECT_EQ(val1, val2) EXPECT_OP(==, val1, val2) 129*08ab5237SOystein Eftevaag #define EXPECT_NE(val1, val2) EXPECT_OP(!=, val1, val2) 130*08ab5237SOystein Eftevaag #define EXPECT_LE(val1, val2) EXPECT_OP(<=, val1, val2) 131*08ab5237SOystein Eftevaag #define EXPECT_LT(val1, val2) EXPECT_OP(< , val1, val2) 132*08ab5237SOystein Eftevaag #define EXPECT_GE(val1, val2) EXPECT_OP(>=, val1, val2) 133*08ab5237SOystein Eftevaag #define EXPECT_GT(val1, val2) EXPECT_OP(> , val1, val2) 134*08ab5237SOystein Eftevaag #define EXPECT_FALSE(cond) EXPECT_TRUE(!(cond)) 135*08ab5237SOystein Eftevaag 136*08ab5237SOystein Eftevaag // C99 declares isnan and isinf should be macros, so the #ifdef test 137*08ab5237SOystein Eftevaag // should be reliable everywhere. Of course, it's not, but these 138*08ab5237SOystein Eftevaag // are testing pertty marginal functionality anyway, so it's ok to 139*08ab5237SOystein Eftevaag // not-run them even in situations they might, with effort, be made to work. 140*08ab5237SOystein Eftevaag #ifdef isnan // Some compilers, like sun's for Solaris 10, don't define this 141*08ab5237SOystein Eftevaag #define EXPECT_NAN(arg) \ 142*08ab5237SOystein Eftevaag do { \ 143*08ab5237SOystein Eftevaag if (!isnan(arg)) { \ 144*08ab5237SOystein Eftevaag fprintf(stderr, "Check failed: isnan(%s)\n", #arg); \ 145*08ab5237SOystein Eftevaag exit(1); \ 146*08ab5237SOystein Eftevaag } \ 147*08ab5237SOystein Eftevaag } while (0) 148*08ab5237SOystein Eftevaag #else 149*08ab5237SOystein Eftevaag #define EXPECT_NAN(arg) 150*08ab5237SOystein Eftevaag #endif 151*08ab5237SOystein Eftevaag 152*08ab5237SOystein Eftevaag #ifdef isinf // Some compilers, like sun's for Solaris 10, don't define this 153*08ab5237SOystein Eftevaag #define EXPECT_INF(arg) \ 154*08ab5237SOystein Eftevaag do { \ 155*08ab5237SOystein Eftevaag if (!isinf(arg)) { \ 156*08ab5237SOystein Eftevaag fprintf(stderr, "Check failed: isinf(%s)\n", #arg); \ 157*08ab5237SOystein Eftevaag exit(1); \ 158*08ab5237SOystein Eftevaag } \ 159*08ab5237SOystein Eftevaag } while (0) 160*08ab5237SOystein Eftevaag #else 161*08ab5237SOystein Eftevaag #define EXPECT_INF(arg) 162*08ab5237SOystein Eftevaag #endif 163*08ab5237SOystein Eftevaag 164*08ab5237SOystein Eftevaag #define EXPECT_DOUBLE_EQ(val1, val2) \ 165*08ab5237SOystein Eftevaag do { \ 166*08ab5237SOystein Eftevaag if (((val1) < (val2) - 0.001 || (val1) > (val2) + 0.001)) { \ 167*08ab5237SOystein Eftevaag fprintf(stderr, "Check failed: %s == %s\n", #val1, #val2); \ 168*08ab5237SOystein Eftevaag exit(1); \ 169*08ab5237SOystein Eftevaag } \ 170*08ab5237SOystein Eftevaag } while (0) 171*08ab5237SOystein Eftevaag 172*08ab5237SOystein Eftevaag #define EXPECT_STREQ(val1, val2) \ 173*08ab5237SOystein Eftevaag do { \ 174*08ab5237SOystein Eftevaag if (strcmp((val1), (val2)) != 0) { \ 175*08ab5237SOystein Eftevaag fprintf(stderr, "Check failed: streq(%s, %s)\n", #val1, #val2); \ 176*08ab5237SOystein Eftevaag exit(1); \ 177*08ab5237SOystein Eftevaag } \ 178*08ab5237SOystein Eftevaag } while (0) 179*08ab5237SOystein Eftevaag 180*08ab5237SOystein Eftevaag // Call this in a .cc file where you will later call RUN_ALL_TESTS in main(). 181*08ab5237SOystein Eftevaag #define TEST_INIT \ 182*08ab5237SOystein Eftevaag static std::vector<void (*)()> g_testlist; /* the tests to run */ \ 183*08ab5237SOystein Eftevaag static int RUN_ALL_TESTS() { \ 184*08ab5237SOystein Eftevaag std::vector<void (*)()>::const_iterator it; \ 185*08ab5237SOystein Eftevaag for (it = g_testlist.begin(); it != g_testlist.end(); ++it) { \ 186*08ab5237SOystein Eftevaag (*it)(); /* The test will error-exit if there's a problem. */ \ 187*08ab5237SOystein Eftevaag } \ 188*08ab5237SOystein Eftevaag fprintf(stderr, "\nPassed %d tests\n\nPASS\n", \ 189*08ab5237SOystein Eftevaag static_cast<int>(g_testlist.size())); \ 190*08ab5237SOystein Eftevaag return 0; \ 191*08ab5237SOystein Eftevaag } 192*08ab5237SOystein Eftevaag 193*08ab5237SOystein Eftevaag // Note that this macro uses a FlagSaver to keep tests isolated. 194*08ab5237SOystein Eftevaag #define TEST(a, b) \ 195*08ab5237SOystein Eftevaag struct Test_##a##_##b { \ 196*08ab5237SOystein Eftevaag Test_##a##_##b() { g_testlist.push_back(&Run); } \ 197*08ab5237SOystein Eftevaag static void Run() { \ 198*08ab5237SOystein Eftevaag FlagSaver fs; \ 199*08ab5237SOystein Eftevaag fprintf(stderr, "Running test %s/%s\n", #a, #b); \ 200*08ab5237SOystein Eftevaag RunTest(); \ 201*08ab5237SOystein Eftevaag } \ 202*08ab5237SOystein Eftevaag static void RunTest(); \ 203*08ab5237SOystein Eftevaag }; \ 204*08ab5237SOystein Eftevaag static Test_##a##_##b g_test_##a##_##b; \ 205*08ab5237SOystein Eftevaag void Test_##a##_##b::RunTest() 206*08ab5237SOystein Eftevaag 207*08ab5237SOystein Eftevaag // This is a dummy class that eases the google->opensource transition. 208*08ab5237SOystein Eftevaag namespace testing { 209*08ab5237SOystein Eftevaag class Test {}; 210*08ab5237SOystein Eftevaag } 211*08ab5237SOystein Eftevaag 212*08ab5237SOystein Eftevaag // Call this in a .cc file where you will later call EXPECT_DEATH 213*08ab5237SOystein Eftevaag #define EXPECT_DEATH_INIT \ 214*08ab5237SOystein Eftevaag static bool g_called_exit; \ 215*08ab5237SOystein Eftevaag static void CalledExit(int) { g_called_exit = true; } 216*08ab5237SOystein Eftevaag 217*08ab5237SOystein Eftevaag #define EXPECT_DEATH(fn, msg) \ 218*08ab5237SOystein Eftevaag do { \ 219*08ab5237SOystein Eftevaag g_called_exit = false; \ 220*08ab5237SOystein Eftevaag gflags_exitfunc = &CalledExit; \ 221*08ab5237SOystein Eftevaag fn; \ 222*08ab5237SOystein Eftevaag gflags_exitfunc = &exit; /* set back to its default */ \ 223*08ab5237SOystein Eftevaag if (!g_called_exit) { \ 224*08ab5237SOystein Eftevaag fprintf(stderr, "Function didn't die (%s): %s\n", msg, #fn); \ 225*08ab5237SOystein Eftevaag exit(1); \ 226*08ab5237SOystein Eftevaag } \ 227*08ab5237SOystein Eftevaag } while (0) 228*08ab5237SOystein Eftevaag 229*08ab5237SOystein Eftevaag #define GTEST_HAS_DEATH_TEST 1 230*08ab5237SOystein Eftevaag 231*08ab5237SOystein Eftevaag // -- path routines ---------------------------------------------------------- 232*08ab5237SOystein Eftevaag 233*08ab5237SOystein Eftevaag // Tries to create the directory path as a temp-dir. If it fails, 234*08ab5237SOystein Eftevaag // changes path to some directory it *can* create. 235*08ab5237SOystein Eftevaag #if defined(__MINGW32__) 236*08ab5237SOystein Eftevaag #include <io.h> 237*08ab5237SOystein Eftevaag inline void MakeTmpdir(std::string* path) { 238*08ab5237SOystein Eftevaag if (!path->empty()) { 239*08ab5237SOystein Eftevaag path->append("/gflags_unittest_testdir"); 240*08ab5237SOystein Eftevaag int err = mkdir(path->c_str()); 241*08ab5237SOystein Eftevaag if (err == 0 || errno == EEXIST) return; 242*08ab5237SOystein Eftevaag } 243*08ab5237SOystein Eftevaag // I had trouble creating a directory in /tmp from mingw 244*08ab5237SOystein Eftevaag *path = "./gflags_unittest"; 245*08ab5237SOystein Eftevaag mkdir(path->c_str()); 246*08ab5237SOystein Eftevaag } 247*08ab5237SOystein Eftevaag #elif defined(_MSC_VER) 248*08ab5237SOystein Eftevaag #include <direct.h> 249*08ab5237SOystein Eftevaag inline void MakeTmpdir(std::string* path) { 250*08ab5237SOystein Eftevaag if (!path->empty()) { 251*08ab5237SOystein Eftevaag int err = _mkdir(path->c_str()); 252*08ab5237SOystein Eftevaag if (err == 0 || errno == EEXIST) return; 253*08ab5237SOystein Eftevaag } 254*08ab5237SOystein Eftevaag char tmppath_buffer[1024]; 255*08ab5237SOystein Eftevaag int tmppath_len = GetTempPathA(sizeof(tmppath_buffer), tmppath_buffer); 256*08ab5237SOystein Eftevaag assert(tmppath_len > 0 && tmppath_len < sizeof(tmppath_buffer)); 257*08ab5237SOystein Eftevaag assert(tmppath_buffer[tmppath_len - 1] == '\\'); // API guarantees it 258*08ab5237SOystein Eftevaag *path = std::string(tmppath_buffer) + "gflags_unittest"; 259*08ab5237SOystein Eftevaag _mkdir(path->c_str()); 260*08ab5237SOystein Eftevaag } 261*08ab5237SOystein Eftevaag #else 262*08ab5237SOystein Eftevaag inline void MakeTmpdir(std::string* path) { 263*08ab5237SOystein Eftevaag if (!path->empty()) { 264*08ab5237SOystein Eftevaag int err = mkdir(path->c_str(), 0755); 265*08ab5237SOystein Eftevaag if (err == 0 || errno == EEXIST) return; 266*08ab5237SOystein Eftevaag } 267*08ab5237SOystein Eftevaag mkdir("/tmp/gflags_unittest", 0755); 268*08ab5237SOystein Eftevaag } 269*08ab5237SOystein Eftevaag #endif 270*08ab5237SOystein Eftevaag 271*08ab5237SOystein Eftevaag // -- string routines -------------------------------------------------------- 272*08ab5237SOystein Eftevaag 273*08ab5237SOystein Eftevaag inline void InternalStringPrintf(std::string* output, const char* format, 274*08ab5237SOystein Eftevaag va_list ap) { 275*08ab5237SOystein Eftevaag char space[128]; // try a small buffer and hope it fits 276*08ab5237SOystein Eftevaag 277*08ab5237SOystein Eftevaag // It's possible for methods that use a va_list to invalidate 278*08ab5237SOystein Eftevaag // the data in it upon use. The fix is to make a copy 279*08ab5237SOystein Eftevaag // of the structure before using it and use that copy instead. 280*08ab5237SOystein Eftevaag va_list backup_ap; 281*08ab5237SOystein Eftevaag va_copy(backup_ap, ap); 282*08ab5237SOystein Eftevaag int bytes_written = vsnprintf(space, sizeof(space), format, backup_ap); 283*08ab5237SOystein Eftevaag va_end(backup_ap); 284*08ab5237SOystein Eftevaag 285*08ab5237SOystein Eftevaag if ((bytes_written >= 0) && (static_cast<size_t>(bytes_written) < sizeof(space))) { 286*08ab5237SOystein Eftevaag output->append(space, bytes_written); 287*08ab5237SOystein Eftevaag return; 288*08ab5237SOystein Eftevaag } 289*08ab5237SOystein Eftevaag 290*08ab5237SOystein Eftevaag // Repeatedly increase buffer size until it fits. 291*08ab5237SOystein Eftevaag int length = sizeof(space); 292*08ab5237SOystein Eftevaag while (true) { 293*08ab5237SOystein Eftevaag if (bytes_written < 0) { 294*08ab5237SOystein Eftevaag // Older snprintf() behavior. :-( Just try doubling the buffer size 295*08ab5237SOystein Eftevaag length *= 2; 296*08ab5237SOystein Eftevaag } else { 297*08ab5237SOystein Eftevaag // We need exactly "bytes_written+1" characters 298*08ab5237SOystein Eftevaag length = bytes_written+1; 299*08ab5237SOystein Eftevaag } 300*08ab5237SOystein Eftevaag char* buf = new char[length]; 301*08ab5237SOystein Eftevaag 302*08ab5237SOystein Eftevaag // Restore the va_list before we use it again 303*08ab5237SOystein Eftevaag va_copy(backup_ap, ap); 304*08ab5237SOystein Eftevaag bytes_written = vsnprintf(buf, length, format, backup_ap); 305*08ab5237SOystein Eftevaag va_end(backup_ap); 306*08ab5237SOystein Eftevaag 307*08ab5237SOystein Eftevaag if ((bytes_written >= 0) && (bytes_written < length)) { 308*08ab5237SOystein Eftevaag output->append(buf, bytes_written); 309*08ab5237SOystein Eftevaag delete[] buf; 310*08ab5237SOystein Eftevaag return; 311*08ab5237SOystein Eftevaag } 312*08ab5237SOystein Eftevaag delete[] buf; 313*08ab5237SOystein Eftevaag } 314*08ab5237SOystein Eftevaag } 315*08ab5237SOystein Eftevaag 316*08ab5237SOystein Eftevaag // Clears output before writing to it. 317*08ab5237SOystein Eftevaag inline void SStringPrintf(std::string* output, const char* format, ...) { 318*08ab5237SOystein Eftevaag va_list ap; 319*08ab5237SOystein Eftevaag va_start(ap, format); 320*08ab5237SOystein Eftevaag output->clear(); 321*08ab5237SOystein Eftevaag InternalStringPrintf(output, format, ap); 322*08ab5237SOystein Eftevaag va_end(ap); 323*08ab5237SOystein Eftevaag } 324*08ab5237SOystein Eftevaag 325*08ab5237SOystein Eftevaag inline void StringAppendF(std::string* output, const char* format, ...) { 326*08ab5237SOystein Eftevaag va_list ap; 327*08ab5237SOystein Eftevaag va_start(ap, format); 328*08ab5237SOystein Eftevaag InternalStringPrintf(output, format, ap); 329*08ab5237SOystein Eftevaag va_end(ap); 330*08ab5237SOystein Eftevaag } 331*08ab5237SOystein Eftevaag 332*08ab5237SOystein Eftevaag inline std::string StringPrintf(const char* format, ...) { 333*08ab5237SOystein Eftevaag va_list ap; 334*08ab5237SOystein Eftevaag va_start(ap, format); 335*08ab5237SOystein Eftevaag std::string output; 336*08ab5237SOystein Eftevaag InternalStringPrintf(&output, format, ap); 337*08ab5237SOystein Eftevaag va_end(ap); 338*08ab5237SOystein Eftevaag return output; 339*08ab5237SOystein Eftevaag } 340*08ab5237SOystein Eftevaag 341*08ab5237SOystein Eftevaag inline bool SafeGetEnv(const char *varname, std::string &valstr) 342*08ab5237SOystein Eftevaag { 343*08ab5237SOystein Eftevaag #if defined(_MSC_VER) && _MSC_VER >= 1400 344*08ab5237SOystein Eftevaag char *val; 345*08ab5237SOystein Eftevaag size_t sz; 346*08ab5237SOystein Eftevaag if (_dupenv_s(&val, &sz, varname) != 0 || !val) return false; 347*08ab5237SOystein Eftevaag valstr = val; 348*08ab5237SOystein Eftevaag free(val); 349*08ab5237SOystein Eftevaag #else 350*08ab5237SOystein Eftevaag const char * const val = getenv(varname); 351*08ab5237SOystein Eftevaag if (!val) return false; 352*08ab5237SOystein Eftevaag valstr = val; 353*08ab5237SOystein Eftevaag #endif 354*08ab5237SOystein Eftevaag return true; 355*08ab5237SOystein Eftevaag } 356*08ab5237SOystein Eftevaag 357*08ab5237SOystein Eftevaag inline int SafeFOpen(FILE **fp, const char* fname, const char *mode) 358*08ab5237SOystein Eftevaag { 359*08ab5237SOystein Eftevaag #if defined(_MSC_VER) && _MSC_VER >= 1400 360*08ab5237SOystein Eftevaag return fopen_s(fp, fname, mode); 361*08ab5237SOystein Eftevaag #else 362*08ab5237SOystein Eftevaag assert(fp != NULL); 363*08ab5237SOystein Eftevaag *fp = fopen(fname, mode); 364*08ab5237SOystein Eftevaag // errno only guaranteed to be set on failure 365*08ab5237SOystein Eftevaag return ((*fp == NULL) ? errno : 0); 366*08ab5237SOystein Eftevaag #endif 367*08ab5237SOystein Eftevaag } 368*08ab5237SOystein Eftevaag 369*08ab5237SOystein Eftevaag 370*08ab5237SOystein Eftevaag } // namespace GFLAGS_NAMESPACE 371*08ab5237SOystein Eftevaag 372*08ab5237SOystein Eftevaag 373*08ab5237SOystein Eftevaag #endif // GFLAGS_UTIL_H_ 374