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