blob: 2d9f1db632dcdda0cb72a9aa24858faa0199e518 [file] [log] [blame]
Brian Silverman70325d62015-09-20 17:00:43 -04001// Copyright (c) 2011, Google Inc.
2// All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without
5// modification, are permitted provided that the following conditions are
6// met:
7//
8// * Redistributions of source code must retain the above copyright
9// notice, this list of conditions and the following disclaimer.
10// * Redistributions in binary form must reproduce the above
11// copyright notice, this list of conditions and the following disclaimer
12// in the documentation and/or other materials provided with the
13// distribution.
14// * Neither the name of Google Inc. nor the names of its
15// contributors may be used to endorse or promote products derived from
16// this software without specific prior written permission.
17//
18// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29// ---
30//
31// Some generically useful utility routines that in google-land would
32// be their own projects. We make a shortened version here.
33
34#ifndef TEMPLATE_UTIL_H_
35#define TEMPLATE_UTIL_H_
36
37#include <config.h>
38#include <ctype.h>
39#include <errno.h>
40#include <stdlib.h>
41#include <stdio.h>
42#include <string.h>
43#include <iostream>
44#include <string>
45#include <utility>
46#include <vector>
47
48// -- utility macros ---------------------------------------------------------
49
50#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
51 TypeName(const TypeName&); \
52 void operator=(const TypeName&)
53
54// Starting with Visual C++ 2005, WinNT.h includes ARRAYSIZE.
55#if !defined(_MSC_VER) || _MSC_VER < 1400
56#define ARRAYSIZE(a) \
57 ((sizeof(a) / sizeof(*(a))) / \
58 static_cast<size_t>(!(sizeof(a) % sizeof(*(a)))))
59#endif
60
61template<typename To, typename From> // use like this: down_cast<T*>(foo);
62inline To down_cast(From* f) { // so we only accept pointers
63 return static_cast<To>(f);
64}
65
66// -- CHECK macros ---------------------------------------------------------
67
68// CHECK dies with a fatal error if condition is not true. It is *not*
69// controlled by NDEBUG, so the check will be executed regardless of
70// compilation mode. Therefore, it is safe to do things like:
71// CHECK(fp->Write(x) == 4)
72// We allow stream-like objects after this for debugging, but they're ignored.
73#define CHECK(condition) \
74 if (true) { \
75 if (!(condition)) { \
76 fprintf(stderr, "Check failed: %s\n", #condition); \
77 exit(1); \
78 } \
79 } else std::cerr << ""
80
81#define CHECK_OP(op, val1, val2) \
82 if (true) { \
83 if (!((val1) op (val2))) { \
84 fprintf(stderr, "Check failed: %s %s %s\n", #val1, #op, #val2); \
85 exit(1); \
86 } \
87 } else std::cerr << ""
88
89#define CHECK_EQ(val1, val2) CHECK_OP(==, val1, val2)
90#define CHECK_NE(val1, val2) CHECK_OP(!=, val1, val2)
91#define CHECK_LE(val1, val2) CHECK_OP(<=, val1, val2)
92#define CHECK_LT(val1, val2) CHECK_OP(< , val1, val2)
93#define CHECK_GE(val1, val2) CHECK_OP(>=, val1, val2)
94#define CHECK_GT(val1, val2) CHECK_OP(> , val1, val2)
95// Synonyms for CHECK_* that are used in some unittests.
96#define EXPECT_EQ(val1, val2) CHECK_EQ(val1, val2)
97#define EXPECT_NE(val1, val2) CHECK_NE(val1, val2)
98#define EXPECT_LE(val1, val2) CHECK_LE(val1, val2)
99#define EXPECT_LT(val1, val2) CHECK_LT(val1, val2)
100#define EXPECT_GE(val1, val2) CHECK_GE(val1, val2)
101#define EXPECT_GT(val1, val2) CHECK_GT(val1, val2)
102#define EXPECT_TRUE(cond) CHECK(cond)
103#define EXPECT_FALSE(cond) CHECK(!(cond))
104#define EXPECT_STREQ(a, b) CHECK(strcmp(a, b) == 0)
105#define ASSERT_TRUE(cond) EXPECT_TRUE(cond)
106// LOG(FATAL) is an alias for CHECK(FALSE). We define FATAL, but no
107// other value that is reasonable inside LOG(), so the compile will
108// fail if someone tries to use LOG(DEBUG) or the like.
109#define LOG(x) INTERNAL_DO_LOG_ ## x
110#define INTERNAL_DO_LOG_FATAL CHECK(false)
111
112// These are used only in debug mode.
113#ifdef NDEBUG
114#define DCHECK(condition) CHECK(condition)
115#define DCHECK_EQ(val1, val2) CHECK_EQ(val1, val2)
116#define DCHECK_NE(val1, val2) CHECK_NE(val1, val2)
117#define DCHECK_LE(val1, val2) CHECK_LE(val1, val2)
118#define DCHECK_LT(val1, val2) CHECK_LT(val1, val2)
119#define DCHECK_GE(val1, val2) CHECK_GE(val1, val2)
120#define DCHECK_GT(val1, val2) CHECK_GT(val1, val2)
121#else
122#define DCHECK(condition) if (true) {} else std::cerr << ""
123#define DCHECK_EQ(val1, val2) if (true) {} else std::cerr << ""
124#define DCHECK_NE(val1, val2) if (true) {} else std::cerr << ""
125#define DCHECK_LE(val1, val2) if (true) {} else std::cerr << ""
126#define DCHECK_LT(val1, val2) if (true) {} else std::cerr << ""
127#define DCHECK_GE(val1, val2) if (true) {} else std::cerr << ""
128#define DCHECK_GT(val1, val2) if (true) {} else std::cerr << ""
129#endif
130
131#define PCHECK(cond) CHECK(cond) << ": " << strerror(errno)
132#define PFATAL(s) do { perror(s); exit(1); } while (0)
133
134// -- testing-related macros --------------------------------------------------
135
136// Call this in a .cc file where you will later call RUN_ALL_TESTS in main().
137#define TEST_INIT \
138 static std::vector<void (*)()> g_testlist; /* the tests to run */ \
139 static int RUN_ALL_TESTS() { \
140 std::vector<void (*)()>::const_iterator it; \
141 for (it = g_testlist.begin(); it != g_testlist.end(); ++it) { \
142 (*it)(); /* The test will error-exit if there's a problem. */ \
143 } \
144 fprintf(stderr, "\nPassed %d tests\n\nPASS\n", \
145 static_cast<int>(g_testlist.size())); \
146 return 0; \
147 }
148
149#define TEST(a, b) \
150 class Test_##a##_##b { \
151 public: \
152 Test_##a##_##b() { g_testlist.push_back(&Run); } \
153 static void Run(); \
154 }; \
155 static Test_##a##_##b g_test_##a##_##b; \
156 void Test_##a##_##b::Run()
157
158// This is a dummy class that eases the google->opensource transition.
159namespace testing {
160class Test {};
161}
162
163// -- template-related macros ----------------------------------------------
164
165#ifndef DEFAULT_TEMPLATE_ROOTDIR
166# define DEFAULT_TEMPLATE_ROOTDIR "."
167#endif
168
169// -- string-related functions ----------------------------------------------
170
171inline bool safe_strto32(const std::string& s, int* i) {
172 char* error_pos;
173 if (s.empty()) return false; // no input at all
174 errno = 0; // just to be sure
175 *i = strtol(s.c_str(), &error_pos, 10);
176 return *error_pos == '\0' && errno == 0;
177}
178
179inline int atoi32(const char* s) {
180 return atoi(s);
181}
182
183inline void StripWhiteSpace(std::string* str) {
184 int str_length = str->length();
185
186 // Strip off leading whitespace.
187 int first = 0;
188 while (first < str_length && isspace(str->at(first))) {
189 ++first;
190 }
191 // If entire string is white space.
192 if (first == str_length) {
193 str->clear();
194 return;
195 }
196 if (first > 0) {
197 str->erase(0, first);
198 str_length -= first;
199 }
200
201 // Strip off trailing whitespace.
202 int last = str_length - 1;
203 while (last >= 0 && isspace(str->at(last))) {
204 --last;
205 }
206 if (last != (str_length - 1) && last >= 0) {
207 str->erase(last + 1, std::string::npos);
208 }
209}
210
211inline void SplitStringIntoKeyValuePairs(
212 const std::string& s,
213 const char* kv_split, // For instance: "="
214 const char* pair_split, // For instance: ","
215 std::vector< std::pair<std::string, std::string> > *pairs) {
216 std::string key, value;
217 std::string* add_to = &key;
218 for (std::string::size_type i = 0; i < s.length(); ++i) {
219 if (s[i] == kv_split[0]) {
220 add_to = &value;
221 } else if (s[i] == pair_split[0]) {
222 if (!key.empty())
223 pairs->push_back(std::pair<std::string, std::string>(key, value));
224 key.clear();
225 value.clear();
226 add_to = &key;
227 } else {
228 *add_to += s[i];
229 }
230 }
231 if (!key.empty())
232 pairs->push_back(std::pair<std::string, std::string>(key, value));
233}
234
235#endif // TEMPLATE_UTIL_H_