My Project
UDK 3.2.7 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  * Version: MPL 1.1 / GPLv3+ / LGPLv3+
4  *
5  * The contents of this file are subject to the Mozilla Public License Version
6  * 1.1 (the "License"); you may not use this file except in compliance with
7  * the License or as specified alternatively below. You may obtain a copy of
8  * the License at http://www.mozilla.org/MPL/
9  *
10  * Software distributed under the License is distributed on an "AS IS" basis,
11  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12  * for the specific language governing rights and limitations under the
13  * License.
14  *
15  * Major Contributor(s):
16  * Copyright (C) 2011 Red Hat, Inc., Stephan Bergmann <sbergman@redhat.com>
17  * (initial developer)
18  *
19  * All Rights Reserved.
20  *
21  * For minor contributions see the git repository.
22  *
23  * Alternatively, the contents of this file may be used under the terms of
24  * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
25  * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
26  * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
27  * instead of those above.
28  */
29 
30 #ifndef INCLUDED_SAL_LOG_HXX
31 #define INCLUDED_SAL_LOG_HXX
32 
33 #include "sal/config.h"
34 
35 #include <cstdlib>
36 #include <sstream>
37 #include <string>
38 
39 #include "sal/detail/log.h"
40 #include "sal/saldllapi.h"
41 #include "sal/types.h"
42 
43 // Avoid the use of other sal code in this header as much as possible, so that
44 // this code can be called from other sal code without causing endless
45 // recursion.
46 
48 
49 extern "C" SAL_DLLPUBLIC void SAL_CALL sal_detail_log(
50  enum sal_detail_LogLevel level, char const * area, char const * where,
51  char const * message);
52 
53 namespace sal { namespace detail {
54 
55 inline void SAL_CALL log(
56  sal_detail_LogLevel level, char const * area, char const * where,
57  std::ostringstream const & stream)
58 {
59  // An alternative would be to have sal_detail_log take a std::ostringstream
60  // pointer (via a C void pointer); the advantage would be smaller client
61  // code (the ".str().c_str()" part would move into the implementation of
62  // sal_detail_log) and potential for proper support of embedded null
63  // characters within the message, but the disadvantage would be dependence
64  // on the C++ ABI; as a compromise, the ".str().c_str()" part has been moved
65  // to this inline function so that it is potentially only emitted once per
66  // dynamic library:
67  sal_detail_log(level, area, where, stream.str().c_str());
68 }
69 
70 // Special handling of the common case where the message consists of just a
71 // string literal, to produce smaller call-site code:
72 
73 struct StreamStart {};
74 
75 struct StreamString {
76  StreamString(char const * s): string(s) {}
77 
78  char const * string;
79 
80  typedef char Result;
81 };
82 
83 struct StreamIgnore {
84  typedef struct { char a[2]; } Result;
85 };
86 
87 inline StreamString operator <<(
88  SAL_UNUSED_PARAMETER StreamStart const &, char const * s)
89 {
90  return StreamString(s);
91 }
92 
93 template< typename T > inline StreamIgnore operator <<(
94  SAL_UNUSED_PARAMETER StreamStart const &, SAL_UNUSED_PARAMETER T const &)
95 {
96  std::abort();
97 #if defined _MSC_VER && _MSC_VER < 1700
98  return StreamIgnore();
99 #endif
100 }
101 
102 template< typename T > inline StreamIgnore operator <<(
103  SAL_UNUSED_PARAMETER StreamString const &, SAL_UNUSED_PARAMETER T const &)
104 {
105  std::abort();
106 #if defined _MSC_VER && _MSC_VER < 1700
107  return StreamIgnore();
108 #endif
109 }
110 
111 template< typename T > inline StreamIgnore operator <<(
112  SAL_UNUSED_PARAMETER StreamIgnore const &, SAL_UNUSED_PARAMETER T const &)
113 {
114  std::abort();
115 #if defined _MSC_VER && _MSC_VER < 1700
116  return StreamIgnore();
117 #endif
118 }
119 
120 template< typename T > typename T::Result getResult(T const &);
121 
122 inline char const * unwrapStream(StreamString const & s) { return s.string; }
123 
124 inline char const * unwrapStream(SAL_UNUSED_PARAMETER StreamIgnore const &) {
125  std::abort();
126 #if defined _MSC_VER && _MSC_VER < 1700
127  return 0;
128 #endif
129 }
130 
131 } }
132 
133 #define SAL_DETAIL_LOG_STREAM(condition, level, area, where, stream) \
134  do { \
135  if (condition) { \
136  if (sizeof ::sal::detail::getResult( \
137  ::sal::detail::StreamStart() << stream) == 1) \
138  { \
139  ::sal_detail_log( \
140  (level), (area), (where), \
141  ::sal::detail::unwrapStream( \
142  ::sal::detail::StreamStart() << stream)); \
143  } else { \
144  ::std::ostringstream sal_detail_stream; \
145  sal_detail_stream << stream; \
146  ::sal::detail::log( \
147  (level), (area), (where), sal_detail_stream); \
148  } \
149  } \
150  } while (false)
151 
153 
164 #define SAL_WHERE SAL_DETAIL_WHERE
165 
180 #define SAL_STREAM(stream) \
181  (dynamic_cast< ::std::ostringstream & >(::std::ostringstream() << stream). \
182  str())
183 
281 #define SAL_INFO(area, stream) \
282  SAL_DETAIL_LOG_STREAM( \
283  SAL_DETAIL_ENABLE_LOG_INFO, ::SAL_DETAIL_LOG_LEVEL_INFO, area, \
284  SAL_WHERE, stream)
285 
291 #define SAL_INFO_IF(condition, area, stream) \
292  SAL_DETAIL_LOG_STREAM( \
293  SAL_DETAIL_ENABLE_LOG_INFO && (condition), \
294  ::SAL_DETAIL_LOG_LEVEL_INFO, area, SAL_WHERE, stream)
295 
301 #define SAL_WARN(area, stream) \
302  SAL_DETAIL_LOG_STREAM( \
303  SAL_DETAIL_ENABLE_LOG_WARN, ::SAL_DETAIL_LOG_LEVEL_WARN, area, \
304  SAL_WHERE, stream)
305 
311 #define SAL_WARN_IF(condition, area, stream) \
312  SAL_DETAIL_LOG_STREAM( \
313  SAL_DETAIL_ENABLE_LOG_WARN && (condition), \
314  ::SAL_DETAIL_LOG_LEVEL_WARN, area, SAL_WHERE, stream)
315 
322 #define SAL_DEBUG(stream) \
323  SAL_DETAIL_LOG_STREAM( \
324  SAL_LOG_TRUE, ::SAL_DETAIL_LOG_LEVEL_DEBUG, 0, 0, stream)
325 
326 #endif
327 
328 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */