xref: /aosp_15_r20/external/gflags/src/util.h (revision 08ab5237c114d5c0eac1090c56f941d3f639d7d3)
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