]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/tools/lldb-mi/MICmnStreamStdout.cpp
Merge ^/head r274961 through r276342.
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / tools / lldb-mi / MICmnStreamStdout.cpp
1 //===-- MIUtilStreamStdout.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:                MIUtilStreamcStdout.cpp
12 //
13 // Overview:    CMICmnStreamStdout 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 "MICmnStreamStdout.h"
24 #include "MICmnLog.h"
25 #include "MICmnResources.h"
26 #include "MIDriver.h"
27
28 //++ ------------------------------------------------------------------------------------
29 // Details:     CMICmnStreamStdout constructor.
30 // Type:        Method.
31 // Args:        None.
32 // Return:      None.
33 // Throws:      None.
34 //--
35 CMICmnStreamStdout::CMICmnStreamStdout( void )
36 {
37 }
38
39 //++ ------------------------------------------------------------------------------------
40 // Details:     CMICmnStreamStdout destructor.
41 // Type:        Overridable.
42 // Args:        None.
43 // Return:      None.
44 // Throws:      None.
45 //--
46 CMICmnStreamStdout::~CMICmnStreamStdout( void )
47 {
48         Shutdown();
49 }
50
51 //++ ------------------------------------------------------------------------------------
52 // Details:     Initialize resources for *this Stdout stream.
53 // Type:        Method.
54 // Args:        None.
55 // Return:      MIstatus::success - Functional succeeded.
56 //                      MIstatus::failure - Functional failed.
57 // Throws:      None.
58 //--
59 bool CMICmnStreamStdout::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(stdout). MI uses 
71         // ::flush(stdout)
72         // It trys to ensure the process attached to the stdout steam gets ALL the data.
73         //::setbuf( stdout, NULL );
74 #endif // _MSC_VER
75         
76         m_bInitialized = bOk;
77
78         return  MIstatus::success;
79 }
80
81 //++ ------------------------------------------------------------------------------------
82 // Details:     Release resources for *this Stdout stream.
83 // Type:        Method.
84 // Args:        None.
85 // Return:      MIstatus::success - Functional succeeded.
86 //                      MIstatus::failure - Functional failed.
87 // Throws:      None.
88 //--
89 bool CMICmnStreamStdout::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 an MI format type response to stdout. The text data does not need to
106 //                      include a carrage line return as this is added to the text. The function also
107 //                      then passes the text data into the CMICmnLog logger.
108 // Type:        Method.
109 // Args:        vText           - (R) MI formatted text.
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 CMICmnStreamStdout::WriteMIResponse( const CMIUtilString & vText, const bool vbSendToLog /* = true */ )
116 {
117         return WritePriv( vText, vText, vbSendToLog );
118 }
119
120 //++ ------------------------------------------------------------------------------------
121 // Details:     Write text data to stdout. The text data does not need to
122 //                      include a carrage line return as this is added to the text. The function also
123 //                      then passes the text data into the CMICmnLog logger.
124 // Type:        Method.
125 // Args:        vText           - (R) Text data.
126 //                      vbSendToLog     - (R) True = Yes send to the Log file too, false = do not. (Dflt = true)
127 // Return:      MIstatus::success - Functional succeeded.
128 //                      MIstatus::failure - Functional failed.
129 // Throws:      None.
130 //--
131 bool CMICmnStreamStdout::Write( const CMIUtilString & vText, const bool vbSendToLog /* = true */ )
132 {
133         if( vText.length() == 0 )
134                 return MIstatus::failure;
135
136         const CMIUtilString strPrefixed( CMIUtilString::Format( "%s: %s", CMIDriver::Instance().GetAppNameShort().c_str(), vText.c_str() ) );
137
138         return WritePriv( strPrefixed, vText, vbSendToLog );
139 }
140
141 //++ ------------------------------------------------------------------------------------
142 // Details:     Write text data to stdout. The text data does not need to
143 //                      include a carrage line return as this is added to the text. The function also
144 //                      then passes the text data into the CMICmnLog logger.
145 // Type:        Method.
146 // Args:        vText                   - (R) Text data prefixed with MI app's short name.
147 //                      vTxtForLogFile  - (R) Text data.
148 //                      vbSendToLog             - (R) True = Yes send to the Log file too, false = do not. (Dflt = true)
149 // Return:      MIstatus::success - Functional succeeded.
150 //                      MIstatus::failure - Functional failed.
151 // Throws:      None.
152 //--
153 bool CMICmnStreamStdout::WritePriv( const CMIUtilString & vText, const CMIUtilString & vTxtForLogFile, const bool vbSendToLog /* = true */ )
154 {
155         if( vText.length() == 0 )
156                 return MIstatus::failure;
157
158         bool bOk = MIstatus::success;
159         {
160                 // Grab the stdout thread lock while we print
161                 CMIUtilThreadLock _lock( m_mutex );
162
163                 // Send this text to stdout
164                 const MIuint status = ::fputs( vText.c_str(), stdout );
165                 if( status == EOF )
166                 {
167                         const CMIUtilString errMsg( CMIUtilString::Format( MIRSRC( IDS_STDOUT_ERR_NOT_ALL_DATA_WRITTEN ), vText.c_str() ) );
168                         SetErrorDescription( errMsg );
169                         bOk = MIstatus::failure;
170                 }
171                 else
172                 {
173                         ::fprintf( stdout, "\n" );
174                         ::fflush( stdout );
175                 }
176
177                 // Send this text to the log
178                 if( bOk && vbSendToLog )
179                         bOk &= m_pLog->WriteLog( vTxtForLogFile );
180         }
181         
182         return bOk;
183 }
184
185 //++ ------------------------------------------------------------------------------------
186 // Details:     Lock the availability of the stream stdout. Other users of *this stream will 
187 //                      be stalled until it is available (Unlock()).
188 // Type:        Method.
189 // Args:        None.
190 // Return:      MIstatus::success - Functional succeeded.
191 //                      MIstatus::failure - Functional failed.
192 // Throws:      None.
193 //--
194 bool CMICmnStreamStdout::Lock( void )
195 {
196         m_mutex.Lock();
197         return MIstatus::success;
198 }
199
200 //++ ------------------------------------------------------------------------------------
201 // Details:     Release a previously locked stdout.
202 // Type:        Method.
203 // Args:        None.
204 // Return:      MIstatus::success - Functional succeeded.
205 //                      MIstatus::failure - Functional failed.
206 // Throws:      None.
207 //--
208 bool CMICmnStreamStdout::Unlock( void )
209 {
210         m_mutex.Unlock();
211         return MIstatus::success;
212 }
213
214 //++ ------------------------------------------------------------------------------------
215 // Details:     Take a text data and send to the stdout stream. Also output to the MI Log
216 //                      file.
217 // Type:        Static method.
218 // Args:        vrTxt   - (R) Text.
219 // Return:      MIstatus::success - Functionality succeeded.
220 //                      MIstatus::failure - Functionality failed.
221 // Throws:      None.
222 //--
223 bool CMICmnStreamStdout::TextToStdout( const CMIUtilString & vrTxt )
224 {
225         const bool bLock = CMICmnStreamStdout::Instance().Lock();
226         const bool bOk = bLock && CMICmnStreamStdout::Instance().WriteMIResponse( vrTxt );
227         bLock && CMICmnStreamStdout::Instance().Unlock();
228         
229         return bOk;
230 }