]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/tools/lldb-mi/MIUtilFileStd.cpp
MFV r288408:
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / tools / lldb-mi / MIUtilFileStd.cpp
1 //===-- MIUtilFileStd.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:        MIUtilFileStd.cpp
12 //
13 // Overview:    CMIUtilFileStd 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 // Third party headers
23 #include <stdio.h>
24 #include <assert.h>
25 #include <string.h> // For strerror()
26 #include <cerrno>
27
28 // In-house headers:
29 #include "MIUtilFileStd.h"
30 #include "MICmnResources.h"
31
32 //++ ------------------------------------------------------------------------------------
33 // Details: CMIUtilFileStd constructor.
34 // Type:    Method.
35 // Args:    None.
36 // Return:  None.
37 // Throws:  None.
38 //--
39 CMIUtilFileStd::CMIUtilFileStd(void)
40     : m_fileNamePath(CMIUtilString())
41     , m_pFileHandle(nullptr)
42 #if defined(_MSC_VER)
43     , m_constCharNewLine("\r\n")
44 #else
45     , m_constCharNewLine("\n")
46 #endif // #if defined( _MSC_VER )
47     , m_bFileError(false)
48 {
49 }
50
51 //++ ------------------------------------------------------------------------------------
52 // Details: CMIUtilFileStd destructor.
53 // Type:    Method.
54 // Args:    None.
55 // Return:  None.
56 // Throws:  None.
57 //--
58 CMIUtilFileStd::~CMIUtilFileStd(void)
59 {
60     Close();
61 }
62
63 //++ ------------------------------------------------------------------------------------
64 // Details: Open file for writing. On the first call to this function after *this object
65 //          is created the file is either created or replace, from then on open only opens
66 //          an existing file.
67 // Type:    Method.
68 // Args:    vFileNamePath   - (R) File name path.
69 //          vwrbNewCreated  - (W) True - file recreated, false - file appended too.
70 // Return:  MIstatus::success - Functional succeeded.
71 //          MIstatus::failure - Functional failed.
72 // Throws:  None.
73 //--
74 bool
75 CMIUtilFileStd::CreateWrite(const CMIUtilString &vFileNamePath, bool &vwrbNewCreated)
76 {
77     // Reset
78     m_bFileError = false;
79     vwrbNewCreated = false;
80
81     if (vFileNamePath.empty())
82     {
83         m_bFileError = true;
84         SetErrorDescription(MIRSRC(IDS_UTIL_FILE_ERR_INVALID_PATHNAME));
85         return MIstatus::failure;
86     }
87
88     // File is already open so exit
89     if (m_pFileHandle != nullptr)
90         return MIstatus::success;
91
92 #if !defined(_MSC_VER)
93     // Open with 'write' and 'binary' mode
94     m_pFileHandle = ::fopen(vFileNamePath.c_str(), "wb");
95 #else
96     // Open a file with exclusive write and shared read permissions
97     m_pFileHandle = ::_fsopen(vFileNamePath.c_str(), "wb", _SH_DENYWR);
98 #endif // !defined( _MSC_VER )
99
100     if (m_pFileHandle == nullptr)
101     {
102         m_bFileError = true;
103         SetErrorDescriptionn(MIRSRC(IDS_UTIL_FILE_ERR_OPENING_FILE), strerror(errno), vFileNamePath.c_str());
104         return MIstatus::failure;
105     }
106
107     vwrbNewCreated = true;
108     m_fileNamePath = vFileNamePath;
109
110     return MIstatus::success;
111 }
112
113 //++ ------------------------------------------------------------------------------------
114 // Details: Write data to existing opened file.
115 // Type:    Method.
116 // Args:    vData - (R) Text data.
117 // Return:  MIstatus::success - Functional succeeded.
118 //          MIstatus::failure - Functional failed.
119 // Throws:  None.
120 //--
121 bool
122 CMIUtilFileStd::Write(const CMIUtilString &vData)
123 {
124     if (vData.size() == 0)
125         return MIstatus::success;
126
127     if (m_bFileError)
128         return MIstatus::failure;
129
130     if (m_pFileHandle == nullptr)
131     {
132         m_bFileError = true;
133         SetErrorDescriptionn(MIRSRC(IDE_UTIL_FILE_ERR_WRITING_NOTOPEN), m_fileNamePath.c_str());
134         return MIstatus::failure;
135     }
136
137     // Get the string size
138     MIuint size = vData.size();
139     if (::fwrite(vData.c_str(), 1, size, m_pFileHandle) == size)
140     {
141         // Flush the data to the file
142         ::fflush(m_pFileHandle);
143         return MIstatus::success;
144     }
145
146     // Not all of the data has been transferred
147     m_bFileError = true;
148     SetErrorDescriptionn(MIRSRC(IDE_UTIL_FILE_ERR_WRITING_FILE), m_fileNamePath.c_str());
149     return MIstatus::failure;
150 }
151
152 //++ ------------------------------------------------------------------------------------
153 // Details: Write data to existing opened file.
154 // Type:    Method.
155 // Args:    vData       - (R) Text data.
156 //          vCharCnt    - (R) Text data length.
157 // Return:  MIstatus::success - Functional succeeded.
158 //          MIstatus::failure - Functional failed.
159 // Throws:  None.
160 //--
161 bool
162 CMIUtilFileStd::Write(const MIchar *vpData, const MIuint vCharCnt)
163 {
164     if (vCharCnt == 0)
165         return MIstatus::success;
166
167     if (m_bFileError)
168         return MIstatus::failure;
169
170     if (m_pFileHandle == nullptr)
171     {
172         m_bFileError = true;
173         SetErrorDescriptionn(MIRSRC(IDE_UTIL_FILE_ERR_WRITING_NOTOPEN), m_fileNamePath.c_str());
174         return MIstatus::failure;
175     }
176
177     if (::fwrite(vpData, 1, vCharCnt, m_pFileHandle) == vCharCnt)
178     {
179         // Flush the data to the file
180         ::fflush(m_pFileHandle);
181         return MIstatus::success;
182     }
183
184     // Not all of the data has been transferred
185     m_bFileError = true;
186     SetErrorDescriptionn(MIRSRC(IDE_UTIL_FILE_ERR_WRITING_FILE), m_fileNamePath.c_str());
187     return MIstatus::failure;
188 }
189
190 //++ ------------------------------------------------------------------------------------
191 // Details: Close existing opened file. Note Close() must must an open!
192 // Type:    Method.
193 // Args:    None.
194 // Return:  None.
195 // Throws:  None.
196 //--
197 void
198 CMIUtilFileStd::Close(void)
199 {
200     if (m_pFileHandle == nullptr)
201         return;
202
203     ::fclose(m_pFileHandle);
204     m_pFileHandle = nullptr;
205     // m_bFileError = false; Do not reset as want to remain until next attempt at open or create
206 }
207
208 //++ ------------------------------------------------------------------------------------
209 // Details: Retrieve state of whether the file is ok.
210 // Type:    Method.
211 // Args:    None.
212 // Return:  True - file ok.
213 //          False - file has a problem.
214 // Throws:  None.
215 //--
216 bool
217 CMIUtilFileStd::IsOk(void) const
218 {
219     return !m_bFileError;
220 }
221
222 //++ ------------------------------------------------------------------------------------
223 // Details: Status on a file existing already.
224 // Type:    Method.
225 // Args:    vFileNamePath.
226 // Return:  True - Exists.
227 //          False - Not found.
228 // Throws:  None.
229 //--
230 bool
231 CMIUtilFileStd::IsFileExist(const CMIUtilString &vFileNamePath) const
232 {
233     if (vFileNamePath.empty())
234         return false;
235
236     FILE *pTmp = nullptr;
237     pTmp = ::fopen(vFileNamePath.c_str(), "wb");
238     if (pTmp != nullptr)
239     {
240         ::fclose(pTmp);
241         return true;
242     }
243
244     return false;
245 }
246
247 //++ ------------------------------------------------------------------------------------
248 // Details: Retrieve the file current carriage line return characters used.
249 // Type:    Method.
250 // Args:    None.
251 // Return:  CMIUtilString & - Text.
252 // Throws:  None.
253 //--
254 const CMIUtilString &
255 CMIUtilFileStd::GetLineReturn(void) const
256 {
257     return m_constCharNewLine;
258 }
259
260 //++ ------------------------------------------------------------------------------------
261 // Details: Given a file name directory path, strip off the filename and return the path.
262 //          It look for either backslash or forward slash.
263 // Type:    Method.
264 // Args:    vDirectoryPath  - (R) Text directory path.
265 // Return:  CMIUtilString - Directory path.
266 // Throws:  None.
267 //--
268 CMIUtilString
269 CMIUtilFileStd::StripOffFileName(const CMIUtilString &vDirectoryPath) const
270 {
271     const MIint nPos = vDirectoryPath.rfind('\\');
272     MIint nPos2 = vDirectoryPath.rfind('/');
273     if ((nPos == (MIint)std::string::npos) && (nPos2 == (MIint)std::string::npos))
274         return vDirectoryPath;
275
276     if (nPos > nPos2)
277         nPos2 = nPos;
278
279     const CMIUtilString strPath(vDirectoryPath.substr(0, nPos2).c_str());
280     return strPath;
281 }
282
283 //++ ------------------------------------------------------------------------------------
284 // Details: Return either backslash or forward slash appropriate to the OS this applilcation
285 //          is running on.
286 // Type:    Static method.
287 // Args:    None.
288 // Return:  MIchar - '/' or '\' character.
289 // Throws:  None.
290 //--
291 MIchar
292 CMIUtilFileStd::GetSlash(void)
293 {
294 #if !defined(_MSC_VER)
295     return '/';
296 #else
297     return '\\';
298 #endif // !defined( _MSC_VER )
299 }