ATLAS Offline Software
Loading...
Searching...
No Matches
MessageCheck.h File Reference

macros for messaging and checking status codes More...

#include "CxxUtils/AthUnlikelyMacros.h"
#include <type_traits>
#include <AsgMessaging/MsgHelpers.h>
#include <AsgMessaging/StatusCode.h>
#include "CxxUtils/checker_macros.h"
#include "CxxUtils/normalizeFunctionName.h"
#include <atomic>
Include dependency graph for Control/AthToolSupport/AsgMessaging/AsgMessaging/MessageCheck.h:

Go to the source code of this file.

Classes

struct  asg::CheckHelper< StatusCode >
struct  asg::CheckHelper< int >
struct  asg::CheckHelper< bool >
struct  asg::CheckHelper< T * >

Namespaces

namespace  asg
namespace  asg::detail

Macros

#define ANA_MSG_HEADER(NAME)
 for standalone code this creates a new message category
#define ASG_TOOLS_MSG_STREAM(NAME, TITLE)
#define ANA_MSG_SOURCE(NAME, TITLE)
 the source code part of ANA_MSG_SOURCE
#define MSGSTREAM_FNAME   ""
#define ASG_TOOLS_MSGSTREAM_FNAME   ""
#define ASG_TOOLS_MSGSTREAM_PREFIX    __FILE__ << ":" << __LINE__ << " (" << ASG_TOOLS_MSGSTREAM_FNAME << "): "
 Common prefix for the non-usual messages.
#define ANA_MSG_LVL_SERIOUS(lvl, xmsg)
 Macro used to print "serious" messages.
#define ANA_MSG_LVL_NOCHK(lvl, xmsg)
 Macro used to print "regular" messages.
#define ANA_MSG_LVL(lvl, xmsg)
 Macro used to print "protected" messages.
#define ANA_MSG_VERBOSE(xmsg)
 Macro printing verbose messages.
#define ANA_MSG_DEBUG(xmsg)
 Macro printing debug messages.
#define ANA_MSG_INFO(xmsg)
 Macro printing info messages.
#define ANA_MSG_WARNING(xmsg)
 Macro printing warning messages.
#define ANA_MSG_ERROR(xmsg)
 Macro printing error messages.
#define ANA_MSG_FATAL(xmsg)
 Macro printing fatal messages.
#define ANA_MSG_ALWAYS(xmsg)
 Macro printing messages that should always appear.
#define ANA_CHECK_SET_TYPE(TYPE)
 set the type for ANA_CHECK to report failures
#define ANA_CHECK(EXP)
 check whether the given expression was successful
#define ANA_CHECK_THROW(EXP)
 check whether the given expression was successful, throwing an exception on failure

Typedefs

typedef StatusCode AsgToolsCheckResultType
 the return type used by ANA_CHECK

Functions

void asg::detail::throw_check_fail (const std::string &str)
 throw an error for a failed check

Detailed Description

macros for messaging and checking status codes

Author
Nils Krumnack

The core of this file is the macro ANA_CHECK. With it, a simple main might look like this:

int main ()
{
using namespace asg::msgUserCode;
return 0;
}
#define ANA_CHECK(EXP)
check whether the given expression was successful
#define ANA_CHECK_SET_TYPE(TYPE)
set the type for ANA_CHECK to report failures
int main()
Definition hello.cxx:18
StatusCode Init(const char *appname)
Function initialising ROOT/PyROOT for using the ATLAS EDM.
Definition Init.cxx:31

For the most part ANA_CHECK works just like ATH_CHECK, except it works for any kind of status code (and other things like bool). By default it will return a regular StatusCode object, but you can make it return a different type by specifying ANA_CHECK_SET_TYPE at the beginning of the function. In the example I use it to return an int instead.

Unfortunately the example will compile without that line, but it will not work as expected, i.e. when you return StatusCode::FAILURE it will convert to a value of 0, which the shell interprets as success. There is very little I can do about that from my side, as that is the intrinsic behavior of StatusCode itself. So it is very important that you remember to put that line in.

If you have a function that needs to indicate failure, but can't do so via a status code (e.g. a constructor) you can use the macro ANA_CHECK_THROW, which will throw an exception instead. However, where possible a status code is preferred.

If this is actually a unit test and you already had the chance to update it to GoogleTest, then there are also macros ASSERT_SUCCESS, ASSERT_FAILURE, EXPECT_SUCCESS and EXPECT_FAILURE defined that integrate with the GoogleTest reporting system.

The other thing needed in the above example is the using namespace line. This makes the standard messaging macros available in functions that are not member functions of a tool. Or almost: It works fine in RootCore, but for dual-use code you need to use ANA_MSG_* instead of ATH_MSG_* for sending messages yourself.

The msgUserCode category I used here is meant for things like main functions, etc. If you want to use this for other standalone functions you may consider making your own category (or indeed several). For that you put in one of your headers the line:

ANA_MSG_HEADER (msgMyCategory)
#define ANA_MSG_HEADER(NAME)
for standalone code this creates a new message category

and then in one of the source files:

ANA_MSG_SOURCE (msgMyCategory, "MyCategory")
#define ANA_MSG_SOURCE(NAME, TITLE)
the source code part of ANA_MSG_SOURCE

That way users get the chosen label as part of the messages. Plus they can actually set the message level separately for each category.

Definition in file Control/AthToolSupport/AsgMessaging/AsgMessaging/MessageCheck.h.

Macro Definition Documentation

◆ ANA_CHECK

#define ANA_CHECK ( EXP)
Value:
{ const auto sc__ = EXP; \
typedef typename std::decay<decltype(sc__)>::type scType__; \
ANA_MSG_ERROR ("Failed to call \"" << #EXP << "\""); \
return ::asg::CheckHelper<AsgToolsCheckResultType>::failureCode(); \
} }
#define ATH_UNLIKELY(x)
this is an internal traits class for status codes used by the ANA_CHECK* macros

check whether the given expression was successful

This works like ATH_CHECK except it can handle all kinds of status codes, not just the regular ones. In particular the user can also set the type of the status code returned via ANA_CHECK_SET_TYPE

Definition at line 324 of file Control/AthToolSupport/AsgMessaging/AsgMessaging/MessageCheck.h.

324#define ANA_CHECK(EXP) \
325 { const auto sc__ = EXP; \
326 typedef typename std::decay<decltype(sc__)>::type scType__; \
327 if (ATH_UNLIKELY(!::asg::CheckHelper<scType__>::isSuccess (sc__))) { \
328 ANA_MSG_ERROR ("Failed to call \"" << #EXP << "\""); \
329 return ::asg::CheckHelper<AsgToolsCheckResultType>::failureCode(); \
330 } }

◆ ANA_CHECK_SET_TYPE

#define ANA_CHECK_SET_TYPE ( TYPE)
Value:
StatusCode AsgToolsCheckResultType
the return type used by ANA_CHECK
#define TYPE(CODE, TYP, IOTYP)

set the type for ANA_CHECK to report failures

normally ANA_CHECK will report failures via a StatusCode object, but this macro can be called inside a function to tell it to report via a different type.

Definition at line 314 of file Control/AthToolSupport/AsgMessaging/AsgMessaging/MessageCheck.h.

314#define ANA_CHECK_SET_TYPE(TYPE) \
315 typedef TYPE AsgToolsCheckResultType;

◆ ANA_CHECK_THROW

#define ANA_CHECK_THROW ( EXP)
Value:
{ const auto sc__ = EXP; \
typedef typename std::decay<decltype(sc__)>::type scType__; \
std::ostringstream str; \
str << #EXP; \
ANA_MSG_ERROR ("Failed to call \"" << str.str() << "\", throwing exception"); \
::asg::detail::throw_check_fail (str.str()); \
} }

check whether the given expression was successful, throwing an exception on failure

This works like ANA_CHECK except it throws when an error occurs. This is meant for situations in which we perform a check inside a function that does not return a StatusCode.

Definition at line 339 of file Control/AthToolSupport/AsgMessaging/AsgMessaging/MessageCheck.h.

339#define ANA_CHECK_THROW(EXP) \
340 { const auto sc__ = EXP; \
341 typedef typename std::decay<decltype(sc__)>::type scType__; \
342 if (ATH_UNLIKELY(!::asg::CheckHelper<scType__>::isSuccess (sc__))) { \
343 std::ostringstream str; \
344 str << #EXP; \
345 ANA_MSG_ERROR ("Failed to call \"" << str.str() << "\", throwing exception"); \
346 ::asg::detail::throw_check_fail (str.str()); \
347 } }

◆ ANA_MSG_ALWAYS

#define ANA_MSG_ALWAYS ( xmsg)
Value:
ANA_MSG_LVL_NOCHK( MSG::ALWAYS, xmsg )
#define ANA_MSG_LVL_NOCHK(lvl, xmsg)
Macro used to print "regular" messages.

Macro printing messages that should always appear.

Definition at line 298 of file Control/AthToolSupport/AsgMessaging/AsgMessaging/MessageCheck.h.

◆ ANA_MSG_DEBUG

#define ANA_MSG_DEBUG ( xmsg)
Value:
ANA_MSG_LVL( MSG::DEBUG, xmsg )
#define ANA_MSG_LVL(lvl, xmsg)
Macro used to print "protected" messages.

Macro printing debug messages.

Definition at line 288 of file Control/AthToolSupport/AsgMessaging/AsgMessaging/MessageCheck.h.

◆ ANA_MSG_ERROR

#define ANA_MSG_ERROR ( xmsg)
Value:
ANA_MSG_LVL_SERIOUS( MSG::ERROR, xmsg )
#define ANA_MSG_LVL_SERIOUS(lvl, xmsg)
Macro used to print "serious" messages.

Macro printing error messages.

Definition at line 294 of file Control/AthToolSupport/AsgMessaging/AsgMessaging/MessageCheck.h.

◆ ANA_MSG_FATAL

#define ANA_MSG_FATAL ( xmsg)
Value:
ANA_MSG_LVL_SERIOUS( MSG::FATAL, xmsg )

Macro printing fatal messages.

Definition at line 296 of file Control/AthToolSupport/AsgMessaging/AsgMessaging/MessageCheck.h.

◆ ANA_MSG_HEADER

#define ANA_MSG_HEADER ( NAME)
Value:
namespace NAME { \
MsgStream& msg (); \
MsgStream& msg (MSG::Level level); \
bool msgLvl (MSG::Level lvl); \
void setMsgLevel (MSG::Level level); }
MsgStream & msg
Definition testRead.cxx:32

for standalone code this creates a new message category

The idea is that this provides a way to use the "standard" messaging macros in code that doesn't inherit from AsgTools. All you have to do is put

using namespace NAME;

at the beginning of a function and then you can use the messaging macros as if you were inside an AsgTool.

Or almost, in RootCore this works just fine, but in Athena ATH_MSG_* is defined slightly differently so that this won't work. To that end we are providing ANA_MSG_* macros that work with this, and in both RootCore and Athena. This way you can also use ATH_CHECK/ANA_CHECK in your code.

Besides allowing to use the standard messaging macros, you can also set the message level similar to how you'd do it for an AsgTool:

NAME::setMsgLevel (MSG::DEBUG);
See also
ANA_MSG_SOURCE

Definition at line 113 of file Control/AthToolSupport/AsgMessaging/AsgMessaging/MessageCheck.h.

113#define ANA_MSG_HEADER(NAME) \
114 namespace NAME { \
115 MsgStream& msg (); \
116 MsgStream& msg (MSG::Level level); \
117 bool msgLvl (MSG::Level lvl); \
118 void setMsgLevel (MSG::Level level); }

◆ ANA_MSG_INFO

#define ANA_MSG_INFO ( xmsg)
Value:
ANA_MSG_LVL_NOCHK( MSG::INFO, xmsg )

Macro printing info messages.

Definition at line 290 of file Control/AthToolSupport/AsgMessaging/AsgMessaging/MessageCheck.h.

◆ ANA_MSG_LVL

#define ANA_MSG_LVL ( lvl,
xmsg )
Value:
do { \
if( msg().level() <= lvl ) { \
ANA_MSG_LVL_NOCHK( lvl, xmsg ); \
} \
} while( 0 )

Macro used to print "protected" messages.

Definition at line 278 of file Control/AthToolSupport/AsgMessaging/AsgMessaging/MessageCheck.h.

278#define ANA_MSG_LVL( lvl, xmsg ) \
279 do { \
280 if( msg().level() <= lvl ) { \
281 ANA_MSG_LVL_NOCHK( lvl, xmsg ); \
282 } \
283 } while( 0 )

◆ ANA_MSG_LVL_NOCHK

#define ANA_MSG_LVL_NOCHK ( lvl,
xmsg )
Value:
msg( lvl ) << xmsg << endmsg
#define endmsg

Macro used to print "regular" messages.

Definition at line 274 of file Control/AthToolSupport/AsgMessaging/AsgMessaging/MessageCheck.h.

274#define ANA_MSG_LVL_NOCHK( lvl, xmsg ) \
275 msg( lvl ) << xmsg << endmsg

◆ ANA_MSG_LVL_SERIOUS

#define ANA_MSG_LVL_SERIOUS ( lvl,
xmsg )
Value:
msg( lvl ) << ASG_TOOLS_MSGSTREAM_PREFIX << xmsg << endmsg
#define ASG_TOOLS_MSGSTREAM_PREFIX
Common prefix for the non-usual messages.

Macro used to print "serious" messages.

Definition at line 270 of file Control/AthToolSupport/AsgMessaging/AsgMessaging/MessageCheck.h.

270#define ANA_MSG_LVL_SERIOUS( lvl, xmsg ) \
271 msg( lvl ) << ASG_TOOLS_MSGSTREAM_PREFIX << xmsg << endmsg

◆ ANA_MSG_SOURCE

#define ANA_MSG_SOURCE ( NAME,
TITLE )
Value:
namespace NAME \
{ \
MsgStream& msg () \
{ \
ASG_TOOLS_MSG_STREAM (result, TITLE); \
return result; \
} \
\
MsgStream& msg (MSG::Level level) \
{ \
return msg() << level; \
} \
\
bool msgLvl (MSG::Level lvl) \
{ \
if (msg().level() <= lvl) \
{ \
msg() << lvl; \
return true; \
} else \
{ \
return false; \
} \
} \
\
void setMsgLevel (MSG::Level level) \
{ \
::asg::MsgHelpers::setPkgMsgLevel (TITLE, level); \
} \
}

the source code part of ANA_MSG_SOURCE

For every message category that you introduce via ANA_MSG_SOURCE you have to add this in one of your source files, to add the source code needed for its function implementations

Definition at line 133 of file Control/AthToolSupport/AsgMessaging/AsgMessaging/MessageCheck.h.

133#define ANA_MSG_SOURCE(NAME,TITLE) \
134 namespace NAME \
135 { \
136 MsgStream& msg () \
137 { \
138 ASG_TOOLS_MSG_STREAM (result, TITLE); \
139 return result; \
140 } \
141 \
142 MsgStream& msg (MSG::Level level) \
143 { \
144 return msg() << level; \
145 } \
146 \
147 bool msgLvl (MSG::Level lvl) \
148 { \
149 if (msg().level() <= lvl) \
150 { \
151 msg() << lvl; \
152 return true; \
153 } else \
154 { \
155 return false; \
156 } \
157 } \
158 \
159 void setMsgLevel (MSG::Level level) \
160 { \
161 ::asg::MsgHelpers::setPkgMsgLevel (TITLE, level); \
162 } \
163 }

◆ ANA_MSG_VERBOSE

#define ANA_MSG_VERBOSE ( xmsg)
Value:
ANA_MSG_LVL( MSG::VERBOSE, xmsg )

Macro printing verbose messages.

Definition at line 286 of file Control/AthToolSupport/AsgMessaging/AsgMessaging/MessageCheck.h.

◆ ANA_MSG_WARNING

#define ANA_MSG_WARNING ( xmsg)
Value:
ANA_MSG_LVL_NOCHK( MSG::WARNING, xmsg )

Macro printing warning messages.

Definition at line 292 of file Control/AthToolSupport/AsgMessaging/AsgMessaging/MessageCheck.h.

◆ ASG_TOOLS_MSG_STREAM

#define ASG_TOOLS_MSG_STREAM ( NAME,
TITLE )
Value:
static thread_local MsgStream NAME {::asg::MsgHelpers::pkgMsgStream (TITLE)};
static MsgStream & pkgMsgStream(const std::string &package)
the message stream for the given package identifier

Definition at line 124 of file Control/AthToolSupport/AsgMessaging/AsgMessaging/MessageCheck.h.

124#define ASG_TOOLS_MSG_STREAM(NAME,TITLE) \
125 static thread_local MsgStream NAME {::asg::MsgHelpers::pkgMsgStream (TITLE)};

◆ ASG_TOOLS_MSGSTREAM_FNAME

#define ASG_TOOLS_MSGSTREAM_FNAME   ""

◆ ASG_TOOLS_MSGSTREAM_PREFIX

#define ASG_TOOLS_MSGSTREAM_PREFIX    __FILE__ << ":" << __LINE__ << " (" << ASG_TOOLS_MSGSTREAM_FNAME << "): "

Common prefix for the non-usual messages.

The idea is that a regular user usually only wants to see DEBUG, INFO and some WARNING messages. So those should be reasonably short. On the other hand serious warnings (ERROR, FATAL) messages should be as precise as possible to make debugging the issue easier.

Definition at line 266 of file Control/AthToolSupport/AsgMessaging/AsgMessaging/MessageCheck.h.

266#define ASG_TOOLS_MSGSTREAM_PREFIX \
267 __FILE__ << ":" << __LINE__ << " (" << ASG_TOOLS_MSGSTREAM_FNAME << "): "

◆ MSGSTREAM_FNAME

#define MSGSTREAM_FNAME   ""

Typedef Documentation

◆ AsgToolsCheckResultType

typedef StatusCode AsgToolsCheckResultType

the return type used by ANA_CHECK

this defaults to the regular StatusCode, but can be overriden via ANA_CHECK_SET_TYPE

Definition at line 306 of file Control/AthToolSupport/AsgMessaging/AsgMessaging/MessageCheck.h.