]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/tools/lldb-mi/MICmnLog.cpp
MFV r329807:
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / tools / lldb-mi / MICmnLog.cpp
1 //===-- MICmnLog.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 "MICmnLog.h"
12 #include "MICmnLogMediumFile.h"
13 #include "MICmnResources.h"
14 #include "MIDriverMgr.h"
15 #include "MIUtilDateTimeStd.h"
16
17 //++
18 //------------------------------------------------------------------------------------
19 // Details: CMICmnLog constructor.
20 // Type:    Method.
21 // Args:    None.
22 // Return:  None.
23 // Throws:  None.
24 //--
25 CMICmnLog::CMICmnLog() : m_bEnabled(false), m_bInitializingATM(false) {
26   // Do not use this constructor, use Initialize()
27 }
28
29 //++
30 //------------------------------------------------------------------------------------
31 // Details: CMICmnLog destructor.
32 // Type:    Method.
33 // Args:    None.
34 // Return:  None.
35 // Throws:  None.
36 //--
37 CMICmnLog::~CMICmnLog() { Shutdown(); }
38
39 //++
40 //------------------------------------------------------------------------------------
41 // Details: Initialize resources for *this Logger.
42 // Type:    Method.
43 // Args:    None.
44 // Return:  MIstatus::success - Functional succeeded.
45 //          MIstatus::failure - Functional failed.
46 // Throws:  None.
47 //--
48 bool CMICmnLog::Initialize() {
49   m_clientUsageRefCnt++;
50
51   if (m_bInitialized)
52     return MIstatus::success;
53
54   ClrErrorDescription();
55
56   // Mediums set inside because explicitly initing in MIDriverMain.cpp causes
57   // compile errors with CAtlFile
58   CMICmnLogMediumFile &rFileLog(CMICmnLogMediumFile::Instance());
59   bool bOk = RegisterMedium(rFileLog);
60   if (bOk) {
61     // Set the Log trace file's header
62     const CMIUtilString &rCR(rFileLog.GetLineReturn());
63     CMIUtilDateTimeStd date;
64     CMIUtilString msg;
65     msg = CMIUtilString::Format(
66         "%s\n", CMIDriverMgr::Instance().GetAppVersion().c_str());
67     CMIUtilString logHdr(msg);
68     msg = CMIUtilString::Format(MIRSRC(IDS_LOG_MSG_CREATION_DATE),
69                                 date.GetDate().c_str(), date.GetTime().c_str(),
70                                 rCR.c_str());
71     logHdr += msg;
72     msg =
73         CMIUtilString::Format(MIRSRC(IDS_LOG_MSG_FILE_LOGGER_PATH),
74                               rFileLog.GetFileNamePath().c_str(), rCR.c_str());
75     logHdr += msg;
76
77     bOk = rFileLog.SetHeaderTxt(logHdr);
78
79     // Note log file medium's status is not available until we write at least
80     // once to the file (so just write the title 1st line)
81     m_bInitializingATM = true;
82     CMICmnLog::WriteLog(".");
83     if (!rFileLog.IsOk()) {
84       const CMIUtilString msg(
85           CMIUtilString::Format(MIRSRC(IDS_LOG_ERR_FILE_LOGGER_DISABLED),
86                                 rFileLog.GetErrorDescription().c_str()));
87       CMICmnLog::WriteLog(msg);
88     }
89     m_bInitializingATM = false;
90   }
91
92   m_bInitialized = bOk;
93
94   return bOk;
95 }
96
97 //++
98 //------------------------------------------------------------------------------------
99 // Details: Release resources for *this Logger.
100 // Type:    Method.
101 // Args:    None.
102 // Return:  MIstatus::success - Functional succeeded.
103 //          MIstatus::failure - Functional failed.
104 // Throws:  None.
105 //--
106 bool CMICmnLog::Shutdown() {
107   if (--m_clientUsageRefCnt > 0)
108     return MIstatus::success;
109
110   if (!m_bInitialized)
111     return MIstatus::success;
112
113   ClrErrorDescription();
114
115   const bool bOk = UnregisterMediumAll();
116
117   m_bInitialized = bOk;
118
119   return bOk;
120 }
121
122 //++
123 //------------------------------------------------------------------------------------
124 // Details: Enabled or disable *this Logger from writing any data to registered
125 // clients.
126 // Type:    Method.
127 // Args:    vbYes   - (R) True = Logger enabled, false = disabled.
128 // Return:  MIstatus::success - Functional succeeded.
129 //          MIstatus::failure - Functional failed.
130 // Throws:  None.
131 //--
132 bool CMICmnLog::SetEnabled(const bool vbYes) {
133   m_bEnabled = vbYes;
134
135   return MIstatus::success;
136 }
137
138 //++
139 //------------------------------------------------------------------------------------
140 // Details: Retrieve state whether *this Logger is enabled writing data to
141 // registered clients.
142 // Type:    Method.
143 // Args:    None.
144 // Return:  True = Logger enable.
145 //          False = disabled.
146 // Throws:  None.
147 //--
148 bool CMICmnLog::GetEnabled() const { return m_bEnabled; }
149
150 //++
151 //------------------------------------------------------------------------------------
152 // Details: Unregister all the Mediums registered with *this Logger.
153 // Type:    Method.
154 // Args:    None.
155 // Return:  MIstatus::success - Functional succeeded.
156 //          MIstatus::failure - Functional failed.
157 // Throws:  None.
158 //--
159 bool CMICmnLog::UnregisterMediumAll() {
160   MapMediumToName_t::const_iterator it = m_mapMediumToName.begin();
161   for (; it != m_mapMediumToName.end(); it++) {
162     IMedium *pMedium = (*it).first;
163     pMedium->Shutdown();
164   }
165
166   m_mapMediumToName.clear();
167
168   return MIstatus::success;
169 }
170
171 //++
172 //------------------------------------------------------------------------------------
173 // Details: Register a Medium with *this Logger.
174 // Type:    Method.
175 // Args:    vrMedium    - (R) The medium to register.
176 // Return:  MIstatus::success - Functional succeeded.
177 //          MIstatus::failure - Functional failed.
178 // Throws:  None.
179 //--
180 bool CMICmnLog::RegisterMedium(const IMedium &vrMedium) {
181   if (HaveMediumAlready(vrMedium))
182     return MIstatus::success;
183
184   IMedium *pMedium = const_cast<IMedium *>(&vrMedium);
185   if (!pMedium->Initialize()) {
186     const CMIUtilString &rStrMedName(pMedium->GetName());
187     const CMIUtilString &rStrMedErr(pMedium->GetError());
188     SetErrorDescription(CMIUtilString::Format(MIRSRC(IDS_LOG_MEDIUM_ERR_INIT),
189                                               rStrMedName.c_str(),
190                                               rStrMedErr.c_str()));
191     return MIstatus::failure;
192   }
193
194   MapPairMediumToName_t pr(pMedium, pMedium->GetName());
195   m_mapMediumToName.insert(pr);
196
197   return MIstatus::success;
198 }
199
200 //++
201 //------------------------------------------------------------------------------------
202 // Details: Query the Logger to see if a medium is already registered.
203 // Type:    Method.
204 // Args:    vrMedium    - (R) The medium to query.
205 // Return:  True - registered.
206 //          False - not registered.
207 // Throws:  None.
208 //--
209 bool CMICmnLog::HaveMediumAlready(const IMedium &vrMedium) const {
210   IMedium *pMedium = const_cast<IMedium *>(&vrMedium);
211   const MapMediumToName_t::const_iterator it = m_mapMediumToName.find(pMedium);
212   if (it != m_mapMediumToName.end())
213     return true;
214
215   return false;
216 }
217
218 //++
219 //------------------------------------------------------------------------------------
220 // Details: Unregister a medium from the Logger.
221 // Type:    Method.
222 // Args:    vrMedium    - (R) The medium to unregister.
223 // Return:  MIstatus::success - Functional succeeded.
224 //          MIstatus::failure - Functional failed.
225 // Throws:  None.
226 //--
227 bool CMICmnLog::UnregisterMedium(const IMedium &vrMedium) {
228   IMedium *pMedium = const_cast<IMedium *>(&vrMedium);
229   m_mapMediumToName.erase(pMedium);
230
231   return MIstatus::success;
232 }
233
234 //++
235 //------------------------------------------------------------------------------------
236 // Details: The callee client uses this function to write to the Logger. The
237 // data to be
238 //          written is given out to all the mediums registered. The verbosity
239 //          type parameter
240 //          indicates to the medium(s) the type of data or message given to it.
241 //          The medium has
242 //          modes of verbosity and depending on the verbosity set determines
243 //          which writes
244 //          go in to the logger.
245 //          The logger must be initialized successfully before a write to any
246 //          registered
247 //          can be carried out.
248 // Type:    Method.
249 // Args:    vData       - (R) The data to write to the logger.
250 //          veType      - (R) Verbosity type.
251 // Return:  MIstatus::success - Functional succeeded.
252 //          MIstatus::failure - Functional failed.
253 // Throws:  None.
254 //--
255 bool CMICmnLog::Write(const CMIUtilString &vData, const ELogVerbosity veType) {
256   if (!m_bInitialized && !m_bInitializingATM)
257     return MIstatus::success;
258   if (m_bRecursiveDive)
259     return MIstatus::success;
260   if (!m_bEnabled)
261     return MIstatus::success;
262
263   m_bRecursiveDive = true;
264
265   MIuint cnt = 0;
266   MIuint cntErr = 0;
267   {
268     MapMediumToName_t::const_iterator it = m_mapMediumToName.begin();
269     while (it != m_mapMediumToName.end()) {
270       IMedium *pMedium = (*it).first;
271       const CMIUtilString &rNameMedium = (*it).second;
272       MIunused(rNameMedium);
273       if (pMedium->Write(vData, veType))
274         cnt++;
275       else
276         cntErr++;
277
278       // Next
279       ++it;
280     }
281   }
282
283   bool bOk = MIstatus::success;
284   const MIuint mediumCnt = m_mapMediumToName.size();
285   if ((cnt == 0) && (mediumCnt > 0)) {
286     SetErrorDescription(MIRSRC(IDS_LOG_MEDIUM_ERR_WRITE_ANY));
287     bOk = MIstatus::failure;
288   }
289   if (bOk && (cntErr != 0)) {
290     SetErrorDescription(MIRSRC(IDS_LOG_MEDIUM_ERR_WRITE_MEDIUMFAIL));
291     bOk = MIstatus::failure;
292   }
293
294   m_bRecursiveDive = false;
295
296   return bOk;
297 }
298
299 //++
300 //------------------------------------------------------------------------------------
301 // Details: Short cut function call to write only to the Log file.
302 //          The logger must be initialized successfully before a write to any
303 //          registered
304 //          can be carried out.
305 // Type:    Static.
306 // Args:    vData   - (R) The data to write to the logger.
307 // Return:  MIstatus::success - Functional succeeded.
308 //          MIstatus::failure - Functional failed.
309 // Throws:  None.
310 //--
311 bool CMICmnLog::WriteLog(const CMIUtilString &vData) {
312   return CMICmnLog::Instance().Write(vData, CMICmnLog::eLogVerbosity_Log);
313 }
314
315 //++
316 //------------------------------------------------------------------------------------
317 // Details: Retrieve a string detailing the last error.
318 // Type:    Method.
319 // Args:    None,
320 // Return:  CMIUtilString.
321 // Throws:  None.
322 //--
323 const CMIUtilString &CMICmnLog::GetErrorDescription() const {
324   return m_strMILastErrorDescription;
325 }
326
327 //++
328 //------------------------------------------------------------------------------------
329 // Details: Set the internal description of the last error.
330 // Type:    Method.
331 // Args:    (R) String containing a description of the last error.
332 // Return:  None.
333 // Throws:  None.
334 //--
335 void CMICmnLog::SetErrorDescription(const CMIUtilString &vrTxt) const {
336   m_strMILastErrorDescription = vrTxt;
337 }
338
339 //++
340 //------------------------------------------------------------------------------------
341 // Details: Clear the last error.
342 // Type:    None.
343 // Args:    None.
344 // Return:  None.
345 // Throws:  None.
346 //--
347 void CMICmnLog::ClrErrorDescription() const {
348   m_strMILastErrorDescription = CMIUtilString("");
349 }