diff options
Diffstat (limited to 'contrib/llvm-project/lldb/tools/lldb-mi/MICmnStreamStdout.cpp')
| -rw-r--r-- | contrib/llvm-project/lldb/tools/lldb-mi/MICmnStreamStdout.cpp | 230 |
1 files changed, 230 insertions, 0 deletions
diff --git a/contrib/llvm-project/lldb/tools/lldb-mi/MICmnStreamStdout.cpp b/contrib/llvm-project/lldb/tools/lldb-mi/MICmnStreamStdout.cpp new file mode 100644 index 000000000000..4a0e2d16adc1 --- /dev/null +++ b/contrib/llvm-project/lldb/tools/lldb-mi/MICmnStreamStdout.cpp @@ -0,0 +1,230 @@ +//===-- MICmnStreamStdout.cpp -----------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// 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() {} + +//++ +// Details: CMICmnStreamStdout destructor. +// Type: Overridable. +// Args: None. +// Return: None. +// Throws: None. +//-- +CMICmnStreamStdout::~CMICmnStreamStdout() { 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() { + 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() { + 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 carriage 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 carriage 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 carriage 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 MIint status = ::fputs(vText.c_str(), stdout); + if (status == EOF) + // Don't call the CMICmnBase::SetErrorDescription() because it will cause + // a stack overflow: + // CMICmnBase::SetErrorDescription -> CMICmnStreamStdout::Write -> + // CMICmnStreamStdout::WritePriv -> CMICmnBase::SetErrorDescription + 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() { + 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() { + 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 bSendToLog = true; + return CMICmnStreamStdout::Instance().WriteMIResponse(vrTxt, bSendToLog); +} + +//++ +// Details: Write prompt to stdout if it's enabled. +// Type: Static method. +// Args: None. +// Return: MIstatus::success - Function succeeded. +// MIstatus::failure - Function failed. +// Throws: None. +//-- +bool CMICmnStreamStdout::WritePrompt() { + const CMICmnStreamStdin &rStdinMan = CMICmnStreamStdin::Instance(); + if (rStdinMan.GetEnablePrompt()) + return TextToStdout(rStdinMan.GetPrompt()); + return MIstatus::success; +} |
