]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/tools/lldb-mi/MICmnLogMediumFile.cpp
Merge lldb trunk r366426, resolve conflicts, and update FREEBSD-Xlist.
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / tools / lldb-mi / MICmnLogMediumFile.cpp
1 //===-- MICmnLogMediumFile.cpp ----------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 // In-house headers:
10 #include "MICmnLogMediumFile.h"
11 #include "MICmnResources.h"
12
13 //++
14 // Details: CMICmnLogMediumFile constructor.
15 // Type:    Method.
16 // Args:    None.
17 // Return:  None.
18 // Throws:  None.
19 //--
20 CMICmnLogMediumFile::CMICmnLogMediumFile()
21     : m_constThisMediumName(MIRSRC(IDS_MEDIUMFILE_NAME)),
22       m_constMediumFileNameFormat("lldb-mi-%s.log"),
23       m_strMediumFileName(MIRSRC(IDS_MEDIUMFILE_ERR_INVALID_PATH)),
24       m_strMediumFileDirectory("."),
25       m_fileNamePath(MIRSRC(IDS_MEDIUMFILE_ERR_INVALID_PATH)),
26       m_eVerbosityType(CMICmnLog::eLogVerbosity_Log),
27       m_strDate(CMIUtilDateTimeStd().GetDate()),
28       m_fileHeaderTxt(MIRSRC(IDS_MEDIUMFILE_ERR_FILE_HEADER)) {}
29
30 //++
31 // Details: CMICmnLogMediumFile destructor.
32 // Type:    Overridden.
33 // Args:    None.
34 // Return:  None.
35 // Throws:  None.
36 //--
37 CMICmnLogMediumFile::~CMICmnLogMediumFile() {}
38
39 //++
40 // Details: Get the singleton instance of *this class.
41 // Type:    Static.
42 // Args:    None.
43 // Return:  CMICmnLogMediumFile - Reference to *this object.
44 // Throws:  None.
45 //--
46 CMICmnLogMediumFile &CMICmnLogMediumFile::Instance() {
47   static CMICmnLogMediumFile instance;
48
49   return instance;
50 }
51
52 //++
53 // Details: Initialize setup *this medium ready for use.
54 // Type:    Overridden.
55 // Args:    None.
56 // Return:  MIstatus::success - Functional succeeded.
57 //          MIstatus::failure - Functional failed.
58 // Throws:  None.
59 //--
60 bool CMICmnLogMediumFile::Initialize() {
61   m_bInitialized = true;
62   return FileFormFileNamePath();
63 }
64
65 //++
66 // Details: Unbind detach or release resources used by *this medium.
67 // Type:    Method.
68 // Args:    None.
69 // Return:  None.
70 // Throws:  None.
71 //--
72 bool CMICmnLogMediumFile::Shutdown() {
73   if (m_bInitialized) {
74     m_bInitialized = false;
75     m_file.Close();
76   }
77   return MIstatus::success;
78 }
79
80 //++
81 // Details: Retrieve the name of *this medium.
82 // Type:    Overridden.
83 // Args:    None.
84 // Return:  CMIUtilString - Text data.
85 // Throws:  None.
86 //--
87 const CMIUtilString &CMICmnLogMediumFile::GetName() const {
88   return m_constThisMediumName;
89 }
90
91 //++
92 // Details: The callee client calls the write function on the Logger. The data
93 // to be
94 //          written is given out to all the mediums registered. The verbosity
95 //          type parameter
96 //          indicates to the medium the type of data or message given to it. The
97 //          medium has
98 //          modes of verbosity and depending on the verbosity set determines
99 //          which data is
100 //          sent to the medium's output.
101 // Type:    Method.
102 // Args:    vData       - (R) The data to write to the logger.
103 //          veType      - (R) Verbosity type.
104 // Return:  MIstatus::success - Functional succeeded.
105 //          MIstatus::failure - Functional failed.
106 // Throws:  None.
107 //--
108 bool CMICmnLogMediumFile::Write(const CMIUtilString &vData,
109                                 const CMICmnLog::ELogVerbosity veType) {
110   if (m_bInitialized && m_file.IsOk()) {
111     const bool bDoWrite = (m_eVerbosityType & veType);
112     if (bDoWrite) {
113       bool bNewCreated = false;
114       bool bOk = m_file.CreateWrite(m_fileNamePath, bNewCreated);
115       if (bOk) {
116         if (bNewCreated)
117           bOk = FileWriteHeader();
118         bOk = bOk && FileWriteEnglish(MassagedData(vData, veType));
119       }
120       return bOk;
121     }
122   }
123
124   return MIstatus::failure;
125 }
126
127 //++
128 // Details: Retrieve *this medium's last error condition.
129 // Type:    Method.
130 // Args:    None.
131 // Return:  CString & -  Text description.
132 // Throws:  None.
133 //--
134 const CMIUtilString &CMICmnLogMediumFile::GetError() const {
135   return m_strMILastErrorDescription;
136 }
137
138 //++
139 // Details: Set the verbosity mode for this medium.
140 // Type:    Method.
141 // Args:    veType  - (R) Mask value.
142 // Return:  MIstatus::success - Functional succeeded.
143 //          MIstatus::failure - Functional failed.
144 // Throws:  None.
145 //--
146 bool CMICmnLogMediumFile::SetVerbosity(const MIuint veType) {
147   m_eVerbosityType = veType;
148   return MIstatus::success;
149 }
150
151 //++
152 // Details: Get the verbosity mode for this medium.
153 // Type:    Method.
154 // Args:    veType  - (R) Mask value.
155 // Return:  CMICmnLog::ELogVerbosity - Mask value.
156 // Throws:  None.
157 //--
158 MIuint CMICmnLogMediumFile::GetVerbosity() const { return m_eVerbosityType; }
159
160 //++
161 // Details: Write data to a file English font.
162 // Type:    Method.
163 // Args:    vData   - (R) The data to write to the logger.
164 // Return:  None.
165 // Throws:  None.
166 //--
167 bool CMICmnLogMediumFile::FileWriteEnglish(const CMIUtilString &vData) {
168   return m_file.Write(vData);
169 }
170
171 //++
172 // Details: Determine and form the medium file's directory path and name.
173 // Type:    Method.
174 // Args:    None.
175 // Return:  MIstatus::success - Functional succeeded.
176 //          MIstatus::failure - Functional failed.
177 // Throws:  None.
178 //--
179 bool CMICmnLogMediumFile::FileFormFileNamePath() {
180   ClrErrorDescription();
181
182   m_fileNamePath = MIRSRC(IDS_MEDIUMFILE_ERR_INVALID_PATH);
183
184   CMIUtilDateTimeStd date;
185   m_strMediumFileName =
186       CMIUtilString::Format(m_constMediumFileNameFormat.c_str(),
187                             date.GetDateTimeLogFilename().c_str());
188
189 #if defined(_MSC_VER)
190   m_fileNamePath = CMIUtilString::Format(
191       "%s\\%s", m_strMediumFileDirectory.c_str(), m_strMediumFileName.c_str());
192 #else
193   m_fileNamePath = CMIUtilString::Format(
194       "%s/%s", m_strMediumFileDirectory.c_str(), m_strMediumFileName.c_str());
195 #endif // defined ( _MSC_VER )
196
197   return MIstatus::success;
198 }
199
200 //++
201 // Details: Retrieve the medium file's directory path and name.
202 // Type:    Method.
203 // Args:    None.
204 // Return:  CMIUtilString & - File path.
205 // Throws:  None.
206 //--
207 const CMIUtilString &CMICmnLogMediumFile::GetFileNamePath() const {
208   return m_fileNamePath;
209 }
210
211 //++
212 // Details: Retrieve the medium file's name.
213 // Type:    Method.
214 // Args:    None.
215 // Return:  CMIUtilString & - File name.
216 // Throws:  None.
217 //--
218 const CMIUtilString &CMICmnLogMediumFile::GetFileName() const {
219   return m_strMediumFileName;
220 }
221
222 //++
223 // Details: Massage the data to behave correct when submitted to file. Insert
224 // extra log
225 //          specific text. The veType is there to allow in the future to parse
226 //          the log and
227 //          filter in out specific types of message to make viewing the log more
228 //          manageable.
229 // Type:    Method.
230 // Args:    vData   - (R) Raw data.
231 //          veType  - (R) Message type.
232 // Return:  CMIUtilString - Massaged data.
233 // Throws:  None.
234 //--
235 CMIUtilString
236 CMICmnLogMediumFile::MassagedData(const CMIUtilString &vData,
237                                   const CMICmnLog::ELogVerbosity veType) {
238   const CMIUtilString strCr("\n");
239   CMIUtilString data;
240   const char verbosityCode(ConvertLogVerbosityTypeToId(veType));
241   const CMIUtilString dt(CMIUtilString::Format("%s %s", m_strDate.c_str(),
242                                                m_dateTime.GetTime().c_str()));
243
244   data = CMIUtilString::Format("%c,%s,%s", verbosityCode, dt.c_str(),
245                                vData.c_str());
246   data = ConvertCr(data);
247
248   // Look for EOL...
249   const size_t pos = vData.rfind(strCr);
250   if (pos == vData.size())
251     return data;
252
253   // ... did not have an EOL so add one
254   data += GetLineReturn();
255
256   return data;
257 }
258
259 //++
260 // Details: Convert the Log's verbosity type number into a single char
261 // character.
262 // Type:    Method.
263 // Args:    veType  - (R) Message type.
264 // Return:  wchar_t - A letter.
265 // Throws:  None.
266 //--
267 char CMICmnLogMediumFile::ConvertLogVerbosityTypeToId(
268     const CMICmnLog::ELogVerbosity veType) const {
269   char c = 0;
270   if (veType != 0) {
271     MIuint cnt = 0;
272     MIuint number(veType);
273     while (1 != number) {
274       number = number >> 1;
275       ++cnt;
276     }
277     c = 'A' + cnt;
278   } else {
279     c = '*';
280   }
281
282   return c;
283 }
284
285 //++
286 // Details: Retrieve state of whether the file medium is ok.
287 // Type:    Method.
288 // Args:    None.
289 // Return:  True - file ok.
290 //          False - file has a problem.
291 // Throws:  None.
292 //--
293 bool CMICmnLogMediumFile::IsOk() const { return m_file.IsOk(); }
294
295 //++
296 // Details: Status on the file log medium existing already.
297 // Type:    Method.
298 // Args:    None.
299 // Return:  True - Exists.
300 //          False - Not found.
301 // Throws:  None.
302 //--
303 bool CMICmnLogMediumFile::IsFileExist() const {
304   return m_file.IsFileExist(GetFileNamePath());
305 }
306
307 //++
308 // Details: Write the header text the logger file.
309 // Type:    Method.
310 // Args:    vText   - (R) Text.
311 // Return:  MIstatus::success - Functional succeeded.
312 //          MIstatus::failure - Functional failed.
313 // Throws:  None.
314 //--
315 bool CMICmnLogMediumFile::FileWriteHeader() {
316   return FileWriteEnglish(ConvertCr(m_fileHeaderTxt));
317 }
318
319 //++
320 // Details: Convert any carriage line returns to be compatible with the platform
321 // the
322 //          Log file is being written to.
323 // Type:    Method.
324 // Args:    vData   - (R) Text data.
325 // Return:  CMIUtilString - Converted string data.
326 // Throws:  None.
327 //--
328 CMIUtilString CMICmnLogMediumFile::ConvertCr(const CMIUtilString &vData) const {
329   const CMIUtilString strCr("\n");
330   const CMIUtilString &rCrCmpat(GetLineReturn());
331
332   if (strCr == rCrCmpat)
333     return vData;
334
335   const size_t nSizeCmpat(rCrCmpat.size());
336   const size_t nSize(strCr.size());
337   CMIUtilString strConv(vData);
338   size_t pos = strConv.find(strCr);
339   while (pos != CMIUtilString::npos) {
340     strConv.replace(pos, nSize, rCrCmpat);
341     pos = strConv.find(strCr, pos + nSizeCmpat);
342   }
343
344   return strConv;
345 }
346
347 //++
348 // Details: Set the header text that is written to the logger file at the
349 // beginning.
350 // Type:    Method.
351 // Args:    vText   - (R) Text.
352 // Return:  MIstatus::success - Functional succeeded.
353 //          MIstatus::failure - Functional failed.
354 // Throws:  None.
355 //--
356 bool CMICmnLogMediumFile::SetHeaderTxt(const CMIUtilString &vText) {
357   m_fileHeaderTxt = vText;
358
359   return MIstatus::success;
360 }
361
362 //++
363 // Details: Retrieve the file current carriage line return characters used.
364 // Type:    Method.
365 // Args:    None.
366 // Return:  CMIUtilString & - Text.
367 // Throws:  None.
368 //--
369 const CMIUtilString &CMICmnLogMediumFile::GetLineReturn() const {
370   return m_file.GetLineReturn();
371 }
372
373 //++
374 // Details: Set the directory to place the log file.
375 // Type:    Method.
376 // Args:    vPath   - (R) Path to log.
377 // Return:  MIstatus::success - Functional succeeded.
378 //          MIstatus::failure - Functional failed.
379 // Throws:  None.
380 //--
381 bool CMICmnLogMediumFile::SetDirectory(const CMIUtilString &vPath) {
382   m_strMediumFileDirectory = vPath;
383
384   return FileFormFileNamePath();
385 }