LibreOffice
LibreOffice 5.3 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 #if defined _MSC_VER && _MSC_VER < 1700
78  return StreamIgnore();
79 #endif
80 }
81 
82 template< typename T > inline StreamIgnore operator <<(
83  SAL_UNUSED_PARAMETER StreamString const &, SAL_UNUSED_PARAMETER T const &)
84 {
85  std::abort();
86 #if defined _MSC_VER && _MSC_VER < 1700
87  return StreamIgnore();
88 #endif
89 }
90 
91 template< typename T > inline StreamIgnore operator <<(
92  SAL_UNUSED_PARAMETER StreamIgnore const &, SAL_UNUSED_PARAMETER T const &)
93 {
94  std::abort();
95 #if defined _MSC_VER && _MSC_VER < 1700
96  return StreamIgnore();
97 #endif
98 }
99 
100 template< typename T > typename T::Result getResult(T const &);
101 
102 inline char const * unwrapStream(StreamString const & s) { return s.string; }
103 
104 inline char const * unwrapStream(SAL_UNUSED_PARAMETER StreamIgnore const &) {
105  std::abort();
106 #if defined _MSC_VER && _MSC_VER < 1700
107  return 0;
108 #endif
109 }
110 
111 } }
112 
113 #define SAL_DETAIL_LOG_STREAM(condition, level, area, where, stream) \
114  do { \
115  if (condition) { \
116  if (sizeof ::sal::detail::getResult( \
117  ::sal::detail::StreamStart() << stream) == 1) \
118  { \
119  ::sal_detail_log( \
120  (level), (area), (where), \
121  ::sal::detail::unwrapStream( \
122  ::sal::detail::StreamStart() << stream)); \
123  } else { \
124  ::std::ostringstream sal_detail_stream; \
125  sal_detail_stream << stream; \
126  ::sal::detail::log( \
127  (level), (area), (where), sal_detail_stream); \
128  } \
129  } \
130  } while (false)
131 
133 
144 #define SAL_WHERE SAL_DETAIL_WHERE
145 
160 #ifdef _LIBCPP_VERSION
161 #define SAL_STREAM(stream) \
162  (::std::ostringstream() << stream).str()
163 #else
164 #define SAL_STREAM(stream) \
165  (dynamic_cast< ::std::ostringstream & >(::std::ostringstream() << stream).str())
166 #endif
167 
293 #define SAL_INFO(area, stream) \
294  SAL_DETAIL_LOG_STREAM( \
295  SAL_DETAIL_ENABLE_LOG_INFO, ::SAL_DETAIL_LOG_LEVEL_INFO, area, \
296  SAL_WHERE, stream)
297 
303 #define SAL_INFO_IF(condition, area, stream) \
304  SAL_DETAIL_LOG_STREAM( \
305  SAL_DETAIL_ENABLE_LOG_INFO && (condition), \
306  ::SAL_DETAIL_LOG_LEVEL_INFO, area, SAL_WHERE, stream)
307 
313 #define SAL_WARN(area, stream) \
314  SAL_DETAIL_LOG_STREAM( \
315  SAL_DETAIL_ENABLE_LOG_WARN, ::SAL_DETAIL_LOG_LEVEL_WARN, area, \
316  SAL_WHERE, stream)
317 
323 #define SAL_WARN_IF(condition, area, stream) \
324  SAL_DETAIL_LOG_STREAM( \
325  SAL_DETAIL_ENABLE_LOG_WARN && (condition), \
326  ::SAL_DETAIL_LOG_LEVEL_WARN, area, SAL_WHERE, stream)
327 
334 #define SAL_DEBUG(stream) \
335  SAL_DETAIL_LOG_STREAM( \
336  SAL_LOG_TRUE, ::SAL_DETAIL_LOG_LEVEL_DEBUG, NULL, NULL, stream)
337 
346 #define SAL_DEBUG_TRACE(stream) \
347  SAL_DETAIL_LOG_STREAM( \
348  SAL_LOG_TRUE, ::SAL_DETAIL_LOG_LEVEL_DEBUG_TRACE, NULL, NULL, stream)
349 
350 #endif
351 
352 /* 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:1894
#define SAL_DLLPUBLIC
Definition: saldllapi.h:30
#define SAL_UNUSED_PARAMETER
Annotate unused but required C++ function parameters.
Definition: types.h:603