LibreOffice
LibreOffice 6.0 SDK C/C++ API Reference
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  sal_detail_LogLevel level, char const * area, char const * where,
31  char const * message, sal_uInt32 backtraceDepth);
32 
33 extern "C" SAL_DLLPUBLIC sal_Bool SAL_CALL sal_detail_log_report(
34  sal_detail_LogLevel level, char const * area);
35 
36 namespace sal { namespace detail {
37 
38 inline void log(
39  sal_detail_LogLevel level, char const * area, char const * where,
40  std::ostringstream const & stream, sal_uInt32 backtraceDepth)
41 {
42  // An alternative would be to have sal_detail_log take a std::ostringstream
43  // pointer (via a C void pointer); the advantage would be smaller client
44  // code (the ".str().c_str()" part would move into the implementation of
45  // sal_detail_log) and potential for proper support of embedded null
46  // characters within the message, but the disadvantage would be dependence
47  // on the C++ ABI; as a compromise, the ".str().c_str()" part has been moved
48  // to this inline function so that it is potentially only emitted once per
49  // dynamic library:
50  sal_detail_log(level, area, where, stream.str().c_str(), backtraceDepth);
51 }
52 
53 // Special handling of the common case where the message consists of just a
54 // string literal, to produce smaller call-site code:
55 
56 struct StreamStart {};
57 
58 struct StreamString {
59  StreamString(char const * s): string(s) {}
60 
61  char const * string;
62 
63  typedef char Result;
64 };
65 
66 struct StreamIgnore {
67  typedef struct { char a[2]; } Result;
68 };
69 
70 inline StreamString operator <<(
71  SAL_UNUSED_PARAMETER StreamStart const &, char const * s)
72 {
73  return StreamString(s);
74 }
75 
76 template< typename T > inline StreamIgnore operator <<(
77  SAL_UNUSED_PARAMETER StreamStart const &, SAL_UNUSED_PARAMETER T const &)
78 {
79  std::abort();
80 #if defined _MSC_VER && _MSC_VER < 1700
81  return StreamIgnore();
82 #endif
83 }
84 
85 template< typename T > inline StreamIgnore operator <<(
86  SAL_UNUSED_PARAMETER StreamString const &, SAL_UNUSED_PARAMETER T const &)
87 {
88  std::abort();
89 #if defined _MSC_VER && _MSC_VER < 1700
90  return StreamIgnore();
91 #endif
92 }
93 
94 template< typename T > inline StreamIgnore operator <<(
95  SAL_UNUSED_PARAMETER StreamIgnore const &, SAL_UNUSED_PARAMETER T const &)
96 {
97  std::abort();
98 #if defined _MSC_VER && _MSC_VER < 1700
99  return StreamIgnore();
100 #endif
101 }
102 
103 template< typename T > typename T::Result getResult(T const &);
104 
105 inline char const * unwrapStream(StreamString const & s) { return s.string; }
106 
107 inline char const * unwrapStream(SAL_UNUSED_PARAMETER StreamIgnore const &) {
108  std::abort();
109 #if defined _MSC_VER && _MSC_VER < 1700
110  return 0;
111 #endif
112 }
113 
114 } }
115 
116 #define SAL_DETAIL_LOG_STREAM(condition, level, area, where, stream) \
117  do { \
118  if ((condition) && sal_detail_log_report(level, area)) { \
119  if (sizeof ::sal::detail::getResult( \
120  ::sal::detail::StreamStart() << stream) == 1) \
121  { \
122  ::sal_detail_log( \
123  (level), (area), (where), \
124  ::sal::detail::unwrapStream( \
125  ::sal::detail::StreamStart() << stream), \
126  0); \
127  } else { \
128  ::std::ostringstream sal_detail_stream; \
129  sal_detail_stream << stream; \
130  ::sal::detail::log( \
131  (level), (area), (where), sal_detail_stream, 0); \
132  } \
133  } \
134  } while (false)
135 
137 
148 #define SAL_WHERE SAL_DETAIL_WHERE
149 
164 #ifdef _LIBCPP_VERSION
165 #define SAL_STREAM(stream) \
166  (::std::ostringstream() << stream).str()
167 #else
168 #define SAL_STREAM(stream) \
169  (dynamic_cast< ::std::ostringstream & >(::std::ostringstream() << stream).str())
170 #endif
171 
297 #define SAL_INFO(area, stream) \
298  SAL_DETAIL_LOG_STREAM( \
299  SAL_DETAIL_ENABLE_LOG_INFO, ::SAL_DETAIL_LOG_LEVEL_INFO, area, \
300  SAL_WHERE, stream)
301 
307 #define SAL_INFO_IF(condition, area, stream) \
308  SAL_DETAIL_LOG_STREAM( \
309  SAL_DETAIL_ENABLE_LOG_INFO && (condition), \
310  ::SAL_DETAIL_LOG_LEVEL_INFO, area, SAL_WHERE, stream)
311 
317 #define SAL_WARN(area, stream) \
318  SAL_DETAIL_LOG_STREAM( \
319  SAL_DETAIL_ENABLE_LOG_WARN, ::SAL_DETAIL_LOG_LEVEL_WARN, area, \
320  SAL_WHERE, stream)
321 
327 #define SAL_WARN_IF(condition, area, stream) \
328  SAL_DETAIL_LOG_STREAM( \
329  SAL_DETAIL_ENABLE_LOG_WARN && (condition), \
330  ::SAL_DETAIL_LOG_LEVEL_WARN, area, SAL_WHERE, stream)
331 
338 #define SAL_DEBUG(stream) \
339  SAL_DETAIL_LOG_STREAM( \
340  SAL_LOG_TRUE, ::SAL_DETAIL_LOG_LEVEL_DEBUG, NULL, NULL, stream)
341 
354 #define SAL_DEBUG_BACKTRACE(stream, backtraceDepth) \
355  do { \
356  if (sizeof ::sal::detail::getResult( \
357  ::sal::detail::StreamStart() << stream) == 1) \
358  { \
359  ::sal_detail_log( \
360  ::SAL_DETAIL_LOG_LEVEL_DEBUG, NULL, NULL, \
361  ::sal::detail::unwrapStream( \
362  ::sal::detail::StreamStart() << stream), \
363  backtraceDepth); \
364  } else { \
365  ::std::ostringstream sal_detail_stream; \
366  sal_detail_stream << stream; \
367  ::sal::detail::log( \
368  ::SAL_DETAIL_LOG_LEVEL_DEBUG, NULL, NULL, sal_detail_stream, \
369  backtraceDepth); \
370  } \
371  } while (false)
372 
373 
374 
375 #endif
376 
377 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
std::basic_ostream< charT, traits > & operator<<(std::basic_ostream< charT, traits > &stream, OString const &rString)
Support for rtl::OString in std::ostream (and thus in CPPUNIT_ASSERT or SAL_INFO macros, for example).
Definition: string.hxx:1892
#define SAL_DLLPUBLIC
Definition: saldllapi.h:30
Definition: types.h:444
unsigned char sal_Bool
Definition: types.h:39
#define SAL_UNUSED_PARAMETER
Annotate unused but required C++ function parameters.
Definition: types.h:587