]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/tools/lldb-mi/MICmnStreamStdout.cpp
Copy libevent sources to contrib
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / tools / lldb-mi / MICmnStreamStdout.cpp
1 //===-- MICmnStreamStdout.cpp -----------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 // In-house headers:
11 #include "MICmnStreamStdout.h"
12 #include "MICmnLog.h"
13 #include "MICmnResources.h"
14 #include "MIDriver.h"
15
16 //++
17 //------------------------------------------------------------------------------------
18 // Details: CMICmnStreamStdout constructor.
19 // Type:    Method.
20 // Args:    None.
21 // Return:  None.
22 // Throws:  None.
23 //--
24 CMICmnStreamStdout::CMICmnStreamStdout() {}
25
26 //++
27 //------------------------------------------------------------------------------------
28 // Details: CMICmnStreamStdout destructor.
29 // Type:    Overridable.
30 // Args:    None.
31 // Return:  None.
32 // Throws:  None.
33 //--
34 CMICmnStreamStdout::~CMICmnStreamStdout() { Shutdown(); }
35
36 //++
37 //------------------------------------------------------------------------------------
38 // Details: Initialize resources for *this Stdout stream.
39 // Type:    Method.
40 // Args:    None.
41 // Return:  MIstatus::success - Functional succeeded.
42 //          MIstatus::failure - Functional failed.
43 // Throws:  None.
44 //--
45 bool CMICmnStreamStdout::Initialize() {
46   m_clientUsageRefCnt++;
47
48   if (m_bInitialized)
49     return MIstatus::success;
50
51   bool bOk = MIstatus::success;
52
53 #ifdef _MSC_VER
54 // Debugging / I/O issues with client.
55 // This is only required on Windows if you do not use ::flush(stdout). MI uses
56 // ::flush(stdout)
57 // It trys to ensure the process attached to the stdout steam gets ALL the data.
58 //::setbuf( stdout, NULL );
59 #endif // _MSC_VER
60
61   m_bInitialized = bOk;
62
63   return MIstatus::success;
64 }
65
66 //++
67 //------------------------------------------------------------------------------------
68 // Details: Release resources for *this Stdout stream.
69 // Type:    Method.
70 // Args:    None.
71 // Return:  MIstatus::success - Functional succeeded.
72 //          MIstatus::failure - Functional failed.
73 // Throws:  None.
74 //--
75 bool CMICmnStreamStdout::Shutdown() {
76   if (--m_clientUsageRefCnt > 0)
77     return MIstatus::success;
78
79   if (!m_bInitialized)
80     return MIstatus::success;
81
82   ClrErrorDescription();
83
84   m_bInitialized = false;
85
86   return MIstatus::success;
87 }
88
89 //++
90 //------------------------------------------------------------------------------------
91 // Details: Write an MI format type response to stdout. The text data does not
92 // need to
93 //          include a carriage line return as this is added to the text. The
94 //          function also
95 //          then passes the text data into the CMICmnLog logger.
96 // Type:    Method.
97 // Args:    vText       - (R) MI formatted text.
98 //          vbSendToLog - (R) True = Yes send to the Log file too, false = do
99 //          not. (Dflt = true)
100 // Return:  MIstatus::success - Functional succeeded.
101 //          MIstatus::failure - Functional failed.
102 // Throws:  None.
103 //--
104 bool CMICmnStreamStdout::WriteMIResponse(const CMIUtilString &vText,
105                                          const bool vbSendToLog /* = true */) {
106   return WritePriv(vText, vText, vbSendToLog);
107 }
108
109 //++
110 //------------------------------------------------------------------------------------
111 // Details: Write text data to stdout. The text data does not need to
112 //          include a carriage line return as this is added to the text. The
113 //          function also
114 //          then passes the text data into the CMICmnLog logger.
115 // Type:    Method.
116 // Args:    vText       - (R) Text data.
117 //          vbSendToLog - (R) True = Yes send to the Log file too, false = do
118 //          not. (Dflt = true)
119 // Return:  MIstatus::success - Functional succeeded.
120 //          MIstatus::failure - Functional failed.
121 // Throws:  None.
122 //--
123 bool CMICmnStreamStdout::Write(const CMIUtilString &vText,
124                                const bool vbSendToLog /* = true */) {
125   if (vText.length() == 0)
126     return MIstatus::failure;
127
128   const CMIUtilString strPrefixed(CMIUtilString::Format(
129       "%s: %s", CMIDriver::Instance().GetAppNameShort().c_str(),
130       vText.c_str()));
131
132   return WritePriv(strPrefixed, vText, vbSendToLog);
133 }
134
135 //++
136 //------------------------------------------------------------------------------------
137 // Details: Write text data to stdout. The text data does not need to
138 //          include a carriage line return as this is added to the text. The
139 //          function also
140 //          then passes the text data into the CMICmnLog logger.
141 // Type:    Method.
142 // Args:    vText           - (R) Text data prefixed with MI app's short name.
143 //          vTxtForLogFile  - (R) Text data.
144 //          vbSendToLog     - (R) True = Yes send to the Log file too, false =
145 //          do not. (Dflt = true)
146 // Return:  MIstatus::success - Functional succeeded.
147 //          MIstatus::failure - Functional failed.
148 // Throws:  None.
149 //--
150 bool CMICmnStreamStdout::WritePriv(const CMIUtilString &vText,
151                                    const CMIUtilString &vTxtForLogFile,
152                                    const bool vbSendToLog /* = true */) {
153   if (vText.length() == 0)
154     return MIstatus::failure;
155
156   bool bOk = MIstatus::success;
157   {
158     // Grab the stdout thread lock while we print
159     CMIUtilThreadLock _lock(m_mutex);
160
161     // Send this text to stdout
162     const MIint status = ::fputs(vText.c_str(), stdout);
163     if (status == EOF)
164       // Don't call the CMICmnBase::SetErrorDescription() because it will cause
165       // a stack overflow:
166       // CMICmnBase::SetErrorDescription -> CMICmnStreamStdout::Write ->
167       // CMICmnStreamStdout::WritePriv -> CMICmnBase::SetErrorDescription
168       bOk = MIstatus::failure;
169     else {
170       ::fprintf(stdout, "\n");
171       ::fflush(stdout);
172     }
173
174     // Send this text to the log
175     if (bOk && vbSendToLog)
176       bOk &= m_pLog->WriteLog(vTxtForLogFile);
177   }
178
179   return bOk;
180 }
181
182 //++
183 //------------------------------------------------------------------------------------
184 // Details: Lock the availability of the stream stdout. Other users of *this
185 // stream will
186 //          be stalled until it is available (Unlock()).
187 // Type:    Method.
188 // Args:    None.
189 // Return:  MIstatus::success - Functional succeeded.
190 //          MIstatus::failure - Functional failed.
191 // Throws:  None.
192 //--
193 bool CMICmnStreamStdout::Lock() {
194   m_mutex.Lock();
195   return MIstatus::success;
196 }
197
198 //++
199 //------------------------------------------------------------------------------------
200 // Details: Release a previously locked stdout.
201 // Type:    Method.
202 // Args:    None.
203 // Return:  MIstatus::success - Functional succeeded.
204 //          MIstatus::failure - Functional failed.
205 // Throws:  None.
206 //--
207 bool CMICmnStreamStdout::Unlock() {
208   m_mutex.Unlock();
209   return MIstatus::success;
210 }
211
212 //++
213 //------------------------------------------------------------------------------------
214 // Details: Take a text data and send to the stdout stream. Also output to the
215 // MI Log
216 //          file.
217 // Type:    Static method.
218 // Args:    vrTxt   - (R) Text.
219 // Return:  MIstatus::success - Functionality succeeded.
220 //          MIstatus::failure - Functionality failed.
221 // Throws:  None.
222 //--
223 bool CMICmnStreamStdout::TextToStdout(const CMIUtilString &vrTxt) {
224   const bool bSendToLog = true;
225   return CMICmnStreamStdout::Instance().WriteMIResponse(vrTxt, bSendToLog);
226 }
227
228 //++
229 //------------------------------------------------------------------------------------
230 // Details: Write prompt to stdout if it's enabled.
231 // Type:    Static method.
232 // Args:    None.
233 // Return:  MIstatus::success - Function succeeded.
234 //          MIstatus::failure - Function failed.
235 // Throws:  None.
236 //--
237 bool CMICmnStreamStdout::WritePrompt() {
238   const CMICmnStreamStdin &rStdinMan = CMICmnStreamStdin::Instance();
239   if (rStdinMan.GetEnablePrompt())
240     return TextToStdout(rStdinMan.GetPrompt());
241   return MIstatus::success;
242 }