1 /************************************************************************* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * 4 * Copyright 2000, 2011 Oracle and/or its affiliates. 5 * 6 * OpenOffice.org - a multi-platform office productivity suite 7 * 8 * This file is part of OpenOffice.org. 9 * 10 * OpenOffice.org is free software: you can redistribute it and/or modify 11 * it under the terms of the GNU Lesser General Public License version 3 12 * only, as published by the Free Software Foundation. 13 * 14 * OpenOffice.org is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU Lesser General Public License version 3 for more details 18 * (a copy is included in the LICENSE file that accompanied this code). 19 * 20 * You should have received a copy of the GNU Lesser General Public License 21 * version 3 along with OpenOffice.org. If not, see 22 * <http://www.openoffice.org/license.html> 23 * for a copy of the LGPLv3 License. 24 * 25 ************************************************************************/ 26 27 #include "precompiled_basic.hxx" 28 29 #include "rtlproto.hxx" 30 #include "sbdiagnose.hxx" 31 32 #include "basic/sbstar.hxx" 33 34 #include <tools/debug.hxx> 35 #include <comphelper/flagguard.hxx> 36 37 #ifdef DBG_UTIL 38 39 static DbgChannelId nRestoreChannelId = 0; 40 static DbgChannelId nAssertionChannelId = 0; 41 static StarBASICRef xAssertionChannelBasic; 42 static String sCaptureFunctionName; 43 static bool bReportingAssertion = false; 44 45 void ResetCapturedAssertions() 46 { 47 if ( nRestoreChannelId != 0 ) 48 { 49 DBG_INSTOUTERROR( nRestoreChannelId ); 50 } 51 nRestoreChannelId = 0; 52 xAssertionChannelBasic = NULL; 53 sCaptureFunctionName = String(); 54 bReportingAssertion = false; 55 } 56 57 void DbgReportAssertion( const sal_Char* i_assertionMessage ) 58 { 59 if ( !xAssertionChannelBasic ) 60 { 61 ResetCapturedAssertions(); 62 return; 63 } 64 65 // prevent infinite recursion 66 if ( bReportingAssertion ) 67 return; 68 ::comphelper::FlagRestorationGuard aGuard( bReportingAssertion, true ); 69 70 SbxArrayRef const xArguments( new SbxArray( SbxVARIANT ) ); 71 SbxVariableRef const xMessageText = new SbxVariable( SbxSTRING ); 72 xMessageText->PutString( String::CreateFromAscii( i_assertionMessage ) ); 73 xArguments->Put( xMessageText, 1 ); 74 75 ErrCode const nError = xAssertionChannelBasic->Call( sCaptureFunctionName, xArguments ); 76 if ( ( nError & SbERR_METHOD_NOT_FOUND ) != 0 ) 77 ResetCapturedAssertions(); 78 } 79 80 #endif 81 82 /// capture assertions, route them to the given given Basic function 83 RTLFUNC(CaptureAssertions) 84 { 85 (void)bWrite; 86 87 // need exactly one argument 88 if ( rPar.Count() != 2 ) 89 { 90 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 91 return; 92 } 93 94 #ifdef DBG_UTIL 95 DBG_TESTSOLARMUTEX(); 96 97 String const sFunctionName = rPar.Get(1)->GetString(); 98 if ( sFunctionName.Len() == 0 ) 99 { 100 ResetCapturedAssertions(); 101 return; 102 } 103 104 if ( nAssertionChannelId == 0 ) 105 { 106 // TODO: should we register a named channel at the VCL API, instead of an unnamed channel at the tools API? 107 // A named channel would mean it would appear in the nonpro-debug-options dialog 108 nAssertionChannelId = DbgRegisterUserChannel( &DbgReportAssertion ); 109 } 110 111 DbgChannelId const nCurrentChannelId = (DbgChannelId)DbgGetErrorOut(); 112 if ( nCurrentChannelId != nAssertionChannelId ) 113 { 114 // remember the current channel 115 nRestoreChannelId = nCurrentChannelId; 116 117 // set the new channel 118 DBG_INSTOUTERROR( nAssertionChannelId ); 119 120 // ensure OSL assertions are captured, too 121 DbgData aData( *DbgGetData() ); 122 aData.bHookOSLAssert = sal_True; 123 DbgUpdateOslHook( &aData ); 124 } 125 126 xAssertionChannelBasic = pBasic; 127 sCaptureFunctionName = sFunctionName; 128 #else 129 (void)pBasic; 130 (void)rPar; 131 (void)bWrite; 132 #endif 133 } 134 135