diff options
Diffstat (limited to 'tools/lldb-mi/MICmnStreamStdout.cpp')
-rw-r--r-- | tools/lldb-mi/MICmnStreamStdout.cpp | 230 |
1 files changed, 230 insertions, 0 deletions
diff --git a/tools/lldb-mi/MICmnStreamStdout.cpp b/tools/lldb-mi/MICmnStreamStdout.cpp new file mode 100644 index 000000000000..0532820eb790 --- /dev/null +++ b/tools/lldb-mi/MICmnStreamStdout.cpp @@ -0,0 +1,230 @@ +//===-- MIUtilStreamStdout.cpp ----------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +//++ +// File: MIUtilStreamcStdout.cpp +// +// Overview: CMICmnStreamStdout implementation. +// +// Environment: Compilers: Visual C++ 12. +// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1 +// Libraries: See MIReadmetxt. +// +// Copyright: None. +//-- + +// In-house headers: +#include "MICmnStreamStdout.h" +#include "MICmnLog.h" +#include "MICmnResources.h" +#include "MIDriver.h" + +//++ ------------------------------------------------------------------------------------ +// Details: CMICmnStreamStdout constructor. +// Type: Method. +// Args: None. +// Return: None. +// Throws: None. +//-- +CMICmnStreamStdout::CMICmnStreamStdout( void ) +{ +} + +//++ ------------------------------------------------------------------------------------ +// Details: CMICmnStreamStdout destructor. +// Type: Overridable. +// Args: None. +// Return: None. +// Throws: None. +//-- +CMICmnStreamStdout::~CMICmnStreamStdout( void ) +{ + Shutdown(); +} + +//++ ------------------------------------------------------------------------------------ +// Details: Initialize resources for *this Stdout stream. +// Type: Method. +// Args: None. +// Return: MIstatus::success - Functional succeeded. +// MIstatus::failure - Functional failed. +// Throws: None. +//-- +bool CMICmnStreamStdout::Initialize( void ) +{ + m_clientUsageRefCnt++; + + if( m_bInitialized ) + return MIstatus::success; + + bool bOk = MIstatus::success; + +#ifdef _MSC_VER + // Debugging / I/O issues with client. + // This is only required on Windows if you do not use ::flush(stdout). MI uses + // ::flush(stdout) + // It trys to ensure the process attached to the stdout steam gets ALL the data. + //::setbuf( stdout, NULL ); +#endif // _MSC_VER + + m_bInitialized = bOk; + + return MIstatus::success; +} + +//++ ------------------------------------------------------------------------------------ +// Details: Release resources for *this Stdout stream. +// Type: Method. +// Args: None. +// Return: MIstatus::success - Functional succeeded. +// MIstatus::failure - Functional failed. +// Throws: None. +//-- +bool CMICmnStreamStdout::Shutdown( void ) +{ + if( --m_clientUsageRefCnt > 0 ) + return MIstatus::success; + + if( !m_bInitialized ) + return MIstatus::success; + + ClrErrorDescription(); + + m_bInitialized = false; + + return MIstatus::success; +} + +//++ ------------------------------------------------------------------------------------ +// Details: Write an MI format type response to stdout. The text data does not need to +// include a carrage line return as this is added to the text. The function also +// then passes the text data into the CMICmnLog logger. +// Type: Method. +// Args: vText - (R) MI formatted text. +// vbSendToLog - (R) True = Yes send to the Log file too, false = do not. (Dflt = true) +// Return: MIstatus::success - Functional succeeded. +// MIstatus::failure - Functional failed. +// Throws: None. +//-- +bool CMICmnStreamStdout::WriteMIResponse( const CMIUtilString & vText, const bool vbSendToLog /* = true */ ) +{ + return WritePriv( vText, vText, vbSendToLog ); +} + +//++ ------------------------------------------------------------------------------------ +// Details: Write text data to stdout. The text data does not need to +// include a carrage line return as this is added to the text. The function also +// then passes the text data into the CMICmnLog logger. +// Type: Method. +// Args: vText - (R) Text data. +// vbSendToLog - (R) True = Yes send to the Log file too, false = do not. (Dflt = true) +// Return: MIstatus::success - Functional succeeded. +// MIstatus::failure - Functional failed. +// Throws: None. +//-- +bool CMICmnStreamStdout::Write( const CMIUtilString & vText, const bool vbSendToLog /* = true */ ) +{ + if( vText.length() == 0 ) + return MIstatus::failure; + + const CMIUtilString strPrefixed( CMIUtilString::Format( "%s: %s", CMIDriver::Instance().GetAppNameShort().c_str(), vText.c_str() ) ); + + return WritePriv( strPrefixed, vText, vbSendToLog ); +} + +//++ ------------------------------------------------------------------------------------ +// Details: Write text data to stdout. The text data does not need to +// include a carrage line return as this is added to the text. The function also +// then passes the text data into the CMICmnLog logger. +// Type: Method. +// Args: vText - (R) Text data prefixed with MI app's short name. +// vTxtForLogFile - (R) Text data. +// vbSendToLog - (R) True = Yes send to the Log file too, false = do not. (Dflt = true) +// Return: MIstatus::success - Functional succeeded. +// MIstatus::failure - Functional failed. +// Throws: None. +//-- +bool CMICmnStreamStdout::WritePriv( const CMIUtilString & vText, const CMIUtilString & vTxtForLogFile, const bool vbSendToLog /* = true */ ) +{ + if( vText.length() == 0 ) + return MIstatus::failure; + + bool bOk = MIstatus::success; + { + // Grab the stdout thread lock while we print + CMIUtilThreadLock _lock( m_mutex ); + + // Send this text to stdout + const MIuint status = ::fputs( vText.c_str(), stdout ); + if( status == EOF ) + { + const CMIUtilString errMsg( CMIUtilString::Format( MIRSRC( IDS_STDOUT_ERR_NOT_ALL_DATA_WRITTEN ), vText.c_str() ) ); + SetErrorDescription( errMsg ); + bOk = MIstatus::failure; + } + else + { + ::fprintf( stdout, "\n" ); + ::fflush( stdout ); + } + + // Send this text to the log + if( bOk && vbSendToLog ) + bOk &= m_pLog->WriteLog( vTxtForLogFile ); + } + + return bOk; +} + +//++ ------------------------------------------------------------------------------------ +// Details: Lock the availability of the stream stdout. Other users of *this stream will +// be stalled until it is available (Unlock()). +// Type: Method. +// Args: None. +// Return: MIstatus::success - Functional succeeded. +// MIstatus::failure - Functional failed. +// Throws: None. +//-- +bool CMICmnStreamStdout::Lock( void ) +{ + m_mutex.Lock(); + return MIstatus::success; +} + +//++ ------------------------------------------------------------------------------------ +// Details: Release a previously locked stdout. +// Type: Method. +// Args: None. +// Return: MIstatus::success - Functional succeeded. +// MIstatus::failure - Functional failed. +// Throws: None. +//-- +bool CMICmnStreamStdout::Unlock( void ) +{ + m_mutex.Unlock(); + return MIstatus::success; +} + +//++ ------------------------------------------------------------------------------------ +// Details: Take a text data and send to the stdout stream. Also output to the MI Log +// file. +// Type: Static method. +// Args: vrTxt - (R) Text. +// Return: MIstatus::success - Functionality succeeded. +// MIstatus::failure - Functionality failed. +// Throws: None. +//-- +bool CMICmnStreamStdout::TextToStdout( const CMIUtilString & vrTxt ) +{ + const bool bLock = CMICmnStreamStdout::Instance().Lock(); + const bool bOk = bLock && CMICmnStreamStdout::Instance().WriteMIResponse( vrTxt ); + bLock && CMICmnStreamStdout::Instance().Unlock(); + + return bOk; +} |