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