1 //===-- CommandReturnObject.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 #include "lldb/Interpreter/CommandReturnObject.h"
11 
12 // C Includes
13 // C++ Includes
14 // Other libraries and framework includes
15 // Project includes
16 #include "lldb/Core/Error.h"
17 #include "lldb/Core/StreamString.h"
18 
19 using namespace lldb;
20 using namespace lldb_private;
21 
22 static void
23 DumpStringToStreamWithNewline (Stream &strm, const std::string &s, bool add_newline_if_empty)
24 {
25     bool add_newline = false;
26     if (s.empty())
27     {
28         add_newline = add_newline_if_empty;
29     }
30     else
31     {
32         // We already checked for empty above, now make sure there is a newline
33         // in the error, and if there isn't one, add one.
34         strm.Write(s.c_str(), s.size());
35 
36         const char last_char = *s.rbegin();
37         add_newline = last_char != '\n' && last_char != '\r';
38 
39     }
40     if (add_newline)
41         strm.EOL();
42 }
43 
44 
45 CommandReturnObject::CommandReturnObject () :
46     m_out_stream (),
47     m_err_stream (),
48     m_status (eReturnStatusStarted),
49     m_did_change_process_state (false),
50     m_interactive (true),
51     m_abnormal_stop_was_expected(false)
52 {
53 }
54 
55 CommandReturnObject::~CommandReturnObject ()
56 {
57 }
58 
59 void
60 CommandReturnObject::AppendErrorWithFormat (const char *format, ...)
61 {
62     if (!format)
63         return;
64     va_list args;
65     va_start (args, format);
66     StreamString sstrm;
67     sstrm.PrintfVarArg(format, args);
68     va_end (args);
69 
70 
71     const std::string &s = sstrm.GetString();
72     if (!s.empty())
73     {
74         Stream &error_strm = GetErrorStream();
75         error_strm.PutCString ("error: ");
76         DumpStringToStreamWithNewline (error_strm, s, false);
77     }
78 }
79 
80 void
81 CommandReturnObject::AppendMessageWithFormat (const char *format, ...)
82 {
83     if (!format)
84         return;
85     va_list args;
86     va_start (args, format);
87     StreamString sstrm;
88     sstrm.PrintfVarArg(format, args);
89     va_end (args);
90 
91     GetOutputStream().Printf("%s", sstrm.GetData());
92 }
93 
94 void
95 CommandReturnObject::AppendWarningWithFormat (const char *format, ...)
96 {
97     if (!format)
98         return;
99     va_list args;
100     va_start (args, format);
101     StreamString sstrm;
102     sstrm.PrintfVarArg(format, args);
103     va_end (args);
104 
105     GetErrorStream().Printf("warning: %s", sstrm.GetData());
106 }
107 
108 void
109 CommandReturnObject::AppendMessage (const char *in_string)
110 {
111     if (!in_string)
112         return;
113     GetOutputStream().Printf("%s\n", in_string);
114 }
115 
116 void
117 CommandReturnObject::AppendWarning (const char *in_string)
118 {
119     if (!in_string || *in_string == '\0')
120         return;
121     GetErrorStream().Printf("warning: %s\n", in_string);
122 }
123 
124 // Similar to AppendWarning, but do not prepend 'warning: ' to message, and
125 // don't append "\n" to the end of it.
126 
127 void
128 CommandReturnObject::AppendRawWarning (const char *in_string)
129 {
130     if (in_string && in_string[0])
131         GetErrorStream().PutCString(in_string);
132 }
133 
134 void
135 CommandReturnObject::AppendError (const char *in_string)
136 {
137     if (!in_string || *in_string == '\0')
138         return;
139     GetErrorStream().Printf ("error: %s\n", in_string);
140 }
141 
142 void
143 CommandReturnObject::SetError (const Error &error, const char *fallback_error_cstr)
144 {
145     const char *error_cstr = error.AsCString();
146     if (error_cstr == nullptr)
147         error_cstr = fallback_error_cstr;
148     SetError(error_cstr);
149 }
150 
151 void
152 CommandReturnObject::SetError (const char *error_cstr)
153 {
154     if (error_cstr)
155     {
156         AppendError (error_cstr);
157         SetStatus (eReturnStatusFailed);
158     }
159 }
160 
161 // Similar to AppendError, but do not prepend 'Error: ' to message, and
162 // don't append "\n" to the end of it.
163 
164 void
165 CommandReturnObject::AppendRawError (const char *in_string)
166 {
167     if (in_string && in_string[0])
168         GetErrorStream().PutCString(in_string);
169 }
170 
171 void
172 CommandReturnObject::SetStatus (ReturnStatus status)
173 {
174     m_status = status;
175 }
176 
177 ReturnStatus
178 CommandReturnObject::GetStatus ()
179 {
180     return m_status;
181 }
182 
183 bool
184 CommandReturnObject::Succeeded ()
185 {
186     return m_status <= eReturnStatusSuccessContinuingResult;
187 }
188 
189 bool
190 CommandReturnObject::HasResult ()
191 {
192     return (m_status == eReturnStatusSuccessFinishResult ||
193             m_status == eReturnStatusSuccessContinuingResult);
194 }
195 
196 void
197 CommandReturnObject::Clear()
198 {
199     lldb::StreamSP stream_sp;
200     stream_sp = m_out_stream.GetStreamAtIndex (eStreamStringIndex);
201     if (stream_sp)
202         static_cast<StreamString *>(stream_sp.get())->Clear();
203     stream_sp = m_err_stream.GetStreamAtIndex (eStreamStringIndex);
204     if (stream_sp)
205         static_cast<StreamString *>(stream_sp.get())->Clear();
206     m_status = eReturnStatusStarted;
207     m_did_change_process_state = false;
208     m_interactive = true;
209 }
210 
211 bool
212 CommandReturnObject::GetDidChangeProcessState ()
213 {
214     return m_did_change_process_state;
215 }
216 
217 void
218 CommandReturnObject::SetDidChangeProcessState (bool b)
219 {
220     m_did_change_process_state = b;
221 }
222 
223 
224 bool
225 CommandReturnObject::GetInteractive () const
226 {
227     return m_interactive;
228 }
229 
230 void
231 CommandReturnObject::SetInteractive (bool b)
232 {
233     m_interactive = b;
234 }
235 
236 
237