summaryrefslogtreecommitdiff
path: root/contrib/llvm-project/lldb/tools/lldb-mi/MICmnStreamStdout.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/lldb/tools/lldb-mi/MICmnStreamStdout.cpp')
-rw-r--r--contrib/llvm-project/lldb/tools/lldb-mi/MICmnStreamStdout.cpp230
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;
+}