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
19using namespace lldb;
20using namespace lldb_private;
21
22static void
23DumpStringToStreamWithNewline (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
45CommandReturnObject::CommandReturnObject () :
46    m_out_stream (),
47    m_err_stream (),
48    m_status (eReturnStatusStarted),
49    m_did_change_process_state (false)
50{
51}
52
53CommandReturnObject::~CommandReturnObject ()
54{
55}
56
57void
58CommandReturnObject::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
78void
79CommandReturnObject::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
92void
93CommandReturnObject::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
106void
107CommandReturnObject::AppendMessage (const char *in_string)
108{
109    if (!in_string)
110        return;
111    GetOutputStream().Printf("%s\n", in_string);
112}
113
114void
115CommandReturnObject::AppendWarning (const char *in_string)
116{
117    if (!in_string || *in_string == '\0')
118        return;
119    GetErrorStream().Printf("warning: %s\n", in_string);
120}
121
122// Similar to AppendWarning, but do not prepend 'warning: ' to message, and
123// don't append "\n" to the end of it.
124
125void
126CommandReturnObject::AppendRawWarning (const char *in_string)
127{
128    if (in_string && in_string[0])
129        GetErrorStream().PutCString(in_string);
130}
131
132void
133CommandReturnObject::AppendError (const char *in_string)
134{
135    if (!in_string || *in_string == '\0')
136        return;
137    GetErrorStream().Printf ("error: %s\n", in_string);
138}
139
140void
141CommandReturnObject::SetError (const Error &error, const char *fallback_error_cstr)
142{
143    const char *error_cstr = error.AsCString();
144    if (error_cstr == NULL)
145        error_cstr = fallback_error_cstr;
146    SetError(error_cstr);
147}
148
149void
150CommandReturnObject::SetError (const char *error_cstr)
151{
152    if (error_cstr)
153    {
154        AppendError (error_cstr);
155        SetStatus (eReturnStatusFailed);
156    }
157}
158
159// Similar to AppendError, but do not prepend 'Error: ' to message, and
160// don't append "\n" to the end of it.
161
162void
163CommandReturnObject::AppendRawError (const char *in_string)
164{
165    if (in_string && in_string[0])
166        GetErrorStream().PutCString(in_string);
167}
168
169void
170CommandReturnObject::SetStatus (ReturnStatus status)
171{
172    m_status = status;
173}
174
175ReturnStatus
176CommandReturnObject::GetStatus ()
177{
178    return m_status;
179}
180
181bool
182CommandReturnObject::Succeeded ()
183{
184    return m_status <= eReturnStatusSuccessContinuingResult;
185}
186
187bool
188CommandReturnObject::HasResult ()
189{
190    return (m_status == eReturnStatusSuccessFinishResult ||
191            m_status == eReturnStatusSuccessContinuingResult);
192}
193
194void
195CommandReturnObject::Clear()
196{
197    lldb::StreamSP stream_sp;
198    stream_sp = m_out_stream.GetStreamAtIndex (eStreamStringIndex);
199    if (stream_sp)
200        static_cast<StreamString *>(stream_sp.get())->Clear();
201    stream_sp = m_err_stream.GetStreamAtIndex (eStreamStringIndex);
202    if (stream_sp)
203        static_cast<StreamString *>(stream_sp.get())->Clear();
204    m_status = eReturnStatusStarted;
205    m_did_change_process_state = false;
206}
207
208bool
209CommandReturnObject::GetDidChangeProcessState ()
210{
211    return m_did_change_process_state;
212}
213
214void
215CommandReturnObject::SetDidChangeProcessState (bool b)
216{
217    m_did_change_process_state = b;
218}
219
220