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 {
51 }
52 
53 CommandReturnObject::~CommandReturnObject ()
54 {
55 }
56 
57 void
58 CommandReturnObject::AppendErrorWithFormat (const char *format, ...)
59 {
60     if (!format)
61         return;
62     va_list args;
63     va_start (args, format);
64     StreamString sstrm;
65     sstrm.PrintfVarArg(format, args);
66     va_end (args);
67 
68 
69     const std::string &s = sstrm.GetString();
70     if (!s.empty())
71     {
72         Stream &error_strm = GetErrorStream();
73         error_strm.PutCString ("error: ");
74         DumpStringToStreamWithNewline (error_strm, s, false);
75     }
76 }
77 
78 void
79 CommandReturnObject::AppendMessageWithFormat (const char *format, ...)
80 {
81     if (!format)
82         return;
83     va_list args;
84     va_start (args, format);
85     StreamString sstrm;
86     sstrm.PrintfVarArg(format, args);
87     va_end (args);
88 
89     GetOutputStream().Printf("%s", sstrm.GetData());
90 }
91 
92 void
93 CommandReturnObject::AppendWarningWithFormat (const char *format, ...)
94 {
95     if (!format)
96         return;
97     va_list args;
98     va_start (args, format);
99     StreamString sstrm;
100     sstrm.PrintfVarArg(format, args);
101     va_end (args);
102 
103     GetErrorStream().Printf("warning: %s", sstrm.GetData());
104 }
105 
106 void
107 CommandReturnObject::AppendMessage (const char *in_string, int len)
108 {
109     if (!in_string || len == 0)
110         return;
111     if (len < 0)
112 	    GetOutputStream().Printf("%s\n", in_string);
113 	else
114 	    GetOutputStream().Printf("%*.*s\n", len, len, in_string);
115 }
116 
117 void
118 CommandReturnObject::AppendWarning (const char *in_string, int len)
119 {
120     if (!in_string)
121         return;
122     if (len < 0)
123         len = ::strlen (in_string);
124     GetErrorStream().Printf("warning: %*.*s\n", len, len, in_string);
125 }
126 
127 // Similar to AppendWarning, but do not prepend 'warning: ' to message, and
128 // don't append "\n" to the end of it.
129 
130 void
131 CommandReturnObject::AppendRawWarning (const char *in_string, int len)
132 {
133     if (!in_string)
134         return;
135     if (len < 0)
136         len = ::strlen (in_string);
137     GetErrorStream().Printf("%*.*s", len, len, in_string);
138 }
139 
140 void
141 CommandReturnObject::AppendError (const char *in_string, int len)
142 {
143     if (!in_string)
144         return;
145     if (len < 0)
146         len = ::strlen (in_string);
147     GetErrorStream().Printf ("error: %*.*s\n", len, len, in_string);
148 }
149 
150 void
151 CommandReturnObject::SetError (const Error &error, const char *fallback_error_cstr)
152 {
153     const char *error_cstr = error.AsCString();
154     if (error_cstr == NULL)
155         error_cstr = fallback_error_cstr;
156     AppendError (error_cstr);
157     SetStatus (eReturnStatusFailed);
158 }
159 // Similar to AppendError, but do not prepend 'Error: ' to message, and
160 // don't append "\n" to the end of it.
161 
162 void
163 CommandReturnObject::AppendRawError (const char *in_string, int len)
164 {
165     if (!in_string)
166         return;
167     if (len < 0)
168         len = ::strlen (in_string);
169     GetErrorStream().Printf ("%*.*s", len, len, in_string);
170 }
171 
172 void
173 CommandReturnObject::SetStatus (ReturnStatus status)
174 {
175     m_status = status;
176 }
177 
178 ReturnStatus
179 CommandReturnObject::GetStatus ()
180 {
181     return m_status;
182 }
183 
184 bool
185 CommandReturnObject::Succeeded ()
186 {
187     return m_status <= eReturnStatusSuccessContinuingResult;
188 }
189 
190 bool
191 CommandReturnObject::HasResult ()
192 {
193     return (m_status == eReturnStatusSuccessFinishResult ||
194             m_status == eReturnStatusSuccessContinuingResult);
195 }
196 
197 void
198 CommandReturnObject::Clear()
199 {
200     lldb::StreamSP stream_sp;
201     stream_sp = m_out_stream.GetStreamAtIndex (eStreamStringIndex);
202     if (stream_sp)
203         static_cast<StreamString *>(stream_sp.get())->Clear();
204     stream_sp = m_err_stream.GetStreamAtIndex (eStreamStringIndex);
205     if (stream_sp)
206         static_cast<StreamString *>(stream_sp.get())->Clear();
207     m_status = eReturnStatusStarted;
208     m_did_change_process_state = false;
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