LibreOffice
LibreOffice 5.0 SDK C/C++ API Reference
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
log.hxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  */
9 
10 #ifndef INCLUDED_SAL_LOG_HXX
11 #define INCLUDED_SAL_LOG_HXX
12 
13 #include <sal/config.h>
14 
15 #include <cstdlib>
16 #include <sstream>
17 #include <string>
18 
19 #include <sal/detail/log.h>
20 #include <sal/saldllapi.h>
21 #include <sal/types.h>
22 
23 // Avoid the use of other sal code in this header as much as possible, so that
24 // this code can be called from other sal code without causing endless
25 // recursion.
26 
28 
29 extern "C" SAL_DLLPUBLIC void SAL_CALL sal_detail_log(
30  enum sal_detail_LogLevel level, char const * area, char const * where,
31  char const * message);
32 
33 namespace sal { namespace detail {
34 
35 inline void SAL_CALL log(
36  sal_detail_LogLevel level, char const * area, char const * where,
37  std::ostringstream const & stream)
38 {
39  // An alternative would be to have sal_detail_log take a std::ostringstream
40  // pointer (via a C void pointer); the advantage would be smaller client
41  // code (the ".str().c_str()" part would move into the implementation of
42  // sal_detail_log) and potential for proper support of embedded null
43  // characters within the message, but the disadvantage would be dependence
44  // on the C++ ABI; as a compromise, the ".str().c_str()" part has been moved
45  // to this inline function so that it is potentially only emitted once per
46  // dynamic library:
47  sal_detail_log(level, area, where, stream.str().c_str());
48 }
49 
50 // Special handling of the common case where the message consists of just a
51 // string literal, to produce smaller call-site code:
52 
53 struct StreamStart {};
54 
55 struct StreamString {
56  StreamString(char const * s): string(s) {}
57 
58  char const * string;
59 
60  typedef char Result;
61 };
62 
63 struct StreamIgnore {
64  typedef struct { char a[2]; } Result;
65 };
66 
67 inline StreamString operator <<(
68  SAL_UNUSED_PARAMETER StreamStart const &, char const * s)
69 {
70  return StreamString(s);
71 }
72 
73 template< typename T > inline StreamIgnore operator <<(
74  SAL_UNUSED_PARAMETER StreamStart const &, SAL_UNUSED_PARAMETER T const &)
75 {
76  std::abort();
77 }
78 
79 template< typename T > inline StreamIgnore operator <<(
80  SAL_UNUSED_PARAMETER StreamString const &, SAL_UNUSED_PARAMETER T const &)
81 {
82  std::abort();
83 }
84 
85 template< typename T > inline StreamIgnore operator <<(
86  SAL_UNUSED_PARAMETER StreamIgnore const &, SAL_UNUSED_PARAMETER T const &)
87 {
88  std::abort();
89 }
90 
91 template< typename T > typename T::Result getResult(T const &);
92 
93 inline char const * unwrapStream(StreamString const & s) { return s.string; }
94 
95 inline char const * unwrapStream(SAL_UNUSED_PARAMETER StreamIgnore const &) {
96  std::abort();
97 }
98 
99 } }
100 
101 #define SAL_DETAIL_LOG_STREAM(condition, level, area, where, stream) \
102  do { \
103  if (condition) { \
104  if (sizeof ::sal::detail::getResult( \
105  ::sal::detail::StreamStart() << stream) == 1) \
106  { \
107  ::sal_detail_log( \
108  (level), (area), (where), \
109  ::sal::detail::unwrapStream( \
110  ::sal::detail::StreamStart() << stream)); \
111  } else { \
112  ::std::ostringstream sal_detail_stream; \
113  sal_detail_stream << stream; \
114  ::sal::detail::log( \
115  (level), (area), (where), sal_detail_stream); \
116  } \
117  } \
118  } while (false)
119 
121 
132 #define SAL_WHERE SAL_DETAIL_WHERE
133 
148 #ifdef _LIBCPP_VERSION
149 #define SAL_STREAM(stream) \
150  (::std::ostringstream() << stream).str()
151 #else
152 #define SAL_STREAM(stream) \
153  (dynamic_cast< ::std::ostringstream & >(::std::ostringstream() << stream).str())
154 #endif
155 
262 #define SAL_INFO(area, stream) \
263  SAL_DETAIL_LOG_STREAM( \
264  SAL_DETAIL_ENABLE_LOG_INFO, ::SAL_DETAIL_LOG_LEVEL_INFO, area, \
265  SAL_WHERE, stream)
266 
272 #define SAL_INFO_IF(condition, area, stream) \
273  SAL_DETAIL_LOG_STREAM( \
274  SAL_DETAIL_ENABLE_LOG_INFO && (condition), \
275  ::SAL_DETAIL_LOG_LEVEL_INFO, area, SAL_WHERE, stream)
276 
282 #define SAL_WARN(area, stream) \
283  SAL_DETAIL_LOG_STREAM( \
284  SAL_DETAIL_ENABLE_LOG_WARN, ::SAL_DETAIL_LOG_LEVEL_WARN, area, \
285  SAL_WHERE, stream)
286 
292 #define SAL_WARN_IF(condition, area, stream) \
293  SAL_DETAIL_LOG_STREAM( \
294  SAL_DETAIL_ENABLE_LOG_WARN && (condition), \
295  ::SAL_DETAIL_LOG_LEVEL_WARN, area, SAL_WHERE, stream)
296 
303 #define SAL_DEBUG(stream) \
304  SAL_DETAIL_LOG_STREAM( \
305  SAL_LOG_TRUE, ::SAL_DETAIL_LOG_LEVEL_DEBUG, 0, 0, stream)
306 
307 #endif
308 
309 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
#define SAL_DLLPUBLIC
Definition: saldllapi.h:30
std::basic_ostream< charT, traits > & operator<<(std::basic_ostream< charT, traits > &stream, OString const &string)
Support for rtl::OString in std::ostream (and thus in CPPUNIT_ASSERT or SAL_INFO macros, for example).
Definition: string.hxx:1733
#define SAL_UNUSED_PARAMETER
Annotate unused but required C++ function parameters.
Definition: types.h:587
Definition: types.h:446