Read-only mirrors. Development, issues and pull requests are on GitHub.

summaryrefslogtreecommitdiffhomepage
path: root/docs/own-main.md
blob: 18d1b7d307c8b2fe4dfc2eb809d64f866362accc (plain)
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
<a id="top"></a>
# Supplying main() yourself

The easiest way to use Catch is to let it supply ```main()``` for you and handle configuring itself from the command line.

This is achieved by writing ```#define CATCH_CONFIG_MAIN``` before the ```#include "catch.hpp"``` in *exactly one* source file.

Sometimes, though, you need to write your own version of main(). You can do this by writing ```#define CATCH_CONFIG_RUNNER``` instead. Now you are free to write ```main()``` as normal and call into Catch yourself manually.

You now have a lot of flexibility - but here are three recipes to get your started:

## Let Catch take full control of args and config

If you just need to have code that executes before and/ or after Catch this is the simplest option.

```c++
#define CATCH_CONFIG_RUNNER
#include "catch.hpp"

int main( int argc, char* argv[] ) {
  // global setup...

  int result = Catch::Session().run( argc, argv );

  // global clean-up...

  return result;
}
```

## Amending the config

If you still want Catch to process the command line, but you want to programatically tweak the config, you can do so in one of two ways:

```c++
#define CATCH_CONFIG_RUNNER
#include "catch.hpp"

int main( int argc, char* argv[] )
{
  Catch::Session session; // There must be exactly one instance
 
  // writing to session.configData() here sets defaults
  // this is the preferred way to set them
    
  int returnCode = session.applyCommandLine( argc, argv );
  if( returnCode != 0 ) // Indicates a command line error
  	  return returnCode;
 
  // writing to session.configData() or session.Config() here 
  // overrides command line args
  // only do this if you know you need to

  int numFailed = session.run();
  
  // numFailed is clamped to 255 as some unices only use the lower 8 bits.
  // This clamping has already been applied, so just return it here
  // You can also do any post run clean-up here
  return numFailed;
}
```

Take a look at the definitions of Config and ConfigData to see what you can do with them.

To take full control of the config simply omit the call to ```applyCommandLine()```.

## Adding your own command line options

Catch embeds a powerful command line parser called [Clara](https://github.com/philsquared/Clara). 
As of Catch2 (and Clara 1.0) Clara allows you to write _composable_ option and argument parsers, 
so extending Catch's own command line options is now easy.

```c++
#define CATCH_CONFIG_RUNNER
#include "catch.hpp"

int main( int argc, char* argv[] )
{
  Catch::Session session; // There must be exactly one instance
  
  int height = 0; // Some user variable you want to be able to set
  
  // Build a new parser on top of Catch's
  using namespace Catch::clara;
  auto cli 
    = session.cli() // Get Catch's composite command line parser
    | Opt( height, "height" ) // bind variable to a new option, with a hint string
        ["-g"]["--height"]    // the option names it will respond to
        ("how high?");        // description string for the help output
        
  // Now pass the new composite back to Catch so it uses that
  session.cli( cli ); 
  
  // Let Catch (using Clara) parse the command line
  int returnCode = session.applyCommandLine( argc, argv );
  if( returnCode != 0 ) // Indicates a command line error
  	return returnCode;

  // if set on the command line then 'height' is now set at this point
  if( height > 0 )
      std::cout << "height: " << height << std::endl;

  return session.run();
}
```

See the [Clara documentation](https://github.com/philsquared/Clara/blob/master/README.md) for more details.


## Version detection

Catch provides a triplet of macros providing the header's version, 

* `CATCH_VERSION_MAJOR`
* `CATCH_VERSION_MINOR`
* `CATCH_VERSION_PATCH`

these macros expand into a single number, that corresponds to the appropriate
part of the version. As an example, given single header version v2.3.4,
the macros would expand into `2`, `3`, and `4` respectively.


---

[Home](Readme.md#top)