LibreOffice: sal/log.hxx Source File

LibreOffice LibreOffice 5.1 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 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
274 #define SAL_INFO(area, stream) \
275 SAL_DETAIL_LOG_STREAM( \
276 SAL_DETAIL_ENABLE_LOG_INFO, ::SAL_DETAIL_LOG_LEVEL_INFO, area, \
277 SAL_WHERE, stream)
278
284 #define SAL_INFO_IF(condition, area, stream) \
285 SAL_DETAIL_LOG_STREAM( \
286 SAL_DETAIL_ENABLE_LOG_INFO && (condition), \
287 ::SAL_DETAIL_LOG_LEVEL_INFO, area, SAL_WHERE, stream)
288
294 #define SAL_WARN(area, stream) \
295 SAL_DETAIL_LOG_STREAM( \
296 SAL_DETAIL_ENABLE_LOG_WARN, ::SAL_DETAIL_LOG_LEVEL_WARN, area, \
297 SAL_WHERE, stream)
298
304 #define SAL_WARN_IF(condition, area, stream) \
305 SAL_DETAIL_LOG_STREAM( \
306 SAL_DETAIL_ENABLE_LOG_WARN && (condition), \
307 ::SAL_DETAIL_LOG_LEVEL_WARN, area, SAL_WHERE, stream)
308
315 #define SAL_DEBUG(stream) \
316 SAL_DETAIL_LOG_STREAM( \
317 SAL_LOG_TRUE, ::SAL_DETAIL_LOG_LEVEL_DEBUG, NULL, NULL, stream)
318
319 #endif
320
321 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
SAL_DLLPUBLIC
#define SAL_DLLPUBLIC
Definition: saldllapi.h:30
SAL_UNUSED_PARAMETER
#define SAL_UNUSED_PARAMETER
Annotate unused but required C++ function parameters.
Definition: types.h:591
sal
Definition: types.h:450
log.h
saldllapi.h
types.h
config.h
rtl::operator<<
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:1858