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/types.h"
41 
42 // Avoid the use of other sal code in this header as much as possible, so that
43 // this code can be called from other sal code without causing endless
44 // recursion.
45 
47 
48 extern "C" SAL_DLLPUBLIC void SAL_CALL sal_detail_log(
49  enum sal_detail_LogLevel level, char const * area, char const * where,
50  char const * message);
51 
52 namespace sal { namespace detail {
53 
54 inline void SAL_CALL log(
55  sal_detail_LogLevel level, char const * area, char const * where,
56  std::ostringstream const & stream)
57 {
58  // An alternative would be to have sal_detail_log take a std::ostringstream
59  // pointer (via a C void pointer); the advantage would be smaller client
60  // code (the ".str().c_str()" part would move into the implementation of
61  // sal_detail_log) and potential for proper support of embedded null
62  // characters within the message, but the disadvantage would be dependence
63  // on the C++ ABI; as a compromise, the ".str().c_str()" part has been moved
64  // to this inline function so that it is potentially only emitted once per
65  // dynamic library:
66  sal_detail_log(level, area, where, stream.str().c_str());
67 }
68 
69 // Special handling of the common case where the message consists of just a
70 // string literal, to produce smaller call-site code:
71 
72 struct StreamStart {};
73 
74 struct StreamString {
75  StreamString(char const * s): string(s) {}
76 
77  char const * string;
78 
79  typedef char Result;
80 };
81 
82 struct StreamIgnore {
83  typedef struct { char a[2]; } Result;
84 };
85 
86 inline StreamString operator <<(
87  SAL_UNUSED_PARAMETER StreamStart const &, char const * s)
88 {
89  return StreamString(s);
90 }
91 
92 template< typename T > inline StreamIgnore operator <<(
93  SAL_UNUSED_PARAMETER StreamStart const &, SAL_UNUSED_PARAMETER T const &)
94 {
95  std::abort();
96 #if defined _MSC_VER
97  return StreamIgnore();
98 #endif
99 }
100 
101 template< typename T > inline StreamIgnore operator <<(
102  SAL_UNUSED_PARAMETER StreamString const &, SAL_UNUSED_PARAMETER T const &)
103 {
104  std::abort();
105 #if defined _MSC_VER
106  return StreamIgnore();
107 #endif
108 }
109 
110 template< typename T > inline StreamIgnore operator <<(
111  SAL_UNUSED_PARAMETER StreamIgnore const &, SAL_UNUSED_PARAMETER T const &)
112 {
113  std::abort();
114 #if defined _MSC_VER
115  return StreamIgnore();
116 #endif
117 }
118 
119 template< typename T > typename T::Result getResult(T const &);
120 
121 inline char const * unwrapStream(StreamString const & s) { return s.string; }
122 
123 inline char const * unwrapStream(SAL_UNUSED_PARAMETER StreamIgnore const &) {
124  std::abort();
125 #if defined _MSC_VER
126  return 0;
127 #endif
128 }
129 
130 } }
131 
132 #define SAL_DETAIL_LOG_STREAM(condition, level, area, where, stream) \
133  do { \
134  if (condition) { \
135  if (sizeof ::sal::detail::getResult( \
136  ::sal::detail::StreamStart() << stream) == 1) \
137  { \
138  ::sal_detail_log( \
139  (level), (area), (where), \
140  ::sal::detail::unwrapStream( \
141  ::sal::detail::StreamStart() << stream)); \
142  } else { \
143  ::std::ostringstream sal_detail_stream; \
144  sal_detail_stream << stream; \
145  ::sal::detail::log( \
146  (level), (area), (where), sal_detail_stream); \
147  } \
148  } \
149  } while (false)
150 
152 
163 #define SAL_WHERE SAL_DETAIL_WHERE
164 
179 #define SAL_STREAM(stream) \
180  (dynamic_cast< ::std::ostringstream & >(::std::ostringstream() << stream). \
181  str())
182 
280 #define SAL_INFO(area, stream) \
281  SAL_DETAIL_LOG_STREAM( \
282  SAL_DETAIL_ENABLE_LOG_INFO, ::SAL_DETAIL_LOG_LEVEL_INFO, area, \
283  SAL_WHERE, stream)
284 
290 #define SAL_INFO_IF(condition, area, stream) \
291  SAL_DETAIL_LOG_STREAM( \
292  SAL_DETAIL_ENABLE_LOG_INFO && (condition), \
293  ::SAL_DETAIL_LOG_LEVEL_INFO, area, SAL_WHERE, stream)
294 
300 #define SAL_WARN(area, stream) \
301  SAL_DETAIL_LOG_STREAM( \
302  SAL_DETAIL_ENABLE_LOG_WARN, ::SAL_DETAIL_LOG_LEVEL_WARN, area, \
303  SAL_WHERE, stream)
304 
310 #define SAL_WARN_IF(condition, area, stream) \
311  SAL_DETAIL_LOG_STREAM( \
312  SAL_DETAIL_ENABLE_LOG_WARN && (condition), \
313  ::SAL_DETAIL_LOG_LEVEL_WARN, area, SAL_WHERE, stream)
314 
321 #define SAL_DEBUG(stream) \
322  SAL_DETAIL_LOG_STREAM( \
323  SAL_LOG_TRUE, ::SAL_DETAIL_LOG_LEVEL_DEBUG, 0, 0, stream)
324 
325 #endif
326 
327 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */