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