UDK 3.2.7 C/C++ API Reference
|
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 00002 /* 00003 * Version: MPL 1.1 / GPLv3+ / LGPLv3+ 00004 * 00005 * The contents of this file are subject to the Mozilla Public License Version 00006 * 1.1 (the "License"); you may not use this file except in compliance with 00007 * the License or as specified alternatively below. You may obtain a copy of 00008 * the License at http://www.mozilla.org/MPL/ 00009 * 00010 * Software distributed under the License is distributed on an "AS IS" basis, 00011 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 00012 * for the specific language governing rights and limitations under the 00013 * License. 00014 * 00015 * Major Contributor(s): 00016 * Copyright (C) 2011 Red Hat, Inc., Stephan Bergmann <sbergman@redhat.com> 00017 * (initial developer) 00018 * 00019 * All Rights Reserved. 00020 * 00021 * For minor contributions see the git repository. 00022 * 00023 * Alternatively, the contents of this file may be used under the terms of 00024 * either the GNU General Public License Version 3 or later (the "GPLv3+"), or 00025 * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"), 00026 * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable 00027 * instead of those above. 00028 */ 00029 00030 #ifndef INCLUDED_SAL_LOG_HXX 00031 #define INCLUDED_SAL_LOG_HXX 00032 00033 #include "sal/config.h" 00034 00035 #include <cstdlib> 00036 #include <sstream> 00037 #include <string> 00038 00039 #include "sal/detail/log.h" 00040 #include "sal/types.h" 00041 00042 // Avoid the use of other sal code in this header as much as possible, so that 00043 // this code can be called from other sal code without causing endless 00044 // recursion. 00045 00047 00048 extern "C" SAL_DLLPUBLIC void SAL_CALL sal_detail_log( 00049 enum sal_detail_LogLevel level, char const * area, char const * where, 00050 char const * message); 00051 00052 namespace sal { namespace detail { 00053 00054 inline void SAL_CALL log( 00055 sal_detail_LogLevel level, char const * area, char const * where, 00056 std::ostringstream const & stream) 00057 { 00058 // An alternative would be to have sal_detail_log take a std::ostringstream 00059 // pointer (via a C void pointer); the advantage would be smaller client 00060 // code (the ".str().c_str()" part would move into the implementation of 00061 // sal_detail_log) and potential for proper support of embedded null 00062 // characters within the message, but the disadvantage would be dependence 00063 // on the C++ ABI; as a compromise, the ".str().c_str()" part has been moved 00064 // to this inline function so that it is potentially only emitted once per 00065 // dynamic library: 00066 sal_detail_log(level, area, where, stream.str().c_str()); 00067 } 00068 00069 // Special handling of the common case where the message consists of just a 00070 // string literal, to produce smaller call-site code: 00071 00072 struct StreamStart {}; 00073 00074 struct StreamString { 00075 StreamString(char const * s): string(s) {} 00076 00077 char const * string; 00078 00079 typedef char Result; 00080 }; 00081 00082 struct StreamIgnore { 00083 typedef struct { char a[2]; } Result; 00084 }; 00085 00086 inline StreamString operator <<( 00087 SAL_UNUSED_PARAMETER StreamStart const &, char const * s) 00088 { 00089 return StreamString(s); 00090 } 00091 00092 template< typename T > inline StreamIgnore operator <<( 00093 SAL_UNUSED_PARAMETER StreamStart const &, SAL_UNUSED_PARAMETER T const &) 00094 { 00095 std::abort(); 00096 #if defined _MSC_VER 00097 return StreamIgnore(); 00098 #endif 00099 } 00100 00101 template< typename T > inline StreamIgnore operator <<( 00102 SAL_UNUSED_PARAMETER StreamString const &, SAL_UNUSED_PARAMETER T const &) 00103 { 00104 std::abort(); 00105 #if defined _MSC_VER 00106 return StreamIgnore(); 00107 #endif 00108 } 00109 00110 template< typename T > inline StreamIgnore operator <<( 00111 SAL_UNUSED_PARAMETER StreamIgnore const &, SAL_UNUSED_PARAMETER T const &) 00112 { 00113 std::abort(); 00114 #if defined _MSC_VER 00115 return StreamIgnore(); 00116 #endif 00117 } 00118 00119 template< typename T > typename T::Result getResult(T const &); 00120 00121 inline char const * unwrapStream(StreamString const & s) { return s.string; } 00122 00123 inline char const * unwrapStream(SAL_UNUSED_PARAMETER StreamIgnore const &) { 00124 std::abort(); 00125 #if defined _MSC_VER 00126 return 0; 00127 #endif 00128 } 00129 00130 } } 00131 00132 #define SAL_DETAIL_LOG_STREAM(condition, level, area, where, stream) \ 00133 do { \ 00134 if (condition) { \ 00135 if (sizeof ::sal::detail::getResult( \ 00136 ::sal::detail::StreamStart() << stream) == 1) \ 00137 { \ 00138 ::sal_detail_log( \ 00139 (level), (area), (where), \ 00140 ::sal::detail::unwrapStream( \ 00141 ::sal::detail::StreamStart() << stream)); \ 00142 } else { \ 00143 ::std::ostringstream sal_detail_stream; \ 00144 sal_detail_stream << stream; \ 00145 ::sal::detail::log( \ 00146 (level), (area), (where), sal_detail_stream); \ 00147 } \ 00148 } \ 00149 } while (false) 00150 00152 00163 #define SAL_WHERE SAL_DETAIL_WHERE 00164 00179 #define SAL_STREAM(stream) \ 00180 (dynamic_cast< ::std::ostringstream & >(::std::ostringstream() << stream). \ 00181 str()) 00182 00280 #define SAL_INFO(area, stream) \ 00281 SAL_DETAIL_LOG_STREAM( \ 00282 SAL_DETAIL_ENABLE_LOG_INFO, ::SAL_DETAIL_LOG_LEVEL_INFO, area, \ 00283 SAL_WHERE, stream) 00284 00290 #define SAL_INFO_IF(condition, area, stream) \ 00291 SAL_DETAIL_LOG_STREAM( \ 00292 SAL_DETAIL_ENABLE_LOG_INFO && (condition), \ 00293 ::SAL_DETAIL_LOG_LEVEL_INFO, area, SAL_WHERE, stream) 00294 00300 #define SAL_WARN(area, stream) \ 00301 SAL_DETAIL_LOG_STREAM( \ 00302 SAL_DETAIL_ENABLE_LOG_WARN, ::SAL_DETAIL_LOG_LEVEL_WARN, area, \ 00303 SAL_WHERE, stream) 00304 00310 #define SAL_WARN_IF(condition, area, stream) \ 00311 SAL_DETAIL_LOG_STREAM( \ 00312 SAL_DETAIL_ENABLE_LOG_WARN && (condition), \ 00313 ::SAL_DETAIL_LOG_LEVEL_WARN, area, SAL_WHERE, stream) 00314 00321 #define SAL_DEBUG(stream) \ 00322 SAL_DETAIL_LOG_STREAM( \ 00323 SAL_LOG_TRUE, ::SAL_DETAIL_LOG_LEVEL_DEBUG, 0, 0, stream) 00324 00325 #endif 00326 00327 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */