/
bsls_buildtarget.t.cpp
320 lines (280 loc) · 12.9 KB
/
bsls_buildtarget.t.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
// bsls_buildtarget.t.cpp -*-C++-*-
// N.B. This test driver must manipulate the definitions of the macros
// referenced by the component *before* the component header has a chance to
// act on the macros.
#ifdef BDE_BUILDTARGET_TEST_EXC
# if defined(BDE_BUILD_TARGET_EXC)
# undef BDE_BUILD_TARGET_EXC
# define BDE_BUILD_TARGET_NO_EXC
# else
# define BDE_BUILD_TARGET_EXC
# if defined(BDE_BUILD_TARGET_NO_EXC)
# undef BDE_BUILD_TARGET_NO_EXC
# endif
# endif
#endif
#ifdef BDE_BUILDTARGET_TEST_MT
# if defined(BDE_BUILD_TARGET_MT)
# undef BDE_BUILD_TARGET_MT
# define BDE_BUILD_TARGET_NO_MT
# else
# define BDE_BUILD_TARGET_MT
# if defined(BDE_BUILD_TARGET_NO_MT)
# undef BDE_BUILD_TARGET_NO_MT
# endif
# endif
#endif
#include <bsls_buildtarget.h>
#include <bsls_bsltestutil.h> // for testing only
#include <stdio.h> // 'printf', 'fprintf', 'setbuf'
#include <stdlib.h> // 'atoi'
using namespace BloombergLP;
//=============================================================================
// TEST PLAN
//-----------------------------------------------------------------------------
// The component under test defines two type names, 'bsls::BuildTargetExc' and
// 'bsls::BuildTargetMt', that are used to enforce uniform settings for
// exception support and multi-threading support across all translation units
// in a program. In each translation unit (TU), 'bsls::BuildTargetExc' is
// associated with a certain symbol having external linkage according to
// whether the TU was built with at most one of '-DBDE_BUILD_TARGET_EXC' and
// '-DBDE_BUILD_TARGET_NO_EXC' (perhaps neither). 'bsls::BuildTargetMt' is
// similarly associated with another symbol having external linkage according
// to whether a given TU was built with at most one of '-DBDE_BUILD_TARGET_MT'
// and '-DBDE_BUILD_TARGET_NO_MT' (perhaps neither). The various
// 'DBDE_BUILD_TARGET*' macros operate by sabotaging the link phase of the
// build process unless the macros are defined identically for the compile
// phase of all translation units.
//
// In order to test this component properly, we would have to arrange to link
// the test driver from two object files, each with a different setting for one
// of the macros. Then we would have to observe that the linker fails.
// Neither action is in the scope of a test driver; it requires a
// meta-test-driver test facility that can observe the compilation process.
//
// The solution (a la 'bslstl_map' by Chen He) is to build a test driver that
// *does* link properly if the two macros match the settings with which
// 'bsls_buildtarget.cpp' was built. Then ask the user to manually modify
// the code so that the test driver is compiled with different settings from
// 'bsls_buildtarget.cpp', and observe that the test driver fails to link.
//
// This mechanism can be enforced by creating above-the-line test cases for
// each macro which always fail if the corresponding 'BDE_BUILDTARGET_TEST_*'
// macro is defined. Therefore, there are two possible states if one of the
// macros is defined: the test fails to build (good), or the test builds and
// fails (bad).
//-----------------------------------------------------------------------------
// [ 4] BDE_BUILD_TARGET_MT
// [ 3] BDE_BUILD_TARGET_EXC
// [ 2] bsls::BuildTargetMt::s_isBuildTargetMt
// [ 1] bsls::BuildTargetExc::s_isBuildTargetExc
//-----------------------------------------------------------------------------
// ============================================================================
// STANDARD BDE ASSERT TEST MACRO
// ----------------------------------------------------------------------------
// NOTE: THIS IS A LOW-LEVEL COMPONENT AND MAY NOT USE ANY C++ LIBRARY
// FUNCTIONS, INCLUDING IOSTREAMS.
static int testStatus = 0;
static void aSsErT(int c, const char *s, int i) {
if (c) {
printf("Error " __FILE__ "(%d): %s (failed)\n", i, s);
if (testStatus >= 0 && testStatus <= 100) ++testStatus;
}
}
#define ASSERT BSLS_BSLTESTUTIL_ASSERT
// ============================================================================
// STANDARD BDE LOOP-ASSERT TEST MACROS
// ----------------------------------------------------------------------------
#define LOOP_ASSERT BSLS_BSLTESTUTIL_LOOP_ASSERT
#define LOOP2_ASSERT BSLS_BSLTESTUTIL_LOOP2_ASSERT
#define LOOP3_ASSERT BSLS_BSLTESTUTIL_LOOP3_ASSERT
#define LOOP4_ASSERT BSLS_BSLTESTUTIL_LOOP4_ASSERT
#define LOOP5_ASSERT BSLS_BSLTESTUTIL_LOOP5_ASSERT
#define LOOP6_ASSERT BSLS_BSLTESTUTIL_LOOP6_ASSERT
#define ASSERTV BSLS_BSLTESTUTIL_ASSERTV
// ============================================================================
// SEMI-STANDARD TEST OUTPUT MACROS
// ----------------------------------------------------------------------------
#define Q BSLS_BSLTESTUTIL_Q // Quote identifier literally.
#define P BSLS_BSLTESTUTIL_P // Print identifier and value.
#define P_ BSLS_BSLTESTUTIL_P_ // P(X) without '\n'.
#define T_ BSLS_BSLTESTUTIL_T_ // Print a tab (w/o newline).
#define L_ BSLS_BSLTESTUTIL_L_ // current Line number
//=============================================================================
// GLOBAL TYPEDEFS/CONSTANTS FOR TESTING
//-----------------------------------------------------------------------------
enum { VERBOSE_ARG_NUM = 2, VERY_VERBOSE_ARG_NUM, VERY_VERY_VERBOSE_ARG_NUM };
//=============================================================================
// GLOBAL HELPER FUNCTIONS FOR TESTING
//-----------------------------------------------------------------------------
//=============================================================================
// MAIN PROGRAM
//-----------------------------------------------------------------------------
int main(int argc, char *argv[])
{
int test = argc > 1 ? atoi(argv[1]) : 0;
int verbose = argc > 2;
// int veryVerbose = argc > 3;
// int veryVeryVerbose = argc > 4;
setbuf(stdout, 0); // Use unbuffered output.
printf("TEST " __FILE__ " CASE %d\n", test);
switch (test) { case 0: // Zero is always the leading case.
case 5: {
// --------------------------------------------------------------------
// USAGE EXAMPLE
// Extracted from component header file.
//
// Concerns:
//: 1 The usage example provided in the component header file compiles,
//: links, and runs as shown.
//
// Plan:
//: 1 Incorporate usage example from header into test driver, remove
//: leading comment characters, and replace 'assert' with 'ASSERT'.
//: (C-1)
//
// Testing:
// USAGE EXAMPLE
// --------------------------------------------------------------------
if (verbose) printf("\nUSAGE EXAMPLE"
"\n=============\n");
} break;
case 4: {
// --------------------------------------------------------------------
// MACRO BDE_BUILD_TARGET_MT
//
// Concerns:
//: 1 A program should not link when 'BDE_BUILD_TARGET_MT' is defined
//: in one translation unit and not defined in another.
//:
//: 2 A program should link when 'BDE_BUILD_TARGET_MT' is defined in
//: all translation units or not defined in all translation units.
//
// Plan:
//: 1 Define a macro, 'BDE_BUILDTARGET_TEST_MT', that when defined,
//: will invert the definitions of 'BDE_BUILD_TARGET_MT' and
//: 'BDE_BUILD_TARGET_NO_MT' in this translation unit. Build with
//: '-D BDE_BUILD_TARGET_NO_MT' specified on the command line and
//: observe that 'bsls_buildtarget.t.cpp' fails to link. Perform a
//: negative test of this condition by forcing an assertion failure
//: if 'BDE_BUILD_TARGET_NO_MT' is defined, and allowing the test to
//: pass otherwise. (C-1..2)
//
// Testing:
// BDE_BUILD_TARGET_MT
// --------------------------------------------------------------------
if (verbose) printf("\nMACRO BDE_BUILD_TARGET_MT"
"\n=========================\n");
#ifdef BDE_BUILDTARGET_TEST_MT
ASSERT(0 == "bsls_buildtarget.t.cpp should not build "
"with BDE_BUILDTARGET_TEST_MT");
#endif
} break;
case 3: {
// --------------------------------------------------------------------
// MACRO BDE_BUILD_TARGET_EXC
//
// Concerns:
//: 1 A program should not link when 'BDE_BUILD_TARGET_EXC' is
//: defined in one translation unit and not defined in another.
//:
//: 2 A program should link when 'BDE_BUILD_TARGET_EXC' is defined in
//: all translation units or not defined in all translation units.
//
// Plan:
//: 1 Define a macro, 'BDE_BUILDTARGET_TEST_EXC', that when defined,
//: will invert the definitions of 'BDE_BUILD_TARGET_EXC' and
//: 'BDE_BUILD_TARGET_NO_EXC' in this translation unit. Build with
//: '-D BDE_BUILD_TARGET_NO_EXC' specified on the command line and
//: observe that 'bsls_buildtarget.t.cpp' fails to link. Perform a
//: negative test of this condition by forcing an assertion failure
//: if 'BDE_BUILD_TARGET_NO_EXC' is defined, and allowing the test to
//: pass otherwise. (C-1..2)
//
// Testing:
// BDE_BUILD_TARGET_EXC
// --------------------------------------------------------------------
if (verbose) printf("\nMACRO BDE_BUILD_TARGET_EXC"
"\n==========================\n");
#ifdef BDE_BUILDTARGET_TEST_EXC
ASSERT(0 == "bsls_buildtarget.t.cpp should not build "
"with BDE_BUILDTARGET_TEST_EXC");
#endif
} break;
case 2: {
// --------------------------------------------------------------------
// DATA MEMBER 'bsls::BuildTargetMt::s_isBuildTargetMt'
//
// Concerns:
//: 1 'bsls::BuildTargetMt::s_isBuildTargetMt' should be defined.
//:
//: 2 'bsls::BuildTargetMt::s_isBuildTargetMt == 1' if and only if
//: 'BDE_BUILD_TARGET_MT' is defined.
//
// Plan:
//: 1 Manually test the value of
//: 'bsls::BuildTargetMt::s_isBuildTargetMt'. (C-1..2)
//
// Testing:
// bsls::BuildTargetMt::s_isBuildTargetMt
// --------------------------------------------------------------------
if (verbose)
printf("\nDATA MEMBER 'bsls::BuildTargetMt::s_isBuildTargetMt'"
"\n====================================================\n");
#ifdef BDE_BUILD_TARGET_MT
ASSERT(1 == bsls::BuildTargetMt::s_isBuildTargetMt);
#else
ASSERT(0 == bsls::BuildTargetMt::s_isBuildTargetMt);
#endif
} break;
case 1: {
// --------------------------------------------------------------------
// DATA MEMBER 'bsls::BuildTargetExc::s_isBuildTargetExc'
//
// Concerns:
//: 1 'bsls::BuildTargetExc::s_isBuildTargetExc' should be defined.
//:
//: 2 'bsls::BuildTargetExc::s_isBuildTargetExc == 1' if and only if
//: 'BDE_BUILD_TARGET_EXC' is defined.
//
// Plan:
//: 1 Manually test the value of
//: 'bsls::BuildTargetExc::s_isBuildTargetExc'. (C-1..2)
//
// Testing:
// bsls::BuildTargetExc::s_isBuildTargetExc
// --------------------------------------------------------------------
if (verbose)
printf("\nDATA MEMBER 'bsls::BuildTargetExc::s_isBuildTargetExc'"
"\n======================================================\n");
#ifdef BDE_BUILD_TARGET_EXC
ASSERT(1 == bsls::BuildTargetExc::s_isBuildTargetExc);
#else
ASSERT(0 == bsls::BuildTargetExc::s_isBuildTargetExc);
#endif
} break;
default: {
fprintf(stderr, "WARNING: CASE `%d' NOT FOUND.\n", test);
testStatus = -1;
}
}
if (testStatus > 0) {
fprintf(stderr, "Error, non-zero test status = %d.\n", testStatus);
}
return testStatus;
}
// ----------------------------------------------------------------------------
// Copyright 2013 Bloomberg Finance L.P.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ----------------------------- END-OF-FILE ----------------------------------