1 //===-- MICmnStreamStdout.cpp -----------------------------------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
10 #include "MICmnStreamStdout.h"
12 #include "MICmnResources.h"
16 // Details: CMICmnStreamStdout constructor.
22 CMICmnStreamStdout::CMICmnStreamStdout() {}
25 // Details: CMICmnStreamStdout destructor.
31 CMICmnStreamStdout::~CMICmnStreamStdout() { Shutdown(); }
34 // Details: Initialize resources for *this Stdout stream.
37 // Return: MIstatus::success - Functional succeeded.
38 // MIstatus::failure - Functional failed.
41 bool CMICmnStreamStdout::Initialize() {
42 m_clientUsageRefCnt++;
45 return MIstatus::success;
47 bool bOk = MIstatus::success;
50 // Debugging / I/O issues with client.
51 // This is only required on Windows if you do not use ::flush(stdout). MI uses
53 // It trys to ensure the process attached to the stdout steam gets ALL the data.
54 //::setbuf( stdout, NULL );
59 return MIstatus::success;
63 // Details: Release resources for *this Stdout stream.
66 // Return: MIstatus::success - Functional succeeded.
67 // MIstatus::failure - Functional failed.
70 bool CMICmnStreamStdout::Shutdown() {
71 if (--m_clientUsageRefCnt > 0)
72 return MIstatus::success;
75 return MIstatus::success;
77 ClrErrorDescription();
79 m_bInitialized = false;
81 return MIstatus::success;
85 // Details: Write an MI format type response to stdout. The text data does not
87 // include a carriage line return as this is added to the text. The
89 // then passes the text data into the CMICmnLog logger.
91 // Args: vText - (R) MI formatted text.
92 // vbSendToLog - (R) True = Yes send to the Log file too, false = do
94 // Return: MIstatus::success - Functional succeeded.
95 // MIstatus::failure - Functional failed.
98 bool CMICmnStreamStdout::WriteMIResponse(const CMIUtilString &vText,
99 const bool vbSendToLog /* = true */) {
100 return WritePriv(vText, vText, vbSendToLog);
104 // Details: Write text data to stdout. The text data does not need to
105 // include a carriage line return as this is added to the text. The
107 // then passes the text data into the CMICmnLog logger.
109 // Args: vText - (R) Text data.
110 // vbSendToLog - (R) True = Yes send to the Log file too, false = do
111 // not. (Dflt = true)
112 // Return: MIstatus::success - Functional succeeded.
113 // MIstatus::failure - Functional failed.
116 bool CMICmnStreamStdout::Write(const CMIUtilString &vText,
117 const bool vbSendToLog /* = true */) {
118 if (vText.length() == 0)
119 return MIstatus::failure;
121 const CMIUtilString strPrefixed(CMIUtilString::Format(
122 "%s: %s", CMIDriver::Instance().GetAppNameShort().c_str(),
125 return WritePriv(strPrefixed, vText, vbSendToLog);
129 // Details: Write text data to stdout. The text data does not need to
130 // include a carriage line return as this is added to the text. The
132 // then passes the text data into the CMICmnLog logger.
134 // Args: vText - (R) Text data prefixed with MI app's short name.
135 // vTxtForLogFile - (R) Text data.
136 // vbSendToLog - (R) True = Yes send to the Log file too, false =
137 // do not. (Dflt = true)
138 // Return: MIstatus::success - Functional succeeded.
139 // MIstatus::failure - Functional failed.
142 bool CMICmnStreamStdout::WritePriv(const CMIUtilString &vText,
143 const CMIUtilString &vTxtForLogFile,
144 const bool vbSendToLog /* = true */) {
145 if (vText.length() == 0)
146 return MIstatus::failure;
148 bool bOk = MIstatus::success;
150 // Grab the stdout thread lock while we print
151 CMIUtilThreadLock _lock(m_mutex);
153 // Send this text to stdout
154 const MIint status = ::fputs(vText.c_str(), stdout);
156 // Don't call the CMICmnBase::SetErrorDescription() because it will cause
158 // CMICmnBase::SetErrorDescription -> CMICmnStreamStdout::Write ->
159 // CMICmnStreamStdout::WritePriv -> CMICmnBase::SetErrorDescription
160 bOk = MIstatus::failure;
162 ::fprintf(stdout, "\n");
166 // Send this text to the log
167 if (bOk && vbSendToLog)
168 bOk &= m_pLog->WriteLog(vTxtForLogFile);
175 // Details: Lock the availability of the stream stdout. Other users of *this
177 // be stalled until it is available (Unlock()).
180 // Return: MIstatus::success - Functional succeeded.
181 // MIstatus::failure - Functional failed.
184 bool CMICmnStreamStdout::Lock() {
186 return MIstatus::success;
190 // Details: Release a previously locked stdout.
193 // Return: MIstatus::success - Functional succeeded.
194 // MIstatus::failure - Functional failed.
197 bool CMICmnStreamStdout::Unlock() {
199 return MIstatus::success;
203 // Details: Take a text data and send to the stdout stream. Also output to the
206 // Type: Static method.
207 // Args: vrTxt - (R) Text.
208 // Return: MIstatus::success - Functionality succeeded.
209 // MIstatus::failure - Functionality failed.
212 bool CMICmnStreamStdout::TextToStdout(const CMIUtilString &vrTxt) {
213 const bool bSendToLog = true;
214 return CMICmnStreamStdout::Instance().WriteMIResponse(vrTxt, bSendToLog);
218 // Details: Write prompt to stdout if it's enabled.
219 // Type: Static method.
221 // Return: MIstatus::success - Function succeeded.
222 // MIstatus::failure - Function failed.
225 bool CMICmnStreamStdout::WritePrompt() {
226 const CMICmnStreamStdin &rStdinMan = CMICmnStreamStdin::Instance();
227 if (rStdinMan.GetEnablePrompt())
228 return TextToStdout(rStdinMan.GetPrompt());
229 return MIstatus::success;