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