]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/tools/lldb-mi/MICmnStreamStderr.cpp
Merge llvm 3.6.0rc2 from ^/vendor/llvm/dist, merge clang 3.6.0rc2 from
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / tools / lldb-mi / MICmnStreamStderr.cpp
1 //===-- MICmnStreamStderr.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:                MICmnStreamStderr.cpp
12 //
13 // Overview:    CMICmnStreamStderr 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 "MICmnStreamStderr.h"
24 #include "MICmnLog.h"
25 #include "MICmnResources.h"
26 #include "MIDriver.h"
27
28 //++ ------------------------------------------------------------------------------------
29 // Details:     CMICmnStreamStderr constructor.
30 // Type:        Method.
31 // Args:        None.
32 // Return:      None.
33 // Throws:      None.
34 //--
35 CMICmnStreamStderr::CMICmnStreamStderr( void )
36 {
37 }
38
39 //++ ------------------------------------------------------------------------------------
40 // Details:     CMICmnStreamStderr destructor.
41 // Type:        Overridable.
42 // Args:        None.
43 // Return:      None.
44 // Throws:      None.
45 //--
46 CMICmnStreamStderr::~CMICmnStreamStderr( void )
47 {
48         Shutdown();
49 }
50
51 //++ ------------------------------------------------------------------------------------
52 // Details:     Initialize resources for *this stderr stream.
53 // Type:        Method.
54 // Args:        None.
55 // Return:      MIstatus::success - Functional succeeded.
56 //                      MIstatus::failure - Functional failed.
57 // Throws:      None.
58 //--
59 bool CMICmnStreamStderr::Initialize( void )
60 {
61         m_clientUsageRefCnt++;
62
63         if( m_bInitialized )
64                 return MIstatus::success;
65
66         bool bOk = MIstatus::success;
67         
68 #ifdef _MSC_VER
69         // Debugging / I/O issues with client.
70         // This is only required on Windows if you do not use ::flush(stderr). MI uses 
71         // ::flush(stderr)
72         // It trys to ensure the process attached to the stderr steam gets ALL the data.
73         //::setbuf( stderr, NULL );
74 #endif // _MSC_VER
75         
76         m_bInitialized = bOk;
77
78         return  MIstatus::success;
79 }
80
81 //++ ------------------------------------------------------------------------------------
82 // Details:     Release resources for *this stderr stream.
83 // Type:        Method.
84 // Args:        None.
85 // Return:      MIstatus::success - Functional succeeded.
86 //                      MIstatus::failure - Functional failed.
87 // Throws:      None.
88 //--
89 bool CMICmnStreamStderr::Shutdown( void )
90 {
91         if( --m_clientUsageRefCnt > 0 )
92                 return MIstatus::success;
93         
94         if( !m_bInitialized )
95                 return MIstatus::success;
96
97         ClrErrorDescription();
98
99         m_bInitialized = false;
100
101         return MIstatus::success;
102 }       
103
104 //++ ------------------------------------------------------------------------------------
105 // Details:     Write text data to stderr. Prefix the message with "MI:". The text data does 
106 //                      not need to include a carrage line return as this is added to the text. The 
107 //                      function also then passes the text data into the CMICmnLog logger.
108 // Type:        Method.
109 // Args:        vText           - (R) Text data.
110 //                      vbSendToLog     - (R) True = Yes send to the Log file too, false = do not. (Dflt = true)
111 // Return:      MIstatus::success - Functional succeeded.
112 //                      MIstatus::failure - Functional failed.
113 // Throws:      None.
114 //--
115 bool CMICmnStreamStderr::Write( const CMIUtilString & vText, const bool vbSendToLog /* = true */ )
116 {
117         if( vText.length() == 0 )
118                 return MIstatus::failure;
119
120         const CMIUtilString strPrefixed( CMIUtilString::Format( "%s: %s", CMIDriver::Instance().GetAppNameShort().c_str(), vText.c_str() ) );
121
122         return WritePriv( strPrefixed, vText, vbSendToLog );
123 }
124
125 //++ ------------------------------------------------------------------------------------
126 // Details:     Write an LLDB text message to stderr. 
127 //                      The text data does not need to include a carrage line return as this is added 
128 //                      to the text. The function also then passes the text data into the CMICmnLog 
129 //                      logger.
130 // Type:        Method.
131 // Args:        vText           - (R) Text data.
132 //                      vbSendToLog     - (R) True = Yes send to the Log file too, false = do not. (Dflt = true)
133 // Return:      MIstatus::success - Functional succeeded.
134 //                      MIstatus::failure - Functional failed.
135 // Throws:      None.
136 //--
137 bool CMICmnStreamStderr::WriteLLDBMsg( const CMIUtilString & vText, const bool vbSendToLog /* = true */ )
138 {
139         if( vText.length() == 0 )
140                 return MIstatus::failure;
141
142         const CMIUtilString strPrefixed( CMIUtilString::Format( "LLDB: %s", vText.c_str() ) );
143
144         return WritePriv( vText, strPrefixed, vbSendToLog );
145 }
146
147 //++ ------------------------------------------------------------------------------------
148 // Details:     Write text data to stderr. The text data does not need to
149 //                      include a carrage line return as this is added to the text. The function also
150 //                      then passes the text data into the CMICmnLog logger.
151 // Type:        Method.
152 // Args:        vText                   - (R) Text data. May be prefixed with MI app's short name.
153 //                      vTxtForLogFile  - (R) Text data.
154 //                      vbSendToLog             - (R) True = Yes send to the Log file too, false = do not. (Dflt = true)
155 // Return:      MIstatus::success - Functional succeeded.
156 //                      MIstatus::failure - Functional failed.
157 // Throws:      None.
158 //--
159 bool CMICmnStreamStderr::WritePriv( const CMIUtilString & vText, const CMIUtilString & vTxtForLogFile, const bool vbSendToLog /* = true */ )
160 {
161         if( vText.length() == 0 )
162                 return MIstatus::failure;
163
164         bool bOk = MIstatus::success;
165         {
166                 // Grab the stderr thread lock while we print
167                 CMIUtilThreadLock _lock( m_mutex );
168
169                 // Send this text to stderr
170                 const MIuint status = ::fputs( vText.c_str(), stderr );
171                 if( status == EOF )
172                 {
173                         const CMIUtilString errMsg( CMIUtilString::Format( MIRSRC( IDS_STDERR_ERR_NOT_ALL_DATA_WRITTEN ), vText.c_str() ) );
174                         SetErrorDescription( errMsg );
175                         bOk = MIstatus::failure;
176                 }
177                 else
178                 {
179                         ::fprintf( stderr, "\n" );
180                         ::fflush( stderr );
181                 }
182
183                 // Send this text to the log
184                 if( bOk && vbSendToLog )
185                         bOk &= m_pLog->WriteLog( vTxtForLogFile );
186         }
187         
188         return bOk;
189 }
190
191 //++ ------------------------------------------------------------------------------------
192 // Details:     Lock the availability of the stream stderr. Other users of *this stream will 
193 //                      be stalled until it is available (Unlock()).
194 // Type:        Method.
195 // Args:        None.
196 // Return:      MIstatus::success - Functional succeeded.
197 //                      MIstatus::failure - Functional failed.
198 // Throws:      None.
199 //--
200 bool CMICmnStreamStderr::Lock( void )
201 {
202         m_mutex.Lock();
203         return MIstatus::success;
204 }
205
206 //++ ------------------------------------------------------------------------------------
207 // Details:     Release a previously locked stderr.
208 // Type:        Method.
209 // Args:        None.
210 // Return:      MIstatus::success - Functional succeeded.
211 //                      MIstatus::failure - Functional failed.
212 // Throws:      None.
213 //--
214 bool CMICmnStreamStderr::Unlock( void )
215 {
216         m_mutex.Unlock();
217         return MIstatus::success;
218 }
219
220 //++ ------------------------------------------------------------------------------------
221 // Details:     Take MI Driver text message and send to the stderr stream. Also output to the
222 //                       MI Log file.
223 // Type:        Static method.
224 // Args:        vrTxt   - (R) Text.
225 // Return:      MIstatus::success - Functionality succeeded.
226 //                      MIstatus::failure - Functionality failed.
227 // Throws:      None.
228 //--
229 bool CMICmnStreamStderr::TextToStderr( const CMIUtilString & vrTxt )
230 {
231         const bool bLock = CMICmnStreamStderr::Instance().Lock();
232         const bool bOk = bLock && CMICmnStreamStderr::Instance().Write( vrTxt );
233         bLock && CMICmnStreamStderr::Instance().Unlock();
234         
235         return bOk;
236 }
237
238 //++ ------------------------------------------------------------------------------------
239 // Details:     Take an LLDB message and send to the stderr stream. The message is not always
240 //                      an error message. The user has typed a command in to the Eclipse console (by-
241 //                      passing Eclipse) and this is the result message from LLDB back to the user.
242 //                      Also output to the MI Log file.
243 // Type:        Static method.
244 // Args:        vrTxt   - (R) Text.
245 // Return:      MIstatus::success - Functionality succeeded.
246 //                      MIstatus::failure - Functionality failed.
247 // Throws:      None.
248 //--
249 bool CMICmnStreamStderr::LLDBMsgToConsole( const CMIUtilString & vrTxt )
250 {
251         const bool bLock = CMICmnStreamStderr::Instance().Lock();
252         const bool bOk = bLock && CMICmnStreamStderr::Instance().WriteLLDBMsg( vrTxt );
253         bLock && CMICmnStreamStderr::Instance().Unlock();
254         
255         return bOk;
256 }
257