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