File Coverage

Catch_xsgen.cc
Criterion Covered Total %
statement 14 15 93.3
branch 7 14 50.0
condition n/a
subroutine n/a
pod n/a
total 21 29 72.4


line stmt bran cond sub pod time code
1             /*
2             * This file was generated automatically by ExtUtils::ParseXS version 3.34 from the
3             * contents of Catch.xs. Do not edit this file, edit Catch.xs instead.
4             *
5             * ANY CHANGES MADE HERE WILL BE LOST!
6             *
7             */
8              
9             #line 1 "Catch.xs"
10             #include // this fixes win32 because that is included by breaks unless previously included
11             #define CATCH_CONFIG_RUNNER
12             #define CATCH_CONFIG_DEFAULT_REPORTER "perl"
13             //#define CATCH_CONFIG_ENABLE_BENCHMARKING
14             #include
15             #include
16             #include
17              
18             using namespace Catch;
19             using namespace std;
20              
21             static Catch::Session session;
22              
23             struct Printer {
24             Printer (ostream& _stream, const AssertionStats& _stats)
25             : stream(_stream), result(_stats.assertionResult), messages(_stats.infoMessages), itMessage(_stats.infoMessages.begin()) {}
26              
27             void print () {
28             itMessage = messages.begin();
29              
30             switch (result.getResultType()) {
31             case ResultWas::Ok:
32             printOriginalExpression();
33             printReconstructedExpression();
34             printRemainingMessages();
35             break;
36             case ResultWas::ExpressionFailed:
37             printOriginalExpression();
38             printReconstructedExpression();
39             if (result.isOk()) printIssue(" # TODO");
40             printRemainingMessages();
41             break;
42             case ResultWas::ThrewException:
43             printIssue("unexpected exception ");
44             printExpressionWas();
45             printRemainingMessages();
46             break;
47             case ResultWas::FatalErrorCondition:
48             printIssue("fatal error condition with message:");
49             printMessage();
50             printExpressionWas();
51             printRemainingMessages();
52             break;
53             case ResultWas::DidntThrowException:
54             printIssue("expected exception, got none");
55             printExpressionWas();
56             printRemainingMessages();
57             break;
58             case ResultWas::Info:
59             stream << "#info";
60             printMessage();
61             printRemainingMessages();
62             break;
63             case ResultWas::Warning:
64             stream << "#warning";
65             printMessage();
66             printRemainingMessages();
67             break;
68             case ResultWas::ExplicitFailure:
69             printIssue("explicitly");
70             printRemainingMessages();
71             break;
72             // These cases are here to prevent compiler warnings
73             case ResultWas::Unknown:
74             case ResultWas::FailureBit:
75             case ResultWas::Exception:
76             stream << "** unsupported ResultWas (should not happenned) **";
77             break;
78             }
79             }
80              
81             private:
82             static inline void expr_replace (string& expr, const string& c, const string& subs) {
83             size_t pos = expr.find(c);
84             while (pos < expr.length()) {
85             expr.replace(pos, c.length(), subs);
86             pos = expr.find(c, pos + subs.length());
87             }
88             }
89            
90             void printIssue (const string& issue) const {
91             stream << " " << issue;
92             }
93              
94             void printExpressionWas () {
95             if (!result.hasExpression()) return;
96             stream << "; expression was:";
97             printOriginalExpression();
98             }
99              
100             void printOriginalExpression () const {
101             if (result.hasExpression()) stream << " " << result.getExpression();
102             }
103            
104             void printReconstructedExpression () const {
105             if (!result.hasExpandedExpression()) return;
106             stream << " for: ";
107             string expr = result.getExpandedExpression();
108             // prevent "str" == "str" splitting into several lines
109             expr_replace(expr, "\"\r\n==\r\n\"", "\" == \"");
110             expr_replace(expr, "\"\n==\n\"", "\" == \"");
111             // replace remaining newlines in text/expressions
112             expr_replace(expr, "\r", "\\r");
113             expr_replace(expr, "\n", "\\n");
114             stream << expr;
115             }
116              
117             void printMessage () {
118             if (itMessage != messages.end()) {
119             stream << " '" << itMessage->message << "'";
120             ++itMessage;
121             }
122             }
123              
124             void printRemainingMessages () {
125             if (itMessage == messages.cend()) return;
126              
127             // using messages.end() directly (or auto) yields compilation error:
128             auto itEnd = messages.cend();
129             const size_t N = static_cast(std::distance(itMessage, itEnd));
130              
131             stream << " with " << pluralise( N, "message" ) << ":";
132              
133             for (; itMessage != itEnd; ++itMessage) {
134             // If this assertion is a warning ignore any INFO messages
135             if (itMessage->type != ResultWas::Info) {
136             stream << "\n# " << itMessage->message;
137             }
138             }
139             }
140              
141             ostream& stream;
142             AssertionResult const& result;
143             vector messages;
144             vector::const_iterator itMessage;
145             };
146              
147              
148             struct PerlReporter : IStreamingReporter {
149             struct Scope {
150             uint32_t count;
151             uint32_t failed;
152             uint32_t depth;
153             string name;
154             string fullname;
155             };
156             static Scope context;
157              
158             static string getDescription () { return "Reports test results in perl test-harness compatible format"; }
159            
160             PerlReporter (const ReporterConfig& _config)
161             : scope(), sliding_scope(), fatal(), config(_config.fullConfig()), stream(_config.stream())
162             {
163             reporterPrefs.shouldRedirectStdOut = false;
164             reporterPrefs.shouldReportAllAssertions = true;
165             }
166            
167             ReporterPreferences getPreferences () const override { return reporterPrefs; }
168              
169             void noMatchingTestCases (const string& spec) override {
170             startErrorLine() << "# No test cases matched '" << spec << "'" << endl;
171             }
172            
173             void skipTest (const TestCaseInfo&) override {}
174            
175             void testRunStarting (const TestRunInfo&) override {
176             scopes.push_back(context);
177             scope = &scopes.back();
178             }
179            
180             void testRunEnded (const TestRunStats&) override {
181             context.count = scope->count;
182             context.failed = scope->failed;
183             scopes.clear();
184             scope = nullptr;
185             }
186            
187             void testGroupStarting (const GroupInfo&) override {}
188             void testGroupEnded (const TestGroupStats&) override {}
189            
190             void testCaseStarting (const TestCaseInfo&) override {}
191            
192             void testCaseEnded (const TestCaseStats&) override {
193             if (fatal) {
194             commitAssertions();
195             sliding_scope = &scopes[1];
196             }
197             commitSlidingScope();
198             }
199            
200             void sectionStarting (const SectionInfo& info) override {
201             if (sliding_scope && sliding_scope->name == info.name) {
202             ++sliding_scope;
203             return;
204             }
205             commitSlidingScope();
206             startScope(info);
207             }
208            
209             void startScope (const SectionInfo& info) {
210             startLine();
211             auto fullname = scope->fullname.length() ? (scope->fullname + " / " + info.name) : info.name;
212             stream << "# Subtest: " << fullname << endl;
213             scopes.push_back({0, 0, scope->depth + 1, info.name, fullname});
214             scope = &scopes.back();
215             }
216            
217             void sectionEnded (const SectionStats&) override {
218             if (fatal) return;
219             if (!sliding_scope) sliding_scope = scope + 1;
220             --sliding_scope;
221             if (sliding_scope == &scopes[1]) commitAssertions();
222             }
223            
224             void commitSlidingScope () {
225             if (!sliding_scope) return;
226             size_t cnt = &scopes.back() - sliding_scope + 1;
227             while (cnt--) closeCurrentScope();
228             sliding_scope = nullptr;
229             }
230            
231             void closeCurrentScope () {
232             auto name = scope->fullname;
233             bool failed = scope->failed;
234             startLine() << "1.." << scope->count << endl;
235             if (scope->failed) {
236             startErrorLine() << "# Looks like you failed " << scope->failed << " test of " << scope->count << " at [" << name << "]." << endl;
237             }
238            
239             scopes.pop_back();
240             if (scopes.empty()) throw "WTF?";
241             scope = &scopes.back();
242            
243             ++scope->count;
244             startLine();
245             if (failed) {
246             ++scope->failed;
247             stream << "not ok";
248             }
249             else stream << "ok";
250             stream << " " << scope->count << " - [" << name << "]" << endl;
251             }
252            
253             ostream& startLine () {
254             for (size_t i = 0; i < scope->depth; ++i) stream << " ";
255             return stream;
256             }
257              
258             ostream& startErrorLine () {
259             for (size_t i = 0; i < scope->depth; ++i) std::cerr << " ";
260             return std::cerr;
261             }
262              
263             void assertionStarting (const AssertionInfo&) override {}
264              
265             bool assertionEnded (const AssertionStats& stats) override {
266             ostringstream s;
267             Printer(s, stats).print();
268             assertions.push_back({stats, s.str()});
269             return true;
270             }
271            
272             void commitAssertions () {
273             for (auto& row : assertions) {
274             auto& stats = row.stats;
275             auto result = stats.assertionResult;
276             // prevent diagnostic messages from counting
277             bool is_test = result.getResultType() != ResultWas::Info && result.getResultType() != ResultWas::Warning;
278            
279             Colour::Code color = Colour::None;
280             ostream& ss = result.succeeded() ? startLine() : startErrorLine();
281            
282             if (is_test) {
283             ++scope->count;
284             if (result.succeeded()) {
285             ss << "ok";
286             } else {
287             ++scope->failed;
288             ss << "not ok";
289             color = Colour::ResultError;
290             }
291             ss << " " << scope->count << " -";
292             }
293            
294             {
295             Colour cg(color); (void)cg;
296             ss << row.expr;
297             ss << " # at " << result.getSourceInfo();
298             }
299            
300             ss << endl;
301            
302             if (is_test && !result.succeeded()) {
303             startErrorLine() << "#\e[1;31m Failed test in section [" << scope->fullname << "] at " << result.getSourceInfo() << "\e[0m" << endl;
304             }
305             }
306             assertions.clear();
307             }
308            
309             void fatalErrorEncountered (StringRef) override {
310             fatal = true;
311             }
312            
313             // void benchmarkPreparing (const std::string& ) override {}
314             // void benchmarkStarting (const BenchmarkInfo& ) override {}
315             // void benchmarkEnded (const BenchmarkStats<>& ) override {}
316             // void benchmarkFailed (const std::string& ) override {}
317              
318             private:
319             struct AData {
320             AssertionStats stats;
321             string expr;
322             };
323            
324             vector scopes;
325             Scope* scope;
326             Scope* sliding_scope;
327             vector assertions;
328             bool fatal;
329             ReporterPreferences reporterPrefs;
330             IConfigPtr config;
331             ostream& stream;
332             };
333              
334             PerlReporter::Scope PerlReporter::context;
335            
336             CATCH_REGISTER_REPORTER("perl", PerlReporter);
337              
338             #line 339 "Catch_xsgen.cc"
339             #ifndef PERL_UNUSED_VAR
340             # define PERL_UNUSED_VAR(var) if (0) var = var
341             #endif
342              
343             #ifndef dVAR
344             # define dVAR dNOOP
345             #endif
346              
347              
348             /* This stuff is not part of the API! You have been warned. */
349             #ifndef PERL_VERSION_DECIMAL
350             # define PERL_VERSION_DECIMAL(r,v,s) (r*1000000 + v*1000 + s)
351             #endif
352             #ifndef PERL_DECIMAL_VERSION
353             # define PERL_DECIMAL_VERSION \
354             PERL_VERSION_DECIMAL(PERL_REVISION,PERL_VERSION,PERL_SUBVERSION)
355             #endif
356             #ifndef PERL_VERSION_GE
357             # define PERL_VERSION_GE(r,v,s) \
358             (PERL_DECIMAL_VERSION >= PERL_VERSION_DECIMAL(r,v,s))
359             #endif
360             #ifndef PERL_VERSION_LE
361             # define PERL_VERSION_LE(r,v,s) \
362             (PERL_DECIMAL_VERSION <= PERL_VERSION_DECIMAL(r,v,s))
363             #endif
364              
365             /* XS_INTERNAL is the explicit static-linkage variant of the default
366             * XS macro.
367             *
368             * XS_EXTERNAL is the same as XS_INTERNAL except it does not include
369             * "STATIC", ie. it exports XSUB symbols. You probably don't want that
370             * for anything but the BOOT XSUB.
371             *
372             * See XSUB.h in core!
373             */
374              
375              
376             /* TODO: This might be compatible further back than 5.10.0. */
377             #if PERL_VERSION_GE(5, 10, 0) && PERL_VERSION_LE(5, 15, 1)
378             # undef XS_EXTERNAL
379             # undef XS_INTERNAL
380             # if defined(__CYGWIN__) && defined(USE_DYNAMIC_LOADING)
381             # define XS_EXTERNAL(name) __declspec(dllexport) XSPROTO(name)
382             # define XS_INTERNAL(name) STATIC XSPROTO(name)
383             # endif
384             # if defined(__SYMBIAN32__)
385             # define XS_EXTERNAL(name) EXPORT_C XSPROTO(name)
386             # define XS_INTERNAL(name) EXPORT_C STATIC XSPROTO(name)
387             # endif
388             # ifndef XS_EXTERNAL
389             # if defined(HASATTRIBUTE_UNUSED) && !defined(__cplusplus)
390             # define XS_EXTERNAL(name) void name(pTHX_ CV* cv __attribute__unused__)
391             # define XS_INTERNAL(name) STATIC void name(pTHX_ CV* cv __attribute__unused__)
392             # else
393             # ifdef __cplusplus
394             # define XS_EXTERNAL(name) extern "C" XSPROTO(name)
395             # define XS_INTERNAL(name) static XSPROTO(name)
396             # else
397             # define XS_EXTERNAL(name) XSPROTO(name)
398             # define XS_INTERNAL(name) STATIC XSPROTO(name)
399             # endif
400             # endif
401             # endif
402             #endif
403              
404             /* perl >= 5.10.0 && perl <= 5.15.1 */
405              
406              
407             /* The XS_EXTERNAL macro is used for functions that must not be static
408             * like the boot XSUB of a module. If perl didn't have an XS_EXTERNAL
409             * macro defined, the best we can do is assume XS is the same.
410             * Dito for XS_INTERNAL.
411             */
412             #ifndef XS_EXTERNAL
413             # define XS_EXTERNAL(name) XS(name)
414             #endif
415             #ifndef XS_INTERNAL
416             # define XS_INTERNAL(name) XS(name)
417             #endif
418              
419             /* Now, finally, after all this mess, we want an ExtUtils::ParseXS
420             * internal macro that we're free to redefine for varying linkage due
421             * to the EXPORT_XSUB_SYMBOLS XS keyword. This is internal, use
422             * XS_EXTERNAL(name) or XS_INTERNAL(name) in your code if you need to!
423             */
424              
425             #undef XS_EUPXS
426             #if defined(PERL_EUPXS_ALWAYS_EXPORT)
427             # define XS_EUPXS(name) XS_EXTERNAL(name)
428             #else
429             /* default to internal */
430             # define XS_EUPXS(name) XS_INTERNAL(name)
431             #endif
432              
433             #ifndef PERL_ARGS_ASSERT_CROAK_XS_USAGE
434             #define PERL_ARGS_ASSERT_CROAK_XS_USAGE assert(cv); assert(params)
435              
436             /* prototype to pass -Wmissing-prototypes */
437             STATIC void
438             S_croak_xs_usage(const CV *const cv, const char *const params);
439              
440             STATIC void
441             S_croak_xs_usage(const CV *const cv, const char *const params)
442             {
443             const GV *const gv = CvGV(cv);
444              
445             PERL_ARGS_ASSERT_CROAK_XS_USAGE;
446              
447             if (gv) {
448             const char *const gvname = GvNAME(gv);
449             const HV *const stash = GvSTASH(gv);
450             const char *const hvname = stash ? HvNAME(stash) : NULL;
451              
452             if (hvname)
453             Perl_croak_nocontext("Usage: %s::%s(%s)", hvname, gvname, params);
454             else
455             Perl_croak_nocontext("Usage: %s(%s)", gvname, params);
456             } else {
457             /* Pants. I don't think that it should be possible to get here. */
458             Perl_croak_nocontext("Usage: CODE(0x%" UVxf ")(%s)", PTR2UV(cv), params);
459             }
460             }
461             #undef PERL_ARGS_ASSERT_CROAK_XS_USAGE
462              
463             #define croak_xs_usage S_croak_xs_usage
464              
465             #endif
466              
467             /* NOTE: the prototype of newXSproto() is different in versions of perls,
468             * so we define a portable version of newXSproto()
469             */
470             #ifdef newXS_flags
471             #define newXSproto_portable(name, c_impl, file, proto) newXS_flags(name, c_impl, file, proto, 0)
472             #else
473             #define newXSproto_portable(name, c_impl, file, proto) (PL_Sv=(SV*)newXS(name, c_impl, file), sv_setpv(PL_Sv, proto), (CV*)PL_Sv)
474             #endif /* !defined(newXS_flags) */
475              
476             #if PERL_VERSION_LE(5, 21, 5)
477             # define newXS_deffile(a,b) Perl_newXS(aTHX_ a,b,file)
478             #else
479             # define newXS_deffile(a,b) Perl_newXS_deffile(aTHX_ a,b)
480             #endif
481              
482             #line 483 "Catch_xsgen.cc"
483              
484              
485 5           XS_EUPXS(XS_Test__Catch__run)
486             {
487 5           dVAR; dXSARGS;
488 5 50         if (items < 3)
489 0           croak_xs_usage(cv, "count, failed, depth, ...");
490             {
491             bool RETVAL;
492 5           SV* count = ST(0)
493             ;
494 5           SV* failed = ST(1)
495             ;
496 5 50         int depth = (int)SvIV(ST(2))
497             ;
498             #line 333 "Catch.xs"
499             int err;
500             {
501             std::vector argv = {"test"};
502              
503             for (int i = 3; i < items; ++i) {
504             SV* arg = ST(i);
505             if (!SvOK(arg)) continue;
506             argv.push_back(SvPV_nolen(arg));
507             }
508              
509             argv.push_back("-i");
510              
511             session.useConfigData({});
512             err = session.applyCommandLine(argv.size(), argv.data());
513             }
514             if (err) croak("session.applyCommandLine: error %d", err);
515              
516             PerlReporter::context.count = SvUV(count);
517             PerlReporter::context.failed = SvUV(failed);
518             PerlReporter::context.depth = depth;
519              
520             RETVAL = session.run() == 0;
521              
522             sv_setuv(count, PerlReporter::context.count);
523             sv_setuv(failed, PerlReporter::context.failed);
524             #line 525 "Catch_xsgen.cc"
525 5 50         ST(0) = boolSV(RETVAL);
526             }
527 5           XSRETURN(1);
528             }
529              
530             #ifdef __cplusplus
531             extern "C"
532             #endif
533              
534 1           XS_EXTERNAL(boot_Test__Catch)
535             {
536             #if PERL_VERSION_LE(5, 21, 5)
537             dVAR; dXSARGS;
538             #else
539 1 50         dVAR; dXSBOOTARGSXSAPIVERCHK;
    50          
540             #endif
541             #if (PERL_REVISION == 5 && PERL_VERSION < 9)
542             char* file = __FILE__;
543             #else
544 1           const char* file = __FILE__;
545             #endif
546              
547             PERL_UNUSED_VAR(file);
548              
549             PERL_UNUSED_VAR(cv); /* -W */
550             PERL_UNUSED_VAR(items); /* -W */
551             #if PERL_VERSION_LE(5, 21, 5)
552             XS_VERSION_BOOTCHECK;
553             # ifdef XS_APIVERSION_BOOTCHECK
554             XS_APIVERSION_BOOTCHECK;
555             # endif
556             #endif
557              
558 1           newXS_deffile("Test::Catch::_run", XS_Test__Catch__run);
559             #if PERL_VERSION_LE(5, 21, 5)
560             # if PERL_VERSION_GE(5, 9, 0)
561             if (PL_unitcheckav)
562             call_list(PL_scopestack_ix, PL_unitcheckav);
563             # endif
564             XSRETURN_YES;
565             #else
566 1           Perl_xs_boot_epilog(aTHX_ ax);
567             #endif
568 4 50         }
    50          
569