1917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein// Copyright (c) 2011, Google Inc.
2917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein// All rights reserved.
3917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein//
4917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein// Redistribution and use in source and binary forms, with or without
5917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein// modification, are permitted provided that the following conditions are
6917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein// met:
7917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein//
8917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein//     * Redistributions of source code must retain the above copyright
9917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein// notice, this list of conditions and the following disclaimer.
10917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein//     * Redistributions in binary form must reproduce the above
11917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein// copyright notice, this list of conditions and the following disclaimer
12917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein// in the documentation and/or other materials provided with the
13917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein// distribution.
14917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein//     * Neither the name of Google Inc. nor the names of its
15917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein// contributors may be used to endorse or promote products derived from
16917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein// this software without specific prior written permission.
17917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein//
18917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein// ---
30917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein//
31917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein// Some generically useful utility routines that in google-land would
32917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein// be their own projects.  We make a shortened version here.
33917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein
34917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein#ifndef GFLAGS_UTIL_H_
35917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein#define GFLAGS_UTIL_H_
36917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein
37f7e89ba9ea82ed2a79413b7c323bca79ac26c747Andreas Schuh#include "config.h"
38f7e89ba9ea82ed2a79413b7c323bca79ac26c747Andreas Schuh
39917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein#include <assert.h>
408566bcf1ebc6ededd78b91eda6889c403d1f9905Andreas Schuh#ifdef HAVE_INTTYPES_H
41392eb67dbf63cb96317eaef9d3370a824d7c4adeAndreas Schuh#  include <inttypes.h>
42917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein#endif
43917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein#include <stdarg.h>     // for va_*
44917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein#include <stdlib.h>
45917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein#include <stdio.h>
46917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein#include <iostream>
47917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein#include <string>
48e491f0161def9f347f13c2f421017b971aa9fd30Andreas Schuh#include <errno.h>
498566bcf1ebc6ededd78b91eda6889c403d1f9905Andreas Schuh#ifdef HAVE_SYS_STAT_H
508477f3174eb9d2cf4e43af222c7bbb6dfd006827Andreas Schuh#  include <sys/stat.h> // for mkdir
518477f3174eb9d2cf4e43af222c7bbb6dfd006827Andreas Schuh#endif
52917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein
53392eb67dbf63cb96317eaef9d3370a824d7c4adeAndreas Schuh
54392eb67dbf63cb96317eaef9d3370a824d7c4adeAndreas Schuhnamespace GFLAGS_NAMESPACE {
55392eb67dbf63cb96317eaef9d3370a824d7c4adeAndreas Schuh
56917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein
57917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein// This is used for unittests for death-testing.  It is defined in gflags.cc.
58917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silversteinextern GFLAGS_DLL_DECL void (*gflags_exitfunc)(int);
59917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein
60acb460af9e66d83401341d9af04984ce53eed0f0Andreas Schuh// Work properly if either strtoll or strtoq is on this system.
61acb460af9e66d83401341d9af04984ce53eed0f0Andreas Schuh#if defined(strtoll) || defined(HAVE_STRTOLL)
62392eb67dbf63cb96317eaef9d3370a824d7c4adeAndreas Schuh#  define strto64  strtoll
638477f3174eb9d2cf4e43af222c7bbb6dfd006827Andreas Schuh#  define strtou64 strtoull
648566bcf1ebc6ededd78b91eda6889c403d1f9905Andreas Schuh#elif defined(HAVE_STRTOQ)
65392eb67dbf63cb96317eaef9d3370a824d7c4adeAndreas Schuh#  define strto64  strtoq
668477f3174eb9d2cf4e43af222c7bbb6dfd006827Andreas Schuh#  define strtou64 strtouq
67917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein// Neither strtoll nor strtoq are defined.  I hope strtol works!
68eeb4db3234ecde76bd8351da9ad6318f3d40545eAndreas Schuh#else
698477f3174eb9d2cf4e43af222c7bbb6dfd006827Andreas Schuh#  define strto64  strtol
70392eb67dbf63cb96317eaef9d3370a824d7c4adeAndreas Schuh#  define strtou64 strtoul
71917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein#endif
72917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein
738477f3174eb9d2cf4e43af222c7bbb6dfd006827Andreas Schuh// If we have inttypes.h, it will have defined PRId32/etc for us.
748477f3174eb9d2cf4e43af222c7bbb6dfd006827Andreas Schuh// If not, take our best guess.
75917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein#ifndef PRId32
76392eb67dbf63cb96317eaef9d3370a824d7c4adeAndreas Schuh#  define PRId32 "d"
77917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein#endif
78917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein#ifndef PRId64
79392eb67dbf63cb96317eaef9d3370a824d7c4adeAndreas Schuh#  define PRId64 "lld"
80917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein#endif
81917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein#ifndef PRIu64
82392eb67dbf63cb96317eaef9d3370a824d7c4adeAndreas Schuh#  define PRIu64 "llu"
83917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein#endif
84917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein
85917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silversteintypedef signed char int8;
86917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silversteintypedef unsigned char uint8;
87917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein
88917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein// -- utility macros ---------------------------------------------------------
89917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein
909db828953a1047c95bf5fb780c3c1f9453f806ebAndreas Schuhtemplate <bool b> struct CompileAssert;
919db828953a1047c95bf5fb780c3c1f9453f806ebAndreas Schuhtemplate <> struct CompileAssert<true> {};
92917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein#define COMPILE_ASSERT(expr, msg) \
939db828953a1047c95bf5fb780c3c1f9453f806ebAndreas Schuh  enum { assert_##msg = sizeof(CompileAssert<bool(expr)>) }
94917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein
95917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein// Returns the number of elements in an array.
96917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein#define arraysize(arr) (sizeof(arr)/sizeof(*(arr)))
97917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein
98917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein
99917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein// -- logging and testing ---------------------------------------------------
100917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein
101917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein// For now, we ignore the level for logging, and don't show *VLOG's at
102917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein// all, except by hand-editing the lines below
103917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein#define LOG(level)    std::cerr
104917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein#define VLOG(level)   if (true) {} else std::cerr
105917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein#define DVLOG(level)  if (true) {} else std::cerr
106917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein
107917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein// CHECK dies with a fatal error if condition is not true.  It is *not*
108917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein// controlled by NDEBUG, so the check will be executed regardless of
109917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein// compilation mode.  Therefore, it is safe to do things like:
110917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein//    CHECK(fp->Write(x) == 4)
111917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein// We allow stream-like objects after this for debugging, but they're ignored.
112917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein#define EXPECT_TRUE(condition)                                  \
113917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein  if (true) {                                                   \
114917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein    if (!(condition)) {                                         \
115917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein      fprintf(stderr, "Check failed: %s\n", #condition);        \
116917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein      exit(1);                                                  \
117917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein    }                                                           \
118917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein  } else std::cerr << ""
119917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein
120917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein#define EXPECT_OP(op, val1, val2)                                       \
121917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein  if (true) {                                                           \
122917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein    if (!((val1) op (val2))) {                                          \
123917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein      fprintf(stderr, "Check failed: %s %s %s\n", #val1, #op, #val2);   \
124917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein      exit(1);                                                          \
125917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein    }                                                                   \
126917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein  } else std::cerr << ""
127917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein
128917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein#define EXPECT_EQ(val1, val2) EXPECT_OP(==, val1, val2)
129917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein#define EXPECT_NE(val1, val2) EXPECT_OP(!=, val1, val2)
130917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein#define EXPECT_LE(val1, val2) EXPECT_OP(<=, val1, val2)
131917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein#define EXPECT_LT(val1, val2) EXPECT_OP(< , val1, val2)
132917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein#define EXPECT_GE(val1, val2) EXPECT_OP(>=, val1, val2)
133917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein#define EXPECT_GT(val1, val2) EXPECT_OP(> , val1, val2)
134917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein#define EXPECT_FALSE(cond)    EXPECT_TRUE(!(cond))
135917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein
136917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein// C99 declares isnan and isinf should be macros, so the #ifdef test
137917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein// should be reliable everywhere.  Of course, it's not, but these
138917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein// are testing pertty marginal functionality anyway, so it's ok to
139917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein// not-run them even in situations they might, with effort, be made to work.
140917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein#ifdef isnan  // Some compilers, like sun's for Solaris 10, don't define this
141917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein#define EXPECT_NAN(arg)                                         \
142917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein  do {                                                          \
143917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein    if (!isnan(arg)) {                                          \
144917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein      fprintf(stderr, "Check failed: isnan(%s)\n", #arg);       \
145917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein      exit(1);                                                  \
146917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein    }                                                           \
147917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein  } while (0)
148917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein#else
149917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein#define EXPECT_NAN(arg)
150917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein#endif
151917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein
152917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein#ifdef isinf  // Some compilers, like sun's for Solaris 10, don't define this
153917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein#define EXPECT_INF(arg)                                         \
154917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein  do {                                                          \
155917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein    if (!isinf(arg)) {                                          \
156917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein      fprintf(stderr, "Check failed: isinf(%s)\n", #arg);       \
157917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein      exit(1);                                                  \
158917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein    }                                                           \
159917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein  } while (0)
160917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein#else
161917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein#define EXPECT_INF(arg)
162917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein#endif
163917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein
164917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein#define EXPECT_DOUBLE_EQ(val1, val2)                                    \
165917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein  do {                                                                  \
166917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein    if (((val1) < (val2) - 0.001 || (val1) > (val2) + 0.001)) {         \
167917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein      fprintf(stderr, "Check failed: %s == %s\n", #val1, #val2);        \
168917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein      exit(1);                                                          \
169917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein    }                                                                   \
170917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein  } while (0)
171917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein
172917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein#define EXPECT_STREQ(val1, val2)                                        \
173917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein  do {                                                                  \
174917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein    if (strcmp((val1), (val2)) != 0) {                                  \
175917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein      fprintf(stderr, "Check failed: streq(%s, %s)\n", #val1, #val2);   \
176917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein      exit(1);                                                          \
177917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein    }                                                                   \
178917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein  } while (0)
179917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein
180917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein// Call this in a .cc file where you will later call RUN_ALL_TESTS in main().
181917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein#define TEST_INIT                                                       \
182917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein  static std::vector<void (*)()> g_testlist;  /* the tests to run */    \
183917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein  static int RUN_ALL_TESTS() {                                          \
184917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein    std::vector<void (*)()>::const_iterator it;                         \
185917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein    for (it = g_testlist.begin(); it != g_testlist.end(); ++it) {       \
186917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein      (*it)();   /* The test will error-exit if there's a problem. */   \
187917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein    }                                                                   \
188917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein    fprintf(stderr, "\nPassed %d tests\n\nPASS\n",                      \
189917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein            static_cast<int>(g_testlist.size()));                       \
190917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein    return 0;                                                           \
191917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein  }
192917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein
193917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein// Note that this macro uses a FlagSaver to keep tests isolated.
194917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein#define TEST(a, b)                                      \
195917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein  struct Test_##a##_##b {                               \
196917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein    Test_##a##_##b() { g_testlist.push_back(&Run); }    \
197917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein    static void Run() {                                 \
198917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein      FlagSaver fs;                                     \
199917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein      fprintf(stderr, "Running test %s/%s\n", #a, #b);  \
200917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein      RunTest();                                        \
201917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein    }                                                   \
202917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein    static void RunTest();                              \
203917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein  };                                                    \
204917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein  static Test_##a##_##b g_test_##a##_##b;               \
205917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein  void Test_##a##_##b::RunTest()
206917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein
207917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein// This is a dummy class that eases the google->opensource transition.
208917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silversteinnamespace testing {
209917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silversteinclass Test {};
210917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein}
211917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein
212917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein// Call this in a .cc file where you will later call EXPECT_DEATH
213917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein#define EXPECT_DEATH_INIT                               \
214917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein  static bool g_called_exit;                            \
215917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein  static void CalledExit(int) { g_called_exit = true; }
216917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein
217917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein#define EXPECT_DEATH(fn, msg)                                           \
218917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein  do {                                                                  \
219917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein    g_called_exit = false;                                              \
220917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein    gflags_exitfunc = &CalledExit;                            \
221917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein    fn;                                                                 \
222917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein    gflags_exitfunc = &exit;    /* set back to its default */ \
223917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein    if (!g_called_exit) {                                               \
224917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein      fprintf(stderr, "Function didn't die (%s): %s\n", msg, #fn);      \
225917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein      exit(1);                                                          \
226917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein    }                                                                   \
227917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein  } while (0)
228917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein
229917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein#define GTEST_HAS_DEATH_TEST 1
230917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein
231917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein// -- path routines ----------------------------------------------------------
232917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein
233917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein// Tries to create the directory path as a temp-dir.  If it fails,
234917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein// changes path to some directory it *can* create.
235917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein#if defined(__MINGW32__)
236357b3d9d0b6dccbfd56ae0a466494f6c2da21901Craig Silverstein#include <io.h>
237357b3d9d0b6dccbfd56ae0a466494f6c2da21901Craig Silversteininline void MakeTmpdir(std::string* path) {
238a0dca4df0c53ded97018098313eb9fda50a92690Andreas Schuh  if (!path->empty()) {
239a0dca4df0c53ded97018098313eb9fda50a92690Andreas Schuh	path->append("/gflags_unittest_testdir");
240a0dca4df0c53ded97018098313eb9fda50a92690Andreas Schuh	int err = mkdir(path->c_str());
241a0dca4df0c53ded97018098313eb9fda50a92690Andreas Schuh	if (err == 0 || errno == EEXIST) return;
242a0dca4df0c53ded97018098313eb9fda50a92690Andreas Schuh  }
243917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein  // I had trouble creating a directory in /tmp from mingw
244a0dca4df0c53ded97018098313eb9fda50a92690Andreas Schuh  *path = "./gflags_unittest";
245a0dca4df0c53ded97018098313eb9fda50a92690Andreas Schuh  mkdir(path->c_str());
246357b3d9d0b6dccbfd56ae0a466494f6c2da21901Craig Silverstein}
247917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein#elif defined(_MSC_VER)
248357b3d9d0b6dccbfd56ae0a466494f6c2da21901Craig Silverstein#include <direct.h>
249357b3d9d0b6dccbfd56ae0a466494f6c2da21901Craig Silversteininline void MakeTmpdir(std::string* path) {
250a0dca4df0c53ded97018098313eb9fda50a92690Andreas Schuh  if (!path->empty()) {
251a0dca4df0c53ded97018098313eb9fda50a92690Andreas Schuh	int err = _mkdir(path->c_str());
252a0dca4df0c53ded97018098313eb9fda50a92690Andreas Schuh	if (err == 0 || errno == EEXIST) return;
253a0dca4df0c53ded97018098313eb9fda50a92690Andreas Schuh  }
254917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein  char tmppath_buffer[1024];
255917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein  int tmppath_len = GetTempPathA(sizeof(tmppath_buffer), tmppath_buffer);
256917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein  assert(tmppath_len > 0 && tmppath_len < sizeof(tmppath_buffer));
257917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein  assert(tmppath_buffer[tmppath_len - 1] == '\\');   // API guarantees it
258a0dca4df0c53ded97018098313eb9fda50a92690Andreas Schuh  *path = std::string(tmppath_buffer) + "gflags_unittest";
259917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein  _mkdir(path->c_str());
260357b3d9d0b6dccbfd56ae0a466494f6c2da21901Craig Silverstein}
261917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein#else
262357b3d9d0b6dccbfd56ae0a466494f6c2da21901Craig Silversteininline void MakeTmpdir(std::string* path) {
263a0dca4df0c53ded97018098313eb9fda50a92690Andreas Schuh  if (!path->empty()) {
264a0dca4df0c53ded97018098313eb9fda50a92690Andreas Schuh	int err = mkdir(path->c_str(), 0755);
265a0dca4df0c53ded97018098313eb9fda50a92690Andreas Schuh	if (err == 0 || errno == EEXIST) return;
266a0dca4df0c53ded97018098313eb9fda50a92690Andreas Schuh  }
267a0dca4df0c53ded97018098313eb9fda50a92690Andreas Schuh  mkdir("/tmp/gflags_unittest", 0755);
268917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein}
269357b3d9d0b6dccbfd56ae0a466494f6c2da21901Craig Silverstein#endif
270917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein
271917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein// -- string routines --------------------------------------------------------
272917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein
273917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silversteininline void InternalStringPrintf(std::string* output, const char* format,
274917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein                                 va_list ap) {
275917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein  char space[128];    // try a small buffer and hope it fits
276917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein
277917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein  // It's possible for methods that use a va_list to invalidate
278917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein  // the data in it upon use.  The fix is to make a copy
279917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein  // of the structure before using it and use that copy instead.
280917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein  va_list backup_ap;
281917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein  va_copy(backup_ap, ap);
282917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein  int bytes_written = vsnprintf(space, sizeof(space), format, backup_ap);
283917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein  va_end(backup_ap);
284917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein
2858011f612470309955d357679324937e369096589Andreas Schuh  if ((bytes_written >= 0) && (static_cast<size_t>(bytes_written) < sizeof(space))) {
286917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein    output->append(space, bytes_written);
287917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein    return;
288917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein  }
289917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein
290917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein  // Repeatedly increase buffer size until it fits.
291917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein  int length = sizeof(space);
292917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein  while (true) {
293917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein    if (bytes_written < 0) {
294917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein      // Older snprintf() behavior. :-(  Just try doubling the buffer size
295917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein      length *= 2;
296917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein    } else {
297917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein      // We need exactly "bytes_written+1" characters
298917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein      length = bytes_written+1;
299917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein    }
300917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein    char* buf = new char[length];
301917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein
302917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein    // Restore the va_list before we use it again
303917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein    va_copy(backup_ap, ap);
304917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein    bytes_written = vsnprintf(buf, length, format, backup_ap);
305917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein    va_end(backup_ap);
306917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein
307917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein    if ((bytes_written >= 0) && (bytes_written < length)) {
308beb69a876be85f28ccb203d2ec7afcb91a9d2173Craig Silverstein      output->append(buf, bytes_written);
309917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein      delete[] buf;
310917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein      return;
311917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein    }
312917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein    delete[] buf;
313917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein  }
314917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein}
315917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein
316917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein// Clears output before writing to it.
317917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silversteininline void SStringPrintf(std::string* output, const char* format, ...) {
318917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein  va_list ap;
319917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein  va_start(ap, format);
320917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein  output->clear();
321917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein  InternalStringPrintf(output, format, ap);
322917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein  va_end(ap);
323917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein}
324917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein
325917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silversteininline void StringAppendF(std::string* output, const char* format, ...) {
326917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein  va_list ap;
327917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein  va_start(ap, format);
328917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein  InternalStringPrintf(output, format, ap);
329917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein  va_end(ap);
330917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein}
331917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein
332917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silversteininline std::string StringPrintf(const char* format, ...) {
333917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein  va_list ap;
334917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein  va_start(ap, format);
335917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein  std::string output;
336917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein  InternalStringPrintf(&output, format, ap);
337917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein  va_end(ap);
338917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein  return output;
339917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein}
340917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein
3418d3797cd15371328c8e0fc5f71060fb9ad4e40c7Andreas Schuhinline bool SafeGetEnv(const char *varname, std::string &valstr)
3428d3797cd15371328c8e0fc5f71060fb9ad4e40c7Andreas Schuh{
3438d3797cd15371328c8e0fc5f71060fb9ad4e40c7Andreas Schuh#if defined(_MSC_VER) && _MSC_VER >= 1400
3448d3797cd15371328c8e0fc5f71060fb9ad4e40c7Andreas Schuh	char  *val;
3458d3797cd15371328c8e0fc5f71060fb9ad4e40c7Andreas Schuh	size_t sz;
3468d3797cd15371328c8e0fc5f71060fb9ad4e40c7Andreas Schuh	if (_dupenv_s(&val, &sz, varname) != 0 || !val) return false;
3478d3797cd15371328c8e0fc5f71060fb9ad4e40c7Andreas Schuh	valstr = val;
3488d3797cd15371328c8e0fc5f71060fb9ad4e40c7Andreas Schuh	free(val);
3498d3797cd15371328c8e0fc5f71060fb9ad4e40c7Andreas Schuh#else
3508d3797cd15371328c8e0fc5f71060fb9ad4e40c7Andreas Schuh	const char * const val = getenv(varname);
3518d3797cd15371328c8e0fc5f71060fb9ad4e40c7Andreas Schuh	if (!val) return false;
3528d3797cd15371328c8e0fc5f71060fb9ad4e40c7Andreas Schuh	valstr = val;
3538d3797cd15371328c8e0fc5f71060fb9ad4e40c7Andreas Schuh#endif
3548d3797cd15371328c8e0fc5f71060fb9ad4e40c7Andreas Schuh	return true;
3558d3797cd15371328c8e0fc5f71060fb9ad4e40c7Andreas Schuh}
3568d3797cd15371328c8e0fc5f71060fb9ad4e40c7Andreas Schuh
357e491f0161def9f347f13c2f421017b971aa9fd30Andreas Schuhinline int SafeFOpen(FILE **fp, const char* fname, const char *mode)
3588d3797cd15371328c8e0fc5f71060fb9ad4e40c7Andreas Schuh{
3598d3797cd15371328c8e0fc5f71060fb9ad4e40c7Andreas Schuh#if defined(_MSC_VER) && _MSC_VER >= 1400
3608d3797cd15371328c8e0fc5f71060fb9ad4e40c7Andreas Schuh	return fopen_s(fp, fname, mode);
3618d3797cd15371328c8e0fc5f71060fb9ad4e40c7Andreas Schuh#else
3628d3797cd15371328c8e0fc5f71060fb9ad4e40c7Andreas Schuh	assert(fp != NULL);
3638d3797cd15371328c8e0fc5f71060fb9ad4e40c7Andreas Schuh	*fp = fopen(fname, mode);
364d8c6a552aae6c85226a6b918224f30b00fd4799fAndreas Schuh    // errno only guaranteed to be set on failure
365d8c6a552aae6c85226a6b918224f30b00fd4799fAndreas Schuh	return ((*fp == NULL) ? errno : 0);
3668d3797cd15371328c8e0fc5f71060fb9ad4e40c7Andreas Schuh#endif
3678d3797cd15371328c8e0fc5f71060fb9ad4e40c7Andreas Schuh}
3688d3797cd15371328c8e0fc5f71060fb9ad4e40c7Andreas Schuh
369392eb67dbf63cb96317eaef9d3370a824d7c4adeAndreas Schuh
370392eb67dbf63cb96317eaef9d3370a824d7c4adeAndreas Schuh} // namespace GFLAGS_NAMESPACE
371392eb67dbf63cb96317eaef9d3370a824d7c4adeAndreas Schuh
372917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein
373917f4e7bf3c36b4c56a77faca639758d3aca2a92Craig Silverstein#endif  // GFLAGS_UTIL_H_
374