From d1076b1b7f4049d8820f410d72c7a60bfac95152 Mon Sep 17 00:00:00 2001 From: Stephan Bergmann Date: Sat, 8 Oct 2011 18:56:48 +0200 Subject: Second attempt at (cross-platform) OSL_FORMAT. --- basic/source/app/app.cxx | 7 ++- basic/source/uno/namecont.cxx | 115 ++++++++++++++++++---------------- sal/inc/osl/diagnose.h | 24 +++++++ sal/osl/all/formatstring.cxx | 61 ++++++++++++++++++ sal/osl/all/makefile.mk | 2 + sal/util/sal.map | 5 ++ sfx2/source/appl/module.cxx | 12 ++-- vcl/unx/generic/printer/ppdparser.cxx | 56 +++++++++++++---- 8 files changed, 208 insertions(+), 74 deletions(-) create mode 100644 sal/osl/all/formatstring.cxx diff --git a/basic/source/app/app.cxx b/basic/source/app/app.cxx index 3f714ddf092a..9eb83c8b503d 100644 --- a/basic/source/app/app.cxx +++ b/basic/source/app/app.cxx @@ -1848,7 +1848,12 @@ String BasicFrame::GenRealString( const String &aResString ) } else { - OSL_FAIL( CByteString("Unknown replacement in String: ").Append( ByteString( aResult.Copy(nStart,nEnd-nStart), RTL_TEXTENCODING_UTF8 ) ).GetBuffer() ); + OSL_FAIL( + OSL_FORMAT( + "Unknown replacement in String: %s", + rtl::OUStringToOString( + aResult.Copy(nStart, nEnd - nStart), + RTL_TEXTENCODING_UTF8).getStr())); nStartPos = nStartPos + StartKenn.Len(); } } diff --git a/basic/source/uno/namecont.cxx b/basic/source/uno/namecont.cxx index d14ca988babc..c0733a35dd5f 100644 --- a/basic/source/uno/namecont.cxx +++ b/basic/source/uno/namecont.cxx @@ -384,21 +384,21 @@ SfxLibraryContainer::SfxLibraryContainer( void ) mxMSF = comphelper::getProcessServiceFactory(); if( !mxMSF.is() ) { - OSL_FAIL( "### couldn't get ProcessServiceFactory\n" ); + OSL_FAIL( "couldn't get ProcessServiceFactory" ); } mxSFI = Reference< XSimpleFileAccess >( mxMSF->createInstance ( OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.ucb.SimpleFileAccess")) ), UNO_QUERY ); if( !mxSFI.is() ) { - OSL_FAIL( "### couldn't create SimpleFileAccess component\n" ); + OSL_FAIL( "couldn't create SimpleFileAccess component" ); } mxStringSubstitution = Reference< XStringSubstitution >( mxMSF->createInstance ( OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.util.PathSubstitution")) ), UNO_QUERY ); if( !mxStringSubstitution.is() ) { - OSL_FAIL( "### couldn't create PathSubstitution component\n" ); + OSL_FAIL( "couldn't create PathSubstitution component" ); } } @@ -673,7 +673,7 @@ sal_Bool SfxLibraryContainer::init_Impl( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.sax.Parser") ) ), UNO_QUERY ); if( !xParser.is() ) { - OSL_FAIL( "### couldn't create sax parser component\n" ); + OSL_FAIL( "couldn't create sax parser component" ); return sal_False; } @@ -824,13 +824,13 @@ sal_Bool SfxLibraryContainer::init_Impl( catch ( xml::sax::SAXException& e ) { (void) e; // avoid warning - OSL_FAIL( OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US ).getStr() ); + OSL_FAIL( OUStringToOString( e.Message, RTL_TEXTENCODING_UTF8 ).getStr() ); return sal_False; } catch ( io::IOException& e ) { (void) e; // avoid warning - OSL_FAIL( OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US ).getStr() ); + OSL_FAIL( OUStringToOString( e.Message, RTL_TEXTENCODING_UTF8 ).getStr() ); return sal_False; } @@ -918,12 +918,16 @@ sal_Bool SfxLibraryContainer::init_Impl( { #if OSL_DEBUG_LEVEL > 0 Any aError( ::cppu::getCaughtException() ); - ::rtl::OStringBuffer aMessage; - aMessage.append( "couldn't open sub storage for library '" ); - aMessage.append( ::rtl::OUStringToOString( rLib.aName, osl_getThreadTextEncoding() ) ); - aMessage.append( "'.\n\nException:" ); - aMessage.append( ::rtl::OUStringToOString( ::comphelper::anyToString( aError ), osl_getThreadTextEncoding() ) ); - OSL_FAIL( aMessage.makeStringAndClear().getStr() ); + OSL_FAIL( + OSL_FORMAT( + ("couldn't open sub storage for library" + " \"%s\". Exception: %s"), + (rtl::OUStringToOString( + rLib.aName, RTL_TEXTENCODING_UTF8). + getStr()), + rtl::OUStringToOString( + comphelper::anyToString(aError), + RTL_TEXTENCODING_UTF8).getStr())); #endif } } @@ -936,7 +940,7 @@ sal_Bool SfxLibraryContainer::init_Impl( if( bLoaded && aLibName != rLib.aName ) { OSL_FAIL( "Different library names in library" - " container and library info files!\n" ); + " container and library info files!" ); } if( GbMigrationSuppressErrors && !bLoaded ) removeLibrary( aLibName ); @@ -1410,13 +1414,11 @@ void SfxLibraryContainer::implStoreLibrary( SfxLibrary* pLib, if( !isLibraryElementValid( pLib->getByName( aElementName ) ) ) { - #if OSL_DEBUG_LEVEL > 0 - ::rtl::OStringBuffer aMessage; - aMessage.append( "invalid library element '" ); - aMessage.append( ::rtl::OUStringToOString( aElementName, osl_getThreadTextEncoding() ) ); - aMessage.append( "'." ); - OSL_FAIL( aMessage.makeStringAndClear().getStr() ); - #endif + OSL_FAIL( + OSL_FORMAT( + "invalid library element \"%s\"", + rtl::OUStringToOString( + aElementName, RTL_TEXTENCODING_UTF8).getStr())); continue; } try { @@ -1447,7 +1449,7 @@ void SfxLibraryContainer::implStoreLibrary( SfxLibrary* pLib, } catch(const uno::Exception& ) { - OSL_FAIL( "Problem during storing of library!\n" ); + OSL_FAIL( "Problem during storing of library!" ); // TODO: error handling? } } @@ -1494,13 +1496,11 @@ void SfxLibraryContainer::implStoreLibrary( SfxLibrary* pLib, if( !isLibraryElementValid( pLib->getByName( aElementName ) ) ) { - #if OSL_DEBUG_LEVEL > 0 - ::rtl::OStringBuffer aMessage; - aMessage.append( "invalid library element '" ); - aMessage.append( ::rtl::OUStringToOString( aElementName, osl_getThreadTextEncoding() ) ); - aMessage.append( "'." ); - OSL_FAIL( aMessage.makeStringAndClear().getStr() ); - #endif + OSL_FAIL( + OSL_FORMAT( + "invalid library element \"%s\"", + rtl::OUStringToOString( + aElementName, RTL_TEXTENCODING_UTF8).getStr())); continue; } @@ -1552,7 +1552,7 @@ void SfxLibraryContainer::implStoreLibraryIndexFile( SfxLibrary* pLib, OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.sax.Writer") ) ), UNO_QUERY ); if( !xHandler.is() ) { - OSL_FAIL( "### couldn't create sax-writer component\n" ); + OSL_FAIL( "couldn't create sax-writer component" ); return; } @@ -1588,7 +1588,7 @@ void SfxLibraryContainer::implStoreLibraryIndexFile( SfxLibrary* pLib, } catch(const uno::Exception& ) { - OSL_FAIL( "Problem during storing of library index file!\n" ); + OSL_FAIL( "Problem during storing of library index file!" ); // TODO: error handling? } } @@ -1637,7 +1637,7 @@ void SfxLibraryContainer::implStoreLibraryIndexFile( SfxLibrary* pLib, } if( !xOut.is() ) { - OSL_FAIL( "### couldn't open output stream\n" ); + OSL_FAIL( "couldn't open output stream" ); return; } @@ -1655,7 +1655,7 @@ sal_Bool SfxLibraryContainer::implLoadLibraryIndexFile( SfxLibrary* pLib, OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.sax.Parser") ) ), UNO_QUERY ); if( !xParser.is() ) { - OSL_FAIL( "### couldn't create sax parser component\n" ); + OSL_FAIL( "couldn't create sax parser component" ); return sal_False; } @@ -1727,7 +1727,7 @@ sal_Bool SfxLibraryContainer::implLoadLibraryIndexFile( SfxLibrary* pLib, } catch(const Exception& ) { - OSL_FAIL( "Parsing error\n" ); + OSL_FAIL( "Parsing error" ); SfxErrorContext aEc( ERRCTX_SFX_LOADBASIC, aLibInfoPath ); sal_uIntPtr nErrorCode = ERRCODE_IO_GENERAL; ErrorHandler::HandleError( nErrorCode ); @@ -1915,12 +1915,15 @@ void SfxLibraryContainer::storeLibraries_Impl( const uno::Reference< embed::XSto { #if OSL_DEBUG_LEVEL > 0 Any aError( ::cppu::getCaughtException() ); - ::rtl::OStringBuffer aMessage; - aMessage.append( "couldn't create sub storage for library '" ); - aMessage.append( ::rtl::OUStringToOString( rLib.aName, osl_getThreadTextEncoding() ) ); - aMessage.append( "'.\n\nException:" ); - aMessage.append( ::rtl::OUStringToOString( ::comphelper::anyToString( aError ), osl_getThreadTextEncoding() ) ); - OSL_FAIL( aMessage.makeStringAndClear().getStr() ); + OSL_FAIL( + OSL_FORMAT( + ("couldn't create sub storage for library" + " \"%s\". Exception: %s"), + rtl::OUStringToOString( + rLib.aName, RTL_TEXTENCODING_UTF8).getStr(), + rtl::OUStringToOString( + comphelper::anyToString(aError), + RTL_TEXTENCODING_UTF8).getStr())); #endif return; } @@ -2025,7 +2028,7 @@ void SfxLibraryContainer::storeLibraries_Impl( const uno::Reference< embed::XSto OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.sax.Writer") ) ), UNO_QUERY ); if( !xHandler.is() ) { - OSL_FAIL( "### couldn't create sax-writer component\n" ); + OSL_FAIL( "couldn't create sax-writer component" ); return; } @@ -2085,7 +2088,7 @@ void SfxLibraryContainer::storeLibraries_Impl( const uno::Reference< embed::XSto } if( !xOut.is() ) { - OSL_FAIL( "### couldn't open output stream\n" ); + OSL_FAIL( "couldn't open output stream" ); return; } @@ -2107,7 +2110,7 @@ void SfxLibraryContainer::storeLibraries_Impl( const uno::Reference< embed::XSto } catch(const uno::Exception& ) { - OSL_FAIL( "Problem during storing of libraries!\n" ); + OSL_FAIL( "Problem during storing of libraries!" ); sal_uIntPtr nErrorCode = ERRCODE_IO_GENERAL; ErrorHandler::HandleError( nErrorCode ); } @@ -2336,12 +2339,15 @@ void SAL_CALL SfxLibraryContainer::loadLibrary( const OUString& Name ) { #if OSL_DEBUG_LEVEL > 0 Any aError( ::cppu::getCaughtException() ); - ::rtl::OStringBuffer aMessage; - aMessage.append( "couldn't open sub storage for library '" ); - aMessage.append( ::rtl::OUStringToOString( Name, osl_getThreadTextEncoding() ) ); - aMessage.append( "'.\n\nException:" ); - aMessage.append( ::rtl::OUStringToOString( ::comphelper::anyToString( aError ), osl_getThreadTextEncoding() ) ); - OSL_FAIL( aMessage.makeStringAndClear().getStr() ); + OSL_FAIL( + OSL_FORMAT( + ("couldn't open sub storage for library \"%s\"." + " Exception: %s"), + (rtl::OUStringToOString(Name, RTL_TEXTENCODING_UTF8). + getStr()), + rtl::OUStringToOString( + comphelper::anyToString(aError), + RTL_TEXTENCODING_UTF8).getStr())); #endif return; } @@ -2386,13 +2392,12 @@ void SAL_CALL SfxLibraryContainer::loadLibrary( const OUString& Name ) if ( !xInStream.is() ) { - #if OSL_DEBUG_LEVEL > 0 - ::rtl::OStringBuffer aMessage; - aMessage.append( "couldn't open library element stream - attempted to open library '" ); - aMessage.append( ::rtl::OUStringToOString( Name, osl_getThreadTextEncoding() ) ); - aMessage.append( "'." ); - OSL_FAIL( aMessage.makeStringAndClear().getStr() ); - #endif + OSL_FAIL( + OSL_FORMAT( + ("couldn't open library element stream - attempted" + " to open library \"%s\""), + rtl::OUStringToOString( + Name, RTL_TEXTENCODING_UTF8).getStr())); return; } } diff --git a/sal/inc/osl/diagnose.h b/sal/inc/osl/diagnose.h index ab5243fe94d5..aab76b320f2a 100644 --- a/sal/inc/osl/diagnose.h +++ b/sal/inc/osl/diagnose.h @@ -192,6 +192,30 @@ pfunc_osl_printDetailedDebugMessage SAL_CALL osl_setDetailedDebugMessageFunc( pf #define OSL_THIS_FUNC "" #endif +#if defined __cplusplus + +#include "rtl/string.hxx" + +/** @internal */ +extern "C" struct _rtl_String * SAL_CALL osl_detail_formatString( + char const * format, ...) SAL_THROW_EXTERN_C(); + // "struct _rtl_String" instead of "rtl_String" for the case where + // osl/diagnose.h is included in rtl/string.hxx + +/** A facility for printf-style messages in OSL_ENSURE, OSL_FAIL, etc. + + Use like: OSL_ENSURE(i == 5, OSL_FORMAT("i should be 5 but is %d", i)); +*/ +#define OSL_FORMAT(format, ...) \ + (::rtl::OString( \ + ::osl_detail_formatString(format, __VA_ARGS__), \ + ::SAL_NO_ACQUIRE).getStr()) + // it appears that all relevant compilers (esp. GCC 4.0 and MS VS 2008 + // Express) already support variadic macros in C++; see also + // + +#endif + #endif /* _OSL_DIAGNOSE_H_ */ /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sal/osl/all/formatstring.cxx b/sal/osl/all/formatstring.cxx new file mode 100644 index 000000000000..9fefa2f52cfe --- /dev/null +++ b/sal/osl/all/formatstring.cxx @@ -0,0 +1,61 @@ +/* + * Version: MPL 1.1 / GPLv3+ / LGPLv3+ + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License or as specified alternatively below. You may obtain a copy of + * the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * Major Contributor(s): + * [ Copyright (C) 2011 Stephan Bergmann, Red Hat Inc. + * (initial developer) ] + * + * All Rights Reserved. + * + * For minor contributions see the git repository. + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 3 or later (the "GPLv3+"), or + * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"), + * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable + * instead of those above. + */ + +#include "precompiled_sal.hxx" +#include "sal/config.h" + +#include +#include +#include // vsnprintf not in C++03 , only C99 + +#include "osl/diagnose.h" +#include "rtl/string.h" +#include "rtl/string.hxx" + +rtl_String * osl_detail_formatString(char const * format, ...) + SAL_THROW_EXTERN_C() +{ + // Avoid the use of other sal code as much as possible, so that this code + // can be called from other sal code without causing endless recursion: + char buf[1024]; + int n1 = sizeof buf - RTL_CONSTASCII_LENGTH("..."); + std::va_list args; + va_start(args, format); + int n2 = vsnprintf(buf, n1, format, args); + va_end(args); + if (n2 < 0) { + std::strcpy(buf, "???"); + n2 = RTL_CONSTASCII_LENGTH("???"); + } else if (n2 >= n1) { + std::strcpy(buf + n1 - 1, "..."); + n2 = sizeof buf - 1; + } + rtl::OString s(buf, n2); + rtl_string_acquire(s.pData); + return s.pData; +} diff --git a/sal/osl/all/makefile.mk b/sal/osl/all/makefile.mk index fa928412ffc3..d9db5b7bb749 100644 --- a/sal/osl/all/makefile.mk +++ b/sal/osl/all/makefile.mk @@ -50,6 +50,7 @@ CXXFLAGS+= $(LFS_CFLAGS) SLOFILES= \ $(SLO)$/utility.obj\ $(SLO)$/filepath.obj\ + $(SLO)$/formatstring.obj\ $(SLO)$/debugbase.obj\ $(SLO)$/loadmodulerelative.obj \ $(SLO)/printtrace.obj @@ -57,6 +58,7 @@ SLOFILES= \ OBJFILES= \ $(OBJ)$/utility.obj\ $(OBJ)$/filepath.obj\ + $(OBJ)$/formatstring.obj\ $(OBJ)$/debugbase.obj\ $(OBJ)$/loadmodulerelative.obj \ $(OBJ)/printtrace.obj diff --git a/sal/util/sal.map b/sal/util/sal.map index 152b02349d9c..b1b8892a0bd1 100755 --- a/sal/util/sal.map +++ b/sal/util/sal.map @@ -625,3 +625,8 @@ PRIVATE_1.1 { sal_detail_initialize; sal_detail_deinitialize; } PRIVATE_1.0; + +PRIVATE_1.2 { # LibreOffice 3.5 + global: + osl_detail_formatString; +} PRIVATE_1.1; diff --git a/sfx2/source/appl/module.cxx b/sfx2/source/appl/module.cxx index 8fa50b38077a..6883e90f5ff5 100644 --- a/sfx2/source/appl/module.cxx +++ b/sfx2/source/appl/module.cxx @@ -391,13 +391,11 @@ FieldUnit SfxModule::GetModuleFieldUnit( ::com::sun::star::uno::Reference< ::com SfxPoolItem const * pItem = pModule->GetItem( SID_ATTR_METRIC ); if ( pItem == NULL ) { -#if OSL_DEBUG_LEVEL > 0 - ::rtl::OStringBuffer message; - message.append( "SfxModule::GetFieldUnit: no metric item in the module implemented by '" ); - message.append( typeid( *pModule ).name() ); - message.append( "'!" ); - OSL_ENSURE( false, message.makeStringAndClear().getStr() ); -#endif + OSL_FAIL( + OSL_FORMAT( + ("SfxModule::GetFieldUnit: no metric item in the module" + " implemented by '%s'!"), + typeid(*pModule).name())); return FUNIT_100TH_MM; } return (FieldUnit)( (SfxUInt16Item*)pItem )->GetValue(); diff --git a/vcl/unx/generic/printer/ppdparser.cxx b/vcl/unx/generic/printer/ppdparser.cxx index a236e5f07ee6..f5c1836eae40 100644 --- a/vcl/unx/generic/printer/ppdparser.cxx +++ b/vcl/unx/generic/printer/ppdparser.cxx @@ -811,35 +811,69 @@ PPDParser::PPDParser( const String& rFile ) : m_pImageableAreas = getKey( String( RTL_CONSTASCII_USTRINGPARAM( "ImageableArea" ) ) ); if( m_pImageableAreas ) m_pDefaultImageableArea = m_pImageableAreas->getDefaultValue(); - DBG_ASSERT( m_pImageableAreas, "Warning: no ImageableArea in PPD\n" ); - DBG_ASSERT( m_pDefaultImageableArea, "Warning: no DefaultImageableArea in PPD\n" ); + DBG_ASSERT( + m_pImageableAreas, + OSL_FORMAT( + "Warning: no ImageableArea in %s\n", + rtl::OUStringToOString(m_aFile, RTL_TEXTENCODING_UTF8).getStr())); + DBG_ASSERT( + m_pDefaultImageableArea, + OSL_FORMAT( + "Warning: no DefaultImageableArea in %s\n", + rtl::OUStringToOString(m_aFile, RTL_TEXTENCODING_UTF8).getStr())); m_pPaperDimensions = getKey( String( RTL_CONSTASCII_USTRINGPARAM( "PaperDimension" ) ) ); if( m_pPaperDimensions ) m_pDefaultPaperDimension = m_pPaperDimensions->getDefaultValue(); - DBG_ASSERT( m_pPaperDimensions, "Warning: no PaperDimension in PPD\n" ); - DBG_ASSERT( m_pDefaultPaperDimension, "Warning: no DefaultPaperDimension in PPD\n" ); + DBG_ASSERT( + m_pPaperDimensions, + OSL_FORMAT( + "Warning: no PaperDimensions in %s\n", + rtl::OUStringToOString(m_aFile, RTL_TEXTENCODING_UTF8).getStr())); + DBG_ASSERT( + m_pDefaultPaperDimension, + OSL_FORMAT( + "Warning: no DefaultPaperDimensions in %s\n", + rtl::OUStringToOString(m_aFile, RTL_TEXTENCODING_UTF8).getStr())); m_pResolutions = getKey( String( RTL_CONSTASCII_USTRINGPARAM( "Resolution" ) ) ); if( m_pResolutions ) m_pDefaultResolution = m_pResolutions->getDefaultValue(); - DBG_ASSERT( m_pResolutions, "Warning: no Resolution in PPD\n" ); - DBG_ASSERT( m_pDefaultResolution, - rtl::OStringBuffer("Warning: no DefaultResolution in "). - append(rtl::OUStringToOString(rFile, osl_getThreadTextEncoding())).append('\n').getStr() ); + DBG_ASSERT( + m_pResolutions, + OSL_FORMAT( + "Warning: no Resolution in %s\n", + rtl::OUStringToOString(m_aFile, RTL_TEXTENCODING_UTF8).getStr())); + DBG_ASSERT( + m_pDefaultResolution, + OSL_FORMAT( + "Warning: no DefaultResolution in %s\n", + rtl::OUStringToOString(m_aFile, RTL_TEXTENCODING_UTF8).getStr())); m_pInputSlots = getKey( String( RTL_CONSTASCII_USTRINGPARAM( "InputSlot" ) ) ); if( m_pInputSlots ) m_pDefaultInputSlot = m_pInputSlots->getDefaultValue(); - DBG_ASSERT( m_pPaperDimensions, "Warning: no InputSlot in PPD\n" ); - DBG_ASSERT( m_pDefaultPaperDimension, "Warning: no DefaultInputSlot in PPD\n" ); + DBG_ASSERT( + m_pInputSlots, + OSL_FORMAT( + "Warning: no InputSlot in %s\n", + rtl::OUStringToOString(m_aFile, RTL_TEXTENCODING_UTF8).getStr())); + DBG_ASSERT( + m_pDefaultInputSlot, + OSL_FORMAT( + "Warning: no DefaultInputSlot in %s\n", + rtl::OUStringToOString(m_aFile, RTL_TEXTENCODING_UTF8).getStr())); m_pDuplexTypes = getKey( String( RTL_CONSTASCII_USTRINGPARAM( "Duplex" ) ) ); if( m_pDuplexTypes ) m_pDefaultDuplexType = m_pDuplexTypes->getDefaultValue(); m_pFontList = getKey( String( RTL_CONSTASCII_USTRINGPARAM( "Font" ) ) ); - DBG_ASSERT( m_pFontList, "Warning: no Font in PPD\n" ); + DBG_ASSERT( + m_pFontList, + OSL_FORMAT( + "Warning: no Font in %s\n", + rtl::OUStringToOString(m_aFile, RTL_TEXTENCODING_UTF8).getStr())); // fill in direct values if( (pKey = getKey( String( RTL_CONSTASCII_USTRINGPARAM( "ModelName" ) ) )) ) -- cgit