UDK 3.2.7 C/C++ API Reference
sal/log.hxx
Go to the documentation of this file.
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: */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines